diff -u --recursive --new-file v2.4.5/linux/CREDITS linux/CREDITS
--- v2.4.5/linux/CREDITS	Tue May 22 19:54:04 2001
+++ linux/CREDITS	Wed Jun 27 13:59:32 2001
@@ -454,6 +454,11 @@
 E: xavyer@ix.netcom.com
 D: USB Serial Empeg Empeg-car Mark I/II Driver
 
+N: Matthias Bruestle
+E: m@mbsks.franken.de
+D: REINER SCT cyberJack pinpad/e-com USB chipcard reader driver
+S: Germany
+
 N: Ray Burr
 E: ryb@nightmare.com
 D: Original author of Amiga FFS filesystem
@@ -1136,13 +1141,11 @@
 S: USA
 
 N: Benjamin Herrenschmidt
-E: bh40@calva.net
+E: benh@kernel.crashing.org
 E: benh@mipsys.com
-D: PowerMac booter (BootX)
-D: Additional PowerBook support
-D: Apple "Core99" machines support (ibook,g4,...)
-S: 22, rue des Marguettes
-S: 75012 Paris
+D: Various parts of PPC & PowerMac
+S: 122, boulevard Baille
+S: 13005 Marseille
 S: France
 
 N: Sebastian Hetze
@@ -1356,13 +1359,15 @@
 E: davej@suse.de
 W: http://www.suse.de/~davej
 D: Moved PCI bridge tuning to userspace (Powertweak).
-D: Centaur/IDT Winchip/Winchip 2 tweaks.
+D: Various x86 (& clones) setup code hacking.
 D: AFFS fixes for 2.3.x
-D: Misc clean ups and other random hacking.
-S: 28, Laura Street,
-S: Treforest, Pontypridd,
-S: Mid Glamorgan, CF37 1NW,
-S: Wales, United Kingdom
+D: Various Janitorial hacks. (kernel-janitor.sourceforge.net)
+S: c/o SuSE Linux UK Ltd
+S: The Kinetic Centre
+S: Theobald Street
+S: Borehamwood
+S: Herts, WD6 4PJ
+S: United Kingdom
 
 N: Ani Joshi
 E: ajoshi@shell.unixbox.com
@@ -1518,6 +1523,17 @@
 S: L3R 8B2
 S: Canada
 
+N: Maxim Krasnyansky
+E: maxk@qualcomm.com
+W: http://vtun.sf.net
+W: http://bluez.sf.net
+D: Author of the Universal TUN/TAP driver
+D: Author of the Linux Bluetooth Subsystem (BlueZ)
+D: Various other kernel patches, cleanups and fixes
+S: 2213 La Terrace Circle
+S: San Jose, CA 95123
+S: USA
+
 N: Andreas S. Krebs
 E: akrebs@altavista.net
 D: CYPRESS CY82C693 chipset IDE, Digital's PC-Alpha 164SX boards
@@ -1742,6 +1758,8 @@
 
 N: Paul Mackerras
 E: paulus@samba.org
+D: PPP driver
+D: Linux for PowerPC
 D: Linux port for PCI Power Macintosh
 
 N: Pat Mackinlay
@@ -2697,9 +2715,7 @@
 N: Marcelo W. Tosatti
 E: marcelo@conectiva.com.br
 W: http://bazar.conectiva.com.br/~marcelo/
-D: Miscellaneous kernel hacker
-D: Cyclom 2X driver, drbd hacker
-D: linuxconf apache & proftpd module maintainer
+D: Miscellaneous kernel hacker (mostly VM/MM work)
 S: Conectiva S.A.
 S: R. Tocantins, 89 - Cristo Rei
 S: 80050-430 - Curitiba - Paraná
@@ -2883,6 +2899,14 @@
 S: X/OS Experts in Open Systems BV
 S: Kruislaan 419
 S: 1098 VA Amsterdam 
+S: The Netherlands
+
+N: Jeroen Vreeken
+E: pe1rxq@amsat.org
+W: http://www.chello.nl/~j.vreeken/
+D: SE401 usb webcam driver
+S: Maastrichterweg 63
+S: 5554 GG Valkenswaard
 S: The Netherlands
 
 N: Peter Shaobo Wang
diff -u --recursive --new-file v2.4.5/linux/Documentation/Changes linux/Documentation/Changes
--- v2.4.5/linux/Documentation/Changes	Sat May 19 17:43:05 2001
+++ linux/Documentation/Changes	Wed Jun 27 13:37:05 2001
@@ -320,7 +320,7 @@
 
 LVM toolset
 -----------
-o  <http://linux.msede.com/lvm/>
+o  <http://www.sistina.com/lvm/>
 
 Pcmcia-cs
 ---------
@@ -347,7 +347,7 @@
 
 PPP
 ---
-o  <ftp://ftp.samba.org/ppp/ppp-2.4.0.tar.gz>
+o  <ftp://ftp.samba.org/pub/ppp/ppp-2.4.0.tar.gz>
 
 Isdn4k-utils
 ------------
diff -u --recursive --new-file v2.4.5/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.4.5/linux/Documentation/Configure.help	Thu May 24 15:03:06 2001
+++ linux/Documentation/Configure.help	Wed Jun 27 13:59:32 2001
@@ -7537,6 +7537,40 @@
   configure your card and that /etc/pcmcia/wireless.opts works :
     http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html
 
+Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards
+CONFIG_AIRO
+  This is the standard Linux driver to support Cisco/Aironet ISA
+  and PCI 802.11 wireless cards.
+  It supports the new 802.11b cards from Cisco (Cisco 34X, Cisco 35X
+  - with or without encryption) as well as card before the Cisco
+  aquisition (Aironet 4500, Aironet 4800, Aironet 4800B).
+
+  This driver support both the standard Linux Wireless Extensions
+  and Cisco proprietary API, so both the Linux Wireless Tools and the
+  Cisco Linux utilities can be used to configure the card.
+
+  The driver can be compiled as a module and will be named "airo.o".
+
+Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards
+CONFIG_AIRO_CS
+  This is the standard Linux driver to support Cisco/Aironet PCMCIA
+  802.11 wireless cards. This driver is the same as the Aironet
+  driver part of the Linux Pcmcia package.
+  It supports the new 802.11b cards from Cisco (Cisco 34X, Cisco 35X
+  - with or without encryption) as well as card before the Cisco
+  aquisition (Aironet 4500, Aironet 4800, Aironet 4800B). It also
+  supports OEM of Cisco such as the DELL TrueMobile 4800 and Xircom
+  802.11b cards.
+
+  This driver support both the standard Linux Wireless Extensions
+  and Cisco proprietary API, so both the Linux Wireless Tools and the
+  Cisco Linux utilities can be used to configure the card.
+
+  To use your PC-cards, you will need supporting software from David
+  Hinds' pcmcia-cs package (see the file Documentation/Changes for
+  location). You also want to check out the PCMCIA-HOWTO, available
+  from http://www.linuxdoc.org/docs.html#howto .
+
 Aviator/Raytheon 2.4MHz wireless support
 CONFIG_PCMCIA_RAYCS
   Say Y here if you intend to attach an Aviator/Raytheon PCMCIA
@@ -10182,91 +10216,150 @@
 Memory Technology Device (MTD) support
 CONFIG_MTD
   Memory Technology Devices are flash, RAM and similar chips, often
-  used for solid state file systems on embedded devices. This option
+  used for solid state filesystems on embedded devices. This option
   will provide the generic support for MTD drivers to register
   themselves with the kernel and for potential users of MTD devices
   to enumerate the devices which are present and obtain a handle on
   them. It will also allow you to select individual drivers for 
-  particular hardware and users of MTD device. If unsure, say N.
+  particular hardware and users of MTD devices. If unsure, say N.
 
 MTD debugging support
 CONFIG_MTD_DEBUG
   This turns on low-level debugging for the entire MTD sub-system.
+  Normally, you should say 'N'.
+
+MTD partitioning support
+CONFIG_MTD_PARTITIONS
+  If you have a device which needs to divide its flash chip(s) up
+  into multiple 'partitions', each of which appears to the user as
+  a separate MTD device, you require this option to be enabled. If
+  unsure, say 'Y'.
+
+  Note, however, that you don't need this option for the DiskOnChip
+  devices. Partitioning on NFTL 'devices' is a different - that's the
+  'normal' form of partitioning used on a block device.
+
+RedBoot partition table parsing
+CONFIG_MTD_REDBOOT_PARTS
+  RedBoot is a ROM monitor and bootloader which deals with multiple
+  'images' in flash devices by putting a table in the last erase
+  block of the device, similar to a partition table, which gives
+  the offsets, lengths and names of all the images stored in the 
+  flash. 
+
+  If you need code which can detect and parse this table, and register
+  MTD 'partitions' corresponding to each image in the table, enable
+  this option. 
+
+  You will still need the parsing functions to be called by the driver
+  for your particular device. It won't happen automatically. The 
+  SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for 
+  example.
+
+Compaq bootldr partition table parsing
+CONFIG_MTD_BOOTLDR_PARTS
+  The Compaq bootldr deals with multiple 'images' in flash devices
+  by putting a table in one of the first erase blocks of the device,
+  similar to a partition table, which gives the offsets, lengths and
+  names of all the images stored in the flash. 
+
+  If you need code which can detect and parse this table, and register
+  MTD 'partitions' corresponding to each image in the table, enable
+  this option. 
+
+  You will still need the parsing functions to be called by the driver
+  for your particular device. It won't happen automatically. The 
+  SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for 
+  example.
+
+ARM Firmware Suite flash layout / partition parsing
+CONFIG_MTD_AFS_PARTS
+  The ARM Firmware Suite allows the user to divide flash devices into
+  multiple 'images'. Each such image has a header containing its name
+  and offset/size etc. 
+
+  If you need code which can detect and parse these tables, and register
+  MTD 'partitions' corresponding to each image detected, enable
+  this option. 
+
+  You will still need the parsing functions to be called by the driver
+  for your particular device. It won't happen automatically. The 
+  'armflash' map driver (CONFIG_MTD_ARMFLASH) does this, for example.
 
 MTD debugging verbosity
 CONFIG_MTD_DEBUG_VERBOSE
   Determines the verbosity level of the MTD debugging messages.
 
-M-Systems Disk-On-Chip 1000 support
-CONFIG_MTD_DOC1000
-  This provides an MTD device driver for the M-Systems DiskOnChip
-  1000 devices, which are obsolete so you probably want to say 'N'.
 
-M-Systems Disk-On-Chip 2000 and Millennium support
-CONFIG_MTD_DOC2000
-  This provides an MTD device driver for the M-Systems DiskOnChip
-  2000 and Millennium devices. Originally designed for the DiskOnChip
-  2000, it also now includes support for the DiskOnChip Millennium.
-  If you have problems with this driver and the DiskOnChip Millennium,
-  you may wish to try the alternative Millennium driver below. To use
-  the alternative driver, you will need to undefine DOC_SINGLE_DRIVER
-  in the drivers/mtd/docprobe.c source code.
+Direct chardevice access to MTD devices
+CONFIG_MTD_CHAR
+  This provides a character device for each MTD device present in
+  the system, allowing the user to read and write directly to the
+  memory chips, and also use ioctl() to obtain information about
+  the device, or to erase parts of it.
 
-  If you use this device, you probably also want to enable the NFTL
-  'NAND Flash Translation Layer' option below, which is used to emulate
-  a block device by using a kind of filesystem on the flash chips.
+Caching block device access to MTD devices
+CONFIG_MTD_BLOCK
+  Although most flash chips have an erase size too large to be useful
+  as block devices, it is possible to use MTD devices which are based
+  on RAM chips in this manner. This block device is a user of MTD devices
+  performing that function.
+
+  At the moment, it is also required for the Journalling Flash File
+  System(s) to obtain a handle on the MTD device when it's mounted
+  (although JFFS and JFFS2 don't actually use any of the functionality
+  of the mtdblock device).
 
-Alternative Disk-On-Chip Millennium support
-CONFIG_MTD_DOC2001
-  This provides an alternative MTD device driver for the M-Systems
-  DiskOnChip Millennium devices. Use this if you have problems with
-  the combined DiskOnChip 2000 and Millennium driver above. To get
-  the DiskOnChip probe code to load and use this driver instead of
-  the other one, you will need to undefine DOC_SINGLE_DRIVER near
-  the beginning of drivers/mtd/docprobe.c
+  Later, it may be extended to perform read/erase/modify/write cycles
+  on flash chips to emulate a smaller block size. Needless to say,
+  this is very unsafe, but could be useful for filesystems which are
+  almost never written to.
 
-  If you use this device, you probably also want to enable the NFTL
-  'NAND Flash Translation Layer' option below, which is used to emulate
-  a block device by using a kind of filesystem on the flash chips.
+  You do not need this option for use with the DiskOnChip devices. For
+  those, enable NFTL support (CONFIG_NFTL) instead.
 
-Ramix PMC551 PCI Mezzanine ram card support
-CONFIG_MTD_PMC551
-  This provides a MTD device driver for the Ramix PMC551 RAM PCI card
-  from Ramix Inc. (http://www.ramix.com/products/memory/pmc551.html).
-  These devices come in memory configurations from 32M - 1G.  If you
-  have one, you probably want to enable this.
+Readonly block device access to MTD devices
+CONFIG_MTD_BLOCK_RO
+  This allows you to mount read-only filesystems (such as cramfs) from
+  an MTD device, without the overhead (and danger) of the caching 
+  driver. 
 
-  If this driver is compiled as a module you get the ability to select the
-  size of the aperture window pointing into the devices memory.  What this
-  means is that if you have a 1G card, normally the kernel will use a 1G
-  memory map as it's view of the device.  As a module, you can select a
-  1M window into the memory and the driver will "slide" the window around
-  the PMC551's memory.  This was particularly useful on the 2.2 kernels
-  on PPC architectures as there was limited kernel space to deal with.
+  You do not need this option for use with the DiskOnChip devices. For
+  those, enable NFTL support (CONFIG_NFTL) instead.
 
-Use extra onboard system memory as MTD device
-CONFIG_MTD_SLRAM
-  If your CPU cannot cache all of the physical memory in your machine,
-  you can still use it for storage or swap by using this driver to
-  present it to the system as a Memory Technology Device.
+FTL (Flash Translation Layer) support
+CONFIG_FTL
+  This provides support for the original Flash Translation Layer which
+  is part of the PCMCIA specification. It uses a kind of pseudo-
+  filesystem on a flash device to emulate a block device with 512-byte
+  sectors, on top of which you put a 'normal' filesystem.
 
-PMC551 256M DRAM Bugfix
-CONFIG_MTD_PMC551_BUGFIX
-  Some of Ramix's PMC551 boards with 256M configurations have invalid
-  column and row mux values. This option will fix them, but will break
-  other memory configurations.  If unsure say N.
+  You may find that the algorithms used in this code are patented
+  unless you live in the Free World where software patents aren't
+  legal - in the USA you are only permitted to use this on PCMCIA
+  hardware, although under the terms of the GPL you're obviously
+  permitted to copy, modify and distribute the code as you wish. Just
+  not use it.
 
-PMC551 Debugging
-CONFIG_MTD_PMC551_DEBUG
-  This option makes the PMC551 more verbose during it's operation and is
-  only really useful if you are developing on this driver or suspect a
-  possible hardware or driver bug.  If unsure say N.
+NFTL (NAND Flash Translation Layer) support
+CONFIG_NFTL
+  This provides support for the NAND Flash Translation Layer which is
+  used on M-Systems' DiskOnChip devices. It uses a kind of pseudo-
+  filesystem on a flash device to emulate a block device with 512-byte
+  sectors, on top of which you put a 'normal' filesystem.
 
-Debugging RAM test driver
-CONFIG_MTD_MTDRAM
-  This enables a test MTD device driver which uses vmalloc() to
-  provide storage. You probably want to say 'N' unless you're
-  testing stuff.
+  You may find that the algorithms used in this code are patented
+  unless you live in the Free World where software patents aren't
+  legal - in the USA you are only permitted to use this on DiskOnChip
+  hardware, although under the terms of the GPL you're obviously
+  permitted to copy, modify and distribute the code as you wish. Just
+  not use it.
+
+Write support for NFTL (EXPERIMENTAL)
+CONFIG_NFTL_RW
+  If you're lucky, this will actually work. Don't whinge if it doesn't.
+  Send mail to the MTD mailing list <linux-mtd@lists.infradead.org> if
+  you want to help to make it more reliable.
 
 Common Flash Interface (CFI) support
 CONFIG_MTD_CFI
@@ -10277,12 +10370,135 @@
   option. Visit (http://www.amd.com/products/nvd/overview/cfi.html)
   for more information on CFI.
 
-CFI support for Intel/Sharp Extended Command Set chips
+CFI Advanced configuration options
+CONFIG_MTD_CFI_ADV_OPTIONS
+  If you need to specify a specific endianness for access to flash
+  chips, or if you wish to reduce the size of the kernel by including
+  support for only specific arrangements of flash chips, say 'Y'. This
+  option does not directly affect the code, but will enable other 
+  configuration options which allow you to do so.
+
+  If unsure, say 'N'.
+
+Specific CFI Flash geometry selection
+CONFIG_MTD_CFI_GEOMETRY
+  This option does not affect the code directly, but will enable 
+  some other configuration options which would allow you to reduce
+  the size of the kernel by including support for only certain 
+  arrangements of CFI chips. If unsure, say 'N' and all options 
+  which are supported by the current code will be enabled.
+
+Support 8-bit buswidth
+CONFIG_MTD_CFI_B1
+  If you wish to support CFI devices on a physical bus which is
+  8 bits wide, say 'Y'.
+
+Support 16-bit buswidth
+CONFIG_MTD_CFI_B2
+  If you wish to support CFI devices on a physical bus which is
+  16 bits wide, say 'Y'.
+
+Support 32-bit buswidth
+CONFIG_MTD_CFI_B4
+  If you wish to support CFI devices on a physical bus which is
+  32 bits wide, say 'Y'.
+
+Support 1-chip flash interleave
+CONFIG_MTD_CFI_I1
+  If your flash chips are not interleaved - i.e. you only have one
+  flash chip addressed by each bus cycle, then say 'Y'.
+
+Support 2-chip flash interleave
+CONFIG_MTD_CFI_I2
+  If your flash chips are interleaved in pairs - i.e. you have two
+  flash chips addressed by each bus cycle, then say 'Y'.
+
+Support 4-chip flash interleave
+CONFIG_MTD_CFI_I4
+  If your flash chips are interleaved in fours - i.e. you have four
+  flash chips addressed by each bus cycle, then say 'Y'.
+
+Flash cmd/query data swapping
+CONFIG_MTD_CFI_NOSWAP
+  This option defines the way in which the CPU attempts to arrange
+  data bits when writing the 'magic' commands to the chips. Saying
+  'NO', which is the default when CONFIG_MTD_CFI_ADV_OPTIONS isn't
+  enabled, means that the CPU will not do any swapping; the chips
+  are expected to be wired to the CPU in 'host-endian' form. 
+  Specific arrangements are possible with the BIG_ENDIAN_BYTE and
+  LITTLE_ENDIAN_BYTE, if the bytes are reversed. 
+
+  If you have a LART, on which the data (and address) lines were
+  connected in a fashion which ensured that the nets were as short
+  as possible, resulting in a bit-shuffling which seems utterly
+  random to the untrained eye, you need the LART_ENDIAN_BYTE option.
+
+  Yes, there really exists something sicker than PDP-endian :)
+
+CFI support for Intel/Sharp Extended Commands
 CONFIG_MTD_CFI_INTELEXT
   The Common Flash Interface defines a number of different command
   sets which a CFI-compliant chip may claim to implement. This code
   provides support for one of those command sets, used on Intel
-  Strataflash and other parts.
+  StrataFlash and other parts.
+
+CFI support for AMD/Fujitsu Standard Commands
+CONFIG_MTD_CFI_AMDSTD
+  The Common Flash Interface defines a number of different command
+  sets which a CFI-compliant chip may claim to implement. This code
+  provides support for one of those command sets, used on chips 
+  chips including the AMD Am29LV320.
+
+CFI support for Intel/Sharp Standard Commands
+CONFIG_MTD_CFI_INTELSTD
+  The Common Flash Interface defines a number of different command
+  sets which a CFI-compliant chip may claim to implement. This code
+  provides support for one of those command sets.
+
+pre-CFI Sharp chip support
+CONFIG_MTD_SHARP
+  This option enables support for flash chips using Sharp-compatible
+  commands, including some which are not CFI-compatible and hence 
+  cannot be used with the CONFIG_MTD_CFI_INTELxxx options.
+
+AMD compatible flash chip support (non-CFI)
+CONFIG_MTD_AMDSTD
+  This option enables support for flash chips using AMD-compatible
+  commands, including some which are not CFI-compatible and hence 
+  cannot be used with the CONFIG_MTD_CFI_AMDSTD option.
+
+  It also works on AMD compatible chips that do conform to CFI.
+
+Support for RAM chips in bus mapping
+CONFIG_MTD_RAM
+  This option enables basic support for RAM chips accessed through 
+  a bus mapping driver.
+
+Support for ROM chips in bus mapping
+CONFIG_MTD_ROM
+  This option enables basic support for ROM chips accessed through 
+  a bus mapping driver.
+
+CONFIG_MTD_JEDEC
+  Enable older older JEDEC flash interface devices for self programming
+  flash. It is commonly used in older AMD chips. It is only called
+  JEDEC because the JEDEC association (http://www.jedec.org/)
+  distributes the identification codes for the chips. WARNING!!!! This
+  code does not compile and is incomplete as are the specific JEDEC
+  devices drivers.
+
+CFI Flash device mapped on StrongARM SA11x0
+CONFIG_MTD_SA1100
+  This enables access to the flash chips on most platforms based on the
+  SA1100 and SA1110, including the Assabet and the Compaq iPAQ. If you
+  have such a board, say 'Y'.
+
+CONFIG_MTD_SA1100_REDBOOT_PARTITIONS
+  Enabling this option will cause the kernel to look for a RedBoot 
+  FIS (Flash Image System) table in the last erase block of the flash
+  chips detected. If you are using RedBoot on your SA11x0-based board
+  and want Linux to present 'partitions' matching the images which
+  RedBoot has listed, say 'Y'. 
 
 Flash chip mapping in physical memory
 CONFIG_MTD_PHYSMAP
@@ -10295,18 +10511,18 @@
 Physical start location of flash chip mapping
 CONFIG_MTD_PHYSMAP_START
   This is the physical memory location at which the flash chips
-  are mapped on your particular target board. Refer to the 
+  are mapped on your particular target board. Refer to the
   memory map which should hopefully be in the documentation for
   your board.
 
 Physical length of flash chip mapping
 CONFIG_MTD_PHYSMAP_LEN
   This is the total length of the mapping of the flash chips on
-  your particular board. If there is space, or aliases, in the 
+  your particular board. If there is space, or aliases, in the
   physical memory map between the chips, this could be larger
   than the total amount of flash present. Refer to the memory
   map which should hopefully be in the documentation for your
-  board. 
+  board.
 
 CONFIG_MTD_PHYSMAP_BUSWIDTH
   This is the total width of the data bus of the flash devices
@@ -10314,14 +10530,12 @@
   bits, you would set the bus width octect value to 4. This is
   used internally by the CFI drivers.
 
-Flash chip mapping on Mixcom piggyback card
-CONFIG_MTD_MIXMEM
-  This supports the paging arrangement for access to flash chips
-  on the MixCOM piggyback card, allowing the flash chip drivers
-  to get on with their job of driving the flash chips without
-  having to know about the paging. If you have one of these boards,
-  you probably want to enable this mapping driver. More info is at
-  (http://www.itc.hu/).
+Flash chip mapping on Sun Microsystems boardsets
+CONFIG_MTD_SUN_UFLASH
+  This provides a 'mapping' driver which supports the way in 
+  which user-programmable flash chips are connected on various 
+  Sun Microsystems boardsets.  This driver will require CFI support 
+  in the kernel, so if you did not enable CFI previously, do that now.
 
 Flash chip mapping on Nora
 CONFIG_MTD_NORA
@@ -10332,13 +10546,6 @@
   PNC-2000 is the name of Network Camera product from PHOTRON
   Ltd. in Japan. It uses CFI-compliant flash.
 
-Flash chip mapping on Octagon 5066 SBC
-CONFIG_MTD_OCTAGON
-  This provides a 'mapping' driver which supports the way in which
-  the flash chips are connected in the Octagon-5066 Single Board
-  Computer. More information on the board is available at
-  (http://www.octagonsystems.com/Products/5066/5066.html).
-
 Flash chip mapping on RPXlite PPC board
 CONFIG_MTD_RPXLITE
   The RPXLite PowerPC board has CFI-compliant chips mapped in
@@ -10347,6 +10554,89 @@
   to communicate with the chips on the RPXLite board. More at
   (http://www.embeddedplanet.com/rpx_lite_specification_sheet.htm).
 
+Flash chip mapping on AMD SC520 CDP board
+CONFIG_MTD_SC520CDP
+  The SC520 CDP board has two banks of CFI-compliant chips and one
+  Dual-in-line JEDEC chip. This 'mapping' driver supports that
+  arrangement, implementing three MTD devices.
+
+Flash chip mapping on Arcom Control Systems' SBC-MediaGX
+CONFIG_MTD_SBC_MEDIAGX
+  This provides a driver for the on-board flash of Arcom Control
+  Systems' SBC-MediaGX development board. By default the flash
+  is split into 3 partitions which are accessed as separate MTD
+  devices. This board utilizes Intel StrataFlash. More info at
+  (http://www.arcomcontrols.com/products/icp/pc104/processors/).
+
+Flash chip mapping on Arcom Control Systems' ELAN-104NC
+CONFIG_MTD_ELAN_104NC
+  This provides a driver for the on-board flash of the Arcom Control
+  System's ELAN-104NC development board. By default the flash
+  is split into 3 partitions which are accessed as separate MTD
+  devices. This board utilizes Intel StrataFlash. More info at
+  (http://www.arcomcontrols.com/products/icp/pc104/processors/).
+
+Flash chip mapping on Compaq iPAQ/Bitsy
+CONFIG_MTD_BITSY
+  This provides a driver for the on-board flash found in Compaq's
+  iPAQ Palm PC and their research prototype the Itsy. iPAQ info at
+  (http://www5.compaq.com/products/handhelds/pocketpc/) and the
+  Itsy (http://www.research.digital.com/wrl/projects/Itsy/index.html).
+ 
+Flash chip mapping on Compaq iPAQ/Bitsy
+CONFIG_MTD_DC21285
+  This provides a driver for the flash accessed using Intel's
+  21285 bridge used with Intel's StrongARM processors. More info at
+  (http://developer.intel.com/design/bridge/quicklist/dsc-21285.htm).
+
+Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board
+CONFIG_MTD_CSTM_MIPS_IXX
+  This provides a mapping driver for the Integrated Tecnology
+  Express, Inc (ITE) QED-4N-S01B eval board and the Globespan IVR Reference
+  Board. It provides the necessary addressing, length, buswidth, vpp code 
+  and addition setup of the flash device for these boards. In addition,
+  this mapping driver can be used for other boards via setting of the
+  CONFIG_MTD_CSTM_MIPS_IXX_START/LEN/BUSWIDTH parameters.  This mapping
+  will provide one mtd device using one partition.  The start address can
+  be offset from the beginning of flash and the len can be less than the
+  total flash device size to allow a window into the flash.  Both CFI and 
+  JEDEC probes are called.
+
+Physical start location of flash mapping
+CONFIG_MTD_CSTM_MIPS_IXX_START
+  This is the physical memory location that the MTD driver will
+  use for the flash chips on your particular target board. 
+  Refer to the memory map which should hopefully be in the 
+  documentation for your board.
+
+Physical length of flash mapping
+CONFIG_MTD_CSTM_MIPS_IXX_LEN
+  This is the total length that the MTD driver will use for the 
+  flash chips on your particular board.  Refer to the memory
+  map which should hopefully be in the documentation for your
+  board. 
+
+Physical bus width of flash mapping
+CONFIG_MTD_CSTM_MIPS_IXX_BUSWIDTH
+  This is the total bus width of the mapping of the flash chips
+  on your particular board.
+
+Flash chip mapping on Mixcom piggyback card
+CONFIG_MTD_MIXMEM
+  This supports the paging arrangement for access to flash chips
+  on the MixCOM piggyback card, allowing the flash chip drivers
+  to get on with their job of driving the flash chips without
+  having to know about the paging. If you have one of these boards,
+  you probably want to enable this mapping driver. More info is at
+  (http://www.itc.hu/).
+
+Flash chip mapping on Octagon 5066 SBC
+CONFIG_MTD_OCTAGON
+  This provides a 'mapping' driver which supports the way in which
+  the flash chips are connected in the Octagon-5066 Single Board
+  Computer. More information on the board is available at
+  (http://www.octagonsystems.com/Products/5066/5066.html).
+
 Flash chip mapping on Tempustech VMAX SBC301
 CONFIG_MTD_VMAX
   This provides a 'mapping' driver which supports the way in which
@@ -10354,57 +10644,168 @@
   Board Computer. More information on the board is available at
   (http://www.tempustech.com/tt301.htm).
 
-Direct chardevice access to MTD devices
-CONFIG_MTD_CHAR
-  This provides a character device for each MTD device present in
-  the system, allowing the user to read and write directly to the
-  memory chips, and also use ioctl() to obtain information about
-  the device, or to erase parts of it.
+Support for NAND flash devices
+CONFIG_MTD_NAND
+  This enables support for accessing all type of NAND flash
+  devices. 
+
+Support for software ECC algorithm
+CONFIG_MTD_NAND_ECC
+  This enables software-based ECC for use with NAND flash chips. It
+  can detect and correct 1 bit errors per 256 byte blocks. This
+  should be used to increase the reliability of the data stored and
+  read on the device.
+
+Support for verify read after write
+CONFIG_MTD_NAND_VERIFY_WRITE
+  This adds an extra check when data is written to the flash. The
+  NAND flash device internally checks only bits transitioning
+  from 1 to 0. There is a rare possibility that even though the
+  device thinks the write was successful, a bit could have been
+  flipped accidentaly due to device wear, gamma rays, whatever.
+  Enable this if you are really paranoid.
 
-Pseudo-blockdevice access to MTD devices
-CONFIG_MTD_BLOCK
-  Although flash chips have an erase size too large to useful as
-  block devices, it is possible to use MTD devices which are based
-  on RAM chips in this manner. This blockdevice user of MTD devices
-  performs that function. At the moment, it is also required for 
-  the Journalling Flash File System to obtain a handle on the MTD 
-  device when it's mounted - although the JFFS doesn't actually use
-  any of the functions of the mtdblock device.
+Support for the SPIA board
+CONFIG_MTD_NAND_SPIA
+  If you had to ask, you don't have one. Say 'N'.
 
-  Later, it may be extended to perform read/erase/modify/write cycles
-  on flash chips to emulate a smaller block size. Needless to say,
-  this is very unsafe, but could be useful for file systems which are
-  almost never written to.
+M-Systems Disk-On-Chip 1000 support
+CONFIG_MTD_DOC1000
+  This provides an MTD device driver for the M-Systems DiskOnChip
+  1000 devices, which are obsolete so you probably want to say 'N'.
 
-FTL (Flash Translation Layer) support
-CONFIG_FTL
-  This provides support for the original Flash Translation Layer which
-  is part of the PCMCIA specification. It uses a kind of pseudo-
-  file system on a flash device to emulate a block device with 512-byte
-  sectors, on top of which you put a 'normal' file system. You may find
-  that the algorithms used in this code are patented unless you live
-  in the Free World where software patents aren't legal - in the USA
-  you are only permitted to use this on PCMCIA hardware, although 
-  under the terms of the GPL you're obviously permitted to copy,
-  modify and distribute the code as you wish. Just not use it.
+M-Systems Disk-On-Chip 2000 and Millennium support
+CONFIG_MTD_DOC2000
+  This provides an MTD device driver for the M-Systems DiskOnChip
+  2000 and Millennium devices. Originally designed for the DiskOnChip 
+  2000, it also now includes support for the DiskOnChip Millennium. 
+  If you have problems with this driver and the DiskOnChip Millennium,
+  you may wish to try the alternative Millennium driver below. To use
+  the alternative driver, you will need to undefine DOC_SINGLE_DRIVER
+  in the drivers/mtd/devices/docprobe.c source code.
 
-NFTL (NAND Flash Translation Layer) support
-CONFIG_NFTL
-  This provides support for the NAND Flash Translation Layer which is
-  used on M-Systems' DiskOnChip devices. It uses a kind of pseudo-
-  file system on a flash device to emulate a block device with 512-byte
-  sectors, on top of which you put a 'normal' file system. You may find
-  that the algorithms used in this code are patented unless you live
-  in the Free World where software patents aren't legal - in the USA
-  you are only permitted to use this on DiskOnChip hardware, although 
-  under the terms of the GPL you're obviously permitted to copy,
-  modify and distribute the code as you wish. Just not use it.
+  If you use this device, you probably also want to enable the NFTL
+  'NAND Flash Translation Layer' option below, which is used to emulate
+  a block device by using a kind of filesystem on the flash chips.
 
-Write support for NFTL (EXPERIMENTAL)
-CONFIG_NFTL_RW
-  If you're lucky, this will actually work. Don't whine if it doesn't.
-  Contact (dwmw2@infradead.org) if you want to help to make it more
-  reliable.
+Alternative Disk-On-Chip Millennium support
+CONFIG_MTD_DOC2001
+  This provides an alternative MTD device driver for the M-Systems 
+  DiskOnChip Millennium devices. Use this if you have problems with
+  the combined DiskOnChip 2000 and Millennium driver above. To get
+  the DiskOnChip probe code to load and use this driver instead of
+  the other one, you will need to undefine DOC_SINGLE_DRIVER near
+  the beginning of drivers/mtd/devices/docprobe.c 
+
+  If you use this device, you probably also want to enable the NFTL
+  'NAND Flash Translation Layer' option below, which is used to emulate
+  a block device by using a kind of filesystem on the flash chips.
+
+Probe for DiskOnChip devices
+CONFIG_MTD_DOCPROBE
+  This isn't a real config option, it's derived. 
+
+Advanced detection options for DiskOnChip
+CONFIG_MTD_DOCPROBE_ADVANCED
+  This option allows you to specify nonstandard address at which to
+  probe for a DiskOnChip, or to change the detection options. You're
+  unlikely to need any of this unless you're using LinuxBIOS. Say 'N'.
+
+Probe for 0x55 0xAA BIOS Extension Signature.
+CONFIG_MTD_DOCPROBE_55AA
+  Check for the 0x55 0xAA signature of a DiskOnChip, and do not continue
+  with probing if it is absent. The signature will always be present for
+  a DiskOnChip 2000 or a normal DiskOnChip Millennium. Only if you have
+  overwritten the first block of a DiskOnChip Millennium will it be 
+  absent. Enable this option if you are using LinuxBIOS or if you need
+  to recover a DiskOnChip Millennium on which you have managed to wipe
+  the first block.
+
+Physical address of DiskOnChip
+CONFIG_MTD_DOCPROBE_ADDRESS
+  By default, the probe for DiskOnChip devices will look for a DiskOnChip
+  at every multiple of 0x2000 between 0xC8000 and 0xEE000. This option 
+  allows you to specify a single address at which to probe for the device,
+  which is useful if you have other devices in that range which get upset
+  when they're probed. 
+
+  (Note that on PowerPC, the normal probe will only check at 0xE4000000.)
+
+  Normally, you should leave this set to zero, to allow the probe at the
+  normal addresses.
+
+Probe high addresses
+CONFIG_MTD_DOCPROBE_HIGH
+  By default, the probe for DiskOnChip devices will look for a DiskOnChip
+  at every multiple of 0x2000 between 0xC8000 and 0xEE000. This option 
+  changes to make it probe between 0xFFFC8000 and 0xFFFEE000. Unless
+  you're using LinuxBIOS, this is unlikely to be useful to you. Say 'N'. 
+
+Ramix PMC551 PCI Mezzanine ram card support
+CONFIG_MTD_PMC551
+  This provides a MTD device driver for the Ramix PMC551 RAM PCI card
+  from Ramix Inc. (http://www.ramix.com/products/memory/pmc551.html).
+  These devices come in memory configurations from 32M - 1G.  If you
+  have one, you probably want to enable this.
+
+  If this driver is compiled as a module you get the ability to select the
+  size of the aperture window pointing into the devices memory.  What this 
+  means is that if you have a 1G card, normally the kernel will use a 1G
+  memory map as it's view of the device.  As a module, you can select a
+  1M window into the memory and the driver will "slide" the window around
+  the PMC551's memory.  This was particularly useful on the 2.2 kernels 
+  on PPC architectures as there was limited kernel space to deal with.
+
+PMC551 256M DRAM Bugfix
+CONFIG_MTD_PMC551_BUGFIX
+  Some of Ramix's PMC551 boards with 256M configurations have invalid column
+  and row mux values. This option will fix them, but will break other memory
+  configurations.  If unsure say N.
+
+PMC551 Debugging
+CONFIG_MTD_PMC551_DEBUG
+  This option makes the PMC551 more verbose during it's operation and is only
+  really usefull if you are developing on this driver or suspect a possible
+  hardware or driver bug.  If unsure say N.
+
+Use extra onboard system memory as MTD device
+CONFIG_MTD_SLRAM
+  If your CPU cannot cache all of the physical memory in your machine,
+  you can still use it for storage or swap by using this driver to
+  present it to the system as a Memory Technology Device.
+
+Debugging RAM test driver
+CONFIG_MTD_MTDRAM
+  This enables a test MTD device driver which uses vmalloc() to
+  provide storage. You probably want to say 'N' unless you're
+  testing stuff.
+
+MTDRAM erase block size in KiB
+CONFIG_MTDRAM_ERASE_SIZE
+  This allows you to configure the size of the erase blocks in the
+  device emulated by the MTDRAM driver. If the MTDRAM driver is built
+  as a module, it is also possible to specify this as a parameter when
+  loading the module.
+
+MTDRAM device size in KiB
+CONFIG_MTDRAM_TOTAL_SIZE
+  This allows you to configure the total size of the MTD device
+  emulated by the MTDRAM driver. If the MTDRAM driver is built
+  as a module, it is also possible to specify this as a parameter when
+  loading the module.
+
+SRAM absolute position
+CONFIG_MTDRAM_ABS_POS
+  If you have system RAM accessible by the CPU but not used by Linux
+  in normal operation, you can give the physical address at which the
+  available RAM starts, and the MTDRAM driver will use it instead of
+  allocating space from Linux's available memory. Otherwise, leave 
+  this set to zero. Most people will want to leave this as zero.
+
+Flash chip mapping on the Flaga Digital Module
+CONFIG_MTD_CFI_FLAGADM
+  Mapping for the Flaga digital module. If you don´t have one, ignore this
+  setting.
 
 Support for USB
 CONFIG_USB
@@ -10709,9 +11110,10 @@
 
 USB Handspring Visor Driver
 CONFIG_USB_SERIAL_VISOR
-  Say Y here if you want to connect to your HandSpring Visor through
-  its USB docking station. See http://usbvisor.sourceforge.net for
-  more information on using this driver.
+  Say Y here if you want to connect to your HandSpring Visor, Palm m500
+  or m505 through its USB docking station.
+  See http://usbvisor.sourceforge.net for more information on using this
+  driver.
 
   This code is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -10841,6 +11243,29 @@
   The module will be called mct_u232.o.  If you want to compile it as
   a module, say M here and read Documentation/modules.txt.
 
+USB Prolific 2303 Single Port Serial Driver
+CONFIG_USB_SERIAL_PL2303
+  Say Y here if you want to use the PL2303 USB Serial single port
+  adapter from Prolific.
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called pl2303.o.  If you want to compile it as
+  a module, say M here and read Documentation/modules.txt.
+
+USB REINER SCT cyberJack pinpad/e-com chipcard reader
+CONFIG_USB_SERIAL_CYBERJACK
+  Say Y here if you want to use a cyberJack pinpad/e-com USB chipcard
+  reader. This is an interface to ISO 7816 compatible contactbased
+  chipcards, e.g. GSM SIMs.
+ 
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called cyberjack.o. If you want to compile it as
+  a module, say M here and read Documentation/modules.txt.
+ 
+  If unsure, say N.
+
 USB Edgeport Serial Driver
 CONFIG_USB_SERIAL_EDGEPORT
   Say Y here if you want to use any of the following devices from
@@ -10946,6 +11371,22 @@
   module, say M here and read Documentation/modules.txt.
 
 
+USB SE401 Camera support
+CONFIG_USB_SE401
+  Say Y here if you want to connect this type of camera to your
+  computer's USB port. See Documentation/usb/se401.txt for more
+  information and for a list of supported cameras.
+  
+  This driver uses the Video For Linux API. You must say Y or M to
+  "Video For Linux" (under Multimedia Devices) to use this driver.
+  Information on this API and pointers to "v4l" programs may be found
+  on the WWW at http://roadrunner.swansea.uk.linux.org/v4l.shtml .
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called se401.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
+
 USB ADMtek Pegasus-based ethernet device support
 CONFIG_USB_PEGASUS
   Say Y if you want to use your USB ethernet device. Supported
@@ -10972,6 +11413,20 @@
   The module will be called pegasus.o. If you want to compile it as a
   module, say M here and read Documentation/modules.txt.
 
+USB CATC NetMate-based Ethernet device support
+CONFIG_USB_CATC
+  Say Y if you want to use one of the following 10Mbps USB Ethernet
+  device based on the EL1210A chip. Supported devices are:
+    Belkin F5U111
+    CATC NetMate
+    CATC NetMate II
+    smartBridges smartNIC
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called catc.o. If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.
+
 USB Kodak DC-2xx Camera support
 CONFIG_USB_DC2XX
   Say Y here if you want to connect this type of still camera to
@@ -11128,12 +11583,13 @@
 
 Microtek USB scanner support
 CONFIG_USB_MICROTEK
-  Say Y here if you want support for the Microtek X6USB and possibly
-  some other scanners by that vendor. The scanner will appear as a
-  scsi generic device to the rest of the system.
-  A patched version of SANE is necessary to use the
-  scanner. It's available at 
-  http://fachschaft.cup.uni-muenchen.de/~neukum/scanner.html
+  Say Y here if you want support for the Microtek X6USB and
+  possibly the Phantom 336CX, Phantom C6 and ScanMaker V6U(S)L.
+  Support for anything but the X6 is experimetal.
+  Please report failures and successes.
+  The scanner will appear as a scsi generic device to the rest
+  of the system. Scsi support is required for this driver to compile
+  and work. SANE 1.0.4 or newer is needed to make use of your scanner.
   This driver can be compiled as a module.
 
 USB Bluetooth support
@@ -13241,8 +13697,8 @@
 Apple Desktop Bus support
 CONFIG_ADB
   Apple Desktop Bus (ADB) support is for support of devices which
-  are connected to the to an ADB port.  ADB devices tend to have
-  4 pins.  If you have an Apple Macintosh prior to the iMac, or a
+  are connected to an ADB port.  ADB devices tend to have 4 pins.
+  If you have an Apple Macintosh prior to the iMac, or a
   "Blue and White G3", you probably want to say Y here.  Otherwise
   say N.
 
@@ -13730,7 +14186,7 @@
   will issue the hlt instruction if nothing is to be done, thereby
   sending the processor to sleep and saving power.
 
-ACPI Support
+ACPI support
 CONFIG_ACPI
   ACPI/OSPM support for Linux is currently under development. As such, 
   this support is preliminary and EXPERIMENTAL. Configuring ACPI support
@@ -13760,6 +14216,57 @@
   The ACPI mailing list may also be of interest:
   http://phobos.fs.tum.de/acpi/index.html
 
+ACPI Debug Statements
+CONFIG_ACPI_DEBUG
+  The ACPI driver can optionally report errors with a great deal
+  of verbosity. Saying Y enables these statements. This will increase
+  your kernel size by around 50K.
+
+ACPI Bus Manager
+CONFIG_ACPI_BUSMGR
+  The ACPI Bus Manager enumerates devices in the ACPI namespace, and
+  handles PnP messages. All ACPI devices use its services, so using them
+  requires saying Y here.
+
+ACPI System Driver
+CONFIG_ACPI_SYS
+  This driver will enable your system to shut down using ACPI, and dump
+  your ACPI DSDT table using /proc/acpi/dsdt.
+
+ACPI Processor Driver
+CONFIG_ACPI_CPU
+  This driver installs ACPI as the idle handler for Linux, and uses ACPI
+  C2 and C3 processor states to save power, on systems that support it.
+
+ACPI Button
+CONFIG_ACPI_BUTTON
+  This driver registers for events based on buttons, such as the power,
+  sleep, and lid switch. In the future, a daemon will read 
+  /proc/acpi/event and perform user-defined actions such as shutting
+  down the system. Until then, you can cat it, and see output when
+  a button is pressed.
+
+ACPI AC Adapter
+CONFIG_ACPI_AC
+  This driver adds support for the AC Adapter object, which indicates
+  whether a system is on AC, or not. Typically, only laptops have this
+  object, since desktops are always on AC.
+
+ACPI Embedded Controller
+CONFIG_ACPI_EC
+  This driver is required on some systems for the proper operation of the
+  battery and thermal drivers. If you are compiling for a laptop, say Y.
+
+ACPI Control Method Battery
+CONFIG_ACPI_CMBATT
+  This driver adds support for battery information through
+  /proc/acpi/battery. If you have a laptop with a battery, say Y.
+
+ACPI Thermal
+CONFIG_ACPI_THERMAL
+  This driver handles overheating conditions on laptops. It is HIGHLY
+  recommended, as your laptop CPU may be damaged without it.
+
 Advanced Power Management BIOS support
 CONFIG_APM
   APM is a BIOS specification for saving power using several different
@@ -14883,17 +15390,20 @@
 
   If unsure, say Y.
 
-ACI mixer (miroPCM12/PCM20)
+ACI mixer (miroSOUND PCM1-pro/PCM12/PCM20 radio)
 CONFIG_SOUND_ACI_MIXER
   ACI (Audio Command Interface) is a protocol used to communicate with
-  the microcontroller on some sound cards produced by miro, e.g. the
-  miroSOUND PCM12 and PCM20. The main function of the ACI is to
-  control the mixer and to get a product identification. 
-
-  This Voxware ACI driver currently only supports the ACI functions on
-  the miroSOUND PCM12 and PCM20 cards. On the PCM20, ACI also controls
-  the radio tuner. This is supported in the video4linux
-  radio-miropcm20 driver.
+  the microcontroller on some sound cards produced by miro and Cardinal
+  Technologies. The main function of the ACI is to control the mixer
+  and to get a product identification. 
+
+  This Voxware ACI driver currently supports the ACI functions on the
+  miroSOUND PCM1-pro, PCM12 and PCM20 radio. On the PCM20 radio, ACI
+  also controls the radio tuner. This is supported in the video4linux
+  miropcm20 driver (say M or Y here and go back to "Multimedia devices"
+  -> "Radio Adapters").
+
+  This driver is also available as a module and will be called aci.o.
 
 SB32/AWE support
 CONFIG_SOUND_AWE32_SYNTH
@@ -16711,11 +17221,11 @@
   say M here and read Documentation/modules.txt. The module will be
   called i2c-parport.o.
 
-Miro PCM20 Radio
+miroSOUND PCM20 radio
 CONFIG_RADIO_MIROPCM20
-  Choose Y here if you have this FM radio card. You also need to say Y
-  to "ACI mixer (miroPCM12/PCM20)" (in "additional low level sound
-  drivers") for this to work.
+  Choose Y here if you have this sound card. You also need to say Y
+  to "ACI mixer (miroSOUND PCM1-pro/PCM12/PCM20 radio)" (in "Sound")
+  for this to work.
 
   In order to control your radio card, you will need to use programs
   that are compatible with the Video for Linux API. Information on 
@@ -16725,7 +17235,21 @@
   If you want to compile this driver as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
   say M here and read Documentation/modules.txt. The module will be
-  called radio-miropcm20.o
+  called miropcm20.o
+
+miroSOUND PCM20 radio RDS user interface (EXPERIMENTAL)
+CONFIG_RADIO_MIROPCM20_RDS
+  Choose Y here if you want to see RDS/RBDS information like RadioText,
+  Programme Service name, Clock Time and date, Programme TYpe and
+  Traffic Announcement/Programme identification. You also need to say
+  Y to "miroSOUND PCM20 radio" and devfs!
+
+  It's not possible to read the raw RDS packets from the device, so
+  the driver cant provide an V4L interface for this. But the
+  availability of RDS is reported over V4L by the basic driver already.
+  Here RDS can be read from files in /dev/v4l/rds.
+
+  As module the driver will be called miropcm20-rds.o.
 
 GemTek Radio Card
 CONFIG_RADIO_GEMTEK
diff -u --recursive --new-file v2.4.5/linux/Documentation/filesystems/00-INDEX linux/Documentation/filesystems/00-INDEX
--- v2.4.5/linux/Documentation/filesystems/00-INDEX	Thu Feb  8 16:32:44 2001
+++ linux/Documentation/filesystems/00-INDEX	Wed Jun 20 11:10:27 2001
@@ -33,7 +33,7 @@
 smbfs.txt
 	- info on using filesystems with the SMB protocol (Windows 3.11 and NT)
 sysv-fs.txt
-	- info on the SystemV/Coherent filesystem.
+	- info on the SystemV/V7/Xenix/Coherent filesystem.
 udf.txt
 	- info and mount options for the UDF filesystem.
 ufs.txt
diff -u --recursive --new-file v2.4.5/linux/Documentation/filesystems/devfs/ChangeLog linux/Documentation/filesystems/devfs/ChangeLog
--- v2.4.5/linux/Documentation/filesystems/devfs/ChangeLog	Fri Apr  6 10:42:48 2001
+++ linux/Documentation/filesystems/devfs/ChangeLog	Wed Jun 20 10:54:31 2001
@@ -1613,3 +1613,51 @@
 - Updated README from master HTML file
 
 - Ported to kernel 2.4.0-test3-pre4 (which had devfs-patch-v174)
+===============================================================================
+Changes for patch v177
+
+- Updated README from master HTML file
+
+- Documentation cleanups
+
+- Ensure <devfs_generate_path> terminates string for root entry
+  Thanks to Tim Jansen <tim@tjansen.de>
+
+- Exported <devfs_get_name> to modules
+
+- Make <devfs_mk_symlink> send events to devfsd
+
+- Cleaned up option processing in <devfs_setup>
+
+- Fixed bugs in handling symlinks: could leak or cause Oops
+
+- Cleaned up directory handling by separating fops
+  Thanks to Alexander Viro <viro@math.psu.edu>
+===============================================================================
+Changes for patch v178
+
+- Fixed handling of inverted options in <devfs_setup>
+===============================================================================
+Changes for patch v179
+
+- Adjusted <try_modload> to account for <devfs_generate_path> fix
+===============================================================================
+Changes for patch v180
+
+- Fixed !CONFIG_DEVFS_FS stub declaration of <devfs_get_info>
+===============================================================================
+Changes for patch v181
+
+- Answered question posed by Al Viro and removed his comments from <devfs_open>
+
+- Moved setting of registered flag after other fields are changed
+
+- Fixed race between <devfsd_close> and <devfsd_notify_one>
+
+- Global VFS changes added bogus BKL to devfsd_close(): removed
+
+- Widened locking in <devfs_readlink> and <devfs_follow_link>
+
+- Replaced <devfsd_read> stack usage with <devfsd_ioctl> kmalloc
+
+- Simplified locking in <devfsd_ioctl> and fixed memory leak
diff -u --recursive --new-file v2.4.5/linux/Documentation/filesystems/devfs/README linux/Documentation/filesystems/devfs/README
--- v2.4.5/linux/Documentation/filesystems/devfs/README	Wed Nov 29 10:11:38 2000
+++ linux/Documentation/filesystems/devfs/README	Tue Jun 12 10:57:46 2001
@@ -3,7 +3,7 @@
 
 Linux Devfs (Device File System) FAQ
 Richard Gooch
-3-JUL-2000
+26-APR-2001
 
 -----------------------------------------------------------------------------
 
@@ -18,7 +18,7 @@
 
 http://www.atnf.csiro.au/~rgooch/linux/
 
-NEWFLASH: The official 2.3.46 kernel has
+NEWSFLASH: The official 2.3.46 kernel has
 included the devfs patch. Future patches will be released which
 build on this. These patches are rolled into Linus' tree from time to
 time.
@@ -54,6 +54,7 @@
 Other Issues
 Kernel Naming Scheme
 Devfsd Naming Scheme
+Old Compatibility Names
 SCSI Host Probing Issues
 
 
@@ -99,6 +100,7 @@
 can easily mount the root filesystem by referring to an entry in the
 devfs namespace.
 
+
 The cost of devfs is a small increase in kernel code size and memory
 usage. About 7 pages of code (some of that in __init sections) and 72
 bytes for each entry in the namespace. A modest system has only a
@@ -157,6 +159,7 @@
 of nodes. This means that changes in the kernel must be reflected by
 changes in the MAKEDEV programme, or else the system administrator
 creates device nodes by hand.
+
 The basic problem is that there are two separate databases of
 major and minor numbers. One is in the kernel and one is in /dev (or
 in a MAKEDEV programme, if you want to look at it that way). This is
@@ -192,6 +195,7 @@
 256 kBytes of /dev inodes, but you could argue that embedded systems
 would have hand-tuned /dev directories. I've had to do just that on my
 embedded systems, but I would rather just leave it to devfs.
+
 Another issue is the time taken to lookup an inode when first
 referenced. Not only does this take time in scanning through a list in
 memory, but also the seek times to read the inodes off disc.
@@ -212,7 +216,7 @@
 likely be implemented in an ad-hoc fashion, as different drivers will
 provide their information in different ways.
 
-Devfs is much cleaner, because it (natually) has a uniform mechanism
+Devfs is much cleaner, because it (naturally) has a uniform mechanism
 to provide this information: the device nodes themselves!
 
 
@@ -253,7 +257,7 @@
 But why do that search at all if you don't have to? Once again, it
 seems pointless.
 
-Note thate devfs doesn't use the major&minor system. For devfs
+Note that devfs doesn't use the major&minor system. For devfs
 entries, the connection is done when you lookup the /dev entry. When
 devfs_register() is called, an internal table is appended which has
 the entry name and the file_operations. If the dentry cache doesn't
@@ -274,9 +278,9 @@
 /dev as a system administration tool
 
 Right now /dev contains a list of conceivable devices, most of which I
-don't have. A devfs would only show those devices available on my
-system. This means that listing /dev would be a handy way of checking
-what devices were available.
+don't have. Devfs only shows those devices available on my
+system. This means that listing /dev is a handy way of checking what
+devices are available.
 
 Major&minor size
 
@@ -289,9 +293,9 @@
 each device entry, which can be used to give an effective 32 bit
 device identifier (i.e. that's like having a 32 bit minor
 number). Since this is private to the kernel, there are no C library
-compatibility which you would have with increasing major and minor
-number sizes. See the section on "Allocation of Device Numbers" for
-details on maintaining compatibility with userspace.
+compatibility issues which you would have with increasing major and
+minor number sizes. See the section on "Allocation of Device Numbers"
+for details on maintaining compatibility with userspace.
 
 Solving this requires a kernel change.
 
@@ -375,9 +379,9 @@
 devfsd on any event, such as registration/unregistration of device
 entries, opening and closing devices, looking up inodes, scanning
 directories and more. This has many possibilities. Some of these are
-already implemented.
+already implemented. See:
+
 
-See: 
 http://www.atnf.csiro.au/~rgooch/linux/
 
 Device entry registration events can be used by devfsd to change
@@ -414,6 +418,7 @@
 requests. Instead of using kmod directly, the event is sent to
 devfsd which can implement an arbitrary authentication before loading
 the module itself.
+
 Inode lookup events can also be used to construct arbitrary
 namespaces, without having to resort to populating devfs with symlinks
 to devices that don't exist.
@@ -447,10 +452,10 @@
 
 Who else does it?
 
-FreeBSD has a devfs implementation. Solaris 2 has a pseudo-devfs
-(something akin to scsidev but for all devices, with some unspecified
-kernel support). BeOS, Plan9 and QNX also have it. SGI's IRIX 6.4 and
-above also have a device filesystem.
+FreeBSD has a devfs implementation. Solaris and AIX each have a
+pseudo-devfs (something akin to scsidev but for all devices, with some
+unspecified kernel support). BeOS, Plan9 and QNX also have it. SGI's
+IRIX 6.4 and above also have a device filesystem.
 
 While we shouldn't just automatically do something because others do
 it, we should not ignore the work of others either. FreeBSD has a lot
@@ -613,6 +618,21 @@
 are problems with dealing with symlinks, I'm suspicious of the level
 of security offered in any case.
 
+A better solution is to install util-linux-2.10.h or later, which
+fixes a bug with ttyname handling in the login programme. Then append
+the following lines to your /etc/securetty file:
+
+vc/1
+vc/2
+vc/3
+vc/4
+vc/5
+vc/6
+vc/7
+vc/8
+
+This will not weaken security.
+
 XFree86
 While not essential, it's probably a good idea to upgrade to XFree86
 4.0, as patches went in to make it more devfs-friendly. If you don't,
@@ -627,17 +647,25 @@
 
  # file classes -- these are regular expressions 
 -<console>=tty[0-9][0-9]* :[0-9]\.[0-9] :[0-9] 
-+<console>=tty[0-9][0-9]* [0-9][0-9]* :[0-9]\.[0-9] :[0-9] 
++<console>=tty[0-9][0-9]* vc/[0-9][0-9]* :[0-9]\.[0-9] :[0-9] 
 
  # device classes -- these are shell-style globs 
  <floppy>=/dev/fd[0-1]* 
 
+If the patch does not apply, then change the line:
+
+<console>=tty[0-9][0-9]* :[0-9]\.[0-9] :[0-9]
+
+with:
+
+<console>=tty[0-9][0-9]* vc/[0-9][0-9]* :[0-9]\.[0-9] :[0-9]
+
 
 Disable devpts
 I've had a report of devpts mounted on /dev/pts not working
 correctly. Since devfs will also manage /dev/pts, there is no
 need to mount devpts as well. You should either edit your
-/etc/fstab so devpts is not mounted, or disable devfs from
+/etc/fstab so devpts is not mounted, or disable devpts from
 your kernel configuration.
 
 Unsupported drivers
@@ -664,15 +692,23 @@
 
 The Kernel
 Finally, you need to make sure devfs is compiled into your
-kernel. Set CONFIG_DEVFS_FS=y and recompile your kernel. Next, you
-need to make sure devfs is mounted. The best solution is to pass
-devfs=mount at the kernel boot command line. You can edit
-/etc/lilo.conf and add the line:
-
-append = "devfs=mount"
+kernel. Set CONFIG_DEVFS_FS=y and CONFIG_DEVFS_MOUNT=y and recompile
+your kernel. At boot, devfs will be mounted onto /dev.
 
-
-This will make the kernel mount devfs at boot time onto /dev.
+If you encounter problems booting (for example if you forgot a
+configuration step), you can pass devfs=nomount at the kernel
+boot command line. This will prevent the kernel from mounting devfs at
+boot time onto /dev.
+
+In general, a kernel built with CONFIG_DEVFS_FS=y but without mounting
+devfs onto /dev is completely safe, and requires no
+configuration changes. One exception to take note of is when
+LABEL= directives are used in /etc/fstab. In this
+case you will be unable to boot properly. This is because the
+mount(8) programme uses /proc/partitions as part of
+the volume label search process, and the device names it finds are not
+available, because setting CONFIG_DEVFS_FS=y changes the names in
+/proc/partitions, irrespective of whether devfs is mounted.
 
 Now you've finished all the steps required. You're now ready to boot
 your shiny new kernel. Enjoy.
@@ -701,7 +737,7 @@
 permissions. It may be configured to record changes in permissions and
 will save them in a database (in fact a directory tree), and restore
 these upon boot. This is an efficient method and results in immediate
-saving of current permissions (unlike the tar approach, which save
+saving of current permissions (unlike the tar approach, which saves
 permissions at some unspecified future time).
 
 The default configuration file supplied with devfsd has config entries
@@ -745,8 +781,11 @@
 
 
 
+
 add the following lines to your /etc/devfsd.conf file:
 
+REGISTER	^pt[sy]/.*	IGNORE
+CHANGE		^pt[sy]/.*	IGNORE
 REGISTER	.*		COPY	/dev-state/$devname $devpath
 CHANGE		.*		COPY	$devpath /dev-state/$devname
 CREATE		.*		COPY	$devpath /dev-state/$devname
@@ -758,6 +797,17 @@
 
 
 
+Permissions database stored in normal directory
+
+If you are using an older kernel which doesn't support VFS binding,
+then you won't be able to have the permissions database in a
+mounted-over /dev. However, you can still use a regular
+directory to store the database. The sample /etc/devfsd.conf
+file above may still be used. You will need to create the
+/dev-state directory prior to installing devfsd. If you have
+old permissions in /dev, then just copy the device nodes over
+to the new directory.
+
 
 Dealing with drivers without devfs support
 
@@ -910,13 +960,48 @@
 configuration file is installed, which is used by the MODLOAD
 action. This should be sufficient for most configurations. If you
 require further configuration, edit your /etc/modules.conf
-file.
+file. The way module autoloading work with devfs is:
+
+
+a process attempts to lookup a device node (e.g. /dev/fred)
+
+
+if that device node does not exist, the full pathname is passed to
+devfsd as a string
+
+
+devfsd will pass the string to the modprobe programme (provided the
+configuration line shown above is present), and specifies that
+/etc/modules.devfs is the configuration file
+
+
+/etc/modules.devfs includes /etc/modules.conf to
+access local configurations
+
+modprobe will search it's configuration files, looking for an alias
+that translates the pathname into a module name
+
+
+the translated pathname is then used to load the module.
+
+
+If you wanted a lookup of /dev/fred to load the
+mymod module, you would require the following configuration
+line in /etc/modules.conf:
+
+alias    /dev/fred    mymod
+
+The /etc/modules.devfs configuration file provides many such
+aliases for standard device names. If you look closely at this file,
+you will note that some modules require multiple alias configuration
+lines. This is required to support module autoloading for old and new
+device names.
 
 Mounting root off a devfs device
 If you wish to mount root off a devfs device when you pass the
-"devfs=only" boot option, then you need to pass in the "root="
-option to the kernel when booting. If you use LILO, then you must have
-this in lilo.conf:
+"devfs=only" boot option, then you need to pass in the
+"root=<device>" option to the kernel when booting. If you use
+LILO, then you must have this in lilo.conf:
 
 append = "root=<device>"
 
@@ -926,12 +1011,12 @@
 root = <device>
 
 
-then LILO will determine the device number of  and will write
-that device number into a special place in the kernel image before
-starting the kernel, and the kernel will use that device number to
-mount the root filesystem. So, using the "append" variety ensures that
-LILO passes the root filesystem device as a string, which devfs can
-then use.
+then LILO will determine the device number of <device> and will
+write that device number into a special place in the kernel image
+before starting the kernel, and the kernel will use that device number
+to mount the root filesystem. So, using the "append" variety ensures
+that LILO passes the root filesystem device as a string, which devfs
+can then use.
 
 Note that this isn't an issue if you don't pass "devfs=only".
 
@@ -1067,7 +1152,8 @@
   --------                   --------                   -----------
   /dev/tts/{0,1,...}         /dev/ttyS{0,1,...}         Serial ports
   /dev/cua/{0,1,...}         /dev/cua{0,1,...}          Call out devices
-  /dev/vc/{0,1,...}          /dev/tty{1...63}           Virtual consoles
+  /dev/vc/0                  /dev/tty                   Current virtual console
+  /dev/vc/{1,2,...}          /dev/tty{1...63}           Virtual consoles
   /dev/vcc/{0,1,...}         /dev/vcs{1...63}           Virtual consoles
   /dev/pty/m{0,1,...}        /dev/ptyp??                PTY masters
   /dev/pty/s{0,1,...}        /dev/ttyp??                PTY slaves
@@ -1109,7 +1195,8 @@
 cases, the kernel-supplied naming scheme is quite convenient, so
 devfsd does not provide another naming scheme. The convenience names
 that devfsd creates are in fact the same names as the original devfs
-kernel patch created (before Linus mandated the Big Name Change).
+kernel patch created (before Linus mandated the Big Name
+Change). These are referred to as "new compatibility entries".
 
 In order to configure devfsd to create these convenience names, the
 following lines should be placed in your /etc/devfsd.conf:
@@ -1198,6 +1285,24 @@
 would appear as /dev/xd/c0t0.
 
 
+Old Compatibility Names
+
+The old compatibility names are the legacy device names, such as
+/dev/hda, /dev/sda, /dev/rtc and so on.
+Devfsd can be configured to create compatibility symlinks so that you
+may continue to use the old names in your configuration files and so
+that old applications will continue to function correctly.
+
+In order to configure devfsd to create these legacy names, the
+following lines should be placed in your /etc/devfsd.conf:
+
+REGISTER	.*		MKOLDCOMPAT
+UNREGISTER	.*		RMOLDCOMPAT
+
+This will cause devfsd to create (and destroy) symbolic links which
+point to the kernel-supplied names.
+
+
 SCSI Host Probing Issues
 
 Devfs allows you to identify SCSI discs based in part on SCSI host
@@ -1220,14 +1325,15 @@
 
 means that devices connected to
 
-- first aha1542 controller   - will be c0b#t#u#
-- first parallel port ZIP    - will be c1b#t#u#
-- second aha1542 controller  - will be c2b#t#u#
-- first NCR53C7xx controller - will be c4b#t#u#
-- any extra controller       - will be c5b#t#u#, c6b#t#u#, etc
+- first aha1542 controller   - will be /dev/scsi/host0/bus#/target#/lun#
+- first parallel port ZIP    - will be /dev/scsi/host1/bus#/target#/lun#
+- second aha1542 controller  - will be /dev/scsi/host2/bus#/target#/lun#
+- first NCR53C7xx controller - will be /dev/scsi/host4/bus#/target#/lun#
+- any extra controller       - will be /dev/scsi/host5/bus#/target#/lun#,
+                                       /dev/scsi/host6/bus#/target#/lun#, etc
 - if any of above controllers will not be found - the reserved names will
   not be used by any other device.
-- c3b#t#u# names will never be used
+- /dev/scsi/host3/bus#/target#/lun# names will never be used
 
 
 You can use ',' instead of ':' as the separator character if you
@@ -1343,6 +1449,7 @@
 
 Making things work
 Alternatives to devfs
+What I don't like about devfs
 
 
 
@@ -1518,6 +1625,54 @@
 
 
 
+
+What I don't like about devfs
+
+Here are some common complaints about devfs, and some suggestions and
+solutions that may make it more palatable for you. I can't please
+everybody, but I do try :-)
+
+I hate the naming scheme
+
+First, remember that no naming scheme will please everybody. You hate
+the scheme, others love it. Who's to say who's right and who's wrong?
+Ultimately, the person who writes the code gets to choose, and what
+exists now is a combination of the the choices made by the
+devfs author and the
+kernel maintainer (Linus).
+
+However, not all is lost. If you want to create your own naming
+scheme, it is a simple matter to write a standalone script, hack
+devfsd, or write a script called by devfsd. You can create whatever
+naming scheme you like.
+
+Further, if you want to remove all traces of the devfs naming scheme
+from /dev, you can mount devfs elsewhere (say
+/devfs) and populate /dev with links into
+/devfs. This population can be automated using devfsd if you
+wish.
+
+You can even use the VFS binding facility to make the links, rather
+than using symbolic links. This way, you don't even have to see the
+"destination" of these symbolic links.
+
+Devfs puts policy into the kernel
+
+There's already policy in the kernel. Device numbers are in fact
+policy (why should the kernel dictate what device numbers I use?).
+Face it, some policy has to be in the kernel. The real difference
+between device names as policy and device numbers as policy is that
+no one will use device numbers directly, because device
+numbers are devoid of meaning to humans and are ugly. At least with
+the devfs device names, (even though you can add your own naming
+scheme) some people will use the devfs-supplied names directly. This
+offends some people :-)
+
+Devfs is bloatware
+
+This is not even remotely true. As shown above,
+both code and data size are quite modest.
+
 -----------------------------------------------------------------------------
 
 
@@ -1550,6 +1705,14 @@
 
 http://johannes.erdfelt.com/hotswap.txt.
 Johannes has promised a HTML version will follow.
+
+
+I presented an invited 
+paper
+at the
+
+2nd Annual Storage Management Workshop held in Miamia, Florida,
+U.S.A. in October 2000.
 
 
 
diff -u --recursive --new-file v2.4.5/linux/Documentation/filesystems/hpfs.txt linux/Documentation/filesystems/hpfs.txt
--- v2.4.5/linux/Documentation/filesystems/hpfs.txt	Fri Jul 28 12:50:51 2000
+++ linux/Documentation/filesystems/hpfs.txt	Mon Jun 11 19:15:27 2001
@@ -1,5 +1,5 @@
-Read/Write HPFS 2.00
-1998-1999, Mikulas Patocka
+Read/Write HPFS 2.05
+1998-2001, Mikulas Patocka
 
 email: mikulas@artax.karlin.mff.cuni.cz
 homepage: http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi
@@ -269,6 +269,20 @@
      Removed a lot of redundant code
 2.00 Fixed a bug in rename (it was there since 1.96)
      Better anti-fragmentation strategy
+2.01 Fixed problem with directory listing over NFS
+     Directory lseek now checks for proper parameters
+     Fixed race-condition in buffer code - it is in all filesystems in Linux;
+        when reading device (cat /dev/hda) while creating files on it, files
+        could be damaged
+2.02 Woraround for bug in breada in Linux. breada could cause accesses beyond
+        end of partition
+2.03 Char, block devices and pipes are correctly created
+     Fixed non-crashing race in unlink (Alexander Viro)
+     Now it works with Japanese version of OS/2
+2.04 Fixed error when ftruncate used to extend file
+2.05 Fixed crash when got mount parameters without =
+     Fixed crash when allocation of anode failed due to full disk
+     Fixed some crashes when block io or inode allocation failed
 
 
  vim: set textwidth=80:
diff -u --recursive --new-file v2.4.5/linux/Documentation/filesystems/udf.txt linux/Documentation/filesystems/udf.txt
--- v2.4.5/linux/Documentation/filesystems/udf.txt	Thu Mar  2 11:17:32 2000
+++ linux/Documentation/filesystems/udf.txt	Mon Jun 11 19:15:27 2001
@@ -1,10 +1,10 @@
 *
 * ./Documentation/filesystems/udf.txt
 *
-UDF Filesystem version 0.9.1
+UDF Filesystem version 0.9.4
 
 If you encounter problems with reading UDF discs using this driver,
-please report them to linux_udf@hootie.lvld.hp.com, which is the
+please report them to linux_udf@hpesjro.fc.hp.com, which is the
 developer's list.
 
 Write support requires a block driver which supports writing. The current
@@ -23,7 +23,8 @@
 	noadinicb	Don't embed data in the inode
 	shortad		Use short ad's
 	longad		Use long ad's (default)
-	strict		Set strict conformance (unused)
+	strict		Set strict conformance
+	iocharset=	Set the NLS character set
 
 The remaining are for debugging and disaster recovery:
 
diff -u --recursive --new-file v2.4.5/linux/Documentation/java.txt linux/Documentation/java.txt
--- v2.4.5/linux/Documentation/java.txt	Thu Jul  1 10:47:08 1999
+++ linux/Documentation/java.txt	Wed Jun 27 13:52:16 2001
@@ -1,4 +1,4 @@
-               Java(tm) Binary Kernel Support for Linux v1.02
+               Java(tm) Binary Kernel Support for Linux v1.03
                ----------------------------------------------
 
 Linux beats them ALL! While all other OS's are TALKING about direct
@@ -30,6 +30,8 @@
    (you should really have read binfmt_misc.txt now):
    support for Java applications:
      ':Java:M::\xca\xfe\xba\xbe::/usr/local/bin/javawrapper:'
+   support for executable Jar files:
+     ':ExecutableJAR:E::jar::/usr/local/bin/jarwrapper:'
    support for Java Applets:
      ':Applet:E::html::/usr/bin/appletviewer:'
    or the following, if you want to be more selective:
@@ -343,7 +345,15 @@
 ====================== Cut here ===================
 
 
-Now simply chmod +x the .class and/or .html files you want to execute.
+====================== Cut here ===================
+#!/bin/bash
+# /usr/local/java/bin/jarwrapper - the wrapper for binfmt_misc/jar
+
+java -jar $1
+====================== Cut here ===================
+
+
+Now simply chmod +x the .class, .jar and/or .html files you want to execute.
 To add a Java program to your path best put a symbolic link to the main
 .class file into /usr/bin (or another place you like) omitting the .class
 extension. The directory containing the original .class file will be
@@ -369,6 +379,11 @@
 	./HelloWorld.class
 
 
+To execute Java Jar files, simple chmod the *.jar files to include
+the execution bit, then just do
+       ./Application.jar
+
+
 To execute Java Applets, simple chmod the *.html files to include
 the execution bit, then just do
 	./Applet.html
@@ -376,5 +391,6 @@
 
 originally by Brian A. Lantz, brian@lantz.com
 heavily edited for binfmt_misc by Richard Günther
-new scripts by Colin J. Watson <cjw44@cam.ac.uk>.
+new scripts by Colin J. Watson <cjw44@cam.ac.uk>
+added executable Jar file support by Kurt Huwig <kurt@iku-netz.de>
 
diff -u --recursive --new-file v2.4.5/linux/Documentation/kernel-parameters.txt linux/Documentation/kernel-parameters.txt
--- v2.4.5/linux/Documentation/kernel-parameters.txt	Wed Apr 18 11:49:11 2001
+++ linux/Documentation/kernel-parameters.txt	Wed Jun 20 11:21:33 2001
@@ -455,6 +455,10 @@
 		lastbus=N		[IA-32] Scan all buses till bus #N. Can be useful
 					if the kernel is unable to find your secondary buses
 					and you want to tell it explicitly which ones they are.
+		assign-busses		[IA-32] Always assign all PCI bus
+					numbers ourselves, overriding
+					whatever the firmware may have
+					done.
 
 	pd.		[PARIDE]
 
diff -u --recursive --new-file v2.4.5/linux/Documentation/networking/TODO linux/Documentation/networking/TODO
--- v2.4.5/linux/Documentation/networking/TODO	Thu Apr 19 13:43:40 2001
+++ linux/Documentation/networking/TODO	Wed Jun 20 11:15:44 2001
@@ -14,12 +14,3 @@
 
 * Add ETHTOOL_GDRVINFO ioctl support to all ethernet drivers.
 
-
-
-To-do items to consider for network drivers
--------------------------------------------
-* Make a single function which handles the ethtool ioctl for
-  most MII-compatible devices?  Ideally the driver would pass function
-  pointers to its existing mdio_{read,write} functions when calling the
-  generic ioctl handler.
-
diff -u --recursive --new-file v2.4.5/linux/Documentation/networking/vortex.txt linux/Documentation/networking/vortex.txt
--- v2.4.5/linux/Documentation/networking/vortex.txt	Tue Mar  6 19:13:51 2001
+++ linux/Documentation/networking/vortex.txt	Wed Jun 20 11:15:44 2001
@@ -230,6 +230,23 @@
 other media types does not occur.
 
 
+Transmit error, Tx status register 82
+-------------------------------------
+
+This is a common error which is almost always caused by another host on
+the same network being in full-duplex mode, while this host is in
+half-duplex mode.  You need to find that other host and make it run in
+half-duplex mode or fix this host to run in full-duplex mode.
+
+As a last resort, you can force the 3c59x driver into full-duplex mode
+with
+
+	options 3c59x full_duplex=1
+
+but this has to be viewed as a workaround for broken network gear and
+should only really be used for equipment which cannot autonegotiate.
+
+
 Additional resources
 --------------------
 
diff -u --recursive --new-file v2.4.5/linux/Documentation/sound/README.OSS linux/Documentation/sound/README.OSS
--- v2.4.5/linux/Documentation/sound/README.OSS	Wed Apr 11 19:02:27 2001
+++ linux/Documentation/sound/README.OSS	Tue Jun 12 10:56:11 2001
@@ -17,7 +17,7 @@
 document can be still interesting and very helpful.
 
 [ File edited 17.01.1999 - Riccardo Facchetti ]
-[ Edited miroSOUND section 17.09.2000 - Robert Siemer ]
+[ Edited miroSOUND section 19.04.2001 - Robert Siemer ]
 
 OSS/Free version 3.8 release notes
 ----------------------------------
@@ -1327,7 +1327,7 @@
 ---------
 
 The miroSOUND PCM1-pro, PCM12 and PCM20 radio has been used
-successfully. This card is based on the MAD16, OPL4, and CS4231A chips
+successfully. These cards are based on the MAD16, OPL4, and CS4231A chips
 and everything said in the section about MAD16 cards applies here,
 too. The only major difference between the PCMxx and other MAD16 cards
 is that instead of the mixer in the CS4231 codec a separate mixer
@@ -1337,8 +1337,8 @@
 you compile this ACI driver together with the normal MAD16 support
 when you use a miroSOUND PCMxx card. The ACI mixer is controlled by
 /dev/mixer and the CS4231 mixer by /dev/mixer1 (depends on load
-time). Only in special cases you want to change something on the CS4231
-mixer.
+time). Only in special cases you want to change something regularly on
+the CS4231 mixer.
 
 The miroSOUND PCM12 and PCM20 radio is capable of full duplex
 operation (simultaneous PCM replay and recording), which allows you to
@@ -1354,10 +1354,9 @@
 miropcm20.o module. Also the 7-band equalizer is integrated
 (limited by the OSS-design). Developement has started and maybe
 finished for the RDS decoder on this card, too. You will be able to
-read radio text, the program service name, program type and
+read RadioText, the Programme Service name, Programme TYpe and
 others. Even the v4l radio module benefits from it with a refined
-strength value. See aci.c, radio-miropcm20.c and rds-miropcm20.c for
-more details.
+strength value. See aci.[ch] and miropcm20*.[ch] for more details.
 
 The following configuration parameters have worked fine for the PCM12
 in Markus Kuhn's system, many other configurations might work, too:
diff -u --recursive --new-file v2.4.5/linux/Documentation/usb/se401.txt linux/Documentation/usb/se401.txt
--- v2.4.5/linux/Documentation/usb/se401.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/usb/se401.txt	Wed Jun 27 13:59:32 2001
@@ -0,0 +1,54 @@
+Linux driver for SE401 based USB cameras
+
+Copyright, 2001, Jeroen Vreeken
+
+
+INTRODUCTION:
+
+The SE401 chip is the used in low-cost usb webcams.
+It is produced by Endpoints Inc. (www.endpoints.com).
+It interfaces directly to a cmos image sensor and USB. The only other major
+part in a se401 based camera is a dram chip.
+
+The following cameras are known to work with this driver:
+
+Aox se401 (non-branded) cameras
+Philips PVCV665 USB VGA webcam 'Vesta Fun'
+Kensington VideoCAM PC Camera Model 67014
+Kensington VideoCAM PC Camera Model 67015
+Kensington VideoCAM PC Camera Model 67016
+Kensington VideoCAM PC Camera Model 67017
+
+
+WHAT YOU NEED:
+
+-	USB support
+-	VIDEO4LINUX support
+
+More information about USB support for linux can be found at:
+http://www.linux-usb.org
+
+
+MODULE OPTIONS:
+
+When the driver is compiled as a module you can also use the 'flickerless'
+option. With it exposure is limited to values that do not interfere with the
+net frequency. Valid options for this option are 0, 50 and 60. (0=disable,
+50=50hz, 60=60hz)
+
+
+KNOWN PROBLEMS:
+
+The driver works fine with the usb-ohci and uhci host controller drivers,
+the default settings also work with usb-uhci. But sending more then one bulk
+transfer at a time with usb-uhci doesn't work yet.
+Users of usb-ohci and uhci can safely enlarge SE401_NUMSBUF in se401.h in
+order to increase the throughput (and thus framerate).
+
+
+HELP:
+
+The latest info on this driver can be found at:
+http://www.chello.nl/~j.vreeken/se401/
+And questions to me can be send to:
+pe1rxq@amsat.org
diff -u --recursive --new-file v2.4.5/linux/Documentation/usb/usb-serial.txt linux/Documentation/usb/usb-serial.txt
--- v2.4.5/linux/Documentation/usb/usb-serial.txt	Mon Mar 19 17:21:54 2001
+++ linux/Documentation/usb/usb-serial.txt	Wed Jun 27 13:59:32 2001
@@ -245,6 +245,17 @@
        Edgeport/16 Dual
 
 
+REINER SCT cyberJack pinpad/e-com USB chipcard reader
+   
+  Interface to ISO 7816 compatible contactbased chipcards, e.g. GSM SIMs.
+  
+Current status:
+  This is the kernel part of the driver for this USB card reader.
+  There is also a user part for a CT-API driver available. A site
+  for downloading is TBA. For now, you can request it from the
+  maintainer (linux-usb@sii.li).
+
+
 Generic Serial driver
 
   If your device is not one of the above listed devices, compatible with
diff -u --recursive --new-file v2.4.5/linux/MAINTAINERS linux/MAINTAINERS
--- v2.4.5/linux/MAINTAINERS	Sun May 20 12:11:38 2001
+++ linux/MAINTAINERS	Wed Jun 27 13:59:32 2001
@@ -231,7 +231,7 @@
 CIRRUS LOGIC GENERIC FBDEV DRIVER
 P:	Jeff Garzik
 M:	jgarzik@mandrakesoft.com
-L:	linux-fbdev@vuser.vu.union.edu
+L:	linux-fbdev-devel@lists.sourceforge.net
 S:	Odd Fixes
 
 CIRRUS LOGIC CS4280/CS461x SOUNDDRIVER
@@ -712,16 +712,11 @@
 M:	perex@suse.cz
 S:	Maintained
 
-ISDN SUBSYSTEM (general)
-P:	Fritz Elfert
-M:	fritz@isdn4linux.de
-L:	isdn4linux@listserv.isdn4linux.de
-W:	http://www.isdn4linux.de
-S:	Maintained
-
-ISDN SUBSYSTEM (card drivers)
+ISDN SUBSYSTEM
 P:	Karsten Keil
 M:	kkeil@suse.de
+P:	Kai Germaschewski
+M:	kai.germaschewski@gmx.de
 L:	isdn4linux@listserv.isdn4linux.de
 W:	http://www.isdn4linux.de
 S:	Maintained
@@ -764,8 +759,8 @@
 M:	kaos@ocs.com.au
 P:	Michael Elizabeth Chastain
 M:	mec@shout.net
-L:	linux-kbuild@torque.net
-W:	http://www.kernel.org/pub/linux/kernel/projects/kbuild/
+L:	kbuild-devel@lists.sourceforge.net
+W:	http://kbuild.sourceforge.net
 S:	Maintained 
 
 KERNEL NFSD
@@ -789,24 +784,30 @@
 L:	linux-x25@vger.kernel.org
 S:	Maintained
 
+LINUX FOR IBM pSERIES (RS/6000)
+P:	Paul Mackerras
+M:	paulus@au.ibm.com
+W:	http://www.ibm.com/linux/ltc/projects/ppc
+S:	Supported
+
 LINUX FOR POWERPC
-P:	Cort Dougan
-M:	cort@fsmlabs.com
+P:	Paul Mackerras
+M:	paulus@samba.org
 W:	http://www.fsmlabs.com/linuxppcbk.html
-S:	Maintained
+S:	Supported
 
 LINUX FOR POWER MACINTOSH
-P:	Paul Mackerras
-M:	paulus@samba.org
+P:	Benjamin Herrenschmidt
+M:	benh@kernel.crashing.org
 W:	http://www.linuxppc.org/
 L:	linuxppc-dev@lists.linuxppc.org
 S:	Maintained
 
 LOGICAL VOLUME MANAGER
 P:     Heinz Mauelshagen
-M:     linux-LVM@EZ-Darmstadt.Telekom.de
-L:     linux-LVM@msede.com
-W:     http://linux.msede.com/lvm
+M:     mge@sistina.de
+L:     linux-LVM@sistina.com
+W:     http://www.sistina.com/lvm
 S:     Maintained 
 
 M68K
@@ -1087,9 +1088,9 @@
 S:	Maintained
 
 RAGE128 FRAMEBUFFER DISPLAY DRIVER
-P:	Brad Douglas
-M:	brad@neruo.com
-L:	linux-fbdev@vuser.vu.union.edu
+P:	Ani Joshi
+M:	ajoshi@shell.unixbox.com
+L:	linux-fbdev-devel@lists.sourceforge.net
 S:	Maintained
 
 RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER
@@ -1169,7 +1170,7 @@
 S:	Unmaintained
 
 SCSI TAPE DRIVER
-P:	Kai Mdkisara
+P:	Kai Mäkisara
 M:	Kai.Makisara@metla.fi
 L:	linux-scsi@vger.kernel.org
 S:	Maintained
@@ -1194,12 +1195,6 @@
 L:	samba@samba.org
 S:	Maintained
 
-SMP: (except SPARC)
-P:	Linus Torvalds
-M:	torvalds@transmeta.com
-L:	linux-smp@vger.kernel.org
-S:	Maintained
-
 SOFTWARE RAID (Multiple Disks) SUPPORT
 P:	Ingo Molnar
 M:	mingo@redhat.com
@@ -1347,8 +1342,8 @@
 M:	bfennema@falcon.csc.calpoly.edu
 P:	Dave Boynton
 M:	dave@trylinux.com
-L:	linux_udf@hootie.lvld.hp.com
-W:	http://www.trylinux.com/projects/udf/index.html
+L:	linux_udf@hpesjro.fc.hp.com
+W:	http://linux-udf.sourceforge.net
 S:	Maintained
 
 UMSDOS FILESYSTEM
@@ -1473,6 +1468,12 @@
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
 
+USB SERIAL CYBERJACK PINPAD/E-COM DRIVER
+M:  linux-usb@sii.li
+L:  linux-usb-users@lists.sourceforge.net
+L:  linux-usb-devel@lists.sourceforge.net
+S:  Supported
+
 USB MASS STORAGE DRIVER
 P:	Matthew Dharm
 M:	mdharm-usb@one-eyed-alien.net
@@ -1571,6 +1572,12 @@
 M:	middelin@polyware.nl
 W:	http://www.polyware.nl/~middelin/En/hobbies.html
 W:	http://www.polyware.nl/~middelin/hobbies.html
+S:	Maintained
+
+Bluetooth Subsystem (BlueZ)
+P:	Maxim Krasnyansky
+M:	maxk@qualcomm.com
+W:	http://bluez.sf.net
 S:	Maintained
 
 THE REST
diff -u --recursive --new-file v2.4.5/linux/Makefile linux/Makefile
--- v2.4.5/linux/Makefile	Fri May 25 09:51:33 2001
+++ linux/Makefile	Sun Jun 24 20:53:07 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
-SUBLEVEL = 5
-EXTRAVERSION =
+SUBLEVEL = 6
+EXTRAVERSION =-pre6
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -87,7 +87,8 @@
 
 CPPFLAGS := -D__KERNEL__ -I$(HPATH)
 
-CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing
+CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
+          -fomit-frame-pointer -fno-strict-aliasing
 AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS)
 
 #
@@ -127,6 +128,7 @@
 DRIVERS-m :=
 DRIVERS-  :=
 
+DRIVERS-$(CONFIG_ACPI) += drivers/acpi/acpi.o
 DRIVERS-$(CONFIG_PARPORT) += drivers/parport/driver.o
 DRIVERS-y += drivers/char/char.o \
 	drivers/block/block.o \
@@ -155,7 +157,8 @@
 DRIVERS-$(CONFIG_PCI) += drivers/pci/driver.o
 DRIVERS-$(CONFIG_MTD) += drivers/mtd/mtdlink.o
 DRIVERS-$(CONFIG_PCMCIA) += drivers/pcmcia/pcmcia.o
-DRIVERS-$(CONFIG_PCMCIA_NETCARD) += drivers/net/pcmcia/pcmcia_net.o
+DRIVERS-$(CONFIG_NET_PCMCIA) += drivers/net/pcmcia/pcmcia_net.o
+DRIVERS-$(CONFIG_NET_WIRELESS) += drivers/net/wireless/wireless_net.o
 DRIVERS-$(CONFIG_PCMCIA_CHRDEV) += drivers/char/pcmcia/pcmcia_char.o
 DRIVERS-$(CONFIG_DIO) += drivers/dio/dio.a
 DRIVERS-$(CONFIG_SBUS) += drivers/sbus/sbus_all.o
@@ -175,8 +178,8 @@
 DRIVERS-$(CONFIG_IRDA) += drivers/net/irda/irda.o
 DRIVERS-$(CONFIG_I2C) += drivers/i2c/i2c.o
 DRIVERS-$(CONFIG_PHONE) += drivers/telephony/telephony.o
-DRIVERS-$(CONFIG_ACPI) += drivers/acpi/acpi.o
 DRIVERS-$(CONFIG_MD) += drivers/md/mddev.o
+DRIVERS-$(CONFIG_BLUEZ) += drivers/bluetooth/bluetooth.o
 
 DRIVERS := $(DRIVERS-y)
 
diff -u --recursive --new-file v2.4.5/linux/arch/alpha/config.in linux/arch/alpha/config.in
--- v2.4.5/linux/arch/alpha/config.in	Fri May 25 09:55:36 2001
+++ linux/arch/alpha/config.in	Mon Jun 11 19:15:27 2001
@@ -348,6 +348,10 @@
 source drivers/usb/Config.in
 source drivers/input/Config.in
 
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   source net/bluetooth/Config.in
+fi
+
 mainmenu_option next_comment
 comment 'Kernel hacking'
 
diff -u --recursive --new-file v2.4.5/linux/arch/alpha/kernel/alpha_ksyms.c linux/arch/alpha/kernel/alpha_ksyms.c
--- v2.4.5/linux/arch/alpha/kernel/alpha_ksyms.c	Fri May 25 09:54:50 2001
+++ linux/arch/alpha/kernel/alpha_ksyms.c	Wed Jun 20 11:10:27 2001
@@ -16,6 +16,7 @@
 #include <linux/pci.h>
 #include <linux/tty.h>
 #include <linux/mm.h>
+#include <linux/delay.h>
 
 #include <asm/io.h>
 #include <asm/hwrpb.h>
@@ -100,6 +101,10 @@
 EXPORT_SYMBOL(__constant_c_memset);
 EXPORT_SYMBOL(copy_page);
 EXPORT_SYMBOL(clear_page);
+
+EXPORT_SYMBOL(__delay);
+EXPORT_SYMBOL(__udelay);
+EXPORT_SYMBOL(udelay);
 
 EXPORT_SYMBOL(__direct_map_base);
 EXPORT_SYMBOL(__direct_map_size);
diff -u --recursive --new-file v2.4.5/linux/arch/alpha/kernel/core_tsunami.c linux/arch/alpha/kernel/core_tsunami.c
--- v2.4.5/linux/arch/alpha/kernel/core_tsunami.c	Thu May 24 15:24:37 2001
+++ linux/arch/alpha/kernel/core_tsunami.c	Mon Jun 11 19:15:27 2001
@@ -11,7 +11,6 @@
 #include <linux/pci.h>
 #include <linux/sched.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 
 #include <asm/ptrace.h>
 #include <asm/system.h>
@@ -21,6 +20,8 @@
 #include <asm/io.h>
 #include <asm/core_tsunami.h>
 #undef __EXTERN_INLINE
+
+#include <linux/bootmem.h>
 
 #include "proto.h"
 #include "pci_impl.h"
diff -u --recursive --new-file v2.4.5/linux/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S
--- v2.4.5/linux/arch/alpha/kernel/entry.S	Thu May 24 15:20:18 2001
+++ linux/arch/alpha/kernel/entry.S	Mon Jun 11 19:15:27 2001
@@ -31,7 +31,7 @@
 #define TASK_STATE		0
 #define TASK_FLAGS		8
 #define TASK_SIGPENDING		16
-#define TASK_ADDR_LIMIT		24	
+#define TASK_ADDR_LIMIT		24
 #define TASK_EXEC_DOMAIN	32
 #define TASK_NEED_RESCHED	40
 #define TASK_PTRACE		48
@@ -576,13 +576,15 @@
 .align 3
 ret_from_sys_call:
 	cmovne	$26,0,$19		/* $19 = 0 => non-restartable */
+#ifdef CONFIG_SMP
 	ldl	$3,TASK_PROCESSOR($8)
-	lda	$4,irq_stat		/* softirq_active */
 	sll	$3,L1_CACHE_SHIFT,$3
+#endif
+	lda	$4,irq_stat
+#ifdef CONFIG_SMP
 	addq	$3,$4,$4
-	ldq	$4,0($4)		/* softirq_active[32] + softirq_mask[32] */
-	sll	$4,32,$3
-	and	$4,$3,$4
+#endif
+	ldq	$4,0($4)		/* __softirq_pending */
 	bne	$4,handle_softirq
 ret_from_softirq:
 	ldq	$0,SP_OFF($30)
diff -u --recursive --new-file v2.4.5/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c
--- v2.4.5/linux/arch/alpha/kernel/irq.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/alpha/kernel/irq.c	Wed Jun 20 11:10:27 2001
@@ -359,7 +359,9 @@
 static void
 register_irq_proc (unsigned int irq)
 {
+#ifdef CONFIG_SMP
 	struct proc_dir_entry *entry;
+#endif
 	char name [MAX_NAMELEN];
 
 	if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type))
@@ -389,7 +391,9 @@
 void
 init_irq_proc (void)
 {
+#ifdef CONFIG_SMP
 	struct proc_dir_entry *entry;
+#endif
 	int i;
 
 	/* create /proc/irq */
@@ -512,7 +516,10 @@
 int
 get_irq_list(char *buf)
 {
-	int i, j;
+#ifdef CONFIG_SMP
+	int j;
+#endif
+	int i;
 	struct irqaction * action;
 	char *p = buf;
 
@@ -569,7 +576,7 @@
 
 
 /*
- * do_IRQ handles all normal device IRQ's (the special
+ * handle_irq handles all normal device IRQ's (the special
  * SMP cross-CPU interrupts have their own specific
  * handlers).
  */
@@ -632,7 +639,7 @@
 	/*
 	 * Edge triggered interrupts need to remember pending events.
 	 * This applies to any hw interrupts that allow a second
-	 * instance of the same irq to arrive while we are in do_IRQ
+	 * instance of the same irq to arrive while we are in handle_irq
 	 * or in the handler. But the code here only handles the _second_
 	 * instance of the irq, not the third or fourth. So it is mostly
 	 * useful for irq hardware that does not mask cleanly in an
@@ -656,6 +663,9 @@
 	 */
 	desc->handler->end(irq);
 	spin_unlock(&desc->lock);
+
+	if (softirq_pending(cpu))
+		do_softirq();
 }
 
 /*
diff -u --recursive --new-file v2.4.5/linux/arch/alpha/kernel/osf_sys.c linux/arch/alpha/kernel/osf_sys.c
--- v2.4.5/linux/arch/alpha/kernel/osf_sys.c	Mon Mar 19 12:35:09 2001
+++ linux/arch/alpha/kernel/osf_sys.c	Tue Jun 12 10:26:14 2001
@@ -44,7 +44,6 @@
 
 extern int do_pipe(int *);
 
-extern asmlinkage int sys_swapon(const char *specialfile, int swap_flags);
 extern asmlinkage unsigned long sys_brk(unsigned long);
 
 /*
diff -u --recursive --new-file v2.4.5/linux/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c
--- v2.4.5/linux/arch/alpha/kernel/process.c	Thu May 24 15:20:18 2001
+++ linux/arch/alpha/kernel/process.c	Wed Jun 20 11:10:27 2001
@@ -28,6 +28,7 @@
 #include <linux/mman.h>
 #include <linux/elfcore.h>
 #include <linux/reboot.h>
+#include <linux/tty.h>
 #include <linux/console.h>
 
 #include <asm/reg.h>
diff -u --recursive --new-file v2.4.5/linux/arch/alpha/kernel/smp.c linux/arch/alpha/kernel/smp.c
--- v2.4.5/linux/arch/alpha/kernel/smp.c	Thu May 24 15:24:37 2001
+++ linux/arch/alpha/kernel/smp.c	Mon Jun 11 19:15:27 2001
@@ -682,6 +682,9 @@
 
 		data->prof_counter = data->prof_multiplier;
 		irq_exit(cpu, RTC_IRQ);
+
+		if (softirq_pending(cpu))
+			do_softirq();
 	}
 }
 
diff -u --recursive --new-file v2.4.5/linux/arch/alpha/kernel/sys_alcor.c linux/arch/alpha/kernel/sys_alcor.c
--- v2.4.5/linux/arch/alpha/kernel/sys_alcor.c	Fri Oct 27 10:55:01 2000
+++ linux/arch/alpha/kernel/sys_alcor.c	Wed Jun 27 16:18:13 2001
@@ -15,6 +15,7 @@
 #include <linux/sched.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/reboot.h>
 
 #include <asm/ptrace.h>
 #include <asm/system.h>
@@ -219,11 +220,21 @@
 static void
 alcor_kill_arch(int mode)
 {
-	/* Who said DEC engineer's have no sense of humor? ;-)  */
-	if (alpha_using_srm) {
-		*(vuip) GRU_RESET = 0x0000dead;
-		mb();
+	switch(mode) {
+	case LINUX_REBOOT_CMD_RESTART:
+		/* Who said DEC engineer's have no sense of humor? ;-)  */
+		if (alpha_using_srm) {
+			*(vuip) GRU_RESET = 0x0000dead;
+			mb();
+		}
+		break;
+	case LINUX_REBOOT_CMD_HALT:
+		break;
+	case LINUX_REBOOT_CMD_POWER_OFF:
+		break;
 	}
+
+	halt();
 }
 
 
diff -u --recursive --new-file v2.4.5/linux/arch/alpha/kernel/sys_dp264.c linux/arch/alpha/kernel/sys_dp264.c
--- v2.4.5/linux/arch/alpha/kernel/sys_dp264.c	Fri May 25 09:54:50 2001
+++ linux/arch/alpha/kernel/sys_dp264.c	Mon Jun 11 19:15:27 2001
@@ -16,18 +16,15 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 
-#define __EXTERN_INLINE inline
-#include <asm/io.h>
-#include <asm/core_tsunami.h>
-#undef  __EXTERN_INLINE
-
 #include <asm/ptrace.h>
 #include <asm/system.h>
 #include <asm/dma.h>
 #include <asm/irq.h>
 #include <asm/bitops.h>
 #include <asm/mmu_context.h>
+#include <asm/io.h>
 #include <asm/pgtable.h>
+#include <asm/core_tsunami.h>
 #include <asm/hwrpb.h>
 
 #include "proto.h"
diff -u --recursive --new-file v2.4.5/linux/arch/alpha/kernel/sys_rawhide.c linux/arch/alpha/kernel/sys_rawhide.c
--- v2.4.5/linux/arch/alpha/kernel/sys_rawhide.c	Fri Mar  2 11:12:07 2001
+++ linux/arch/alpha/kernel/sys_rawhide.c	Mon Jun 11 19:15:27 2001
@@ -59,10 +59,11 @@
 	irq -= 16;
 	hose = irq / 24;
 	irq -= hose * 24;
+	mask = 1 << irq;
 
 	spin_lock(&rawhide_irq_lock);
-	mask = cached_irq_masks[hose] |= 1 << irq;
-	mask |= hose_irq_masks[hose];
+	mask |= cached_irq_masks[hose];
+	cached_irq_masks[hose] = mask;
 	rawhide_update_irq_hw(hose, mask);
 	spin_unlock(&rawhide_irq_lock);
 }
@@ -75,14 +76,37 @@
 	irq -= 16;
 	hose = irq / 24;
 	irq -= hose * 24;
+	mask = ~(1 << irq) | hose_irq_masks[hose];
 
 	spin_lock(&rawhide_irq_lock);
-	mask = cached_irq_masks[hose] &= ~(1 << irq);
-	mask |= hose_irq_masks[hose];
+	mask &= cached_irq_masks[hose];
+	cached_irq_masks[hose] = mask;
 	rawhide_update_irq_hw(hose, mask);
 	spin_unlock(&rawhide_irq_lock);
 }
 
+static void
+rawhide_mask_and_ack_irq(unsigned int irq)
+{
+	unsigned int mask, mask1, hose;
+
+	irq -= 16;
+	hose = irq / 24;
+	irq -= hose * 24;
+	mask1 = 1 << irq;
+	mask = ~mask1 | hose_irq_masks[hose];
+
+	spin_lock(&rawhide_irq_lock);
+
+	mask &= cached_irq_masks[hose];
+	cached_irq_masks[hose] = mask;
+	rawhide_update_irq_hw(hose, mask);
+
+	/* Clear the interrupt.  */
+	*(vuip)MCPCIA_INT_REQ(MCPCIA_HOSE2MID(hose)) = mask1;
+
+	spin_unlock(&rawhide_irq_lock);
+}
 
 static unsigned int
 rawhide_startup_irq(unsigned int irq)
@@ -104,7 +128,7 @@
 	shutdown:	rawhide_disable_irq,
 	enable:		rawhide_enable_irq,
 	disable:	rawhide_disable_irq,
-	ack:		rawhide_disable_irq,
+	ack:		rawhide_mask_and_ack_irq,
 	end:		rawhide_end_irq,
 };
 
@@ -145,8 +169,12 @@
 	mcpcia_init_hoses();
 
 	for (hose = hose_head; hose; hose = hose->next) {
-		int h = hose->index;
-		rawhide_update_irq_hw(h, hose_irq_masks[h]);
+		unsigned int h = hose->index;
+		unsigned int mask = hose_irq_masks[h];
+
+		cached_irq_masks[h] = mask;
+		*(vuip)MCPCIA_INT_MASK0(MCPCIA_HOSE2MID(h)) = mask;
+		*(vuip)MCPCIA_INT_MASK1(MCPCIA_HOSE2MID(h)) = 0;
 	}
 
 	for (i = 16; i < 128; ++i) {
diff -u --recursive --new-file v2.4.5/linux/arch/alpha/kernel/sys_sable.c linux/arch/alpha/kernel/sys_sable.c
--- v2.4.5/linux/arch/alpha/kernel/sys_sable.c	Fri Oct 27 10:55:01 2000
+++ linux/arch/alpha/kernel/sys_sable.c	Tue Jun 12 11:44:59 2001
@@ -96,7 +96,7 @@
 static inline void
 sable_update_irq_hw(unsigned long bit, unsigned long mask)
 {
-	int port = 0x536;
+	int port = 0x537;
 
 	if (bit >= 16) {
 		port = 0x53d;
@@ -121,7 +121,7 @@
 	} else if (bit >= 8) {
 		port = 0x53a;
 		val1 = 0xE0 | (bit - 8);
-		val2 = 0xE0 | 2;
+		val2 = 0xE0 | 3;
 	} else {
 		port = 0x536;
 		val1 = 0xE0 | (bit - 0);
diff -u --recursive --new-file v2.4.5/linux/arch/alpha/kernel/sys_sio.c linux/arch/alpha/kernel/sys_sio.c
--- v2.4.5/linux/arch/alpha/kernel/sys_sio.c	Fri Oct 27 10:55:01 2000
+++ linux/arch/alpha/kernel/sys_sio.c	Wed Jun 20 11:10:27 2001
@@ -17,6 +17,7 @@
 #include <linux/sched.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/tty.h>
 
 #include <asm/compiler.h>
 #include <asm/ptrace.h>
diff -u --recursive --new-file v2.4.5/linux/arch/alpha/lib/Makefile linux/arch/alpha/lib/Makefile
--- v2.4.5/linux/arch/alpha/lib/Makefile	Thu Feb  8 12:56:29 2001
+++ linux/arch/alpha/lib/Makefile	Wed Jun 20 11:10:27 2001
@@ -21,6 +21,7 @@
 endif
 
 OBJS =	__divqu.o __remqu.o __divlu.o __remlu.o \
+	udelay.o \
 	$(ev6)memset.o \
 	$(ev6)memcpy.o \
 	memmove.o \
diff -u --recursive --new-file v2.4.5/linux/arch/alpha/lib/udelay.c linux/arch/alpha/lib/udelay.c
--- v2.4.5/linux/arch/alpha/lib/udelay.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/alpha/lib/udelay.c	Wed Jun 20 11:10:27 2001
@@ -0,0 +1,47 @@
+#include <linux/config.h>
+#include <linux/sched.h> /* for udelay's use of smp_processor_id */
+#include <asm/param.h>
+#include <asm/smp.h>
+#include <linux/delay.h>
+
+/*
+ * Copyright (C) 1993, 2000 Linus Torvalds
+ *
+ * Delay routines, using a pre-computed "loops_per_jiffy" value.
+ */
+
+/*
+ * Use only for very small delays (< 1 msec). 
+ *
+ * The active part of our cycle counter is only 32-bits wide, and
+ * we're treating the difference between two marks as signed.  On
+ * a 1GHz box, that's about 2 seconds.
+ */
+
+void __delay(int loops)
+{
+	int tmp;
+	__asm__ __volatile__(
+		"	rpcc %0\n"
+		"	addl %1,%0,%1\n"
+		"1:	rpcc %0\n"
+		"	subl %1,%0,%0\n"
+		"	bgt %0,1b"
+		: "=&r" (tmp), "=r" (loops) : "1"(loops));
+}
+
+void __udelay(unsigned long usecs, unsigned long lpj)
+{
+	usecs *= (((unsigned long)HZ << 32) / 1000000) * lpj;
+	__delay((long)usecs >> 32);
+}
+
+void udelay(unsigned long usecs)
+{
+#ifdef CONFIG_SMP
+	__udelay(usecs, cpu_data[smp_processor_id()].loops_per_jiffy);
+#else
+	__udelay(usecs, loops_per_jiffy);
+#endif
+}
+
diff -u --recursive --new-file v2.4.5/linux/arch/arm/Makefile linux/arch/arm/Makefile
--- v2.4.5/linux/arch/arm/Makefile	Thu Apr 12 12:20:31 2001
+++ linux/arch/arm/Makefile	Wed Jun 27 14:12:04 2001
@@ -26,7 +26,7 @@
 apcs-$(CONFIG_CPU_26)		:=-mcpu=arm3 -Os
 
 arch-y				:=
-arch-$(CONFIG_CPU_32v3)		:=-march=armv3m
+arch-$(CONFIG_CPU_32v3)		:=-march=armv3
 arch-$(CONFIG_CPU_32v4)		:=-march=armv4
 arch-$(CONFIG_CPU_32v5)		:=-march=armv5
 
@@ -123,6 +123,10 @@
 MACHINE		 = clps711x
 endif
 
+ifeq ($(CONFIG_ARCH_ANAKIN),y)
+MACHINE		 = anakin
+endif
+
 export	LIBGCC MACHINE PROCESSOR TEXTADDR GZFLAGS
 
 # Only set INCDIR if its not already defined above
@@ -156,7 +160,7 @@
 LIBS		:= arch/arm/fastfpe/fast-math-emu.o $(LIBS)
 endif
 
-ifeq ($(CONFIG_ARCH_CLPS7500),y)
+ifeq ($(findstring y,$(CONFIG_ARCH_CLPS7500) $(CONFIG_ARCH_L7200)),y)
 SUBDIRS		+= drivers/acorn/char
 DRIVERS		+= drivers/acorn/char/acorn-char.o
 endif
@@ -237,8 +241,8 @@
 	@( \
 	CFG=$(@:_config=); \
 	if [ -f arch/arm/def-configs/$$CFG ]; then \
-	  $(RM) arch/arm/defconfig; \
-	  cp arch/arm/def-configs/$$CFG arch/arm/defconfig; \
+	  [ -f .config ] && $(MV) .config .config.old; \
+	  cp arch/arm/def-configs/$$CFG .config; \
 	  echo "*** Default configuration for $$CFG installed"; \
 	  echo "*** Next, you may run 'make oldconfig'"; \
 	else \
diff -u --recursive --new-file v2.4.5/linux/arch/arm/boot/Makefile linux/arch/arm/boot/Makefile
--- v2.4.5/linux/arch/arm/boot/Makefile	Thu Apr 12 12:03:50 2001
+++ linux/arch/arm/boot/Makefile	Wed Jun 27 14:12:04 2001
@@ -90,9 +90,17 @@
 ifeq ($(CONFIG_SA1100_GRAPHICSCLIENT),y)
   ZTEXTADDR	 = 0xC0200000
 endif
+ifeq ($(CONFIG_SA1100_YOPY),y)
+  ZTEXTADDR      = 0x00080000
+  ZBSSADDR       = 0xc0200000
+endif
 ifeq ($(CONFIG_SA1111),y)
   ZRELADDR	 = 0xc0208000
 endif
+endif
+
+ifeq ($(CONFIG_ARCH_ANAKIN),y)
+ZTEXTADDR	 = 0x20008000
 endif
 
 #
diff -u --recursive --new-file v2.4.5/linux/arch/arm/boot/compressed/Makefile linux/arch/arm/boot/compressed/Makefile
--- v2.4.5/linux/arch/arm/boot/compressed/Makefile	Thu Apr 12 12:03:50 2001
+++ linux/arch/arm/boot/compressed/Makefile	Wed Jun 27 14:12:04 2001
@@ -30,7 +30,7 @@
 endif
 
 ifeq ($(CONFIG_ARCH_INTEGRATOR),y)
-OBJS		+= head-netwinder.o
+OBJS		+= head-integrator.o
 endif
 
 ifeq ($(CONFIG_ARCH_FTVPCI),y)
diff -u --recursive --new-file v2.4.5/linux/arch/arm/boot/compressed/head-integrator.S linux/arch/arm/boot/compressed/head-integrator.S
--- v2.4.5/linux/arch/arm/boot/compressed/head-integrator.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/boot/compressed/head-integrator.S	Wed Jun 27 14:12:04 2001
@@ -0,0 +1,4 @@
+#include <asm/mach-types.h>
+
+		.section	".start", #alloc, #execinstr
+		mov	r7, #MACH_TYPE_INTEGRATOR
diff -u --recursive --new-file v2.4.5/linux/arch/arm/boot/compressed/head.S linux/arch/arm/boot/compressed/head.S
--- v2.4.5/linux/arch/arm/boot/compressed/head.S	Thu Apr 12 12:03:50 2001
+++ linux/arch/arm/boot/compressed/head.S	Wed Jun 27 14:12:04 2001
@@ -12,7 +12,39 @@
 
 /*
  * Debugging stuff
+ *
+ * Note that these macros must not contain any code which is not
+ * 100% relocatable.  Any attempt to do so will result in a crash.
+ * Please select one of the following when turning on debugging.
  */
+#ifdef DEBUG
+#if 0 /* DC21285-type */
+		.macro	loadsp,	rb
+		mov	\rb, #0x7c000000
+		.endm
+		.macro	writeb,	rb
+		strb	\rb, [r3, #0x3f8]
+		.endm
+#elif 0 /* RiscPC-type */
+		.macro	loadsp,	rb
+		mov	\rb, #0x03000000
+		orr	\rb, \rb, #0x00010000
+		.endm
+		.macro	writeb,	rb
+		strb	\rb, [r3, #0x3f8 << 2]
+		.endm
+#elif 0 /* integrator-type */
+		.macro	loadsp, rb
+		mov	\rb, #0x16000000
+		.endm
+		.macro	writeb, rb
+		strb	\rb, [r3, #0]
+		.endm
+#else
+#error no serial architecture defined
+#endif
+#endif
+
 		.macro	kputc,val
 		mov	r0, \val
 		bl	putc
@@ -27,53 +59,31 @@
 		.macro	debug_reloc_start
 #ifdef DEBUG
 		kputc	#'\n'
-		kphex	r6, 8
+		kphex	r6, 8		/* processor id */
 		kputc	#':'
-		kphex	r5, 8
+		kphex	r7, 8		/* architecture id */
+		kputc	#':'
+		mrc	p15, 0, r0, c1, c0
+		kphex	r0, 8		/* control reg
+		kputc	#'\n'
+		kphex	r5, 8		/* decompressed kernel start */
 		kputc	#'-'
-		kphex	r8, 8
+		kphex	r8, 8		/* decompressed kernel end  */
 		kputc	#'>'
-		kphex	r4, 8
+		kphex	r4, 8		/* kernel execution address */
 		kputc	#'\n'
 #endif
 		.endm
 
 		.macro	debug_reloc_end
 #ifdef DEBUG
-		mov	r8, r0
-		kphex	r5, 8
-		kputc	#'-'
-		kphex	r8, 8
+		kphex	r5, 8		/* end of kernel */
 		kputc	#'\n'
 		mov	r0, r4
-		bl	memdump
+		bl	memdump		/* dump 256 bytes at start of kernel */
 #endif
 		.endm
 
-/*
- * Note that these macros must not contain any code which is not
- * 100% relocatable.  Any attempt to do so will result in a crash.
- */
-#if 0
-		.macro	loadsp,	rb
-		mov	\rb, #0x7c000000
-		.endm
-
-		.macro	writeb,	rb
-		strb	\rb, [r3, #0x3f8]
-		.endm
-#else
-		.macro	loadsp,	rb
-		mov	\rb, #0x03000000
-		orr	\rb, \rb, #0x00010000
-		.endm
-
-		.macro	writeb,	rb
-		strb	\rb, [r3, #0x3f8 << 2]
-		.endm
-#endif
-
-
 		.section ".start", #alloc, #execinstr
 /*
  * sort out different calling conventions
@@ -91,14 +101,18 @@
 		.word	_edata			@ zImage end address
 1:		mov	r7, r1			@ save architecture ID
 		mov	r8, #0			@ save r0
-#ifdef CONFIG_ANGELBOOT
+
 		/*
 		 * Booting from Angel - need to enter SVC mode and disable
-		 * FIQs/IRQs (numeric definitions from angel arm.h source)
+		 * FIQs/IRQs (numeric definitions from angel arm.h source).
+		 * We only do this if we were in user mode on entry.
 		 */
+		mrs	r0, cpsr		@ get current mode
+		tst	r0, #3			@ not user?
+		bne	not_angel
 		mov	r0, #0x17		@ angel_SWIreason_EnterSVC
 		swi	0x123456		@ angel_SWI_ARM
-		mrs	r0, cpsr		@ turn off interrupts to
+not_angel:	mrs	r0, cpsr		@ turn off interrupts to
 		orr	r0, r0, #0xc0		@ prevent angel from running
 		msr	cpsr_c, r0
 
@@ -106,7 +120,7 @@
 		 * Note that some cache flushing and other stuff may
 		 * be needed here - is there an Angel SWI call for this?
 		 */
-#endif
+
 		/*
 		 * some architecture specific code can be inserted
 		 * by the linker here, but it should preserve r7 and r8.
@@ -300,30 +314,46 @@
 		.size	proc_sa1110_type, . - proc_sa1110_type
 
 /*
- * Turn off StrongARM cache and MMU.  It is safe to
- * leave the I-cache on.
+ * Turn off the Cache and MMU.  ARMv3 does not support
+ * reading the control register, but ARMv4 does.
  *
- * On entry,
- *  r6 = processor ID
- * On exit,
- *  r0, r1 corrupted
- * This routine must preserve:
- *  r4, r6, r7
+ * On entry,  r6 = processor ID
+ * On exit,   r0, r1 corrupted
+ * This routine must preserve: r4, r6, r7
  */
 		.align	5
-cache_off:	ldr	r1, proc_sa110_type
-		eor	r1, r1, r6
-		movs	r1, r1, lsr #5		@ catch SA110 and SA1100
-		beq	1f
-		ldr	r1, proc_sa1110_type
-		eor	r1, r1, r6
-		movs	r1, r1, lsr #4
-		movne	pc, lr
-1:
+cache_off:
+#ifdef CONFIG_CPU_ARM610
+		eor	r1, r6, #0x41000000
+		eor	r1, r1, #0x00560000
+		bic	r1, r1, #0x0000001f
+		teq	r1, #0x00000600
+		mov	r0, #0x00000060		@ ARM6 control reg.
+		beq	__armv3_cache_off
+#endif
+#ifdef CONFIG_CPU_ARM710
+		eor	r1, r6, #0x41000000
+		bic	r1, r1, #0x00070000
+		bic	r1, r1, #0x000000ff
+		teq	r1, #0x00007000		@ ARM7
+		teqne	r1, #0x00007100		@ ARM710
+		mov	r0, #0x00000070		@ ARM7 control reg.
+		beq	__armv3_cache_off
+#endif
 		mrc	p15, 0, r0, c1, c0
 		bic	r0, r0, #0x000d
-		mcr	p15, 0, r0, c1, c0
-		mov	pc, lr		
+		mcr	p15, 0, r0, c1, c0	@ turn MMU and cache off
+		mov	r0, #0
+		mcr	p15, 0, r0, c7, c7	@ invalidate whole cache v4
+		mcr	p15, 0, r0, c8, c7	@ invalidate whole TLB v4
+		mov	pc, lr
+
+__armv3_cache_off:
+		mcr	p15, 0, r0, c1, c0	@ turn MMU and cache off
+		mov	r0, #0
+		mcr	p15, 0, r0, c7, c0	@ invalidate whole cache v3
+		mcr	p15, 0, r0, c5, c0	@ invalidate whole TLB v3
+		mov	pc, lr
 
 /*
  * Clean and flush the cache to maintain consistency.
@@ -401,13 +431,10 @@
 
 memdump:	mov	r12, r0
 		mov	r10, lr
-		mov	r1, #8
-		bl	phex
-		mov	r0, #'\n'
-		bl	putc
 		mov	r11, #0
 2:		mov	r0, r11, lsl #2
-		mov	r1, #4
+		add	r0, r0, r12
+		mov	r1, #8
 		bl	phex
 		mov	r0, #':'
 		bl	putc
diff -u --recursive --new-file v2.4.5/linux/arch/arm/boot/compressed/setup-sa1100.S linux/arch/arm/boot/compressed/setup-sa1100.S
--- v2.4.5/linux/arch/arm/boot/compressed/setup-sa1100.S	Thu Apr 12 12:03:50 2001
+++ linux/arch/arm/boot/compressed/setup-sa1100.S	Wed Jun 27 14:12:04 2001
@@ -16,16 +16,16 @@
 		.text
 
 GPIO_BASE:	.long	0x90040000
-#define GPLR	0x00
-#define GPDR	0x04
-#define GPSR	0x08
-#define GAFR	0x1c
+#define GPLR		0x00
+#define GPDR		0x04
+#define GPSR		0x08
+#define GAFR		0x1c
 
 PPC_BASE:	.long	0x90060000
-#define PPAR	0x08
+#define PPAR		0x08
 
 IC_BASE:	.long	0x90050000
-#define ICMR	0x04
+#define ICMR		0x04
 
 UART1_BASE:	.long	0x80010000
 UART3_BASE:	.long	0x80050000
@@ -95,7 +95,11 @@
 		@ Initialize UART (if bootloader has not done it yet)...
 		teq	r3, #MACH_TYPE_BRUTUS
 		teqne	r3, #MACH_TYPE_ASSABET
+		teqne   r3, #MACH_TYPE_ITSY
+		teqne   r3, #MACH_TYPE_OMNIMETER
+		teqne   r3, #MACH_TYPE_JORNADA720
 		teqne	r3, #MACH_TYPE_GRAPHICSCLIENT
+		teqne	r3, #MACH_TYPE_FLEXANET
 		bne	skip_uart
 
 		@ UART3 if Assabet is used with Neponset
diff -u --recursive --new-file v2.4.5/linux/arch/arm/config.in linux/arch/arm/config.in
--- v2.4.5/linux/arch/arm/config.in	Tue Apr 17 17:19:24 2001
+++ linux/arch/arm/config.in	Mon Jun 11 19:15:27 2001
@@ -482,6 +482,9 @@
 
 source drivers/usb/Config.in
 
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   source net/bluetooth/Config.in
+fi
 
 mainmenu_option next_comment
 comment 'Kernel hacking'
diff -u --recursive --new-file v2.4.5/linux/arch/arm/kernel/calls.S linux/arch/arm/kernel/calls.S
--- v2.4.5/linux/arch/arm/kernel/calls.S	Mon Sep 18 15:15:24 2000
+++ linux/arch/arm/kernel/calls.S	Wed Jun 27 14:12:04 2001
@@ -13,6 +13,7 @@
 #define NR_syscalls 256
 #else
 
+__syscall_start:
 /* 0 */		.long	SYMBOL_NAME(sys_ni_syscall)
 		.long	SYMBOL_NAME(sys_exit)
 		.long	SYMBOL_NAME(sys_fork_wrapper)
@@ -176,7 +177,7 @@
 /* 160 */	.long	SYMBOL_NAME(sys_sched_get_priority_min)
 		.long	SYMBOL_NAME(sys_sched_rr_get_interval)
 		.long	SYMBOL_NAME(sys_nanosleep)
-		.long	SYMBOL_NAME(sys_mremap)
+		.long	SYMBOL_NAME(sys_arm_mremap)
 		.long	SYMBOL_NAME(sys_setresuid16)
 /* 165 */	.long	SYMBOL_NAME(sys_getresuid16)
 		.long	SYMBOL_NAME(sys_ni_syscall)
@@ -231,8 +232,13 @@
 /* 215 */	.long	SYMBOL_NAME(sys_setfsuid)
 		.long	SYMBOL_NAME(sys_setfsgid)
 		.long	SYMBOL_NAME(sys_getdents64)
+		.long	SYMBOL_NAME(sys_pivot_root)
+		.long	SYMBOL_NAME(sys_mincore)
+/* 220 */	.long	SYMBOL_NAME(sys_madvise)
+		.long	SYMBOL_NAME(sys_fcntl64)
+__syscall_end:
 
-		.rept	NR_syscalls-217
+		.rept	NR_syscalls - (__syscall_end - __syscall_start) / 4
 			.long	SYMBOL_NAME(sys_ni_syscall)
 		.endr
 #endif
diff -u --recursive --new-file v2.4.5/linux/arch/arm/kernel/ecard.c linux/arch/arm/kernel/ecard.c
--- v2.4.5/linux/arch/arm/kernel/ecard.c	Thu Apr 12 12:20:31 2001
+++ linux/arch/arm/kernel/ecard.c	Wed Jun 27 14:12:04 2001
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/kernel/ecard.c
  *
- *  Copyright 1995-1998 Russell King
+ *  Copyright 1995-2001 Russell King
  *
  * 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
@@ -26,7 +26,6 @@
  *  17-Apr-1999	RMK	Support for EASI Type C cycles.
  */
 #define ECARD_C
-#define __KERNEL_SYSCALLS__
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -34,6 +33,7 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
+#include <linux/reboot.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
@@ -382,12 +382,12 @@
  * We ignore all calls, unless it is a SYS_RESTART call - power down/halts
  * will be followed by a SYS_RESTART if ctrl-alt-del is pressed again.
  */
-static void ecard_reboot(struct notifier_block *me, unsigned long val, void *v)
+static int ecard_reboot(struct notifier_block *me, unsigned long val, void *v)
 {
 	struct ecard_request req;
 
 	if (val != SYS_RESTART)
-		return;
+		return 0;
 
 	/*
 	 * Disable the expansion card interrupt
@@ -414,6 +414,7 @@
 	have_expmask = ~0;
 	__raw_writeb(have_expmask, EXPMASK_ENABLE);
 #endif
+	return 0;
 }
 
 static struct notifier_block ecard_reboot_notifier = {
diff -u --recursive --new-file v2.4.5/linux/arch/arm/kernel/entry-armv.S linux/arch/arm/kernel/entry-armv.S
--- v2.4.5/linux/arch/arm/kernel/entry-armv.S	Thu Apr 12 12:20:31 2001
+++ linux/arch/arm/kernel/entry-armv.S	Wed Jun 27 14:12:04 2001
@@ -1179,7 +1179,6 @@
 		stmfd	sp!, {r4 - r6, lr}
 
 		adr	r1, .LCvectors			@ set up the vectors
-		mov	r0, #0
 		ldmia	r1, {r1, r2, r3, r4, r5, r6, ip, lr}
 		stmia	r0, {r1, r2, r3, r4, r5, r6, ip, lr}
 
diff -u --recursive --new-file v2.4.5/linux/arch/arm/kernel/fiq.c linux/arch/arm/kernel/fiq.c
--- v2.4.5/linux/arch/arm/kernel/fiq.c	Thu Apr 12 12:20:31 2001
+++ linux/arch/arm/kernel/fiq.c	Wed Jun 27 14:12:04 2001
@@ -48,7 +48,7 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
-#define FIQ_VECTOR 0x1c
+#define FIQ_VECTOR (vectors_base() + 0x1c)
 
 static unsigned long no_fiq_insn;
 
diff -u --recursive --new-file v2.4.5/linux/arch/arm/kernel/sys_arm.c linux/arch/arm/kernel/sys_arm.c
--- v2.4.5/linux/arch/arm/kernel/sys_arm.c	Mon Mar 19 12:35:10 2001
+++ linux/arch/arm/kernel/sys_arm.c	Wed Jun 27 14:12:04 2001
@@ -55,10 +55,19 @@
 	unsigned long prot, unsigned long flags,
 	unsigned long fd, unsigned long pgoff)
 {
-	int error = -EBADF;
+	int error = -EINVAL;
 	struct file * file = NULL;
 
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	/*
+	 * If we are doing a fixed mapping, and address < PAGE_SIZE,
+	 * then deny it.
+	 */
+	if (flags & MAP_FIXED && addr < PAGE_SIZE && vectors_base() == 0)
+		goto out;
+
+	error = -EBADF;
 	if (!(flags & MAP_ANONYMOUS)) {
 		file = fget(fd);
 		if (!file)
@@ -99,6 +108,29 @@
 	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
 out:
 	return error;
+}
+
+asmlinkage unsigned long
+sys_arm_mremap(unsigned long addr, unsigned long old_len,
+	       unsigned long new_len, unsigned long flags,
+	       unsigned long new_addr)
+{
+	unsigned long ret = -EINVAL;
+
+	/*
+	 * If we are doing a fixed mapping, and address < PAGE_SIZE,
+	 * then deny it.
+	 */
+	if (flags & MREMAP_FIXED && new_addr < PAGE_SIZE &&
+	    vectors_base() == 0)
+		goto out;
+
+	down_write(&current->mm->mmap_sem);
+	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
+	up_write(&current->mm->mmap_sem);
+
+out:
+	return ret;
 }
 
 /*
diff -u --recursive --new-file v2.4.5/linux/arch/arm/kernel/traps.c linux/arch/arm/kernel/traps.c
--- v2.4.5/linux/arch/arm/kernel/traps.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/arm/kernel/traps.c	Wed Jun 27 14:12:04 2001
@@ -20,6 +20,7 @@
 #include <linux/mm.h>
 #include <linux/spinlock.h>
 #include <linux/ptrace.h>
+#include <linux/elf.h>
 #include <linux/init.h>
 
 #include <asm/atomic.h>
@@ -27,6 +28,7 @@
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/unistd.h>
 
 #include "ptrace.h"
 
@@ -143,12 +145,24 @@
 		c_backtrace(fp, processor_mode(regs));
 }
 
+/*
+ * This is called from SysRq-T (show_task) to display the current
+ * call trace for each process.  Very useful.
+ */
+void show_trace_task(struct task_struct *tsk)
+{
+	if (tsk != current) {
+		unsigned int fp = tsk->thread.save->fp;
+		c_backtrace(fp, 0x10);
+	}
+}
+
 spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
 
 /*
  * This function is protected against re-entrancy.
  */
-void die(const char *str, struct pt_regs *regs, int err)
+NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
 {
 	struct task_struct *tsk = current;
 
@@ -173,9 +187,9 @@
 		fs = get_fs();
 		set_fs(KERNEL_DS);
 
-		dump_instr(regs);
 		dump_stack(tsk, (unsigned long)(regs + 1));
 		dump_backtrace(regs, tsk);
+		dump_instr(regs);
 
 		set_fs(fs);
 	}
@@ -448,9 +462,12 @@
 
 void __init trap_init(void)
 {
-	extern void __trap_init(void);
+	extern void __trap_init(void *);
 
-	__trap_init();
+	__trap_init((void *)vectors_base());
+	if (vectors_base() != 0)
+		printk("Relocating machine vectors to 0x%08x\n",
+			vectors_base());
 #ifdef CONFIG_CPU_32
 	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
 #endif
diff -u --recursive --new-file v2.4.5/linux/arch/arm/mach-ebsa110/arch.c linux/arch/arm/mach-ebsa110/arch.c
--- v2.4.5/linux/arch/arm/mach-ebsa110/arch.c	Thu Apr 12 12:20:31 2001
+++ linux/arch/arm/mach-ebsa110/arch.c	Wed Jun 27 14:12:04 2001
@@ -1,10 +1,7 @@
 /*
  *  linux/arch/arm/mach-ebsa110/arch.c
  *
- *  Architecture specific fixups.  This is where any
- *  parameters in the params struct are fixed up, or
- *  any additional architecture specific information
- *  is pulled from the params struct.
+ *  Architecture specific fixups.
  */
 #include <linux/tty.h>
 #include <linux/delay.h>
diff -u --recursive --new-file v2.4.5/linux/arch/arm/mach-ebsa110/hardware.h linux/arch/arm/mach-ebsa110/hardware.h
--- v2.4.5/linux/arch/arm/mach-ebsa110/hardware.h	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/mach-ebsa110/hardware.h	Wed Jun 27 14:12:04 2001
@@ -0,0 +1,16 @@
+/*
+ *  linux/arch/arm/mach-ebsa110/hardware.h
+ *
+ *  Copyright (C) 2001 Russell King
+ *
+ *  Local hardware definitions.
+ */
+#ifndef HARDWARE_H
+#define HARDWARE_H
+
+#define IRQ_MASK		0xfe000000	/* read */
+#define IRQ_MSET		0xfe000000	/* write */
+#define IRQ_STAT		0xff000000	/* read */
+#define IRQ_MCLR		0xff000000	/* write */
+
+#endif
diff -u --recursive --new-file v2.4.5/linux/arch/arm/mach-ebsa110/io.c linux/arch/arm/mach-ebsa110/io.c
--- v2.4.5/linux/arch/arm/mach-ebsa110/io.c	Sun May 20 12:11:38 2001
+++ linux/arch/arm/mach-ebsa110/io.c	Wed Jun 27 14:12:04 2001
@@ -188,6 +188,7 @@
 u32 __inl(int port)
 {
 	BUG();
+	return 0;
 }
 
 EXPORT_SYMBOL(__inb);
diff -u --recursive --new-file v2.4.5/linux/arch/arm/mm/consistent.c linux/arch/arm/mm/consistent.c
--- v2.4.5/linux/arch/arm/mm/consistent.c	Thu Apr 12 12:20:31 2001
+++ linux/arch/arm/mm/consistent.c	Wed Jun 27 14:12:04 2001
@@ -67,18 +67,21 @@
 #endif
 
 	/*
-	 * free wasted pages.  We skip the first page since
-	 * we know that it will have count = 1 and won't
-	 * require freeing.
+	 * free wasted pages.  We skip the first page since we know
+	 * that it will have count = 1 and won't require freeing.
+	 * We also mark the pages in use as reserved so that
+	 * remap_page_range works.
 	 */
 	page = virt_to_page(virt);
 	free = page + (size >> PAGE_SHIFT);
 	end  = page + (1 << order);
 
-	while (++page < end) {
+	for (; page < end; page++) {
 		set_page_count(page, 1);
 		if (page >= free)
 			__free_page(page);
+		else
+			SetPageReserved(page);
 	}
 	return ret;
 
@@ -108,10 +111,26 @@
  * free a page as defined by the above mapping.  We expressly forbid
  * calling this from interrupt context.
  */
-void consistent_free(void *vaddr)
+void consistent_free(void *vaddr, size_t size, dma_addr_t handle)
 {
+	struct page *page, *end;
+	void *virt;
+
 	if (in_interrupt())
 		BUG();
+
+	virt = bus_to_virt(handle);
+
+	/*
+	 * More messing around with the MM internals.  This is
+	 * sick, but then so is remap_page_range().
+	 */
+	size = PAGE_ALIGN(size);
+	page = virt_to_page(virt);
+	end = page + (size >> PAGE_SHIFT);
+
+	for (; page < end; page++)
+		ClearPageReserved(page);
 
 	__iounmap(vaddr);
 }
diff -u --recursive --new-file v2.4.5/linux/arch/arm/mm/fault-armv.c linux/arch/arm/mm/fault-armv.c
--- v2.4.5/linux/arch/arm/mm/fault-armv.c	Wed May 16 15:25:16 2001
+++ linux/arch/arm/mm/fault-armv.c	Wed Jun 27 14:12:04 2001
@@ -24,6 +24,7 @@
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/unaligned.h>
 
@@ -45,9 +46,8 @@
  *
  * Speed optimisations and better fault handling by Russell King.
  *
- * NOTE!!! This is not portable onto the ARM6/ARM7 processors yet.  Also,
- * it seems to give a severe performance impact (1 abort/ms - NW runs at
- * ARM6 speeds) with GCC 2.7.2.2 - needs checking with a later GCC/EGCS.
+ * *** NOTE ***
+ * This code is not portable to processors with late data abort handling.
  */
 #define CODING_BITS(i)	(i & 0x0e000000)
 
@@ -57,6 +57,8 @@
 #define LDST_W_BIT(i)	(i & (1 << 21))		/* Writeback		*/
 #define LDST_L_BIT(i)	(i & (1 << 20))		/* Load			*/
 
+#define LDST_P_EQ_U(i)	((((i) ^ ((i) >> 1)) & (1 << 23)) == 0)
+
 #define LDSTH_I_BIT(i)	(i & (1 << 22))		/* half-word immed	*/
 #define LDM_S_BIT(i)	(i & (1 << 22))		/* write CPSR from SPSR	*/
 
@@ -336,29 +338,48 @@
 	return TYPE_FAULT;
 }
 
+/*
+ * LDM/STM alignment handler.
+ *
+ * There are 4 variants of this instruction:
+ *
+ * B = rn pointer before instruction, A = rn pointer after instruction
+ *              ------ increasing address ----->
+ *	        |    | r0 | r1 | ... | rx |    |
+ * PU = 01             B                    A
+ * PU = 11        B                    A
+ * PU = 00        A                    B
+ * PU = 10             A                    B
+ */
 static int
 do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *regs)
 {
 	unsigned int rd, rn, correction, nr_regs, regbits;
-	unsigned long eaddr;
-
-	correction = 4; /* sometimes 8 on ARMv3 */
-	regs->ARM_pc += correction;
-
-	rd = RD_BITS(instr);
-	rn = RN_BITS(instr);
-	eaddr = regs->uregs[rn];
+	unsigned long eaddr, newaddr;
 
 	if (LDM_S_BIT(instr))
 		goto bad;
 
+	correction = 4; /* processor implementation defined */
+	regs->ARM_pc += correction;
+
 	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;
 
+	rn = RN_BITS(instr);
+	newaddr = eaddr = regs->uregs[rn];
+
 	if (!LDST_U_BIT(instr))
-		eaddr -= nr_regs;
+		nr_regs = -nr_regs;
+	newaddr += nr_regs;
+	if (!LDST_U_BIT(instr))
+		eaddr = newaddr;
+
+	if (LDST_P_EQ_U(instr))	/* U = P */
+		eaddr += 4;
 
 	/*
 	 * This is a "hint" - we already have eaddr worked out by the
@@ -369,34 +390,23 @@
 			"addr = %08lx, eaddr = %08lx\n",
 			 instruction_pointer(regs), instr, addr, eaddr);
 
-	if ((LDST_U_BIT(instr) == 0 && LDST_P_BIT(instr) == 0) ||
-	    (LDST_U_BIT(instr)      && LDST_P_BIT(instr)))
-		eaddr += 4;
-
 	for (regbits = REGMASK_BITS(instr), rd = 0; regbits; regbits >>= 1, rd += 1)
 		if (regbits & 1) {
-			if (LDST_L_BIT(instr)) {
+			if (LDST_L_BIT(instr))
 				get32_unaligned_check(regs->uregs[rd], eaddr);
-				if (rd == 15)
-					correction = 0;
-			} else
+			else
 				put32_unaligned_check(regs->uregs[rd], eaddr);
 			eaddr += 4;
 		}
 
-	if (LDST_W_BIT(instr)) {
-		if (LDST_P_BIT(instr) && !LDST_U_BIT(instr))
-			eaddr -= nr_regs;
-		else if (LDST_P_BIT(instr))
-			eaddr -= 4;
-		else if (!LDST_U_BIT(instr))
-			eaddr -= 4 + nr_regs;
-		regs->uregs[rn] = eaddr;
-	}
-	regs->ARM_pc -= correction;
+	if (LDST_W_BIT(instr))
+		regs->uregs[rn] = newaddr;
+	if (!LDST_L_BIT(instr) || !(REGMASK_BITS(instr) & (1 << 15)))
+		regs->ARM_pc -= correction;
 	return TYPE_DONE;
 
 fault:
+	regs->ARM_pc -= correction;
 	return TYPE_FAULT;
 
 bad:
diff -u --recursive --new-file v2.4.5/linux/arch/arm/mm/mm-armv.c linux/arch/arm/mm/mm-armv.c
--- v2.4.5/linux/arch/arm/mm/mm-armv.c	Thu Apr 12 12:20:31 2001
+++ linux/arch/arm/mm/mm-armv.c	Wed Jun 27 14:12:04 2001
@@ -79,37 +79,40 @@
 
 	memzero(new_pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t));
 
-	/*
-	 * This lock is here just to satisfy pmd_alloc and pte_lock
-	 */
-	spin_lock(&mm->page_table_lock);
+	init_pgd = pgd_offset_k(0);
 
-	/*
-	 * On ARM, first page must always be allocated since it contains
-	 * the machine vectors.
-	 */
-	new_pmd = pmd_alloc(mm, new_pgd, 0);
-	if (!new_pmd)
-		goto no_pmd;
-
-	new_pte = pte_alloc(mm, new_pmd, 0);
-	if (!new_pte)
-		goto no_pte;
+	if (vectors_base() == 0) {
+		init_pmd = pmd_offset(init_pgd, 0);
+		init_pte = pte_offset(init_pmd, 0);
+
+		/*
+		 * This lock is here just to satisfy pmd_alloc and pte_lock
+		 */
+		spin_lock(&mm->page_table_lock);
+
+		/*
+		 * On ARM, first page must always be allocated since it
+		 * contains the machine vectors.
+		 */
+		new_pmd = pmd_alloc(mm, new_pgd, 0);
+		if (!new_pmd)
+			goto no_pmd;
+
+		new_pte = pte_alloc(mm, new_pmd, 0);
+		if (!new_pte)
+			goto no_pte;
 
-	init_pgd = pgd_offset_k(0);
-	init_pmd = pmd_offset(init_pgd, 0);
-	init_pte = pte_offset(init_pmd, 0);
+		set_pte(new_pte, *init_pte);
 
-	set_pte(new_pte, *init_pte);
+		spin_unlock(&mm->page_table_lock);
+	}
 
 	/*
 	 * Copy over the kernel and IO PGD entries
 	 */
-	memcpy(new_pgd  + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
+	memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
 		       (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
 
-	spin_unlock(&mm->page_table_lock);
-
 	/*
 	 * FIXME: this should not be necessary
 	 */
@@ -134,25 +137,26 @@
 
 void free_pgd_slow(pgd_t *pgd)
 {
-	if (pgd) { /* can pgd be NULL? */
-		pmd_t *pmd;
-		pte_t *pte;
-
-		/* pgd is always present and good */
-		pmd = (pmd_t *)pgd;
-		if (pmd_none(*pmd))
-			goto free;
-		if (pmd_bad(*pmd)) {
-			pmd_ERROR(*pmd);
-			pmd_clear(pmd);
-			goto free;
-		}
+	pmd_t *pmd;
+	pte_t *pte;
 
-		pte = pte_offset(pmd, 0);
+	if (!pgd)
+		return;
+
+	/* pgd is always present and good */
+	pmd = (pmd_t *)pgd;
+	if (pmd_none(*pmd))
+		goto free;
+	if (pmd_bad(*pmd)) {
+		pmd_ERROR(*pmd);
 		pmd_clear(pmd);
-		pte_free(pte);
-		pmd_free(pmd);
+		goto free;
 	}
+
+	pte = pte_offset(pmd, 0);
+	pmd_clear(pmd);
+	pte_free(pte);
+	pmd_free(pmd);
 free:
 	free_pages((unsigned long) pgd, 2);
 }
@@ -296,17 +300,6 @@
 
 	init_maps = p = alloc_bootmem_low_pages(PAGE_SIZE);
 
-	p->physical   = virt_to_phys(init_maps);
-	p->virtual    = 0;
-	p->length     = PAGE_SIZE;
-	p->domain     = DOMAIN_USER;
-	p->prot_read  = 0;
-	p->prot_write = 0;
-	p->cacheable  = 1;
-	p->bufferable = 0;
-
-	p ++;
-
 	for (i = 0; i < mi->nr_banks; i++) {
 		if (mi->bank[i].size == 0)
 			continue;
@@ -350,16 +343,9 @@
 #endif
 
 	/*
-	 * We may have a mapping in virtual address 0.
-	 * Clear it out.
-	 */
-	clear_mapping(0);
-
-	/*
 	 * Go through the initial mappings, but clear out any
 	 * pgdir entries that are not in the description.
 	 */
-	i = 0;
 	q = init_maps;
 	do {
 		if (address < q->virtual || q == p) {
@@ -374,6 +360,21 @@
 			q ++;
 		}
 	} while (address != 0);
+
+	/*
+	 * Create a mapping for the machine vectors at virtual address 0
+	 * or 0xffff0000.  We should always try the high mapping.
+	 */
+	init_maps->physical   = virt_to_phys(init_maps);
+	init_maps->virtual    = vectors_base();
+	init_maps->length     = PAGE_SIZE;
+	init_maps->domain     = DOMAIN_USER;
+	init_maps->prot_read  = 0;
+	init_maps->prot_write = 0;
+	init_maps->cacheable  = 1;
+	init_maps->bufferable = 0;
+
+	create_mapping(init_maps);
 
 	flush_cache_all();
 }
diff -u --recursive --new-file v2.4.5/linux/arch/arm/mm/mm-l7200.c linux/arch/arm/mm/mm-l7200.c
--- v2.4.5/linux/arch/arm/mm/mm-l7200.c	Thu Apr 12 12:20:31 2001
+++ linux/arch/arm/mm/mm-l7200.c	Wed Jun 27 14:12:04 2001
@@ -10,7 +10,6 @@
 #include <asm/hardware.h>
 #include <asm/page.h>
 #include <asm/proc/domain.h>
-#include <asm/setup.h>
 
 #include <asm/mach/map.h>
 
diff -u --recursive --new-file v2.4.5/linux/arch/arm/tools/Makefile linux/arch/arm/tools/Makefile
--- v2.4.5/linux/arch/arm/tools/Makefile	Tue Mar  6 19:44:35 2001
+++ linux/arch/arm/tools/Makefile	Wed Jun 27 14:12:04 2001
@@ -16,7 +16,7 @@
 
 $(TOPDIR)/include/asm-arm/constants.h: constants-hdr getconstants.c
 	$(CC) $(CFLAGS) -S -o - getconstants.c | \
-	 sed 's/^\(#define .* \)#\(.*\)/\1\2/;/^#define/!d' | \
+	 sed 's/^\(#define .* \)[#$$]\(.*\)/\1\2/;/^#define/!d' | \
 	 cat constants-hdr - > $@.tmp
 	cmp $@.tmp $@ >/dev/null 2>&1 || mv $@.tmp $@; $(RM) $@.tmp
 
diff -u --recursive --new-file v2.4.5/linux/arch/arm/tools/getconstants.c linux/arch/arm/tools/getconstants.c
--- v2.4.5/linux/arch/arm/tools/getconstants.c	Wed Apr 11 19:02:27 2001
+++ linux/arch/arm/tools/getconstants.c	Wed Jun 27 14:12:04 2001
@@ -60,7 +60,5 @@
 
 DEFN("PAGE_SZ",			PAGE_SIZE);
 
-DEFN("KSWI_BASE",		0x900000);
-DEFN("KSWI_SYS_BASE",		0x9f0000);
 DEFN("SYS_ERROR0",		0x9f0000);
 }
diff -u --recursive --new-file v2.4.5/linux/arch/arm/tools/mach-types linux/arch/arm/tools/mach-types
--- v2.4.5/linux/arch/arm/tools/mach-types	Wed Apr 11 19:02:27 2001
+++ linux/arch/arm/tools/mach-types	Wed Jun 27 14:12:04 2001
@@ -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: Sat Apr 7 09:45:09 2001
+# Last update: Sun Jun 17 00:53:17 2001
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -63,7 +63,7 @@
 citygo			SA1100_CITYGO		CITYGO			51
 pfs168			SA1100_PFS168		PFS168			52
 spot			SA1100_SPOT		SPOT			53
-flexanet		ARCH_FLEXANET		FLEXANET		54
+flexanet		SA1100_FLEXANET		FLEXANET		54
 webpal			ARCH_WEBPAL		WEBPAL			55
 linpda			SA1100_LINPDA		LINPDA			56
 anakin			ARCH_ANAKIN		ANAKIN			57
@@ -77,6 +77,26 @@
 xfile			SA1100_XFILE		XFILE			65
 accelent_ep9312		ARCH_ACCELENT_EP9312	ACCELENT_EP9312		66
 ic200			ARCH_IC200		IC200			67
+creditlart		SA1100_CREDITLART	CREDITLART		68
+htm			SA1100_HTM		HTM			69
+iq80310			ARCH_IQ80310		IQ80310			70
+freebot			SA1100_FREEBOT		FREEBOT			71
+entel			ARCH_ENTEL		ENTEL			72
+enp3510			ARCH_ENP3510		ENP3510			73
+trizeps			SA1100_TRIZEPS		TRIZEPS			74
+nesa			SA1100_NESA		NESA			75
+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
+itt_cpb			SA1100_ITT_CPB		ITT_CPB			81
+sa1110_svc		ARCH_SA1110_SVC		SA1110_SVC		82
+alpha2			SA1100_ALPHA2		ALPHA2			84
+alpha1			SA1100_ALPHA1		ALPHA1			85
+netarm			ARCH_NETARM		NETARM			86
+simpad			SA1100_SIMPAD		SIMPAD			87
+pda1			ARCH_PDA1		PDA1			88
+lubbock			ARCH_LUBBOCK		LUBBOCK			89
 
 # The following are unallocated
-empeg			SA1100_EMPEG		EMPEG
diff -u --recursive --new-file v2.4.5/linux/arch/cris/drivers/ide.c linux/arch/cris/drivers/ide.c
--- v2.4.5/linux/arch/cris/drivers/ide.c	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/drivers/ide.c	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-/* $Id: ide.c,v 1.9 2001/03/01 13:11:18 bjornw Exp $
+/* $Id: ide.c,v 1.16 2001/04/05 08:30:07 matsfg Exp $
  *
  * Etrax specific IDE functions, like init and PIO-mode setting etc.
  * Almost the entire ide.c is used for the rest of the Etrax ATA driver.
@@ -8,6 +8,28 @@
  *             Mikael Starvik     (pio setup stuff)
  *
  * $Log: ide.c,v $
+ * Revision 1.16  2001/04/05 08:30:07  matsfg
+ * Corrected cse1 and csp0 reset.
+ *
+ * Revision 1.15  2001/04/04 14:34:06  bjornw
+ * Re-instated code that mysteriously disappeared during review updates.
+ *
+ * Revision 1.14  2001/04/04 13:45:12  matsfg
+ * Calls REG_SHADOW_SET for cse1 reset so only the resetbit is affected
+ *
+ * Revision 1.13  2001/04/04 13:26:40  matsfg
+ * memmapping is done in init.c
+ *
+ * Revision 1.12  2001/04/04 11:37:56  markusl
+ * Updated according to review remarks
+ *
+ * Revision 1.11  2001/03/29 12:49:14  matsfg
+ * Changed check for ata_tot_size from >= to >.
+ * Sets sw_len to 0 if size is exactly 65536.
+ *
+ * Revision 1.10  2001/03/16 09:39:30  matsfg
+ * Support for reset on port CSP0
+ *
  * Revision 1.9  2001/03/01 13:11:18  bjornw
  * 100 -> HZ
  *
@@ -158,6 +180,10 @@
 #define ATA_PIO0_STROBE 19
 #define ATA_PIO0_HOLD    4
 
+static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive);
+static void e100_ideproc (ide_ide_action_t func, ide_drive_t *drive,
+			  void *buffer, unsigned int length);
+
 /*
  * good_dma_drives() lists the model names (from "hdparm -i")
  * of drives which do not support mword2 DMA but which are
@@ -174,7 +200,7 @@
 	unsigned long flags;
 	
 	pio = 4;
-	//pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
+	/* pio = ide_get_best_pio_mode(drive, pio, 4, NULL); */
 	
 	save_flags(flags);
 	cli();
@@ -226,10 +252,6 @@
 	restore_flags(flags);
 }
 
-static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive); /* defined below */
-static void e100_ideproc (ide_ide_action_t func, ide_drive_t *drive,
-			  void *buffer, unsigned int length);        /* defined below */
-
 void __init 
 init_e100_ide (void)
 {
@@ -277,26 +299,23 @@
 	*R_GEN_CONFIG = genconfig_shadow;
 
 #ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
-#ifndef CONFIG_CRIS_LOW_MAP
-	/* remap the I/O-mapped reset-bit from CSE1 to something inside our kernel space */
-	reset_addr = (unsigned long *)ioremap((unsigned long)(MEM_CSE1_START |
-							      MEM_NON_CACHEABLE), 16);
-	*reset_addr = 0;
-#else
-	/* LOW_MAP, can't do the ioremap, but it's already mapped straight over */
-	reset_addr = (unsigned long *)(MEM_CSE1_START | MEM_NON_CACHEABLE);
-	*reset_addr = 0;
+        init_ioremap();
+        REG_SHADOW_SET(port_cse1_addr, port_cse1_shadow, 16, 0);
 #endif
+
+#ifdef CONFIG_ETRAX_IDE_CSP0_8_RESET
+        init_ioremap();
+        REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, 8, 0);
 #endif
 
 	/* wait some */
-
-	dummy = 1;
-	dummy = 2;
-	dummy = 3;
+	udelay(25);
 
 #ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
-	*reset_addr = 1 << 16;
+	REG_SHADOW_SET(port_cse1_addr, port_cse1_shadow, 16, 1);
+#endif
+#ifdef CONFIG_ETRAX_IDE_CSP0_8_RESET
+	REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, 8, 1);
 #endif
 #ifdef CONFIG_ETRAX_IDE_G27_RESET
 	*R_PORT_G_DATA = 0; /* de-assert bus-reset */
@@ -349,7 +368,6 @@
 e100_atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount)
 {
 	ide_ioreg_t data_reg = IDE_DATA_REG;
-	unsigned long status;
 
 	D(printk("atapi_input_bytes, dreg 0x%x, buffer 0x%x, count %d\n",
 		 data_reg, buffer, bytecount));
@@ -376,7 +394,7 @@
 	
 	/* initiate a multi word dma read using PIO handshaking */
 	
-	*R_ATA_TRANSFER_CNT = bytecount >> 1;
+	*R_ATA_TRANSFER_CNT = IO_FIELD(R_ATA_TRANSFER_CNT, count, bytecount >> 1);
 	
 	*R_ATA_CTRL_DATA = data_reg |
 		IO_STATE(R_ATA_CTRL_DATA, rw,       read) |
@@ -390,35 +408,38 @@
 	LED_DISK_READ(1);
 	WAIT_DMA(3);
 	LED_DISK_READ(0);
-	
+
 #if 0
-	/* old polled transfer code */
-	
-	/* initiate a multi word read */
-	
-	*R_ATA_TRANSFER_CNT = wcount << 1;
-	
-	*R_ATA_CTRL_DATA = data_reg |
-		IO_STATE(R_ATA_CTRL_DATA, rw,       read) |
-		IO_STATE(R_ATA_CTRL_DATA, src_dst,  register) |
-		IO_STATE(R_ATA_CTRL_DATA, handsh,   pio) |
-		IO_STATE(R_ATA_CTRL_DATA, multi,    on) |
-		IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
-	
-	/* svinto has a latency until the busy bit actually is set */
-	
-	nop(); nop();
-	nop(); nop();
-	nop(); nop();
-	nop(); nop();
-	nop(); nop();
-	
-	/* unit should be busy during multi transfer */
-	while((status = *R_ATA_STATUS_DATA) & IO_MASK(R_ATA_STATUS_DATA, busy)) {
-		while(!(status & IO_MASK(R_ATA_STATUS_DATA, dav)))
-			status = *R_ATA_STATUS_DATA;
-		*ptr++ = (unsigned short)(status & 0xffff);
-	}
+        /* old polled transfer code
+	 * this should be moved into a new function that can do polled
+	 * transfers if DMA is not available
+	 */
+        
+        /* initiate a multi word read */
+        
+        *R_ATA_TRANSFER_CNT = wcount << 1;
+        
+        *R_ATA_CTRL_DATA = data_reg |
+                IO_STATE(R_ATA_CTRL_DATA, rw,       read) |
+                IO_STATE(R_ATA_CTRL_DATA, src_dst,  register) |
+                IO_STATE(R_ATA_CTRL_DATA, handsh,   pio) |
+                IO_STATE(R_ATA_CTRL_DATA, multi,    on) |
+                IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
+        
+        /* svinto has a latency until the busy bit actually is set */
+        
+        nop(); nop();
+        nop(); nop();
+        nop(); nop();
+        nop(); nop();
+        nop(); nop();
+        
+        /* unit should be busy during multi transfer */
+        while((status = *R_ATA_STATUS_DATA) & IO_MASK(R_ATA_STATUS_DATA, busy)) {
+                while(!(status & IO_MASK(R_ATA_STATUS_DATA, dav)))
+                        status = *R_ATA_STATUS_DATA;
+                *ptr++ = (unsigned short)(status & 0xffff);
+        }
 #endif
 }
 
@@ -426,8 +447,6 @@
 e100_atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount)
 {
 	ide_ioreg_t data_reg = IDE_DATA_REG;
-	unsigned short *ptr = (unsigned short *)buffer;
-	unsigned long ctrl;
 	
 	D(printk("atapi_output_bytes, dreg 0x%x, buffer 0x%x, count %d\n",
 		 data_reg, buffer, bytecount));
@@ -454,7 +473,7 @@
 	
 	/* initiate a multi word dma write using PIO handshaking */
 	
-	*R_ATA_TRANSFER_CNT = bytecount >> 1;
+	*R_ATA_TRANSFER_CNT = IO_FIELD(R_ATA_TRANSFER_CNT, count, bytecount >> 1);
 	
 	*R_ATA_CTRL_DATA = data_reg |
 		IO_STATE(R_ATA_CTRL_DATA, rw,       write) |
@@ -470,40 +489,42 @@
 	LED_DISK_WRITE(0);
 
 #if 0
-	/* old polled write code */
+        /* old polled write code - see comment in input_bytes */
 
-	while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)); /* wait for busy flag */
+	/* wait for busy flag */
+        while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)); 
 
-	/* initiate a multi word write */
+        /* initiate a multi word write */
 
-	*R_ATA_TRANSFER_CNT = bytecount >> 1;
+        *R_ATA_TRANSFER_CNT = bytecount >> 1;
 
-	ctrl = data_reg |
-		IO_STATE(R_ATA_CTRL_DATA, rw,       write) |
-		IO_STATE(R_ATA_CTRL_DATA, src_dst,  register) |
-		IO_STATE(R_ATA_CTRL_DATA, handsh,   pio) |
-		IO_STATE(R_ATA_CTRL_DATA, multi,    on) |
-		IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
-	
-	LED_DISK_WRITE(1);
-	
-	/* Etrax will set busy = 1 until the multi pio transfer has finished
-	 * and tr_rdy = 1 after each succesful word transfer. 
-	 * When the last byte has been transferred Etrax will first set tr_tdy = 1 
-	 * and then busy = 0 (not in the same cycle). If we read busy before it
-	 * has been set to 0 we will think that we should transfer more bytes 
-	 * and then tr_rdy would be 0 forever. This is solved by checking busy
-	 * in the inner loop.
-	 */
-	
-	do {
-		*R_ATA_CTRL_DATA = ctrl | *ptr++;
-		while(!(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, tr_rdy)) &&
-		      (*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)));
-	} while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy));
+        ctrl = data_reg |
+                IO_STATE(R_ATA_CTRL_DATA, rw,       write) |
+                IO_STATE(R_ATA_CTRL_DATA, src_dst,  register) |
+                IO_STATE(R_ATA_CTRL_DATA, handsh,   pio) |
+                IO_STATE(R_ATA_CTRL_DATA, multi,    on) |
+                IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
+        
+        LED_DISK_WRITE(1);
+        
+        /* Etrax will set busy = 1 until the multi pio transfer has finished
+         * and tr_rdy = 1 after each succesful word transfer. 
+         * When the last byte has been transferred Etrax will first set tr_tdy = 1 
+         * and then busy = 0 (not in the same cycle). If we read busy before it
+         * has been set to 0 we will think that we should transfer more bytes 
+         * and then tr_rdy would be 0 forever. This is solved by checking busy
+         * in the inner loop.
+         */
+        
+        do {
+                *R_ATA_CTRL_DATA = ctrl | *ptr++;
+                while(!(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, tr_rdy)) &&
+                      (*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)));
+        } while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy));
+
+        LED_DISK_WRITE(0);
+#endif  
 
-	LED_DISK_WRITE(0);
-#endif	
 }
 
 /*
@@ -604,7 +625,7 @@
 		      those blocks that were actually set-up for transfer.
 		*/
 
-		if(ata_tot_size + size >= 131072) {
+		if(ata_tot_size + size > 131072) {
 			printk("too large total ATA DMA request, %d + %d!\n", ata_tot_size, size);
 			return 1;
 		}
@@ -625,7 +646,12 @@
                         addr += 65536;
                 }
 		/* ok we want to do IO at addr, size bytes. set up a new descriptor entry */
-		ata_descrs[count].sw_len = size;
+                if(size == 65536) {
+                  ata_descrs[count].sw_len = 0;  /* 0 means 65536, this is a 16-bit field */
+                }
+                else {
+                  ata_descrs[count].sw_len = size;
+                }
 		ata_descrs[count].ctrl = 0;
 		ata_descrs[count].buf = addr;
 		ata_descrs[count].next = virt_to_phys(&ata_descrs[count + 1]);
@@ -793,9 +819,11 @@
 		
 		/* initiate a multi word dma read using DMA handshaking */
 		
-		*R_ATA_TRANSFER_CNT = ata_tot_size >> 1;
+		*R_ATA_TRANSFER_CNT =
+			IO_FIELD(R_ATA_TRANSFER_CNT, count, ata_tot_size >> 1);
 		
-		*R_ATA_CTRL_DATA = IDE_DATA_REG  |
+		*R_ATA_CTRL_DATA =
+			IO_FIELD(R_ATA_CTRL_DATA, data, IDE_DATA_REG) |
 			IO_STATE(R_ATA_CTRL_DATA, rw,       read) |
 			IO_STATE(R_ATA_CTRL_DATA, src_dst,  dma)  |
 			IO_STATE(R_ATA_CTRL_DATA, handsh,   dma)  |
@@ -834,9 +862,11 @@
 		
 		/* initiate a multi word dma write using DMA handshaking */
 		
-		*R_ATA_TRANSFER_CNT = ata_tot_size >> 1;
+		*R_ATA_TRANSFER_CNT =
+			IO_FIELD(R_ATA_TRANSFER_CNT, count, ata_tot_size >> 1);
 		
-		*R_ATA_CTRL_DATA = IDE_DATA_REG |
+		*R_ATA_CTRL_DATA =
+			IO_FIELD(R_ATA_CTRL_DATA, data,     IDE_DATA_REG) |
 			IO_STATE(R_ATA_CTRL_DATA, rw,       write) |
 			IO_STATE(R_ATA_CTRL_DATA, src_dst,  dma) |
 			IO_STATE(R_ATA_CTRL_DATA, handsh,   dma) |
diff -u --recursive --new-file v2.4.5/linux/arch/i386/config.in linux/arch/i386/config.in
--- v2.4.5/linux/arch/i386/config.in	Thu May 24 15:14:08 2001
+++ linux/arch/i386/config.in	Wed Jun 20 17:47:39 2001
@@ -245,6 +245,10 @@
 
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
    dep_bool '  ACPI support' CONFIG_ACPI $CONFIG_PM
+   
+   if [ "$CONFIG_ACPI" != "n" ]; then
+      source drivers/acpi/Config.in
+   fi
 fi
 
 dep_tristate '  Advanced Power Management BIOS support' CONFIG_APM $CONFIG_PM
@@ -374,6 +378,10 @@
 endmenu
 
 source drivers/usb/Config.in
+
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   source net/bluetooth/Config.in
+fi
 
 mainmenu_option next_comment
 comment 'Kernel hacking'
diff -u --recursive --new-file v2.4.5/linux/arch/i386/defconfig linux/arch/i386/defconfig
--- v2.4.5/linux/arch/i386/defconfig	Tue May 22 10:53:06 2001
+++ linux/arch/i386/defconfig	Wed Jun 27 15:59:52 2001
@@ -192,7 +192,7 @@
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_IDEDISK_MULTI_MODE=y
 # CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
 # CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
 # CONFIG_BLK_DEV_IDEDISK_IBM is not set
@@ -217,10 +217,10 @@
 CONFIG_BLK_DEV_RZ1000=y
 CONFIG_BLK_DEV_IDEPCI=y
 CONFIG_IDEPCI_SHARE_IRQ=y
-# CONFIG_BLK_DEV_IDEDMA_PCI is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
-# CONFIG_IDEDMA_PCI_AUTO is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
 # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
 # CONFIG_BLK_DEV_AEC62XX is not set
@@ -235,8 +235,8 @@
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_HPT34X_AUTODMA is not set
 # CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_PIIX_TUNING is not set
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_PIIX_TUNING=y
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX is not set
@@ -247,7 +247,8 @@
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
 # CONFIG_IDE_CHIPSETS is not set
-# CONFIG_IDEDMA_AUTO is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_IDEDMA_IVB is not set
 # CONFIG_DMA_NONPCI is not set
 CONFIG_BLK_DEV_IDE_MODES=y
 
@@ -362,6 +363,13 @@
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
@@ -380,7 +388,6 @@
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
 CONFIG_EEPRO100=y
-# CONFIG_EEPRO100_PM is not set
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -397,16 +404,18 @@
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_WINBOND_840 is not set
-# CONFIG_HAPPYMEAL is not set
 # CONFIG_NET_POCKET is not set
 
 #
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
+# CONFIG_MYRI_SBUS is not set
 # CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_FDDI is not set
+# CONFIG_PLIP is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
 
@@ -445,7 +454,6 @@
 # CONFIG_PCMCIA_NETWAVE is not set
 # CONFIG_PCMCIA_WAVELAN is not set
 # CONFIG_AIRONET4500_CS is not set
-CONFIG_PCMCIA_NETCARD=y
 
 #
 # Amateur Radio support
@@ -703,6 +711,7 @@
 # CONFIG_USB_IBMCAM is not set
 # CONFIG_USB_OV511 is not set
 # CONFIG_USB_PWC is not set
+# CONFIG_USB_SE401 is not set
 # CONFIG_USB_DSBR is not set
 # CONFIG_USB_DABUSB is not set
 
@@ -711,6 +720,7 @@
 #
 # CONFIG_USB_PLUSB is not set
 # CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_CATC is not set
 # CONFIG_USB_NET1080 is not set
 
 #
diff -u --recursive --new-file v2.4.5/linux/arch/i386/kernel/apic.c linux/arch/i386/kernel/apic.c
--- v2.4.5/linux/arch/i386/kernel/apic.c	Tue Dec  5 12:43:48 2000
+++ linux/arch/i386/kernel/apic.c	Wed Jun 20 11:06:38 2001
@@ -23,6 +23,7 @@
 #include <linux/mc146818rtc.h>
 #include <linux/kernel_stat.h>
 
+#include <asm/atomic.h>
 #include <asm/smp.h>
 #include <asm/mtrr.h>
 #include <asm/mpspec.h>
@@ -270,7 +271,13 @@
 	 *   PCI Ne2000 networking cards and PII/PIII processors, dual
 	 *   BX chipset. ]
 	 */
-#if 0
+	/*
+	 * Actually disabling the focus CPU check just makes the hang less
+	 * frequent as it makes the interrupt distributon model be more
+	 * like LRU than MRU (the short-term load is more even across CPUs).
+	 * See also the comment in end_level_ioapic_irq().  --macro
+	 */
+#if 1
 	/* Enable focus processor (bit==0) */
 	value &= ~(1<<9);
 #else
@@ -728,6 +735,9 @@
 	irq_enter(cpu, 0);
 	smp_local_timer_interrupt(regs);
 	irq_exit(cpu, 0);
+
+	if (softirq_pending(cpu))
+		do_softirq();
 }
 
 /*
@@ -764,7 +774,7 @@
 	apic_write(APIC_ESR, 0);
 	v1 = apic_read(APIC_ESR);
 	ack_APIC_irq();
-	irq_err_count++;
+	atomic_inc(&irq_err_count);
 
 	/* Here is what the APIC error bits mean:
 	   0: Send CS error
diff -u --recursive --new-file v2.4.5/linux/arch/i386/kernel/bluesmoke.c linux/arch/i386/kernel/bluesmoke.c
--- v2.4.5/linux/arch/i386/kernel/bluesmoke.c	Mon May 21 12:34:50 2001
+++ linux/arch/i386/kernel/bluesmoke.c	Wed Jun 27 16:18:13 2001
@@ -182,7 +182,7 @@
  *	Set up machine check reporting on the Winchip C6 series
  */
  
-static void winchip_mcheck_init(struct cpuinfo_x86 *c)
+static void __init winchip_mcheck_init(struct cpuinfo_x86 *c)
 {
 	u32 lo, hi;
 	/* Not supported on C3 */
@@ -207,8 +207,14 @@
  *	This has to be run for each processor
  */
 
+
+static int mce_disabled = 0;
+
 void __init mcheck_init(struct cpuinfo_x86 *c)
 {
+	if(mce_disabled)
+		return;
+		
 	switch(c->x86_vendor)
 	{
 		case X86_VENDOR_AMD:
@@ -226,3 +232,9 @@
 			break;
 	}
 }
+
+static void __init mcheck_disable(char *str, int *unused)
+{
+	mce_disabled = 1;
+}
+__setup("nomce", mcheck_disable);
diff -u --recursive --new-file v2.4.5/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- v2.4.5/linux/arch/i386/kernel/entry.S	Wed Nov  8 17:09:50 2000
+++ linux/arch/i386/kernel/entry.S	Tue Jun 12 11:47:28 2001
@@ -203,18 +203,7 @@
 	call *SYMBOL_NAME(sys_call_table)(,%eax,4)
 	movl %eax,EAX(%esp)		# save the return value
 ENTRY(ret_from_sys_call)
-#ifdef CONFIG_SMP
-	movl processor(%ebx),%eax
-	shll $CONFIG_X86_L1_CACHE_SHIFT,%eax
-	movl SYMBOL_NAME(irq_stat)(,%eax),%ecx		# softirq_active
-	testl SYMBOL_NAME(irq_stat)+4(,%eax),%ecx	# softirq_mask
-#else
-	movl SYMBOL_NAME(irq_stat),%ecx		# softirq_active
-	testl SYMBOL_NAME(irq_stat)+4,%ecx	# softirq_mask
-#endif
-	jne   handle_softirq
-	
-ret_with_reschedule:
+	cli				# need_resched and signals atomic test
 	cmpl $0,need_resched(%ebx)
 	jne reschedule
 	cmpl $0,sigpending(%ebx)
@@ -257,33 +246,16 @@
 	jmp ret_from_sys_call
 
 	ALIGN
-ret_from_exception:
-#ifdef CONFIG_SMP
-	GET_CURRENT(%ebx)
-	movl processor(%ebx),%eax
-	shll $CONFIG_X86_L1_CACHE_SHIFT,%eax
-	movl SYMBOL_NAME(irq_stat)(,%eax),%ecx		# softirq_active
-	testl SYMBOL_NAME(irq_stat)+4(,%eax),%ecx	# softirq_mask
-#else
-	movl SYMBOL_NAME(irq_stat),%ecx		# softirq_active
-	testl SYMBOL_NAME(irq_stat)+4,%ecx	# softirq_mask
-#endif
-	jne   handle_softirq
-
 ENTRY(ret_from_intr)
 	GET_CURRENT(%ebx)
+ret_from_exception:
 	movl EFLAGS(%esp),%eax		# mix EFLAGS and CS
 	movb CS(%esp),%al
 	testl $(VM_MASK | 3),%eax	# return to VM86 mode or non-supervisor?
-	jne ret_with_reschedule
+	jne ret_from_sys_call
 	jmp restore_all
 
 	ALIGN
-handle_softirq:
-	call SYMBOL_NAME(do_softirq)
-	jmp ret_from_intr
-	
-	ALIGN
 reschedule:
 	call SYMBOL_NAME(schedule)    # test
 	jmp ret_from_sys_call
@@ -334,14 +306,16 @@
 	pushl $-1		# mark this as an int
 	SAVE_ALL
 	GET_CURRENT(%ebx)
-	pushl $ret_from_exception
 	movl %cr0,%eax
 	testl $0x4,%eax			# EM (math emulation bit)
-	je SYMBOL_NAME(math_state_restore)
+	jne device_not_available_emulate
+	call SYMBOL_NAME(math_state_restore)
+	jmp ret_from_exception
+device_not_available_emulate:
 	pushl $0		# temporary storage for ORIG_EIP
 	call  SYMBOL_NAME(math_emulate)
 	addl $4,%esp
-	ret
+	jmp ret_from_exception
 
 ENTRY(debug)
 	pushl $0
diff -u --recursive --new-file v2.4.5/linux/arch/i386/kernel/head.S linux/arch/i386/kernel/head.S
--- v2.4.5/linux/arch/i386/kernel/head.S	Fri Apr 20 16:23:30 2001
+++ linux/arch/i386/kernel/head.S	Wed Jun 20 11:00:53 2001
@@ -41,8 +41,6 @@
  *
  * On entry, %esi points to the real-mode code as a 32-bit pointer.
  */
-ENTRY(stext)
-ENTRY(_stext)
 startup_32:
 /*
  * Set segments to known values
@@ -409,6 +407,12 @@
 ENTRY(empty_zero_page)
 
 .org 0x5000
+
+/*
+ * Real beginning of normal "text" segment
+ */
+ENTRY(stext)
+ENTRY(_stext)
 
 /*
  * This starts the data section. Note that the above is all
diff -u --recursive --new-file v2.4.5/linux/arch/i386/kernel/i8259.c linux/arch/i386/kernel/i8259.c
--- v2.4.5/linux/arch/i386/kernel/i8259.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/i386/kernel/i8259.c	Wed Jun 20 11:06:38 2001
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
 
+#include <asm/atomic.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -321,7 +322,7 @@
 			printk("spurious 8259A interrupt: IRQ%d.\n", irq);
 			spurious_irq_mask |= irqmask;
 		}
-		irq_err_count++;
+		atomic_inc(&irq_err_count);
 		/*
 		 * Theoretically we do not have to handle this IRQ,
 		 * but in Linux this does not cause problems and is
diff -u --recursive --new-file v2.4.5/linux/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c
--- v2.4.5/linux/arch/i386/kernel/io_apic.c	Fri Feb  9 11:28:31 2001
+++ linux/arch/i386/kernel/io_apic.c	Wed Jun 20 11:06:38 2001
@@ -33,6 +33,8 @@
 #include <asm/smp.h>
 #include <asm/desc.h>
 
+#define APIC_LOCKUP_DEBUG
+
 static spinlock_t ioapic_lock = SPIN_LOCK_UNLOCKED;
 
 /*
@@ -122,8 +124,14 @@
 	static void name##_IO_APIC_irq (unsigned int irq)		\
 	__DO_ACTION(R, ACTION, FINAL)
 
-DO_ACTION( __mask,    0, |= 0x00010000, io_apic_sync(entry->apic))/* mask = 1 */
-DO_ACTION( __unmask,  0, &= 0xfffeffff, )				/* mask = 0 */
+DO_ACTION( __mask,             0, |= 0x00010000, io_apic_sync(entry->apic) )
+						/* mask = 1 */
+DO_ACTION( __unmask,           0, &= 0xfffeffff, )
+						/* mask = 0 */
+DO_ACTION( __mask_and_edge,    0, = (reg & 0xffff7fff) | 0x00010000, )
+						/* mask = 1, trigger = 0 */
+DO_ACTION( __unmask_and_level, 0, = (reg & 0xfffeffff) | 0x00008000, )
+						/* mask = 0, trigger = 1 */
 
 static void mask_IO_APIC_irq (unsigned int irq)
 {
@@ -255,10 +263,16 @@
  */
 static int pin_2_irq(int idx, int apic, int pin);
 
-int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pci_pin)
+int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
 {
 	int apic, i, best_guess = -1;
 
+	Dprintk("querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n",
+		bus, slot, pin);
+	if (mp_bus_id_to_pci_bus[bus] == -1) {
+		printk(KERN_WARNING "PCI BIOS passed nonexistent PCI bus %d!\n", bus);
+		return -1;
+	}
 	for (i = 0; i < mp_irq_entries; i++) {
 		int lbus = mp_irqs[i].mpc_srcbus;
 
@@ -269,14 +283,14 @@
 
 		if ((mp_bus_id_to_type[lbus] == MP_BUS_PCI) &&
 		    !mp_irqs[i].mpc_irqtype &&
-		    (bus == mp_bus_id_to_pci_bus[mp_irqs[i].mpc_srcbus]) &&
+		    (bus == lbus) &&
 		    (slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f))) {
 			int irq = pin_2_irq(i,apic,mp_irqs[i].mpc_dstirq);
 
 			if (!(apic || IO_APIC_IRQ(irq)))
 				continue;
 
-			if (pci_pin == (mp_irqs[i].mpc_srcbusirq & 3))
+			if (pin == (mp_irqs[i].mpc_srcbusirq & 3))
 				return irq;
 			/*
 			 * Use the first all-but-pin matching entry as a
@@ -728,9 +742,11 @@
 	printk(KERN_DEBUG ".... register #01: %08X\n", *(int *)&reg_01);
 	printk(KERN_DEBUG ".......     : max redirection entries: %04X\n", reg_01.entries);
 	if (	(reg_01.entries != 0x0f) && /* older (Neptune) boards */
+		(reg_01.entries != 0x11) &&
 		(reg_01.entries != 0x17) && /* typical ISA+PCI boards */
 		(reg_01.entries != 0x1b) && /* Compaq Proliant boards */
 		(reg_01.entries != 0x1f) && /* dual Xeon boards */
+		(reg_01.entries != 0x20) &&
 		(reg_01.entries != 0x22) && /* bigger Xeon boards */
 		(reg_01.entries != 0x2E) &&
 		(reg_01.entries != 0x3F)
@@ -847,6 +863,8 @@
 
 	v = apic_read(APIC_EOI);
 	printk(KERN_DEBUG "... APIC EOI: %08x\n", v);
+	v = apic_read(APIC_RRR);
+	printk(KERN_DEBUG "... APIC RRR: %08x\n", v);
 	v = apic_read(APIC_LDR);
 	printk(KERN_DEBUG "... APIC LDR: %08x\n", v);
 	v = apic_read(APIC_DFR);
@@ -1191,12 +1209,61 @@
 #define enable_level_ioapic_irq		unmask_IO_APIC_irq
 #define disable_level_ioapic_irq	mask_IO_APIC_irq
 
-static void end_level_ioapic_irq (unsigned int i)
+static void end_level_ioapic_irq (unsigned int irq)
 {
+	unsigned long v;
+
+/*
+ * It appears there is an erratum which affects at least version 0x11
+ * of I/O APIC (that's the 82093AA and cores integrated into various
+ * chipsets).  Under certain conditions a level-triggered interrupt is
+ * erroneously delivered as edge-triggered one but the respective IRR
+ * bit gets set nevertheless.  As a result the I/O unit expects an EOI
+ * message but it will never arrive and further interrupts are blocked
+ * from the source.  The exact reason is so far unknown, but the
+ * phenomenon was observed when two consecutive interrupt requests
+ * from a given source get delivered to the same CPU and the source is
+ * temporarily disabled in between.
+ *
+ * A workaround is to simulate an EOI message manually.  We achieve it
+ * by setting the trigger mode to edge and then to level when the edge
+ * trigger mode gets detected in the TMR of a local APIC for a
+ * level-triggered interrupt.  We mask the source for the time of the
+ * operation to prevent an edge-triggered interrupt escaping meanwhile.
+ * The idea is from Manfred Spraul.  --macro
+ */
+	v = apic_read(APIC_TMR + ((IO_APIC_VECTOR(irq) & ~0x1f) >> 1));
+
 	ack_APIC_irq();
+
+	if (!(v & (1 << (IO_APIC_VECTOR(irq) & 0x1f)))) {
+#ifdef APIC_MISMATCH_DEBUG
+		atomic_inc(&irq_mis_count);
+#endif
+		spin_lock(&ioapic_lock);
+		__mask_and_edge_IO_APIC_irq(irq);
+#ifdef APIC_LOCKUP_DEBUG
+		for (;;) {
+			struct irq_pin_list *entry = irq_2_pin + irq;
+			unsigned int reg;
+
+			if (entry->pin == -1)
+				break;
+			reg = io_apic_read(entry->apic, 0x10 + entry->pin * 2);
+			if (reg & 0x00004000)
+				printk(KERN_CRIT "Aieee!!!  Remote IRR"
+					" still set after unlock!\n");
+			if (!entry->next)
+				break;
+			entry = irq_2_pin + entry->next;
+		}
+#endif
+		__unmask_and_level_IO_APIC_irq(irq);
+		spin_unlock(&ioapic_lock);
+	}
 }
 
-static void mask_and_ack_level_ioapic_irq (unsigned int i) { /* nothing */ }
+static void mask_and_ack_level_ioapic_irq (unsigned int irq) { /* nothing */ }
 
 static void set_ioapic_affinity (unsigned int irq, unsigned long mask)
 {
@@ -1426,7 +1493,7 @@
 	pin1 = find_isa_irq_pin(0, mp_INT);
 	pin2 = find_isa_irq_pin(0, mp_ExtINT);
 
-	printk(KERN_INFO "..TIMER: vector=%d pin1=%d pin2=%d\n", vector, pin1, pin2);
+	printk(KERN_INFO "..TIMER: vector=%02X pin1=%d pin2=%d\n", vector, pin1, pin2);
 
 	if (pin1 != -1) {
 		/*
diff -u --recursive --new-file v2.4.5/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
--- v2.4.5/linux/arch/i386/kernel/irq.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/i386/kernel/irq.c	Wed Jun 20 11:06:38 2001
@@ -33,6 +33,7 @@
 #include <linux/irq.h>
 #include <linux/proc_fs.h>
 
+#include <asm/atomic.h>
 #include <asm/io.h>
 #include <asm/smp.h>
 #include <asm/system.h>
@@ -119,7 +120,12 @@
 	end_none
 };
 
-volatile unsigned long irq_err_count;
+atomic_t irq_err_count;
+#ifdef CONFIG_X86_IO_APIC
+#ifdef APIC_MISMATCH_DEBUG
+atomic_t irq_mis_count;
+#endif
+#endif
 
 /*
  * Generic, controller-independent functions:
@@ -167,7 +173,12 @@
 			apic_timer_irqs[cpu_logical_map(j)]);
 	p += sprintf(p, "\n");
 #endif
-	p += sprintf(p, "ERR: %10lu\n", irq_err_count);
+	p += sprintf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
+#ifdef CONFIG_X86_IO_APIC
+#ifdef APIC_MISMATCH_DEBUG
+	p += sprintf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
+#endif
+#endif
 	return p - buf;
 }
 
@@ -623,7 +634,7 @@
 	desc->handler->end(irq);
 	spin_unlock(&desc->lock);
 
-	if (softirq_active(cpu) & softirq_mask(cpu))
+	if (softirq_pending(cpu))
 		do_softirq();
 	return 1;
 }
diff -u --recursive --new-file v2.4.5/linux/arch/i386/kernel/mpparse.c linux/arch/i386/kernel/mpparse.c
--- v2.4.5/linux/arch/i386/kernel/mpparse.c	Tue Nov 14 21:25:34 2000
+++ linux/arch/i386/kernel/mpparse.c	Mon Jun 11 19:15:27 2001
@@ -36,7 +36,7 @@
  */
 int apic_version [MAX_APICS];
 int mp_bus_id_to_type [MAX_MP_BUSSES];
-int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { -1, };
+int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
 int mp_current_pci_id;
 int pic_mode;
 unsigned long mp_lapic_addr;
diff -u --recursive --new-file v2.4.5/linux/arch/i386/kernel/pci-i386.h linux/arch/i386/kernel/pci-i386.h
--- v2.4.5/linux/arch/i386/kernel/pci-i386.h	Thu Jun 22 07:17:16 2000
+++ linux/arch/i386/kernel/pci-i386.h	Wed Jun 20 11:21:33 2001
@@ -12,14 +12,15 @@
 #define DBG(x...)
 #endif
 
-#define PCI_PROBE_BIOS 1
-#define PCI_PROBE_CONF1 2
-#define PCI_PROBE_CONF2 4
-#define PCI_NO_SORT 0x100
-#define PCI_BIOS_SORT 0x200
-#define PCI_NO_CHECKS 0x400
-#define PCI_ASSIGN_ROMS 0x1000
-#define PCI_BIOS_IRQ_SCAN 0x2000
+#define PCI_PROBE_BIOS		0x0001
+#define PCI_PROBE_CONF1		0x0002
+#define PCI_PROBE_CONF2		0x0004
+#define PCI_NO_SORT		0x0100
+#define PCI_BIOS_SORT		0x0200
+#define PCI_NO_CHECKS		0x0400
+#define PCI_ASSIGN_ROMS		0x1000
+#define PCI_BIOS_IRQ_SCAN	0x2000
+#define PCI_ASSIGN_ALL_BUSSES	0x4000
 
 extern unsigned int pci_probe;
 
diff -u --recursive --new-file v2.4.5/linux/arch/i386/kernel/pci-irq.c linux/arch/i386/kernel/pci-irq.c
--- v2.4.5/linux/arch/i386/kernel/pci-irq.c	Wed May 16 10:25:39 2001
+++ linux/arch/i386/kernel/pci-irq.c	Wed Jun 20 11:16:01 2001
@@ -411,7 +411,7 @@
 	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, pirq_piix_get, pirq_piix_set },
 	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX,   pirq_piix_get, pirq_piix_set },
 	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82820FW_0, pirq_piix_get, pirq_piix_set },
+	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, pirq_piix_get, pirq_piix_set },
 
 	{ "ALI", PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, pirq_ali_get, pirq_ali_set },
 
@@ -587,13 +587,14 @@
 		if (info->irq[pin].link == pirq) {
 			/* We refuse to override the dev->irq information. Give a warning! */
 		    	if (dev2->irq && dev2->irq != irq) {
-		    		printk(KERN_INFO "IRQ routing conflict in pirq table for device %s\n", dev2->slot_name);
+		    		printk(KERN_INFO "IRQ routing conflict for %s, have irq %d, want irq %d\n",
+				       dev2->slot_name, dev2->irq, irq);
 		    		continue;
 		    	}
 			dev2->irq = irq;
 			pirq_penalty[irq]++;
 			if (dev != dev2)
-				printk(KERN_INFO "PCI: The same IRQ used for device %s\n", dev2->slot_name);
+				printk(KERN_INFO "PCI: Sharing IRQ %d with %s\n", irq, dev2->slot_name);
 		}
 	}
 	return 1;
@@ -656,10 +657,12 @@
 			if (pin) {
 				pin--;		/* interrupt pins are numbered starting from 1 */
 				irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin);
-/*
- * Will be removed completely if things work out well with fuzzy parsing
- */
-#if 0
+	/*
+	 * Busses behind bridges are typically not listed in the MP-table.
+	 * In this case we have to look up the IRQ based on the parent bus,
+	 * parent slot, and pin number. The SMP code detects such bridged
+	 * busses itself so we should get into this branch reliably.
+	 */
 				if (irq < 0 && dev->bus->parent) { /* go back to the bridge */
 					struct pci_dev * bridge = dev->bus->self;
 
@@ -670,7 +673,6 @@
 						printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n", 
 							bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq);
 				}
-#endif
 				if (irq >= 0) {
 					printk(KERN_INFO "PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n",
 						dev->bus->number, PCI_SLOT(dev->devfn), pin, irq);
diff -u --recursive --new-file v2.4.5/linux/arch/i386/kernel/pci-pc.c linux/arch/i386/kernel/pci-pc.c
--- v2.4.5/linux/arch/i386/kernel/pci-pc.c	Thu Apr 19 22:57:06 2001
+++ linux/arch/i386/kernel/pci-pc.c	Wed Jun 20 11:21:33 2001
@@ -940,18 +940,6 @@
 	pcibios_max_latency = 32;
 }
 
-static void __init pci_fixup_via_acpi(struct pci_dev *d)
-{
-	/*
-	 * VIA ACPI device: IRQ line in PCI config byte 0x42
-	 */
-	u8 irq;
-	pci_read_config_byte(d, 0x42, &irq);
-	irq &= 0x0f;
-	if (irq && (irq != 2))
-		d->irq = irq;
-}
-
 static void __init pci_fixup_piix4_acpi(struct pci_dev *d)
 {
 	/*
@@ -1006,8 +994,6 @@
 	{ PCI_FIXUP_HEADER,	PCI_ANY_ID,		PCI_ANY_ID,			pci_fixup_ide_bases },
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_5597,		pci_fixup_latency },
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_5598,		pci_fixup_latency },
-	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_3,	pci_fixup_via_acpi },
-	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_4,	pci_fixup_via_acpi },
  	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C691,	pci_fixup_via691 },
  	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C598_1,	pci_fixup_via691_2 },
  	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82371AB_3,	pci_fixup_piix4_acpi },
@@ -1104,6 +1090,9 @@
 	else if (!strcmp(str, "rom")) {
 		pci_probe |= PCI_ASSIGN_ROMS;
 		return NULL;
+	} else if (!strcmp(str, "assign-busses")) {
+		pci_probe |= PCI_ASSIGN_ALL_BUSSES;
+		return NULL;
 	} else if (!strncmp(str, "irqmask=", 8)) {
 		pcibios_irq_mask = simple_strtol(str+8, NULL, 0);
 		return NULL;
@@ -1112,6 +1101,11 @@
 		return NULL;
 	}
 	return str;
+}
+
+unsigned int pcibios_assign_all_busses(void)
+{
+	return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
 }
 
 int pcibios_enable_device(struct pci_dev *dev)
diff -u --recursive --new-file v2.4.5/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c
--- v2.4.5/linux/arch/i386/kernel/traps.c	Mon May  7 14:15:21 2001
+++ linux/arch/i386/kernel/traps.c	Wed Jun 20 13:59:44 2001
@@ -105,6 +105,7 @@
 	i = 1;
 	module_start = VMALLOC_START;
 	module_end = VMALLOC_END;
+	module_end = 0;
 	while (((long) stack & (THREAD_SIZE-1)) != 0) {
 		addr = *stack++;
 		/*
@@ -129,7 +130,12 @@
 
 void show_trace_task(struct task_struct *tsk)
 {
-	show_trace(&tsk->thread.esp);
+	unsigned long esp = tsk->thread.esp;
+
+	/* User space on another CPU? */
+	if ((esp ^ (unsigned long)tsk) & (PAGE_MASK<<1))
+		return;
+	show_trace((unsigned long *)esp);
 }
 
 void show_stack(unsigned long * esp)
diff -u --recursive --new-file v2.4.5/linux/arch/i386/math-emu/fpu_trig.c linux/arch/i386/math-emu/fpu_trig.c
--- v2.4.5/linux/arch/i386/math-emu/fpu_trig.c	Fri Apr  6 10:42:47 2001
+++ linux/arch/i386/math-emu/fpu_trig.c	Tue Jun 12 11:06:54 2001
@@ -1543,6 +1543,7 @@
 	  EXCEPTION(EX_INTERNAL | 0x116);
 	  return;
 #endif /* PARANOID */
+	  break;
 	}
     }
   else if ( (st0_tag == TAG_Valid) || (st0_tag == TW_Denormal) )
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/Makefile linux/arch/m68k/Makefile
--- v2.4.5/linux/arch/m68k/Makefile	Thu Jan  4 13:00:55 2001
+++ linux/arch/m68k/Makefile	Mon Jun 11 19:15:27 2001
@@ -110,8 +110,8 @@
 endif
 
 ifdef CONFIG_SUN3X
-CORE_FILES := $(CORE_FILES) arch/m68k/sun3x/sun3x.o
-SUBDIRS := $(SUBDIRS) arch/m68k/sun3x
+CORE_FILES := $(CORE_FILES) arch/m68k/sun3x/sun3x.o arch/m68k/sun3/sun3.o
+SUBDIRS := $(SUBDIRS) arch/m68k/sun3x arch/m68k/sun3
 endif
 
 ifdef CONFIG_SUN3
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/amiga/amisound.c linux/arch/m68k/amiga/amisound.c
--- v2.4.5/linux/arch/m68k/amiga/amisound.c	Thu Jan  4 13:00:55 2001
+++ linux/arch/m68k/amiga/amisound.c	Mon Jun 11 19:15:27 2001
@@ -16,7 +16,7 @@
 #include <asm/system.h>
 #include <asm/amigahw.h>
 
-static u_short *snd_data = NULL;
+static unsigned short *snd_data = NULL;
 static const signed char sine_data[] = {
 	0,  39,  75,  103,  121,  127,  121,  103,  75,  39,
 	0, -39, -75, -103, -121, -127, -121, -103, -75, -39
@@ -28,7 +28,7 @@
      * device since it depends on htotal (for OCS/ECS/AGA)
      */
 
-volatile u_short amiga_audio_min_period = 124;	/* Default for pre-OCS */
+volatile unsigned short amiga_audio_min_period = 124; /* Default for pre-OCS */
 
 #define MAX_PERIOD	(65535)
 
@@ -37,9 +37,9 @@
      *	Current period (set by dmasound.c)
      */
 
-u_short amiga_audio_period = MAX_PERIOD;
+unsigned short amiga_audio_period = MAX_PERIOD;
 
-static u_long clock_constant;
+static unsigned long clock_constant;
 
 void __init amiga_init_sound(void)
 {
@@ -76,7 +76,7 @@
 	del_timer( &sound_timer );
 
 	if (hz > 20 && hz < 32767) {
-		u_long period = (clock_constant / hz);
+		unsigned long period = (clock_constant / hz);
 
 		if (period < amiga_audio_min_period)
 			period = amiga_audio_min_period;
@@ -86,7 +86,7 @@
 		/* setup pointer to data, period, length and volume */
 		custom.aud[2].audlc = snd_data;
 		custom.aud[2].audlen = sizeof(sine_data)/2;
-		custom.aud[2].audper = (u_short)period;
+		custom.aud[2].audper = (unsigned short)period;
 		custom.aud[2].audvol = 32; /* 50% of maxvol */
 	
 		if (ticks) {
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/amiga/cia.c linux/arch/m68k/amiga/cia.c
--- v2.4.5/linux/arch/m68k/amiga/cia.c	Mon Nov 27 17:57:34 2000
+++ linux/arch/m68k/amiga/cia.c	Mon Jun 11 19:15:27 2001
@@ -23,8 +23,8 @@
 
 struct ciabase {
 	volatile struct CIA *cia;
-	u_char icr_mask, icr_data;
-	u_short int_mask;
+	unsigned char icr_mask, icr_data;
+	unsigned short int_mask;
 	int handler_irq, cia_irq, server_irq;
 	char *name;
 	irq_handler_t irq_list[CIA_IRQS];
@@ -46,7 +46,7 @@
 
 unsigned char cia_set_irq(struct ciabase *base, unsigned char mask)
 {
-	u_char old;
+	unsigned char old;
 
 	old = (base->icr_data |= base->cia->icr);
 	if (mask & CIA_ICR_SETCLR)
@@ -65,7 +65,7 @@
 
 unsigned char cia_able_irq(struct ciabase *base, unsigned char mask)
 {
-	u_char old, tmp;
+	unsigned char old, tmp;
 	int i;
 
 	old = base->icr_mask;
@@ -91,7 +91,7 @@
                     void (*handler)(int, void *, struct pt_regs *),
                     unsigned long flags, const char *devname, void *dev_id)
 {
-	u_char mask;
+	unsigned char mask;
 
 	base->irq_list[irq].handler = handler;
 	base->irq_list[irq].flags   = flags;
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/amiga/config.c linux/arch/m68k/amiga/config.c
--- v2.4.5/linux/arch/m68k/amiga/config.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/m68k/amiga/config.c	Mon Jun 11 19:15:27 2001
@@ -16,7 +16,6 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/init.h>
@@ -31,6 +30,7 @@
 #include <asm/amigahw.h>
 #include <asm/amigaints.h>
 #include <asm/irq.h>
+#include <asm/rtc.h>
 #include <asm/keyboard.h>
 #include <asm/machdep.h>
 #include <asm/io.h>
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/amiga/pcmcia.c linux/arch/m68k/amiga/pcmcia.c
--- v2.4.5/linux/arch/m68k/amiga/pcmcia.c	Thu Dec 17 09:06:25 1998
+++ linux/arch/m68k/amiga/pcmcia.c	Mon Jun 11 19:15:27 2001
@@ -19,7 +19,7 @@
 #include <asm/amipcmcia.h>
 
 /* gayle config byte for program voltage and access speed */
-static u_char cfg_byte = GAYLE_CFG_0V|GAYLE_CFG_150NS;
+static unsigned char cfg_byte = GAYLE_CFG_0V|GAYLE_CFG_150NS;
 
 void pcmcia_reset(void)
 {
@@ -64,7 +64,7 @@
 
 void pcmcia_program_voltage(int voltage)
 {
-	u_char v;
+	unsigned char v;
 
 	switch (voltage) {
 	case PCMCIA_0V:
@@ -87,7 +87,7 @@
 
 void pcmcia_access_speed(int speed)
 {
-	u_char s;
+	unsigned char s;
 
 	if (speed <= PCMCIA_SPEED_100NS)
 		s = GAYLE_CFG_100NS;
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/apollo/config.c linux/arch/m68k/apollo/config.c
--- v2.4.5/linux/arch/m68k/apollo/config.c	Wed Jan 26 12:44:20 2000
+++ linux/arch/m68k/apollo/config.c	Mon Jun 11 19:15:27 2001
@@ -2,7 +2,6 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/console.h>
 
@@ -12,6 +11,7 @@
 #include <asm/pgtable.h>
 #include <asm/apollohw.h>
 #include <asm/irq.h>
+#include <asm/rtc.h>
 #include <asm/machdep.h>
 
 u_long sio01_physaddr;
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/atari/time.c linux/arch/m68k/atari/time.c
--- v2.4.5/linux/arch/m68k/atari/time.c	Thu Aug 26 12:42:31 1999
+++ linux/arch/m68k/atari/time.c	Mon Jun 11 19:15:27 2001
@@ -12,10 +12,10 @@
 
 #include <linux/types.h>
 #include <linux/mc146818rtc.h>
-#include <linux/kd.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 
+#include <asm/rtc.h>
 
 void __init
 atari_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/bvme6000/config.c linux/arch/m68k/bvme6000/config.c
--- v2.4.5/linux/arch/m68k/bvme6000/config.c	Mon Jan 31 10:32:53 2000
+++ linux/arch/m68k/bvme6000/config.c	Mon Jun 11 19:15:27 2001
@@ -17,7 +17,6 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/linkage.h>
@@ -30,6 +29,7 @@
 #include <asm/setup.h>
 #include <asm/irq.h>
 #include <asm/traps.h>
+#include <asm/rtc.h>
 #include <asm/machdep.h>
 #include <asm/bvme6000hw.h>
 
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/bvme6000/rtc.c linux/arch/m68k/bvme6000/rtc.c
--- v2.4.5/linux/arch/m68k/bvme6000/rtc.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/m68k/bvme6000/rtc.c	Mon Jun 11 19:15:27 2001
@@ -76,7 +76,7 @@
 		unsigned char mon, day, hrs, min, sec, leap_yr;
 		unsigned int yrs;
 
-		if (!suser())
+		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
 
 		if (copy_from_user(&rtc_tm, (struct rtc_time*)arg,
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/config.in linux/arch/m68k/config.in
--- v2.4.5/linux/arch/m68k/config.in	Mon May 21 18:12:09 2001
+++ linux/arch/m68k/config.in	Mon Jun 11 19:15:27 2001
@@ -55,8 +55,8 @@
 if [ "$CONFIG_HP300" = "y" ]; then
    bool '  DIO bus support' CONFIG_DIO
 fi
-bool 'Sun3 support' CONFIG_SUN3
 bool 'Sun3x support' CONFIG_SUN3X
+bool 'Sun3 support' CONFIG_SUN3
   
 bool 'Q40/Q60 support' CONFIG_Q40
 
@@ -112,7 +112,7 @@
    bool 'Support for ST-RAM as swap space' CONFIG_STRAM_SWAP
    bool 'ST-RAM statistics in /proc' CONFIG_STRAM_PROC
 fi
-if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_ATARI" = "y" ]; then
+if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_ATARI" = "y" -o "$CONFIG_Q40" = "y" ]; then
    bool 'Use power LED as a heartbeat' CONFIG_HEARTBEAT
 else
   if [ "$CONFIG_HP300" = "y" ]; then
@@ -142,13 +142,17 @@
    fi
    dep_tristate '  Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT
    if [ "$CONFIG_PRINTER" != "n" ]; then
-      bool '    Support IEEE1284 status readback' CONFIG_PRINTER_READBACK
+      bool '    Support IEEE1284 status readback' CONFIG_PARPORT_1284
    fi
 fi
 
 source drivers/pci/Config.in
 source drivers/zorro/Config.in
 
+if [ "$CONFIG_Q40" = "y" ]; then
+source drivers/pnp/Config.in
+fi
+
 endmenu
 
 source drivers/mtd/Config.in
@@ -264,11 +268,11 @@
    fi
 
    if [ "$CONFIG_SUN3" = "y" ]; then
-	dep_tristate 'Sun3 NCR5380 SCSI' CONFIG_SUN3_SCSI $CONFIG_SCSI
+	dep_tristate 'Sun3 NCR5380 OBIO SCSI' CONFIG_SUN3_SCSI $CONFIG_SCSI
    fi
 
    if [ "$CONFIG_SUN3X" = "y" ]; then
-      bool 'ESP SCSI driver' CONFIG_SUN3X_ESP
+      bool 'Sun3x ESP SCSI' CONFIG_SUN3X_ESP
    fi
 
    endmenu
@@ -338,6 +342,9 @@
       if [ "$CONFIG_SUN3" = "y" -o "$CONFIG_SUN3X" = "y" ]; then
 	tristate '  Sun3/Sun3x on-board LANCE support' CONFIG_SUN3LANCE
       fi
+      if [ "$CONFIG_SUN3" = "y" ]; then
+	tristate '  Sun3 on-board Intel 82586 support' CONFIG_SUN3_82586
+      fi
       if [ "$CONFIG_HP300" = "y" ]; then
 	 bool '  HP on-board LANCE support' CONFIG_HPLANCE
       fi
@@ -367,7 +374,6 @@
 if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then
    bool '    Support more than 4 serial ports' CONFIG_SERIAL_MANY_PORTS
    bool '    Support for sharing serial interrupts' CONFIG_SERIAL_SHARE_IRQ
-#   bool '    Autodetect IRQ - do not yet enable !!' CONFIG_SERIAL_DETECT_IRQ
    bool '    Support special multiport boards' CONFIG_SERIAL_MULTIPORT
    bool '    Support the Bell Technologies HUB6 card' CONFIG_HUB6
 fi
@@ -451,16 +457,16 @@
 else
    define_bool CONFIG_SUN3X_ZS n
 fi
-dep_bool '  Sun keyboard support' CONFIG_SUN_KEYBOARD $CONFIG_SUN3X_ZS
-dep_bool '  Sun mouse support' CONFIG_SUN_MOUSE $CONFIG_SUN3X_ZS
-if [ "$CONFIG_SUN_MOUSE" = "y" ]; then
-   define_bool CONFIG_BUSMOUSE y
-fi
 if [ "$CONFIG_SUN3X_ZS" = "y" ]; then
+   define_bool CONFIG_SUN_KEYBOARD y
+   define_bool CONFIG_SUN_MOUSE y
+   define_bool CONFIG_BUSMOUSE y
    define_bool CONFIG_SBUS y
    define_bool CONFIG_SBUSCHAR y
    define_bool CONFIG_SUN_SERIAL y
 else
+   define_bool CONFIG_SUN_KEYBOARD n
+   define_bool CONFIG_SUN_MOUSE n
    define_bool CONFIG_SBUS n
 fi
 
@@ -508,9 +514,6 @@
    else
       bool 'Generic /dev/rtc emulation' CONFIG_GEN_RTC
    fi
-fi
-if [ "$CONFIG_Q40" = "y" ]; then
-  bool 'Q40 Real Time Clock Support' CONFIG_Q40RTC
 fi
 bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
 if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/kernel/head.S linux/arch/m68k/kernel/head.S
--- v2.4.5/linux/arch/m68k/kernel/head.S	Tue Mar  6 19:44:36 2001
+++ linux/arch/m68k/kernel/head.S	Mon Jun 11 19:15:27 2001
@@ -1178,8 +1178,45 @@
 #ifdef CONFIG_SUN3X
 	is_not_sun3x(L(notsun3x))
 
+	/* oh, the pain..  We're gonna want the prom code after
+	 * starting the MMU, so we copy the mappings, translating
+	 * from 8k -> 4k pages as we go.
+	 */
+
+	/* copy maps from 0xfee00000 to 0xff000000 */
+	movel	#0xfee00000, %d0
+	moveq	#ROOT_INDEX_SHIFT, %d1
+	lsrl	%d1,%d0
+	mmu_get_root_table_entry	%d0
+
+	movel	#0xfee00000, %d0
+	moveq	#PTR_INDEX_SHIFT, %d1
+	lsrl	%d1,%d0
+	andl	#PTR_TABLE_SIZE-1, %d0
+	mmu_get_ptr_table_entry		%a0,%d0
+
+	movel	#0xfee00000, %d0
+	moveq	#PAGE_INDEX_SHIFT, %d1
+	lsrl	%d1,%d0
+	andl	#PAGE_TABLE_SIZE-1, %d0
+	mmu_get_page_table_entry	%a0,%d0
+
+	/* this is where the prom page table lives */	
+	movel	0xfefe00d4, %a1
+	movel	%a1@, %a1
+
+	movel	#((0x200000 >> 13)-1), %d1
+
+1:
+	movel	%a1@+, %d3
+	movel	%d3,%a0@+
+	addl	#0x1000,%d3
+	movel	%d3,%a0@+
+	
+	dbra	%d1,1b	
+		
 	/* setup tt1 for I/O */
-	mmu_map_tt	#1,#0x40000000,#0x40000000,#_PAGE_NOCACHE_S
+	mmu_map_tt	#1,#0x40000000,#0x40000000,#_PAGE_NOCACHE_S 
 	jbra	L(mmu_init_done)
 
 L(notsun3x):
@@ -1363,7 +1400,7 @@
 	is_not_sun3x(1f)
 
 	/* enable copro */
-	oriw	#0x4000,0x61000000
+	oriw	#0x4000,0x61000000 
 1:
 #endif
 
@@ -3061,6 +3098,16 @@
 2:
 #endif
 
+#ifdef CONFIG_SUN3X
+	is_not_sun3x(2f) 
+	movel	%d0,-(%sp)
+	movel	0xFEFE0018,%a1
+	jbsr	(%a1)
+	addq	#4,%sp
+	jbra	L(serial_putc_done)
+2:	
+#endif
+	
 #ifdef CONFIG_Q40
 	is_not_q40(2f)
 	tst.l	%pc@(L(q40_do_debug))	/* only debug if requested */
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/kernel/ptrace.c linux/arch/m68k/kernel/ptrace.c
--- v2.4.5/linux/arch/m68k/kernel/ptrace.c	Mon Nov 27 18:02:06 2000
+++ linux/arch/m68k/kernel/ptrace.c	Mon Jun 11 19:15:27 2001
@@ -107,15 +107,19 @@
 	ret = -ESRCH;
 	read_lock(&tasklist_lock);
 	child = find_task_by_pid(pid);
-	read_unlock(&tasklist_lock);	/* FIXME!!! */
+	if (child)
+		get_task_struct(child);
+	read_unlock(&tasklist_lock);
 	if (!child)
 		goto out;
+
 	ret = -EPERM;
 	if (pid == 1)		/* you may not mess with init */
-		goto out;
+		goto out_tsk;
+
 	if (request == PTRACE_ATTACH) {
 		if (child == current)
-			goto out;
+			goto out_tsk;
 		if ((!child->dumpable ||
 		    (current->uid != child->euid) ||
 		    (current->uid != child->suid) ||
@@ -124,10 +128,10 @@
 		    (current->gid != child->sgid) ||
 	 	    (!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
 	 	    (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
-			goto out;
+			goto out_tsk;
 		/* the same process cannot be attached many times */
 		if (child->ptrace & PT_PTRACED)
-			goto out;
+			goto out_tsk;
 		child->ptrace |= PT_PTRACED;
 
 		write_lock_irqsave(&tasklist_lock, flags);
@@ -140,17 +144,17 @@
 
 		send_sig(SIGSTOP, child, 1);
 		ret = 0;
-		goto out;
+		goto out_tsk;
 	}
 	ret = -ESRCH;
 	if (!(child->ptrace & PT_PTRACED))
-		goto out;
+		goto out_tsk;
 	if (child->state != TASK_STOPPED) {
 		if (request != PTRACE_KILL)
-			goto out;
+			goto out_tsk;
 	}
 	if (child->p_pptr != current)
-		goto out;
+		goto out_tsk;
 
 	switch (request) {
 	/* when I and D space are separate, these will need to be fixed. */
@@ -162,9 +166,9 @@
 			copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
 			ret = -EIO;
 			if (copied != sizeof(tmp))
-				goto out;
+				break;
 			ret = put_user(tmp,(unsigned long *) data);
-			goto out;
+			break;
 		}
 
 	/* read the word at location addr in the USER area. */
@@ -172,8 +176,9 @@
 			unsigned long tmp;
 			
 			ret = -EIO;
-			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
-				goto out;
+			if ((addr & 3) || addr < 0 ||
+			    addr > sizeof(struct user) - 3)
+				break;
 			
 			tmp = 0;  /* Default return condition */
 			addr = addr >> 2; /* temporary hack. */
@@ -193,9 +198,9 @@
 					      ((tmp & 0x0000ffff) << 16);
 #endif
 			} else
-				goto out;
+				break;
 			ret = put_user(tmp,(unsigned long *) data);
-			goto out;
+			break;
 		}
 
       /* when I and D space are separate, this will have to be fixed. */
@@ -203,14 +208,15 @@
 		case PTRACE_POKEDATA:
 			ret = 0;
 			if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
-				goto out;
+				break;
 			ret = -EIO;
-			goto out;
+			break;
 
 		case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
 			ret = -EIO;
-			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
-				goto out;
+			if ((addr & 3) || addr < 0 ||
+			    addr > sizeof(struct user) - 3)
+				break;
 
 			addr = addr >> 2; /* temporary hack. */
 			    
@@ -221,9 +227,9 @@
 			}
 			if (addr < 19) {
 				if (put_reg(child, addr, data))
-					goto out;
+					break;
 				ret = 0;
-				goto out;
+				break;
 			}
 			if (addr >= 21 && addr < 48)
 			{
@@ -240,7 +246,7 @@
 				child->thread.fp[addr - 21] = data;
 				ret = 0;
 			}
-			goto out;
+			break;
 
 		case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
 		case PTRACE_CONT: { /* restart after signal. */
@@ -248,7 +254,7 @@
 
 			ret = -EIO;
 			if ((unsigned long) data > _NSIG)
-				goto out;
+				break;
 			if (request == PTRACE_SYSCALL)
 				child->ptrace |= PT_TRACESYS;
 			else
@@ -259,7 +265,7 @@
 			put_reg(child, PT_SR, tmp);
 			wake_up_process(child);
 			ret = 0;
-			goto out;
+			break;
 		}
 
 /*
@@ -272,13 +278,13 @@
 
 			ret = 0;
 			if (child->state == TASK_ZOMBIE) /* already dead */
-				goto out;
+				break;
 			child->exit_code = SIGKILL;
 	/* make sure the single step bit is not set. */
 			tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
 			put_reg(child, PT_SR, tmp);
 			wake_up_process(child);
-			goto out;
+			break;
 		}
 
 		case PTRACE_SINGLESTEP: {  /* set the trap flag. */
@@ -286,7 +292,7 @@
 
 			ret = -EIO;
 			if ((unsigned long) data > _NSIG)
-				goto out;
+				break;
 			child->ptrace &= ~PT_TRACESYS;
 			tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
 			put_reg(child, PT_SR, tmp);
@@ -295,7 +301,7 @@
 	/* give it a chance to run. */
 			wake_up_process(child);
 			ret = 0;
-			goto out;
+			break;
 		}
 
 		case PTRACE_DETACH: { /* detach a process that was attached. */
@@ -303,7 +309,7 @@
 
 			ret = -EIO;
 			if ((unsigned long) data > _NSIG)
-				goto out;
+				break;
 			child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
 			child->exit_code = data;
 			write_lock_irqsave(&tasklist_lock, flags);
@@ -316,7 +322,7 @@
 			put_reg(child, PT_SR, tmp);
 			wake_up_process(child);
 			ret = 0;
-			goto out;
+			break;
 		}
 
 		case PTRACE_GETREGS: { /* Get all gp regs from the child. */
@@ -328,12 +334,12 @@
 				tmp >>= 16;
 			    if (put_user(tmp, (unsigned long *) data)) {
 				ret = -EFAULT;
-				goto out;
+				break;
 			    }
 			    data += sizeof(long);
 			}
 			ret = 0;
-			goto out;
+			break;
 		}
 
 		case PTRACE_SETREGS: { /* Set all gp regs in the child. */
@@ -342,7 +348,7 @@
 			for (i = 0; i < 19; i++) {
 			    if (get_user(tmp, (unsigned long *) data)) {
 				ret = -EFAULT;
-				goto out;
+				break;
 			    }
 			    if (i == PT_SR) {
 				tmp &= SR_MASK;
@@ -353,7 +359,7 @@
 			    data += sizeof(long);
 			}
 			ret = 0;
-			goto out;
+			break;
 		}
 
 		case PTRACE_GETFPREGS: { /* Get the child FPU state. */
@@ -361,7 +367,7 @@
 			if (copy_to_user((void *)data, &child->thread.fp,
 					 sizeof(struct user_m68kfp_struct)))
 				ret = -EFAULT;
-			goto out;
+			break;
 		}
 
 		case PTRACE_SETFPREGS: { /* Set the child FPU state. */
@@ -369,13 +375,15 @@
 			if (copy_from_user(&child->thread.fp, (void *)data,
 					   sizeof(struct user_m68kfp_struct)))
 				ret = -EFAULT;
-			goto out;
+			break;
 		}
 
 		default:
 			ret = -EIO;
-			goto out;
+			break;
 	}
+out_tsk:
+	free_task_struct(child);
 out:
 	unlock_kernel();
 	return ret;
@@ -383,10 +391,9 @@
 
 asmlinkage void syscall_trace(void)
 {
-	lock_kernel();
 	if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
 			!= (PT_PTRACED|PT_TRACESYS))
-		goto out;
+		return;
 	current->exit_code = SIGTRAP;
 	current->state = TASK_STOPPED;
 	notify_parent(current, SIGCHLD);
@@ -400,6 +407,4 @@
 		send_sig(current->exit_code, current, 1);
 		current->exit_code = 0;
 	}
-out:
-	unlock_kernel();
 }
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/kernel/setup.c linux/arch/m68k/kernel/setup.c
--- v2.4.5/linux/arch/m68k/kernel/setup.c	Fri Apr 13 20:26:07 2001
+++ linux/arch/m68k/kernel/setup.c	Mon Jun 11 19:15:27 2001
@@ -34,6 +34,10 @@
 #ifdef CONFIG_ATARI
 #include <asm/atarihw.h>
 #endif
+#ifdef CONFIG_SUN3X
+#include <asm/dvma.h>
+extern void sun_serial_setup(void);
+#endif
 
 #ifdef CONFIG_BLK_DEV_INITRD
 #include <linux/blk.h>
@@ -106,6 +110,11 @@
 char *mach_sysrq_xlate = NULL;
 #endif
 
+#if defined(CONFIG_ISA)
+int isa_type;
+int isa_sex;
+#endif
+
 extern int amiga_parse_bootinfo(const struct bi_record *);
 extern int atari_parse_bootinfo(const struct bi_record *);
 extern int mac_parse_bootinfo(const struct bi_record *);
@@ -137,7 +146,7 @@
 {
     while (record->tag != BI_LAST) {
 	int unknown = 0;
-	const u_long *data = record->data;
+	const unsigned long *data = record->data;
 	switch (record->tag) {
 	    case BI_MACHTYPE:
 	    case BI_CPUTYPE:
@@ -186,7 +195,7 @@
 	if (unknown)
 	    printk("m68k_parse_bootinfo: unknown tag 0x%04x ignored\n",
 		   record->tag);
-	record = (struct bi_record *)((u_long)record+record->size);
+	record = (struct bi_record *)((unsigned long)record+record->size);
     }
 
     m68k_realnum_memory = m68k_num_memory;
@@ -365,14 +374,44 @@
 	if (MACH_IS_ATARI)
 		atari_stram_reserve_pages(availmem);
 #endif
+#ifdef CONFIG_SUN3X
+	if (MACH_IS_SUN3X) {
+		dvma_init();
+#ifdef CONFIG_SUN3X_ZS
+		sun_serial_setup();
+#endif
+	}
+#endif
+
 #endif /* !CONFIG_SUN3 */
+
 	paging_init();
+
+/* set ISA defs early as possible */
+#if defined(CONFIG_ISA)
+#if defined(CONFIG_Q40) 
+	if (MACH_IS_Q40) {
+	    isa_type = Q40_ISA;
+	    isa_sex = 0;
+	} 
+#elif defined(CONFIG_GG2)
+	if (MACH_IS_AMIGA && AMIGAHW_PRESENT(GG2_ISA)){
+	    isa_type = GG2_ISA;
+	    isa_sex = 0;
+	}
+#elif defined(CONFIG_AMIGA_PCMCIA)
+	if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)){
+	    isa_type = AG_ISA;
+	    isa_sex = 1;
+	}
+#endif
+#endif
 }
 
 int get_cpuinfo(char * buffer)
 {
     const char *cpu, *mmu, *fpu;
-    u_long clockfreq, clockfactor;
+    unsigned long clockfreq, clockfactor;
 
 #define LOOP_CYCLES_68020	(8)
 #define LOOP_CYCLES_68030	(8)
@@ -447,7 +486,7 @@
 {
     int len = 0;
     char model[80];
-    u_long mem;
+    unsigned long mem;
     int i;
 
     if (mach_get_model)
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/kernel/sys_m68k.c linux/arch/m68k/kernel/sys_m68k.c
--- v2.4.5/linux/arch/m68k/kernel/sys_m68k.c	Mon Mar 19 12:35:09 2001
+++ linux/arch/m68k/kernel/sys_m68k.c	Mon Jun 11 19:15:27 2001
@@ -267,7 +267,8 @@
   return -ENOSYS;
 }
 
-/* Convert virtual address VADDR to physical address PADDR */
+
+/* Convert virtual (user) address VADDR to physical address PADDR */
 #define virt_to_phys_040(vaddr)						\
 ({									\
   unsigned long _mmusr, _paddr;						\
@@ -447,6 +448,12 @@
 {
   unsigned long paddr, i;
 
+  /*
+   * 68060 manual says: 
+   *  cpush %dc : flush DC, remains valid (with our %cacr setup)
+   *  cpush %ic : invalidate IC
+   *  cpush %bc : flush DC + invalidate IC
+   */
   switch (scope)
     {
     case FLUSH_SCOPE_ALL:
@@ -455,20 +462,17 @@
 	case FLUSH_CACHE_DATA:
 	  __asm__ __volatile__ (".chip 68060\n\t"
 				"cpusha %dc\n\t"
-				"cinva %dc\n\t"
 				".chip 68k");
 	  break;
 	case FLUSH_CACHE_INSN:
 	  __asm__ __volatile__ (".chip 68060\n\t"
 				"cpusha %ic\n\t"
-				"cinva %ic\n\t"
 				".chip 68k");
 	  break;
 	default:
 	case FLUSH_CACHE_BOTH:
 	  __asm__ __volatile__ (".chip 68060\n\t"
 				"cpusha %bc\n\t"
-				"cinva %bc\n\t"
 				".chip 68k");
 	  break;
 	}
@@ -506,14 +510,12 @@
 	    case FLUSH_CACHE_DATA:
 	      __asm__ __volatile__ (".chip 68060\n\t"
 				    "cpushl %%dc,(%0)\n\t"
-				    "cinvl %%dc,(%0)\n\t"
 				    ".chip 68k"
 				    : : "a" (paddr));
 	      break;
 	    case FLUSH_CACHE_INSN:
 	      __asm__ __volatile__ (".chip 68060\n\t"
 				    "cpushl %%ic,(%0)\n\t"
-				    "cinvl %%ic,(%0)\n\t"
 				    ".chip 68k"
 				    : : "a" (paddr));
 	      break;
@@ -521,7 +523,6 @@
 	    case FLUSH_CACHE_BOTH:
 	      __asm__ __volatile__ (".chip 68060\n\t"
 				    "cpushl %%bc,(%0)\n\t"
-				    "cinvl %%bc,(%0)\n\t"
 				    ".chip 68k"
 				    : : "a" (paddr));
 	      break;
@@ -568,14 +569,12 @@
 	    case FLUSH_CACHE_DATA:
 	      __asm__ __volatile__ (".chip 68060\n\t"
 				    "cpushp %%dc,(%0)\n\t"
-				    "cinvp %%dc,(%0)\n\t"
 				    ".chip 68k"
 				    : : "a" (paddr));
 	      break;
 	    case FLUSH_CACHE_INSN:
 	      __asm__ __volatile__ (".chip 68060\n\t"
 				    "cpushp %%ic,(%0)\n\t"
-				    "cinvp %%ic,(%0)\n\t"
 				    ".chip 68k"
 				    : : "a" (paddr));
 	      break;
@@ -583,7 +582,6 @@
 	    case FLUSH_CACHE_BOTH:
 	      __asm__ __volatile__ (".chip 68060\n\t"
 				    "cpushp %%bc,(%0)\n\t"
-				    "cinvp %%bc,(%0)\n\t"
 				    ".chip 68k"
 				    : : "a" (paddr));
 	      break;
@@ -607,13 +605,14 @@
 		goto out;
 
 	if (scope == FLUSH_SCOPE_ALL) {
-		/* Only the superuser may flush the whole cache. */
+		/* Only the superuser may explicitly flush the whole cache. */
 		ret = -EPERM;
 		if (!capable(CAP_SYS_ADMIN))
 			goto out;
 	} else {
-		/* Verify that the specified address region actually belongs to
-		 * this process.
+		/*
+		 * Verify that the specified address region actually belongs
+		 * to this process.
 		 */
 		vma = find_vma (current->mm, addr);
 		ret = -EINVAL;
@@ -652,10 +651,21 @@
 		}
 		ret = 0;
 		goto out;
-	} else if (CPU_IS_040) {
+	} else {
+	    /*
+	     * 040 or 060: don't blindly trust 'scope', someone could
+	     * try to flush a few megs of memory.
+	     */
+
+	    if (len>=3*PAGE_SIZE && scope<FLUSH_SCOPE_PAGE)
+	        scope=FLUSH_SCOPE_PAGE;
+	    if (len>=10*PAGE_SIZE && scope<FLUSH_SCOPE_ALL)
+	        scope=FLUSH_SCOPE_ALL;
+	    if (CPU_IS_040) {
 		ret = cache_flush_040 (addr, scope, cache, len);
-	} else if (CPU_IS_060) {
+	    } else if (CPU_IS_060) {
 		ret = cache_flush_060 (addr, scope, cache, len);
+	    }
 	}
 out:
 	unlock_kernel();
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/kernel/traps.c linux/arch/m68k/kernel/traps.c
--- v2.4.5/linux/arch/m68k/kernel/traps.c	Thu Jan  4 13:00:55 2001
+++ linux/arch/m68k/kernel/traps.c	Mon Jun 11 19:15:27 2001
@@ -72,6 +72,12 @@
  */
 void __init base_trap_init(void)
 {
+	if(MACH_IS_SUN3X) {
+		extern e_vector *sun3x_prom_vbr;
+
+		__asm__ volatile ("movec %%vbr, %0" : "=r" ((void*)sun3x_prom_vbr));
+	}
+	
 	/* setup the exception vector table */
 	__asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors));
 
@@ -245,9 +251,12 @@
 #endif /* CONFIG_M68060 */
 
 #if defined (CONFIG_M68040)
-static inline unsigned long probe040(int iswrite, unsigned long addr)
+static inline unsigned long probe040(int iswrite, unsigned long addr, int wbs)
 {
 	unsigned long mmusr;
+	mm_segment_t old_fs = get_fs();
+
+	set_fs(MAKE_MM_SEG(wbs));
 
 	asm volatile (".chip 68040");
 
@@ -260,6 +269,8 @@
 
 	asm volatile (".chip 68k");
 
+	set_fs(old_fs); 
+
 	return mmusr;
 }
 
@@ -267,7 +278,9 @@
 				   unsigned long wbd)
 {
 	int res = 0;
+	mm_segment_t old_fs = get_fs();
 
+	/* set_fs can not be moved, otherwise put_user() may oops */
 	set_fs(MAKE_MM_SEG(wbs));
 
 	switch (wbs & WBSIZ_040) {
@@ -282,6 +295,10 @@
 		break;
 	}
 
+	/* set_fs can not be moved, otherwise put_user() may oops */
+	set_fs(old_fs); 
+	
+
 #ifdef DEBUG
 	printk("do_040writeback1, res=%d\n",res);
 #endif
@@ -293,10 +310,12 @@
  * to that exception is discarded, set a few bits in the old frame 
  * to simulate what it should look like
  */
-static inline void fix_xframe040(struct frame *fp, unsigned short wbs)
+static inline void fix_xframe040(struct frame *fp, unsigned long wba, unsigned short wbs)
 {
-	fp->un.fmt7.faddr = current->thread.faddr;
+	fp->un.fmt7.faddr = wba;
 	fp->un.fmt7.ssw = wbs & 0xff;
+	if (wba != current->thread.faddr)
+	    fp->un.fmt7.ssw |= MA_040;
 }
 
 static inline void do_040writebacks(struct frame *fp)
@@ -312,7 +331,7 @@
 		res = do_040writeback1(fp->un.fmt7.wb2s, fp->un.fmt7.wb2a,
 				       fp->un.fmt7.wb2d);
 		if (res)
-			fix_xframe040(fp, fp->un.fmt7.wb2s);
+			fix_xframe040(fp, fp->un.fmt7.wb2a, fp->un.fmt7.wb2s);
 		else 
 			fp->un.fmt7.wb2s = 0;
 	}
@@ -322,7 +341,14 @@
 		res = do_040writeback1(fp->un.fmt7.wb3s, fp->un.fmt7.wb3a,
 				       fp->un.fmt7.wb3d);
 		if (res)
-			fix_xframe040(fp, fp->un.fmt7.wb3s);
+		    {
+			fix_xframe040(fp, fp->un.fmt7.wb3a, fp->un.fmt7.wb3s);
+
+			fp->un.fmt7.wb2s = fp->un.fmt7.wb3s;
+			fp->un.fmt7.wb3s &= (~WBV_040);
+			fp->un.fmt7.wb2a = fp->un.fmt7.wb3a;
+			fp->un.fmt7.wb2d = fp->un.fmt7.wb3d;
+		    }
 		else
 			fp->un.fmt7.wb3s = 0;
 	}
@@ -339,19 +365,15 @@
  */
 asmlinkage void berr_040cleanup(struct frame *fp)
 {
-	mm_segment_t old_fs = get_fs();
-
 	fp->un.fmt7.wb2s &= ~4;
 	fp->un.fmt7.wb3s &= ~4;
 
 	do_040writebacks(fp);
-	set_fs(old_fs);
 }
 
 static inline void access_error040(struct frame *fp)
 {
 	unsigned short ssw = fp->un.fmt7.ssw;
-	mm_segment_t old_fs = get_fs();
 	unsigned long mmusr;
 
 #ifdef DEBUG
@@ -374,9 +396,8 @@
 		if (ssw & MA_040)
 			addr = (addr + 7) & -8;
 
-		set_fs(MAKE_MM_SEG(ssw));
 		/* MMU error, get the MMUSR info for this access */
-		mmusr = probe040(!(ssw & RW_040), addr);
+		mmusr = probe040(!(ssw & RW_040), addr, ssw);
 #ifdef DEBUG
 		printk("mmusr = %lx\n", mmusr);
 #endif
@@ -386,8 +407,12 @@
 			__flush_tlb040_one(addr);
 			errorcode = 0;
 		}
-		if (!(ssw & RW_040))
+
+		/* despite what documentation seems to say, RMW 
+		 * accesses have always both the LK and RW bits set */
+		if (!(ssw & RW_040) || (ssw & LK_040))
 			errorcode |= 2;
+
 		if (do_page_fault(&fp->ptregs, addr, errorcode)) {
 #ifdef DEBUG
 		        printk("do_page_fault() !=0 \n");
@@ -415,7 +440,6 @@
 	}
 
 	do_040writebacks(fp);
-	set_fs(old_fs);
 }
 #endif /* CONFIG_M68040 */
 
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/mac/config.c linux/arch/m68k/mac/config.c
--- v2.4.5/linux/arch/m68k/mac/config.c	Sun Dec  3 17:48:19 2000
+++ linux/arch/m68k/mac/config.c	Mon Jun 11 19:15:27 2001
@@ -13,7 +13,6 @@
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/mm.h>
-#include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/interrupt.h>
@@ -31,6 +30,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/pgtable.h>
+#include <asm/rtc.h>
 #include <asm/machdep.h>
 
 #include <asm/macintosh.h>
@@ -78,8 +78,6 @@
 
 extern void (*kd_mksound)(unsigned int, unsigned int);
 extern void mac_mksound(unsigned int, unsigned int);
-extern int mac_floppy_init(void);
-extern void mac_floppy_setup(char *,int *);
 
 extern void nubus_sweep_video(void);
 
@@ -122,8 +120,6 @@
 }
 #endif
 
-extern struct fb_info *mac_fb_init(long *);
-
 extern void mac_default_handler(int, void *, struct pt_regs *);
 
 void (*mac_handlers[8])(int, void *, struct pt_regs *)=
@@ -387,8 +383,7 @@
 	{	MAC_MODEL_P460,  "Performa 460", MAC_ADB_IISI, MAC_VIA_IIci,   MAC_SCSI_OLD, 	MAC_IDE_NONE,   MAC_SCC_II,	MAC_ETHER_NONE,	MAC_NUBUS},
 	{	MAC_MODEL_P475,  "Performa 475", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE,   MAC_SCC_II,	MAC_ETHER_NONE, MAC_NUBUS},
 	{	MAC_MODEL_P475F, "Performa 475", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE,   MAC_SCC_II,	MAC_ETHER_NONE, MAC_NUBUS},
-	{	MAC_MODEL_P520,  "Performa 520", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE,   MAC_SCC_II,	MAC_ETHER_NONE,	MAC_NUBUS},
-
+	{	MAC_MODEL_P520,  "Performa 520", MAC_ADB_CUDA, MAC_VIA_IIci,   MAC_SCSI_OLD,    MAC_IDE_NONE,   MAC_SCC_II,	MAC_ETHER_NONE,	MAC_NUBUS},
 	{	MAC_MODEL_P550,  "Performa 550", MAC_ADB_CUDA, MAC_VIA_IIci,   MAC_SCSI_OLD,    MAC_IDE_NONE,   MAC_SCC_II,	MAC_ETHER_NONE,	MAC_NUBUS},
 	{	MAC_MODEL_P575,  "Performa 575", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE,   MAC_SCC_II,	MAC_ETHER_NONE, MAC_NUBUS},
 	/* These have the comm slot, and therefore the possibility of SONIC ethernet */
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/mac/debug.c linux/arch/m68k/mac/debug.c
--- v2.4.5/linux/arch/m68k/mac/debug.c	Thu Oct 12 14:20:48 2000
+++ linux/arch/m68k/mac/debug.c	Mon Jun 11 19:15:27 2001
@@ -187,7 +187,7 @@
 
 
 
-/* Mac: loops_per_sec min. 1900000 ^= .5 us; MFPDELAY was 0.6 us*/
+/* Mac: loops_per_jiffy min. 19000 ^= .5 us; MFPDELAY was 0.6 us*/
 
 #define uSEC 1
 
@@ -286,9 +286,9 @@
 		barrier();				\
     } while(0)
 
-/* loops_per_sec isn't initialized yet, so we can't use udelay(). This does a
+/* loops_per_jiffy isn't initialized yet, so we can't use udelay(). This does a
  * delay of ~ 60us. */
-/* Mac: loops_per_sec min. 1900000 ^= .5 us; MFPDELAY was 0.6 us*/
+/* Mac: loops_per_jiffy min. 19000 ^= .5 us; MFPDELAY was 0.6 us*/
 #define LONG_DELAY()				\
     do {					\
 	int i;					\
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/mac/iop.c linux/arch/m68k/mac/iop.c
--- v2.4.5/linux/arch/m68k/mac/iop.c	Sun Feb 13 11:21:42 2000
+++ linux/arch/m68k/mac/iop.c	Mon Jun 11 19:15:27 2001
@@ -51,9 +51,6 @@
  *   IOP hasn't died.
  * o Some of the IOP manager routines need better error checking and
  *   return codes. Nothing major, just prettying up.
- *
- * + share the stuff you were smoking when you wrote the iop_get_proc_info()
- *   for case when CONFIG_PROC_FS is undefined.
  */
 
 /*
@@ -129,9 +126,6 @@
 
 #ifdef CONFIG_PROC_FS
 static int iop_get_proc_info(char *, char **, off_t, int);
-#else
-/* What the bloody hell is THAT ??? */
-static int iop_get_proc_info(char *, char **, off_t, int) {}
 #endif /* CONFIG_PROC_FS */
 
 /* structure for tracking channel listeners */
@@ -307,7 +301,11 @@
 		iop_listeners[IOP_NUM_ISM][i].handler = NULL;
 	}
 
-	create_proc_info_entry("mac_iop",0,0,iop_get_proc_info);
+#if 0	/* Crashing in 2.4 now, not yet sure why.   --jmt */
+#ifdef CONFIG_PROC_FS
+	create_proc_info_entry("mac_iop", 0, &proc_root, iop_get_proc_info);
+#endif
+#endif
 }
 
 /*
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/mac/macints.c linux/arch/m68k/mac/macints.c
--- v2.4.5/linux/arch/m68k/mac/macints.c	Sun Dec  3 17:48:19 2000
+++ linux/arch/m68k/mac/macints.c	Mon Jun 11 19:15:27 2001
@@ -129,9 +129,13 @@
 #include <asm/macintosh.h>
 #include <asm/mac_via.h>
 #include <asm/mac_psc.h>
+#include <asm/hwtest.h>
 
 #include <asm/macints.h>
 
+#define DEBUG_SPURIOUS
+#define SHUTUP_SONIC
+
 /*
  * The mac_irq_list array is an array of linked lists of irq_node_t nodes.
  * Each node contains one handler to be called whenever the interrupt
@@ -233,6 +237,17 @@
 
 	scc_mask = 0;
 
+	/* Make sure the SONIC interrupt is cleared or things get ugly */
+#ifdef SHUTUP_SONIC
+	printk("Killing onboard sonic... ");
+	/* This address should hopefully be mapped already */
+	if (hwreg_present((void*)(0x50f0a000))) {
+		*(long *)(0x50f0a014) = 0x7fffL;
+		*(long *)(0x50f0a010) = 0L;
+	}
+	printk("Done.\n");
+#endif /* SHUTUP_SONIC */
+
 	/* 
 	 * Now register the handlers for the the master IRQ handlers
 	 * at levels 1-7. Most of the work is done elsewhere.
@@ -627,9 +642,7 @@
 void mac_default_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
 #ifdef DEBUG_SPURIOUS
-	if (console_loglevel > 6) {
-		printk("Unexpected IRQ %d on device %p\n", irq, dev_id);
-	}
+	printk("Unexpected IRQ %d on device %p\n", irq, dev_id);
 #endif
 }
 
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/mac/misc.c linux/arch/m68k/mac/misc.c
--- v2.4.5/linux/arch/m68k/mac/misc.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/m68k/mac/misc.c	Mon Jun 11 19:15:27 2001
@@ -2,7 +2,6 @@
  * Miscellaneous Mac68K-specific stuff 
  */
 
-#include <stdarg.h>
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/errno.h>
@@ -12,7 +11,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/time.h>
-#include <linux/kd.h>
+
 #include <linux/mm.h>
 
 #include <linux/adb.h>
@@ -21,6 +20,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
+#include <asm/rtc.h>
 #include <asm/system.h>
 #include <asm/segment.h>
 #include <asm/setup.h>
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/mac/psc.c linux/arch/m68k/mac/psc.c
--- v2.4.5/linux/arch/m68k/mac/psc.c	Sun Dec  3 17:48:19 2000
+++ linux/arch/m68k/mac/psc.c	Mon Jun 11 19:15:27 2001
@@ -139,7 +139,6 @@
 	int irq_bit,i;
 	unsigned char events;
 
-	irq -= VEC_SPUR;
 	base_irq = irq << 3;
 
 #ifdef DEBUG_IRQS
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/mac/via.c linux/arch/m68k/mac/via.c
--- v2.4.5/linux/arch/m68k/mac/via.c	Sun Dec  3 17:45:20 2000
+++ linux/arch/m68k/mac/via.c	Mon Jun 11 19:15:27 2001
@@ -410,8 +410,6 @@
 	int irq_bit, i;
 	unsigned char events, mask;
 
-	irq -= VEC_SPUR;
-
 	mask = via1[vIER] & 0x7F;
 	if (!(events = via1[vIFR] & mask)) return;
 
@@ -423,6 +421,7 @@
 			via1[vIER] = irq_bit | 0x80;
 		}
 
+#if 0 /* freakin' pmu is doing weird stuff */
 	if (!oss_present) {
 		/* This (still) seems to be necessary to get IDE
 		   working.  However, if you enable VBL interrupts,
@@ -435,14 +434,13 @@
 		mac_do_irq_list(IRQ_MAC_NUBUS, regs);
 		via_irq_enable(IRQ_MAC_NUBUS);
 	}
+#endif
 }
 
 void via2_irq(int irq, void *dev_id, struct pt_regs *regs)
 {
 	int irq_bit, i;
 	unsigned char events, mask;
-
-	irq -= VEC_SPUR;
 
 	mask = via2[gIER] & 0x7F;
 	if (!(events = via2[gIFR] & mask)) return;
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/math-emu/multi_arith.h linux/arch/m68k/math-emu/multi_arith.h
--- v2.4.5/linux/arch/m68k/math-emu/multi_arith.h	Sun Aug 15 11:47:29 1999
+++ linux/arch/m68k/math-emu/multi_arith.h	Mon Jun 11 19:15:27 2001
@@ -329,7 +329,7 @@
 	int carry;
 
 	/* we assume here, gcc only insert move and a clr instr */
-	asm volatile ("add.b %1,%0" : "=d,=g" (dest->lowmant)
+	asm volatile ("add.b %1,%0" : "=d,g" (dest->lowmant)
 		: "g,d" (src->lowmant), "0,0" (dest->lowmant));
 	asm volatile ("addx.l %1,%0" : "=d" (dest->mant.m32[1])
 		: "d" (src->mant.m32[1]), "0" (dest->mant.m32[1]));
@@ -360,7 +360,7 @@
 extern inline void fp_submant(struct fp_ext *dest, struct fp_ext *src1, struct fp_ext *src2)
 {
 	/* we assume here, gcc only insert move and a clr instr */
-	asm volatile ("sub.b %1,%0" : "=d,=g" (dest->lowmant)
+	asm volatile ("sub.b %1,%0" : "=d,g" (dest->lowmant)
 		: "g,d" (src2->lowmant), "0,0" (src1->lowmant));
 	asm volatile ("subx.l %1,%0" : "=d" (dest->mant.m32[1])
 		: "d" (src2->mant.m32[1]), "0" (src1->mant.m32[1]));
@@ -383,7 +383,7 @@
 })
 #define fp_addx96(dest, src) ({						\
 	/* we assume here, gcc only insert move and a clr instr */	\
-	asm volatile ("add.l %1,%0" : "=d,=g" (dest->m32[2])		\
+	asm volatile ("add.l %1,%0" : "=d,g" (dest->m32[2])		\
 		: "g,d" (temp.m32[1]), "0,0" (dest->m32[2]));		\
 	asm volatile ("addx.l %1,%0" : "=d" (dest->m32[1])		\
 		: "d" (temp.m32[0]), "0" (dest->m32[1]));		\
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/mm/init.c linux/arch/m68k/mm/init.c
--- v2.4.5/linux/arch/m68k/mm/init.c	Mon Oct 16 12:58:51 2000
+++ linux/arch/m68k/mm/init.c	Mon Jun 11 19:15:27 2001
@@ -32,11 +32,7 @@
 #include <asm/atari_stram.h>
 #endif
 
-static unsigned long totalram_pages;
-
-#ifdef CONFIG_SUN3
-void mmu_emu_reserve_pages(unsigned long max_page);
-#endif
+unsigned long totalram_pages = 0;
 
 int do_check_pgt_cache(int low, int high)
 {
@@ -86,7 +82,7 @@
 void show_mem(void)
 {
     unsigned long i;
-    int free = 0, total = 0, reserved = 0, nonshared = 0, shared = 0;
+    int free = 0, total = 0, reserved = 0, shared = 0;
     int cached = 0;
 
     printk("\nMem-info:\n");
@@ -101,15 +97,12 @@
 	    cached++;
 	else if (!page_count(mem_map+i))
 	    free++;
-	else if (page_count(mem_map+i) == 1)
-	    nonshared++;
 	else
 	    shared += page_count(mem_map+i) - 1;
     }
     printk("%d pages of RAM\n",total);
     printk("%d free pages\n",free);
     printk("%d reserved pages\n",reserved);
-    printk("%d pages nonshared\n",nonshared);
     printk("%d pages shared\n",shared);
     printk("%d pages swap cached\n",cached);
     printk("%ld pages in page table cache\n",pgtable_cache_size);
@@ -137,17 +130,11 @@
 
 #ifdef CONFIG_ATARI
 	if (MACH_IS_ATARI)
-		atari_stram_reserve_pages( start_mem );
-#endif
-
-#ifdef CONFIG_SUN3
-	/* reserve rom pages */
-	mmu_emu_reserve_pages(max_mapnr);
+		atari_stram_mem_init_hook();
 #endif
 
 	/* this will put all memory onto the freelists */
 	totalram_pages = free_all_bootmem();
-	printk("tp:%ld\n", totalram_pages);
 
 	for (tmp = PAGE_OFFSET ; tmp < (unsigned long)high_memory; tmp += PAGE_SIZE) {
 #if 0
@@ -201,13 +188,15 @@
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
+	int pages = 0;
 	for (; start < end; start += PAGE_SIZE) {
 		ClearPageReserved(virt_to_page(start));
 		set_page_count(virt_to_page(start), 1);
 		free_page(start);
 		totalram_pages++;
+		pages++;
 	}
-	printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+	printk ("Freeing initrd memory: %dk freed\n", pages);
 }
 #endif
 
@@ -220,15 +209,8 @@
     val->sharedram = 0;
     val->freeram = nr_free_pages();
     val->bufferram = atomic_read(&buffermem_pages);
-    while (i-- > 0) {
-	if (PageReserved(mem_map+i))
-	    continue;
-	val->totalram++;
-	if (!page_count(mem_map+i))
-	    continue;
-	val->sharedram += page_count(mem_map+i) - 1;
-    }
     val->totalhigh = 0;
     val->freehigh = 0;
+    val->mem_unit = PAGE_SIZE;
     return;
 }
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/mm/memory.c linux/arch/m68k/mm/memory.c
--- v2.4.5/linux/arch/m68k/mm/memory.c	Sat May 19 17:43:05 2001
+++ linux/arch/m68k/mm/memory.c	Mon Jun 11 19:15:27 2001
@@ -39,6 +39,7 @@
 	pgd_set(pgd, (pmd_t *)BAD_PAGETABLE);
 }
 
+#if 0
 pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
 {
 	pte_t *pte;
@@ -63,7 +64,9 @@
 	}
 	return (pte_t *)__pmd_page(*pmd) + offset;
 }
+#endif
 
+#if 0
 pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset)
 {
 	pmd_t *pmd;
@@ -84,7 +87,7 @@
 	}
 	return (pmd_t *)__pgd_page(*pgd) + offset;
 }
-
+#endif
 
 /* ++andreas: {get,free}_pointer_table rewritten to use unused fields from
    struct page instead of separately kmalloced struct.  Stolen from
@@ -250,6 +253,10 @@
 	if (voff == 0)
 		return m68k_memory[i-1].addr + m68k_memory[i-1].size;
 
+	/* As a special case allow `__pa(high_memory)'.  */
+	if (voff == 0)
+		return m68k_memory[i-1].addr + m68k_memory[i-1].size;
+
 	return mm_vtop_fallback(vaddr);
 }
 #endif
@@ -454,16 +461,21 @@
 			      ".chip 68k"		\
 			      : : "a" (paddr))
 
-/* push and invalidate page in both caches */
+/* push and invalidate page in both caches, must disable ints
+ * to avoid invalidating valid data */
 #define	pushcl040(paddr)			\
-	do { push040(paddr);			\
+	do { unsigned long flags;               \
+             save_flags(flags);                 \
+	     cli();                             \
+             push040(paddr);			\
 	     if (CPU_IS_060) clear040(paddr);	\
+	     restore_flags(flags);              \
 	} while(0)
 
 /* push page in both caches, invalidate in i-cache */
+/* RZ: cpush %bc DOES invalidate %ic, regardless of DPI */
 #define	pushcli040(paddr)			\
 	do { push040(paddr);			\
-	     if (CPU_IS_060) cleari040(paddr);	\
 	} while(0)
 
 
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/mvme147/config.c linux/arch/m68k/mvme147/config.c
--- v2.4.5/linux/arch/m68k/mvme147/config.c	Mon Nov 27 17:11:26 2000
+++ linux/arch/m68k/mvme147/config.c	Mon Jun 11 19:15:27 2001
@@ -16,7 +16,6 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/linkage.h>
@@ -29,6 +28,7 @@
 #include <asm/setup.h>
 #include <asm/irq.h>
 #include <asm/traps.h>
+#include <asm/rtc.h>
 #include <asm/machdep.h>
 #include <asm/mvme147hw.h>
 
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/mvme16x/config.c linux/arch/m68k/mvme16x/config.c
--- v2.4.5/linux/arch/m68k/mvme16x/config.c	Mon Jan 31 10:32:53 2000
+++ linux/arch/m68k/mvme16x/config.c	Mon Jun 11 19:15:27 2001
@@ -17,7 +17,6 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/linkage.h>
@@ -30,11 +29,10 @@
 #include <asm/setup.h>
 #include <asm/irq.h>
 #include <asm/traps.h>
+#include <asm/rtc.h>
 #include <asm/machdep.h>
 #include <asm/mvme16xhw.h>
 
-int atari_SCC_reset_done = 1;		/* So SCC doesn't get reset */
-u_long atari_mch_cookie = 0;
 extern t_bdid mvme_bdid;
 
 static MK48T08ptr_t volatile rtc = (MK48T08ptr_t)MVME_RTC_BASE;
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/mvme16x/rtc.c linux/arch/m68k/mvme16x/rtc.c
--- v2.4.5/linux/arch/m68k/mvme16x/rtc.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/m68k/mvme16x/rtc.c	Mon Jun 11 19:15:27 2001
@@ -72,7 +72,7 @@
 		unsigned char mon, day, hrs, min, sec, leap_yr;
 		unsigned int yrs;
 
-		if (!suser())
+		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
 
 		if (copy_from_user(&rtc_tm, (struct rtc_time*)arg,
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/q40/README linux/arch/m68k/q40/README
--- v2.4.5/linux/arch/m68k/q40/README	Tue Mar  6 19:44:36 2001
+++ linux/arch/m68k/q40/README	Mon Jun 11 19:15:27 2001
@@ -3,43 +3,48 @@
 
 You may try http://www.geocities.com/SiliconValley/Bay/2602/ for
 some up to date information. Booter and other tools will be also
-available from this place and ftp.uni-erlangen.de/linux/680x0/q40/
+available from this place or ftp.uni-erlangen.de/linux/680x0/q40/
 and mirrors.
 
 Hints to documentation usually refer to the linux source tree in
 /usr/src/linux/Documentation unless URL given.
 
-It seems IRQ unmasking can't be safely done on a Q40. Autoprobing is 
-not yet implemented - do not try it! (See below)
+It seems IRQ unmasking can't be safely done on a Q40. IRQ probing 
+is not implemented - do not try it! (See below)
 
-For a list of kernel commandline options read the documentation for the
+For a list of kernel command-line options read the documentation for the
 particular device drivers.
 
 The floppy imposes a very high interrupt load on the CPU, approx 30K/s.
 When something blocks interrupts (HD) it will loose some of them, so far 
-this is not known to have caused any data loss. On hihgly loaded systems
-it can make the floppy very slow or practicaly stop. Other Q40 OS' simply 
+this is not known to have caused any data loss. On highly loaded systems
+it can make the floppy very slow or practically stop. Other Q40 OS' simply 
 poll the floppy for this reason - something that can't be done in Linux.
-Only possible cure is getting a 82072 contoler with fifo instead of 
-the 8272A
+Only possible cure is getting a 82072 controller with fifo instead of 
+the 8272A.
 
-drivers used by the Q40, appart from the very obvious (console etc.):
+drivers used by the Q40, apart from the very obvious (console etc.):
 	drivers/char/q40_keyb.c		# use PC keymaps for national keyboards
 		     serial.c		# normal PC driver - any speed
 	             lp.c		# printer driver
-		char/joystick/*		# most of this should work
+		     genrtc.c		# RTC
+		char/joystick/*		# most of this should work, not 
+				        # in default config.in
 	        block/q40ide.c		# startup for ide
 		      ide*		# see Documentation/ide.txt
 		      floppy.c		# normal PC driver, DMA emu in asm/floppy.h
 					# and arch/m68k/kernel/entry.S
 					# see drivers/block/README.fd
+		net/ne.c
 		video/q40fb.c
-		misc/parport_pc.c
+		parport/*
+		sound/dmasound_core.c
+		      dmasound_q40.c
 
 Various other PC drivers can be enabled simply by adding them to 
 arch/m68k/config.in, especially 8 bit devices should be without any
 problems. For cards using 16bit io/mem more care is required, like 
-checking byteorder issues, hacking memcpy_*_io etc.
+checking byte order issues, hacking memcpy_*_io etc.
 
 
 Debugging
@@ -47,7 +52,7 @@
 
 Upon startup the kernel will usually output "ABCQGHIJ" into the SRAM, 
 preceded by the booter signature. This is a trace just in case something 
-went wrong during earliest setup stages. 
+went wrong during earliest setup stages of head.S. 
 **Changed** to preserve SRAM contents by default, this is only done when 
 requested - SRAM must start with '%LX$' signature to do this. '-d' option 
 to 'lxx' loader enables this.
@@ -55,13 +60,15 @@
 SRAM can also be used as additional console device, use debug=mem.
 This will save kernel startup msgs into SRAM, the screen will display 
 only the penguin - and shell prompt if it gets that far..
+Unfortunately only 2000 bytes are available.
 
 Serial console works and can also be used for debugging, see loader_txt
 
 Most problems seem to be caused by fawlty or badly configured io-cards or 
-harddrives anyway..there are so many things that can go wrong here.
-Make sure to configure the parallel port as SPP for first testing..the
-Q40 may have trouble with parallel interrupts.
+hard drives anyway.
+Make sure to configure the parallel port as SPP and remove IRQ/DMA jumpers
+for first testing. The Q40 does not support DMA and may have trouble with
+parallel ports version of interrupts.
 
 
 Q40 Hardware Description
@@ -71,30 +78,27 @@
 questions.
 
 The Q40 consists of a 68040@40 MHz, 1MB video RAM, up to 32MB RAM, AT-style
-keyboard interface, 1 Programmable LED, 2 8bit DACs and up to 1MB ROM, 1MB
+keyboard interface, 1 Programmable LED, 2x8bit DACs and up to 1MB ROM, 1MB
 shadow ROM.
+The Q60 has any of 68060 or 68LC060 and up to 128 MB RAM.
 
-Most interfacing like floppy, hd, serial, parallel ports is done via ISA 
+Most interfacing like floppy, IDE, serial and parallel ports is done via ISA 
 slots. The ISA io and mem range is mapped (sparse&byteswapped!) into separate 
 regions of the memory.
 The main interrupt register IIRQ_REG will indicate whether an IRQ was internal 
 or from some ISA devices, EIRQ_REG can distinguish up to 8 ISA IRQs.
 
 The Q40 custom chip is programmable to provide 2 periodic timers:
-	- 50 or 200 Hz - level 2,
-	- 10 or 20 KHz - level 4 
-  !!THIS CANT BE DISABLED!!
-
+	- 50 or 200 Hz - level 2, !!THIS CANT BE DISABLED!!
+	- 10 or 20 KHz - level 4, used for dma-sound 
+  
 Linux uses the 200 Hz interrupt for timer and beep by default.
 
 
 Interrupts
 ==========
 
-q40 master chip handles only level triggered interrupts :-((
-
-IRQ sharing is not yet implemented but this should be only a minor
-problem..
+q40 master chip handles only a subset of level triggered interrupts.
 
 Linux has some requirements wrt interrupt architecture, these are
 to my knowledge:
@@ -103,27 +107,28 @@
 	(b) working enable/disable_irq
 
 Luckily these requirements are only important for drivers shared
-with other architectures - ide,serial,parallel, ethernet..
+with other architectures - ide,serial,parallel, ethernet.
 q40ints.c now contains a trivial hack for (a), (b) is more difficult
-because only irq's 4-15 can be disabled - and only all o them at once.
+because only irq's 4-15 can be disabled - and only all of them at once.
 Thus disable_irq() can effectively block the machine if the driver goes
 asleep.
-One thing to keep in minde when hacking around the interrupt code is 
-that there is no way to find out which IRQ caused a request.
+One thing to keep in mind when hacking around the interrupt code is 
+that there is no way to find out which IRQ caused a request, [EI]IRQ_REG
+displays current state of the various IRQ lines.
 
 Keyboard
 ========
 
 q40 receives AT make/break codes from the keyboard, these are translated to
 the PC scancodes x86 Linux uses. So by theory every national keyboard should
-work just by loading the apropriate x86 keytable - see any national-HOWTO.
+work just by loading the appropriate x86 keytable - see any national-HOWTO.
 
 Unfortunately the AT->PC translation isn't quite trivial and even worse, my 
 documentation of it is absolutely minimal - thus some exotic keys may not 
 behave exactly as expected.
 
 There is still hope that it can be fixed completely though. If you encounter 
-problems, email me idealy this:
+problems, email me ideally this:
 	- exact keypress/release sequence
 	- 'showkey -s' run on q40, non-X session
 	- 'showkey -s' run on a PC, non-X session
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/q40/config.c linux/arch/m68k/q40/config.c
--- v2.4.5/linux/arch/m68k/q40/config.c	Fri Apr  6 10:42:48 2001
+++ linux/arch/m68k/q40/config.c	Mon Jun 11 19:15:27 2001
@@ -13,11 +13,9 @@
  */
 
 #include <linux/config.h>
-#include <stdarg.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/linkage.h>
@@ -25,6 +23,7 @@
 #include <linux/major.h>
 #include <linux/serial_reg.h>
 
+#include <asm/io.h>
 #include <asm/rtc.h>
 #include <asm/bootinfo.h>
 #include <asm/system.h>
@@ -32,6 +31,7 @@
 #include <asm/setup.h>
 #include <asm/irq.h>
 #include <asm/traps.h>
+#include <asm/rtc.h>
 #include <asm/machdep.h>
 #include <asm/q40_master.h>
 #include <asm/keyboard.h>
@@ -39,6 +39,8 @@
 extern void floppy_eject(void);
 extern void floppy_setup(char *str, int *ints);
 
+extern int q40kbd_translate(unsigned char scancode, unsigned char *keycode,
+			    char raw_mode);
 extern void q40_process_int (int level, struct pt_regs *regs);
 extern void (*q40_sys_default_handler[]) (int, void *, struct pt_regs *);  /* added just for debugging */
 extern void q40_init_IRQ (void);
@@ -50,16 +52,17 @@
 static int  q40_get_hardware_list(char *buffer);
 extern int  q40_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
 extern void q40_sched_init(void (*handler)(int, void *, struct pt_regs *));
-extern int  q40_keyb_init(void);
-extern int  q40_kbdrate (struct kbd_repeat *);
+
 extern unsigned long q40_gettimeoffset (void);
 extern void q40_gettod (int *year, int *mon, int *day, int *hour,
                            int *min, int *sec);
 extern int q40_hwclk (int, struct hwclk_time *);
 extern int q40_set_clock_mmss (unsigned long);
 extern void q40_reset (void);
+void q40_halt(void);
 extern void q40_waitbut(void);
 void q40_set_vectors (void);
+
 extern void (*kd_mksound)(unsigned int, unsigned int);
 void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/ );
 
@@ -67,16 +70,9 @@
 extern char m68k_debug_device[];
 static void q40_mem_console_write(struct console *co, const char *b,
 				    unsigned int count);
-#if 0
-extern int ql_ticks=0;
-extern int sound_ticks=0;
-#endif
 
 extern int ql_ticks;
 
-static unsigned char bcd2bin (unsigned char b);
-static unsigned char bin2bcd (unsigned char b);
-
 static int q40_wait_key(struct console *co){return 0;}
 static struct console q40_console_driver = {
 	name:		"debug",
@@ -90,11 +86,13 @@
 extern char *q40_mem_cptr; /*=(char *)0xff020000;*/
 static int _cpleft;
 
+#if 0
 int q40_kbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode)
 {
         *keycodep = keycode;
         return 1;
 }
+#endif
 
 static void q40_mem_console_write(struct console *co, const char *s,
 				  unsigned int count)
@@ -130,13 +128,36 @@
 }
 #endif
 
-void q40_reset()
+static int halted=0;
+
+#ifdef CONFIG_HEARTBEAT
+static void q40_heartbeat(int on)
 {
+  if (halted) return;
 
+  if (on)
+    Q40_LED_ON();
+  else
+    Q40_LED_OFF();
+}
+#endif
+
+void q40_reset()
+{
+        halted=1;
         printk ("\n\n*******************************************\n"
 		"Called q40_reset : press the RESET button!! \n"
 		"*******************************************\n");
-	
+	Q40_LED_ON();
+	while(1) ;
+}
+void q40_halt()
+{
+        halted=1;
+        printk ("\n\n*******************\n"
+		    "  Called q40_halt\n"
+		    "*******************\n");
+	Q40_LED_ON();
 	while(1) ;
 }
 
@@ -202,17 +223,17 @@
 
 void __init config_q40(void)
 {
-    mach_sched_init      = q40_sched_init;           /* ok */
-    /*mach_kbdrate         = q40_kbdrate;*/          /* unneeded ?*/
-    mach_keyb_init       = q40_keyb_init;            /* OK */
-    mach_kbd_translate   = q40_kbd_translate;
+    mach_sched_init      = q40_sched_init;
+
+    mach_keyb_init       = q40kbd_init_hw;
+    mach_kbd_translate   = q40kbd_translate;
     mach_init_IRQ        = q40_init_IRQ;   
     mach_gettimeoffset   = q40_gettimeoffset; 
     mach_gettod  	 = q40_gettod;
     mach_hwclk           = q40_hwclk; 
     mach_set_clock_mmss	 = q40_set_clock_mmss;
-/*  mach_mksound         = q40_mksound; */
-    mach_reset		 = q40_reset;           /* use reset button instead !*/
+
+    mach_reset		 = q40_reset;
     mach_free_irq	 = q40_free_irq; 
     mach_process_int	 = q40_process_int;
     mach_get_irq_list	 = q40_get_irq_list;
@@ -220,26 +241,28 @@
     enable_irq		 = q40_enable_irq;
     disable_irq          = q40_disable_irq;
     mach_default_handler = &q40_sys_default_handler;
-    mach_get_model       = q40_get_model; /* no use..*/
-    mach_get_hardware_list = q40_get_hardware_list; /* no use */
+    mach_get_model       = q40_get_model;
+    mach_get_hardware_list = q40_get_hardware_list;
     kd_mksound             = q40_mksound;
-    /*mach_kbd_leds        = q40kbd_leds;*/
+
 #ifdef CONFIG_MAGIC_SYSRQ
     mach_sysrq_key       = 0x54;
 #endif
-    conswitchp = &dummy_con;
-#if 0 /*def CONFIG_BLK_DEV_FD*/
-    mach_floppy_setup    = floppy_setup;
-    mach_floppy_eject    = floppy_eject;
-    /**/
+#ifdef CONFIG_HEARTBEAT
+    mach_heartbeat = q40_heartbeat;
 #endif
+    mach_halt = q40_halt;
+    conswitchp = &dummy_con;
 
+    /* disable a few things that SMSQ might have left enabled */
     q40_disable_irqs();
-    mach_max_dma_address = 32*1024*1024;   /* no DMA at all, but ide-scsi requires it.. */
 
+    /* no DMA at all, but ide-scsi requires it.. make sure
+     * all physical RAM fits into the boundary - otherwise 
+     * allocator may play costly and useless tricks */
+    mach_max_dma_address = 1024*1024*1024;   
 
-/* useful for early debugging stages - writes kernel messages into SRAM */
-
+    /* useful for early debugging stages - writes kernel messages into SRAM */
     if (!strncmp( m68k_debug_device,"mem",3 ))
       {
 	/*printk("using NVRAM debug, q40_mem_cptr=%p\n",q40_mem_cptr);*/
@@ -252,109 +275,24 @@
 
 int q40_parse_bootinfo(const struct bi_record *rec)
 {
-  return 1;  /* unknown */
+  return 1;
 }
 
-#if 0
-#define DAC_LEFT  ((unsigned char *)0xff008000)
-#define DAC_RIGHT ((unsigned char *)0xff008004)
-void q40_mksound(unsigned int hz, unsigned int ticks)
-{
-  /* for now ignore hz, except that hz==0 switches off sound */
-  /* simply alternate the ampl 0-255-0-.. at 200Hz */
-  if (hz==0)
-    {
-      if (sound_ticks)
-	sound_ticks=1; /* atomic - no irq spinlock used */
-
-      *DAC_LEFT=0;
-      *DAC_RIGHT=0;
 
-      return;
-    }
-  /* sound itself is done in q40_timer_int */
-  if (sound_ticks == 0) sound_ticks=1000; /* pretty long beep */
-  sound_ticks=ticks<<1;
-}
-
-static void (*q40_timer_routine)(int, void *, struct pt_regs *);
-static short rtc_oldsecs=0;
-unsigned rtc_irq_flags=0;
-unsigned rtc_irq_ctrl=0;
-
-static void q40_timer_int (int irq, void *dev_id, struct pt_regs *fp)
-{
-#if (HZ==10000)
-    master_outb(-1,SAMPLE_CLEAR_REG);
-#else /* must be 50 or 100 */
-    master_outb(-1,FRAME_CLEAR_REG);
-#endif
-
-#if (HZ==100)
-    ql_ticks = ql_ticks ? 0 : 1;
-    if (sound_ticks)
-      {
-	unsigned char sval=(sound_ticks & 1) ? 0 : 255;
-	sound_ticks--;
-	*DAC_LEFT=sval;
-	*DAC_RIGHT=sval;
-      }
-#ifdef CONFIG_Q40RTC
-    if (rtc_irq_ctrl && (rtc_oldsecs != RTC_SECS))
-      {
-	rtc_oldsecs = RTC_SECS;
-	rtc_irq_flags = RTC_UIE;
-	rtc_interrupt();
-      }
-#endif
-    if (ql_ticks) return;
-#endif
-    q40_timer_routine(irq, dev_id, fp);
+static inline unsigned char bcd2bin (unsigned char b)
+{
+	return ((b>>4)*10 + (b&15));
 }
-#endif
 
-#if 0
-extern void (*q40_timer_routine)(int, void *, struct pt_regs *);
-extern void q40_timer_int();
-
-void q40_sched_init (void (*timer_routine)(int, void *, struct pt_regs *))
+static inline unsigned char bin2bcd (unsigned char b)
 {
-    int timer_irq;
-
-    q40_timer_routine = timer_routine;
-
-#if (HZ==10000)
-    timer_irq=Q40_IRQ_TIMER;
-#else
-    timer_irq=Q40_IRQ_FRAME;
-#endif
-
-    /*printk("registering sched/timer IRQ %d\n", timer_irq);*/
-
-    if (request_irq(timer_irq, q40_timer_int, 0,
-				"timer", q40_timer_int))
-	panic ("Couldn't register timer int");
-
-#if (HZ==10000)
-    master_outb(SAMPLE_LOW,SAMPLE_RATE_REG);
-    master_outb(-1,SAMPLE_CLEAR_REG);
-    master_outb(1,SAMPLE_ENABLE_REG);
-#else
-    master_outb(-1,FRAME_CLEAR_REG);   /* not necessary ? */
-#if (HZ==100)
-    master_outb( 1,FRAME_RATE_REG);
-#endif
-#endif
+	return (((b/10)*16) + (b%10));
 }
-#endif
+
 
 unsigned long q40_gettimeoffset (void)
 {
-#if (HZ==100)
     return 5000*(ql_ticks!=0);
-#else
-    return 0;
-#endif
 }
 
 extern void q40_gettod (int *year, int *mon, int *day, int *hour,
@@ -362,7 +300,7 @@
 {
 	RTC_CTRL |= RTC_READ;
 	*year = bcd2bin (RTC_YEAR);
-	*mon = bcd2bin (RTC_MNTH)-1;
+	*mon = bcd2bin (RTC_MNTH);
 	*day = bcd2bin (RTC_DATE);
 	*hour = bcd2bin (RTC_HOUR);
 	*min = bcd2bin (RTC_MINS);
@@ -371,15 +309,6 @@
 
 }
 
-static unsigned char bcd2bin (unsigned char b)
-{
-	return ((b>>4)*10 + (b&15));
-}
-
-static unsigned char bin2bcd (unsigned char b)
-{
-	return (((b/10)*16) + (b%10));
-}
 
 
 /*
@@ -439,8 +368,6 @@
 /*
  * Set the minutes and seconds from seconds value 'nowtime'.  Fail if
  * clock is out by > 30 minutes.  Logic lifted from atari code.
- * Algorithm is to wait for the 10ms register to change, and then to
- * wait a short while, and then set it.
  */
 
 int q40_set_clock_mmss (unsigned long nowtime)
@@ -469,18 +396,3 @@
 	return retval;
 }
 
-extern void q40kbd_init_hw(void);
-
-int q40_keyb_init (void)
-{
-        q40kbd_init_hw();
-	return 0;
-}
-
-#if 0
-/* dummy to cause */
-void q40_slow_io()
-{
-  return;
-}
-#endif
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/q40/q40ints.c linux/arch/m68k/q40/q40ints.c
--- v2.4.5/linux/arch/m68k/q40/q40ints.c	Mon Nov 27 17:11:26 2000
+++ linux/arch/m68k/q40/q40ints.c	Mon Jun 11 19:15:27 2001
@@ -1,7 +1,7 @@
 /*
  * arch/m68k/q40/q40ints.c
  *
- * Copyright (C) 1999 Richard Zidlicky
+ * Copyright (C) 1999,2001 Richard Zidlicky
  *
  * 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
@@ -44,7 +44,7 @@
 void q40_irq2_handler (int, void *, struct pt_regs *fp);
 
 
-extern void (*q40_sys_default_handler[]) (int, void *, struct pt_regs *);  /* added just for debugging */
+extern void (*q40_sys_default_handler[]) (int, void *, struct pt_regs *);
 
 static void q40_defhand (int irq, void *dev_id, struct pt_regs *fp);
 static void sys_default_handler(int lev, void *dev_id, struct pt_regs *regs);
@@ -97,9 +97,9 @@
 	sys_request_irq(IRQ2,q40_irq2_handler, 0, "q40 ISA and master chip", NULL);
 
 	/* now enable some ints.. */
-	master_outb(1,EXT_ENABLE_REG);  /* hm, aint that too early? */
+	master_outb(1,EXT_ENABLE_REG);  /* ISA IRQ 5-15 */
 
-	/* would be spurious ints by now, q40kbd_init_hw() does that */
+	/* make sure keyboard IRQ is disabled */
 	master_outb(0,KEY_IRQ_ENABLE_REG);
 }
 
@@ -139,7 +139,7 @@
 	    if (dev_id==NULL)
 		  {
 		printk("WARNING: dev_id == NULL in request_irq\n");
-		dev_id=1;
+		dev_id=(void*)1;
 	      }
 	    irq_tab[irq].handler = handler;
 	    irq_tab[irq].flags   = flags;
@@ -202,7 +202,8 @@
 /* 
  * this stuff doesn't really belong here..
 */
-int ql_ticks=0;
+
+int ql_ticks=0;              /* 200Hz ticks since last jiffie */
 static int sound_ticks=0;
 
 #define SVOL 45
@@ -214,7 +215,7 @@
   if (hz==0)
     {
       if (sound_ticks)
-	sound_ticks=1; /* atomic - no irq spinlock used */
+	sound_ticks=1;
 
       *DAC_LEFT=128;
       *DAC_RIGHT=128;
@@ -227,14 +228,9 @@
 }
 
 static void (*q40_timer_routine)(int, void *, struct pt_regs *);
-static short rtc_oldsecs=0;
-unsigned rtc_irq_flags=0;
-unsigned rtc_irq_ctrl=0;
 
 static void q40_timer_int (int irq, void * dev, struct pt_regs * regs)
 {
-
-  
 #if (HZ==100)
     ql_ticks = ql_ticks ? 0 : 1;
     if (sound_ticks)
@@ -244,12 +240,12 @@
 	*DAC_LEFT=sval;
 	*DAC_RIGHT=sval;
       }
-#ifdef CONFIG_Q40RTC
-    if (rtc_irq_ctrl && (rtc_oldsecs != RTC_SECS))
+#if defined(CONFIG_Q40RTC) || defined(CONFIG_GEN_RTC)
+    if (gen_rtc_irq_ctrl && (q40rtc_oldsecs != RTC_SECS))
       {
-	rtc_oldsecs = RTC_SECS;
-	rtc_irq_flags = RTC_UIE;
-	rtc_interrupt();
+	q40rtc_oldsecs = RTC_SECS;
+	gen_rtc_irq_flags = RTC_UIE;
+	gen_rtc_interrupt(0);
       }
 #endif
     if (ql_ticks) return;
@@ -322,16 +318,14 @@
 static int ccleirq=60;    /* ISA dev IRQ's*/
 /*static int cclirq=60;*/     /* internal */
 
-/* FIX: add shared ints,mask,unmask,probing.... */
-
+/* FIXME: add shared ints,mask,unmask,probing.... */
 
 #define IRQ_INPROGRESS 1
 /*static unsigned short saved_mask;*/
 static int do_tint=0;
 
 #define DEBUG_Q40INT
-#define IP_USE_DISABLE /* would be nice, but crashes ???? */
-/*static int dd_count=0;*/
+/*#define IP_USE_DISABLE *//* would be nice, but crashes ???? */
 
 static int mext_disabled=0;  /* ext irq disabled by master chip? */
 static int aliased_irq=0;  /* how many times inside handler ?*/
@@ -404,40 +398,36 @@
 		    if ( disabled ) 
 		      {
 #ifdef IP_USE_DISABLE
-		  if (irq>4){
-		    disabled=0;
-		    /*dd_count--;*/
-		    enable_irq(irq);}
+			if (irq>4){
+			  disabled=0;
+			  enable_irq(irq);}
 #else
-		  disabled=0;
+			disabled=0;
 			/*printk("reenabling irq %d\n",irq); */
-#if 0
-		  fp->sr = ((fp->sr) & (~0x700)); /* unneeded ?! */
-#endif
 #endif
 		      }
 	      goto repeat;  /* return;  */
 		  }
 	      }
-      if (mer && ccleirq>0 && !aliased_irq) 
+	    if (mer && ccleirq>0 && !aliased_irq) 
 	      printk("ISA interrupt from unknown source? EIRQ_REG = %x\n",mer),ccleirq--;
 	  } 
  iirq:
-  mir=master_inb(IIRQ_REG);
-  if (mir&IRQ_FRAME_MASK) 
+	mir=master_inb(IIRQ_REG);
+	if (mir&IRQ_FRAME_MASK) 
 	  {
-      do_tint++;
-      master_outb(-1,FRAME_CLEAR_REG);
-    }
-  for(;do_tint>0;do_tint--) 
-	      {
-      irq_tab[Q40_IRQ_FRAME].count++;
-      irq_tab[Q40_IRQ_FRAME].handler(Q40_IRQ_FRAME,irq_tab[Q40_IRQ_FRAME].dev_id,fp);    
-    }
-  if (mir&IRQ_KEYB_MASK) /* may handle it even if actually disabled*/
-		      {
-      irq_tab[Q40_IRQ_KEYBOARD].count++;
-      irq_tab[Q40_IRQ_KEYBOARD].handler(Q40_IRQ_KEYBOARD,irq_tab[Q40_IRQ_KEYBOARD].dev_id,fp);
+	    do_tint++;
+	    master_outb(-1,FRAME_CLEAR_REG);
+	  }
+	for(;do_tint>0;do_tint--) 
+	  {
+	    irq_tab[Q40_IRQ_FRAME].count++;
+	    irq_tab[Q40_IRQ_FRAME].handler(Q40_IRQ_FRAME,irq_tab[Q40_IRQ_FRAME].dev_id,fp);    
+	  }
+	if (mir&IRQ_KEYB_MASK) /* may handle it even if actually disabled*/
+	  {
+	    irq_tab[Q40_IRQ_KEYBOARD].count++;
+	    irq_tab[Q40_IRQ_KEYBOARD].handler(Q40_IRQ_KEYBOARD,irq_tab[Q40_IRQ_KEYBOARD].dev_id,fp);
 	  }
 }
 
@@ -499,7 +489,7 @@
 void q40_disable_irq (unsigned int irq)
 {
   /* disable ISA iqs : only do something if the driver has been
-  * verified to be Q40 "compatible" - right now only IDE
+  * verified to be Q40 "compatible" - right now IDE, NE2K
   * Any driver should not attempt to sleep accross disable_irq !!
   */
 
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/sun3/Makefile linux/arch/m68k/sun3/Makefile
--- v2.4.5/linux/arch/m68k/sun3/Makefile	Fri Dec 29 14:07:20 2000
+++ linux/arch/m68k/sun3/Makefile	Mon Jun 11 19:15:27 2001
@@ -14,7 +14,9 @@
 
 export-objs	:= sun3_ksyms.o
 
-obj-y		:= config.o idprom.o mmu_emu.o sun3ints.o leds.o dvma.o \
-			sbus.o intersil.o sun3_ksyms.o
+obj-y	:= sun3_ksyms.o sun3ints.o sun3dvma.o sbus.o
+
+obj-$(CONFIG_SUN3) += config.o idprom.o mmu_emu.o leds.o dvma.o \
+			intersil.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/sun3/config.c linux/arch/m68k/sun3/config.c
--- v2.4.5/linux/arch/m68k/sun3/config.c	Fri Dec 29 14:07:20 2000
+++ linux/arch/m68k/sun3/config.c	Mon Jun 11 19:15:27 2001
@@ -8,13 +8,10 @@
  * for more details.
  */
 
-#include <stdarg.h>
-
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/init.h>
@@ -27,10 +24,12 @@
 #include <asm/pgtable.h>
 #include <asm/sun3-head.h>
 #include <asm/sun3mmu.h>
+#include <asm/rtc.h>
 #include <asm/machdep.h>
 #include <asm/intersil.h>
 #include <asm/irq.h>
 #include <asm/segment.h>
+#include <asm/sun3ints.h>
 
 extern char _text, _end;
 
@@ -39,15 +38,6 @@
 extern unsigned long sun3_gettimeoffset(void);
 extern int sun3_get_irq_list (char *);
 extern void sun3_sched_init(void (*handler)(int, void *, struct pt_regs *));
-extern void sun3_init_IRQ (void);
-extern void (*sun3_default_handler[]) (int, void *, struct pt_regs *);
-extern int sun3_request_irq (unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
-                              unsigned long flags, const char *devname, void *dev_id);
-extern void sun3_free_irq (unsigned int irq, void *dev_id);
-extern void sun3_enable_irq (unsigned int);
-extern void sun3_disable_irq (unsigned int);
-extern void sun3_enable_interrupts (void);
-extern void sun3_disable_interrupts (void);
 extern void sun3_get_model (char* model);
 extern void idprom_init (void);
 extern void sun3_gettod (int *yearp, int *monp, int *dayp,
@@ -56,7 +46,7 @@
 
 extern void sun_serial_setup(void);
 volatile char* clock_va; 
-extern unsigned char* sun3_intreg;
+extern volatile unsigned char* sun3_intreg;
 extern unsigned long availmem;
 unsigned long num_pages;
 
@@ -76,7 +66,7 @@
 	prom_init((void *)LINUX_OPPROM_BEGVM);
 		
 	GET_CONTROL_BYTE(AC_SENABLE,enable_register);
-	enable_register |= 0x40; /* Enable FPU */	
+	enable_register |= 0x50; /* Enable FPU */	
 	SET_CONTROL_BYTE(AC_SENABLE,enable_register);
 	GET_CONTROL_BYTE(AC_SENABLE,enable_register);
 	
@@ -154,6 +144,7 @@
 //	mach_keyb_init       =  sun3_keyb_init;
 	enable_irq     	     =  sun3_enable_irq;
         disable_irq  	     =  sun3_disable_irq;
+	mach_process_int     =  sun3_process_int;
         mach_get_irq_list    =  sun3_get_irq_list;
         mach_gettod          =  sun3_gettod;	
         mach_reset           =  sun3_reboot;
@@ -161,7 +152,7 @@
 	mach_get_model	     =  sun3_get_model;
 	mach_hwclk           =  sun3_hwclk;
 	mach_halt	     =  sun3_halt;
-#ifndef CONFIG_SERIAL_CONSOLE
+#if !defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_FB)
 	conswitchp 	     = &dummy_con;
 #endif
 
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/sun3/dvma.c linux/arch/m68k/sun3/dvma.c
--- v2.4.5/linux/arch/m68k/sun3/dvma.c	Fri Dec 29 14:07:20 2000
+++ linux/arch/m68k/sun3/dvma.c	Mon Jun 11 19:15:27 2001
@@ -4,42 +4,62 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/bootmem.h>
+#include <linux/list.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/sun3mmu.h>
 #include <asm/dvma.h>
 
-unsigned long dvma_next_free = DVMA_START;
-unsigned long dvma_region_end = DVMA_START + (DVMA_RESERVED_PMEGS * SUN3_PMEG_SIZE);
 
+static unsigned long ptelist[120];
 
-/* reserve such dma memory as we see fit */
-void sun3_dvma_init(void)
+inline unsigned long dvma_page(unsigned long kaddr, unsigned long vaddr)
 {
-	unsigned long dvma_phys_start;
-	
-	dvma_phys_start = (sun3_get_pte(DVMA_START) & 
-			   SUN3_PAGE_PGNUM_MASK);
-	dvma_phys_start <<= PAGE_SHIFT;
+	unsigned long pte;
+	unsigned long j;
+	pte_t ptep;
 	
-	reserve_bootmem(dvma_phys_start,
-			(DVMA_RESERVED_PMEGS * SUN3_PMEG_SIZE));
+	j = *(volatile unsigned long *)kaddr;
+	*(volatile unsigned long *)kaddr = j;
 
-}
+	ptep = __mk_pte(kaddr, PAGE_KERNEL);
+	pte = pte_val(ptep);
+//		printk("dvma_remap: addr %lx -> %lx pte %08lx len %x\n", 
+//		       kaddr, vaddr, pte, len);
+	if(ptelist[(vaddr & 0xff000) >> PAGE_SHIFT] != pte) {
+		sun3_put_pte(vaddr, pte);
+		ptelist[(vaddr & 0xff000) >> PAGE_SHIFT] = pte;
+	}
 
-/* get needed number of free dma pages, or panic if not enough */
+	return (vaddr + (kaddr & ~PAGE_MASK));
 
-void *sun3_dvma_malloc(int len)
+}
+
+int dvma_map_iommu(unsigned long kaddr, unsigned long baddr, 
+			      int len)
 {
+
+	unsigned long end;
 	unsigned long vaddr;
 
-       	if((dvma_next_free + len) > dvma_region_end) 
-		panic("sun3_dvma_malloc: out of dvma pages");
+	vaddr = dvma_btov(baddr);
+
+	end = vaddr + len;
 	
-	vaddr = dvma_next_free;
-	dvma_next_free = DVMA_ALIGN(dvma_next_free + len);
+	while(vaddr < end) {
+		dvma_page(kaddr, vaddr);
+		kaddr += PAGE_SIZE;
+		vaddr += PAGE_SIZE;
+	}
+
+	return 0;
 
-	return (void *)vaddr;
 }
-     
 
+void sun3_dvma_init(void)
+{
+
+	memset(ptelist, 0, sizeof(ptelist));
+
+
+}
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/sun3/intersil.c linux/arch/m68k/sun3/intersil.c
--- v2.4.5/linux/arch/m68k/sun3/intersil.c	Wed Jan 26 12:44:21 2000
+++ linux/arch/m68k/sun3/intersil.c	Mon Jun 11 19:15:27 2001
@@ -11,9 +11,9 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/kd.h>
 
 #include <asm/system.h>
+#include <asm/rtc.h>
 #include <asm/intersil.h>
 
 
@@ -30,7 +30,7 @@
 void sun3_gettod (int *yearp, int *monp, int *dayp,
                    int *hourp, int *minp, int *secp)
 {
-	u_char wday;
+	unsigned char wday;
 	volatile struct intersil_dt* todintersil;
 	unsigned long flags;
 
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/sun3/mmu_emu.c linux/arch/m68k/sun3/mmu_emu.c
--- v2.4.5/linux/arch/m68k/sun3/mmu_emu.c	Fri Dec 29 14:07:20 2000
+++ linux/arch/m68k/sun3/mmu_emu.c	Mon Jun 11 19:15:27 2001
@@ -29,6 +29,7 @@
 extern void prom_reboot (char *) __attribute__ ((__noreturn__));
 
 #undef DEBUG_MMU_EMU
+#define DEBUG_PROM_MAPS
 
 /*
 ** Defines
@@ -157,9 +158,12 @@
 	j = 0;
 	for (num=0, seg=0x0F800000; seg<0x10000000; seg+=16*PAGE_SIZE) {
 		if (sun3_get_segmap (seg) != SUN3_INVALID_PMEG) {
-#ifdef DEBUG_MMU_EMU
-			printk ("mapped:");
-			print_pte_vaddr (seg);
+#ifdef DEBUG_PROM_MAPS
+			for(i = 0; i < 16; i++) {
+				printk ("mapped:");
+				print_pte_vaddr (seg + (i*PAGE_SIZE));
+				break;
+			}
 #endif
 			// the lowest mapping here is the end of our
 			// vmalloc region
@@ -174,7 +178,7 @@
 	}
 
 	
-	sun3_dvma_init();
+	dvma_init();
 	
 	
 	/* blank everything below the kernel, and we've got the base
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/sun3/sbus.c linux/arch/m68k/sun3/sbus.c
--- v2.4.5/linux/arch/m68k/sun3/sbus.c	Wed Sep  8 11:20:42 1999
+++ linux/arch/m68k/sun3/sbus.c	Mon Jun 11 19:15:27 2001
@@ -12,8 +12,12 @@
 #include <linux/types.h>
 #include <linux/init.h>
 
+extern void rs_init(void);
+
 void __init sbus_init(void)
 {
+
+	rs_init();
 
 }
 
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/sun3/sun3_ksyms.c linux/arch/m68k/sun3/sun3_ksyms.c
--- v2.4.5/linux/arch/m68k/sun3/sun3_ksyms.c	Fri Jan 28 08:04:58 2000
+++ linux/arch/m68k/sun3/sun3_ksyms.c	Mon Jun 11 19:15:27 2001
@@ -6,5 +6,8 @@
 /*
  * Add things here when you find the need for it.
  */
-EXPORT_SYMBOL(sun3_dvma_malloc);
+EXPORT_SYMBOL(dvma_map_align);
+EXPORT_SYMBOL(dvma_unmap);
+EXPORT_SYMBOL(dvma_malloc_align);
+EXPORT_SYMBOL(dvma_free);
 EXPORT_SYMBOL(idprom);
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/sun3/sun3dvma.c linux/arch/m68k/sun3/sun3dvma.c
--- v2.4.5/linux/arch/m68k/sun3/sun3dvma.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/m68k/sun3/sun3dvma.c	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,295 @@
+/*
+ * linux/arch/m68k/mm/sun3dvma.c
+ *
+ * Copyright (C) 2000 Sam Creasey
+ *
+ * Contains common routines for sun3/sun3x DVMA management.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/list.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/dvma.h>
+
+#ifdef CONFIG_SUN3X
+extern void dvma_unmap_iommu(unsigned long baddr, int len);
+#else
+static inline void dvma_unmap_iommu(unsigned long a, int b)
+{
+}
+#endif
+
+unsigned long iommu_use[IOMMU_TOTAL_ENTRIES];
+
+#define dvma_index(baddr) ((baddr - DVMA_START) >> DVMA_PAGE_SHIFT)
+
+#define dvma_entry_use(baddr)		(iommu_use[dvma_index(baddr)])
+
+struct hole {
+	unsigned long start;
+	unsigned long end;
+	unsigned long size;
+	struct list_head list;
+};
+
+static struct list_head hole_list;
+static struct list_head hole_cache;
+static struct hole initholes[64];
+
+static inline int refill(void)
+{
+
+	struct hole *hole;
+	struct hole *prev = NULL;
+	struct list_head *cur;
+	int ret = 0;
+	
+	list_for_each(cur, &hole_list) {
+		hole = list_entry(cur, struct hole, list);
+
+		if(!prev) {
+			prev = hole;
+			continue;
+		}
+		
+		if(hole->end == prev->start) {
+			hole->size += prev->size;
+			hole->end = prev->end;
+			list_del(&(prev->list));
+			list_add(&(prev->list), &hole_cache);
+			ret++;
+		}
+		
+	}
+
+	return ret;
+}
+	
+static inline struct hole *rmcache(void)
+{
+	struct hole *ret;
+
+	if(list_empty(&hole_cache)) {
+		if(!refill()) {
+			printk("out of dvma hole cache!\n");
+			BUG();
+		}
+	}
+
+	ret = list_entry(hole_cache.next, struct hole, list);
+	list_del(&(ret->list));
+
+	return ret;
+
+}
+
+static inline unsigned long get_baddr(int len, unsigned long align)
+{
+	
+	struct list_head *cur;
+	struct hole *hole;
+
+	if(list_empty(&hole_list)) {
+		printk("out of dvma holes!\n");
+		BUG();
+	}
+
+	list_for_each(cur, &hole_list) {
+		unsigned long newlen;
+
+		hole = list_entry(cur, struct hole, list);
+
+		if(align > DVMA_PAGE_SIZE) 
+			newlen = len + ((hole->end - len) & (align-1));
+		else
+			newlen = len;
+		
+		if(hole->size > newlen) {
+			hole->end -= newlen;
+			hole->size -= newlen;
+			dvma_entry_use(hole->end) = newlen;
+			return hole->end;
+		} else if(hole->size == newlen) {
+			list_del(&(hole->list));
+			list_add(&(hole->list), &hole_cache);
+			dvma_entry_use(hole->start) = newlen;
+			return hole->start;
+		}
+
+	}
+
+	printk("unable to find dvma hole!\n");
+	BUG();
+	return 0;
+}
+
+static inline int free_baddr(unsigned long baddr)
+{
+	
+	unsigned long len;
+	struct hole *hole;
+	struct list_head *cur;
+	unsigned long orig_baddr;
+
+	orig_baddr = baddr;
+	len = dvma_entry_use(baddr);
+	dvma_entry_use(baddr) = 0;
+	baddr &= DVMA_PAGE_MASK;
+	dvma_unmap_iommu(baddr, len);
+
+	list_for_each(cur, &hole_list) {
+		hole = list_entry(cur, struct hole, list);
+		
+		if(hole->end == baddr) {
+			hole->end += len;
+			hole->size += len;
+			return 0;
+		} else if(hole->start == (baddr + len)) {
+			hole->start = baddr;
+			hole->size += len;
+			return 0;
+		}
+
+	}
+
+	hole = rmcache();
+	
+	hole->start = baddr;
+	hole->end = baddr + len;
+	hole->size = len;
+	
+//	list_add_tail(&(hole->list), cur);
+	list_add(&(hole->list), cur);
+	
+	return 0;
+	
+}
+
+void dvma_init(void)
+{
+	
+	struct hole *hole;
+	int i;
+
+	INIT_LIST_HEAD(&hole_list);
+	INIT_LIST_HEAD(&hole_cache);
+
+	/* prepare the hole cache */
+	for(i = 0; i < 64; i++) 
+		list_add(&(initholes[i].list), &hole_cache);
+		
+	hole = rmcache();
+	hole->start = DVMA_START;
+	hole->end = DVMA_END;
+	hole->size = DVMA_SIZE;
+	
+	list_add(&(hole->list), &hole_list);
+
+	memset(iommu_use, 0, sizeof(iommu_use));
+
+	dvma_unmap_iommu(DVMA_START, DVMA_SIZE);
+
+#ifdef CONFIG_SUN3
+	sun3_dvma_init();
+#endif
+
+}
+
+inline unsigned long dvma_map_align(unsigned long kaddr, int len, int align)
+{
+
+	unsigned long baddr;
+	unsigned long off;
+
+	if(!len)
+		len = 0x800;
+
+	if(!kaddr || !len) {
+//		printk("error: kaddr %lx len %x\n", kaddr, len);
+//		*(int *)4 = 0;
+		return 0;
+	}
+
+#ifdef DEBUG
+	printk("dvma_map request %08lx bytes from %08lx\n", 
+	       len, kaddr);
+#endif
+	off = kaddr & ~DVMA_PAGE_MASK;
+	kaddr &= PAGE_MASK;
+	len += off;
+	len = ((len + (DVMA_PAGE_SIZE-1)) & DVMA_PAGE_MASK);
+
+	if(align == 0)
+		align = DVMA_PAGE_SIZE;
+	else
+		align = ((align + (DVMA_PAGE_SIZE-1)) & DVMA_PAGE_MASK);
+
+	baddr = get_baddr(len, align);
+//	printk("using baddr %lx\n", baddr);
+
+	if(!dvma_map_iommu(kaddr, baddr, len))
+		return (baddr + off);
+	
+	printk("dvma_map failed kaddr %lx baddr %lx len %x\n", kaddr, baddr, len);
+	BUG();
+	return 0;
+}
+
+void dvma_unmap(void *baddr)
+{
+
+	free_baddr((unsigned long)baddr);
+	
+	return;
+
+}
+
+
+void *dvma_malloc_align(unsigned long len, unsigned long align)
+{
+	unsigned long kaddr;
+	unsigned long baddr;
+	unsigned long vaddr;
+
+	if(!len)
+		return NULL;
+
+#ifdef DEBUG
+	printk("dvma_malloc request %lx bytes\n", len);
+#endif
+	len = ((len + (DVMA_PAGE_SIZE-1)) & DVMA_PAGE_MASK);
+
+        if((kaddr = __get_free_pages(GFP_ATOMIC, get_order(len))) == 0)
+		return NULL;
+
+	if((baddr = (unsigned long)dvma_map_align(kaddr, len, align)) == 0) {
+		free_pages(kaddr, get_order(len));
+		return NULL;
+	}
+
+	vaddr = dvma_btov(baddr);
+
+	if(dvma_map_cpu(kaddr, vaddr, len) < 0) {
+		dvma_unmap((void *)baddr);
+		free_pages(kaddr, get_order(len));
+		return NULL;
+	}
+
+#ifdef DEBUG
+	printk("mapped %08lx bytes %08lx kern -> %08lx bus\n",
+	       len, kaddr, baddr);
+#endif
+
+	return (void *)vaddr;
+
+}
+
+void dvma_free(void *vaddr)
+{
+
+	return;
+
+}
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/sun3/sun3ints.c linux/arch/m68k/sun3/sun3ints.c
--- v2.4.5/linux/arch/m68k/sun3/sun3ints.c	Fri Dec 29 14:07:20 2000
+++ linux/arch/m68k/sun3/sun3ints.c	Mon Jun 11 19:15:27 2001
@@ -1,5 +1,5 @@
  /*
- * linux/arch/m68k/sun3/sun3ints.c -- Sun-3 Linux interrupt handling code
+ * linux/arch/m68k/sun3/sun3ints.c -- Sun-3(x) Linux interrupt handling code
  *
  * 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
@@ -35,7 +35,7 @@
        ~(0x10), ~(0x08)
 };
 
-unsigned char* sun3_intreg;
+volatile unsigned char* sun3_intreg;
 
 void sun3_insert_irq(irq_node_t **list, irq_node_t *node)
 {
@@ -45,10 +45,6 @@
 {
 }
 
-void sun3_free_irq(unsigned int irq, void *dev_id)
-{
-}
-
 void sun3_enable_irq(unsigned int irq)
 {
 	*sun3_intreg |=  (1<<irq);
@@ -71,41 +67,54 @@
 	return 0;
 }
 
+static void sun3_int7(int irq, void *dev_id, struct pt_regs *fp)
+{
+	sun3_do_irq(irq,fp);
+	if(!(kstat.irqs[0][SYS_IRQS + irq] % 2000)) 
+		sun3_leds(led_pattern[(kstat.irqs[0][SYS_IRQS+irq]%16000)/2000]);
+}
+
 static void sun3_int5(int irq, void *dev_id, struct pt_regs *fp)
 {
         kstat.irqs[0][SYS_IRQS + irq]++;
-        *sun3_intreg &= ~(1<<irq);
+#ifdef CONFIG_SUN3
 	intersil_clear();
+#endif
+        *sun3_intreg &= ~(1<<irq);
         *sun3_intreg |=  (1<<irq);
+#ifdef CONFIG_SUN3
+	intersil_clear();
+#endif
         do_timer(fp);
         if(!(kstat.irqs[0][SYS_IRQS + irq] % 20))
                 sun3_leds(led_pattern[(kstat.irqs[0][SYS_IRQS+irq]%160)
                 /20]);
 }
 
-static void sun3_int7(int irq, void *dev_id, struct pt_regs *fp)
-{
-	sun3_do_irq(irq,fp);
-	if(!(kstat.irqs[0][SYS_IRQS + irq] % 2000)) 
-		sun3_leds(led_pattern[(kstat.irqs[0][SYS_IRQS+irq]%16000)/2000]);
-}
-
 /* handle requested ints, excepting 5 and 7, which always do the same
    thing */
 static void *dev_ids[SYS_IRQS];
-static void (*inthandler[SYS_IRQS])(int, void *, struct pt_regs *) = {
+static void (*sun3_inthandler[SYS_IRQS])(int, void *, struct pt_regs *) = {
 	NULL, NULL, NULL, NULL, NULL, sun3_int5, NULL, sun3_int7
 };
+static void (*sun3_vechandler[192])(int, void *, struct pt_regs *);
+static void *vec_ids[192];
+static char *vec_names[192];
 
 static void sun3_inthandle(int irq, void *dev_id, struct pt_regs *fp)
 {
-	if(inthandler[irq] == NULL)
+	if(sun3_inthandler[irq] == NULL)
 		panic ("bad interrupt %d received (id %p)\n",irq, dev_id);
 
         kstat.irqs[0][SYS_IRQS + irq]++;
         *sun3_intreg &= ~(1<<irq);
 
-	inthandler[irq](irq, dev_ids[irq], fp);
+	sun3_inthandler[irq](irq, dev_ids[irq], fp);
+}
+
+static void sun3_vec255(int irq, void *dev_id, struct pt_regs *fp)
+{
+//	intersil_clear();
 }
 
 void (*sun3_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
@@ -120,6 +129,8 @@
 {
 	int i;
 
+	*sun3_intreg = 1;
+
 	for(i = 0; i < SYS_IRQS; i++)
 	{
 		if(dev_names[i])
@@ -127,25 +138,94 @@
 					0, dev_names[i], NULL);
 	}
 
+	for(i = 0; i < 192; i++) 
+		sun3_vechandler[i] = NULL;
+	
+	sun3_vechandler[191] = sun3_vec255;
 }
                                 
 int sun3_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
                       unsigned long flags, const char *devname, void *dev_id)
 {
-	if(inthandler[irq] != NULL) {
-		printk("sun3_request_irq: request for irq %d -- already taken!\n", irq);
-		return -1;
-	}
 
-	inthandler[irq] = handler;
-	dev_ids[irq] = dev_id;
-	dev_names[irq] = devname;
+	if(irq < SYS_IRQS) {
+		if(sun3_inthandler[irq] != NULL) {
+			printk("sun3_request_irq: request for irq %d -- already taken!\n", irq);
+			return 1;
+		}
+		
+		sun3_inthandler[irq] = handler;
+		dev_ids[irq] = dev_id;
+		dev_names[irq] = devname;
+		
+		/* setting devname would be nice */
+		sys_request_irq(irq, sun3_default_handler[irq], 0, devname, NULL);
+
+		return 0;
+	} else {
+		if((irq >= 64) && (irq <= 255)) {
+		        int vec;
+
+			vec = irq - 64;
+			if(sun3_vechandler[vec] != NULL) {
+				printk("sun3_request_irq: request for vec %d -- already taken!\n", irq);
+				return 1;
+			}
+
+			sun3_vechandler[vec] = handler;
+			vec_ids[vec] = dev_id;
+			vec_names[vec] = devname;
+			
+			return 0;
+		}
+	}
 
-	/* setting devname would be nice */
-	
-	sys_request_irq(irq, sun3_default_handler[irq], 0, devname, NULL);
-	
+	printk("sun3_request_irq: invalid irq %d\n", irq);
+	return 1;
 
-	return 0;
 }
                         
+void sun3_free_irq(unsigned int irq, void *dev_id)
+{
+
+	if(irq < SYS_IRQS) {
+		if(sun3_inthandler[irq] == NULL) 
+			panic("sun3_free_int: attempt to free unused irq %d\n", irq);
+		if(dev_ids[irq] != dev_id)
+			panic("sun3_free_int: incorrect dev_id for irq %d\n", irq);
+		
+		sun3_inthandler[irq] = NULL;
+		return;
+	} else if((irq >= 64) && (irq <= 255)) {
+		int vec;
+
+		vec = irq - 64;
+		if(sun3_vechandler[vec] == NULL)
+			panic("sun3_free_int: attempt to free unused vector %d\n", irq);
+		if(vec_ids[irq] != dev_id)
+			panic("sun3_free_int: incorrect dev_id for vec %d\n", irq);
+		
+		sun3_vechandler[vec] = NULL;
+		return;
+	} else {
+		panic("sun3_free_irq: invalid irq %d\n", irq);
+	}		
+}
+
+void sun3_process_int(int irq, struct pt_regs *regs)
+{
+
+	if((irq >= 64) && (irq <= 255)) {
+		int vec;
+
+		vec = irq - 64;
+		if(sun3_vechandler[vec] == NULL) 
+			panic ("bad interrupt vector %d received\n",irq);
+			
+		sun3_vechandler[vec](irq, vec_ids[vec], regs);
+		return;
+	} else {
+		panic("sun3_process_int: unable to handle interrupt vector %d\n",
+		      irq);
+	}
+}
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/sun3x/Makefile linux/arch/m68k/sun3x/Makefile
--- v2.4.5/linux/arch/m68k/sun3x/Makefile	Fri Dec 29 14:07:20 2000
+++ linux/arch/m68k/sun3x/Makefile	Mon Jun 11 19:15:27 2001
@@ -9,6 +9,6 @@
 
 O_TARGET := sun3x.o
 
-obj-y		:= config.o time.o dvma.o sbus.o
+obj-y		:= config.o time.o dvma.o prom.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/sun3x/config.c linux/arch/m68k/sun3x/config.c
--- v2.4.5/linux/arch/m68k/sun3x/config.c	Thu Aug 26 12:42:31 1999
+++ linux/arch/m68k/sun3x/config.c	Mon Jun 11 19:15:27 2001
@@ -14,39 +14,24 @@
 #include <asm/system.h>
 #include <asm/machdep.h>
 #include <asm/irq.h>
-#include <asm/sun3x.h>
+#include <asm/sun3xprom.h>
+#include <asm/sun3ints.h>
+#include <asm/setup.h>
 
 #include "time.h"
 
-static volatile unsigned char *sun3x_intreg = (unsigned char *)SUN3X_INTREG;
-extern int serial_console;
+volatile char *clock_va;
+extern volatile unsigned char *sun3_intreg;
 
-void sun3x_halt(void)
-{
-    /* Disable interrupts */
-    cli();
-
-    /* we can't drop back to PROM, so we loop here */
-    for (;;);
-}
-
-void sun3x_reboot(void)
-{
-    /* This never returns, don't bother saving things */
-    cli();
-
-    /* no idea, whether this works */
-    asm ("reset");
-}
 
 int __init sun3x_keyb_init(void)
 {
-    return 0;
+	return 0;
 }
 
 int sun3x_kbdrate(struct kbd_repeat *r)
 {
-    return 0;
+	return 0;
 }
 
 void sun3x_kbd_leds(unsigned int i)
@@ -54,36 +39,15 @@
 
 }
 
-static void sun3x_badint (int irq, void *dev_id, struct pt_regs *fp)
+void sun3_leds(unsigned int i)
 {
-    printk ("received spurious interrupt %d\n",irq);
-    num_spurious += 1;
-}
 
-void (*sun3x_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
-    sun3x_badint, sun3x_badint, sun3x_badint, sun3x_badint,
-    sun3x_badint, sun3x_badint, sun3x_badint, sun3x_badint
-};
-
-void sun3x_enable_irq(unsigned int irq)
-{
-    *sun3x_intreg |= (1 << irq);
 }
 
-void sun3x_disable_irq(unsigned int irq)
+/* should probably detect types of these eventually. */
+static void sun3x_get_model(char *model)
 {
-    *sun3x_intreg &= ~(1 << irq);
-}
-
-void __init sun3x_init_IRQ(void)
-{
-    /* disable all interrupts initially */
-    *sun3x_intreg = 1;  /* master enable only */
-}
-
-int sun3x_get_irq_list(char *buf)
-{
-    return 0;
+	sprintf(model, "Sun3x");
 }
 
 /*
@@ -91,38 +55,51 @@
  */
 void __init config_sun3x(void)
 {
-    mach_get_irq_list	 = sun3x_get_irq_list;
-    mach_max_dma_address = 0xffffffff; /* we can DMA anywhere, whee */
 
-    mach_keyb_init       = sun3x_keyb_init;
-    mach_kbdrate         = sun3x_kbdrate;
-    mach_kbd_leds        = sun3x_kbd_leds;
-
-    mach_sched_init      = sun3x_sched_init;
-    mach_init_IRQ        = sun3x_init_IRQ;
-    enable_irq           = sun3x_enable_irq;
-    disable_irq          = sun3x_disable_irq;
-    mach_request_irq     = sys_request_irq;
-    mach_free_irq        = sys_free_irq;
-    mach_default_handler = &sun3x_default_handler;
-    mach_gettimeoffset   = sun3x_gettimeoffset;
-    mach_reset           = sun3x_reboot;
+	sun3x_prom_init();
+
+	mach_get_irq_list	 = sun3_get_irq_list;
+	mach_max_dma_address = 0xffffffff; /* we can DMA anywhere, whee */
 
-    mach_gettod          = sun3x_gettod;
+	mach_keyb_init       = sun3x_keyb_init;
+	mach_kbdrate         = sun3x_kbdrate;
+	mach_kbd_leds        = sun3x_kbd_leds;
+
+	mach_default_handler = &sun3_default_handler;
+	mach_sched_init      = sun3x_sched_init;
+	mach_init_IRQ        = sun3_init_IRQ;
+	enable_irq           = sun3_enable_irq;
+	disable_irq          = sun3_disable_irq;
+	mach_request_irq     = sun3_request_irq;
+	mach_free_irq        = sun3_free_irq;
+	mach_process_int     = sun3_process_int;
     
-    switch (*(unsigned char *)SUN3X_EEPROM_CONS) {
+	mach_gettimeoffset   = sun3x_gettimeoffset;
+	mach_reset           = sun3x_reboot;
+
+	mach_gettod          = sun3x_gettod;
+	mach_hwclk           = sun3x_hwclk;
+	mach_get_model       = sun3x_get_model;
+
+	sun3_intreg = (unsigned char *)SUN3X_INTREG;
+
+	/* only the serial console is known to work anyway... */
+#if 0    
+	switch (*(unsigned char *)SUN3X_EEPROM_CONS) {
 	case 0x10:
-	    serial_console = 1;
-	    conswitchp = NULL;
-	    break;
+		serial_console = 1;
+		conswitchp = NULL;
+		break;
 	case 0x11:
-	    serial_console = 2;
-	    conswitchp = NULL;
-	    break;
+		serial_console = 2;
+		conswitchp = NULL;
+		break;
 	default:
-	    serial_console = 0;
-	    conswitchp = &dummy_con;
-	    break;
-    }
+		serial_console = 0;
+		conswitchp = &dummy_con;
+		break;
+	}
+#endif
 
 }
+
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/sun3x/dvma.c linux/arch/m68k/sun3x/dvma.c
--- v2.4.5/linux/arch/m68k/sun3x/dvma.c	Tue May 11 09:57:14 1999
+++ linux/arch/m68k/sun3x/dvma.c	Mon Jun 11 19:15:27 2001
@@ -2,21 +2,31 @@
  * Virtual DMA allocation
  *
  * (C) 1999 Thomas Bogendoerfer (tsbogend@alpha.franken.de) 
+ *
+ * 11/26/2000 -- disabled the existing code because it didn't work for 
+ * me in 2.4.  Replaced with a significantly more primitive version 
+ * similar to the sun3 code.  the old functionality was probably more 
+ * desirable, but....   -- Sam Creasey (sammy@oh.verio.com)
+ *
  */
 
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
 #include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
 
 #include <asm/sun3x.h>
 #include <asm/dvma.h>
 #include <asm/io.h>
 #include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 
 /* IOMMU support */
 
-#define IOMMU_ENTRIES		   2048
 #define IOMMU_ADDR_MASK            0x03ffe000
 #define IOMMU_CACHE_INHIBIT        0x00000040
 #define IOMMU_FULL_BLOCK           0x00000020
@@ -28,135 +38,170 @@
 #define IOMMU_DT_VALID             0x00000001
 #define IOMMU_DT_BAD               0x00000002
 
-#define DVMA_PAGE_SHIFT	13
-#define DVMA_PAGE_SIZE	(1UL << DVMA_PAGE_SHIFT)
-#define DVMA_PAGE_MASK	(~(DVMA_PAGE_SIZE-1))
-
 
 static volatile unsigned long *iommu_pte = (unsigned long *)SUN3X_IOMMU;
-static unsigned long iommu_use[IOMMU_ENTRIES];
-static unsigned long iommu_bitmap[IOMMU_ENTRIES/32];
 
 
 #define dvma_entry_paddr(index) 	(iommu_pte[index] & IOMMU_ADDR_MASK)
 #define dvma_entry_vaddr(index,paddr) 	((index << DVMA_PAGE_SHIFT) |  \
 					 (paddr & (DVMA_PAGE_SIZE-1)))
+#if 0
+#define dvma_entry_set(index,addr)	(iommu_pte[index] =            \
+					    (addr & IOMMU_ADDR_MASK) | \
+				             IOMMU_DT_VALID | IOMMU_CACHE_INHIBIT)
+#else
 #define dvma_entry_set(index,addr)	(iommu_pte[index] =            \
 					    (addr & IOMMU_ADDR_MASK) | \
 				             IOMMU_DT_VALID)
+#endif
 #define dvma_entry_clr(index)		(iommu_pte[index] = IOMMU_DT_INVALID)
-#define dvma_entry_use(index)		(iommu_use[index])
-#define dvma_entry_inc(index)		(iommu_use[index]++)
-#define dvma_entry_dec(index)		(iommu_use[index]--)
 #define dvma_entry_hash(addr)		((addr >> DVMA_PAGE_SHIFT) ^ \
 					 ((addr & 0x03c00000) >>     \
 						(DVMA_PAGE_SHIFT+4)))
-#define dvma_map			iommu_bitmap
-#define dvma_map_size			(IOMMU_ENTRIES/2)
-#define dvma_slow_offset		(IOMMU_ENTRIES/2)
-#define dvma_is_slow(addr)		((addr) & 		      \
-					 (dvma_slow_offset << DVMA_PAGE_SHIFT))
 
-static int fixed_dvma;
+#undef DEBUG
 
-void __init dvma_init(void)
+#ifdef DEBUG
+/* code to print out a dvma mapping for debugging purposes */
+void dvma_print (unsigned long dvma_addr)
 {
-    unsigned long tmp;
 
-    if ((unsigned long)high_memory < (IOMMU_ENTRIES << DVMA_PAGE_SHIFT)) {
-	printk ("Sun3x fixed DVMA mapping\n");
-	fixed_dvma = 1;
-	for (tmp = 0; tmp < (unsigned long)high_memory; tmp += DVMA_PAGE_SIZE)
-	dvma_entry_set (tmp >> DVMA_PAGE_SHIFT, virt_to_phys((void *)tmp));
-	fixed_dvma = 1;
-    } else {
-	printk ("Sun3x variable DVMA mapping\n");
-	for (tmp = 0; tmp < IOMMU_ENTRIES; tmp++)
-	    dvma_entry_clr (tmp);
-	fixed_dvma = 0;
-    }
+        unsigned long index;
+
+        index = dvma_addr >> DVMA_PAGE_SHIFT;
+
+        printk("idx %lx dvma_addr %08lx paddr %08lx\n", index, dvma_addr,
+               dvma_entry_paddr(index));
+
+
 }
+#endif
 
-unsigned long dvma_slow_alloc (unsigned long paddr, int npages)
+
+/* create a virtual mapping for a page assigned within the IOMMU
+   so that the cpu can reach it easily */
+inline int dvma_map_cpu(unsigned long kaddr, 
+			       unsigned long vaddr, int len)
 {
-    int scan, base;
-    
-    scan = 0;
-    for (;;) {
-	scan = find_next_zero_bit(dvma_map, dvma_map_size, scan);
-	if ((base = scan) + npages > dvma_map_size) {
-	    printk ("dvma_slow_alloc failed for %d pages\n",npages);
-	    return 0;
-	}
-	for  (;;) {
-	    if (scan >= base + npages) goto found;
-	    if (test_bit(scan, dvma_map)) break;
-	    scan++;
-	}
-    }
+	pgd_t *pgd;
+	unsigned long end;
+	int ret = 0;
+
+	kaddr &= PAGE_MASK;
+	vaddr &= PAGE_MASK;
+
+	end = PAGE_ALIGN(vaddr + len);
+
+#ifdef DEBUG
+	printk("dvma: mapping kern %08lx to virt %08lx\n",
+	       kaddr, vaddr);
+#endif
+	pgd = pgd_offset_k(vaddr);
+	
+	do {
+		pmd_t *pmd;
+		unsigned long end2;
+
+		if((pmd = pmd_alloc_kernel(pgd, vaddr)) == NULL) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		if((end & PGDIR_MASK) > (vaddr & PGDIR_MASK)) 
+			end2 = (vaddr + (PGDIR_SIZE-1)) & PGDIR_MASK;
+		else
+			end2 = end;
+
+		do {
+			pte_t *pte;
+			unsigned long end3;
+
+			if((pte = pte_alloc_kernel(pmd, vaddr)) == NULL) {
+				ret = -ENOMEM;
+				goto out;
+			}
+
+			if((end2 & PMD_MASK) > (vaddr & PMD_MASK)) 
+				end3 = (vaddr + (PMD_SIZE-1)) & PMD_MASK;
+			else
+				end3 = end2;
+
+			do {
+#ifdef DEBUG
+				printk("mapping %08lx phys to %08lx\n",
+				       __pa(kaddr), vaddr);
+#endif
+				set_pte(pte, __mk_pte(kaddr, PAGE_KERNEL));
+				pte++;
+				kaddr += PAGE_SIZE;
+				vaddr += PAGE_SIZE;
+			} while(vaddr < end3);
+			
+		} while(vaddr < end2);
+
+	} while(vaddr < end);
+	
+	flush_tlb_all();
 
-found:
-    for (scan = base; scan < base+npages; scan++) {
-	dvma_entry_set(scan+dvma_slow_offset, paddr);
-	paddr += DVMA_PAGE_SIZE;
-	set_bit(scan, dvma_map);
-    }
-    return (dvma_entry_vaddr((base+dvma_slow_offset),paddr));
+ out:
+	return ret;
 }
 
-unsigned long dvma_alloc (unsigned long paddr, unsigned long size)
+
+inline int dvma_map_iommu(unsigned long kaddr, unsigned long baddr,
+				 int len) 
 {
-    int index;
-    int pages = ((paddr & ~DVMA_PAGE_MASK) + size + (DVMA_PAGE_SIZE-1)) >>
-		DVMA_PAGE_SHIFT;
-
-    if (fixed_dvma)
-	return ((unsigned long)phys_to_virt (paddr));
-
-    if (pages > 1) /* multi page, allocate from slow pool */
-	return dvma_slow_alloc (paddr, pages);
-    
-    index = dvma_entry_hash (paddr);
-
-    if (dvma_entry_use(index)) {
-	if (dvma_entry_paddr(index) == (paddr & DVMA_PAGE_MASK)) {
-	    dvma_entry_inc(index);
-	    return dvma_entry_vaddr(index,paddr);
+	unsigned long end, index;
+
+	index = baddr >> DVMA_PAGE_SHIFT;
+	end = ((baddr+len) >> DVMA_PAGE_SHIFT);
+	
+	if(len & ~DVMA_PAGE_MASK)
+		end++;
+
+	for(; index < end ; index++) {
+//		if(dvma_entry_use(index))
+//			BUG();
+//		printk("mapping pa %lx to ba %lx\n", __pa(kaddr), index << DVMA_PAGE_SHIFT);
+
+		dvma_entry_set(index, __pa(kaddr));
+
+		iommu_pte[index] |= IOMMU_FULL_BLOCK;
+//		dvma_entry_inc(index);
+		
+		kaddr += DVMA_PAGE_SIZE;
 	}
-	/* collision, allocate from slow pool */
-	return dvma_slow_alloc (paddr, pages);
-    }
-    
-    dvma_entry_set(index,paddr); 
-    dvma_entry_inc(index);
-    return dvma_entry_vaddr(index,paddr);
+
+#ifdef DEBUG	
+	for(index = (baddr >> DVMA_PAGE_SHIFT); index < end; index++) 
+		dvma_print(index << DVMA_PAGE_SHIFT);
+#endif
+	return 0;
+
 }
 
-void dvma_free (unsigned long dvma_addr, unsigned long size)
+void dvma_unmap_iommu(unsigned long baddr, int len)
 {
-    int npages;
-    int index;
-    
-    if (fixed_dvma)
-	return;
-
-    if (!dvma_is_slow(dvma_addr)) {
-	index = (dvma_addr >> DVMA_PAGE_SHIFT);
-	if (dvma_entry_use(index) == 0) {
-	    printk ("dvma_free: %lx entry already free\n",dvma_addr);
-	    return;
+
+	int index, end;
+	
+	
+	index = baddr >> DVMA_PAGE_SHIFT;
+	end = (DVMA_PAGE_ALIGN(baddr+len) >> DVMA_PAGE_SHIFT);
+	
+	for(; index < end ; index++) {
+#ifdef DEBUG
+		printk("freeing bus mapping %08x\n", index << DVMA_PAGE_SHIFT);
+#endif
+#if 0
+		if(!dvma_entry_use(index)) 
+			printk("dvma_unmap freeing unused entry %04x\n",
+			       index);
+		else
+			dvma_entry_dec(index);
+#endif
+		dvma_entry_clr(index);
 	}
-        dvma_entry_dec(index);
-	if (dvma_entry_use(index) == 0)
-	    dvma_entry_clr(index);
-	return;
-    }
-
-    /* free in slow pool */
-    npages = ((dvma_addr & ~DVMA_PAGE_MASK) + size + (DVMA_PAGE_SIZE-1)) >>
-	    DVMA_PAGE_SHIFT;
-    for (index = (dvma_addr >> DVMA_PAGE_SHIFT); npages--; index++) {
-	dvma_entry_clr(index);
-	clear_bit (index,dvma_map);
-    }
+
 }
+
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/sun3x/prom.c linux/arch/m68k/sun3x/prom.c
--- v2.4.5/linux/arch/m68k/sun3x/prom.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/m68k/sun3x/prom.c	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,165 @@
+/* Prom access routines for the sun3x */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/bootinfo.h>
+#include <asm/setup.h>
+#include <asm/traps.h>
+#include <asm/sun3xprom.h>
+#include <asm/idprom.h>
+#include <asm/segment.h>
+#include <asm/sun3ints.h>
+#include <asm/openprom.h>
+#include <asm/machines.h>
+
+void (*sun3x_putchar)(int);
+int (*sun3x_getchar)(void);
+int (*sun3x_mayget)(void);
+int (*sun3x_mayput)(int);
+void (*sun3x_prom_reboot)(void);
+e_vector sun3x_prom_abort;
+struct idprom *idprom;
+static struct idprom idprom_buffer;
+struct linux_romvec *romvec;
+
+/* prom vector table */
+e_vector *sun3x_prom_vbr;
+
+extern e_vector vectors[256];  /* arch/m68k/kernel/traps.c */
+
+/* Handle returning to the prom */
+void sun3x_halt(void)
+{
+    unsigned long flags;
+    
+    /* Disable interrupts while we mess with things */
+    save_flags(flags); cli();
+
+    /* Restore prom vbr */
+    __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)sun3x_prom_vbr));
+
+    /* Restore prom NMI clock */
+//    sun3x_disable_intreg(5);
+    sun3_enable_irq(7);
+
+    /* Let 'er rip */
+    __asm__ volatile ("trap #14" : : );
+
+    /* Restore everything */
+    sun3_disable_irq(7);
+    sun3_enable_irq(5);
+
+    __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors));
+    restore_flags(flags);
+}
+
+void sun3x_reboot(void)
+{
+    /* This never returns, don't bother saving things */
+    cli();
+
+    /* Restore prom vbr */
+    __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)sun3x_prom_vbr));
+
+    /* Restore prom NMI clock */
+    sun3_disable_irq(5);
+    sun3_enable_irq(7);
+
+    /* Let 'er rip */
+    (*romvec->pv_reboot)("vmlinux");
+}
+
+extern char m68k_debug_device[];
+
+static void sun3x_prom_write(struct console *co, const char *s,
+                             unsigned int count)
+{
+    while (count--) {
+        if (*s == '\n')
+            sun3x_putchar('\r');
+        sun3x_putchar(*s++);
+    }
+}
+
+/* debug console - write-only */
+
+static struct console sun3x_debug = {
+	"debug",
+	sun3x_prom_write,  	/* write */
+	NULL,			/* read */
+	NULL,			/* device */
+	NULL,			/* wait_key */
+	NULL,			/* unblank */
+	NULL,			/* setup */
+	CON_PRINTBUFFER,
+	-1,
+	0,
+	NULL
+};
+
+void sun3x_prom_init(void)
+{
+    /* Read the vector table */
+	int i;
+
+
+    sun3x_putchar = *(void (**)(int)) (SUN3X_P_PUTCHAR);
+    sun3x_getchar = *(int (**)(void)) (SUN3X_P_GETCHAR);
+    sun3x_mayget = *(int (**)(void))  (SUN3X_P_MAYGET);
+    sun3x_mayput = *(int (**)(int))   (SUN3X_P_MAYPUT);
+    sun3x_prom_reboot = *(void (**)(void)) (SUN3X_P_REBOOT);
+    sun3x_prom_abort = *(e_vector *)  (SUN3X_P_ABORT);
+    romvec = (struct linux_romvec *)SUN3X_PROM_BASE;
+
+    /* make a copy of the idprom structure */
+    for(i = 0; i < sizeof(struct idprom); i++) 
+	    ((unsigned char *)(&idprom_buffer))[i] = ((unsigned char *)SUN3X_IDPROM)[i];
+    idprom = &idprom_buffer;
+
+    if((idprom->id_machtype & SM_ARCH_MASK) != SM_SUN3X) {
+	    printk("Warning: machine reports strange type %02x\n");
+	    printk("Pretending it's a 3/80, but very afraid...\n");
+	    idprom->id_machtype = SM_SUN3X | SM_3_80;
+    }
+
+    /* point trap #14 at abort.
+     * XXX this is futile since we restore the vbr first - oops
+     */
+    vectors[VEC_TRAP14] = sun3x_prom_abort;
+    
+    /* If debug=prom was specified, start the debug console */
+
+    if (!strcmp(m68k_debug_device, "prom"))
+        register_console(&sun3x_debug);
+
+    
+}
+
+/* some prom functions to export */
+int prom_getintdefault(int node, char *property, int deflt)
+{
+	return deflt;
+}
+
+int prom_getbool (int node, char *prop)
+{
+	return 1;
+}
+
+void prom_printf(char *fmt, ...)
+{
+
+}
+
+void prom_halt (void)
+{
+	sun3x_halt();
+}
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/sun3x/sbus.c linux/arch/m68k/sun3x/sbus.c
--- v2.4.5/linux/arch/m68k/sun3x/sbus.c	Thu Aug 26 12:42:31 1999
+++ linux/arch/m68k/sun3x/sbus.c	Wed Dec 31 16:00:00 1969
@@ -1,44 +0,0 @@
-/*
- * SBus helper functions
- *
- * Sun3x don't have a sbus, but many of the used devices are also
- * used on Sparc machines with sbus. To avoid having a lot of
- * duplicate code, we provide necessary glue stuff to make using
- * of the sbus driver code possible.
- *
- * (C) 1999 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-
-void __init sbus_init(void)
-{
-
-}
-
-void *sparc_alloc_io (u32 address, void *virtual, int len, char *name,
-                      u32 bus_type, int rdonly)
-{
-	return (void *)address;
-}
-
-int prom_getintdefault(int node, char *property, int deflt)
-{
-	return deflt;
-}
-
-int prom_getbool (int node, char *prop)
-{
-	return 1;
-}
-
-void prom_printf(char *fmt, ...)
-{
-
-}
-
-void prom_halt (void)
-{
-
-}
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/sun3x/sun3x_ksyms.c linux/arch/m68k/sun3x/sun3x_ksyms.c
--- v2.4.5/linux/arch/m68k/sun3x/sun3x_ksyms.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/m68k/sun3x/sun3x_ksyms.c	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,13 @@
+#include <linux/module.h>
+#include <linux/types.h>
+#include <asm/dvma.h>
+#include <asm/idprom.h>
+
+/*
+ * Add things here when you find the need for it.
+ */
+EXPORT_SYMBOL(dvma_map_align);
+EXPORT_SYMBOL(dvma_unmap);
+EXPORT_SYMBOL(dvma_malloc_align);
+EXPORT_SYMBOL(dvma_free);
+EXPORT_SYMBOL(idprom);
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/sun3x/time.c linux/arch/m68k/sun3x/time.c
--- v2.4.5/linux/arch/m68k/sun3x/time.c	Thu Aug 26 12:42:31 1999
+++ linux/arch/m68k/sun3x/time.c	Mon Jun 11 19:15:27 2001
@@ -5,6 +5,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/kd.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
@@ -15,6 +16,8 @@
 #include <asm/system.h>
 #include <asm/traps.h>
 #include <asm/sun3x.h>
+#include <asm/sun3ints.h>
+#include <asm/rtc.h>
 
 #include "time.h"
 
@@ -33,6 +36,7 @@
 #define C_CALIB   0x1f
 
 #define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
+#define BIN_TO_BCD(val) (((val/10) << 4) | (val % 10))
 
 /* Read the Mostek */
 void sun3x_gettod (int *yearp, int *monp, int *dayp,
@@ -45,7 +49,7 @@
 
     /* Read values */
     *yearp = BCD_TO_BIN(*(eeprom + M_YEAR));
-    *monp  = BCD_TO_BIN(*(eeprom + M_MONTH));
+    *monp  = BCD_TO_BIN(*(eeprom + M_MONTH)) +1;
     *dayp  = BCD_TO_BIN(*(eeprom + M_DATE));
     *hourp = BCD_TO_BIN(*(eeprom + M_HOUR));
     *minp  = BCD_TO_BIN(*(eeprom + M_MIN));
@@ -55,6 +59,40 @@
     *(eeprom + M_CONTROL) &= ~C_READ;
 }
 
+int sun3x_hwclk(int set, struct hwclk_time *t)
+{
+	volatile struct mostek_dt *h = 
+		(unsigned char *)(SUN3X_EEPROM+M_CONTROL);
+	unsigned long flags;
+
+	save_and_cli(flags);
+	
+	if(set) {
+		h->csr |= C_WRITE;
+		h->sec = BIN_TO_BCD(t->sec);
+		h->min = BIN_TO_BCD(t->min);
+		h->hour = BIN_TO_BCD(t->hour);
+		h->wday = BIN_TO_BCD(t->wday);
+		h->mday = BIN_TO_BCD(t->day);
+		h->month = BIN_TO_BCD(t->mon);
+		h->year = BIN_TO_BCD(t->year);
+		h->csr &= ~C_WRITE;
+	} else {
+		h->csr |= C_READ;
+		t->sec = BCD_TO_BIN(h->sec);
+		t->min = BCD_TO_BIN(h->min);
+		t->hour = BCD_TO_BIN(h->hour);
+		t->wday = BCD_TO_BIN(h->wday);
+		t->day = BCD_TO_BIN(h->mday);
+		t->mon = BCD_TO_BIN(h->month);
+		t->year = BCD_TO_BIN(h->year);
+		h->csr &= ~C_READ;
+	}
+
+	restore_flags(flags);
+
+	return 0;
+}
 /* Not much we can do here */
 unsigned long sun3x_gettimeoffset (void)
 {
@@ -74,9 +112,12 @@
 
 void __init sun3x_sched_init(void (*vector)(int, void *, struct pt_regs *))
 {
-    sys_request_irq(5, sun3x_timer_tick, IRQ_FLG_STD, "timer tick", vector);
+	
+	sun3_disable_interrupts();
+	
 
     /* Pulse enable low to get the clock started */
-    disable_irq(5);
-    enable_irq(5);
+	sun3_disable_irq(5);
+	sun3_enable_irq(5);
+	sun3_enable_interrupts();
 }
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/sun3x/time.h linux/arch/m68k/sun3x/time.h
--- v2.4.5/linux/arch/m68k/sun3x/time.h	Tue May 11 09:57:14 1999
+++ linux/arch/m68k/sun3x/time.h	Mon Jun 11 19:15:27 2001
@@ -1,9 +1,21 @@
 #ifndef SUN3X_TIME_H
 #define SUN3X_TIME_H
 
-void sun3x_gettod (int *yearp, int *monp, int *dayp,
+extern void sun3x_gettod (int *yearp, int *monp, int *dayp,
                    int *hourp, int *minp, int *secp);
+extern int sun3x_hwclk(int set, struct hwclk_time *t);
 unsigned long sun3x_gettimeoffset (void);
 void sun3x_sched_init(void (*vector)(int, void *, struct pt_regs *));
+
+struct mostek_dt {
+	volatile unsigned char csr;
+	volatile unsigned char sec;
+	volatile unsigned char min;
+	volatile unsigned char hour;
+	volatile unsigned char wday;
+	volatile unsigned char mday;
+	volatile unsigned char month;
+	volatile unsigned char year;
+};
 
 #endif
diff -u --recursive --new-file v2.4.5/linux/arch/ppc/boot/common/misc-common.c linux/arch/ppc/boot/common/misc-common.c
--- v2.4.5/linux/arch/ppc/boot/common/misc-common.c	Thu May 24 15:02:06 2001
+++ linux/arch/ppc/boot/common/misc-common.c	Mon Jun 11 19:15:27 2001
@@ -268,7 +268,7 @@
 	s.zfree = zfree;
 	r = inflateInit2(&s, -MAX_WBITS);
 	if (r != Z_OK) {
-		puts("inflateInit2 returned %d\n");
+		puts("inflateInit2 returned "); puthex(r); puts("\n");
 		exit();
 	}
 	s.next_in = src + i;
@@ -277,7 +277,7 @@
 	s.avail_out = dstlen;
 	r = inflate(&s, Z_FINISH);
 	if (r != Z_OK && r != Z_STREAM_END) {
-		puts("inflate returned %d\n");
+		puts("inflate returned "); puthex(r); puts("\n");
 		exit();
 	}
 	*lenp = s.next_out - (unsigned char *) dst;
diff -u --recursive --new-file v2.4.5/linux/arch/ppc/boot/mbx/Makefile linux/arch/ppc/boot/mbx/Makefile
--- v2.4.5/linux/arch/ppc/boot/mbx/Makefile	Thu May 24 15:02:06 2001
+++ linux/arch/ppc/boot/mbx/Makefile	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.5 05/18/01 06:20:29 patch
+# BK Id: SCCS/s.Makefile 1.7 06/05/01 20:20:05 paulus
 #
 #
 # arch/ppc/mbxboot/Makefile
@@ -87,13 +87,21 @@
 	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
 		--add-section=initrd=../images/ramdisk.image.gz \
 		--add-section=image=../images/vmlinux.gz \
-		$@.tmp ../images/$@.mbx
+		$@.tmp ../images/$@.embedded
 
 zImage: zvmlinux
-	ln -sf zvmlinux.mbx ../images/zImage.mbx
+ifeq ($(CONFIG_RPXCLASSIC),y)
+	dd if=../images/zvmlinux.embedded of=../images/zImage.embedded bs=65536 skip=1
+else
+	ln -sf ../images/zvmlinux.embedded ../images/zImage.embedded
+endif
 
 zImage.initrd: zvmlinux.initrd
-	ln -sf zvmlinux.initrd.mbx ../images/zImage.initrd.mbx
+ifeq ($(CONFIG_RPXCLASSIC),y)
+	dd if=../images/zvmlinux.initrd.embedded of=../images/zImage.initrd.embedded bs=65536 skip=1
+else
+	ln -sf ../images/zvmlinux.initrd.embedded ../images/zImage.initrd.embedded
+endif
 
 zvmlinux: $(OBJECTS) $(LIBS) ../images/vmlinux.gz
 #
@@ -114,14 +122,14 @@
 	$(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS)
 	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
 		--add-section=image=../images/vmlinux.gz \
-		$@.tmp ../images/$@.mbx
-# Remove zvmlinux and zvmlinux.temp, we have ../images/zvmlinux.mbx
+		$@.tmp ../images/$@.embedded
+# Remove zvmlinux and zvmlinux.temp, we have ../images/zvmlinux.embedded
 	rm -f $@.tmp $@
 
 znetboot : zImage
-	cp ../images/zImage.mbx $(TFTPIMAGE)
+	cp ../images/zImage.embedded $(TFTPIMAGE)
 
 znetboot.initrd : zImage.initrd
-	cp ../images/zImage.initrd.mbx $(TFTPIMAGE)
+	cp ../images/zImage.initrd.embedded $(TFTPIMAGE)
 
 include $(TOPDIR)/Rules.make 
diff -u --recursive --new-file v2.4.5/linux/arch/ppc/boot/pmac/Makefile linux/arch/ppc/boot/pmac/Makefile
--- v2.4.5/linux/arch/ppc/boot/pmac/Makefile	Thu May 24 15:02:07 2001
+++ linux/arch/ppc/boot/pmac/Makefile	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.8 05/21/01 09:10:38 trini
+# BK Id: SCCS/s.Makefile 1.10 06/05/01 20:22:51 paulus
 #
 # Makefile for making XCOFF bootable images for booting on PowerMacs
 # using Open Firmware.
@@ -7,7 +7,7 @@
 #
 # Cleaned up, moved into arch/ppc/boot/pmac
 # Tom Rini		January 2001
- 
+
 OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
 COFF_LD_ARGS = -e _start -T ld.script -Ttext 500000 -Tdata 510000 -Bstatic
 CHRP_LD_ARGS = -Ttext 0x01000000
diff -u --recursive --new-file v2.4.5/linux/arch/ppc/boot/prep/misc.c linux/arch/ppc/boot/prep/misc.c
--- v2.4.5/linux/arch/ppc/boot/prep/misc.c	Thu May 24 15:02:07 2001
+++ linux/arch/ppc/boot/prep/misc.c	Mon Jun 11 19:15:27 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.misc.c 1.8 05/18/01 06:20:29 patch
+ * BK Id: SCCS/s.misc.c 1.10 06/05/01 20:20:05 paulus
  */
 /*
  * misc.c
@@ -393,7 +393,7 @@
 	{
 		struct bi_record *rec;
 	    
-		rec = (struct bi_record *)PAGE_ALIGN(zimage_size);
+		rec = (struct bi_record *)_ALIGN((unsigned long)(zimage_size)+(1<<20)-1,(1<<20));
 	    
 		rec->tag = BI_FIRST;
 		rec->size = sizeof(struct bi_record);
@@ -406,8 +406,8 @@
 	    
 		rec->tag = BI_MACHTYPE;
 		rec->data[0] = _MACH_prep;
-		rec->data[1] = 1;
-		rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+		rec->data[1] = 0;
+		rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long);
 		rec = (struct bi_record *)((unsigned long)rec + rec->size);
 	    
 		rec->tag = BI_CMD_LINE;
diff -u --recursive --new-file v2.4.5/linux/arch/ppc/config.in linux/arch/ppc/config.in
--- v2.4.5/linux/arch/ppc/config.in	Tue May 22 10:23:16 2001
+++ linux/arch/ppc/config.in	Mon Jun 11 19:15:27 2001
@@ -365,6 +365,10 @@
 
 source drivers/usb/Config.in
 
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   source net/bluetooth/Config.in
+fi
+
 mainmenu_option next_comment
 comment 'Kernel hacking'
 
diff -u --recursive --new-file v2.4.5/linux/arch/ppc/kernel/Makefile linux/arch/ppc/kernel/Makefile
--- v2.4.5/linux/arch/ppc/kernel/Makefile	Mon May 21 17:04:46 2001
+++ linux/arch/ppc/kernel/Makefile	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.17 05/21/01 00:48:24 cort
+# BK Id: SCCS/s.Makefile 1.19 05/26/01 14:48:14 paulus
 #
 #
 # Makefile for the linux kernel.
@@ -32,7 +32,7 @@
 export-objs			:= ppc_ksyms.o prep_setup.o 
 
 obj-y				:= entry.o traps.o irq.o idle.o time.o misc.o \
-					process.o signal.o bitops.o ptrace.o \
+					process.o signal.o ptrace.o \
 					ppc_htab.o semaphore.o syscalls.o  \
 					align.o setup.o
 obj-$(CONFIG_MODULES)		+= ppc_ksyms.o
diff -u --recursive --new-file v2.4.5/linux/arch/ppc/kernel/chrp_setup.c linux/arch/ppc/kernel/chrp_setup.c
--- v2.4.5/linux/arch/ppc/kernel/chrp_setup.c	Mon May 21 17:04:46 2001
+++ linux/arch/ppc/kernel/chrp_setup.c	Mon Jun 11 19:15:27 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.chrp_setup.c 1.17 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.chrp_setup.c 1.20 06/05/01 21:22:02 paulus
  */
 /*
  *  linux/arch/ppc/kernel/setup.c
@@ -204,13 +204,10 @@
 	active = sio_read(0x30);
 	level0 = sio_read(0x70);
 	type0 = sio_read(0x71);
-	printk("sio: %s irq level %d, type %d, %sactive: ", name, level0,
-	       type0, !active ? "in" : "");
-	if (level0 == level && type0 == type && active)
-		printk("OK\n");
-	else {
-		printk("remapping to level %d, type %d, active\n", level,
-		       type);
+	if (level0 != level || type0 != type || !active) {
+		printk(KERN_WARNING "sio: %s irq level %d, type %d, %sactive: "
+		       "remapping to level %d, type %d, active\n",
+		       name, level0, type0, !active ? "in" : "", level, type);
 		sio_write(0x01, 0x30);
 		sio_write(level, 0x70);
 		sio_write(type, 0x71);
diff -u --recursive --new-file v2.4.5/linux/arch/ppc/kernel/entry.S linux/arch/ppc/kernel/entry.S
--- v2.4.5/linux/arch/ppc/kernel/entry.S	Mon May 21 17:04:46 2001
+++ linux/arch/ppc/kernel/entry.S	Tue Jun 12 11:07:16 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.entry.S 1.12 05/21/01 11:49:59 paulus
+ * BK Id: SCCS/s.entry.S 1.15 06/09/01 22:16:38 paulus
  */
 /*
  *  PowerPC version 
@@ -310,25 +310,7 @@
 	beq	restore
 	.globl	ret_from_except
 ret_from_except:
-	lwz	r5,_MSR(r1)
-	andi.	r5,r5,MSR_EE
-	beq	2f
-	lis	r4,irq_stat@ha		/* &softirq_active for cpu 0 */
-	addi	r4,r4,irq_stat@l
-#ifdef CONFIG_SMP
-	/* get processor # */
-	lwz	r3,PROCESSOR(r2)
-	slwi	r3,r3,LG_CACHE_LINE_SIZE
-	add	r4,r4,r3
-#endif /* CONFIG_SMP */
-	lwz	r5,0(r4)		/* softirq_active */
-	lwz	r4,4(r4)		/* softirq_mask */
-	and.	r5,r5,r4
-	beq+	2f
-	bl	do_softirq
-	.globl	do_bottom_half_ret
-do_bottom_half_ret:
-2:	lwz	r3,_MSR(r1)	/* Returning to user mode? */
+	lwz	r3,_MSR(r1)	/* Returning to user mode? */
 	andi.	r3,r3,MSR_PR
 	beq+	do_signal_ret	/* if so, check need_resched and signals */
 	lwz	r3,NEED_RESCHED(r2)
diff -u --recursive --new-file v2.4.5/linux/arch/ppc/kernel/irq.c linux/arch/ppc/kernel/irq.c
--- v2.4.5/linux/arch/ppc/kernel/irq.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/irq.c	Mon Jun 11 19:15:27 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.irq.c 1.23 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.irq.c 1.26 06/06/01 22:33:09 paulus
  */
 /*
  *  arch/ppc/kernel/irq.c
@@ -551,6 +551,9 @@
 	ppc_irq_dispatch_handler( regs, irq );
 out:	
         hardirq_exit( cpu );
+
+	if (softirq_pending(cpu))
+		do_softirq();
 	return 1; /* lets ret_from_int know we can do checks */
 }
 
diff -u --recursive --new-file v2.4.5/linux/arch/ppc/kernel/ppc_ksyms.c linux/arch/ppc/kernel/ppc_ksyms.c
--- v2.4.5/linux/arch/ppc/kernel/ppc_ksyms.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/ppc_ksyms.c	Tue Jun 12 11:07:16 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.ppc_ksyms.c 1.31 05/18/01 08:18:10 patch
+ * BK Id: SCCS/s.ppc_ksyms.c 1.34 06/09/01 22:38:13 paulus
  */
 #include <linux/config.h>
 #include <linux/module.h>
@@ -357,7 +357,6 @@
 #endif /* CONFIG_8xx */
 
 EXPORT_SYMBOL(ret_to_user_hook);
-EXPORT_SYMBOL(do_softirq);
 EXPORT_SYMBOL(next_mmu_context);
 EXPORT_SYMBOL(set_context);
 EXPORT_SYMBOL(mmu_context_overflow);
diff -u --recursive --new-file v2.4.5/linux/arch/ppc/kernel/prep_pci.c linux/arch/ppc/kernel/prep_pci.c
--- v2.4.5/linux/arch/ppc/kernel/prep_pci.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/prep_pci.c	Wed Jun 20 11:16:01 2001
@@ -939,17 +939,6 @@
 				pci_write_config_byte(dev, 0x44, reg);
 			}
 		}
-		if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
-						PCI_DEVICE_ID_VIA_82C586_2,
-						dev)))
-		{
-			/* Force correct USB function interrupt */
-			dev->irq = 11;
-			pcibios_write_config_byte(dev->bus->number,
-					dev->devfn,
-					PCI_INTERRUPT_LINE,
-					dev->irq);
-		}
 	}
 	if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND,
 				   PCI_DEVICE_ID_WINBOND_82C105, dev))){
diff -u --recursive --new-file v2.4.5/linux/arch/ppc/kernel/prom.c linux/arch/ppc/kernel/prom.c
--- v2.4.5/linux/arch/ppc/kernel/prom.c	Thu May 24 15:03:05 2001
+++ linux/arch/ppc/kernel/prom.c	Mon Jun 11 19:15:27 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.prom.c 1.20 05/23/01 00:38:42 cort
+ * BK Id: SCCS/s.prom.c 1.23 06/06/01 22:49:01 paulus
  */
 /*
  * Procedures for interfacing to the Open Firmware PROM on
@@ -42,9 +42,11 @@
 /*
  * Properties whose value is longer than this get excluded from our
  * copy of the device tree.  This way we don't waste space storing
- * things like "driver,AAPL,MacOS,PowerPC" properties.
+ * things like "driver,AAPL,MacOS,PowerPC" properties.  But this value
+ * does need to be big enough to ensure that we don't lose things
+ * like the interrupt-map property on a PCI-PCI bridge.
  */
-#define MAX_PROPERTY_LENGTH	1024
+#define MAX_PROPERTY_LENGTH	4096
 
 struct prom_args {
 	const char *service;
@@ -670,16 +672,16 @@
 	prom_alloc_htab();
 #endif
 
-#ifdef CONFIG_SMP
-	prom_hold_cpus(mem);
-#endif
-
 	mem = check_display(mem);
 
 	prom_print(RELOC("copying OF device tree..."));
 	mem = copy_device_tree(mem, mem + (1<<20));
 	prom_print(RELOC("done\n"));
 
+#ifdef CONFIG_SMP
+	prom_hold_cpus(mem);
+#endif
+
 	RELOC(klimit) = (char *) (mem - offset);
 
 	/* If we are already running at 0xc0000000, we assume we were loaded by
@@ -1190,7 +1192,7 @@
 	if ((_machine == _MACH_chrp) || (boot_infos == 0 && pmac_newworld))
 		use_of_interrupt_tree = 1;
 
-	mem = finish_node(allnodes, mem, NULL, 0, 0);
+	mem = finish_node(allnodes, mem, NULL, 1, 1);
 	dev_tree_size = mem - (unsigned long) allnodes;
 	klimit = (char *) mem;
 }
@@ -1225,10 +1227,7 @@
 
 	np->name = get_property(np, "name", 0);
 	np->type = get_property(np, "device_type", 0);
-#if 0
-	np->n_addr_cells = naddrc;
-	np->n_size_cells = nsizec;
-#endif
+
 	/* get the device addresses and interrupts */
 	if (ifunc != NULL) {
 		mem_start = ifunc(np, mem_start, naddrc, nsizec);
@@ -1244,16 +1243,6 @@
 	ip = (int *) get_property(np, "#size-cells", 0);
 	if (ip != NULL)
 		nsizec = *ip;
-#if 0
-	if (np->parent == NULL) {
-		/*
-		 * Set the n_addr/size_cells on the root to its
-		 * own values, rather than 0.
-		 */
-		np->n_addr_cells = naddrc;
-		np->n_size_cells = nsizec;
-	}
-#endif	
 
 	/* the f50 sets the name to 'display' and 'compatible' to what we
 	 * expect for the name -- Cort
@@ -1479,7 +1468,8 @@
 		if (ip != NULL)
 			return *ip;
 	} while(np->parent);
-	return 0;
+	/* No #address-cells property for the root node, default to 1 */
+	return 1;
 }
 
 int
@@ -1493,7 +1483,8 @@
 		if (ip != NULL)
 			return *ip;
 	} while(np->parent);
-	return 0;
+	/* No #size-cells property for the root node, default to 1 */
+	return 1;
 }
 
 __init
@@ -1980,7 +1971,7 @@
 	struct property *pp;
 
 	for (pp = np->properties; pp != 0; pp = pp->next) {
-		if (name && strcmp(pp->name, name) == 0) {
+		if (pp->name != NULL && strcmp(pp->name, name) == 0) {
 			if (lenp != 0)
 				*lenp = pp->length;
 			return pp->value;
diff -u --recursive --new-file v2.4.5/linux/arch/ppc/kernel/smp.c linux/arch/ppc/kernel/smp.c
--- v2.4.5/linux/arch/ppc/kernel/smp.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/smp.c	Mon Jun 11 19:15:27 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.smp.c 1.23 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.smp.c 1.25 05/23/01 00:38:42 cort
  */
 /*
  * Smp support for ppc.
@@ -670,12 +670,12 @@
 static void
 smp_gemini_kick_cpu(int nr)
 {
-	openpic_init_processor( 1<<i );
+	openpic_init_processor( 1<<nr );
 	openpic_init_processor( 0 );
 }
 
 static void
-smp_gemini_setup_cpu(void)
+smp_gemini_setup_cpu(int cpu_nr)
 {
 	if (OpenPIC_Addr)
 		do_openpic_setup_cpu();
diff -u --recursive --new-file v2.4.5/linux/arch/ppc/kernel/time.c linux/arch/ppc/kernel/time.c
--- v2.4.5/linux/arch/ppc/kernel/time.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/time.c	Mon Jun 11 19:15:27 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.time.c 1.15 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.time.c 1.18 06/06/01 22:33:09 paulus
  */
 /*
  * Common time routines among all ppc machines.
@@ -210,6 +210,10 @@
 		ppc_md.heartbeat();
 	
 	hardirq_exit(cpu);
+
+	if (softirq_pending(cpu))
+		do_softirq();
+
 	return 1; /* lets ret_from_int know we can do checks */
 }
 
diff -u --recursive --new-file v2.4.5/linux/arch/ppc/xmon/xmon.c linux/arch/ppc/xmon/xmon.c
--- v2.4.5/linux/arch/ppc/xmon/xmon.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/xmon/xmon.c	Tue Jun 12 11:07:16 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.xmon.c 1.9 05/17/01 18:14:24 cort
+ * BK Id: SCCS/s.xmon.c 1.12 06/09/01 22:18:05 paulus
  */
 /*
  * Routines providing a simple monitor for use on the PowerMac.
@@ -661,8 +661,7 @@
 	unsigned stack[2];
 	struct pt_regs regs;
 	extern char ret_from_intercept, ret_from_syscall_1, ret_from_syscall_2;
-	extern char do_bottom_half_ret, do_signal_ret;
-	extern char ret_from_except;
+	extern char do_signal_ret, ret_from_except;
 
 	printf("backtrace:\n");
 	
@@ -680,7 +679,6 @@
 		    || stack[1] == (unsigned) &ret_from_except
 		    || stack[1] == (unsigned) &ret_from_syscall_1
 		    || stack[1] == (unsigned) &ret_from_syscall_2
-		    || stack[1] == (unsigned) &do_bottom_half_ret
 		    || stack[1] == (unsigned) &do_signal_ret) {
 			if (mread(sp+16, &regs, sizeof(regs)) != sizeof(regs))
 				break;
diff -u --recursive --new-file v2.4.5/linux/arch/sh/config.in linux/arch/sh/config.in
--- v2.4.5/linux/arch/sh/config.in	Tue Apr 17 17:19:25 2001
+++ linux/arch/sh/config.in	Wed Jun 27 13:55:29 2001
@@ -29,7 +29,9 @@
 choice 'SuperH system type'					\
 	"Generic		CONFIG_SH_GENERIC		\
 	 SolutionEngine		CONFIG_SH_SOLUTION_ENGINE	\
-	 Overdrive		CONFIG_SH_OVERDRIVE		\
+	 SolutionEngine7751	CONFIG_SH_7751_SOLUTION_ENGINE	\
+	 STB1_Harp		CONFIG_SH_STB1_HARP		\
+	 STB1_Overdrive		CONFIG_SH_STB1_OVERDRIVE	\
 	 HP620			CONFIG_SH_HP620			\
 	 HP680			CONFIG_SH_HP680			\
 	 HP690			CONFIG_SH_HP690			\
@@ -37,9 +39,17 @@
 	 DMIDA			CONFIG_SH_DMIDA    		\
 	 EC3104			CONFIG_SH_EC3104		\
 	 Dreamcast		CONFIG_SH_DREAMCAST		\
+	 CAT68701		CONFIG_SH_CAT68701		\
+	 BigSur			CONFIG_SH_BIGSUR		\
+	 SH2000			CONFIG_SH_SH2000		\
 	 BareCPU		CONFIG_SH_UNKNOWN" Generic
 
-define_bool CONFIG_SH_RTC y
+# The SH7750 RTC module is disabled in the Dreamcast
+if [ "$CONFIG_SH_DREAMCAST" = "y" ]; then
+   define_bool CONFIG_SH_RTC n
+else
+   define_bool CONFIG_SH_RTC y
+fi
 
 if [ "$CONFIG_SH_HP620" = "y" -o "$CONFIG_SH_HP680" = "y" -o \
      "$CONFIG_SH_HP690" = "y" ]; then
@@ -50,7 +60,9 @@
    "SH7707 CONFIG_CPU_SUBTYPE_SH7707 \
     SH7708 CONFIG_CPU_SUBTYPE_SH7708 \
     SH7709 CONFIG_CPU_SUBTYPE_SH7709 \
-    SH7750 CONFIG_CPU_SUBTYPE_SH7750" SH7708
+    SH7750 CONFIG_CPU_SUBTYPE_SH7750 \
+    SH7751 CONFIG_CPU_SUBTYPE_SH7751 \
+    ST40STB1 CONFIG_CPU_SUBTYPE_ST40STB1" SH7708
 if [ "$CONFIG_CPU_SUBTYPE_SH7707" = "y" ]; then
    define_bool CONFIG_CPU_SH3 y
    define_bool CONFIG_CPU_SH4 n
@@ -67,12 +79,30 @@
    define_bool CONFIG_CPU_SH3 n
    define_bool CONFIG_CPU_SH4 y
 fi
+if [ "$CONFIG_CPU_SUBTYPE_SH7751" = "y" ]; then
+   define_bool CONFIG_CPU_SH3 n
+   define_bool CONFIG_CPU_SH4 y
+fi
+if [ "$CONFIG_CPU_SUBTYPE_ST40STB1" = "y" ]; then
+   define_bool CONFIG_CPU_SH3 n
+   define_bool CONFIG_CPU_SH4 y
+fi
 bool 'Little Endian' CONFIG_CPU_LITTLE_ENDIAN
 if [ "$CONFIG_SH_SOLUTION_ENGINE" = "y" -o "$CONFIG_SH_HP600" = "y" -o \
-     "$CONFIG_SH_OVERDRIVE" = "y" ]; then
+     "$CONFIG_SH_BIGSUR" = "y" -o "$CONFIG_SH_7751_SOLUTION_ENGINE" = "y" -o \
+     "$CONFIG_SH_DREAMCAST" = "y" -o "$CONFIG_SH_SH2000" = "y" ]; then
   define_hex CONFIG_MEMORY_START 0c000000
 else
-  hex 'Physical memory start address' CONFIG_MEMORY_START 08000000
+  if [ "$CONFIG_CPU_SUBTYPE_ST40STB1" = "y" ]; then
+    bool 'Memory on LMI' CONFIG_ST40_LMI_MEMORY
+    if [ "$CONFIG_ST40_LMI_MEMORY" = "y" ] ; then
+      define_hex CONFIG_MEMORY_START 08000000
+    else
+      hex 'EMI physical memory start address' CONFIG_MEMORY_START 08000000
+    fi
+  else
+    hex 'Physical memory start address' CONFIG_MEMORY_START 08000000
+  fi
 fi
 endmenu
 
@@ -89,7 +119,8 @@
 
 bool 'Networking support' CONFIG_NET
 
-if [ "$CONFIG_SH_GENERIC" = "y" -o "$CONFIG_SH_SOLUTION_ENGINE" = "y" -o "$CONFIG_SH_UNKNOWN" = "y" ]; then
+if [ "$CONFIG_SH_GENERIC" = "y" -o "$CONFIG_SH_SOLUTION_ENGINE" = "y" -o \
+     "$CONFIG_SH_UNKNOWN" = "y" -o "$CONFIG_SH_CAT68701" = "y" ]; then
   bool 'Compact Flash Enabler support' CONFIG_CF_ENABLER
 fi
 
@@ -101,6 +132,7 @@
 
 bool 'Hitachi HD64465 companion chip support' CONFIG_HD64465
 if [ "$CONFIG_HD64465" = "y" ]; then
+   hex 'HD64465 start address' CONFIG_HD64465_IOBASE b0000000
    int 'HD64465 IRQ' CONFIG_HD64465_IRQ 5
 fi
 
@@ -197,6 +229,10 @@
 #
 source drivers/input/Config.in
 
+if [ "$CONFIG_SH_DREAMCAST" = "y" ]; then
+source drivers/maple/Config.in
+fi
+
 mainmenu_option next_comment
 comment 'Character devices'
 
@@ -217,10 +253,29 @@
 fi
 
 if [ "$CONFIG_SH_GENERIC" = "y" -o \
-     "$CONFIG_SH_OVERDRIVE" = "y" -o "$CONFIG_SH_SOLUTION_ENGINE" = "y" ]; then
+     "$CONFIG_SH_CAT68701" = "y" -o \
+     "$CONFIG_SH_STB1_HARP" = "y" -o \
+     "$CONFIG_SH_STB1_OVERDRIVE" = "y" -o \
+     "$CONFIG_SH_BIGSUR" = "y" -o \
+     "$CONFIG_SH_7751_SOLUTION_ENGINE" = "y" -o \
+     "$CONFIG_SH_SOLUTION_ENGINE" = "y" ]; then
   bool 'Heartbeat LED' CONFIG_HEARTBEAT
 fi
 
+if [ "$CONFIG_SH_DREAMCAST" = "y" -a "$CONFIG_MAPLE" != "n" ]; then
+   mainmenu_option next_comment
+   comment 'Maple Bus input peripherals'
+   if [ "$CONFIG_INPUT" != "n" ]; then
+      dep_tristate '  Maple Bus keyboard support' CONFIG_MAPLE_KEYBOARD $CONFIG_INPUT
+      dep_tristate '  Maple Bus mouse support' CONFIG_MAPLE_MOUSE $CONFIG_INPUT
+   else
+      comment 'Input core support is required for Maple input peripherals'
+   fi
+   endmenu
+fi
+
+source drivers/char/joystick/Config.in
+
 if [ "$CONFIG_PARPORT" != "n" ]; then
    dep_tristate 'Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT
    if [ "$CONFIG_PRINTER" != "n" ]; then
@@ -228,13 +283,16 @@
    fi
    dep_tristate 'Support for user-space parallel port device drivers' CONFIG_PPDEV $CONFIG_PARPORT
 fi
-endmenu
-
+bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE
+tristate 'Enhanced Real Time Clock Support' CONFIG_RTC
 if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then
    source drivers/char/pcmcia/Config.in
 fi
+endmenu
 
 source fs/Config.in
+
+source drivers/media/Config.in
 
 if [ "$CONFIG_VT" = "y" ]; then
    mainmenu_option next_comment
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/Makefile linux/arch/sh/kernel/Makefile
--- v2.4.5/linux/arch/sh/kernel/Makefile	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/Makefile	Wed Jun 27 13:55:29 2001
@@ -24,8 +24,15 @@
 obj-$(CONFIG_SH_STANDARD_BIOS)	+= sh_bios.o
 
 ifeq ($(CONFIG_PCI),y)
-obj-y				+= pci-sh.o 
+ifeq ($(CONFIG_SH_DREAMCAST),y)
+obj-y 				+= pci-dc.o
+else
+obj-y                           += pci-dma.o 
 obj-$(CONFIG_CPU_SUBTYPE_ST40STB1)+= pci_st40.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7751)+= pci-sh7751.o 
+obj-$(CONFIG_SH_BIGSUR)+= pci-bigsur.o
+obj-$(CONFIG_SH_7751_SOLUTION_ENGINE)+= pci-7751se.o
+endif
 endif
 
 obj-$(CONFIG_SH_HP600)		+= mach_hp600.o
@@ -33,6 +40,15 @@
 
 obj-$(CONFIG_SH_SOLUTION_ENGINE)+= mach_se.o setup_se.o io_se.o led_se.o
 machine-specific-objs		+= mach_se.o setup_se.o io_se.o led_se.o
+
+obj-$(CONFIG_SH_7751_SOLUTION_ENGINE)+= mach_se.o setup_se.o io_se.o led_se.o pci-7751se.o
+machine-specific-objs           += mach_se.o setup_se.o io_se.o led_se.o pci-7751se.o
+
+obj-$(CONFIG_SH_BIGSUR)		+= mach_bigsur.o setup_bigsur.o io_bigsur.o led_bigsur.o
+machine-specific-objs		+= mach_bigsur.o setup_bigsur.o io_bigsur.o led_bigsur.o
+
+obj-$(CONFIG_SH_SH2000)		+= setup_sh2000.o io_sh2000.o
+machine-specific-objs		+= setup_sh2000.o io_sh2000.o
 
 obj-$(CONFIG_SH_CAT68701) 	+= mach_cat68701.o io_cat68701.o
 machine-specific-objs		+= mach_cat68701.o io_cat68701.o
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/entry.S linux/arch/sh/kernel/entry.S
--- v2.4.5/linux/arch/sh/kernel/entry.S	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/entry.S	Wed Jun 27 13:55:29 2001
@@ -489,8 +489,9 @@
 __syscall_ret_trace:
 	.long	syscall_ret_trace
 __syscall_ret:
-	.long	SYMBOL_NAME(syscall_ret)
-
+	.long	syscall_ret
+__INV_IMASK:
+	.long	0xffffff0f	! ~(IMASK)
 
 
 	.align	2
@@ -502,30 +503,16 @@
 	.align	2
 1:	.long	SYMBOL_NAME(schedule)
 
-ENTRY(ret_from_irq)
-	mov	#OFF_SR, r0
-	mov.l	@(r0,r15), r0	! get status register
-	shll	r0
-	shll	r0		! kernel space?
-	bt	restore_all	! Yes, it's from kernel, go back soon
-	!
-	STI()
-	bra	ret_with_reschedule
-	 nop
-
-ENTRY(ret_from_exception)
+ret_from_irq:
+ret_from_exception:
 	mov	#OFF_SR, r0
 	mov.l	@(r0,r15), r0	! get status register
 	shll	r0
 	shll	r0		! kernel space?
 	bt	restore_all	! Yes, it's from kernel, go back soon
 	!
-	STI()
 	bra	ret_from_syscall
 	 nop
-	.align	2
-__INV_IMASK:
-	.long	0xffffff0f	! ~(IMASK)
 
 	.align 2
 #ifdef COMPAT_OLD_SYSCALL_ABI
@@ -538,16 +525,11 @@
 	/* fall through */
 
 ENTRY(ret_from_syscall)
-	mov.l	__irq_stat, r0	! softirq_active
-	mov.l	@r0, r1
-	mov.l	@(4,r0), r2	! softirq_mask
-	tst	r2, r1
-	bt	ret_with_reschedule
-handle_softirq:
-	mov.l	__do_softirq, r0
-	jsr	@r0
-	 nop
-ret_with_reschedule:
+	/* CLI */
+	stc	sr, r0
+	or	#0xf0, r0
+	ldc	r0, sr
+	!
 	stc	k_current, r1
 	mov.l	@(need_resched,r1), r0
 	tst	r0, r0
@@ -567,8 +549,6 @@
 	.long	SYMBOL_NAME(do_signal)
 __irq_stat:
 	.long	SYMBOL_NAME(irq_stat)
-__do_softirq:
-	.long	SYMBOL_NAME(do_softirq)
 
 	.align 2
 restore_all:
@@ -707,7 +687,7 @@
 	bra	handle_exception
 	 mov.l	@k2, k2
 	.align	2
-2:	.long	SYMBOL_NAME(ret_from_exception)
+2:	.long	ret_from_exception
 1:	.long	EXPEVT
 !
 !
@@ -728,8 +708,8 @@
 	.align	2
 1:	.long	EXPEVT
 2:	.long	INTEVT
-3:	.long	SYMBOL_NAME(ret_from_irq)
-4:	.long	SYMBOL_NAME(ret_from_exception)
+3:	.long	ret_from_irq
+4:	.long	ret_from_exception
 
 !
 !
@@ -941,24 +921,143 @@
 	.long   SYMBOL_NAME(do_IRQ)	! 63      pcc1i
 #endif
 #elif defined(__SH4__)
-	.long	SYMBOL_NAME(do_IRQ)	! Hitachi UDI
-	.long	SYMBOL_NAME(do_IRQ)	! GPIO
-	.long	SYMBOL_NAME(do_IRQ)	! DMAC dmte0
-	.long	SYMBOL_NAME(do_IRQ)	!      dmte1
-	.long	SYMBOL_NAME(do_IRQ)	!      dmte2
-	.long	SYMBOL_NAME(do_IRQ)	!      dmte3
-	.long	SYMBOL_NAME(do_IRQ)	!      dmae
-	.long	SYMBOL_NAME(do_IRQ)
-	.long	SYMBOL_NAME(do_IRQ)	! SCIF eri
-	.long	SYMBOL_NAME(do_IRQ)	!      rxi
-	.long	SYMBOL_NAME(do_IRQ)	!      bri
-	.long	SYMBOL_NAME(do_IRQ)	!      txi
+	.long	SYMBOL_NAME(do_IRQ)	! 32 Hitachi UDI
+	.long	SYMBOL_NAME(do_IRQ)	! 33 GPIO
+	.long	SYMBOL_NAME(do_IRQ)	! 34 DMAC dmte0
+	.long	SYMBOL_NAME(do_IRQ)	! 35      dmte1
+	.long	SYMBOL_NAME(do_IRQ)	! 36      dmte2
+	.long	SYMBOL_NAME(do_IRQ)	! 37      dmte3
+	.long	SYMBOL_NAME(do_IRQ)	! 38      dmae
+	.long	error			! 39
+	.long	SYMBOL_NAME(do_IRQ)	! 40 SCIF eri
+	.long	SYMBOL_NAME(do_IRQ)	! 41      rxi
+	.long	SYMBOL_NAME(do_IRQ)	! 42      bri
+	.long	SYMBOL_NAME(do_IRQ)	! 43      txi
+	.long	error			! 44
+	.long	error			! 45
+	.long	error			! 46
+	.long	error			! 47
+	.long	SYMBOL_NAME(do_fpu_state_restore)	! 48
+	.long	SYMBOL_NAME(do_fpu_state_restore)	! 49
+#endif
+#if defined(CONFIG_CPU_SUBTYPE_SH7751)
+	.long	error
+	.long	error
+	.long	error
+	.long	error
+	.long	error
+	.long	error
+	.long	error
+	.long	error
+	.long	error
+	.long	error
 	.long	error
 	.long	error
 	.long	error
 	.long	error
-	.long	SYMBOL_NAME(do_fpu_state_restore)
-	.long	SYMBOL_NAME(do_fpu_state_restore)
+	.long	SYMBOL_NAME(do_IRQ)	! PCI serr
+	.long	SYMBOL_NAME(do_IRQ)	!     dma3
+	.long	SYMBOL_NAME(do_IRQ)	!     dma2
+	.long	SYMBOL_NAME(do_IRQ)	!     dma1
+	.long	SYMBOL_NAME(do_IRQ)	!     dma0
+	.long	SYMBOL_NAME(do_IRQ)	!     pwon
+	.long	SYMBOL_NAME(do_IRQ)	!     pwdwn
+	.long	SYMBOL_NAME(do_IRQ)	!     err
+#elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
+	.long	error			!  50 0x840
+	.long	error			!  51 0x860
+	.long	error			!  52 0x880
+	.long	error			!  53 0x8a0
+	.long	error			!  54 0x8c0
+	.long	error			!  55 0x8e0
+	.long	error			!  56 0x900
+	.long	error			!  57 0x920
+	.long	error			!  58 0x940
+	.long	error			!  59 0x960
+	.long	error			!  60 0x980
+	.long	error			!  61 0x9a0
+	.long	error			!  62 0x9c0
+	.long	error			!  63 0x9e0
+	.long	SYMBOL_NAME(do_IRQ)	!  64 0xa00 PCI serr
+	.long	SYMBOL_NAME(do_IRQ)	!  65 0xa20     err
+	.long	SYMBOL_NAME(do_IRQ)	!  66 0xa40     ad
+	.long	SYMBOL_NAME(do_IRQ)	!  67 0xa60     pwr_dwn
+	.long	error			!  68 0xa80
+	.long	error			!  69 0xaa0
+	.long	error			!  70 0xac0
+	.long	error			!  71 0xae0
+	.long	SYMBOL_NAME(do_IRQ)	!  72 0xb00 DMA INT0
+	.long	SYMBOL_NAME(do_IRQ)	!  73 0xb20     INT1
+	.long	SYMBOL_NAME(do_IRQ)	!  74 0xb40     INT2
+	.long	SYMBOL_NAME(do_IRQ)	!  75 0xb60     INT3
+	.long	SYMBOL_NAME(do_IRQ)	!  76 0xb80     INT4
+	.long	error			!  77 0xba0
+	.long	SYMBOL_NAME(do_IRQ)	!  78 0xbc0 DMA ERR
+	.long	error			!  79 0xbe0
+	.long	SYMBOL_NAME(do_IRQ)	!  80 0xc00 PIO0
+	.long	SYMBOL_NAME(do_IRQ)	!  81 0xc20 PIO1
+	.long	SYMBOL_NAME(do_IRQ)	!  82 0xc40 PIO2
+	.long	error			!  83 0xc60
+	.long	error			!  84 0xc80
+	.long	error			!  85 0xca0
+	.long	error			!  86 0xcc0
+	.long	error			!  87 0xce0
+	.long	error			!  88 0xd00
+	.long	error			!  89 0xd20
+	.long	error			!  90 0xd40
+	.long	error			!  91 0xd60
+	.long	error			!  92 0xd80
+	.long	error			!  93 0xda0
+	.long	error			!  94 0xdc0
+	.long	error			!  95 0xde0
+	.long	error			!  96 0xe00
+	.long	error			!  97 0xe20
+	.long	error			!  98 0xe40
+	.long	error			!  99 0xe60
+	.long	error			! 100 0xe80
+	.long	error			! 101 0xea0
+	.long	error			! 102 0xec0
+	.long	error			! 103 0xee0
+	.long	error			! 104 0xf00
+	.long	error			! 105 0xf20
+	.long	error			! 106 0xf40
+	.long	error			! 107 0xf60
+	.long	error			! 108 0xf80
+	.long	error			! 109 0xfa0
+	.long	error			! 110 0xfc0
+	.long	error			! 111 0xfe0
+	.long	SYMBOL_NAME(do_IRQ)	! 112 0x1000 Mailbox
+	.long	error			! 113 0x1020
+	.long	error			! 114 0x1040
+	.long	error			! 115 0x1060
+	.long	error			! 116 0x1080
+	.long	error			! 117 0x10a0
+	.long	error			! 118 0x10c0
+	.long	error			! 119 0x10e0
+	.long	error			! 120 0x1100
+	.long	error			! 121 0x1120
+	.long	error			! 122 0x1140
+	.long	error			! 123 0x1160
+	.long	error			! 124 0x1180
+	.long	error			! 125 0x11a0
+	.long	error			! 126 0x11c0
+	.long	error			! 127 0x11e0
+	.long	error			! 128 0x1200
+	.long	error			! 129 0x1220
+	.long	error			! 130 0x1240
+	.long	error			! 131 0x1260
+	.long	error			! 132 0x1280
+	.long	error			! 133 0x12a0
+	.long	error			! 134 0x12c0
+	.long	error			! 135 0x12e0
+	.long	error			! 136 0x1300
+	.long	error			! 137 0x1320
+	.long	error			! 138 0x1340
+	.long	error			! 139 0x1360
+	.long	SYMBOL_NAME(do_IRQ)	! 140 0x1380 EMPI INV_ADDR
+	.long	error			! 141 0x13a0
+	.long	error			! 142 0x13c0
+	.long	error			! 143 0x13e0
 #endif
 
 ENTRY(sys_call_table)
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/hd64465_gpio.c linux/arch/sh/kernel/hd64465_gpio.c
--- v2.4.5/linux/arch/sh/kernel/hd64465_gpio.c	Sun May 20 12:11:38 2001
+++ linux/arch/sh/kernel/hd64465_gpio.c	Wed Jun 27 13:55:29 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: hd64465_gpio.c,v 1.1 2001/01/02 15:35:22 mjd Exp $
+ * $Id: hd64465_gpio.c,v 1.2 2001/05/24 00:13:47 gniibe Exp $
  * by Greg Banks <gbanks@pocketpenguins.com>
  * (c) 2000 PocketPenguins Inc
  *
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/io_bigsur.c linux/arch/sh/kernel/io_bigsur.c
--- v2.4.5/linux/arch/sh/kernel/io_bigsur.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/io_bigsur.c	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,249 @@
+/*
+ * include/asm-sh/io_bigsur.c
+ *
+ * By Dustin McIntire (dustin@sensoria.com) (c)2001
+ * Derived from io_hd64465.h, which bore the message:
+ * By Greg Banks <gbanks@pocketpenguins.com>
+ * (c) 2000 PocketPenguins Inc. 
+ * and from io_hd64461.h, which bore the message:
+ * Copyright 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * IO functions for a Hitachi Big Sur Evaluation Board.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/machvec.h>
+#include <asm/io.h>
+#include <asm/bigsur.h>
+
+//#define BIGSUR_DEBUG 2
+#undef BIGSUR_DEBUG
+
+#ifdef BIGSUR_DEBUG
+#define DPRINTK(args...)	printk(args)
+#define DIPRINTK(n, args...)	if (BIGSUR_DEBUG>(n)) printk(args)
+#else
+#define DPRINTK(args...)
+#define DIPRINTK(n, args...)
+#endif
+
+
+/* Low iomap maps port 0-1K to addresses in 8byte chunks */
+#define BIGSUR_IOMAP_LO_THRESH 0x400
+#define BIGSUR_IOMAP_LO_SHIFT	3
+#define BIGSUR_IOMAP_LO_MASK	((1<<BIGSUR_IOMAP_LO_SHIFT)-1)
+#define BIGSUR_IOMAP_LO_NMAP	(BIGSUR_IOMAP_LO_THRESH>>BIGSUR_IOMAP_LO_SHIFT)
+static u32 bigsur_iomap_lo[BIGSUR_IOMAP_LO_NMAP];
+static u8 bigsur_iomap_lo_shift[BIGSUR_IOMAP_LO_NMAP];
+
+/* High iomap maps port 1K-64K to addresses in 1K chunks */
+#define BIGSUR_IOMAP_HI_THRESH 0x10000
+#define BIGSUR_IOMAP_HI_SHIFT	10
+#define BIGSUR_IOMAP_HI_MASK	((1<<BIGSUR_IOMAP_HI_SHIFT)-1)
+#define BIGSUR_IOMAP_HI_NMAP	(BIGSUR_IOMAP_HI_THRESH>>BIGSUR_IOMAP_HI_SHIFT)
+static u32 bigsur_iomap_hi[BIGSUR_IOMAP_HI_NMAP];
+static u8 bigsur_iomap_hi_shift[BIGSUR_IOMAP_HI_NMAP];
+
+#ifndef MAX
+#define MAX(a,b)    ((a)>(b)?(a):(b))
+#endif
+
+#define PORT2ADDR(x) (sh_mv.mv_isa_port2addr(x))
+
+void bigsur_port_map(u32 baseport, u32 nports, u32 addr, u8 shift)
+{
+    u32 port, endport = baseport + nports;
+
+    DPRINTK("bigsur_port_map(base=0x%0x, n=0x%0x, addr=0x%08x)\n",
+	    baseport, nports, addr);
+	    
+	for (port = baseport ;
+	     port < endport && port < BIGSUR_IOMAP_LO_THRESH ;
+	     port += (1<<BIGSUR_IOMAP_LO_SHIFT)) {
+	    	DPRINTK("    maplo[0x%x] = 0x%08x\n", port, addr);
+    	    bigsur_iomap_lo[port>>BIGSUR_IOMAP_LO_SHIFT] = addr;
+    	    bigsur_iomap_lo_shift[port>>BIGSUR_IOMAP_LO_SHIFT] = shift;
+	    	addr += (1<<(BIGSUR_IOMAP_LO_SHIFT));
+	}
+
+	for (port = MAX(baseport, BIGSUR_IOMAP_LO_THRESH) ;
+	     port < endport && port < BIGSUR_IOMAP_HI_THRESH ;
+	     port += (1<<BIGSUR_IOMAP_HI_SHIFT)) {
+	    	DPRINTK("    maphi[0x%x] = 0x%08x\n", port, addr);
+    	    bigsur_iomap_hi[port>>BIGSUR_IOMAP_HI_SHIFT] = addr;
+    	    bigsur_iomap_hi_shift[port>>BIGSUR_IOMAP_HI_SHIFT] = shift;
+	    	addr += (1<<(BIGSUR_IOMAP_HI_SHIFT));
+	}
+}
+EXPORT_SYMBOL(bigsur_port_map);
+
+void bigsur_port_unmap(u32 baseport, u32 nports)
+{
+    u32 port, endport = baseport + nports;
+	
+    DPRINTK("bigsur_port_unmap(base=0x%0x, n=0x%0x)\n", baseport, nports);
+
+	for (port = baseport ;
+	     port < endport && port < BIGSUR_IOMAP_LO_THRESH ;
+	     port += (1<<BIGSUR_IOMAP_LO_SHIFT)) {
+    	    bigsur_iomap_lo[port>>BIGSUR_IOMAP_LO_SHIFT] = 0;
+	}
+
+	for (port = MAX(baseport, BIGSUR_IOMAP_LO_THRESH) ;
+	     port < endport && port < BIGSUR_IOMAP_HI_THRESH ;
+	     port += (1<<BIGSUR_IOMAP_HI_SHIFT)) {
+    	    bigsur_iomap_hi[port>>BIGSUR_IOMAP_HI_SHIFT] = 0;
+	}
+}
+EXPORT_SYMBOL(bigsur_port_unmap);
+
+unsigned long bigsur_isa_port2addr(unsigned long port)
+{
+    unsigned long addr = 0;
+	unsigned char shift;
+
+	/* Physical address not in P0, do nothing */
+	if (PXSEG(port)) addr = port;
+	/* physical address in P0, map to P2 */
+	else if (port >= 0x30000)
+	    addr = P2SEGADDR(port);
+	/* Big Sur I/O + HD64465 registers 0x10000-0x30000 */
+	else if (port >= BIGSUR_IOMAP_HI_THRESH)
+	    addr = BIGSUR_INTERNAL_BASE + (port - BIGSUR_IOMAP_HI_THRESH);
+	/* Handle remapping of high IO/PCI IO ports */
+	else if (port >= BIGSUR_IOMAP_LO_THRESH) {
+	    addr = bigsur_iomap_hi[port >> BIGSUR_IOMAP_HI_SHIFT];
+	    shift = bigsur_iomap_hi_shift[port >> BIGSUR_IOMAP_HI_SHIFT];
+	    if (addr != 0)
+		    addr += (port & BIGSUR_IOMAP_HI_MASK) << shift;
+	}
+	/* Handle remapping of low IO ports */
+	else {
+	    addr = bigsur_iomap_lo[port >> BIGSUR_IOMAP_LO_SHIFT];
+	    shift = bigsur_iomap_lo_shift[port >> BIGSUR_IOMAP_LO_SHIFT];
+	    if (addr != 0)
+	    	addr += (port & BIGSUR_IOMAP_LO_MASK) << shift;
+	}
+
+    DIPRINTK(2, "PORT2ADDR(0x%08lx) = 0x%08lx\n", port, addr);
+
+	return addr;
+}
+
+static inline void delay(void)
+{
+	ctrl_inw(0xa0000000);
+}
+
+unsigned char bigsur_inb(unsigned long port)
+{
+	unsigned long addr = PORT2ADDR(port);
+	unsigned long b = (addr == 0 ? 0 : *(volatile unsigned char*)addr);
+
+	DIPRINTK(0, "inb(%08lx) = %02x\n", addr, (unsigned)b);
+	return b;
+}
+
+unsigned char bigsur_inb_p(unsigned long port)
+{
+    unsigned long v;
+	unsigned long addr = PORT2ADDR(port);
+
+	v = (addr == 0 ? 0 : *(volatile unsigned char*)addr);
+	delay();
+	DIPRINTK(0, "inb_p(%08lx) = %02x\n", addr, (unsigned)v);
+	return v;
+}
+
+unsigned short bigsur_inw(unsigned long port)
+{
+    unsigned long addr = PORT2ADDR(port);
+	unsigned long b = (addr == 0 ? 0 : *(volatile unsigned short*)addr);
+	DIPRINTK(0, "inw(%08lx) = %04lx\n", addr, b);
+	return b;
+}
+
+unsigned int bigsur_inl(unsigned long port)
+{
+    unsigned long addr = PORT2ADDR(port);
+	unsigned int b = (addr == 0 ? 0 : *(volatile unsigned long*)addr);
+	DIPRINTK(0, "inl(%08lx) = %08x\n", addr, b);
+	return b;
+}
+
+void bigsur_insb(unsigned long port, void *buffer, unsigned long count)
+{
+	unsigned char *buf=buffer;
+	while(count--) *buf++=inb(port);
+}
+
+void bigsur_insw(unsigned long port, void *buffer, unsigned long count)
+{
+	unsigned short *buf=buffer;
+	while(count--) *buf++=inw(port);
+}
+
+void bigsur_insl(unsigned long port, void *buffer, unsigned long count)
+{
+	unsigned long *buf=buffer;
+	while(count--) *buf++=inl(port);
+}
+
+void bigsur_outb(unsigned char b, unsigned long port)
+{
+	unsigned long addr = PORT2ADDR(port);
+
+	DIPRINTK(0, "outb(%02x, %08lx)\n", (unsigned)b, addr);
+	if (addr != 0)
+	    *(volatile unsigned char*)addr = b;
+}
+
+void bigsur_outb_p(unsigned char b, unsigned long port)
+{
+	unsigned long addr = PORT2ADDR(port);
+
+	DIPRINTK(0, "outb_p(%02x, %08lx)\n", (unsigned)b, addr);
+    if (addr != 0)
+	    *(volatile unsigned char*)addr = b;
+	delay();
+}
+
+void bigsur_outw(unsigned short b, unsigned long port)
+{
+	unsigned long addr = PORT2ADDR(port);
+	DIPRINTK(0, "outw(%04x, %08lx)\n", (unsigned)b, addr);
+	if (addr != 0)
+	    *(volatile unsigned short*)addr = b;
+}
+
+void bigsur_outl(unsigned int b, unsigned long port)
+{
+	unsigned long addr = PORT2ADDR(port);
+	DIPRINTK(0, "outl(%08x, %08lx)\n", b, addr);
+	if (addr != 0)
+            *(volatile unsigned long*)addr = b;
+}
+
+void bigsur_outsb(unsigned long port, const void *buffer, unsigned long count)
+{
+	const unsigned char *buf=buffer;
+	while(count--) outb(*buf++, port);
+}
+
+void bigsur_outsw(unsigned long port, const void *buffer, unsigned long count)
+{
+	const unsigned short *buf=buffer;
+	while(count--) outw(*buf++, port);
+}
+
+void bigsur_outsl(unsigned long port, const void *buffer, unsigned long count)
+{
+	const unsigned long *buf=buffer;
+	while(count--) outl(*buf++, port);
+}
+
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/io_dc.c linux/arch/sh/kernel/io_dc.c
--- v2.4.5/linux/arch/sh/kernel/io_dc.c	Sun May 20 12:11:38 2001
+++ linux/arch/sh/kernel/io_dc.c	Wed Jun 27 13:55:29 2001
@@ -1,5 +1,5 @@
 /*
- *	$Id: io_dc.c,v 1.1 2001/04/01 15:02:00 yaegashi Exp $
+ *	$Id: io_dc.c,v 1.2 2001/05/24 00:13:47 gniibe Exp $
  *	I/O routines for SEGA Dreamcast
  */
 
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/io_hd64465.c linux/arch/sh/kernel/io_hd64465.c
--- v2.4.5/linux/arch/sh/kernel/io_hd64465.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/io_hd64465.c	Wed Jun 27 13:55:29 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: io_hd64465.c,v 1.6 2001/02/15 09:13:51 dave_mckay Exp $
+ * $Id: io_hd64465.c,v 1.7 2001/05/09 07:39:36 gniibe Exp $
  * by Greg Banks <gbanks@pocketpenguins.com>
  * (c) 2000 PocketPenguins Inc
  *
@@ -52,6 +52,8 @@
 #define MAX(a,b)    ((a)>(b)?(a):(b))
 #endif
 
+#define PORT2ADDR(x) (sh_mv.mv_isa_port2addr(x))
+
 void hd64465_port_map(unsigned short baseport, unsigned int nports,
 		      unsigned long addr, unsigned char shift)
 {
@@ -101,7 +103,7 @@
 }
 EXPORT_SYMBOL(hd64465_port_unmap);
 
-static /*__inline__*/ unsigned long PORT2ADDR(unsigned long port)
+unsigned long hd64465_isa_port2addr(unsigned long port)
 {
     	unsigned long addr = 0;
 	unsigned char shift;
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/io_sh2000.c linux/arch/sh/kernel/io_sh2000.c
--- v2.4.5/linux/arch/sh/kernel/io_sh2000.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/io_sh2000.c	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,19 @@
+/*
+ * I/O routine for SH-2000
+ */
+#include <linux/config.h>
+#include <asm/io.h>
+#include <asm/machvec.h>
+
+#define IDE_OFFSET    0xb6200000
+#define NIC_OFFSET    0xb6000000
+#define EXTBUS_OFFSET 0xba000000
+
+unsigned long sh2000_isa_port2addr(unsigned long offset)
+{
+	if((offset & ~7) == 0x1f0 || offset == 0x3f6)
+		return IDE_OFFSET + offset;
+	else if((offset & ~0x1f) == 0x300)
+		return NIC_OFFSET + offset;
+	return EXTBUS_OFFSET + offset;
+}
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/irq.c linux/arch/sh/kernel/irq.c
--- v2.4.5/linux/arch/sh/kernel/irq.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/sh/kernel/irq.c	Wed Jun 27 13:55:29 2001
@@ -38,12 +38,6 @@
 #include <linux/irq.h>
 
 /*
- * Micro-access to controllers is serialized over the whole
- * system. We never hold this lock when we call the actual
- * IRQ handler.
- */
-spinlock_t irq_controller_lock = SPIN_LOCK_UNLOCKED;
-/*
  * Controller mappings for all interrupt sources:
  */
 irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
@@ -160,14 +154,15 @@
  */
 void disable_irq_nosync(unsigned int irq)
 {
+	irq_desc_t *desc = irq_desc + irq;
 	unsigned long flags;
 
-	spin_lock_irqsave(&irq_controller_lock, flags);
-	if (!irq_desc[irq].depth++) {
-		irq_desc[irq].status |= IRQ_DISABLED;
-		irq_desc[irq].handler->disable(irq);
+	spin_lock_irqsave(&desc->lock, flags);
+	if (!desc->depth++) {
+		desc->status |= IRQ_DISABLED;
+		desc->handler->disable(irq);
 	}
-	spin_unlock_irqrestore(&irq_controller_lock, flags);
+	spin_unlock_irqrestore(&desc->lock, flags);
 }
 
 /*
@@ -187,28 +182,29 @@
 
 void enable_irq(unsigned int irq)
 {
+	irq_desc_t *desc = irq_desc + irq;
 	unsigned long flags;
 
-	spin_lock_irqsave(&irq_controller_lock, flags);
-	switch (irq_desc[irq].depth) {
+	spin_lock_irqsave(&desc->lock, flags);
+	switch (desc->depth) {
 	case 1: {
-		unsigned int status = irq_desc[irq].status & ~IRQ_DISABLED;
-		irq_desc[irq].status = status;
+		unsigned int status = desc->status & ~IRQ_DISABLED;
+		desc->status = status;
 		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
-			irq_desc[irq].status = status | IRQ_REPLAY;
-			hw_resend_irq(irq_desc[irq].handler,irq);
+			desc->status = status | IRQ_REPLAY;
+			hw_resend_irq(desc->handler,irq);
 		}
-		irq_desc[irq].handler->enable(irq);
+		desc->handler->enable(irq);
 		/* fall-through */
 	}
 	default:
-		irq_desc[irq].depth--;
+		desc->depth--;
 		break;
 	case 0:
 		printk("enable_irq() unbalanced from %p\n",
 		       __builtin_return_address(0));
 	}
-	spin_unlock_irqrestore(&irq_controller_lock, flags);
+	spin_unlock_irqrestore(&desc->lock, flags);
 }
 
 /*
@@ -245,7 +241,7 @@
 
 	kstat.irqs[cpu][irq]++;
 	desc = irq_desc + irq;
-	spin_lock(&irq_controller_lock);
+	spin_lock(&desc->lock);
 	desc->handler->ack(irq);
 	/*
 	   REPLAY is when Linux resends an IRQ that was dropped earlier
@@ -265,7 +261,6 @@
 		status |= IRQ_INPROGRESS; /* we are handling it */
 	}
 	desc->status = status;
-	spin_unlock(&irq_controller_lock);
 
 	/*
 	 * If there is no IRQ handler or it was disabled, exit early.
@@ -274,7 +269,7 @@
 	   will take care of it.
 	 */
 	if (!action)
-		return 1;
+		goto out;
 
 	/*
 	 * Edge triggered interrupts need to remember
@@ -287,23 +282,24 @@
 	 * SMP environment.
 	 */
 	for (;;) {
+		spin_unlock(&desc->lock);
 		handle_IRQ_event(irq, &regs, action);
-		spin_lock(&irq_controller_lock);
+		spin_lock(&desc->lock);
 
 		if (!(desc->status & IRQ_PENDING))
 			break;
 		desc->status &= ~IRQ_PENDING;
-		spin_unlock(&irq_controller_lock);
 	}
 	desc->status &= ~IRQ_INPROGRESS;
-	if (!(desc->status & IRQ_DISABLED))
-		desc->handler->end(irq);
-	spin_unlock(&irq_controller_lock);
+out:
+	/*
+	 * The ->end() handler has to deal with interrupts which got
+	 * disabled while the handler was running.
+	 */
+	desc->handler->end(irq);
+	spin_unlock(&desc->lock);
 
-#if 0
-	__sti();
-#endif
-	if (softirq_active(cpu)&softirq_mask(cpu))
+	if (softirq_pending(cpu))
 		do_softirq();
 	return 1;
 }
@@ -342,14 +338,16 @@
 
 void free_irq(unsigned int irq, void *dev_id)
 {
+	irq_desc_t *desc;
 	struct irqaction **p;
 	unsigned long flags;
 
 	if (irq >= ACTUAL_NR_IRQS)
 		return;
 
-	spin_lock_irqsave(&irq_controller_lock,flags);
-	p = &irq_desc[irq].action;
+	desc = irq_desc + irq;
+	spin_lock_irqsave(&desc->lock,flags);
+	p = &desc->action;
 	for (;;) {
 		struct irqaction * action = *p;
 		if (action) {
@@ -360,20 +358,22 @@
 
 			/* Found it - now remove it from the list of entries */
 			*pp = action->next;
-			if (!irq_desc[irq].action) {
-				irq_desc[irq].status |= IRQ_DISABLED;
-				irq_desc[irq].handler->shutdown(irq);
+			if (!desc->action) {
+				desc->status |= IRQ_DISABLED;
+				desc->handler->shutdown(irq);
 			}
-			spin_unlock_irqrestore(&irq_controller_lock,flags);
+			spin_unlock_irqrestore(&desc->lock,flags);
 			kfree(action);
 			return;
 		}
 		printk("Trying to free free IRQ%d\n",irq);
-		spin_unlock_irqrestore(&irq_controller_lock,flags);
+		spin_unlock_irqrestore(&desc->lock,flags);
 		return;
 	}
 }
 
+static DECLARE_MUTEX(probe_sem);
+
 /*
  * IRQ autodetection code..
  *
@@ -385,21 +385,44 @@
 unsigned long probe_irq_on(void)
 {
 	unsigned int i;
-	unsigned long delay;
+	irq_desc_t *desc;
 	unsigned long val;
+	unsigned long delay;
+
+	down(&probe_sem);
+	/* 
+	 * something may have generated an irq long ago and we want to
+	 * flush such a longstanding irq before considering it as spurious. 
+	 */
+	for (i = NR_IRQS-1; i > 0; i--) {
+		desc = irq_desc + i;
+
+		spin_lock_irq(&desc->lock);
+		if (!desc->action)
+		  desc->handler->startup(i);
+		spin_unlock_irq(&desc->lock);
+	}
+
+	/* Wait for longstanding interrupts to trigger. */
+	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
+		/* about 20ms delay */ synchronize_irq();
 
 	/*
-	 * first, enable any unassigned irqs
+	 * enable any unassigned irqs
+	 * (we must startup again here because if a longstanding irq
+	 * happened in the previous stage, it may have masked itself)
 	 */
-	spin_lock_irq(&irq_controller_lock);
 	for (i = NR_IRQS-1; i > 0; i--) {
-		if (!irq_desc[i].action) {
-			irq_desc[i].status |= IRQ_AUTODETECT | IRQ_WAITING;
-			if (irq_desc[i].handler->startup(i))
-				irq_desc[i].status |= IRQ_PENDING;
+		desc = irq_desc + i;
+
+		spin_lock_irq(&desc->lock);
+		if (!desc->action) {
+			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
+			if (desc->handler->startup(i))
+				desc->status |= IRQ_PENDING;
 		}
+		spin_unlock_irq(&desc->lock);
 	}
-	spin_unlock_irq(&irq_controller_lock);
 
 	/*
 	 * Wait for spurious interrupts to trigger
@@ -411,23 +434,25 @@
 	 * Now filter out any obviously spurious interrupts
 	 */
 	val = 0;
-	spin_lock_irq(&irq_controller_lock);
 	for (i=0; i<NR_IRQS; i++) {
-		unsigned int status = irq_desc[i].status;
+		desc = irq_desc + i;
+		unsigned int status;
 
-		if (!(status & IRQ_AUTODETECT))
-			continue;
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
 
-		/* It triggered already - consider it spurious. */
-		if (!(status & IRQ_WAITING)) {
-			irq_desc[i].status = status & ~IRQ_AUTODETECT;
-			irq_desc[i].handler->shutdown(i);
+		if (status & IRQ_AUTODETECT) {
+			/* It triggered already - consider it spurious. */
+			if (!(status & IRQ_WAITING)) {
+				desc->status = status & ~IRQ_AUTODETECT;
+				desc->handler->shutdown(i);
+			} else
+				if (i < 32)
+					val |= 1 << i;
 		}
-
-		if (i < 32)
-			val |= 1 << i;
+		spin_unlock_irq(&desc->lock);
 	}
-	spin_unlock_irq(&irq_controller_lock);
+	spin_unlock_irq(&desc->lock);
 
 	return val;
 }
@@ -438,22 +463,25 @@
 
 	nr_irqs = 0;
 	irq_found = 0;
-	spin_lock_irq(&irq_controller_lock);
 	for (i=0; i<NR_IRQS; i++) {
-		unsigned int status = irq_desc[i].status;
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
 
-		if (!(status & IRQ_AUTODETECT))
-			continue;
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
 
-		if (!(status & IRQ_WAITING)) {
-			if (!nr_irqs)
-				irq_found = i;
-			nr_irqs++;
+		if (status & IRQ_AUTODETECT) {
+			if (!(status & IRQ_WAITING)) {
+				if (!nr_irqs)
+					irq_found = i;
+				nr_irqs++;
+			}
+			desc->status = status & ~IRQ_AUTODETECT;
+			desc->handler->shutdown(i);
 		}
-		irq_desc[i].status = status & ~IRQ_AUTODETECT;
-		irq_desc[i].handler->shutdown(i);
+		spin_unlock_irq(&desc->lock);
 	}
-	spin_unlock_irq(&irq_controller_lock);
+	up(&probe_sem);
 
 	if (nr_irqs > 1)
 		irq_found = -irq_found;
@@ -465,6 +493,7 @@
 	int shared = 0;
 	struct irqaction *old, **p;
 	unsigned long flags;
+	irq_desc_t *desc = irq_desc + irq;
 
 	/*
 	 * Some drivers like serial.c use request_irq() heavily,
@@ -486,12 +515,12 @@
 	/*
 	 * The following block of code has to be executed atomically
 	 */
-	spin_lock_irqsave(&irq_controller_lock,flags);
-	p = &irq_desc[irq].action;
+	spin_lock_irqsave(&desc->lock,flags);
+	p = &desc->action;
 	if ((old = *p) != NULL) {
 		/* Can't share interrupts unless both agree to */
 		if (!(old->flags & new->flags & SA_SHIRQ)) {
-			spin_unlock_irqrestore(&irq_controller_lock,flags);
+			spin_unlock_irqrestore(&desc->lock,flags);
 			return -EBUSY;
 		}
 
@@ -506,11 +535,11 @@
 	*p = new;
 
 	if (!shared) {
-		irq_desc[irq].depth = 0;
-		irq_desc[irq].status &= ~IRQ_DISABLED;
-		irq_desc[irq].handler->startup(irq);
+		desc->depth = 0;
+		desc->status &= ~IRQ_DISABLED;
+		desc->handler->startup(irq);
 	}
-	spin_unlock_irqrestore(&irq_controller_lock,flags);
+	spin_unlock_irqrestore(&desc->lock,flags);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/irq_intc2.c linux/arch/sh/kernel/irq_intc2.c
--- v2.4.5/linux/arch/sh/kernel/irq_intc2.c	Sun May 20 12:11:38 2001
+++ linux/arch/sh/kernel/irq_intc2.c	Wed Jun 27 13:55:29 2001
@@ -45,7 +45,7 @@
 }
 
 static struct hw_interrupt_type intc2_irq_type = {
-	"INTC2-based-IRQ",
+	"INTC2-IRQ",
 	startup_intc2_irq,
 	shutdown_intc2_irq,
 	enable_intc2_irq,
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/irq_ipr.c linux/arch/sh/kernel/irq_ipr.c
--- v2.4.5/linux/arch/sh/kernel/irq_ipr.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/irq_ipr.c	Wed Jun 27 13:55:29 2001
@@ -46,7 +46,7 @@
 }
 
 static struct hw_interrupt_type ipr_irq_type = {
-	"IPR-based-IRQ",
+	"IPR-IRQ",
 	startup_ipr_irq,
 	shutdown_ipr_irq,
 	enable_ipr_irq,
@@ -189,7 +189,9 @@
 
 void __init init_IRQ(void)
 {
+#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
 	int i;
+#endif
 
 	make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY);
 	make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY);
@@ -226,27 +228,6 @@
 	 * Initialize the Interrupt Controller (INTC)
 	 * registers to their power on values
 	 */ 
-#if 0
-	/*
-	 * XXX: I think that this is the job of boot loader. -- gniibe
-	 *
-	 * When Takeshi released new boot loader following setting
-	 * will be removed shortly.
-	 */
-	ctrl_outb(0, INTC_IRR0);
-	ctrl_outb(0, INTC_IRR1);
-	ctrl_outb(0, INTC_IRR2);
-
-	ctrl_outw(0, INTC_ICR0);
-	ctrl_outw(0, INTC_ICR1);/* Really? 0x4000?*/
-	ctrl_outw(0, INTC_ICR2);
-	ctrl_outw(0, INTC_INTER);
-	ctrl_outw(0, INTC_IPRA);
-	ctrl_outw(0, INTC_IPRB);
-	ctrl_outw(0, INTC_IPRC);
-	ctrl_outw(0, INTC_IPRD);
-	ctrl_outw(0, INTC_IPRE);
-#endif
 
 	/*
 	 * Enable external irq (INTC IRQ mode).
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/led_bigsur.c linux/arch/sh/kernel/led_bigsur.c
--- v2.4.5/linux/arch/sh/kernel/led_bigsur.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/led_bigsur.c	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,55 @@
+/*
+ * linux/arch/sh/kernel/led_bigsur.c
+ *
+ * By Dustin McIntire (dustin@sensoria.com) (c)2001
+ * Derived from led_se.c and led.c, which bore the message:
+ * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * This file contains Big Sur specific LED code.
+ */
+
+#include <linux/config.h>
+#include <asm/io.h>
+#include <asm/bigsur.h>
+
+static void mach_led(int position, int value)
+{
+	int word;
+	
+	word = bigsur_inl(BIGSUR_CSLR);
+	if (value) {
+		bigsur_outl(word & ~BIGSUR_LED, BIGSUR_CSLR);
+	} else {
+		bigsur_outl(word | BIGSUR_LED, BIGSUR_CSLR);
+	}
+}
+
+#ifdef CONFIG_HEARTBEAT
+
+#include <linux/sched.h>
+
+/* Cycle the LED on/off */
+void heartbeat_bigsur(void)
+{
+	static unsigned cnt = 0, period = 0, dist = 0;
+
+	if (cnt == 0 || cnt == dist)
+		mach_led( -1, 1);
+	else if (cnt == 7 || cnt == dist+7)
+		mach_led( -1, 0);
+
+	if (++cnt > period) {
+		cnt = 0;
+		/* The hyperbolic function below modifies the heartbeat period
+		 * length in dependency of the current (5min) load. It goes
+		 * through the points f(0)=126, f(1)=86, f(5)=51,
+		 * f(inf)->30. */
+		period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
+		dist = period / 4;
+	}
+}
+#endif /* CONFIG_HEARTBEAT */
+
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/mach_bigsur.c linux/arch/sh/kernel/mach_bigsur.c
--- v2.4.5/linux/arch/sh/kernel/mach_bigsur.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/mach_bigsur.c	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,77 @@
+/*
+ * linux/arch/sh/kernel/mach_bigsur.c
+ *
+ * By Dustin McIntire (dustin@sensoria.com) (c)2001
+ * Derived from mach_se.h, which bore the message:
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * Machine vector for the Hitachi Big Sur Evaluation Board
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+#include <asm/io.h>
+#include <asm/io_bigsur.h>
+#include <asm/irq.h>
+
+/*
+ * The Machine Vector
+ */
+extern void heartbeat_bigsur(void);
+extern void setup_bigsur(void);
+extern void init_bigsur_IRQ(void);
+
+struct sh_machine_vector mv_bigsur __initmv = {
+	mv_name:		"Big Sur",
+	mv_nr_irqs:		NR_IRQS,     // Defined in <asm/irq.h>
+	mv_inb:			bigsur_inb,
+	mv_inw:			bigsur_inw,
+	mv_inl:			bigsur_inl,
+	mv_outb:		bigsur_outb,
+	mv_outw:		bigsur_outw,
+	mv_outl:		bigsur_outl,
+
+	mv_inb_p:		bigsur_inb_p,
+	mv_inw_p:		bigsur_inw,
+	mv_inl_p:		bigsur_inl,
+	mv_outb_p:		bigsur_outb_p,
+	mv_outw_p:		bigsur_outw,
+	mv_outl_p:		bigsur_outl,
+
+	mv_insb:		bigsur_insb,
+	mv_insw:		bigsur_insw,
+	mv_insl:		bigsur_insl,
+	mv_outsb:		bigsur_outsb,
+	mv_outsw:		bigsur_outsw,
+	mv_outsl:		bigsur_outsl,
+
+	mv_readb:		generic_readb,
+	mv_readw:		generic_readw,
+	mv_readl:		generic_readl,
+	mv_writeb:		generic_writeb,
+	mv_writew:		generic_writew,
+	mv_writel:		generic_writel,
+
+	mv_ioremap:		generic_ioremap,
+	mv_iounmap:		generic_iounmap,
+
+	mv_isa_port2addr:	bigsur_isa_port2addr,
+	mv_irq_demux:       bigsur_irq_demux,
+
+	mv_init_arch:		setup_bigsur,
+	mv_init_irq:		init_bigsur_IRQ,
+#ifdef CONFIG_HEARTBEAT
+	mv_heartbeat:		heartbeat_bigsur,
+#endif
+	mv_rtc_gettimeofday:	sh_rtc_gettimeofday,
+	mv_rtc_settimeofday:	sh_rtc_settimeofday,
+
+};
+ALIAS_MV(bigsur)
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/mach_dc.c linux/arch/sh/kernel/mach_dc.c
--- v2.4.5/linux/arch/sh/kernel/mach_dc.c	Sun May 20 12:11:38 2001
+++ linux/arch/sh/kernel/mach_dc.c	Wed Jun 27 13:55:29 2001
@@ -1,5 +1,5 @@
 /*
- *	$Id: mach_dc.c,v 1.1 2001/04/01 15:02:00 yaegashi Exp $
+ *	$Id: mach_dc.c,v 1.4 2001/05/24 05:09:16 mrbrown Exp $
  *	SEGA Dreamcast machine vector
  */
 
@@ -23,7 +23,7 @@
 struct sh_machine_vector mv_dreamcast __initmv = {
 	mv_name:		"dreamcast",
 
-	mv_nr_irqs:		48,
+	mv_nr_irqs:		NR_IRQS,
 
 	mv_inb:			generic_inb,
 	mv_inw:			generic_inw,
@@ -57,11 +57,9 @@
 	mv_iounmap:		generic_iounmap,
 
 	mv_init_arch:		setup_dreamcast,
-#ifdef CONFIG_PCI
-	mv_init_pci:		dreamcast_pcibios_init,
-#endif
 	mv_isa_port2addr:	dreamcast_isa_port2addr,
+	mv_irq_demux:		systemasic_irq_demux,
 
-	mv_hw_dreamcast:		1,
+	mv_hw_dreamcast:	1,
 };
 ALIAS_MV(dreamcast)
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/pci-7751se.c linux/arch/sh/kernel/pci-7751se.c
--- v2.4.5/linux/arch/sh/kernel/pci-7751se.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/pci-7751se.c	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,102 @@
+/*
+ * linux/arch/sh/kernel/pci-7751se.c
+ *
+ * Author:  Ian DaSilva (idasilva@mvista.com)
+ *
+ * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * PCI initialization for the Hitachi SH7751 Solution Engine board (MS7751SE01)
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+#include <asm/io.h>
+#include <asm/pci-sh7751.h>
+
+#define PCIMCR_MRSET_OFF	0xBFFFFFFF
+#define PCIMCR_RFSH_OFF		0xFFFFFFFB
+
+/*
+ * Only long word accesses of the PCIC's internal local registers and the
+ * configuration registers from the CPU is supported.
+ */
+#define PCIC_WRITE(x,v) writel((v), PCI_REG(x))
+#define PCIC_READ(x) readl(PCI_REG(x))
+
+/*
+ * Description:  This function sets up and initializes the pcic, sets
+ * up the BARS, maps the DRAM into the address space etc, etc.
+ */
+int __init pcibios_init_platform(void)
+{
+   unsigned long data;
+   unsigned long bcr1, wcr1, wcr2, wcr3, mcr;
+   unsigned short bcr2;
+
+   //
+   // Initialize the slave bus controller on the pcic.  The values used
+   // here should not be hardcoded, but they should be taken from the bsc
+   // on the processor, to make this function as generic as possible.
+   // (i.e. Another sbc may usr different SDRAM timing settings -- in order
+   // for the pcic to work, its settings need to be exactly the same.)
+   //
+   bcr1 = (*(volatile unsigned long*)(SH7751_BCR1));
+   bcr2 = (*(volatile unsigned short*)(SH7751_BCR2));
+   wcr1 = (*(volatile unsigned long*)(SH7751_WCR1));
+   wcr2 = (*(volatile unsigned long*)(SH7751_WCR2));
+   wcr3 = (*(volatile unsigned long*)(SH7751_WCR3));
+   mcr = (*(volatile unsigned long*)(SH7751_MCR));
+
+   bcr1 = bcr1 | 0x00080000;  /* Enable Bit 19, BREQEN */
+   (*(volatile unsigned long*)(SH7751_BCR1)) = bcr1;   
+
+   bcr1 = bcr1 | 0x40080000;  /* Enable Bit 19 BREQEN, set PCIC to slave */
+   PCIC_WRITE(SH7751_PCIBCR1, bcr1);	 /* PCIC BCR1 */
+   PCIC_WRITE(SH7751_PCIBCR2, bcr2);     /* PCIC BCR2 */
+   PCIC_WRITE(SH7751_PCIWCR1, wcr1);     /* PCIC WCR1 */
+   PCIC_WRITE(SH7751_PCIWCR2, wcr2);     /* PCIC WCR2 */
+   PCIC_WRITE(SH7751_PCIWCR3, wcr3);     /* PCIC WCR3 */
+   mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
+   PCIC_WRITE(SH7751_PCIMCR, mcr);      /* PCIC MCR */
+
+   PCIC_WRITE(SH7751_PCIINTM, 0x0000c3ff);
+   PCIC_WRITE(SH7751_PCIAINTM, 0x0000980f);
+   PCIC_WRITE(SH7751_PCICONF1, 0xF39000C7);  /* FB9000C7 */
+   PCIC_WRITE(SH7751_PCICONF2, 0x00000000);  /* PCI Class code & Revision ID */
+   PCIC_WRITE(SH7751_PCICONF4, 0xab000001);  /* PCI I/O */
+   PCIC_WRITE(SH7751_PCICONF5, 0x0c000000);  /* PCI MEM0 old val: 0xb0000000 */
+   PCIC_WRITE(SH7751_PCICONF6, 0xd0000000);  /* PCI MEM1 */
+   PCIC_WRITE(SH7751_PCICONF11, 0x35051054); /* PCI Sub system ID & Sub system vendor ID */
+   PCIC_WRITE(SH7751_PCILSR0, 0x03f00000);   /* PCI MEM0 */
+   PCIC_WRITE(SH7751_PCILSR1, 0x00000000);   /* PCI MEM1 */
+   PCIC_WRITE(SH7751_PCILAR0, 0x0c000000);   /* MEM0 */
+   PCIC_WRITE(SH7751_PCILAR1, 0x00000000);   /* MEM1 */
+
+   PCIC_WRITE(SH7751_PCICR, 0xa5000001);
+
+   printk("SH7751 PCI: Finished initialization of the PCI controller\n");
+
+   return 1;
+}
+
+int __init pcibios_map_platform_irq(u8 slot, u8 pin)
+{
+        switch (slot) {
+        case 0: return 13;
+        case 1: return 13; 	/* AMD Ethernet controller */
+        case 2: return -1;
+        case 3: return -1;
+        case 4: return -1;
+        default:
+                printk("PCI: Bad IRQ mapping request for slot %d\n", slot);
+                return -1;
+        }
+}
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/pci-bigsur.c linux/arch/sh/kernel/pci-bigsur.c
--- v2.4.5/linux/arch/sh/kernel/pci-bigsur.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/pci-bigsur.c	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,163 @@
+/*
+ * linux/arch/sh/kernel/pci-bigsur.c
+ *
+ * By Dustin McIntire (dustin@sensoria.com) (c)2001
+
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * PCI initialization for the Hitachi Big Sur Evaluation Board
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+#include <asm/io.h>
+#include <asm/pci-sh7751.h>
+#include <asm/bigsur.h>
+
+#define PCI_REG(reg)        (SH7751_PCIREG_BASE+reg)
+
+/*
+ * Initialize the Big Sur PCI interface 
+ * Setup hardware to be Central Funtion
+ * Copy the BSR regs to the PCI interface
+ * Setup PCI windows into local RAM
+ */
+int __init pcibios_init_platform(void) {
+	u32 reg;
+	u32 word;
+
+	PCIDBG(1,"PCI: bigsur_pci_init called\n");
+	/* Set the BCR's to enable PCI access */
+	reg = inl(SH7751_BCR1);
+	reg |= 0x80000;
+	outl(reg, SH7751_BCR1);
+	
+	/* Setup the host hardware */
+	if(inl(PCI_REG(SH7751_PCICONF0)) !=
+	   (u32)((SH7751_DEVICE_ID <<16) | (SH7751_VENDOR_ID))) {
+	   printk("PCI: Unkown PCI host bridge.\n");
+	   return 0;
+	}  
+	printk("PCI: SH7751 PCI host bridge found.\n");
+	
+	/* Turn the clocks back on (not done in reset)*/
+	outl(0, PCI_REG(SH7751_PCICLKR));
+	/* Clear Powerdown IRQ's (not done in reset) */
+	word = SH7751_PCIPINT_D3 | SH7751_PCIPINT_D0;
+	outl(word, PCI_REG(SH7751_PCICLKR));
+
+	/* toggle PCI reset pin */
+	word = SH7751_PCICR_PREFIX | SH7751_PCICR_PRST;
+	outl(word,PCI_REG(SH7751_PCICR));    
+	/* Wait for a long time... not 1 sec. but long enough */
+	mdelay(100);
+	word = SH7751_PCICR_PREFIX;
+	outl(word,PCI_REG(SH7751_PCICR)); 
+	
+    /* set the command/status bits to:
+     * Wait Cycle Control + Parity Enable + Bus Master +
+     * Mem space enable
+     */
+    word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER | 
+           SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES;
+	outl(word, PCI_REG(SH7751_PCICONF1));
+
+	/* define this host as the host bridge */
+	word = SH7751_PCI_HOST_BRIDGE << 24;
+	outl(word, PCI_REG(SH7751_PCICONF2));
+
+	/* Set IO and Mem windows to local address 
+	 * Make PCI and local address the same for easy 1 to 1 mapping 
+	 * Window0 = BIGSUR_LSR0_SIZE @ non-cached CS3 base = SDRAM
+	 * Window1 = BIGSUR_LSR1_SIZE @ cached CS3 base = SDRAM 
+	 */
+	word = BIGSUR_LSR0_SIZE - 1;
+	outl(word, PCI_REG(SH7751_PCILSR0));
+	word = BIGSUR_LSR1_SIZE - 1;
+	outl(word, PCI_REG(SH7751_PCILSR1));
+	/* Set the values on window 0 PCI config registers */
+	word = P2SEGADDR(SH7751_CS3_BASE_ADDR);
+	outl(word, PCI_REG(SH7751_PCILAR0));
+	outl(word, PCI_REG(SH7751_PCICONF5));
+	/* Set the values on window 1 PCI config registers */
+	word =  PHYSADDR(SH7751_CS3_BASE_ADDR);
+	outl(word, PCI_REG(SH7751_PCILAR1));
+	outl(word, PCI_REG(SH7751_PCICONF6));
+
+	/* Set the local 16MB PCI memory space window to 
+	 * the lowest PCI mapped address
+	 */
+	word = PCIBIOS_MIN_MEM & SH7751_PCIMBR_MASK;
+	PCIDBG(2,"PCI: Setting upper bits of Memory window to 0x%x\n", word);
+	outl(word , PCI_REG(SH7751_PCIMBR));
+
+	/* Map IO space into PCI IO window
+	 * The IO window is 64K-PCIBIOS_MIN_IO in size
+	 * IO addresses will be translated to the 
+	 * PCI IO window base address
+	 */
+	PCIDBG(3,"PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", PCIBIOS_MIN_IO,
+	    (64*1024), SH7751_PCI_IO_BASE+PCIBIOS_MIN_IO);
+	bigsur_port_map(PCIBIOS_MIN_IO, (64*1024), SH7751_PCI_IO_BASE+PCIBIOS_MIN_IO,0);
+	    
+	/* Make sure the MSB's of IO window are set to access PCI space correctly */
+	word = PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK;
+	PCIDBG(2,"PCI: Setting upper bits of IO window to 0x%x\n", word);
+	outl(word, PCI_REG(SH7751_PCIIOBR));
+	
+	/* Set PCI WCRx, BCRx's, copy from BSC locations */
+	word = inl(SH7751_BCR1);
+	/* check BCR for SDRAM in area 3 */
+	if(((word >> 3) & 1) == 0) {
+		printk("PCI: Area 3 is not configured for SDRAM. BCR1=0x%x\n", word);
+		return 0;
+	}
+	outl(word, PCI_REG(SH7751_PCIBCR1));
+	word = (u16)inw(SH7751_BCR2);
+	/* check BCR2 for 32bit SDRAM interface*/
+	if(((word >> 6) & 0x3) != 0x3) {
+		printk("PCI: Area 3 is not 32 bit SDRAM. BCR2=0x%x\n", word);
+		return 0;
+	}
+	outl(word, PCI_REG(SH7751_PCIBCR2));
+	/* configure the wait control registers */
+	word = inl(SH7751_WCR1);
+	outl(word, PCI_REG(SH7751_PCIWCR1));
+	word = inl(SH7751_WCR2);
+	outl(word, PCI_REG(SH7751_PCIWCR2));
+	word = inl(SH7751_WCR3);
+	outl(word, PCI_REG(SH7751_PCIWCR3));
+	word = inl(SH7751_MCR);
+	outl(word, PCI_REG(SH7751_PCIMCR));
+
+	/* NOTE: I'm ignoring the PCI error IRQs for now..
+	 * TODO: add support for the internal error interrupts and
+	 * DMA interrupts...
+	 */
+	 
+	/* SH7751 init done, set central function init complete */
+	word = SH7751_PCICR_PREFIX | SH7751_PCICR_CFIN;
+	outl(word,PCI_REG(SH7751_PCICR)); 
+	PCIDBG(2,"PCI: bigsur_pci_init finished\n");
+
+	return 1;
+}
+
+int pcibios_map_platform_irq(u8 slot, u8 pin)
+{
+    /* The Big Sur can be used in a CPCI chassis, but the SH7751 PCI interface is on the
+     * wrong end of the board so that it can also support a V320 CPI interface chip...
+     * Therefor the IRQ mapping is somewhat use dependent... I'l assume a linear map for
+     * now, i.e. INTA=slot0,pin0... INTD=slot3,pin0...
+     */ 
+    int irq = (slot + pin-1)%4 + BIGSUR_SH7751_PCI_IRQ_BASE;
+    PCIDBG(2,"PCI: Mapping Big Sur IRQ for slot %d, pin %c to irq %d\n", slot, pin-1+'A', irq);
+    return irq;
+     
+}
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/pci-dc.c linux/arch/sh/kernel/pci-dc.c
--- v2.4.5/linux/arch/sh/kernel/pci-dc.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/pci-dc.c	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,276 @@
+/*
+ $	$Id: pci-dc.c,v 1.2 2001/05/24 05:09:16 mrbrown Exp $
+ *	Dreamcast PCI: Supports SEGA Broadband Adaptor only.
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/pci.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/dc_sysasic.h>
+
+#define	GAPSPCI_REGS		0x01001400
+#define GAPSPCI_DMA_BASE	0x01840000
+#define GAPSPCI_DMA_SIZE	32768
+#define GAPSPCI_BBA_CONFIG	0x01001600
+
+#define	GAPSPCI_IRQ		HW_EVENT_EXTERNAL
+
+static int gapspci_dma_used;
+
+static struct pci_bus *pci_root_bus;
+
+struct pci_fixup pcibios_fixups[] = {
+	{0, 0, 0, NULL}
+};
+
+#define BBA_SELECTED(dev) (dev->bus->number==0 && dev->devfn==0)
+
+static int gapspci_read_config_byte(struct pci_dev *dev, int where,
+                                    u8 * val)
+{
+	if (BBA_SELECTED(dev))
+		*val = inb(GAPSPCI_BBA_CONFIG+where);
+	else
+                *val = 0xff;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int gapspci_read_config_word(struct pci_dev *dev, int where,
+                                    u16 * val)
+{
+        if (BBA_SELECTED(dev))
+		*val = inw(GAPSPCI_BBA_CONFIG+where);
+	else
+                *val = 0xffff;
+
+        return PCIBIOS_SUCCESSFUL;
+}
+
+static int gapspci_read_config_dword(struct pci_dev *dev, int where,
+                                     u32 * val)
+{
+        if (BBA_SELECTED(dev))
+		*val = inl(GAPSPCI_BBA_CONFIG+where);
+	else
+                *val = 0xffffffff;
+
+        return PCIBIOS_SUCCESSFUL;
+}
+
+static int gapspci_write_config_byte(struct pci_dev *dev, int where,
+                                     u8 val)
+{
+        if (BBA_SELECTED(dev))
+		outb(val, GAPSPCI_BBA_CONFIG+where);
+
+        return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int gapspci_write_config_word(struct pci_dev *dev, int where,
+                                     u16 val)
+{
+        if (BBA_SELECTED(dev))
+		outw(val, GAPSPCI_BBA_CONFIG+where);
+
+        return PCIBIOS_SUCCESSFUL;
+}
+
+static int gapspci_write_config_dword(struct pci_dev *dev, int where,
+                                      u32 val)
+{
+        if (BBA_SELECTED(dev))
+		outl(val, GAPSPCI_BBA_CONFIG+where);
+
+        return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pci_config_ops = {
+        gapspci_read_config_byte,
+        gapspci_read_config_word,
+        gapspci_read_config_dword,
+        gapspci_write_config_byte,
+        gapspci_write_config_word,
+        gapspci_write_config_dword
+};
+
+
+void pcibios_align_resource(void *data, struct resource *res,
+			    unsigned long size)
+{
+}
+
+
+void __init pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+}
+
+
+void __init pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+			     struct resource *res, int resource)
+{
+}
+
+
+void pcibios_set_master(struct pci_dev *dev)
+{
+	/* No special bus mastering setup handling */
+}
+
+
+int pcibios_enable_device(struct pci_dev *dev)
+{
+
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for (idx = 0; idx < 6; idx++) {
+		r = dev->resource + idx;
+		if (!r->start && r->end) {
+			printk(KERN_ERR
+			       "PCI: Device %s not available because"
+			       " of resource collisions\n",
+			       dev->slot_name);
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (cmd != old_cmd) {
+		printk("PCI: enabling device %s (%04x -> %04x)\n",
+		       dev->slot_name, old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+
+}
+
+
+void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+			   dma_addr_t * dma_handle)
+{
+	unsigned long buf;
+
+	if (gapspci_dma_used+size > GAPSPCI_DMA_SIZE)
+		return NULL;
+
+	buf = GAPSPCI_DMA_BASE+gapspci_dma_used;
+
+	gapspci_dma_used = PAGE_ALIGN(gapspci_dma_used+size);
+	
+	printk("pci_alloc_consistent: %ld bytes at 0x%p\n", size, buf);
+
+	*dma_handle = (dma_addr_t)buf;
+
+	return (void *)P2SEGADDR(buf);
+}
+
+
+void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle)
+{
+	/* XXX */
+}
+
+
+void __init pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
+{
+}                                                                                
+
+void __init pcibios_fixup_bus(struct pci_bus *bus)
+{
+	struct list_head *ln;
+	struct pci_dev *dev;
+
+	for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
+		dev = pci_dev_b(ln);
+		if (!BBA_SELECTED(dev)) continue;
+
+		printk("PCI: MMIO fixup to %s\n", dev->name);
+		dev->resource[1].start=0x01001700;
+		dev->resource[1].end=0x010017ff;
+	}
+}
+
+
+static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
+{
+	return PCI_SLOT(dev->devfn);
+}
+
+
+static int __init map_dc_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	return GAPSPCI_IRQ;
+}
+
+
+void __init pcibios_init(void)
+{
+	pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
+	/* pci_assign_unassigned_resources(); */
+	pci_fixup_irqs(no_swizzle, map_dc_irq);
+}
+
+
+/* Haven't done anything here as yet */
+char * __init pcibios_setup(char *str)
+{
+	return str;
+}
+
+
+int __init gapspci_init(void)
+{
+	int i;
+	char idbuf[16];
+
+	for(i=0; i<16; i++)
+		idbuf[i]=inb(GAPSPCI_REGS+i);
+
+	if(strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16))
+		return -1;
+
+	outl(0x5a14a501, GAPSPCI_REGS+0x18);
+
+	for(i=0; i<1000000; i++);
+
+	if(inl(GAPSPCI_REGS+0x18)!=1)
+		return -1;
+
+	outl(0x01000000, GAPSPCI_REGS+0x20);
+	outl(0x01000000, GAPSPCI_REGS+0x24);
+
+	outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28);
+	outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c);
+
+	outl(1, GAPSPCI_REGS+0x14);
+	outl(1, GAPSPCI_REGS+0x34);
+
+	gapspci_dma_used=0;
+
+	/* Setting Broadband Adapter */
+	outw(0xf900, GAPSPCI_BBA_CONFIG+0x06);
+	outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30);
+	outb(0x00, GAPSPCI_BBA_CONFIG+0x3c);
+	outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d);
+	outw(0x0006, GAPSPCI_BBA_CONFIG+0x04);
+	outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10);
+	outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14);
+
+	return 0;
+}
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/pci-dma.c linux/arch/sh/kernel/pci-dma.c
--- v2.4.5/linux/arch/sh/kernel/pci-dma.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/pci-dma.c	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,42 @@
+/* 
+ * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.                            
+ *
+ * Dynamic DMA mapping support.
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+
+
+void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+			   dma_addr_t * dma_handle)
+{
+	void *ret;
+	int gfp = GFP_ATOMIC;
+
+	ret = (void *) __get_free_pages(gfp, get_order(size));
+
+	if (ret != NULL) {
+	        /* Is it neccessary to do the memset? */
+		memset(ret, 0, size);
+		*dma_handle = virt_to_bus(ret);
+	}
+	/* We must flush the cache before we pass it on to the device */
+	flush_cache_all();
+	return  P2SEGADDR(ret);
+}
+
+void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle)
+{
+        unsigned long p1addr=P1SEGADDR((unsigned long)vaddr);
+
+	free_pages(p1addr, get_order(size));
+}
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/pci-sh.c linux/arch/sh/kernel/pci-sh.c
--- v2.4.5/linux/arch/sh/kernel/pci-sh.c	Wed Aug  9 13:59:04 2000
+++ linux/arch/sh/kernel/pci-sh.c	Wed Dec 31 16:00:00 1969
@@ -1,25 +0,0 @@
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/errno.h>
-#include <asm/machvec.h>
-
-void __init pcibios_init(void)
-{
-	if (sh_mv.mv_init_pci != NULL) {
-		sh_mv.mv_init_pci();
-	}
-}
-
-/* Haven't done anything here as yet */
-char * __init pcibios_setup(char *str)
-{
-	return str;
-}
-
-/* We don't have anything here to fixup */
-struct pci_fixup pcibios_fixups[] = {
-	{0, 0, 0, NULL}
-};
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/pci-sh7751.c linux/arch/sh/kernel/pci-sh7751.c
--- v2.4.5/linux/arch/sh/kernel/pci-sh7751.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/pci-sh7751.c	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,674 @@
+/*
+ *	Low-Level PCI Support for the SH7751
+ *
+ *  Dustin McIntire (dustin@sensoria.com)
+ *	Derived from arch/i386/kernel/pci-*.c which bore the message:
+ *	(c) 1999--2000 Martin Mares <mj@suse.cz>
+ *	
+ *  May be copied or modified under the terms of the GNU General Public
+ *  License.  See linux/COPYING for more information.
+ *
+*/
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+#include <linux/irq.h>
+
+#include <asm/segment.h>
+#include <asm/machvec.h>
+#include <asm/io.h>
+#include <asm/pci-sh7751.h>
+
+struct pci_ops *pci_check_direct(void);
+void pcibios_resource_survey(void);
+static u8 pcibios_swizzle(struct pci_dev *dev, u8 *pin);
+static int pcibios_lookup_irq(struct pci_dev *dev, u8 slot, u8 pin);
+
+unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1;
+int pcibios_last_bus = -1;
+struct pci_bus *pci_root_bus;
+struct pci_ops *pci_root_ops;
+
+/*
+ * Direct access to PCI hardware...
+ */
+
+#ifdef CONFIG_PCI_DIRECT
+
+
+#define CONFIG_CMD(dev, where) (0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) | (where & ~3))
+
+#define PCI_REG(reg) (SH7751_PCIREG_BASE+reg)
+
+/*
+ * Functions for accessing PCI configuration space with type 1 accesses
+ */
+static int pci_conf1_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	u32 word;
+	unsigned long flags;
+
+    /* PCIPDR may only be accessed as 32 bit words, 
+     * so we must do byte alignment by hand 
+     */
+	__save_and_cli(flags);
+	outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
+	word = inl(PCI_REG(SH7751_PCIPDR));
+	__restore_flags(flags);
+	switch (where & 0x3) {
+	    case 3:
+		    *value = (u8)(word >> 24);
+			break;
+		case 2:
+		    *value = (u8)(word >> 16);
+			break;
+		case 1:
+		    *value = (u8)(word >> 8);
+			break;
+		default:
+		    *value = (u8)word;
+			break;
+    }
+	PCIDBG(4,"pci_conf1_read_config_byte@0x%08x=0x%x\n",
+	     CONFIG_CMD(dev,where),*value);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_conf1_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	u32 word;
+	unsigned long flags;
+
+    /* PCIPDR may only be accessed as 32 bit words, 
+     * so we must do word alignment by hand 
+     */
+	__save_and_cli(flags);
+	outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
+	word = inl(PCI_REG(SH7751_PCIPDR));
+	__restore_flags(flags);
+	switch (where & 0x3) {
+	    case 3:
+		    // This should never happen...
+			printk(KERN_ERR "PCI BIOS: read_config_word: Illegal u16 alignment");
+	        return PCIBIOS_BAD_REGISTER_NUMBER;
+		case 2:
+		    *value = (u16)(word >> 16);
+			break;
+		case 1:
+		    *value = (u16)(word >> 8);
+			break;
+		default:
+		    *value = (u16)word;
+			break;
+    }
+	PCIDBG(4,"pci_conf1_read_config_word@0x%08x=0x%x\n",
+	     CONFIG_CMD(dev,where),*value);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_conf1_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+	unsigned long flags;
+	
+	__save_and_cli(flags);
+	outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
+	*value = inl(PCI_REG(SH7751_PCIPDR));
+	__restore_flags(flags);
+	PCIDBG(4,"pci_conf1_read_config_dword@0x%08x=0x%x\n",
+	     CONFIG_CMD(dev,where),*value);
+	return PCIBIOS_SUCCESSFUL;    
+}
+
+static int pci_conf1_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	u32 word;
+	u32 shift = (where & 3) * 8;
+	u32 mask = ((1 << 8) - 1) << shift;  // create the byte mask
+	unsigned long flags;
+
+    /* Since SH7751 only does 32bit access we'll have to do a
+     * read,mask,write operation
+     */ 
+	__save_and_cli(flags);
+	outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
+	word = inl(PCI_REG(SH7751_PCIPDR)) ;
+	word &= ~mask;
+	word |= value << shift;
+ 
+	outl(word, PCI_REG(SH7751_PCIPDR));
+	__restore_flags(flags);
+	PCIDBG(4,"pci_conf1_write_config_byte@0x%08x=0x%x\n",
+	     CONFIG_CMD(dev,where),word);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_conf1_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	u32 word;
+	u32 shift = (where & 3) * 8;
+	u32 mask = ((1 << 16) - 1) << shift;  // create the word mask
+	unsigned long flags;
+
+    /* Since SH7751 only does 32bit access we'll have to do a
+     * read,mask,write operation.  We'll allow an odd byte offset,
+	 * though it should be illegal.
+     */ 
+	if (shift == 24)
+	    return PCIBIOS_BAD_REGISTER_NUMBER;
+	__save_and_cli(flags);
+	outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
+	word = inl(PCI_REG(SH7751_PCIPDR)) ;
+	word &= ~mask;
+	word |= value << shift;
+ 
+	outl(value, PCI_REG(SH7751_PCIPDR));
+	__restore_flags(flags);
+	PCIDBG(4,"pci_conf1_write_config_word@0x%08x=0x%x\n",
+	     CONFIG_CMD(dev,where),word);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_conf1_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
+	outl(value, PCI_REG(SH7751_PCIPDR));
+	__restore_flags(flags);
+	PCIDBG(4,"pci_conf1_write_config_dword@0x%08x=0x%x\n",
+	     CONFIG_CMD(dev,where),value);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+#undef CONFIG_CMD
+
+static struct pci_ops pci_direct_conf1 = {
+	pci_conf1_read_config_byte,
+	pci_conf1_read_config_word,
+	pci_conf1_read_config_dword,
+	pci_conf1_write_config_byte,
+	pci_conf1_write_config_word,
+	pci_conf1_write_config_dword
+};
+
+struct pci_ops * __init pci_check_direct(void)
+{
+	unsigned int tmp, id;
+
+	/* check for SH7751 hardware */
+	id = (SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID;
+	if(inl(SH7751_PCIREG_BASE+SH7751_PCICONF0) != id) {
+		PCIDBG(2,"PCI: This is not an SH7751\n");
+		return NULL;
+	}
+	/*
+	 * Check if configuration works.
+	 */
+	if (pci_probe & PCI_PROBE_CONF1) {
+		tmp = inl (PCI_REG(SH7751_PCIPAR));
+		outl (0x80000000, PCI_REG(SH7751_PCIPAR));
+		if (inl (PCI_REG(SH7751_PCIPAR)) == 0x80000000) {
+			outl (tmp, PCI_REG(SH7751_PCIPAR));
+			printk(KERN_INFO "PCI: Using configuration type 1\n");
+			request_region(PCI_REG(SH7751_PCIPAR), 8, "PCI conf1");
+			return &pci_direct_conf1;
+		}
+		outl (tmp, PCI_REG(SH7751_PCIPAR));
+	}
+
+	PCIDBG(2,"PCI: pci_check_direct failed\n");
+	return NULL;
+}
+
+#endif
+
+/*
+ * BIOS32 and PCI BIOS handling.
+ * 
+ * The BIOS version of the pci functions is not yet implemented but it is left
+ * in for completeness.  Currently an error will be genereated at compile time. 
+ */
+ 
+#ifdef CONFIG_PCI_BIOS
+
+#error PCI BIOS is not yet supported on SH7751
+
+#endif /* CONFIG_PCI_BIOS */
+
+/***************************************************************************************/
+
+/*
+ *  Handle bus scanning and fixups ....
+ */
+
+
+/*
+ * Discover remaining PCI buses in case there are peer host bridges.
+ * We use the number of last PCI bus provided by the PCI BIOS.
+ */
+static void __init pcibios_fixup_peer_bridges(void)
+{
+	int n;
+	struct pci_bus bus;
+	struct pci_dev dev;
+	u16 l;
+
+	if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff)
+		return;
+	PCIDBG(2,"PCI: Peer bridge fixup\n");
+	for (n=0; n <= pcibios_last_bus; n++) {
+		if (pci_bus_exists(&pci_root_buses, n))
+			continue;
+		bus.number = n;
+		bus.ops = pci_root_ops;
+		dev.bus = &bus;
+		for(dev.devfn=0; dev.devfn<256; dev.devfn += 8)
+			if (!pci_read_config_word(&dev, PCI_VENDOR_ID, &l) &&
+			    l != 0x0000 && l != 0xffff) {
+				PCIDBG(3,"Found device at %02x:%02x [%04x]\n", n, dev.devfn, l);
+				printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n);
+				pci_scan_bus(n, pci_root_ops, NULL);
+				break;
+			}
+	}
+}
+
+
+static void __init pci_fixup_ide_bases(struct pci_dev *d)
+{
+	int i;
+
+	/*
+	 * PCI IDE controllers use non-standard I/O port decoding, respect it.
+	 */
+	if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
+		return;
+	PCIDBG(3,"PCI: IDE base address fixup for %s\n", d->slot_name);
+	for(i=0; i<4; i++) {
+		struct resource *r = &d->resource[i];
+		if ((r->start & ~0x80) == 0x374) {
+			r->start |= 2;
+			r->end = r->start;
+		}
+	}
+}
+
+
+/* Add future fixups here... */
+struct pci_fixup pcibios_fixups[] = {
+	{ PCI_FIXUP_HEADER,	PCI_ANY_ID,	PCI_ANY_ID,	pci_fixup_ide_bases },
+	{ 0 }
+};
+
+void __init pcibios_fixup_pbus_ranges(struct pci_bus *b,
+		struct pbus_set_ranges_data *range)
+{
+	/* No fixups needed */
+}
+
+/*
+ *  Called after each bus is probed, but before its children
+ *  are examined.
+ */
+
+void __init pcibios_fixup_bus(struct pci_bus *b)
+{
+	pci_read_bridge_bases(b);
+}
+
+/*
+ * Initialization. Try all known PCI access methods. Note that we support
+ * using both PCI BIOS and direct access: in such cases, we use I/O ports
+ * to access config space.
+ * 
+ * Note that the platform specific initialization (BSC registers, and memory
+ * space mapping) will be called via the machine vectors (sh_mv.mv_pci_init()) if it
+ * exitst and via the platform defined function pcibios_init_platform().  
+ * See pci_bigsur.c for implementation;
+ * 
+ * The BIOS version of the pci functions is not yet implemented but it is left
+ * in for completeness.  Currently an error will be genereated at compile time. 
+ */
+
+void __init pcibios_init(void)
+{
+	struct pci_ops *bios = NULL;
+	struct pci_ops *dir = NULL;
+
+	PCIDBG(1,"PCI: Starting intialization.\n");
+#ifdef CONFIG_PCI_BIOS
+	if ((pci_probe & PCI_PROBE_BIOS) && ((bios = pci_find_bios()))) {
+		pci_probe |= PCI_BIOS_SORT;
+		pci_bios_present = 1;
+	}
+#endif
+#ifdef CONFIG_PCI_DIRECT
+	if (pci_probe & PCI_PROBE_CONF1 )
+		dir = pci_check_direct();
+#endif
+	if (dir) {
+		pci_root_ops = dir;
+	    if(!pcibios_init_platform())
+			PCIDBG(1,"PCI: Initialization failed\n");
+	    if (sh_mv.mv_init_pci != NULL)
+            sh_mv.mv_init_pci();
+	}
+	else if (bios)
+		pci_root_ops = bios;
+	else {
+		PCIDBG(1,"PCI: No PCI bus detected\n");
+		return;
+	}
+
+	PCIDBG(1,"PCI: Probing PCI hardware\n");
+	pci_root_bus = pci_scan_bus(0, pci_root_ops, NULL);
+	//pci_assign_unassigned_resources();
+	pci_fixup_irqs(pcibios_swizzle, pcibios_lookup_irq);
+	pcibios_fixup_peer_bridges();
+	pcibios_resource_survey();
+
+#ifdef CONFIG_PCI_BIOS
+	if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
+		pcibios_sort();
+#endif
+}
+
+char * __init pcibios_setup(char *str)
+{
+	if (!strcmp(str, "off")) {
+		pci_probe = 0;
+		return NULL;
+	}
+#ifdef CONFIG_PCI_BIOS
+	else if (!strcmp(str, "bios")) {
+		pci_probe = PCI_PROBE_BIOS;
+		return NULL;
+	} else if (!strcmp(str, "nobios")) {
+		pci_probe &= ~PCI_PROBE_BIOS;
+		return NULL;
+	} else if (!strcmp(str, "nosort")) {
+		pci_probe |= PCI_NO_SORT;
+		return NULL;
+	} else if (!strcmp(str, "biosirq")) {
+		pci_probe |= PCI_BIOS_IRQ_SCAN;
+		return NULL;
+	}
+#endif
+#ifdef CONFIG_PCI_DIRECT
+	else if (!strcmp(str, "conf1")) {
+		pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS;
+		return NULL;
+	}
+#endif
+	else if (!strcmp(str, "rom")) {
+		pci_probe |= PCI_ASSIGN_ROMS;
+		return NULL;
+	} else if (!strncmp(str, "lastbus=", 8)) {
+		pcibios_last_bus = simple_strtol(str+8, NULL, 0);
+		return NULL;
+	}
+	return str;
+}
+
+void
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+			struct resource *res, int resource)
+{
+	u32 new, check;
+	int reg;
+
+	new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+	if (resource < 6) {
+		reg = PCI_BASE_ADDRESS_0 + 4*resource;
+	} else if (resource == PCI_ROM_RESOURCE) {
+		res->flags |= PCI_ROM_ADDRESS_ENABLE;
+		new |= PCI_ROM_ADDRESS_ENABLE;
+		reg = dev->rom_base_reg;
+	} else {
+		/* Somebody might have asked allocation of a non-standard resource */
+		return;
+	}
+	
+	pci_write_config_dword(dev, reg, new);
+	pci_read_config_dword(dev, reg, &check);
+	if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
+		printk(KERN_ERR "PCI: Error while updating region "
+		       "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+		       new, check);
+	}
+}
+
+/*
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ */
+void
+pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+{
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long start = res->start;
+
+		if (start & 0x300) {
+			start = (start + 0x3ff) & ~0x3ff;
+			res->start = start;
+		}
+	}
+}
+
+
+/*
+ *    Allocate the bridge and device resources
+ */
+
+static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
+{
+	struct list_head *ln;
+	struct pci_bus *bus;
+	struct pci_dev *dev;
+	int idx;
+	struct resource *r, *pr;
+	
+	PCIDBG(2,"PCI: pcibios_allocate_bus_reasources called\n" );
+	/* Depth-First Search on bus tree */
+	for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
+		bus = pci_bus_b(ln);
+		if ((dev = bus->self)) {
+			for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
+				r = &dev->resource[idx];
+				if (!r->start)
+					continue;
+				pr = pci_find_parent_resource(dev, r);
+				if (!pr || request_resource(pr, r) < 0)
+					printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, dev->slot_name);
+			}
+		}
+		pcibios_allocate_bus_resources(&bus->children);
+	}
+}
+
+static void __init pcibios_allocate_resources(int pass)
+{
+	struct pci_dev *dev;
+	int idx, disabled;
+	u16 command;
+	struct resource *r, *pr;
+
+	PCIDBG(2,"PCI: pcibios_allocate_resources pass %d called\n", pass);
+	pci_for_each_dev(dev) {
+		pci_read_config_word(dev, PCI_COMMAND, &command);
+		for(idx = 0; idx < 6; idx++) {
+			r = &dev->resource[idx];
+			if (r->parent)		/* Already allocated */
+				continue;
+			if (!r->start)		/* Address not assigned at all */
+				continue;
+			if (r->flags & IORESOURCE_IO)
+				disabled = !(command & PCI_COMMAND_IO);
+			else
+				disabled = !(command & PCI_COMMAND_MEMORY);
+			if (pass == disabled) {
+				PCIDBG(3,"PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n",
+				    r->start, r->end, r->flags, disabled, pass);
+				pr = pci_find_parent_resource(dev, r);
+				if (!pr || request_resource(pr, r) < 0) {
+					printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, dev->slot_name);
+					/* We'll assign a new address later */
+					r->end -= r->start;
+					r->start = 0;
+				}
+			}
+		}
+		if (!pass) {
+			r = &dev->resource[PCI_ROM_RESOURCE];
+			if (r->flags & PCI_ROM_ADDRESS_ENABLE) {
+				/* Turn the ROM off, leave the resource region, but keep it unregistered. */
+				u32 reg;
+				PCIDBG(3,"PCI: Switching off ROM of %s\n", dev->slot_name);
+				r->flags &= ~PCI_ROM_ADDRESS_ENABLE;
+				pci_read_config_dword(dev, dev->rom_base_reg, &reg);
+				pci_write_config_dword(dev, dev->rom_base_reg, reg & ~PCI_ROM_ADDRESS_ENABLE);
+			}
+		}
+	}
+}
+
+static void __init pcibios_assign_resources(void)
+{
+	struct pci_dev *dev;
+	int idx;
+	struct resource *r;
+
+	PCIDBG(2,"PCI: pcibios_assign_resources called\n");
+	pci_for_each_dev(dev) {
+		int class = dev->class >> 8;
+
+		/* Don't touch classless devices and host bridges */
+		if (!class || class == PCI_CLASS_BRIDGE_HOST)
+			continue;
+
+		for(idx=0; idx<6; idx++) {
+			r = &dev->resource[idx];
+
+			/*
+			 *  Don't touch IDE controllers and I/O ports of video cards!
+			 */
+			if ((class == PCI_CLASS_STORAGE_IDE && idx < 4) ||
+			    (class == PCI_CLASS_DISPLAY_VGA && (r->flags & IORESOURCE_IO)))
+				continue;
+
+			/*
+			 *  We shall assign a new address to this resource, either because
+			 *  the BIOS forgot to do so or because we have decided the old
+			 *  address was unusable for some reason.
+			 */
+			if (!r->start && r->end)
+				pci_assign_resource(dev, idx);
+		}
+
+		if (pci_probe & PCI_ASSIGN_ROMS) {
+			r = &dev->resource[PCI_ROM_RESOURCE];
+			r->end -= r->start;
+			r->start = 0;
+			if (r->end)
+				pci_assign_resource(dev, PCI_ROM_RESOURCE);
+		}
+	}
+}
+
+void __init pcibios_resource_survey(void)
+{
+	PCIDBG(1,"PCI: Allocating resources\n");
+	pcibios_allocate_bus_resources(&pci_root_buses);
+	pcibios_allocate_resources(0);
+	pcibios_allocate_resources(1);
+	pcibios_assign_resources();
+}
+
+int pcibios_enable_device(struct pci_dev *dev)
+{
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for(idx=0; idx<6; idx++) {
+		r = &dev->resource[idx];
+		if (!r->start && r->end) {
+			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (dev->resource[PCI_ROM_RESOURCE].start)
+		cmd |= PCI_COMMAND_MEMORY;
+	if (cmd != old_cmd) {
+		printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", dev->name, old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+}
+
+/*
+ *  If we set up a device for bus mastering, we need to check and set
+ *  the latency timer as it may not be properly set.
+ */
+unsigned int pcibios_max_latency = 255;
+
+void pcibios_set_master(struct pci_dev *dev)
+{
+	u8 lat;
+	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+	if (lat < 16)
+		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+	else if (lat > pcibios_max_latency)
+		lat = pcibios_max_latency;
+	else
+		return;
+	printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", dev->name, lat);
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
+}
+
+/***************************************************************************************/
+/* 
+ * 	IRQ functions 
+ */
+static u8 __init pcibios_swizzle(struct pci_dev *dev, u8 *pin)
+{
+	/* no swizzling */
+	return PCI_SLOT(dev->devfn);
+}
+
+static int pcibios_lookup_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int irq = -1;
+
+	/* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */
+	irq = pcibios_map_platform_irq(slot,pin);
+	if( irq < 0 ) {
+	    PCIDBG(3,"PCI: Error mapping IRQ on device %s\n", dev->name);
+		return irq;
+	}
+	
+	PCIDBG(2,"Setting IRQ for slot %s to %d\n", dev->slot_name, irq);
+
+	return irq;
+}
+
+void __init pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+	PCIDBG(3,"PCI: Update IRQ for %s on irq %d\n", dev->name, irq);
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/pci_st40.c linux/arch/sh/kernel/pci_st40.c
--- v2.4.5/linux/arch/sh/kernel/pci_st40.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/pci_st40.c	Wed Jun 27 13:55:29 2001
@@ -141,6 +141,31 @@
 	return tmp;
 }
 
+static void __init pci_fixup_ide_bases(struct pci_dev *d)
+{
+	int i;
+
+	/*
+	 * PCI IDE controllers use non-standard I/O port decoding, respect it.
+	 */
+	if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
+		return;
+	printk("PCI: IDE base address fixup for %s\n", d->slot_name);
+	for(i=0; i<4; i++) {
+		struct resource *r = &d->resource[i];
+		if ((r->start & ~0x80) == 0x374) {
+			r->start |= 2;
+			r->end = r->start;
+		}
+	}
+}
+
+
+/* Add future fixups here... */
+struct pci_fixup pcibios_fixups[] = {
+	{ PCI_FIXUP_HEADER,	PCI_ANY_ID,	PCI_ANY_ID,	pci_fixup_ide_bases },
+	{ 0 }
+};
 
 int __init st40pci_init(unsigned memStart, unsigned memSize)
 {
@@ -234,6 +259,11 @@
 	return 1;
 }
 
+char * __init pcibios_setup(char *str)
+{
+	return str;
+}
+
 
 #define SET_CONFIG_BITS(bus,devfn,where)\
   (((bus) << 16) | ((devfn) << 8) | ((where) & ~3) | (bus!=0))
@@ -390,10 +420,14 @@
 	ranges->mem_end -= bus->resource[1]->start;
 }
 
-void __init st40_pcibios_init(void)
+void __init pcibios_init(void)
 {
 	extern unsigned long memory_start, memory_end;
 
+	if (sh_mv.mv_init_pci != NULL) {
+		sh_mv.mv_init_pci();
+	}
+
 	/* The pci subsytem needs to know where memory is and how much 
 	 * of it there is. I've simply made these globals. A better mechanism
 	 * is probably needed.
@@ -491,4 +525,24 @@
 {
 	printk("PCI: Assigning IRQ %02d to %s\n", irq, dev->name);
 	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
+
+/*
+ *  If we set up a device for bus mastering, we need to check the latency
+ *  timer as certain crappy BIOSes forget to set it properly.
+ */
+unsigned int pcibios_max_latency = 255;
+
+void pcibios_set_master(struct pci_dev *dev)
+{
+	u8 lat;
+	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+	if (lat < 16)
+		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+	else if (lat > pcibios_max_latency)
+		lat = pcibios_max_latency;
+	else
+		return;
+	printk("PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat);
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
 }
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/rtc.c linux/arch/sh/kernel/rtc.c
--- v2.4.5/linux/arch/sh/kernel/rtc.c	Thu May 24 15:14:08 2001
+++ linux/arch/sh/kernel/rtc.c	Wed Jun 27 13:55:29 2001
@@ -13,62 +13,6 @@
 #include <asm/io.h>
 #include <asm/rtc.h>
 
-/* RCR1 Bits */
-#define RCR1_CF		0x80	/* Carry Flag             */
-#define RCR1_CIE	0x10	/* Carry Interrupt Enable */
-#define RCR1_AIE	0x08	/* Alarm Interrupt Enable */
-#define RCR1_AF		0x01	/* Alarm Flag             */
-
-/* RCR2 Bits */
-#define RCR2_PEF	0x80	/* PEriodic interrupt Flag */
-#define RCR2_PESMASK	0x70	/* Periodic interrupt Set  */
-#define RCR2_RTCEN	0x08	/* ENable RTC              */
-#define RCR2_ADJ	0x04	/* ADJustment (30-second)  */
-#define RCR2_RESET	0x02	/* Reset bit               */
-#define RCR2_START	0x01	/* Start bit               */
-
-#if defined(__sh3__)
-/* SH-3 RTC */
-#define R64CNT  	0xfffffec0
-#define RSECCNT 	0xfffffec2
-#define RMINCNT 	0xfffffec4
-#define RHRCNT  	0xfffffec6
-#define RWKCNT  	0xfffffec8
-#define RDAYCNT 	0xfffffeca
-#define RMONCNT 	0xfffffecc
-#define RYRCNT  	0xfffffece
-#define RSECAR  	0xfffffed0
-#define RMINAR  	0xfffffed2
-#define RHRAR   	0xfffffed4
-#define RWKAR   	0xfffffed6
-#define RDAYAR  	0xfffffed8
-#define RMONAR  	0xfffffeda
-#define RCR1    	0xfffffedc
-#define RCR2    	0xfffffede
-
-#define RTC_BIT_INVERTED	0	/* No bug on SH7708, SH7709A */
-#elif defined(__SH4__)
-/* SH-4 RTC */
-#define R64CNT  	0xffc80000
-#define RSECCNT 	0xffc80004
-#define RMINCNT 	0xffc80008
-#define RHRCNT  	0xffc8000c
-#define RWKCNT  	0xffc80010
-#define RDAYCNT 	0xffc80014
-#define RMONCNT 	0xffc80018
-#define RYRCNT  	0xffc8001c  /* 16bit */
-#define RSECAR  	0xffc80020
-#define RMINAR  	0xffc80024
-#define RHRAR   	0xffc80028
-#define RWKAR   	0xffc8002c
-#define RDAYAR  	0xffc80030
-#define RMONAR  	0xffc80034
-#define RCR1    	0xffc80038
-#define RCR2    	0xffc8003c
-
-#define RTC_BIT_INVERTED	0x40	/* bug on SH7750, SH7750S */
-#endif
-
 #ifndef BCD_TO_BIN
 #define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
 #endif
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/setup.c linux/arch/sh/kernel/setup.c
--- v2.4.5/linux/arch/sh/kernel/setup.c	Fri Apr 27 14:10:32 2001
+++ linux/arch/sh/kernel/setup.c	Wed Jun 27 13:55:29 2001
@@ -521,6 +521,9 @@
 	
 	PRINT_CLOCK("CPU", boot_cpu_data.cpu_clock);
 	PRINT_CLOCK("Bus", boot_cpu_data.bus_clock);
+#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
+	PRINT_CLOCK("Memory", boot_cpu_data.memory_clock);
+#endif
 	PRINT_CLOCK("Peripheral module", boot_cpu_data.module_clock);
 
 	return p - buffer;
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/setup_bigsur.c linux/arch/sh/kernel/setup_bigsur.c
--- v2.4.5/linux/arch/sh/kernel/setup_bigsur.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/setup_bigsur.c	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,381 @@
+/*
+ *
+ * By Dustin McIntire (dustin@sensoria.com) (c)2001
+ * 
+ * Setup and IRQ handling code for the HD64465 companion chip.
+ * by Greg Banks <gbanks@pocketpenguins.com>
+ * Copyright (c) 2000 PocketPenguins Inc
+ *
+ * Derived from setup_hd64465.c which bore the message:
+ * Greg Banks <gbanks@pocketpenguins.com>
+ * Copyright (c) 2000 PocketPenguins Inc and
+ * Copyright (C) 2000 YAEGASHI Takeshi
+ * and setup_cqreek.c which bore message:
+ * Copyright (C) 2000  Niibe Yutaka
+ * 
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * Setup and IRQ functions for a Hitachi Big Sur Evaluation Board.
+ * 
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+
+#include <asm/io_bigsur.h>
+#include <asm/hd64465.h>
+#include <asm/bigsur.h>
+
+//#define BIGSUR_DEBUG 3
+#undef BIGSUR_DEBUG
+
+#ifdef BIGSUR_DEBUG
+#define DPRINTK(args...)	printk(args)
+#define DIPRINTK(n, args...)	if (BIGSUR_DEBUG>(n)) printk(args)
+#else
+#define DPRINTK(args...)
+#define DIPRINTK(n, args...)
+#endif /* BIGSUR_DEBUG */
+
+#ifdef CONFIG_HD64465
+extern int hd64465_irq_demux(int irq);
+#endif /* CONFIG_HD64465 */
+
+
+/*===========================================================*/
+//		Big Sur CPLD IRQ Routines	
+/*===========================================================*/
+
+/* Level 1 IRQ routines */
+static void disable_bigsur_l1irq(unsigned int irq)
+{
+	unsigned long flags;
+	unsigned char mask;
+	unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0;
+	unsigned char bit =  (1 << ((irq - MGATE_IRQ_LOW)%8) );
+
+	if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {	
+   		DPRINTK("Disable L1 IRQ %d\n", irq);
+   		DIPRINTK(2,"disable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n", 
+   			mask_port, bit);
+		save_and_cli(flags);
+
+		/* Disable IRQ - set mask bit */
+		mask = inb(mask_port) | bit;
+		outb(mask, mask_port);
+		restore_flags(flags);
+		return;
+	}
+   	DPRINTK("disable_bigsur_l1irq: Invalid IRQ %d\n", irq);	
+}
+
+static void enable_bigsur_l1irq(unsigned int irq)
+{
+	unsigned long flags;
+	unsigned char mask;
+	unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0;
+	unsigned char bit =  (1 << ((irq - MGATE_IRQ_LOW)%8) );
+
+	if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {	
+	   	DPRINTK("Enable L1 IRQ %d\n", irq);
+   		DIPRINTK(2,"enable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n", 
+   			mask_port, bit);
+		save_and_cli(flags);
+		/* Enable L1 IRQ - clear mask bit */
+		mask = inb(mask_port) & ~bit;
+		outb(mask, mask_port);
+		restore_flags(flags);
+		return;
+	}
+   	DPRINTK("enable_bigsur_l1irq: Invalid IRQ %d\n", irq);	
+}
+
+
+/* Level 2 irq masks and registers for L2 decoding */
+/* Level2 bitmasks for each level 1 IRQ */
+const u32 bigsur_l2irq_mask[] = 
+    {0x40,0x80,0x08,0x01,0x01,0x3C,0x3E,0xFF,0x40,0x80,0x06,0x03};
+/* Level2 to ISR[n] map for each level 1 IRQ */
+const u32 bigsur_l2irq_reg[]  = 
+    {   2,   2,   3,   3,   1,   2,   1,   0,   1,   1,   3,   2};
+/* Level2 to Level 1 IRQ map */
+const u32 bigsur_l2_l1_map[]  = 
+    {7,7,7,7,7,7,7,7, 4,6,6,6,6,6,8,9, 11,11,5,5,5,5,0,1, 3,10,10,2,-1,-1,-1,-1};
+/* IRQ inactive level (high or low) */
+const u32 bigsur_l2_inactv_state[]  =   {0x00, 0xBE, 0xFC, 0xF7};
+ 
+/* CPLD external status and mask registers base and offsets */
+static const u32 isr_base = BIGSUR_IRQ0;
+static const u32 isr_offset = BIGSUR_IRQ0 - BIGSUR_IRQ1;
+static const u32 imr_base = BIGSUR_IMR0;
+static const u32 imr_offset = BIGSUR_IMR0 - BIGSUR_IMR1;
+
+#define REG_NUM(irq)  ((irq-BIGSUR_2NDLVL_IRQ_LOW)/8 )
+
+/* Level 2 IRQ routines */
+static void disable_bigsur_l2irq(unsigned int irq)
+{
+	unsigned long flags;
+	unsigned char mask;
+	unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8);
+	unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset;
+
+    if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
+   		DPRINTK("Disable L2 IRQ %d\n", irq);
+   		DIPRINTK(2,"disable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n", 
+   			mask_port, bit);
+		save_and_cli(flags);
+
+		/* Disable L2 IRQ - set mask bit */
+		mask = inb(mask_port) | bit;
+		outb(mask, mask_port);
+		restore_flags(flags);
+		return;
+	}
+ 	DPRINTK("disable_bigsur_l2irq: Invalid IRQ %d\n", irq);	
+}
+
+static void enable_bigsur_l2irq(unsigned int irq)
+{
+	unsigned long flags;
+	unsigned char mask;
+	unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8);
+	unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset;
+
+    if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
+   		DPRINTK("Enable L2 IRQ %d\n", irq);
+   		DIPRINTK(2,"enable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n", 
+   			mask_port, bit);
+		save_and_cli(flags);
+
+		/* Enable L2 IRQ - clear mask bit */
+		mask = inb(mask_port) & ~bit;
+		outb(mask, mask_port);
+		restore_flags(flags);
+		return;
+	}
+   	DPRINTK("enable_bigsur_l2irq: Invalid IRQ %d\n", irq);
+}
+
+static void mask_and_ack_bigsur(unsigned int irq)
+{
+   	DPRINTK("mask_and_ack_bigsur IRQ %d\n", irq);
+	if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)	
+		disable_bigsur_l1irq(irq);
+	else
+		disable_bigsur_l2irq(irq);
+}
+
+static void end_bigsur_irq(unsigned int irq)
+{
+   	DPRINTK("end_bigsur_irq IRQ %d\n", irq);
+	if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)	
+		enable_bigsur_l1irq(irq);
+	else
+		enable_bigsur_l2irq(irq);
+}
+
+static unsigned int startup_bigsur_irq(unsigned int irq)
+{ 
+	u8 mask;
+	u32 reg;
+
+   	DPRINTK("startup_bigsur_irq IRQ %d\n", irq);
+
+	if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
+		/* Enable the L1 IRQ */	
+		enable_bigsur_l1irq(irq);
+		/* Enable all L2 IRQs in this L1 IRQ */
+		mask = ~(bigsur_l2irq_mask[irq-BIGSUR_IRQ_LOW]);
+		reg = imr_base - bigsur_l2irq_reg[irq-BIGSUR_IRQ_LOW] * imr_offset;
+		mask &= inb(reg);
+		outb(mask,reg); 
+   		DIPRINTK(2,"startup_bigsur_irq: IMR=0x%08x mask=0x%x\n",reg,inb(reg));
+	}
+	else {
+		/* Enable the L2 IRQ - clear mask bit */
+		enable_bigsur_l2irq(irq);
+		/* Enable the L1 bit masking this L2 IRQ */
+		enable_bigsur_l1irq(bigsur_l2_l1_map[irq-BIGSUR_2NDLVL_IRQ_LOW]);
+   		DIPRINTK(2,"startup_bigsur_irq: L1=%d L2=%d\n",
+   			bigsur_l2_l1_map[irq-BIGSUR_2NDLVL_IRQ_LOW],irq);
+	}
+	return 0;
+}
+
+static void shutdown_bigsur_irq(unsigned int irq)
+{
+   	DPRINTK("shutdown_bigsur_irq IRQ %d\n", irq);
+	if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)	
+		disable_bigsur_l1irq(irq);
+	else
+		disable_bigsur_l2irq(irq);
+}
+
+/* Define the IRQ structures for the L1 and L2 IRQ types */
+static struct hw_interrupt_type bigsur_l1irq_type = {
+	"BigSur-CPLD-Level1-IRQ",
+	startup_bigsur_irq,
+	shutdown_bigsur_irq,
+	enable_bigsur_l1irq,
+	disable_bigsur_l1irq,
+	mask_and_ack_bigsur,
+	end_bigsur_irq
+};
+
+static struct hw_interrupt_type bigsur_l2irq_type = {
+	"BigSur-CPLD-Level2-IRQ",
+	startup_bigsur_irq,
+	shutdown_bigsur_irq,
+	enable_bigsur_l2irq,
+	disable_bigsur_l2irq,
+	mask_and_ack_bigsur,
+	end_bigsur_irq
+};
+
+
+static void make_bigsur_l1isr(unsigned int irq) {
+
+	/* sanity check first */
+	if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {	
+		/* save the handler in the main description table */
+		irq_desc[irq].handler = &bigsur_l1irq_type;
+		irq_desc[irq].status = IRQ_DISABLED;
+		irq_desc[irq].action = 0;
+		irq_desc[irq].depth = 1;
+
+		disable_bigsur_l1irq(irq);
+		return;
+	}
+   	DPRINTK("make_bigsur_l1isr: bad irq, %d\n", irq);
+	return;
+} 
+
+static void make_bigsur_l2isr(unsigned int irq) {
+
+	/* sanity check first */
+	if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {	
+		/* save the handler in the main description table */
+		irq_desc[irq].handler = &bigsur_l2irq_type;
+		irq_desc[irq].status = IRQ_DISABLED;
+		irq_desc[irq].action = 0;
+		irq_desc[irq].depth = 1;
+
+		disable_bigsur_l2irq(irq);
+		return;
+	}
+   	DPRINTK("make_bigsur_l2isr: bad irq, %d\n", irq);
+	return;
+} 
+
+/* The IRQ's will be decoded as follows: 
+ * If a level 2 handler exists and there is an unmasked active
+ * IRQ, the 2nd level handler will be called.
+ * If a level 2 handler does not exist for the active IRQ
+ * the 1st level handler will be called.
+ */ 
+
+int bigsur_irq_demux(int irq)
+{
+	int dmux_irq = irq;
+	u8 mask, actv_irqs;
+	u32 reg_num;
+
+   	DIPRINTK(3,"bigsur_irq_demux, irq=%d\n", irq);
+   	/* decode the 1st level IRQ */
+	if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
+		/* Get corresponding L2 ISR bitmask and ISR number */
+		mask = bigsur_l2irq_mask[irq-BIGSUR_IRQ_LOW];
+		reg_num = bigsur_l2irq_reg[irq-BIGSUR_IRQ_LOW];
+		/* find the active IRQ's (XOR with inactive level)*/
+		actv_irqs = inb(isr_base-reg_num*isr_offset) ^ 
+					bigsur_l2_inactv_state[reg_num];
+		/* decode active IRQ's */
+		actv_irqs = actv_irqs & mask & ~(inb(imr_base-reg_num*imr_offset));
+		/* if NEZ then we have an active L2 IRQ */
+		if(actv_irqs) dmux_irq = ffz(~actv_irqs) + reg_num*8+BIGSUR_2NDLVL_IRQ_LOW;	
+   		/* if no 2nd level IRQ action, but has 1st level, use 1st level handler */
+		if(!irq_desc[dmux_irq].action && irq_desc[irq].action) 
+			dmux_irq = irq;
+   		DIPRINTK(1,"bigsur_irq_demux: irq=%d dmux_irq=%d mask=0x%04x reg=%d\n", 
+   			irq, dmux_irq, mask, reg_num);
+	}
+#ifdef CONFIG_HD64465
+	dmux_irq = hd64465_irq_demux(dmux_irq);
+#endif /* CONFIG_HD64465 */
+   	DIPRINTK(3,"bigsur_irq_demux, demux_irq=%d\n", dmux_irq);
+		
+	return dmux_irq;
+}
+
+/*===========================================================*/
+//		Big Sur Init Routines	
+/*===========================================================*/
+void __init init_bigsur_IRQ(void)
+{
+	int i;
+
+	if (!MACH_BIGSUR) return;
+
+	/* Create ISR's for Big Sur CPLD IRQ's */
+	/*==============================================================*/
+	for(i=BIGSUR_IRQ_LOW;i<BIGSUR_IRQ_HIGH;i++) 
+	 	make_bigsur_l1isr(i);
+
+	printk(KERN_INFO "Big Sur CPLD L1 interrupts %d to %d.\n",
+		BIGSUR_IRQ_LOW,BIGSUR_IRQ_HIGH);
+
+	for(i=BIGSUR_2NDLVL_IRQ_LOW;i<BIGSUR_2NDLVL_IRQ_HIGH;i++) 
+ 		make_bigsur_l2isr(i);
+
+	printk(KERN_INFO "Big Sur CPLD L2 interrupts %d to %d.\n",
+		BIGSUR_2NDLVL_IRQ_LOW,BIGSUR_2NDLVL_IRQ_HIGH);
+
+}
+
+int __init setup_bigsur(void)
+{
+	static int done = 0; /* run this only once */
+
+	if (!MACH_BIGSUR || done) return 0;
+	done = 1;
+
+	/* Mask all 2nd level IRQ's */
+	outb(-1,BIGSUR_IMR0);
+	outb(-1,BIGSUR_IMR1);
+	outb(-1,BIGSUR_IMR2);
+	outb(-1,BIGSUR_IMR3);
+
+	/* Mask 1st level interrupts */
+	outb(-1,BIGSUR_IRLMR0);
+	outb(-1,BIGSUR_IRLMR1);
+
+#if defined (CONFIG_HD64465) && defined (CONFIG_SERIAL) 
+	/* remap IO ports for first ISA serial port to HD64465 UART */
+	bigsur_port_map(0x3f8, 8, CONFIG_HD64465_IOBASE + 0x8000, 1);
+#endif /* CONFIG_HD64465 && CONFIG_SERIAL */
+	/* TODO: setup IDE registers */
+	bigsur_port_map(BIGSUR_IDECTL_IOPORT, 2, BIGSUR_ICTL, 8);
+	/* Setup the Ethernet port to BIGSUR_ETHER_IOPORT */
+	bigsur_port_map(BIGSUR_ETHER_IOPORT, 16, BIGSUR_ETHR+BIGSUR_ETHER_IOPORT, 0);
+	/* set page to 1 */
+	outw(1, BIGSUR_ETHR+0xe);
+	/* set the IO port to BIGSUR_ETHER_IOPORT */
+	outw(BIGSUR_ETHER_IOPORT<<3, BIGSUR_ETHR+0x2);
+
+    return 0;
+}
+
+module_init(setup_bigsur);
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/setup_dc.c linux/arch/sh/kernel/setup_dc.c
--- v2.4.5/linux/arch/sh/kernel/setup_dc.c	Sun May 20 12:11:38 2001
+++ linux/arch/sh/kernel/setup_dc.c	Wed Jun 27 13:55:29 2001
@@ -1,5 +1,15 @@
-/*
- *	$Id: setup_dc.c,v 1.1 2001/04/01 15:02:00 yaegashi Exp $
+/* arch/sh/kernel/setup_dc.c
+ *
+ * Hardware support for the Sega Dreamcast.
+ *
+ * Copyright (c) 2001 M. R. Brown <mrbrown@linuxdc.org>
+ *
+ * This file is part of the LinuxDC project (www.linuxdc.org)
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ * 
+ * This file originally bore the message:
+ *	$Id: setup_dc.c,v 1.5 2001/05/24 05:09:16 mrbrown Exp $
  *	SEGA Dreamcast support
  */
 
@@ -9,105 +19,167 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/irq.h>
-#include <linux/pci.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/dc_sysasic.h>
 
-#define	GAPSPCI_REGS		0x01001400
-#define GAPSPCI_DMA_BASE	0x01840000
-#define GAPSPCI_DMA_SIZE	32768
-#define GAPSPCI_BBA_CONFIG	0x01001600
+int __init gapspci_init(void);
 
-#define	GAPSPCI_IRQ		11
-#define	GAPSPCI_INTC		0x005f6924
+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
 
-static int gapspci_dma_used;
+/* Dreamcast System ASIC Hardware Events -
+ 
+   The Dreamcast's System ASIC (located on the PowerVR2 chip) is responsible
+   for receiving hardware events from system peripherals and triggering an
+   SH7750 IRQ.  Hardware events can trigger IRQs 13, 11, or 9 depending on
+   which bits are set in the Event Mask Registers (EMRs).  When a hardware
+   event is triggered, it's corresponding bit in the Event Status Registers
+   (ESRs) is set, and that bit should be rewritten to the ESR to acknowledge
+   that event.
 
-static struct pci_bus *pci_root_bus;
+   There are three 32-bit ESRs located at 0xa05f8900 - 0xa05f6908.  Event
+   types can be found in include/asm-sh/dc_sysasic.h.  There are three groups
+   of EMRs that parallel the ESRs.  Each EMR group corresponds to an IRQ, so
+   0xa05f6910 - 0xa05f6918 triggers IRQ 13, 0xa05f6920 - 0xa05f6928 triggers
+   IRQ 11, and 0xa05f6930 - 0xa05f6938 triggers IRQ 9.
 
-static void disable_gapspci_irq(unsigned int irq)
-{
-	unsigned long flags;
-	unsigned long intc;
+   In the kernel, these events are mapped to virtual IRQs so that drivers can
+   respond to them as they would a normal interrupt.  In order to keep this
+   mapping simple, the events are mapped as:
 
-	save_and_cli(flags);
-	intc = inl(GAPSPCI_INTC);
-	intc &= ~(1<<3);
-	outl(intc, GAPSPCI_INTC);
-	restore_flags(flags);
-}
+   6900/6910 - Events  0-31, IRQ 13
+   6904/6924 - Events 32-63, IRQ 11
+   6908/6938 - Events 64-95, IRQ  9
 
+*/
 
-static void enable_gapspci_irq(unsigned int irq)
-{
-	unsigned long flags;
-	unsigned long intc;
+#define ESR_BASE 0x005f6900    /* Base event status register */
+#define EMR_BASE 0x005f6910    /* Base event mask register */
 
-	save_and_cli(flags);
-	intc = inl(GAPSPCI_INTC);
-	intc |= (1<<3);
-	outl(intc, GAPSPCI_INTC);
-	restore_flags(flags);
-}
+/* Helps us determine the EMR group that this event belongs to: 0 = 0x6910,
+   1 = 0x6920, 2 = 0x6930; also determine the event offset */
+#define LEVEL(event) (((event) - HW_EVENT_IRQ_BASE) / 32)
+
+/* Return the hardware event's bit positon within the EMR/ESR */
+#define EVENT_BIT(event) (((event) - HW_EVENT_IRQ_BASE) & 31)
 
+/* For each of these *_irq routines, the IRQ passed in is the virtual IRQ
+   (logically mapped to the corresponding bit for the hardware event). */
 
-static void mask_and_ack_gapspci_irq(unsigned int irq)
+/* Disable the hardware event by masking its bit in its EMR */
+static inline void disable_systemasic_irq(unsigned int irq)
 {
-	unsigned long flags;
-	unsigned long intc;
+	__u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
+	__u32 mask;
+	mask = inl(emr);
+	mask &= ~(1 << EVENT_BIT(irq));
+	outl(mask, emr);
+}
 
-	save_and_cli(flags);
-	intc = inl(GAPSPCI_INTC);
-	intc &= ~(1<<3);
-	outl(intc, GAPSPCI_INTC);
-	restore_flags(flags);
+/* Enable the hardware event by setting its bit in its EMR */
+static inline void enable_systemasic_irq(unsigned int irq)
+{
+	__u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
+	__u32 mask;
+	mask = inl(emr);
+	mask |= (1 << EVENT_BIT(irq));
+	outl(mask, emr);
 }
 
+/* Acknowledge a hardware event by writing its bit back to its ESR */
+static void ack_systemasic_irq(unsigned int irq)
+{
+	__u32 esr = ESR_BASE + (LEVEL(irq) << 2);
+	disable_systemasic_irq(irq);
+	outl((1 << EVENT_BIT(irq)), esr);
+}
 
-static void end_gapspci_irq(unsigned int irq)
+/* After a IRQ has been ack'd and responded to, it needs to be renabled */
+static void end_systemasic_irq(unsigned int irq)
 {
-	enable_gapspci_irq(irq);
+	enable_systemasic_irq(irq);
 }
 
+static unsigned int startup_systemasic_irq(unsigned int irq)
+{
+	enable_systemasic_irq(irq);
 
-static unsigned int startup_gapspci_irq(unsigned int irq)
-{ 
-	enable_gapspci_irq(irq);
 	return 0;
 }
 
-
-static void shutdown_gapspci_irq(unsigned int irq)
+static void shutdown_systemasic_irq(unsigned int irq)
 {
-	disable_gapspci_irq(irq);
+	disable_systemasic_irq(irq);
 }
 
-
-static struct hw_interrupt_type gapspci_irq_type = {
-	"GAPSPCI-IRQ",
-	startup_gapspci_irq,
-	shutdown_gapspci_irq,
-	enable_gapspci_irq,
-	disable_gapspci_irq,
-	mask_and_ack_gapspci_irq,
-	end_gapspci_irq
+static struct hw_interrupt_type systemasic_int = {
+	typename:       "System ASIC",
+	startup:        startup_systemasic_irq,
+	shutdown:       shutdown_systemasic_irq,
+	enable:         enable_systemasic_irq,
+	disable:        disable_systemasic_irq,
+	ack:            ack_systemasic_irq,
+	end:            end_systemasic_irq,
 };
 
-
-static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
+/*
+ * Map the hardware event indicated by the processor IRQ to a virtual IRQ.
+ */
+int systemasic_irq_demux(int irq)
 {
-	return PCI_SLOT(dev->devfn);
-}
+	__u32 emr, esr, status, level;
+	__u32 j, bit;
 
-static int __init map_od_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
-	return GAPSPCI_IRQ;
+	switch (irq) {
+		case 13:
+			level = 0;
+			break;
+		case 11:
+			level = 1;
+			break;
+		case  9:
+			level = 2;
+			break;
+		default:
+			return irq;
+	}
+	emr = EMR_BASE + (level << 4) + (level << 2);
+	esr = ESR_BASE + (level << 2);
+
+	/* Mask the ESR to filter any spurious, unwanted interrtupts */
+	status = inl(esr);
+	status &= inl(emr);
+
+	/* Now scan and find the first set bit as the event to map */
+	for (bit = 1, j = 0; j < 32; bit <<= 1, j++) {
+		if (status & bit) {
+			irq = HW_EVENT_IRQ_BASE + j + (level << 5);
+			return irq;
+		}
+	}
+
+	/* Not reached */
+	return irq;
 }
 
 int __init setup_dreamcast(void)
 {
+	int i;
+
+	/* Mask all hardware events */
+	/* XXX */
+
+	/* Acknowledge any previous events */
+	/* XXX */
+
+	/* Assign all virtual IRQs to the System ASIC int. handler */
+	for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++)
+		irq_desc[i].handler = &systemasic_int;
+
+#ifdef CONFIG_PCI
 	gapspci_init();
+#endif
 
 	printk(KERN_INFO "SEGA Dreamcast support.\n");
 #if 0
@@ -128,232 +200,5 @@
  *	PCR: 0x0000
  */
 #endif
-	return 0;
-}
-
-
-/*
- *	Dreamcast PCI: Supports SEGA Broadband Adaptor only.
- */
-
-#define BBA_SELECTED(dev) (dev->bus->number==0 && dev->devfn==0)
-
-static int gapspci_read_config_byte(struct pci_dev *dev, int where,
-                                    u8 * val)
-{
-	if (BBA_SELECTED(dev))
-		*val = inb(GAPSPCI_BBA_CONFIG+where);
-	else
-                *val = 0xff;
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int gapspci_read_config_word(struct pci_dev *dev, int where,
-                                    u16 * val)
-{
-        if (BBA_SELECTED(dev))
-		*val = inw(GAPSPCI_BBA_CONFIG+where);
-	else
-                *val = 0xffff;
-
-        return PCIBIOS_SUCCESSFUL;
-}
-
-static int gapspci_read_config_dword(struct pci_dev *dev, int where,
-                                     u32 * val)
-{
-        if (BBA_SELECTED(dev))
-		*val = inl(GAPSPCI_BBA_CONFIG+where);
-	else
-                *val = 0xffffffff;
-
-        return PCIBIOS_SUCCESSFUL;
-}
-
-static int gapspci_write_config_byte(struct pci_dev *dev, int where,
-                                     u8 val)
-{
-        if (BBA_SELECTED(dev))
-		outb(val, GAPSPCI_BBA_CONFIG+where);
-
-        return PCIBIOS_SUCCESSFUL;
-}
-
-
-static int gapspci_write_config_word(struct pci_dev *dev, int where,
-                                     u16 val)
-{
-        if (BBA_SELECTED(dev))
-		outw(val, GAPSPCI_BBA_CONFIG+where);
-
-        return PCIBIOS_SUCCESSFUL;
-}
-
-static int gapspci_write_config_dword(struct pci_dev *dev, int where,
-                                      u32 val)
-{
-        if (BBA_SELECTED(dev))
-		outl(val, GAPSPCI_BBA_CONFIG+where);
-
-        return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops pci_config_ops = {
-        gapspci_read_config_byte,
-        gapspci_read_config_word,
-        gapspci_read_config_dword,
-        gapspci_write_config_byte,
-        gapspci_write_config_word,
-        gapspci_write_config_dword
-};
-
-
-void pcibios_align_resource(void *data, struct resource *res,
-			    unsigned long size)
-{
-}
-
-
-void __init pcibios_update_irq(struct pci_dev *dev, int irq)
-{
-}
-
-
-void __init pcibios_update_resource(struct pci_dev *dev, struct resource *root,
-			     struct resource *res, int resource)
-{
-}
-
-
-int pcibios_enable_device(struct pci_dev *dev)
-{
-
-	u16 cmd, old_cmd;
-	int idx;
-	struct resource *r;
-
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
-	old_cmd = cmd;
-	for (idx = 0; idx < 6; idx++) {
-		r = dev->resource + idx;
-		if (!r->start && r->end) {
-			printk(KERN_ERR
-			       "PCI: Device %s not available because"
-			       " of resource collisions\n",
-			       dev->slot_name);
-			return -EINVAL;
-		}
-		if (r->flags & IORESOURCE_IO)
-			cmd |= PCI_COMMAND_IO;
-		if (r->flags & IORESOURCE_MEM)
-			cmd |= PCI_COMMAND_MEMORY;
-	}
-	if (cmd != old_cmd) {
-		printk("PCI: enabling device %s (%04x -> %04x)\n",
-		       dev->slot_name, old_cmd, cmd);
-		pci_write_config_word(dev, PCI_COMMAND, cmd);
-	}
-	return 0;
-
-}
-
-
-void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
-			   dma_addr_t * dma_handle)
-{
-	unsigned long buf;
-
-	if (gapspci_dma_used+size > GAPSPCI_DMA_SIZE)
-		return NULL;
-
-	buf = GAPSPCI_DMA_BASE+gapspci_dma_used;
-
-	gapspci_dma_used = PAGE_ALIGN(gapspci_dma_used+size);
-	
-	printk("pci_alloc_consistent: %d bytes at 0x%08x\n", size, buf);
-
-	*dma_handle = (dma_addr_t)buf;
-
-	return (void *)P2SEGADDR(buf);
-}
-
-
-void pci_free_consistent(struct pci_dev *hwdev, size_t size,
-			 void *vaddr, dma_addr_t dma_handle)
-{
-}
-
-
-void __init
-pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
-{
-}                                                                                
-
-void __init pcibios_fixup_bus(struct pci_bus *bus)
-{
-	struct list_head *ln;
-	struct pci_dev *dev;
-
-	for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
-		dev = pci_dev_b(ln);
-		if (!BBA_SELECTED(dev)) continue;
-
-		printk("PCI: MMIO fixup to %s\n", dev->name);
-		dev->resource[1].start=0x01001700;
-		dev->resource[1].end=0x010017ff;
-	}
-}
-
-
-void __init dreamcast_pcibios_init(void)
-{
-	pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
-	/* pci_assign_unassigned_resources(); */
-	pci_fixup_irqs(no_swizzle, map_od_irq);
-}
-
-
-static __init int gapspci_init(void)
-{
-	int i;
-	char idbuf[16];
-
-	for(i=0; i<16; i++)
-		idbuf[i]=inb(GAPSPCI_REGS+i);
-
-	if(strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16))
-		return -1;
-
-	outl(0x5a14a501, GAPSPCI_REGS+0x18);
-
-	for(i=0; i<1000000; i++);
-
-	if(inl(GAPSPCI_REGS+0x18)!=1)
-		return -1;
-
-	outl(0x01000000, GAPSPCI_REGS+0x20);
-	outl(0x01000000, GAPSPCI_REGS+0x24);
-
-	outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28);
-	outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c);
-
-	outl(1, GAPSPCI_REGS+0x14);
-	outl(1, GAPSPCI_REGS+0x34);
-
-	gapspci_dma_used=0;
-
-	/*  */
-	irq_desc[GAPSPCI_IRQ].handler = &gapspci_irq_type;
-
-	/* Setting Broadband Adapter */
-	outw(0xf900, GAPSPCI_BBA_CONFIG+0x06);
-	outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30);
-	outb(0x00, GAPSPCI_BBA_CONFIG+0x3c);
-	outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d);
-	outw(0x0006, GAPSPCI_BBA_CONFIG+0x04);
-	outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10);
-	outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14);
-
 	return 0;
 }
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/setup_od.c linux/arch/sh/kernel/setup_od.c
--- v2.4.5/linux/arch/sh/kernel/setup_od.c	Mon Jun 19 17:59:37 2000
+++ linux/arch/sh/kernel/setup_od.c	Wed Dec 31 16:00:00 1969
@@ -1,35 +0,0 @@
-/* $Id: setup_od.c,v 1.1 2000/06/14 09:35:59 stuart_menefy Exp $
- *
- * arch/sh/kernel/setup_od.c
- *
- * Copyright (C) 2000  Stuart Menefy
- *
- * STMicroelectronics Overdrive Support.
- *
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-/*
- * Initialize the board
- */
-int __init setup_od(void)
-{
-	/* Enable RS232 receive buffers */
-	volatile int* p = (volatile int*)0xa3000000;
-
-#if defined(CONFIG_SH_ORION)
-	*p=1;
-#elif defined(CONFIG_SH_OVERDRIVE)
-	*p=0x1e;
-#else
-#error Illegal configuration
-#endif
-
-	printk(KERN_INFO "STMicroelectronics Overdrive Setup...done\n");
-	return 0;
-}
-
-module_init(setup_od);
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/setup_sh2000.c linux/arch/sh/kernel/setup_sh2000.c
--- v2.4.5/linux/arch/sh/kernel/setup_sh2000.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/setup_sh2000.c	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,95 @@
+/*
+ * linux/arch/sh/kernel/setup_sh2000.c
+ *
+ * Copyright (C) 2001  SUGIOKA Tochinobu
+ *
+ * SH-2000 Support.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/io_generic.h>
+#include <asm/machvec.h>
+#include <asm/machvec_init.h>
+#include <asm/rtc.h>
+
+#define CF_CIS_BASE	0xb4200000
+
+#define PORT_PECR	0xa4000108
+#define PORT_PHCR	0xa400010E
+#define	PORT_ICR1	0xa4000010
+#define	PORT_IRR0	0xa4000004
+
+/*
+ * Initialize the board
+ */
+int __init setup_sh2000(void)
+{
+	/* XXX: RTC setting comes here */
+
+	/* These should be done by BIOS/IPL ... */
+	/* Enable nCE2A, nCE2B output */
+	ctrl_outw(ctrl_inw(PORT_PECR) & ~0xf00, PORT_PECR);
+	/* Enable the Compact Flash card, and set the level interrupt */
+	ctrl_outw(0x0042, CF_CIS_BASE+0x0200);
+	/* Enable interrupt */
+	ctrl_outw(ctrl_inw(PORT_PHCR) & ~0x03f3, PORT_PHCR);
+	ctrl_outw(1, PORT_ICR1);
+	ctrl_outw(ctrl_inw(PORT_IRR0) & ~0xff3f, PORT_IRR0);
+	printk(KERN_INFO "SH-2000 Setup...done\n");
+	return 0;
+}
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_sh2000 __initmv = {
+	mv_name:		"sh2000",
+
+	mv_nr_irqs:		80,
+
+	mv_inb:			generic_inb,
+	mv_inw:			generic_inw,
+	mv_inl:			generic_inl,
+	mv_outb:		generic_outb,
+	mv_outw:		generic_outw,
+	mv_outl:		generic_outl,
+
+	mv_inb_p:		generic_inb_p,
+	mv_inw_p:		generic_inw_p,
+	mv_inl_p:		generic_inl_p,
+	mv_outb_p:		generic_outb_p,
+	mv_outw_p:		generic_outw_p,
+	mv_outl_p:		generic_outl_p,
+
+	mv_insb:		generic_insb,
+	mv_insw:		generic_insw,
+	mv_insl:		generic_insl,
+	mv_outsb:		generic_outsb,
+	mv_outsw:		generic_outsw,
+	mv_outsl:		generic_outsl,
+
+	mv_readb:		generic_readb,
+	mv_readw:		generic_readw,
+	mv_readl:		generic_readl,
+	mv_writeb:		generic_writeb,
+	mv_writew:		generic_writew,
+	mv_writel:		generic_writel,
+
+	mv_init_arch:		setup_sh2000,
+
+	mv_isa_port2addr:	sh2000_isa_port2addr,
+
+	mv_ioremap:		generic_ioremap,
+	mv_iounmap:		generic_iounmap,
+
+	mv_rtc_gettimeofday:	sh_rtc_gettimeofday,
+	mv_rtc_settimeofday:	sh_rtc_settimeofday,
+
+	mv_hw_sh2000:		1,
+};
+ALIAS_MV(sh2000)
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/sh_ksyms.c linux/arch/sh/kernel/sh_ksyms.c
--- v2.4.5/linux/arch/sh/kernel/sh_ksyms.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/sh_ksyms.c	Wed Jun 27 13:55:29 2001
@@ -18,6 +18,7 @@
 #include <asm/hardirq.h>
 #include <asm/delay.h>
 #include <asm/pgalloc.h>
+#include <asm/pci.h>
 #include <linux/irq.h>
 
 extern void dump_thread(struct pt_regs *, struct user *);
@@ -44,14 +45,25 @@
 EXPORT_SYMBOL(strpbrk);
 EXPORT_SYMBOL(strstr);
 EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(strnlen);
 EXPORT_SYMBOL(strchr);
 EXPORT_SYMBOL(strcat);
 EXPORT_SYMBOL(strncat);
 
+/* PCI exports */
+#ifdef CONFIG_PCI
+EXPORT_SYMBOL(pci_alloc_consistent);
+EXPORT_SYMBOL(pci_free_consistent);
+EXPORT_SYMBOL(pcibios_penalize_isa_irq);
+#endif
+
 /* mem exports */
 EXPORT_SYMBOL(memchr);
 EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memcpy_fromio);
+EXPORT_SYMBOL(memcpy_toio);
 EXPORT_SYMBOL(memset);
+EXPORT_SYMBOL(memset_io);
 EXPORT_SYMBOL(memmove);
 EXPORT_SYMBOL(memcmp);
 
@@ -63,20 +75,32 @@
 
 EXPORT_SYMBOL(get_vm_area);
 
+/* semaphore exports */
+EXPORT_SYMBOL(__up);
+EXPORT_SYMBOL(__down);
+EXPORT_SYMBOL(__down_interruptible);
+
+EXPORT_SYMBOL(__udelay);
+EXPORT_SYMBOL(__const_udelay);
+
 #define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL_NOVERS(name)
  
 /* These symbols are generated by the compiler itself */
 DECLARE_EXPORT(__udivsi3);
 DECLARE_EXPORT(__sdivsi3);
+DECLARE_EXPORT(__ashrdi3);
+DECLARE_EXPORT(__ashldi3);
+DECLARE_EXPORT(__lshrdi3);
+DECLARE_EXPORT(__movstr);
 
 #ifdef __SH4__
  
 DECLARE_EXPORT(__movstr_i4_even);
 DECLARE_EXPORT(__movstr_i4_odd);
-DECLARE_EXPORT(__ashrdi3);
-DECLARE_EXPORT(__ashldi3);
 
 /* needed by some modules */
+EXPORT_SYMBOL(flush_cache_all);
+EXPORT_SYMBOL(flush_cache_range);
 EXPORT_SYMBOL(flush_dcache_page);
 #endif
 EXPORT_SYMBOL(flush_tlb_page);
diff -u --recursive --new-file v2.4.5/linux/arch/sh/kernel/time.c linux/arch/sh/kernel/time.c
--- v2.4.5/linux/arch/sh/kernel/time.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/time.c	Wed Jun 27 13:55:29 2001
@@ -64,7 +64,11 @@
 #define CCN_PVR_CHIP_MASK  0xff
 #define CCN_PVR_CHIP_ST40STB1 0x4
 
-#endif
+#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
+#define CLOCKGEN_MEMCLKCR 0xbb040038
+#define MEMCLKCR_RATIO_MASK 0x7
+#endif /* CONFIG_CPU_SUBTYPE_ST40STB1 */
+#endif /* __sh3__ or __SH4__ */
 
 extern rwlock_t xtime_lock;
 extern unsigned long wall_jiffies;
@@ -285,6 +289,9 @@
 void __init time_init(void)
 {
 	unsigned int cpu_clock, master_clock, bus_clock, module_clock;
+#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
+	unsigned int memory_clock;
+#endif
 	unsigned int timer_freq;
 	unsigned short frqcr, ifc, pfc, bfc;
 	unsigned long interval;
@@ -335,23 +342,35 @@
 		{ 0x123, {{1,4}, {1,4}, {1,8}}},
 		{ 0x16C, {{1,4}, {1,8}, {1,8}}},
 	};
+
+	struct memclk_data {
+		unsigned char multiplier;
+		unsigned char divisor;
+	};
+	static struct memclk_data st40_memclk_table[8] = {
+		{1,1},	// 000
+		{1,2},	// 001
+		{1,3},	// 010
+		{2,3},	// 011
+		{1,4},	// 100
+		{1,6},	// 101
+		{1,8},	// 110
+		{1,8}	// 111
+	};
 #endif
 #endif
 
-#if defined(CONFIG_SH_DREAMCAST)
-	xtime.tv_sec = 0;
-	xtime.tv_usec = 0;
-#else
-	rtc_gettimeofday(&xtime);
-#endif
+	if (MACH_DREAMCAST)
+		xtime.tv_sec = xtime.tv_usec = 0;
+	else
+		rtc_gettimeofday(&xtime);
 
 	setup_irq(TIMER_IRQ, &irq0);
 
-#if defined(CONFIG_SH_DREAMCAST)
-	timer_freq = 50*1000*1000/4;
-#else
-	timer_freq = get_timer_frequency();
-#endif
+	if (MACH_DREAMCAST)
+		timer_freq = 50*1000*1000/4;
+	else
+		timer_freq = get_timer_frequency();
 
 	module_clock = timer_freq * 4;
 
@@ -386,6 +405,8 @@
 			/* Unfortunatly the STB1 FRQCR values are different from the 7750 ones */
 			struct frqcr_data *d;
 			int a;
+			unsigned long memclkcr;
+			struct memclk_data *e;
 
 			for (a=0; a<ARRAY_SIZE(st40_frqcr_table); a++) {
 				d = &st40_frqcr_table[a];
@@ -397,13 +418,18 @@
 				printk("ERROR: Unrecognised FRQCR value, using default multipliers\n");
 			}
 
-			printk("Clock multipliers: CPU: %d/%d Bus: %d/%d Periph: %d/%d\n",
+			memclkcr = ctrl_inl(CLOCKGEN_MEMCLKCR);
+			e = &st40_memclk_table[memclkcr & MEMCLKCR_RATIO_MASK];
+
+			printk("Clock multipliers: CPU: %d/%d Bus: %d/%d Mem: %d/%d Periph: %d/%d\n",
 			       d->factor[0].multiplier, d->factor[0].divisor,
 			       d->factor[1].multiplier, d->factor[1].divisor,
+			       e->multiplier,           e->divisor,
 			       d->factor[2].multiplier, d->factor[2].divisor);
 			
 			master_clock = module_clock * d->factor[2].divisor    / d->factor[2].multiplier;
 			bus_clock    = master_clock * d->factor[1].multiplier / d->factor[1].divisor;
+			memory_clock = master_clock * e->multiplier           / e->divisor;
 			cpu_clock    = master_clock * d->factor[0].multiplier / d->factor[0].divisor;
 			goto skip_calc;
 		} else
@@ -418,11 +444,17 @@
 	master_clock = module_clock * pfc;
 	bus_clock = master_clock / bfc;
 	cpu_clock = master_clock / ifc;
+#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
  skip_calc:
+#endif
 	printk("CPU clock: %d.%02dMHz\n",
 	       (cpu_clock / 1000000), (cpu_clock % 1000000)/10000);
 	printk("Bus clock: %d.%02dMHz\n",
 	       (bus_clock/1000000), (bus_clock % 1000000)/10000);
+#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
+	printk("Memory clock: %d.%02dMHz\n",
+	       (memory_clock/1000000), (memory_clock % 1000000)/10000);
+#endif
 	printk("Module clock: %d.%02dMHz\n",
 	       (module_clock/1000000), (module_clock % 1000000)/10000);
 	interval = (module_clock/4 + HZ/2) / HZ;
@@ -432,6 +464,9 @@
 	current_cpu_data.cpu_clock    = cpu_clock;
 	current_cpu_data.master_clock = master_clock;
 	current_cpu_data.bus_clock    = bus_clock;
+#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
+	current_cpu_data.memory_clock = memory_clock;
+#endif
 	current_cpu_data.module_clock = module_clock;
 
 	/* Start TMU0 */
diff -u --recursive --new-file v2.4.5/linux/arch/sh/mm/cache.c linux/arch/sh/mm/cache.c
--- v2.4.5/linux/arch/sh/mm/cache.c	Sun May 20 12:11:38 2001
+++ linux/arch/sh/mm/cache.c	Wed Jun 27 13:55:29 2001
@@ -151,7 +151,8 @@
 #elif defined(__SH4__)
 #ifdef CONFIG_CPU_SUBTYPE_ST40STB1
 	cpu_data->type = CPU_ST40STB1;
-#elif defined(CONFIG_CPU_SUBTYPE_SH7750)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \
+      defined(CONFIG_CPU_SUBTYPE_SH7751)
 	cpu_data->type = CPU_SH7750;
 #else
 #error Unknown SH4 CPU type
diff -u --recursive --new-file v2.4.5/linux/arch/sh/mm/fault.c linux/arch/sh/mm/fault.c
--- v2.4.5/linux/arch/sh/mm/fault.c	Mon Mar 19 12:35:10 2001
+++ linux/arch/sh/mm/fault.c	Wed Jun 27 13:55:29 2001
@@ -281,11 +281,12 @@
 {
 	unsigned long flags;
 	unsigned long pteval;
-	unsigned long pteaddr;
+	unsigned long vpn;
+#if defined(__SH4__)
 	unsigned long ptea;
+#endif
 
 	save_and_cli(flags);
-
 #if defined(__SH4__)
 	if (pte_shared(pte)) {
 		struct page *pg;
@@ -305,13 +306,13 @@
 	}
 
 	/* Set PTEH register */
-	pteaddr = (address & MMU_VPN_MASK) | get_asid();
-	ctrl_outl(pteaddr, MMU_PTEH);
+	vpn = (address & MMU_VPN_MASK) | get_asid();
+	ctrl_outl(vpn, MMU_PTEH);
 
-	/* Set PTEA register */
-	/* TODO: make this look less hacky */
 	pteval = pte_val(pte);
 #if defined(__SH4__)
+	/* Set PTEA register */
+	/* TODO: make this look less hacky */
 	ptea = ((pteval >> 28) & 0xe) | (pteval & 0x1);
 	ctrl_outl(ptea, MMU_PTEA);
 #endif
@@ -341,9 +342,9 @@
 	data = (page & 0xfffe0000) | asid; /* VALID bit is off */
 	ctrl_outl(data, addr);
 #elif defined(__SH4__)
-	jump_to_P2();
 	addr = MMU_UTLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT;
 	data = page | asid; /* VALID bit is off */
+	jump_to_P2();
 	ctrl_outl(data, addr);
 	back_to_P1();
 #endif
@@ -352,27 +353,34 @@
 #if defined(__SH4__)
 static void __flush_tlb_phys(unsigned long phys)
 {
-	int i;
-	unsigned long addr, data;
+	unsigned long addr, data, pte;
 
-	jump_to_P2();
-	for (i = 0; i < MMU_UTLB_ENTRIES; i++) {
-		addr = MMU_UTLB_DATA_ARRAY | (i<<MMU_U_ENTRY_SHIFT);
+	pte = phys | MMU_UTLB_VALID;
+	for (addr = MMU_UTLB_DATA_ARRAY;
+	     addr < MMU_UTLB_DATA_ARRAY+(MMU_UTLB_ENTRIES<<MMU_U_ENTRY_SHIFT);
+	     addr += (1<<MMU_U_ENTRY_SHIFT)) {
 		data = ctrl_inl(addr);
-		if ((data & MMU_UTLB_VALID) && (data&PAGE_MASK) == phys) {
+		if ((data & (MMU_UTLB_VALID|PAGE_MASK)) == pte) {
 			data &= ~MMU_UTLB_VALID;
+			jump_to_P2();
 			ctrl_outl(data, addr);
+			back_to_P1();
+			break;
 		}
 	}
-	for (i = 0; i < MMU_ITLB_ENTRIES; i++) {
-		addr = MMU_ITLB_DATA_ARRAY | (i<<MMU_I_ENTRY_SHIFT);
+	pte = phys | MMU_ITLB_VALID;
+	for (addr = MMU_ITLB_DATA_ARRAY;
+	     addr < MMU_ITLB_DATA_ARRAY+(MMU_ITLB_ENTRIES<<MMU_I_ENTRY_SHIFT);
+	     addr += (1<<MMU_I_ENTRY_SHIFT)) {
 		data = ctrl_inl(addr);
-		if ((data & MMU_ITLB_VALID) && (data&PAGE_MASK) == phys) {
+		if ((data & (MMU_ITLB_VALID|PAGE_MASK)) == pte) {
 			data &= ~MMU_ITLB_VALID;
+			jump_to_P2();
 			ctrl_outl(data, addr);
+			back_to_P1();
+			break;
 		}
 	}
-	back_to_P1();
 }
 #endif
 
diff -u --recursive --new-file v2.4.5/linux/arch/sh/mm/init.c linux/arch/sh/mm/init.c
--- v2.4.5/linux/arch/sh/mm/init.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/mm/init.c	Wed Jun 27 13:55:29 2001
@@ -100,7 +100,7 @@
 extern char _text, _etext, _edata, __bss_start, _end;
 extern char __init_begin, __init_end;
 
-pgd_t swapper_pg_dir[1024];
+pgd_t swapper_pg_dir[PTRS_PER_PGD];
 
 /* It'd be good if these lines were in the standard header file. */
 #define START_PFN	(NODE_DATA(0)->bdata->node_boot_start >> PAGE_SHIFT)
@@ -120,7 +120,7 @@
 	/* We don't need kernel mapping as hardware support that. */
 	pg_dir = swapper_pg_dir;
 
-	for (i=0; i < USER_PTRS_PER_PGD*2; i++)
+	for (i=0; i < PTRS_PER_PGD; i++)
 		pgd_val(pg_dir[i]) = 0;
 
 	/* Enable MMU */
diff -u --recursive --new-file v2.4.5/linux/arch/sh/stboards/Makefile linux/arch/sh/stboards/Makefile
--- v2.4.5/linux/arch/sh/stboards/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/stboards/Makefile	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,15 @@
+#
+# Makefile for STMicroelectronics board specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+all: stboards.o
+O_TARGET := stboards.o
+obj-y := irq.o setup.o mach.o led.o
+
+clean:
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/arch/sh/stboards/harp.h linux/arch/sh/stboards/harp.h
--- v2.4.5/linux/arch/sh/stboards/harp.h	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/stboards/harp.h	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,43 @@
+/* 
+ * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.                            
+ *
+ * Defintions applicable to the STMicroelectronics ST40STB1 HARP and
+ * compatible boards.
+ */
+
+#if defined(CONFIG_SH_STB1_HARP)
+
+#define EPLD_BASE     0xa0800000
+
+#define EPLD_LED      (EPLD_BASE+0x000c0000)
+#define EPLD_INTSTAT0 (EPLD_BASE+0x00200000)
+#define EPLD_INTSTAT1 (EPLD_BASE+0x00240000)
+#define EPLD_INTMASK0 (EPLD_BASE+0x00280000)
+#define EPLD_INTMASK1 (EPLD_BASE+0x002c0000)
+#define EPLD_PAGEADDR (EPLD_BASE+0x00300000)
+#define EPLD_REVID1   (EPLD_BASE+0x00380000)
+#define EPLD_REVID2   (EPLD_BASE+0x003c0000)
+
+#define EPLD_LED_ON  1
+#define EPLD_LED_OFF 0
+
+#elif defined(CONFIG_SH_STB1_OVERDRIVE)
+
+#define EPLD_BASE     0xa7000000
+
+#define EPLD_REVID    (EPLD_BASE+0x00000000)
+#define EPLD_LED      (EPLD_BASE+0x00040000)
+#define EPLD_INTMASK0 (EPLD_BASE+0x001c0000)
+#define EPLD_INTMASK1 (EPLD_BASE+0x00200000)
+#define EPLD_INTSTAT0 (EPLD_BASE+0x00240000)
+#define EPLD_INTSTAT1 (EPLD_BASE+0x00280000)
+
+#define EPLD_LED_ON  0
+#define EPLD_LED_OFF 1
+
+#else
+#error Unknown board
+#endif
diff -u --recursive --new-file v2.4.5/linux/arch/sh/stboards/irq.c linux/arch/sh/stboards/irq.c
--- v2.4.5/linux/arch/sh/stboards/irq.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/stboards/irq.c	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,149 @@
+/* 
+ * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.                            
+ *
+ * Looks after interrupts on the HARP board.
+ *
+ * Bases on the IPR irq system
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+
+#include "harp.h"
+
+
+#define NUM_EXTERNAL_IRQS 16
+
+// Early versions of the STB1 Overdrive required this nasty frig
+//#define INVERT_INTMASK_WRITES
+
+static void enable_harp_irq(unsigned int irq);
+static void disable_harp_irq(unsigned int irq);
+
+/* shutdown is same as "disable" */
+#define shutdown_harp_irq disable_harp_irq
+
+static void mask_and_ack_harp(unsigned int);
+static void end_harp_irq(unsigned int irq);
+
+static unsigned int startup_harp_irq(unsigned int irq)
+{
+	enable_harp_irq(irq);
+	return 0;		/* never anything pending */
+}
+
+static struct hw_interrupt_type harp_irq_type = {
+	"Harp-IRQ",
+	startup_harp_irq,
+	shutdown_harp_irq,
+	enable_harp_irq,
+	disable_harp_irq,
+	mask_and_ack_harp,
+	end_harp_irq
+};
+
+static void disable_harp_irq(unsigned int irq)
+{
+	unsigned val, flags;
+	unsigned maskReg;
+	unsigned mask;
+	int pri;
+
+	if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
+		return;
+
+	pri = 15 - irq;
+
+	if (pri < 8) {
+		maskReg = EPLD_INTMASK0;
+	} else {
+		maskReg = EPLD_INTMASK1;
+		pri -= 8;
+	}
+
+	save_and_cli(flags);
+	mask = ctrl_inl(maskReg);
+	mask &= (~(1 << pri));
+#if defined(INVERT_INTMASK_WRITES)
+	mask ^= 0xff;
+#endif
+	ctrl_outl(mask, maskReg);
+	restore_flags(flags);
+}
+
+static void enable_harp_irq(unsigned int irq)
+{
+	unsigned flags;
+	unsigned maskReg;
+	unsigned mask;
+	int pri;
+
+	if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
+		return;
+
+	pri = 15 - irq;
+
+	if (pri < 8) {
+		maskReg = EPLD_INTMASK0;
+	} else {
+		maskReg = EPLD_INTMASK1;
+		pri -= 8;
+	}
+
+	save_and_cli(flags);
+	mask = ctrl_inl(maskReg);
+
+
+	mask |= (1 << pri);
+
+#if defined(INVERT_INTMASK_WRITES)
+	mask ^= 0xff;
+#endif
+	ctrl_outl(mask, maskReg);
+
+	restore_flags(flags);
+}
+
+/* This functions sets the desired irq handler to be an overdrive type */
+static void __init make_harp_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+	irq_desc[irq].handler = &harp_irq_type;
+	disable_harp_irq(irq);
+}
+
+static void mask_and_ack_harp(unsigned int irq)
+{
+	disable_harp_irq(irq);
+}
+
+static void end_harp_irq(unsigned int irq)
+{
+	enable_harp_irq(irq);
+}
+
+void __init init_harp_irq(void)
+{
+	int i;
+
+#if !defined(INVERT_INTMASK_WRITES)
+	// On the harp these are set to enable an interrupt
+	ctrl_outl(0x00, EPLD_INTMASK0);
+	ctrl_outl(0x00, EPLD_INTMASK1);
+#else
+	// On the Overdrive the data is inverted before being stored in the reg
+	ctrl_outl(0xff, EPLD_INTMASK0);
+	ctrl_outl(0xff, EPLD_INTMASK1);
+#endif
+
+	for (i = 0; i < NUM_EXTERNAL_IRQS; i++) {
+		make_harp_irq(i);
+	}
+}
diff -u --recursive --new-file v2.4.5/linux/arch/sh/stboards/led.c linux/arch/sh/stboards/led.c
--- v2.4.5/linux/arch/sh/stboards/led.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/stboards/led.c	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,52 @@
+/*
+ * linux/arch/sh/stboards/led.c
+ *
+ * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * This file contains ST40STB1 HARP and compatible code.
+ */
+
+#include <linux/config.h>
+#include <asm/io.h>
+#include "harp.h"
+
+/* Harp: Flash LD10 (front pannel) connected to EPLD (IC8) */
+/* Overdrive: Flash LD1 (front panel) connected to EPLD (IC4) */
+/* Works for HARP and overdrive */
+static void mach_led(int position, int value)
+{
+	if (value) {
+		ctrl_outl(EPLD_LED_ON, EPLD_LED);
+	} else {
+		ctrl_outl(EPLD_LED_OFF, EPLD_LED);
+	}
+}
+
+#ifdef CONFIG_HEARTBEAT
+
+#include <linux/sched.h>
+
+/* acts like an actual heart beat -- ie thump-thump-pause... */
+void heartbeat_harp(void)
+{
+	static unsigned cnt = 0, period = 0, dist = 0;
+
+	if (cnt == 0 || cnt == dist)
+		mach_led( -1, 1);
+	else if (cnt == 7 || cnt == dist+7)
+		mach_led( -1, 0);
+
+	if (++cnt > period) {
+		cnt = 0;
+		/* The hyperbolic function below modifies the heartbeat period
+		 * length in dependency of the current (5min) load. It goes
+		 * through the points f(0)=126, f(1)=86, f(5)=51,
+		 * f(inf)->30. */
+		period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
+		dist = period / 4;
+	}
+}
+#endif
diff -u --recursive --new-file v2.4.5/linux/arch/sh/stboards/mach.c linux/arch/sh/stboards/mach.c
--- v2.4.5/linux/arch/sh/stboards/mach.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/stboards/mach.c	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,77 @@
+/*
+ * linux/arch/sh/stboards/mach.c
+ *
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * Machine vector for the STMicroelectronics STB1 HARP and compatible boards
+ */
+
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+#include <asm/io_hd64465.h>
+#include <asm/hd64465.h>
+
+void setup_harp(void);
+void init_harp_irq(void);
+void heartbeat_harp(void);
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_harp __initmv = {
+	mv_name:		"STB1 Harp",
+
+	mv_nr_irqs:		89 + HD64465_IRQ_NUM,
+
+	mv_inb:			hd64465_inb,
+	mv_inw:			hd64465_inw,
+	mv_inl:			hd64465_inl,
+	mv_outb:		hd64465_outb,
+	mv_outw:		hd64465_outw,
+	mv_outl:		hd64465_outl,
+
+	mv_inb_p:		hd64465_inb_p,
+	mv_inw_p:		hd64465_inw,
+	mv_inl_p:		hd64465_inl,
+	mv_outb_p:		hd64465_outb_p,
+	mv_outw_p:		hd64465_outw,
+	mv_outl_p:		hd64465_outl,
+
+	mv_insb:		hd64465_insb,
+	mv_insw:		hd64465_insw,
+	mv_insl:		hd64465_insl,
+	mv_outsb:		hd64465_outsb,
+	mv_outsw:		hd64465_outsw,
+	mv_outsl:		hd64465_outsl,
+
+	mv_readb:		generic_readb,
+	mv_readw:		generic_readw,
+	mv_readl:		generic_readl,
+	mv_writeb:		generic_writeb,
+	mv_writew:		generic_writew,
+	mv_writel:		generic_writel,
+
+        mv_ioremap:             generic_ioremap,
+        mv_iounmap:             generic_iounmap,
+ 
+        mv_isa_port2addr:       hd64465_isa_port2addr,
+
+	mv_init_arch:		setup_harp,
+#ifdef CONFIG_PCI
+	mv_init_irq:		init_harp_irq,
+#endif
+#ifdef CONFIG_HEARTBEAT
+	mv_heartbeat:		heartbeat_harp,
+#endif
+        mv_rtc_gettimeofday:    sh_rtc_gettimeofday,
+        mv_rtc_settimeofday:    sh_rtc_settimeofday,
+};
+
+ALIAS_MV(harp)
diff -u --recursive --new-file v2.4.5/linux/arch/sh/stboards/pcidma.c linux/arch/sh/stboards/pcidma.c
--- v2.4.5/linux/arch/sh/stboards/pcidma.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/stboards/pcidma.c	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,42 @@
+/* 
+ * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.                            
+ *
+ * Dynamic DMA mapping support.
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+
+
+void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+			   dma_addr_t * dma_handle)
+{
+	void *ret;
+	int gfp = GFP_ATOMIC;
+
+	ret = (void *) __get_free_pages(gfp, get_order(size));
+
+	if (ret != NULL) {
+	        /* Is it neccessary to do the memset? */
+		memset(ret, 0, size);
+		*dma_handle = virt_to_bus(ret);
+	}
+	/* We must flush the cache before we pass it on to the device */
+	flush_cache_all();
+	return  P2SEGADDR(ret);
+}
+
+void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle)
+{
+        unsigned long p1addr=P1SEGADDR((unsigned long)vaddr);
+
+	free_pages(p1addr, get_order(size));
+}
diff -u --recursive --new-file v2.4.5/linux/arch/sh/stboards/setup.c linux/arch/sh/stboards/setup.c
--- v2.4.5/linux/arch/sh/stboards/setup.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/stboards/setup.c	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,50 @@
+/*
+ * arch/sh/stboard/setup.c
+ *
+ * Copyright (C) 2001 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * STMicroelectronics ST40STB1 HARP and compatible support.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/io.h>
+#include "harp.h"
+/*
+ * Initialize the board
+ */
+int __init setup_harp(void)
+{
+#ifdef CONFIG_SH_STB1_HARP
+	unsigned long ic8_version, ic36_version;
+
+	ic8_version = ctrl_inl(EPLD_REVID2);
+	ic36_version = ctrl_inl(EPLD_REVID1);
+
+        printk("STMicroelectronics STB1 HARP initialisaton\n");
+        printk("EPLD versions: IC8: %d.%02d, IC36: %d.%02d\n",
+               (ic8_version >> 4) & 0xf, ic8_version & 0xf,
+               (ic36_version >> 4) & 0xf, ic36_version & 0xf);
+#elif defined(CONFIG_SH_STB1_OVERDRIVE)
+	unsigned long version;
+
+	version = ctrl_inl(EPLD_REVID);
+
+        printk("STMicroelectronics STB1 Overdrive initialisaton\n");
+        printk("EPLD version: %d.%02d\n",
+	       (version >> 4) & 0xf, version & 0xf);
+#else
+#error Undefined machine
+#endif
+ 
+        /* Currently all STB1 chips have problems with the sleep instruction,
+         * so disable it here.
+         */
+	disable_hlt();
+
+	return 0;
+}
diff -u --recursive --new-file v2.4.5/linux/arch/sparc/config.in linux/arch/sparc/config.in
--- v2.4.5/linux/arch/sparc/config.in	Mon May 21 18:12:09 2001
+++ linux/arch/sparc/config.in	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.110 2001/05/20 05:14:46 davem Exp $
+# $Id: config.in,v 1.111 2001/06/01 08:12:10 davem Exp $
 # For a description of the syntax of this configuration file,
 # see Documentation/kbuild/config-language.txt.
 #
@@ -250,6 +250,10 @@
 endmenu
 
 source fs/Config.in
+
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   source net/bluetooth/Config.in
+fi
 
 mainmenu_option next_comment
 comment 'Watchdog'
diff -u --recursive --new-file v2.4.5/linux/arch/sparc/kernel/rtrap.S linux/arch/sparc/kernel/rtrap.S
--- v2.4.5/linux/arch/sparc/kernel/rtrap.S	Sun Aug  6 11:43:17 2000
+++ linux/arch/sparc/kernel/rtrap.S	Tue Jun 12 11:08:46 2001
@@ -1,4 +1,4 @@
-/* $Id: rtrap.S,v 1.55 2000/08/05 10:48:40 davem Exp $
+/* $Id: rtrap.S,v 1.56 2001/06/05 09:56:06 davem Exp $
  * rtrap.S: Return from Sparc trap low-level code.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -52,9 +52,8 @@
 	sll	%l3, 5, %l3
 	sethi	%hi(C_LABEL(irq_stat)), %l4		! &softirq_active
 	add	%l4, %l3, %l4
-	ld	[%l4 + %lo(C_LABEL(irq_stat))], %g5	! softirq_active
-	ld	[%l4 + %lo(C_LABEL(irq_stat) + 4)], %g4	! softirq_mask
-	andcc	%g4, %g5, %g0
+	ld	[%l4 + %lo(C_LABEL(irq_stat))], %g5	! softirq_pending
+	cmp	%g5, 0
 	be	C_LABEL(ret_trap_lockless_ipi)
 	 nop
 	call	C_LABEL(do_softirq)
diff -u --recursive --new-file v2.4.5/linux/arch/sparc64/config.in linux/arch/sparc64/config.in
--- v2.4.5/linux/arch/sparc64/config.in	Sun May 20 11:32:07 2001
+++ linux/arch/sparc64/config.in	Thu Jun 21 14:27:40 2001
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.143 2001/05/20 05:14:46 davem Exp $
+# $Id: config.in,v 1.146 2001/06/16 04:15:26 davem Exp $
 # For a description of the syntax of this configuration file,
 # see the Configure script.
 #
@@ -36,6 +36,7 @@
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
 define_bool CONFIG_ISA n
+define_bool CONFIG_ISAPNP n
 define_bool CONFIG_EISA n
 define_bool CONFIG_MCA n
 define_bool CONFIG_PCMCIA n
@@ -235,71 +236,7 @@
 
    bool 'Network device support' CONFIG_NETDEVICES
    if [ "$CONFIG_NETDEVICES" = "y" ]; then
-      tristate '  Dummy net driver support' CONFIG_DUMMY
-      tristate '  Bonding driver support' CONFIG_BONDING
-      tristate '  Universal TUN/TAP device driver support' CONFIG_TUN
-      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-        if [ "$CONFIG_NETLINK" = "y" ]; then
-          tristate '  Ethertap network tap (OBSOLETE)' CONFIG_ETHERTAP
-        fi
-      fi
-      tristate '  PPP (point-to-point) support' CONFIG_PPP
-      if [ ! "$CONFIG_PPP" = "n" ]; then
-         dep_tristate '  PPP support for async serial ports' CONFIG_PPP_ASYNC $CONFIG_PPP
-         dep_tristate '  PPP support for sync tty ports' CONFIG_PPP_SYNC_TTY $CONFIG_PPP
-         dep_tristate '  PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP
-         dep_tristate '  PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP m
-         if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-            dep_tristate '  PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP
-         fi
-      fi
-      tristate '  SLIP (serial line) support' CONFIG_SLIP
-      if [ "$CONFIG_SLIP" != "n" ]; then
-	 bool '    CSLIP compressed headers' CONFIG_SLIP_COMPRESSED
-	 bool '    Keepalive and linefill' CONFIG_SLIP_SMART
-	 bool '    Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6
-      fi
-
-      mainmenu_option next_comment
-      comment 'Ethernet (10 or 100Mbit)'
-
-      tristate 'Sun LANCE support' CONFIG_SUNLANCE
-      tristate 'Sun Happy Meal 10/100baseT support' CONFIG_HAPPYMEAL
-      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-	 tristate 'Sun BigMAC 10/100baseT support (EXPERIMENTAL)' CONFIG_SUNBMAC
-      fi
-      tristate '  Sun QuadEthernet support' CONFIG_SUNQE
-      if [ "$CONFIG_PCI" = "y" ]; then
-	 tristate 'Generic DECchip & DIGITAL EtherWORKS PCI/EISA' CONFIG_DE4X5
-	 tristate 'DECchip Tulip (dc21x4x) PCI support' CONFIG_TULIP
-	 tristate '3c590/3c900 series (592/595/597) "Vortex/Boomerang" support' CONFIG_VORTEX
-	 tristate 'RealTek RTL-8139 support' CONFIG_8139TOO
-	 tristate 'PCI NE2000 support' CONFIG_NE2K_PCI
-	 tristate 'VIA Rhine support' CONFIG_VIA_RHINE
-	 tristate 'EtherExpressPro/100 support' CONFIG_EEPRO100
-	 tristate 'Adaptec Starfire support' CONFIG_ADAPTEC_STARFIRE
-      fi
-      endmenu
-
-      mainmenu_option next_comment
-      comment 'Ethernet (1000 Mbit)'
-
-      if [ "$CONFIG_PCI" = "y" ]; then
-	  tristate 'Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support' CONFIG_ACENIC
-	  if [ "$CONFIG_ACENIC" != "n" ]; then
-	    bool '  Omit support for old Tigon I based AceNICs' CONFIG_ACENIC_OMIT_TIGON_I
-	  fi
-	  tristate 'SysKonnect SK-98xx support' CONFIG_SK98LIN
-	  tristate 'Sun GEM support' CONFIG_SUNGEM
-      fi
-      tristate 'MyriCOM Gigabit Ethernet support' CONFIG_MYRI_SBUS
-      endmenu
-
-      bool 'FDDI driver support' CONFIG_FDDI
-      if [ "$CONFIG_FDDI" = "y" ]; then
-          tristate '  SysKonnect FDDI PCI support' CONFIG_SKFP
-      fi
-
+      source drivers/net/Config.in
       if [ "$CONFIG_ATM" = "y" ]; then
 	source drivers/atm/Config.in
       fi
@@ -330,6 +267,11 @@
 comment 'XFree86 DRI support'
 bool 'Direct Rendering Manager (XFree86 DRI support)' CONFIG_DRM
 dep_tristate '  Creator/Creator3D' CONFIG_DRM_FFB $CONFIG_DRM
+dep_tristate '  3dfx Banshee/Voodoo3+' CONFIG_DRM_TDFX $CONFIG_DRM
+dep_tristate '  ATI Rage 128' CONFIG_DRM_R128 $CONFIG_DRM
+if [ "$CONFIG_DRM_R128" != "n" ]; then
+   define_bool CONFIG_AGP y
+fi
 endmenu
 
 source drivers/input/Config.in
@@ -346,6 +288,10 @@
 endmenu
 
 source drivers/usb/Config.in
+
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   source net/bluetooth/Config.in
+fi
 
 mainmenu_option next_comment
 comment 'Watchdog'
diff -u --recursive --new-file v2.4.5/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- v2.4.5/linux/arch/sparc64/defconfig	Thu May 24 15:00:58 2001
+++ linux/arch/sparc64/defconfig	Thu Jun 21 14:27:40 2001
@@ -26,6 +26,7 @@
 # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 # CONFIG_ISA is not set
+# CONFIG_ISAPNP is not set
 # CONFIG_EISA is not set
 # CONFIG_MCA is not set
 # CONFIG_PCMCIA is not set
@@ -359,46 +360,119 @@
 # Network device support
 #
 CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_APPLETALK is not set
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
 CONFIG_TUN=m
-CONFIG_PPP=m
-# CONFIG_PPP_ASYNC is not set
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-# CONFIG_PPP_BSDCOMP is not set
-CONFIG_PPPOE=m
-CONFIG_SLIP=m
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_SMART=y
-# CONFIG_SLIP_MODE_SLIP6 is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
+CONFIG_NET_ETHERNET=y
 CONFIG_SUNLANCE=y
 CONFIG_HAPPYMEAL=y
 CONFIG_SUNBMAC=m
 CONFIG_SUNQE=m
-CONFIG_DE4X5=m
-CONFIG_TULIP=m
+CONFIG_SUNLANCE=y
+CONFIG_SUNGEM=y
+CONFIG_NET_VENDOR_3COM=y
+# CONFIG_EL1 is not set
+# CONFIG_EL2 is not set
+# CONFIG_ELPLUS is not set
+# CONFIG_EL16 is not set
+# CONFIG_ELMC is not set
+# CONFIG_ELMC_II is not set
 CONFIG_VORTEX=m
-CONFIG_8139TOO=m
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_ADAPTEC_STARFIRE=m
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+CONFIG_DE4X5=m
+CONFIG_DGRS=m
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=m
+# CONFIG_LNE390 is not set
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
 CONFIG_NE2K_PCI=m
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_SIS900 is not set
+CONFIG_EPIC100=m
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
 CONFIG_VIA_RHINE=m
-CONFIG_EEPRO100=m
-CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_WINBOND_840=m
+# CONFIG_NET_POCKET is not set
 
 #
 # Ethernet (1000 Mbit)
 #
 CONFIG_ACENIC=m
 # CONFIG_ACENIC_OMIT_TIGON_I is not set
-CONFIG_SK98LIN=m
-CONFIG_SUNGEM=y
 CONFIG_MYRI_SBUS=m
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+CONFIG_SK98LIN=m
 CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
 CONFIG_SKFP=m
+CONFIG_HIPPI=y
+# CONFIG_ROADRUNNER is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+# CONFIG_PPP_ASYNC is not set
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
 
 #
 # Unix 98 PTY support
@@ -417,6 +491,9 @@
 #
 CONFIG_DRM=y
 CONFIG_DRM_FFB=m
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_AGP=y
 
 #
 # Input core support
@@ -661,6 +738,19 @@
 # USB misc drivers
 #
 CONFIG_USB_RIO500=m
+
+#
+# Bluetooth support
+#
+CONFIG_BLUEZ=m
+CONFIG_BLUEZ_L2CAP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BLUEZ_HCIUSB=m
+CONFIG_BLUEZ_HCIUART=m
+CONFIG_BLUEZ_HCIEMU=m
 
 #
 # Watchdog
diff -u --recursive --new-file v2.4.5/linux/arch/sparc64/kernel/devices.c linux/arch/sparc64/kernel/devices.c
--- v2.4.5/linux/arch/sparc64/kernel/devices.c	Sun May 20 12:11:38 2001
+++ linux/arch/sparc64/kernel/devices.c	Tue Jun 12 11:08:46 2001
@@ -9,6 +9,7 @@
 #include <linux/threads.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/string.h>
 
 #include <asm/page.h>
 #include <asm/oplib.h>
diff -u --recursive --new-file v2.4.5/linux/arch/sparc64/kernel/ebus.c linux/arch/sparc64/kernel/ebus.c
--- v2.4.5/linux/arch/sparc64/kernel/ebus.c	Thu Apr 26 22:17:25 2001
+++ linux/arch/sparc64/kernel/ebus.c	Tue Jun 12 11:08:46 2001
@@ -1,4 +1,4 @@
-/* $Id: ebus.c,v 1.61 2001/04/24 05:13:25 davem Exp $
+/* $Id: ebus.c,v 1.63 2001/06/08 02:27:16 davem Exp $
  * ebus.c: PCI to EBus bridge device.
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
@@ -25,7 +25,6 @@
 #ifdef CONFIG_SUN_AUXIO
 extern void auxio_probe(void);
 #endif
-extern void rs_init(void);
 
 static inline void *ebus_alloc(size_t size)
 {
@@ -269,8 +268,6 @@
 	printk("]");
 }
 
-extern void clock_probe(void);
-extern void power_init(void);
 
 void __init ebus_init(void)
 {
@@ -395,10 +392,7 @@
 		++num_ebus;
 	}
 
-	rs_init();
 #ifdef CONFIG_SUN_AUXIO
 	auxio_probe();
 #endif
-	clock_probe();
-	power_init();
 }
diff -u --recursive --new-file v2.4.5/linux/arch/sparc64/kernel/ioctl32.c linux/arch/sparc64/kernel/ioctl32.c
--- v2.4.5/linux/arch/sparc64/kernel/ioctl32.c	Wed May 16 10:31:27 2001
+++ linux/arch/sparc64/kernel/ioctl32.c	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-/* $Id: ioctl32.c,v 1.115 2001/05/12 06:41:58 davem Exp $
+/* $Id: ioctl32.c,v 1.117 2001/06/02 21:39:55 davem Exp $
  * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
  *
  * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
@@ -90,6 +90,9 @@
 #include <linux/sonet.h>
 #include <linux/atm_suni.h>
 
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci.h>
+
 /* Use this to get at 32-bit user passed pointers. 
    See sys_sparc32.c for description about these. */
 #define A(__x) ((unsigned long)(__x))
@@ -3469,6 +3472,10 @@
 COMPATIBLE_IOCTL(CDROM_LOCKDOOR)
 COMPATIBLE_IOCTL(CDROM_DEBUG)
 COMPATIBLE_IOCTL(CDROM_GET_CAPABILITY)
+/* DVD ioctls */
+COMPATIBLE_IOCTL(DVD_READ_STRUCT)
+COMPATIBLE_IOCTL(DVD_WRITE_STRUCT)
+COMPATIBLE_IOCTL(DVD_AUTH)
 /* Big L */
 COMPATIBLE_IOCTL(LOOP_SET_FD)
 COMPATIBLE_IOCTL(LOOP_CLR_FD)
@@ -3719,6 +3726,17 @@
 COMPATIBLE_IOCTL(WIOCSTART)
 COMPATIBLE_IOCTL(WIOCSTOP)
 COMPATIBLE_IOCTL(WIOCGSTAT)
+/* Bluetooth ioctls */
+COMPATIBLE_IOCTL(HCIDEVUP)
+COMPATIBLE_IOCTL(HCIDEVDOWN)
+COMPATIBLE_IOCTL(HCIDEVRESET)
+COMPATIBLE_IOCTL(HCIRESETSTAT)
+COMPATIBLE_IOCTL(HCIGETINFO)
+COMPATIBLE_IOCTL(HCIGETDEVLIST)
+COMPATIBLE_IOCTL(HCISETRAW)
+COMPATIBLE_IOCTL(HCISETSCAN)
+COMPATIBLE_IOCTL(HCISETAUTH)
+COMPATIBLE_IOCTL(HCIINQUIRY)
 /* Misc. */
 COMPATIBLE_IOCTL(0x41545900)		/* ATYIO_CLKR */
 COMPATIBLE_IOCTL(0x41545901)		/* ATYIO_CLKW */
diff -u --recursive --new-file v2.4.5/linux/arch/sparc64/kernel/irq.c linux/arch/sparc64/kernel/irq.c
--- v2.4.5/linux/arch/sparc64/kernel/irq.c	Thu Apr 26 22:17:25 2001
+++ linux/arch/sparc64/kernel/irq.c	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.100 2001/04/24 01:09:12 davem Exp $
+/* $Id: irq.c,v 1.101 2001/06/04 06:50:18 ecd Exp $
  * irq.c: UltraSparc IRQ handling/init/registry.
  *
  * Copyright (C) 1997  David S. Miller  (davem@caip.rutgers.edu)
@@ -783,6 +783,8 @@
 		unsigned char flags = bp->flags;
 
 		nbp = __bucket(bp->irq_chain);
+		bp->irq_chain = 0;
+
 		if ((flags & IBF_ACTIVE) != 0) {
 #ifdef CONFIG_PCI
 			if ((flags & IBF_DMA_SYNC) != 0) {
diff -u --recursive --new-file v2.4.5/linux/arch/sparc64/kernel/pci.c linux/arch/sparc64/kernel/pci.c
--- v2.4.5/linux/arch/sparc64/kernel/pci.c	Wed May 16 10:31:27 2001
+++ linux/arch/sparc64/kernel/pci.c	Wed Jun 20 21:00:55 2001
@@ -1,4 +1,4 @@
-/* $Id: pci.c,v 1.29 2001/05/15 08:54:30 davem Exp $
+/* $Id: pci.c,v 1.35 2001/06/13 06:34:30 davem Exp $
  * pci.c: UltraSparc PCI controller support.
  *
  * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com)
@@ -177,6 +177,10 @@
 	}
 }
 
+extern void rs_init(void);
+extern void clock_probe(void);
+extern void power_init(void);
+
 void __init pcibios_init(void)
 {
 	pci_controller_probe();
@@ -190,6 +194,9 @@
 
 	isa_init();
 	ebus_init();
+	rs_init();
+	clock_probe();
+	power_init();
 }
 
 struct pci_fixup pcibios_fixups[] = {
@@ -198,6 +205,66 @@
 
 void pcibios_fixup_bus(struct pci_bus *pbus)
 {
+	struct pci_pbm_info *pbm = pbus->sysdata;
+
+	/* Generic PCI bus probing sets these to point at
+	 * &io{port,mem}_resouce which is wrong for us.
+	 */
+	pbus->resource[0] = &pbm->io_space;
+	pbus->resource[1] = &pbm->mem_space;
+}
+
+/* NOTE: This can get called before we've fixed up pdev->sysdata. */
+int pci_claim_resource(struct pci_dev *pdev, int resource)
+{
+	struct pci_pbm_info *pbm = pci_bus2pbm[pdev->bus->number];
+	struct resource *res = &pdev->resource[resource];
+	struct resource *root;
+
+	if (!pbm)
+		return -EINVAL;
+
+	if (res->flags & IORESOURCE_IO)
+		root = &pbm->io_space;
+	else
+		root = &pbm->mem_space;
+
+	pbm->parent->resource_adjust(pdev, res, root);
+
+	return request_resource(root, res);
+}
+
+int pci_assign_resource(struct pci_dev *pdev, int resource)
+{
+	struct pcidev_cookie *pcp = pdev->sysdata;
+	struct pci_pbm_info *pbm = pcp->pbm;
+	struct resource *res = &pdev->resource[resource];
+	struct resource *root;
+	unsigned long min, max, size, align;
+	int err;
+
+	if (res->flags & IORESOURCE_IO) {
+		root = &pbm->io_space;
+		min = root->start + 0x400UL;
+		max = root->end;
+	} else {
+		root = &pbm->mem_space;
+		min = root->start;
+		max = min + 0x80000000UL;
+	}
+
+	size = res->end - res->start;
+	align = size + 1;
+
+	err = allocate_resource(root, res, size + 1, min, max, align, NULL, NULL);
+	if (err < 0) {
+		printk("PCI: Failed to allocate resource %d for %s\n",
+		       resource, pdev->name);
+	} else {
+		pbm->parent->base_address_update(pdev, resource);
+	}
+
+	return err;
 }
 
 void pcibios_update_resource(struct pci_dev *pdev, struct resource *res1,
@@ -238,6 +305,53 @@
 
 /* Platform support for /proc/bus/pci/X/Y mmap()s. */
 
+/* If the user uses a host-bridge as the PCI device, he may use
+ * this to perform a raw mmap() of the I/O or MEM space behind
+ * that controller.
+ *
+ * This can be useful for execution of x86 PCI bios initialization code
+ * on a PCI card, like the xfree86 int10 stuff does.
+ */
+static int __pci_mmap_make_offset_bus(struct pci_dev *pdev, struct vm_area_struct *vma,
+				      enum pci_mmap_state mmap_state)
+{
+	struct pcidev_cookie *pcp = pdev->sysdata;
+	struct pci_pbm_info *pbm;
+	unsigned long space_size, user_offset, user_size;
+
+	if (!pcp)
+		return -ENXIO;
+	pbm = pcp->pbm;
+	if (!pbm)
+		return -ENXIO;
+
+	if (mmap_state == pci_mmap_io) {
+		space_size = (pbm->io_space.end -
+			      pbm->io_space.start) + 1;
+	} else {
+		space_size = (pbm->mem_space.end -
+			      pbm->mem_space.start) + 1;
+	}
+
+	/* Make sure the request is in range. */
+	user_offset = vma->vm_pgoff << PAGE_SHIFT;
+	user_size = vma->vm_end - vma->vm_start;
+
+	if (user_offset >= space_size ||
+	    (user_offset + user_size) > space_size)
+		return -EINVAL;
+
+	if (mmap_state == pci_mmap_io) {
+		vma->vm_pgoff = (pbm->io_space.start +
+				 user_offset) >> PAGE_SHIFT;
+	} else {
+		vma->vm_pgoff = (pbm->mem_space.start +
+				 user_offset) >> PAGE_SHIFT;
+	}
+
+	return 0;
+}
+
 /* Adjust vm_pgoff of VMA such that it is the physical page offset corresponding
  * to the 32-bit pci bus offset for DEV requested by the user.
  *
@@ -248,14 +362,17 @@
  *
  * Returns negative error code on failure, zero on success.
  */
-static __inline__ int __pci_mmap_make_offset(struct pci_dev *dev, struct vm_area_struct *vma,
-					     enum pci_mmap_state mmap_state)
+static int __pci_mmap_make_offset(struct pci_dev *dev, struct vm_area_struct *vma,
+				  enum pci_mmap_state mmap_state)
 {
 	unsigned long user_offset = vma->vm_pgoff << PAGE_SHIFT;
 	unsigned long user32 = user_offset & 0xffffffffUL;
 	unsigned long largest_base, this_base, addr32;
 	int i;
 
+	if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST)
+		return __pci_mmap_make_offset_bus(dev, vma, mmap_state);
+
 	/* Figure out which base address this is for. */
 	largest_base = 0UL;
 	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
@@ -303,7 +420,7 @@
 /* Set vm_flags of VMA, as appropriate for this architecture, for a pci device
  * mapping.
  */
-static __inline__ void __pci_mmap_set_flags(struct pci_dev *dev, struct vm_area_struct *vma,
+static void __pci_mmap_set_flags(struct pci_dev *dev, struct vm_area_struct *vma,
 					    enum pci_mmap_state mmap_state)
 {
 	vma->vm_flags |= (VM_SHM | VM_LOCKED);
@@ -312,7 +429,7 @@
 /* Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
  * device mapping.
  */
-static __inline__ void __pci_mmap_set_pgprot(struct pci_dev *dev, struct vm_area_struct *vma,
+static void __pci_mmap_set_pgprot(struct pci_dev *dev, struct vm_area_struct *vma,
 					     enum pci_mmap_state mmap_state)
 {
 	/* Our io_remap_page_range takes care of this, do nothing. */
diff -u --recursive --new-file v2.4.5/linux/arch/sparc64/kernel/pci_common.c linux/arch/sparc64/kernel/pci_common.c
--- v2.4.5/linux/arch/sparc64/kernel/pci_common.c	Sat May 19 18:13:15 2001
+++ linux/arch/sparc64/kernel/pci_common.c	Wed Jun 20 21:00:55 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_common.c,v 1.18 2001/05/18 23:06:35 davem Exp $
+/* $Id: pci_common.c,v 1.25 2001/06/14 16:57:41 davem Exp $
  * pci_common.c: PCI controller common support.
  *
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -93,12 +93,38 @@
 }
 
 /* Older versions of OBP on PCI systems encode 64-bit MEM
- * space assignments incorrectly, this fixes them up.
+ * space assignments incorrectly, this fixes them up.  We also
+ * take the opportunity here to hide other kinds of bogus
+ * assignments.
  */
-static void __init fixup_obp_assignments(struct pcidev_cookie *pcp)
+static void __init fixup_obp_assignments(struct pci_dev *pdev,
+					 struct pcidev_cookie *pcp)
 {
 	int i;
 
+	if (pdev->vendor == PCI_VENDOR_ID_AL &&
+	    (pdev->device == PCI_DEVICE_ID_AL_M7101 ||
+	     pdev->device == PCI_DEVICE_ID_AL_M1533)) {
+		int i;
+
+		/* Zap all of the normal resources, they are
+		 * meaningless and generate bogus resource collision
+		 * messages.  This is OpenBoot's ill-fated attempt to
+		 * represent the implicit resources that these devices
+		 * have.
+		 */
+		pcp->num_prom_assignments = 0;
+		for (i = 0; i < 6; i++) {
+			pdev->resource[i].start =
+				pdev->resource[i].end =
+				pdev->resource[i].flags = 0;
+		}
+		pdev->resource[PCI_ROM_RESOURCE].start =
+			pdev->resource[PCI_ROM_RESOURCE].end =
+			pdev->resource[PCI_ROM_RESOURCE].flags = 0;
+		return;
+	}
+
 	for (i = 0; i < pcp->num_prom_assignments; i++) {
 		struct linux_prom_pci_registers *ap;
 		int space;
@@ -194,7 +220,7 @@
 				(err / sizeof(pcp->prom_assignments[0]));
 	}
 
-	fixup_obp_assignments(pcp);
+	fixup_obp_assignments(pdev, pcp);
 
 	pdev->sysdata = pcp;
 }
@@ -231,11 +257,13 @@
 	}
 }
 
-static void __init bad_assignment(struct linux_prom_pci_registers *ap,
+static void __init bad_assignment(struct pci_dev *pdev,
+				  struct linux_prom_pci_registers *ap,
 				  struct resource *res,
 				  int do_prom_halt)
 {
-	prom_printf("PCI: Bogus PROM assignment.\n");
+	prom_printf("PCI: Bogus PROM assignment. BUS[%02x] DEVFN[%x]\n",
+		    pdev->bus->number, pdev->devfn);
 	if (ap)
 		prom_printf("PCI: phys[%08x:%08x:%08x] size[%08x:%08x]\n",
 			    ap->phys_hi, ap->phys_mid, ap->phys_lo,
@@ -293,7 +321,7 @@
 	case  PCI_ROM_ADDRESS:
 		/* It had better be MEM space. */
 		if (space != 2)
-			bad_assignment(ap, NULL, 0);
+			bad_assignment(pdev, ap, NULL, 0);
 
 		res = &pdev->resource[PCI_ROM_RESOURCE];
 		break;
@@ -308,7 +336,7 @@
 		break;
 
 	default:
-		bad_assignment(ap, NULL, 0);
+		bad_assignment(pdev, ap, NULL, 0);
 		res = NULL;
 		break;
 	};
@@ -316,6 +344,19 @@
 	return res;
 }
 
+static int __init pdev_resource_collisions_expected(struct pci_dev *pdev)
+{
+	if (pdev->vendor != PCI_VENDOR_ID_SUN)
+		return 0;
+
+	if (pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS ||
+	    pdev->device == PCI_DEVICE_ID_SUN_RIO_1394 ||
+	    pdev->device == PCI_DEVICE_ID_SUN_RIO_USB)
+		return 1;
+
+	return 0;
+}
+
 static void __init pdev_record_assignments(struct pci_pbm_info *pbm,
 					   struct pci_dev *pdev)
 {
@@ -332,14 +373,15 @@
 		ap = &pcp->prom_assignments[i];
 		root = get_root_resource(ap, pbm);
 		res = get_device_resource(ap, pdev);
-		if (root == NULL || res == NULL)
+		if (root == NULL || res == NULL ||
+		    res->flags == 0)
 			continue;
 
 		/* Ok we know which resource this PROM assignment is
 		 * for, sanity check it.
 		 */
 		if ((res->start & 0xffffffffUL) != ap->phys_lo)
-			bad_assignment(ap, res, 1);
+			bad_assignment(pdev, ap, res, 1);
 
 		/* If it is a 64-bit MEM space assignment, verify that
 		 * the resource is too and that the upper 32-bits match.
@@ -348,9 +390,9 @@
 			if (((res->flags & IORESOURCE_MEM) == 0) ||
 			    ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK)
 			     != PCI_BASE_ADDRESS_MEM_TYPE_64))
-				bad_assignment(ap, res, 1);
+				bad_assignment(pdev, ap, res, 1);
 			if ((res->start >> 32) != ap->phys_mid)
-				bad_assignment(ap, res, 1);
+				bad_assignment(pdev, ap, res, 1);
 
 			/* PBM cannot generate cpu initiated PIOs
 			 * to the full 64-bit space.  Therefore the
@@ -374,12 +416,17 @@
 		if (request_resource(root, res) < 0) {
 			/* OK, there is some conflict.  But this is fine
 			 * since we'll reassign it in the fixup pass.
-			 * Nevertheless notify the user that OBP made
-			 * an error.
+			 *
+			 * We notify the user that OBP made an error if it
+			 * is a case we don't expect.
 			 */
-			printk(KERN_ERR "PCI: Address space collision on region %ld "
-			       "of device %s\n",
-			       (res - &pdev->resource[0]), pdev->name);
+			if (!pdev_resource_collisions_expected(pdev)) {
+				printk(KERN_ERR "PCI: Address space collision on region %ld "
+				       "[%016lx:%016lx] of device %s\n",
+				       (res - &pdev->resource[0]),
+				       res->start, res->end,
+				       pdev->name);
+			}
 		}
 	}
 }
@@ -397,6 +444,23 @@
 		pci_record_assignments(pbm, pci_bus_b(walk));
 }
 
+/* Return non-zero if PDEV has implicit I/O resources even
+ * though it may not have an I/O base address register
+ * active.
+ */
+static int __init has_implicit_io(struct pci_dev *pdev)
+{
+	int class = pdev->class >> 8;
+
+	if (class == PCI_CLASS_NOT_DEFINED ||
+	    class == PCI_CLASS_NOT_DEFINED_VGA ||
+	    class == PCI_CLASS_STORAGE_IDE ||
+	    (pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
+		return 1;
+
+	return 0;
+}
+
 static void __init pdev_assign_unassigned(struct pci_pbm_info *pbm,
 					  struct pci_dev *pdev)
 {
@@ -460,7 +524,7 @@
 	 */
 	if (io_seen || mem_seen) {
 		pci_read_config_word(pdev, PCI_COMMAND, &cmd);
-		if (io_seen)
+		if (io_seen || has_implicit_io(pdev))
 			cmd |= PCI_COMMAND_IO;
 		if (mem_seen)
 			cmd |= PCI_COMMAND_MEMORY;
@@ -819,6 +883,46 @@
 	walk = &pbus->children;
 	for (walk = walk->next; walk != &pbus->children; walk = walk->next)
 		pci_setup_busmastering(pbm, pci_bus_b(walk));
+}
+
+void pci_register_legacy_regions(struct resource *io_res,
+				 struct resource *mem_res)
+{
+	struct resource *p;
+
+	/* VGA Video RAM. */
+	p = kmalloc(sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return;
+
+	memset(p, 0, sizeof(*p));
+	p->name = "Video RAM area";
+	p->start = mem_res->start + 0xa0000UL;
+	p->end = p->start + 0x1ffffUL;
+	p->flags = IORESOURCE_BUSY;
+	request_resource(mem_res, p);
+
+	p = kmalloc(sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return;
+
+	memset(p, 0, sizeof(*p));
+	p->name = "System ROM";
+	p->start = mem_res->start + 0xf0000UL;
+	p->end = p->start + 0xffffUL;
+	p->flags = IORESOURCE_BUSY;
+	request_resource(mem_res, p);
+
+	p = kmalloc(sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return;
+
+	memset(p, 0, sizeof(*p));
+	p->name = "Video ROM";
+	p->start = mem_res->start + 0xc0000UL;
+	p->end = p->start + 0x7fffUL;
+	p->flags = IORESOURCE_BUSY;
+	request_resource(mem_res, p);
 }
 
 /* Generic helper routines for PCI error reporting. */
diff -u --recursive --new-file v2.4.5/linux/arch/sparc64/kernel/pci_impl.h linux/arch/sparc64/kernel/pci_impl.h
--- v2.4.5/linux/arch/sparc64/kernel/pci_impl.h	Wed May 16 10:31:27 2001
+++ linux/arch/sparc64/kernel/pci_impl.h	Wed Jun 20 21:00:55 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_impl.h,v 1.8 2001/05/15 08:54:30 davem Exp $
+/* $Id: pci_impl.h,v 1.9 2001/06/13 06:34:30 davem Exp $
  * pci_impl.h: Helper definitions for PCI controller support.
  *
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -33,6 +33,8 @@
 					    struct pci_bus *pbus);
 extern void pci_setup_busmastering(struct pci_pbm_info *pbm,
 				   struct pci_bus *pbus);
+extern void pci_register_legacy_regions(struct resource *io_res,
+					struct resource *mem_res);
 
 /* Error reporting support. */
 extern void pci_scan_for_target_abort(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *);
diff -u --recursive --new-file v2.4.5/linux/arch/sparc64/kernel/pci_psycho.c linux/arch/sparc64/kernel/pci_psycho.c
--- v2.4.5/linux/arch/sparc64/kernel/pci_psycho.c	Wed May 16 10:31:27 2001
+++ linux/arch/sparc64/kernel/pci_psycho.c	Wed Jun 20 21:00:55 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_psycho.c,v 1.24 2001/05/15 08:54:30 davem Exp $
+/* $Id: pci_psycho.c,v 1.26 2001/06/13 06:34:30 davem Exp $
  * pci_psycho.c: PSYCHO/U2P specific PCI controller support.
  *
  * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -353,23 +353,28 @@
 	if (ret == 0 && pdev == NULL) {
 		ret = 1;
 	} else if (ret == 0) {
-		switch ((pdev->class >> 16) & 0x0f) {
+		switch ((pdev->class >> 16) & 0xff) {
 		case PCI_BASE_CLASS_STORAGE:
 			ret = 4;
+			break;
 
 		case PCI_BASE_CLASS_NETWORK:
 			ret = 6;
+			break;
 
 		case PCI_BASE_CLASS_DISPLAY:
 			ret = 9;
+			break;
 
 		case PCI_BASE_CLASS_MULTIMEDIA:
 		case PCI_BASE_CLASS_MEMORY:
 		case PCI_BASE_CLASS_BRIDGE:
 			ret = 10;
+			break;
 
 		default:
 			ret = 1;
+			break;
 		};
 	}
 
@@ -1404,6 +1409,8 @@
 
 	request_resource(&ioport_resource, &pbm->io_space);
 	request_resource(&iomem_resource, &pbm->mem_space);
+	pci_register_legacy_regions(&pbm->io_space,
+				    &pbm->mem_space);
 }
 
 static void psycho_pbm_strbuf_init(struct pci_controller_info *p,
diff -u --recursive --new-file v2.4.5/linux/arch/sparc64/kernel/pci_sabre.c linux/arch/sparc64/kernel/pci_sabre.c
--- v2.4.5/linux/arch/sparc64/kernel/pci_sabre.c	Wed May 16 10:31:27 2001
+++ linux/arch/sparc64/kernel/pci_sabre.c	Wed Jun 20 21:00:55 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_sabre.c,v 1.32 2001/05/15 11:10:01 davem Exp $
+/* $Id: pci_sabre.c,v 1.37 2001/06/13 06:34:30 davem Exp $
  * pci_sabre.c: Sabre specific PCI controller support.
  *
  * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -16,6 +16,7 @@
 #include <asm/pbm.h>
 #include <asm/iommu.h>
 #include <asm/irq.h>
+#include <asm/smp.h>
 
 #include "pci_impl.h"
 
@@ -196,7 +197,7 @@
 
 #define SABRE_CONFIGSPACE	0x001000000UL
 #define SABRE_IOSPACE		0x002000000UL
-#define SABRE_IOSPACE_SIZE	0x00000ffffUL
+#define SABRE_IOSPACE_SIZE	0x000ffffffUL
 #define SABRE_MEMSPACE		0x100000000UL
 #define SABRE_MEMSPACE_SIZE	0x07fffffffUL
 
@@ -590,23 +591,28 @@
 	if (ret == 0 && pdev == NULL) {
 		ret = 1;
 	} else if (ret == 0) {
-		switch ((pdev->class >> 16) & 0x0f) {
+		switch ((pdev->class >> 16) & 0xff) {
 		case PCI_BASE_CLASS_STORAGE:
 			ret = 4;
+			break;
 
 		case PCI_BASE_CLASS_NETWORK:
 			ret = 6;
+			break;
 
 		case PCI_BASE_CLASS_DISPLAY:
 			ret = 9;
+			break;
 
 		case PCI_BASE_CLASS_MULTIMEDIA:
 		case PCI_BASE_CLASS_MEMORY:
 		case PCI_BASE_CLASS_BRIDGE:
 			ret = 10;
+			break;
 
 		default:
 			ret = 1;
+			break;
 		};
 	}
 	return ret;
@@ -1025,8 +1031,8 @@
 					 struct resource *res,
 					 struct resource *root)
 {
-	struct pcidev_cookie *pcp = pdev->sysdata;
-	struct pci_controller_info *p = pcp->pbm->parent;
+	struct pci_pbm_info *pbm = pci_bus2pbm[pdev->bus->number];
+	struct pci_controller_info *p = pbm->parent;
 	unsigned long base;
 
 	if (res->flags & IORESOURCE_IO)
@@ -1351,6 +1357,12 @@
 			    (pbm == &p->pbm_A ? 'A' : 'B'));
 		prom_halt();
 	}
+
+	/* Register legacy regions if this PBM covers that area. */
+	if (pbm->io_space.start == ibase &&
+	    pbm->mem_space.start == mbase)
+		pci_register_legacy_regions(&pbm->io_space,
+					    &pbm->mem_space);
 }
 
 static void __init sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dma_begin)
@@ -1476,7 +1488,7 @@
 
 		/* Hack up top-level resources. */
 		pbm->io_space.start = p->controller_regs + SABRE_IOSPACE;
-		pbm->io_space.end   = pbm->io_space.start + (1UL << 16) - 1UL;
+		pbm->io_space.end   = pbm->io_space.start + (1UL << 24) - 1UL;
 		pbm->io_space.flags = IORESOURCE_IO;
 
 		pbm->mem_space.start = p->controller_regs + SABRE_MEMSPACE;
@@ -1491,6 +1503,9 @@
 			prom_printf("Cannot register Hummingbird's MEM space.\n");
 			prom_halt();
 		}
+
+		pci_register_legacy_regions(&pbm->io_space,
+					    &pbm->mem_space);
 	}
 }
 
@@ -1514,8 +1529,19 @@
 
 		if (prom_getproperty(pnode, "compatible",
 				     compat, sizeof(compat)) > 0 &&
-		    !strcmp(compat, "pci108e,a001"))
+		    !strcmp(compat, "pci108e,a001")) {
 			hummingbird_p = 1;
+		} else {
+			int cpu_node = linux_cpus[0].prom_node;
+
+			/* Of course, Sun has to encode things a thousand
+			 * different ways, inconsistently.
+			 */
+			if (prom_getproperty(cpu_node, "name",
+					     compat, sizeof(compat)) > 0 &&
+			    !strcmp(compat, "SUNW,UltraSPARC-IIe"))
+				hummingbird_p = 1;
+		}
 	}
 
 	p = kmalloc(sizeof(*p), GFP_ATOMIC);
diff -u --recursive --new-file v2.4.5/linux/arch/sparc64/kernel/pci_schizo.c linux/arch/sparc64/kernel/pci_schizo.c
--- v2.4.5/linux/arch/sparc64/kernel/pci_schizo.c	Wed May 16 10:31:27 2001
+++ linux/arch/sparc64/kernel/pci_schizo.c	Wed Jun 20 21:00:55 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_schizo.c,v 1.16 2001/05/15 08:54:30 davem Exp $
+/* $Id: pci_schizo.c,v 1.19 2001/06/20 21:31:00 davem Exp $
  * pci_schizo.c: SCHIZO specific PCI controller support.
  *
  * Copyright (C) 2001 David S. Miller (davem@redhat.com)
@@ -339,23 +339,28 @@
 	if (ret == 0 && pdev == NULL) {
 		ret = 1;
 	} else if (ret == 0) {
-		switch ((pdev->class >> 16) & 0x0f) {
+		switch ((pdev->class >> 16) & 0xff) {
 		case PCI_BASE_CLASS_STORAGE:
 			ret = 4;
+			break;
 
 		case PCI_BASE_CLASS_NETWORK:
 			ret = 6;
+			break;
 
 		case PCI_BASE_CLASS_DISPLAY:
 			ret = 9;
+			break;
 
 		case PCI_BASE_CLASS_MULTIMEDIA:
 		case PCI_BASE_CLASS_MEMORY:
 		case PCI_BASE_CLASS_BRIDGE:
 			ret = 10;
+			break;
 
 		default:
 			ret = 1;
+			break;
 		};
 	}
 
@@ -1191,17 +1196,38 @@
 	/* Make all Safari error conditions fatal except unmapped errors
 	 * which we make generate interrupts.
 	 */
+#if 1
+	/* XXX Something wrong with some Excalibur systems
+	 * XXX Sun is shipping.  The behavior on a 2-cpu
+	 * XXX machine is that both CPU1 parity error bits
+	 * XXX are set and are immediately set again when
+	 * XXX their error status bits are cleared.  Just
+	 * XXX ignore them for now.  -DaveM
+	 */
+	schizo_write(base + SCHIZO_SAFARI_ERRCTRL,
+		     (SCHIZO_SAFERRCTRL_EN |
+		      (SAFARI_ERROR_BADCMD | SAFARI_ERROR_SSMDIS |
+		       SAFARI_ERROR_BADMA | SAFARI_ERROR_BADMB |
+		       SAFARI_ERROR_BADMC |
+		       SAFARI_ERROR_CIQTO |
+		       SAFARI_ERROR_LPQTO | SAFARI_ERROR_SFPQTO |
+		       SAFARI_ERROR_UFPQTO | SAFARI_ERROR_APERR |
+		       SAFARI_ERROR_BUSERR | SAFARI_ERROR_TIMEOUT |
+		       SAFARI_ERROR_ILL)));
+#else
 	schizo_write(base + SCHIZO_SAFARI_ERRCTRL,
 		     (SCHIZO_SAFERRCTRL_EN |
 		      (SAFARI_ERROR_BADCMD | SAFARI_ERROR_SSMDIS |
 		       SAFARI_ERROR_BADMA | SAFARI_ERROR_BADMB |
-		       SAFARI_ERROR_BADMC | SAFARI_ERROR_CPU1PS |
-		       SAFARI_ERROR_CPU1PB | SAFARI_ERROR_CPU0PS |
-		       SAFARI_ERROR_CPU0PB | SAFARI_ERROR_CIQTO |
+		       SAFARI_ERROR_BADMC |
+		       SAFARI_ERROR_CPU1PS | SAFARI_ERROR_CPU1PB |
+		       SAFARI_ERROR_CPU0PS | SAFARI_ERROR_CPU0PB |
+		       SAFARI_ERROR_CIQTO |
 		       SAFARI_ERROR_LPQTO | SAFARI_ERROR_SFPQTO |
 		       SAFARI_ERROR_UFPQTO | SAFARI_ERROR_APERR |
 		       SAFARI_ERROR_BUSERR | SAFARI_ERROR_TIMEOUT |
 		       SAFARI_ERROR_ILL)));
+#endif
 
 	schizo_write(base + SCHIZO_SAFARI_IRQCTRL,
 		     (SCHIZO_SAFIRQCTRL_EN | (SAFARI_ERROR_UNMAP)));
@@ -1487,6 +1513,8 @@
 
 	request_resource(&ioport_resource, &pbm->io_space);
 	request_resource(&iomem_resource, &pbm->mem_space);
+	pci_register_legacy_regions(&pbm->io_space,
+				    &pbm->mem_space);
 }
 
 #define SCHIZO_STRBUF_CONTROL_A		(SCHIZO_PBM_A_REGS_OFF + 0x02800UL)
diff -u --recursive --new-file v2.4.5/linux/arch/sparc64/kernel/power.c linux/arch/sparc64/kernel/power.c
--- v2.4.5/linux/arch/sparc64/kernel/power.c	Tue Jul 11 15:46:08 2000
+++ linux/arch/sparc64/kernel/power.c	Tue Jun 12 11:08:46 2001
@@ -1,4 +1,4 @@
-/* $Id: power.c,v 1.8 2000/07/11 22:41:33 davem Exp $
+/* $Id: power.c,v 1.9 2001/06/08 02:28:22 davem Exp $
  * power.c: Power management driver.
  *
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -81,6 +81,11 @@
 {
 	struct linux_ebus *ebus;
 	struct linux_ebus_device *edev;
+	static int invoked = 0;
+
+	if (invoked)
+		return;
+	invoked = 1;
 
 	for_each_ebus(ebus) {
 		for_each_ebusdev(edev, ebus) {
diff -u --recursive --new-file v2.4.5/linux/arch/sparc64/kernel/process.c linux/arch/sparc64/kernel/process.c
--- v2.4.5/linux/arch/sparc64/kernel/process.c	Thu Apr 12 12:10:25 2001
+++ linux/arch/sparc64/kernel/process.c	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-/*  $Id: process.c,v 1.117 2001/03/30 07:10:41 davem Exp $
+/*  $Id: process.c,v 1.118 2001/06/03 13:41:13 ecd Exp $
  *  arch/sparc64/kernel/process.c
  *
  *  Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -111,6 +111,7 @@
 extern void (*prom_palette)(int);
 extern int serial_console;
 #endif
+extern void (*prom_keyboard)(void);
 
 void machine_halt(void)
 {
@@ -121,6 +122,8 @@
 	if (!serial_console && prom_palette)
 		prom_palette (1);
 #endif
+	if (prom_keyboard)
+		prom_keyboard();
 	prom_halt();
 	panic("Halt failed!");
 }
@@ -139,6 +142,8 @@
 	if (!serial_console && prom_palette)
 		prom_palette (1);
 #endif
+	if (prom_keyboard)
+		prom_keyboard();
 	if (cmd)
 		prom_reboot(cmd);
 	if (*reboot_command)
diff -u --recursive --new-file v2.4.5/linux/arch/sparc64/kernel/rtrap.S linux/arch/sparc64/kernel/rtrap.S
--- v2.4.5/linux/arch/sparc64/kernel/rtrap.S	Sun Mar 25 18:14:21 2001
+++ linux/arch/sparc64/kernel/rtrap.S	Tue Jun 12 11:08:46 2001
@@ -1,4 +1,4 @@
-/* $Id: rtrap.S,v 1.54 2001/03/08 22:08:51 davem Exp $
+/* $Id: rtrap.S,v 1.55 2001/06/05 09:56:06 davem Exp $
  * rtrap.S: Preparing for return from trap on Sparc V9.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -88,9 +88,8 @@
 		sethi			%hi(irq_stat), %l2	! &softirq_active
 		or			%l2, %lo(irq_stat), %l2	! &softirq_active
 		sllx			%l0, 6, %l0
-		ldx			[%l2 + %l0], %l1	! softirq_active + softirq_mask
-		srlx			%l1, 32, %l2
-		andcc			%l1, %l2, %g0
+		lduw			[%l2 + %l0], %l1	! softirq_pending
+		cmp			%l1, 0
 
 		bne,pn			%icc, __handle_softirq
 		 ldx			[%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
diff -u --recursive --new-file v2.4.5/linux/arch/sparc64/kernel/setup.c linux/arch/sparc64/kernel/setup.c
--- v2.4.5/linux/arch/sparc64/kernel/setup.c	Thu Apr 26 22:17:25 2001
+++ linux/arch/sparc64/kernel/setup.c	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-/*  $Id: setup.c,v 1.64 2001/04/24 21:10:05 davem Exp $
+/*  $Id: setup.c,v 1.65 2001/06/03 13:41:13 ecd Exp $
  *  linux/arch/sparc64/kernel/setup.c
  *
  *  Copyright (C) 1995,1996  David S. Miller (davem@caip.rutgers.edu)
@@ -64,6 +64,7 @@
 #if CONFIG_SUN_CONSOLE
 void (*prom_palette)(int);
 #endif
+void (*prom_keyboard)(void);
 asmlinkage void sys_sync(void);	/* it's really int */
 
 static void
diff -u --recursive --new-file v2.4.5/linux/arch/sparc64/kernel/sparc64_ksyms.c linux/arch/sparc64/kernel/sparc64_ksyms.c
--- v2.4.5/linux/arch/sparc64/kernel/sparc64_ksyms.c	Sun May 20 11:32:07 2001
+++ linux/arch/sparc64/kernel/sparc64_ksyms.c	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-/* $Id: sparc64_ksyms.c,v 1.107 2001/05/18 08:01:35 davem Exp $
+/* $Id: sparc64_ksyms.c,v 1.108 2001/06/05 03:39:50 davem Exp $
  * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -24,6 +24,7 @@
 #include <asm/oplib.h>
 #include <asm/delay.h>
 #include <asm/system.h>
+#include <asm/auxio.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -184,6 +185,9 @@
 EXPORT_SYMBOL(mostek_lock);
 EXPORT_SYMBOL(mstk48t02_regs);
 EXPORT_SYMBOL(request_fast_irq);
+#if CONFIG_SUN_AUXIO
+EXPORT_SYMBOL(auxio_register);
+#endif
 #if CONFIG_SBUS
 EXPORT_SYMBOL(sbus_root);
 EXPORT_SYMBOL(dma_chain);
diff -u --recursive --new-file v2.4.5/linux/arch/sparc64/kernel/sys_sparc32.c linux/arch/sparc64/kernel/sys_sparc32.c
--- v2.4.5/linux/arch/sparc64/kernel/sys_sparc32.c	Fri Apr 13 20:15:55 2001
+++ linux/arch/sparc64/kernel/sys_sparc32.c	Wed Jun 20 21:00:55 2001
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.176 2001/04/14 01:12:02 davem Exp $
+/* $Id: sys_sparc32.c,v 1.177 2001/06/10 06:48:46 davem Exp $
  * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -3493,6 +3493,7 @@
 
 #endif  /* CONFIG_MODULES */
 
+#if defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)
 /* Stuff for NFS server syscalls... */
 struct nfsctl_svc32 {
 	u16			svc32_port;
@@ -3815,6 +3816,13 @@
 		kfree(kres);
 	return err;
 }
+#else /* !NFSD */
+extern asmlinkage long sys_ni_syscall(void);
+int asmlinkage sys32_nfsservctl(int cmd, void *notused, void *notused2)
+{
+	return sys_ni_syscall();
+}
+#endif
 
 /* Translations due to time_t size differences.  Which affects all
    sorts of things, like timeval and itimerval.  */
diff -u --recursive --new-file v2.4.5/linux/arch/sparc64/kernel/time.c linux/arch/sparc64/kernel/time.c
--- v2.4.5/linux/arch/sparc64/kernel/time.c	Thu Apr 26 22:17:25 2001
+++ linux/arch/sparc64/kernel/time.c	Tue Jun 12 11:08:46 2001
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.37 2001/04/24 01:09:12 davem Exp $
+/* $Id: time.c,v 1.39 2001/06/08 02:33:37 davem Exp $
  * time.c: UltraSparc timer and TOD clock support.
  *
  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -32,6 +32,7 @@
 #include <asm/fhc.h>
 #include <asm/pbm.h>
 #include <asm/ebus.h>
+#include <asm/isa.h>
 #include <asm/starfire.h>
 
 extern rwlock_t xtime_lock;
@@ -408,7 +409,13 @@
 	unsigned long flags;
 #ifdef CONFIG_PCI
 	struct linux_ebus *ebus = NULL;
+	struct isa_bridge *isa_br = NULL;
 #endif
+	static int invoked = 0;
+
+	if (invoked)
+		return;
+	invoked = 1;
 
 
 	if (this_is_starfire) {
@@ -433,6 +440,9 @@
 	else if (ebus_chain != NULL) {
 		ebus = ebus_chain;
 		busnd = ebus->prom_node;
+	} else if (isa_chain != NULL) {
+		isa_br = isa_chain;
+		busnd = isa_br->prom_node;
 	}
 #endif
 	else if (sbus_root != NULL) {
@@ -465,6 +475,13 @@
 					node = prom_getchild(busnd);
 				}
 			}
+			while ((node == 0) && isa_br != NULL) {
+				isa_br = isa_br->next;
+				if (isa_br != NULL) {
+					busnd = isa_br->prom_node;
+					node = prom_getchild(busnd);
+				}
+			}
 #endif
 			if (node == 0) {
 				prom_printf("clock_probe: Cannot find timer chip\n");
@@ -504,6 +521,22 @@
 				mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
 			}
 			break;
+		} else if (isa_chain != NULL) {
+			struct isa_device *isadev;
+
+			for_each_isadev(isadev, isa_br)
+				if (isadev->prom_node == node)
+					break;
+			if (isadev == NULL) {
+				prom_printf("%s: Mostek not probed by ISA\n");
+				prom_halt();
+			}
+			if (!strcmp(model, "ds1287")) {
+				ds1287_regs = isadev->resource.start;
+			} else {
+				mstk48t59_regs = isadev->resource.start;
+				mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
+			}
 		}
 #endif
 		else {
diff -u --recursive --new-file v2.4.5/linux/arch/sparc64/math-emu/sfp-util.h linux/arch/sparc64/math-emu/sfp-util.h
--- v2.4.5/linux/arch/sparc64/math-emu/sfp-util.h	Mon Dec 20 22:05:52 1999
+++ linux/arch/sparc64/math-emu/sfp-util.h	Wed Jun 20 21:00:55 2001
@@ -1,4 +1,4 @@
-/* $Id: sfp-util.h,v 1.4 1999/09/20 12:14:19 jj Exp $
+/* $Id: sfp-util.h,v 1.5 2001/06/10 06:48:46 davem Exp $
  * arch/sparc64/math-emu/sfp-util.h
  *
  * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz)
@@ -12,10 +12,10 @@
 #include <asm/byteorder.h>
 
 #define add_ssaaaa(sh, sl, ah, al, bh, bl) 						\
-  __asm__ ("addcc %4,%5,%1
-  	    add %2,%3,%0
-  	    bcs,a,pn %%xcc, 1f
-  	    add %0, 1, %0
+  __asm__ ("addcc %4,%5,%1\n\
+  	    add %2,%3,%0\n\
+  	    bcs,a,pn %%xcc, 1f\n\
+  	    add %0, 1, %0\n\
   	    1:"										\
 	   : "=r" ((UDItype)(sh)),				      			\
 	     "=&r" ((UDItype)(sl))				      			\
@@ -26,10 +26,10 @@
 	   : "cc")
 	   
 #define sub_ddmmss(sh, sl, ah, al, bh, bl) 						\
-  __asm__ ("subcc %4,%5,%1
-  	    sub %2,%3,%0
-  	    bcs,a,pn %%xcc, 1f
-  	    sub %0, 1, %0
+  __asm__ ("subcc %4,%5,%1\n\
+  	    sub %2,%3,%0\n\
+  	    bcs,a,pn %%xcc, 1f\n\
+  	    sub %0, 1, %0\n\
   	    1:"										\
 	   : "=r" ((UDItype)(sh)),				      			\
 	     "=&r" ((UDItype)(sl))				      			\
@@ -43,26 +43,26 @@
   do {											\
 	  UDItype tmp1, tmp2, tmp3, tmp4;						\
 	  __asm__ __volatile__ (							\
-		   "srl %7,0,%3
-		    mulx %3,%6,%1
-		    srlx %6,32,%2
-		    mulx %2,%3,%4
-		    sllx %4,32,%5
-		    srl %6,0,%3
-		    sub %1,%5,%5
-		    srlx %5,32,%5
-		    addcc %4,%5,%4
-		    srlx %7,32,%5
-		    mulx %3,%5,%3
-		    mulx %2,%5,%5
-		    sethi %%hi(0x80000000),%2
-		    addcc %4,%3,%4
-		    srlx %4,32,%4
-		    add %2,%2,%2
-		    movcc %%xcc,%%g0,%2
-		    addcc %5,%4,%5
-		    sllx %3,32,%3
-		    add %1,%3,%1
+		   "srl %7,0,%3\n\
+		    mulx %3,%6,%1\n\
+		    srlx %6,32,%2\n\
+		    mulx %2,%3,%4\n\
+		    sllx %4,32,%5\n\
+		    srl %6,0,%3\n\
+		    sub %1,%5,%5\n\
+		    srlx %5,32,%5\n\
+		    addcc %4,%5,%4\n\
+		    srlx %7,32,%5\n\
+		    mulx %3,%5,%3\n\
+		    mulx %2,%5,%5\n\
+		    sethi %%hi(0x80000000),%2\n\
+		    addcc %4,%3,%4\n\
+		    srlx %4,32,%4\n\
+		    add %2,%2,%2\n\
+		    movcc %%xcc,%%g0,%2\n\
+		    addcc %5,%4,%5\n\
+		    sllx %3,32,%3\n\
+		    add %1,%3,%1\n\
 		    add %5,%2,%0"							\
 	   : "=r" ((UDItype)(wh)),							\
 	     "=&r" ((UDItype)(wl)),							\
diff -u --recursive --new-file v2.4.5/linux/drivers/Makefile linux/drivers/Makefile
--- v2.4.5/linux/drivers/Makefile	Wed May 16 10:27:02 2001
+++ linux/drivers/Makefile	Mon Jun 11 19:15:27 2001
@@ -7,7 +7,8 @@
 
 
 mod-subdirs :=	dio mtd sbus video macintosh usb input telephony sgi i2o ide \
-		scsi md ieee1394 pnp isdn atm fc4 net/hamradio i2c acpi
+		scsi md ieee1394 pnp isdn atm fc4 net/hamradio i2c acpi \
+		bluetooth
 
 subdir-y :=	parport char block net sound misc media cdrom
 subdir-m :=	$(subdir-y)
@@ -42,6 +43,8 @@
 subdir-$(CONFIG_HAMRADIO)	+= net/hamradio
 subdir-$(CONFIG_I2C)		+= i2c
 subdir-$(CONFIG_ACPI)		+= acpi
+
+subdir-$(CONFIG_BLUEZ)		+= bluetooth
 
 include $(TOPDIR)/Rules.make
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acorn/char/keyb_arc.c linux/drivers/acorn/char/keyb_arc.c
--- v2.4.5/linux/drivers/acorn/char/keyb_arc.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/acorn/char/keyb_arc.c	Wed Jun 27 14:12:04 2001
@@ -390,7 +390,7 @@
 		kbd_state, keyval);
 #endif
 	mdelay(1);
-	inb(IOC_KARTRX);
+	ioc_readb(IOC_KARTRX);
 	a5kkbd_sendbyte (HRST);
 	kbd_state = KBD_INITRST;
 	return 0;
@@ -407,13 +407,13 @@
 static void a5kkbd_rx(int irq, void *dev_id, struct pt_regs *regs)
 {
 	kbd_pt_regs = regs;
-	if (handle_rawcode(inb(IOC_KARTRX)))
+	if (handle_rawcode(ioc_readb(IOC_KARTRX)))
 		tasklet_schedule(&keyboard_tasklet);
 }
 
 static void a5kkbd_tx(int irq, void *dev_id, struct pt_regs *regs)
 {
-	outb (kbd_txval[kbd_txtail], IOC_KARTTX);
+	ioc_writeb (kbd_txval[kbd_txtail], IOC_KARTTX);
 	KBD_INCTXPTR(kbd_txtail);
 	if (kbd_txtail == kbd_txhead)
 		disable_irq(irq);
@@ -431,7 +431,7 @@
 
 	if (request_irq (IRQ_KEYBOARDTX, a5kkbd_tx, 0, "keyboard", NULL) != 0)
 		panic("Could not allocate keyboard transmit IRQ!");
-	(void)inb(IOC_KARTRX);
+	(void)ioc_readb(IOC_KARTRX);
 	if (request_irq (IRQ_KEYBOARDRX, a5kkbd_rx, 0, "keyboard", NULL) != 0)
 		panic("Could not allocate keyboard receive IRQ!");
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acorn/char/keyb_ps2.c linux/drivers/acorn/char/keyb_ps2.c
--- v2.4.5/linux/drivers/acorn/char/keyb_ps2.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/acorn/char/keyb_ps2.c	Wed Jun 27 14:12:04 2001
@@ -24,6 +24,7 @@
 #include <linux/random.h>
 #include <linux/ctype.h>
 #include <linux/kbd_ll.h>
+#include <linux/delay.h>
 #include <linux/init.h>
 
 #include <asm/bitops.h>
@@ -37,6 +38,12 @@
 extern void kbd_reset_kdown(void);
 int kbd_read_mask;
 
+#define TX_DONE 0
+#define TX_SENT 1
+#define TX_SEND 2
+
+static volatile int tx_state;
+
 #define VERSION 100
 
 #define KBD_REPORT_ERR
@@ -233,8 +240,33 @@
 
 static inline void ps2kbd_sendbyte(unsigned char val)
 {
-	while(!(inb(IOMD_KCTRL) & (1 << 7)));
-	outb(val, IOMD_KARTTX);
+	int tries = 3, timeout = 1000;
+
+	tx_state = TX_SEND;
+
+	do {
+		switch (tx_state) {
+		case TX_SEND:
+			tx_state = TX_SENT;
+			timeout = 1000;
+			tries --;
+
+			while(!(iomd_readb(IOMD_KCTRL) & (1 << 7)));
+			iomd_writeb(val, IOMD_KARTTX);
+			break;
+
+		case TX_SENT:
+			udelay(1000);
+			if (--timeout == 0) {
+				printk(KERN_ERR "Keyboard timeout\n");
+				tx_state = TX_DONE;
+			}
+			break;
+
+		case TX_DONE:
+			break;
+		}
+	} while (tries > 0 && tx_state != TX_DONE);
 }
 
 static unsigned char status;
@@ -254,18 +286,30 @@
 
 	if (keyval > 0x83) {
 		switch (keyval) {
-			case KBD_ESCAPEE0:
-				ncodes = 2;
-				bi = 0;
-				break;
-			case KBD_ESCAPEE1:
-				ncodes = 3;
-				bi = 0;
-				break;
-			case KBD_BREAK:
-				status |= CODE_BREAK;
-			default:
-				return;
+		case KBD_ESCAPEE0:
+			ncodes = 2;
+			bi = 0;
+			break;
+
+		case KBD_ESCAPEE1:
+			ncodes = 3;
+			bi = 0;
+			break;
+
+		case KBD_ACK:
+			tx_state = TX_DONE;
+			return;
+
+		case KBD_RESEND:
+			tx_state = TX_SEND;
+			return;
+
+		case KBD_BREAK:
+			status |= CODE_BREAK;
+			return;
+
+		default:
+			return;
 		}
 	}
 
@@ -278,6 +322,13 @@
 		switch (buffer[0] << 8 | buffer[1]) {
 		case ESCE0(0x11): keysym = K_RALT; break;
 		case ESCE0(0x14): keysym = K_RCTL; break;
+		/*
+		 * take care of MS extra keys (actually
+		 * 0x7d - 0x7f, but last one is already K_NONE
+		 */
+		case ESCE0(0x1f): keysym = 124;    break;
+		case ESCE0(0x27): keysym = 125;    break;
+		case ESCE0(0x2f): keysym = 126;    break;
 		case ESCE0(0x4a): keysym = KP_SLH; break;
 		case ESCE0(0x5a): keysym = KP_ENT; break;
 		case ESCE0(0x69): keysym = K_END;  break;
@@ -320,8 +371,8 @@
 {
 	kbd_pt_regs = regs;
 
-	while (inb(IOMD_KCTRL) & (1 << 5))
-		handle_rawcode(inb(IOMD_KARTRX));
+	while (iomd_readb(IOMD_KCTRL) & (1 << 5))
+		handle_rawcode(iomd_readb(IOMD_KARTRX));
 	tasklet_schedule(&keyboard_tasklet);
 }
 
@@ -332,10 +383,10 @@
 int __init ps2kbd_init_hw(void)
 {
 	/* Reset the keyboard state machine. */
-	outb(0, IOMD_KCTRL);
-	outb(8, IOMD_KCTRL);
+	iomd_writeb(0, IOMD_KCTRL);
+	iomd_writeb(8, IOMD_KCTRL);
+	iomd_readb(IOMD_KARTRX);
 
-	(void)IOMD_KARTRX;
 	if (request_irq (IRQ_KEYBOARDRX, ps2kbd_rx, 0, "keyboard", NULL) != 0)
 		panic("Could not allocate keyboard receive IRQ!");
 	if (request_irq (IRQ_KEYBOARDTX, ps2kbd_tx, 0, "keyboard", NULL) != 0)
diff -u --recursive --new-file v2.4.5/linux/drivers/acorn/char/mouse_ps2.c linux/drivers/acorn/char/mouse_ps2.c
--- v2.4.5/linux/drivers/acorn/char/mouse_ps2.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acorn/char/mouse_ps2.c	Wed Jun 27 14:12:04 2001
@@ -0,0 +1,289 @@
+/* 
+ * Driver for PS/2 mouse on IOMD interface
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/mm.h>
+#include <linux/malloc.h>
+#include <linux/ptrace.h>
+#include <linux/signal.h>
+#include <linux/timer.h>
+#include <linux/random.h>
+#include <linux/ctype.h>
+#include <linux/kbd_ll.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/miscdevice.h>
+
+#include <asm/bitops.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/hardware/iomd.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+/*
+ *	PS/2 Auxiliary Device
+ */
+
+static struct aux_queue *queue;	/* Mouse data buffer. */
+static int aux_count = 0;
+/* used when we send commands to the mouse that expect an ACK. */
+static unsigned char mouse_reply_expected = 0;
+
+#define MAX_RETRIES	60		/* some aux operations take long time*/
+
+/*
+ *	Mouse Commands
+ */
+
+#define AUX_SET_RES		0xE8	/* Set resolution */
+#define AUX_SET_SCALE11		0xE6	/* Set 1:1 scaling */
+#define AUX_SET_SCALE21		0xE7	/* Set 2:1 scaling */
+#define AUX_GET_SCALE		0xE9	/* Get scaling factor */
+#define AUX_SET_STREAM		0xEA	/* Set stream mode */
+#define AUX_SET_SAMPLE		0xF3	/* Set sample rate */
+#define AUX_ENABLE_DEV		0xF4	/* Enable aux device */
+#define AUX_DISABLE_DEV		0xF5	/* Disable aux device */
+#define AUX_RESET		0xFF	/* Reset aux device */
+#define AUX_ACK			0xFA	/* Command byte ACK. */
+
+#define AUX_BUF_SIZE		2048	/* This might be better divisible by
+					   three to make overruns stay in sync
+					   but then the read function would 
+					   need a lock etc - ick */
+
+struct aux_queue {
+	unsigned long head;
+	unsigned long tail;
+	wait_queue_head_t proc_list;
+	struct fasync_struct *fasync;
+	unsigned char buf[AUX_BUF_SIZE];
+};
+
+/*
+ * Send a byte to the mouse.
+ */
+static void aux_write_dev(int val)
+{
+	while (!(iomd_readb(IOMD_MSECTL) & 0x80));
+	iomd_writeb(val, IOMD_MSEDAT);
+}
+
+/*
+ * Send a byte to the mouse & handle returned ack
+ */
+static void aux_write_ack(int val)
+{
+	while (!(iomd_readb(IOMD_MSECTL) & 0x80));
+	iomd_writeb(val, IOMD_MSEDAT);
+
+	/* we expect an ACK in response. */
+	mouse_reply_expected++;
+}
+
+static unsigned char get_from_queue(void)
+{
+	unsigned char result;
+
+	result = queue->buf[queue->tail];
+	queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
+	return result;
+}
+
+static void psaux_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	int val = iomd_readb(IOMD_MSEDAT);
+
+	if (mouse_reply_expected) {
+		if (val == AUX_ACK) {
+			mouse_reply_expected--;
+			return;
+		}
+		mouse_reply_expected = 0;
+	}
+
+	add_mouse_randomness(val);
+	if (aux_count) {
+		int head = queue->head;
+
+		queue->buf[head] = val;
+		head = (head + 1) & (AUX_BUF_SIZE-1);
+		if (head != queue->tail) {
+			queue->head = head;
+			kill_fasync(&queue->fasync, SIGIO, POLL_IN);
+			wake_up_interruptible(&queue->proc_list);
+		}
+	}
+}
+
+static inline int queue_empty(void)
+{
+	return queue->head == queue->tail;
+}
+
+static int fasync_aux(int fd, struct file *filp, int on)
+{
+	int retval;
+
+	retval = fasync_helper(fd, filp, on, &queue->fasync);
+	if (retval < 0)
+		return retval;
+	return 0;
+}
+
+
+/*
+ * Random magic cookie for the aux device
+ */
+#define AUX_DEV ((void *)queue)
+
+static int release_aux(struct inode * inode, struct file * file)
+{
+	fasync_aux(-1, file, 0);
+	if (--aux_count)
+		return 0;
+	free_irq(IRQ_MOUSERX, AUX_DEV);
+	return 0;
+}
+
+/*
+ * Install interrupt handler.
+ * Enable auxiliary device.
+ */
+
+static int open_aux(struct inode * inode, struct file * file)
+{
+	if (aux_count++)
+		return 0;
+
+	queue->head = queue->tail = 0;		/* Flush input queue */
+	if (request_irq(IRQ_MOUSERX, psaux_interrupt, SA_SHIRQ, "ps/2 mouse", 
+			AUX_DEV)) {
+		aux_count--;
+		return -EBUSY;
+	}
+
+	aux_write_ack(AUX_ENABLE_DEV); /* Enable aux device */
+
+	return 0;
+}
+
+/*
+ * Put bytes from input queue to buffer.
+ */
+
+static ssize_t read_aux(struct file * file, char * buffer,
+			size_t count, loff_t *ppos)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	ssize_t i = count;
+	unsigned char c;
+
+	if (queue_empty()) {
+		if (file->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		add_wait_queue(&queue->proc_list, &wait);
+repeat:
+		current->state = TASK_INTERRUPTIBLE;
+		if (queue_empty() && !signal_pending(current)) {
+			schedule();
+			goto repeat;
+		}
+		current->state = TASK_RUNNING;
+		remove_wait_queue(&queue->proc_list, &wait);
+	}
+	while (i > 0 && !queue_empty()) {
+		c = get_from_queue();
+		put_user(c, buffer++);
+		i--;
+	}
+	if (count-i) {
+		file->f_dentry->d_inode->i_atime = CURRENT_TIME;
+		return count-i;
+	}
+	if (signal_pending(current))
+		return -ERESTARTSYS;
+	return 0;
+}
+
+/*
+ * Write to the aux device.
+ */
+
+static ssize_t write_aux(struct file * file, const char * buffer,
+			 size_t count, loff_t *ppos)
+{
+	ssize_t retval = 0;
+
+	if (count) {
+		ssize_t written = 0;
+
+		if (count > 32)
+			count = 32; /* Limit to 32 bytes. */
+		do {
+			char c;
+			get_user(c, buffer++);
+			aux_write_dev(c);
+			written++;
+		} while (--count);
+		retval = -EIO;
+		if (written) {
+			retval = written;
+			file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
+		}
+	}
+
+	return retval;
+}
+
+static unsigned int aux_poll(struct file *file, poll_table * wait)
+{
+	poll_wait(file, &queue->proc_list, wait);
+	if (!queue_empty())
+		return POLLIN | POLLRDNORM;
+	return 0;
+}
+
+struct file_operations psaux_fops = {
+	read:		read_aux,
+	write:		write_aux,
+	poll:		aux_poll,
+	open:		open_aux,
+	release:	release_aux,
+	fasync:		fasync_aux,
+};
+
+/*
+ * Initialize driver.
+ */
+static struct miscdevice psaux_mouse = {
+	PSMOUSE_MINOR, "psaux", &psaux_fops
+};
+
+int __init psaux_init(void)
+{
+	/* Reset the mouse state machine. */
+	iomd_writeb(0, IOMD_MSECTL);
+	iomd_writeb(8, IOMD_MSECTL);
+  
+	misc_register(&psaux_mouse);
+	queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
+	memset(queue, 0, sizeof(*queue));
+	queue->head = queue->tail = 0;
+	init_waitqueue_head(&queue->proc_list);
+
+	aux_write_ack(AUX_SET_SAMPLE);
+	aux_write_ack(100);			/* 100 samples/sec */
+	aux_write_ack(AUX_SET_RES);
+	aux_write_ack(3);			/* 8 counts per mm */
+	aux_write_ack(AUX_SET_SCALE21);		/* 2:1 scaling */
+
+	return 0;
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/acorn/char/mouse_rpc.c linux/drivers/acorn/char/mouse_rpc.c
--- v2.4.5/linux/drivers/acorn/char/mouse_rpc.c	Mon Sep 18 15:15:21 2000
+++ linux/drivers/acorn/char/mouse_rpc.c	Wed Jun 27 14:12:04 2001
@@ -34,9 +34,9 @@
 	short x, y, dx, dy;
 	int buttons;
 
-	x = (short)inl(IOMD_MOUSEX);
-	y = (short)inl(IOMD_MOUSEY);
-	buttons = (inl (0x800C4000) >> 4) & 7;
+	x = (short)iomd_readl(IOMD_MOUSEX);
+	y = (short)iomd_readl(IOMD_MOUSEY);
+	buttons = (__raw_readl(0xe0310000) >> 4) & 7;
 
 	dx = x - old_x;
 	old_x = x;
@@ -60,9 +60,9 @@
 	if (mousedev < 0)
 		printk("rpcmouse: could not register mouse driver\n");
 	else {
-		old_x = (short)inl(IOMD_MOUSEX);
-		old_y = (short)inl(IOMD_MOUSEY);
-		old_b = (inl (0x800C4000) >> 4) & 7;
+		old_x = (short)iomd_readl(IOMD_MOUSEX);
+		old_y = (short)iomd_readl(IOMD_MOUSEY);
+		old_b = (__raw_readl(0xe0310000) >> 4) & 7;
 		if (request_irq(IRQ_VSYNCPULSE, mouse_rpc_irq, SA_SHIRQ, "mouse", &mousedev)) {
 			printk("rpcmouse: unable to allocate VSYNC interrupt\n");
 			unregister_busmouse(mousedev);
diff -u --recursive --new-file v2.4.5/linux/drivers/acorn/net/ether1.c linux/drivers/acorn/net/ether1.c
--- v2.4.5/linux/drivers/acorn/net/ether1.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/acorn/net/ether1.c	Wed Jun 27 14:12:04 2001
@@ -75,7 +75,7 @@
 
 /* ------------------------------------------------------------------------- */
 
-static const char version[] __initdata = KERN_INFO "ether1 ethernet driver (c) 2000 Russell King v1.07\n";
+static char version[] __initdata = "ether1 ethernet driver (c) 2000 Russell King v1.07\n";
 
 #define BUS_16 16
 #define BUS_8  8
@@ -990,7 +990,7 @@
 	static unsigned int version_printed = 0;
 
 	if (net_debug && version_printed++ == 0)
-		printk (version);
+		printk(KERN_INFO "%s", version);
 }
 
 static struct net_device * __init ether1_init_one(struct expansion_card *ec)
@@ -1045,7 +1045,6 @@
 release:
 	release_region(dev->base_addr, 16);
 	release_region(dev->base_addr + 0x800, 4096);
-free:
 	unregister_netdev(dev);
 	kfree(dev);
 out:
diff -u --recursive --new-file v2.4.5/linux/drivers/acorn/net/ether3.c linux/drivers/acorn/net/ether3.c
--- v2.4.5/linux/drivers/acorn/net/ether3.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/acorn/net/ether3.c	Wed Jun 27 14:12:04 2001
@@ -70,7 +70,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-static const char version[] __initdata = "ether3 ethernet driver (c) 1995-2000 R.M.King v1.17\n";
+static char version[] __initdata = "ether3 ethernet driver (c) 1995-2000 R.M.King v1.17\n";
 
 #include "ether3.h"
 
@@ -777,7 +777,7 @@
 	static unsigned version_printed = 0;
 
 	if (net_debug && version_printed++ == 0)
-		printk(version);
+		printk(KERN_INFO "%s", version);
 }
 
 static const char * __init
diff -u --recursive --new-file v2.4.5/linux/drivers/acorn/scsi/acornscsi.c linux/drivers/acorn/scsi/acornscsi.c
--- v2.4.5/linux/drivers/acorn/scsi/acornscsi.c	Fri Mar  2 18:38:37 2001
+++ linux/drivers/acorn/scsi/acornscsi.c	Wed Jun 27 14:12:04 2001
@@ -144,6 +144,7 @@
 #include <linux/ioport.h>
 #include <linux/blk.h>
 #include <linux/delay.h>
+#include <linux/init.h>
 
 #include <asm/bitops.h>
 #include <asm/system.h>
@@ -157,6 +158,8 @@
 #include "acornscsi.h"
 #include "msgqueue.h"
 
+#include <scsi/scsicam.h>
+
 #define VER_MAJOR 2
 #define VER_MINOR 0
 #define VER_PATCH 6
@@ -206,24 +209,24 @@
 static inline void
 sbic_arm_write(unsigned int io_port, int reg, int value)
 {
-    outb_t(reg, io_port);
-    outb_t(value, io_port + 4);
+    __raw_writeb(reg, io_port);
+    __raw_writeb(value, io_port + 4);
 }
 
 #define sbic_arm_writenext(io,val) \
-	outb_t((val), (io) + 4)
+	__raw_writeb((val), (io) + 4)
 
 static inline
 int sbic_arm_read(unsigned int io_port, int reg)
 {
     if(reg == ASR)
-	   return inl_t(io_port) & 255;
-    outb_t(reg, io_port);
-    return inl_t(io_port + 4) & 255;
+	   return __raw_readl(io_port) & 255;
+    __raw_writeb(reg, io_port);
+    return __raw_readl(io_port + 4) & 255;
 }
 
 #define sbic_arm_readnext(io) \
-	inb_t((io) + 4)
+	__raw_readb((io) + 4)
 
 #ifdef USE_DMAC
 #define dmac_read(io_port,reg) \
@@ -2858,7 +2861,7 @@
  * Params   : host - host to setup
  */
 static
-void acornscsi_init(AS_Host *host)
+void acornscsi_host_init(AS_Host *host)
 {
     memset(&host->stats, 0, sizeof (host->stats));
     queue_initialise(&host->queues.issue);
@@ -2926,7 +2929,7 @@
 	    host->scsi.irq = NO_IRQ;
 	}
 
-	acornscsi_init(host);
+	acornscsi_host_init(host);
 
 	++count;
     }
@@ -3118,9 +3121,40 @@
     return pos;
 }
 
-#ifdef MODULE
+static Scsi_Host_Template acornscsi_template = {
+	module:			THIS_MODULE,
+	proc_info:		acornscsi_proc_info,
+	name:			"AcornSCSI",
+	detect:			acornscsi_detect,
+	release:		acornscsi_release,
+	info:			acornscsi_info,
+	queuecommand:		acornscsi_queuecmd,
+	abort:			acornscsi_abort,
+	reset:			acornscsi_reset,
+	bios_param:		scsicam_bios_param,
+	can_queue:		16,
+	this_id:		7,
+	sg_tablesize:		SG_ALL,
+	cmd_per_lun:		2,
+	unchecked_isa_dma:	0,
+	use_clustering:		DISABLE_CLUSTERING
+};
 
-Scsi_Host_Template driver_template = ACORNSCSI_3;
+static int __init acornscsi_init(void)
+{
+	acornscsi_template.module = THIS_MODULE;
+	scsi_register_module(MODULE_SCSI_HA, &acornscsi_template);
+	if (acornscsi_template.present)
+		return 0;
 
-#include "../../scsi/scsi_module.c"
-#endif
+	scsi_unregister_module(MODULE_SCSI_HA, &acornscsi_template);
+	return -ENODEV;
+}
+
+static void __exit acornscsi_exit(void)
+{
+	scsi_unregister_module(MODULE_SCSI_HA, &acornscsi_template);
+}
+
+module_init(acornscsi_init);
+module_exit(acornscsi_exit);
diff -u --recursive --new-file v2.4.5/linux/drivers/acorn/scsi/acornscsi.h linux/drivers/acorn/scsi/acornscsi.h
--- v2.4.5/linux/drivers/acorn/scsi/acornscsi.h	Mon Sep 18 15:15:22 2000
+++ linux/drivers/acorn/scsi/acornscsi.h	Wed Jun 27 14:12:04 2001
@@ -12,52 +12,6 @@
 #ifndef ACORNSCSI_H
 #define ACORNSCSI_H
 
-#ifndef ASM
-extern int acornscsi_detect (Scsi_Host_Template *);
-extern int acornscsi_release (struct Scsi_Host *);
-extern const char *acornscsi_info (struct Scsi_Host *);
-extern int acornscsi_queuecmd (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-extern int acornscsi_abort (Scsi_Cmnd *);
-extern int acornscsi_reset (Scsi_Cmnd *, unsigned int);
-extern int acornscsi_proc_info (char *, char **, off_t, int, int, int);
-extern int acornscsi_biosparam (Disk *, kdev_t, int []);
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 2
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 16
-#endif
-
-#include "linux/proc_fs.h"
-
-#include <scsi/scsicam.h>
-
-#define ACORNSCSI_3 {							\
-proc_info:		acornscsi_proc_info,				\
-name:			"AcornSCSI",					\
-detect:			acornscsi_detect,				\
-release:		acornscsi_release,	/* Release */		\
-info:			acornscsi_info,					\
-queuecommand:		acornscsi_queuecmd,				\
-abort:			acornscsi_abort,				\
-reset:			acornscsi_reset,				\
-bios_param:		scsicam_bios_param,				\
-can_queue:		CAN_QUEUE,		/* can_queue */		\
-this_id:		7,			/* this id */		\
-sg_tablesize:		SG_ALL,			/* sg_tablesize */	\
-cmd_per_lun:		CMD_PER_LUN,		/* cmd_per_lun */	\
-unchecked_isa_dma:	0,			/* unchecked isa dma */	\
-use_clustering:		DISABLE_CLUSTERING				\
-	}
-
-#ifndef HOSTS_C
-
 /* SBIC registers */
 #define OWNID			0
 #define OWNID_FS1		(1<<7)
@@ -405,7 +359,4 @@
     struct status_entry status[9][STATUS_BUFFER_SIZE];
 } AS_Host;
 
-#endif /* ndef HOSTS_C */
-
-#endif /* ndef ASM */
 #endif /* ACORNSCSI_H */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/Config.in linux/drivers/acpi/Config.in
--- v2.4.5/linux/drivers/acpi/Config.in	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/Config.in	Wed Jun 20 17:47:39 2001
@@ -0,0 +1,17 @@
+#
+# ACPI configuration
+#
+#mainmenu_option next_comment
+#comment 'ACPI Configuration'
+
+dep_bool     '    ACPI Debug Statements' CONFIG_ACPI_DEBUG $CONFIG_ACPI
+dep_tristate '    ACPI Bus Manager' CONFIG_ACPI_BUSMGR $CONFIG_ACPI
+
+dep_tristate '      System' CONFIG_ACPI_SYS $CONFIG_ACPI_BUSMGR $CONFIG_ACPI
+dep_tristate '      Processor' CONFIG_ACPI_CPU $CONFIG_ACPI_BUSMGR $CONFIG_ACPI
+dep_tristate '      Button' CONFIG_ACPI_BUTTON $CONFIG_ACPI_BUSMGR $CONFIG_ACPI
+dep_tristate '      AC Adapter' CONFIG_ACPI_AC $CONFIG_ACPI_BUSMGR $CONFIG_ACPI
+dep_tristate '      Embedded Controller' CONFIG_ACPI_EC $CONFIG_ACPI_BUSMGR $CONFIG_ACPI
+dep_tristate '      Control Method Battery' CONFIG_ACPI_CMBATT $CONFIG_ACPI_BUSMGR $CONFIG_ACPI $CONFIG_ACPI_EC
+dep_tristate '      Thermal' CONFIG_ACPI_THERMAL $CONFIG_ACPI_BUSMGR $CONFIG_ACPI  $CONFIG_ACPI_EC
+#endmenu
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/Makefile linux/drivers/acpi/Makefile
--- v2.4.5/linux/drivers/acpi/Makefile	Sat Mar  3 17:46:47 2001
+++ linux/drivers/acpi/Makefile	Wed Jun 20 17:47:39 2001
@@ -1,13 +1,15 @@
 #
 # Makefile for the Linux ACPI interpreter
-#
+# (It's a mess, but it's all here for a reason.)
+# 
 
 O_TARGET := acpi.o
 
 export-objs := acpi_ksyms.o
 
 export ACPI_CFLAGS
-ACPI_CFLAGS := -D_LINUX
+
+ACPI_CFLAGS := -D_LINUX -I$(CURDIR)/include
 
 #
 # CONFIG_ACPI_KERNEL_CONFIG is currently only IA64
@@ -16,25 +18,37 @@
   ACPI_CFLAGS += -DCONFIG_ACPI_KERNEL_CONFIG_ONLY
 endif
 
-EXTRA_CFLAGS += -I./include
+acpi-subdirs := utilities dispatcher events hardware \
+		executer namespace parser resources tables
 
-EXTRA_CFLAGS += $(ACPI_CFLAGS)
+ifdef CONFIG_ACPI_DEBUG
+  ACPI_CFLAGS += -DACPI_DEBUG -Wno-unused #-DENABLE_DEBUGGER
+
+  #acpi-subdirs += debugger
+endif
 
-acpi-subdirs := common dispatcher events hardware \
-		interpreter namespace parser resources tables
+EXTRA_CFLAGS += $(ACPI_CFLAGS)
 
-subdir-$(CONFIG_ACPI) += $(acpi-subdirs)
+mod-subdirs  := ospm
 
-obj-$(CONFIG_ACPI) := $(patsubst %,%.o,$(acpi-subdirs))
-obj-$(CONFIG_ACPI) += os.o acpi_ksyms.o
+subdir-$(CONFIG_ACPI) 		+= $(acpi-subdirs)
+subdir-$(CONFIG_ACPI_BUSMGR)	+= ospm
 
+obj-$(CONFIG_ACPI)	+= os.o acpi_ksyms.o
+obj-$(CONFIG_ACPI)	+= $(foreach dir,$(acpi-subdirs),$(dir)/$(dir).o) 
 ifdef CONFIG_ACPI_KERNEL_CONFIG
-  obj-$(CONFIG_ACPI) += acpiconf.o osconf.o
+   obj-$(CONFIG_ACPI) 	+= acpiconf.o osconf.o
 else
-  obj-$(CONFIG_ACPI) += driver.o cmbatt.o cpu.o ec.o acpi_ksyms.o sys.o table.o power.o
+   obj-$(CONFIG_ACPI)	+= driver.o
 endif
 
-include $(TOPDIR)/Rules.make
+ifeq ($(CONFIG_ACPI_BUSMGR),y)
+	obj-y			+= ospm/ospm.o
+endif
 
-clean:
-	$(RM) *.o */*.o
+# commented out until we distribute it -ASG
+#ifeq ($(CONFIG_KDB),y)
+#	obj-m	+= kdb/kdbm_acpi.o
+#endif
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/acpi_ksyms.c linux/drivers/acpi/acpi_ksyms.c
--- v2.4.5/linux/drivers/acpi/acpi_ksyms.c	Fri Feb 16 16:06:17 2001
+++ linux/drivers/acpi/acpi_ksyms.c	Wed Jun 20 17:47:39 2001
@@ -18,6 +18,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -27,6 +28,7 @@
 #include "acdebug.h"
 
 extern int acpi_in_debugger;
+extern FADT_DESCRIPTOR acpi_fadt;
 
 #define _COMPONENT	OS_DEPENDENT
 	MODULE_NAME	("symbols")
@@ -55,9 +57,7 @@
 EXPORT_SYMBOL(debug_print_raw);
 EXPORT_SYMBOL(debug_print_prefix);
 
-EXPORT_SYMBOL(acpi_cm_strncmp);
-EXPORT_SYMBOL(acpi_cm_memcpy);
-EXPORT_SYMBOL(acpi_cm_memset);
+EXPORT_SYMBOL(acpi_ut_format_exception);
 
 EXPORT_SYMBOL(acpi_get_handle);
 EXPORT_SYMBOL(acpi_get_parent);
@@ -66,6 +66,7 @@
 EXPORT_SYMBOL(acpi_get_object_info);
 EXPORT_SYMBOL(acpi_get_next_object);
 EXPORT_SYMBOL(acpi_evaluate_object);
+EXPORT_SYMBOL(acpi_get_table);
 
 EXPORT_SYMBOL(acpi_install_notify_handler);
 EXPORT_SYMBOL(acpi_remove_notify_handler);
@@ -73,6 +74,11 @@
 EXPORT_SYMBOL(acpi_remove_gpe_handler);
 EXPORT_SYMBOL(acpi_install_address_space_handler);
 EXPORT_SYMBOL(acpi_remove_address_space_handler);
+EXPORT_SYMBOL(acpi_install_fixed_event_handler);
+EXPORT_SYMBOL(acpi_remove_fixed_event_handler);
+
+EXPORT_SYMBOL(acpi_acquire_global_lock);
+EXPORT_SYMBOL(acpi_release_global_lock);
 
 EXPORT_SYMBOL(acpi_get_current_resources);
 EXPORT_SYMBOL(acpi_get_possible_resources);
@@ -81,3 +87,20 @@
 EXPORT_SYMBOL(acpi_enable_event);
 EXPORT_SYMBOL(acpi_disable_event);
 EXPORT_SYMBOL(acpi_clear_event);
+
+EXPORT_SYMBOL(acpi_get_timer_duration);
+EXPORT_SYMBOL(acpi_get_timer);
+
+EXPORT_SYMBOL(acpi_os_signal_semaphore);
+EXPORT_SYMBOL(acpi_os_create_semaphore);
+EXPORT_SYMBOL(acpi_os_delete_semaphore);
+EXPORT_SYMBOL(acpi_os_wait_semaphore);
+
+EXPORT_SYMBOL(acpi_os_in32);
+EXPORT_SYMBOL(acpi_os_out32);
+EXPORT_SYMBOL(acpi_fadt);
+EXPORT_SYMBOL(acpi_hw_register_bit_access);
+EXPORT_SYMBOL(acpi_hw_obtain_sleep_type_register_data);
+EXPORT_SYMBOL(acpi_enter_sleep_state);
+EXPORT_SYMBOL(acpi_get_system_info);
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/cmbatt.c linux/drivers/acpi/cmbatt.c
--- v2.4.5/linux/drivers/acpi/cmbatt.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/cmbatt.c	Wed Dec 31 16:00:00 1969
@@ -1,390 +0,0 @@
-/*
- *  cmbatt.c - Control Method Battery driver
- *
- *  Copyright (C) 2000 Andrew Grover
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-/*
- * Changes:
- * Brendan Burns <bburns@wso.williams.edu> 2000-11-15
- * - added proc battery interface
- * - parse returned data from _BST and _BIF
- * Andy Grover <andrew.grover@intel.com> 2000-12-8
- * - improved proc interface
- * Pavel Machek <pavel@suse.cz> 2001-1-31
- * - fixed oops on NULLs in return from _BIF
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include "acpi.h"
-#include "driver.h"
-
-#define _COMPONENT	OS_DEPENDENT
-	MODULE_NAME	("cmbatt")
-
-/* ACPI-specific defines */
-#define ACPI_CMBATT_HID		"PNP0C0A"
-#define ACPI_BATT_PRESENT	0x10
-#define ACPI_BATT_UNKNOWN	0xFFFFFFFF
-
-/* driver-specific defines */
-#define MAX_CM_BATTERIES	0x8
-#define MAX_BATT_STRLEN		0x20
-
-#define Xstrncpy(a, b, c) if (b) strncpy(a,b,c); else strncpy(a, "unknown", c)
-
-struct cmbatt_info
-{
-	u32  power_unit;
-	u32  design_capacity;
-	u32  last_full_capacity;
-	u32  battery_technology;
-	u32  design_voltage;
-	u32  design_capacity_warning;
-	u32  design_capacity_low;
-	u32  battery_capacity_granularity_1;
-	u32  battery_capacity_granularity_2;
-
-	char model_number[MAX_BATT_STRLEN];
-	char serial_number[MAX_BATT_STRLEN];
-	char battery_type[MAX_BATT_STRLEN];
-	char oem_info[MAX_BATT_STRLEN];
-};
-
-struct cmbatt_context
-{
-	u32			is_present;
-	ACPI_HANDLE		handle;
-	char			UID[9];
-	char			*power_unit;
-	struct cmbatt_info	info;
-};
-
-struct cmbatt_status
-{
-	u32			state;
-	u32			present_rate;
-	u32			remaining_capacity;
-	u32			present_voltage;
-};
-
-static u32 batt_count = 0;
-
-static struct cmbatt_context batt_list[MAX_CM_BATTERIES];
-
-static ACPI_STATUS
-acpi_get_battery_status(ACPI_HANDLE handle, struct cmbatt_status *result)
-{
-	ACPI_OBJECT       *obj;
-	ACPI_OBJECT       *objs;
-	ACPI_BUFFER       buf;
-
-	buf.length = 0;
-	buf.pointer = NULL;		
-
-	/* determine buffer length needed */
-	if (acpi_evaluate_object(handle, "_BST", NULL, &buf) != AE_BUFFER_OVERFLOW) {
-		printk(KERN_ERR "Cmbatt: Could not get battery status struct length\n");
-		return AE_NOT_FOUND;
-	}
-
-	buf.pointer = kmalloc(buf.length, GFP_KERNEL);
-	if (!buf.pointer)
-		return AE_NO_MEMORY;
-
-	/* get the data */
-	if (!ACPI_SUCCESS(acpi_evaluate_object(handle, "_BST", NULL, &buf))) {
-		printk(KERN_ERR "Cmbatt: Could not get battery status\n");
-		kfree (buf.pointer);
-		return AE_NOT_FOUND;
-	}
-
-	obj = (ACPI_OBJECT *) buf.pointer;
-	objs = obj->package.elements;
-
-	result->state = objs[0].integer.value;
-	result->present_rate = objs[1].integer.value;
-	result->remaining_capacity = objs[2].integer.value;
-	result->present_voltage = objs[3].integer.value;
-
-	kfree(buf.pointer);
-
-	return AE_OK;
-}
-
-static ACPI_STATUS
-acpi_get_battery_info(ACPI_HANDLE handle, struct cmbatt_info *result)
-{
-	ACPI_OBJECT       *obj;
-	ACPI_OBJECT       *objs;
-	ACPI_BUFFER       buf;
-
-	buf.length = 0;
-	buf.pointer = NULL;
-
-	/* determine the length of the data */
-	if (acpi_evaluate_object(handle, "_BIF", NULL, &buf) != AE_BUFFER_OVERFLOW) {
-		printk(KERN_ERR "Cmbatt: Could not get battery info struct length\n");
-		return AE_NOT_FOUND;
-	}
-
-	buf.pointer = kmalloc(buf.length, GFP_KERNEL);
-	if (!buf.pointer)
-		return AE_NO_MEMORY;
-
-	/* get the data */
-	if (!ACPI_SUCCESS(acpi_evaluate_object(handle, "_BIF", NULL, &buf))) {
-		printk(KERN_ERR "Cmbatt: Could not get battery info\n");
-		kfree (buf.pointer);
-		return AE_NOT_FOUND;
-	}
-	
-	obj = (ACPI_OBJECT *) buf.pointer;
-	objs = obj->package.elements;
-	
-	result->power_unit=objs[0].integer.value;
-	result->design_capacity=objs[1].integer.value;
-	result->last_full_capacity=objs[2].integer.value;
-	result->battery_technology=objs[3].integer.value;
-	result->design_voltage=objs[4].integer.value;
-	result->design_capacity_warning=objs[5].integer.value;
-	result->design_capacity_low=objs[6].integer.value;
-	result->battery_capacity_granularity_1=objs[7].integer.value;
-	result->battery_capacity_granularity_2=objs[8].integer.value;
-
- 	/* BUG: trailing NULL issue */
-	Xstrncpy(result->model_number, objs[9].string.pointer, MAX_BATT_STRLEN-1);
-	Xstrncpy(result->serial_number, objs[10].string.pointer, MAX_BATT_STRLEN-1);
-	Xstrncpy(result->battery_type, objs[11].string.pointer, MAX_BATT_STRLEN-1);
-	Xstrncpy(result->oem_info, objs[12].string.pointer, MAX_BATT_STRLEN-1);
-	
-	kfree(buf.pointer);
-
-	return AE_OK;
-}
-
-/*
- * We found a device with the correct HID
- */
-static ACPI_STATUS
-acpi_found_cmbatt(ACPI_HANDLE handle, u32 level, void *ctx, void **value)
-{
-	ACPI_DEVICE_INFO	info;
-
-	if (batt_count >= MAX_CM_BATTERIES) {
-		printk(KERN_ERR "Cmbatt: MAX_CM_BATTERIES exceeded\n");
-		return AE_OK;
-	}
-
-	if (!ACPI_SUCCESS(acpi_get_object_info(handle, &info))) {
-		printk(KERN_ERR "Cmbatt: Could not get battery object info\n");
-		return (AE_OK);
-	}
-
-	if (info.valid & ACPI_VALID_UID) {
-		strncpy(batt_list[batt_count].UID, info.unique_id, 9);
-	}
-	else if (batt_count > 1) {
-		printk(KERN_WARNING "Cmbatt: No UID but more than 1 battery\n");
-	}
-	
-	if (!(info.valid & ACPI_VALID_STA)) {
-		printk(KERN_ERR "Cmbatt: Battery _STA invalid\n");
-		return AE_OK;
-	}
-
-	if (!(info.current_status & ACPI_BATT_PRESENT)) {
-		printk(KERN_INFO "Cmbatt: Battery socket %d empty\n", batt_count);
-		batt_list[batt_count].is_present = FALSE;
-	}
-	else {
-		printk(KERN_INFO "Cmbatt: Battery socket %d occupied\n", batt_count);
-		batt_list[batt_count].is_present = TRUE;
-		if (acpi_get_battery_info(handle, &batt_list[batt_count].info) != AE_OK) {
-			printk(KERN_ERR "acpi_get_battery_info failed\n");
-			return AE_OK;
-		}
-
-		batt_list[batt_count].power_unit = (batt_list[batt_count].info.power_unit) ? "mA" : "mW";
-	}
-	
-	batt_list[batt_count].handle = handle;
-
-	batt_count++;
-
-	return AE_OK;
-}
-
-static int
-proc_read_batt_info(char *page, char **start, off_t off,
-			int count, int *eof, void *data)
-{
-	struct cmbatt_info *info;
-	u32 batt_num = (u32) data;
-	char *p = page;
-	int len;
-
-	info = &batt_list[batt_num].info;
-
-	/* don't get info more than once for a single proc read */
-	if (off != 0)
-		goto end;
-
-	if (!batt_list[batt_num].is_present) {
-		p += sprintf(p, "battery %d not present\n", batt_num);
-		goto end;
-	}
-
-	if (info->last_full_capacity != ACPI_BATT_UNKNOWN)
-		p += sprintf(p, "Last Full Capacity: %d %sh\n", 
-		     info->last_full_capacity, batt_list[batt_num].power_unit);
-
-	if (info->design_capacity != ACPI_BATT_UNKNOWN)
-		p += sprintf(p, "Design Capacity:    %d %sh\n", 
-		     info->design_capacity, batt_list[batt_num].power_unit);
-	
-	if (info->battery_technology)
-		p += sprintf(p, "Battery Technology: Secondary\n");
-	else
-		p += sprintf(p, "Battery Technology: Primary\n");
-	
-	if (info->design_voltage != ACPI_BATT_UNKNOWN)
-		p += sprintf(p, "Design Voltage:     %d mV\n", 
-		     info->design_voltage);
-	
-	p += sprintf(p, "Design Capacity Warning:    %d %sh\n",
-		info->design_capacity_warning, batt_list[batt_num].power_unit);
-	p += sprintf(p, "Design Capacity Low:        %d %sh\n",
-		info->design_capacity_low, batt_list[batt_num].power_unit);
-	p += sprintf(p, "Battery Capacity Granularity 1: %d\n",
-		info->battery_capacity_granularity_1);
-	p += sprintf(p, "Battery Capacity Granularity 2: %d\n",
-		info->battery_capacity_granularity_2);
-	p += sprintf(p, "Model number; %s\nSerial number: %s\nBattery type: %s\nOEM info: %s\n",
-		info->model_number,info->serial_number,
-		info->battery_type,info->oem_info);
-end:
-	len = (p - page);
-	if (len <= off+count) *eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len>count) len = count;
-	if (len<0) len = 0;
-	return len;
-}
-
-static int
-proc_read_batt_status(char *page, char **start, off_t off,
-			int count, int *eof, void *data)
-{
-	struct cmbatt_status status;
-	u32 batt_num = (u32) data;
-	char *p = page;
-	int len;
-
-	/* don't get status more than once for a single proc read */
-	if (off != 0)
-		goto end;
-
-	if (!batt_list[batt_num].is_present) {
-		p += sprintf(p, "battery %d not present\n", batt_num);
-		goto end;
-	}
-
-	if (acpi_get_battery_status(batt_list[batt_num].handle, &status) != AE_OK) {
-		printk(KERN_ERR "Cmbatt: acpi_get_battery_status failed\n");
-		goto end;
-	}
-
-	p += sprintf(p, "Battery discharging:        %s\n",
-		     (status.state & 0x1)?"yes":"no");
-	p += sprintf(p, "Battery charging:           %s\n",
-		     (status.state & 0x2)?"yes":"no");
-	p += sprintf(p, "Battery critically low:     %s\n",
-		     (status.state & 0x4)?"yes":"no");
-
-	if (status.present_rate != ACPI_BATT_UNKNOWN)
-		p += sprintf(p, "Battery rate:               %d %s\n",
-			status.present_rate, batt_list[batt_num].power_unit);
-
-	if (status.remaining_capacity != ACPI_BATT_UNKNOWN)
-		p += sprintf(p, "Battery capacity:           %d %sh\n",
-			status.remaining_capacity, batt_list[batt_num].power_unit);
-
-	if (status.present_voltage != ACPI_BATT_UNKNOWN)
-		p += sprintf(p, "Battery voltage:            %d mV\n",
-			status.present_voltage);
-
-end:
-
-	len = (p - page);
-	if (len <= off+count) *eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len>count) len = count;
-	if (len<0) len = 0;
-	return len;
-}
-
-
-
-int
-acpi_cmbatt_init(void)
-{
-	int i;
-
-	acpi_get_devices(ACPI_CMBATT_HID, 
-			acpi_found_cmbatt,
-			NULL,
-			NULL);
-
-	for (i = 0; i < batt_count; i++) {
-
-		char batt_name[20];
-
-		sprintf(batt_name, "power/batt%d_info", i);
-		create_proc_read_entry(batt_name, 0, NULL,
-			proc_read_batt_info, (void *) i);
-
-		sprintf(batt_name, "power/batt%d_status", i);
-		create_proc_read_entry(batt_name, 0, NULL,
-			proc_read_batt_status, (void *) i);
-
-	}
-
-	return 0;
-}
-
-int
-acpi_cmbatt_terminate(void)
-{
-	int i;
-
-	for (i = 0; i < batt_count; i++) {
-
-		char batt_name[20];
-
-		sprintf(batt_name, "power/batt%d_info", i);
-		remove_proc_entry(batt_name, NULL);
-
-		sprintf(batt_name, "power/batt%d_status", i);
-		remove_proc_entry(batt_name, NULL);
-	}
-
-	return 0;
-}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/common/Makefile linux/drivers/acpi/common/Makefile
--- v2.4.5/linux/drivers/acpi/common/Makefile	Fri Dec 29 14:07:21 2000
+++ linux/drivers/acpi/common/Makefile	Wed Dec 31 16:00:00 1969
@@ -1,16 +0,0 @@
-#
-# Makefile for all Linux ACPI interpreter subdirectories
-#
-
-O_TARGET := ../$(shell basename `pwd`).o
-
-obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c))
-
-EXTRA_CFLAGS += -I../include
-
-EXTRA_CFLAGS += $(ACPI_CFLAGS)
-
-include $(TOPDIR)/Rules.make
-
-clean:
-	$(RM) *.o 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/common/cmalloc.c linux/drivers/acpi/common/cmalloc.c
--- v2.4.5/linux/drivers/acpi/common/cmalloc.c	Mon Jan 29 10:15:58 2001
+++ linux/drivers/acpi/common/cmalloc.c	Wed Dec 31 16:00:00 1969
@@ -1,170 +0,0 @@
-/******************************************************************************
- *
- * Module Name: cmalloc - local memory allocation routines
- *              $Revision: 84 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acparser.h"
-#include "acinterp.h"
-#include "acnamesp.h"
-#include "acglobal.h"
-
-#define _COMPONENT          MISCELLANEOUS
-	 MODULE_NAME         ("cmalloc")
-
-
-/*****************************************************************************
- *
- * FUNCTION:    _Cm_allocate
- *
- * PARAMETERS:  Size                - Size of the allocation
- *              Component           - Component type of caller
- *              Module              - Source file name of caller
- *              Line                - Line number of caller
- *
- * RETURN:      Address of the allocated memory on success, NULL on failure.
- *
- * DESCRIPTION: The subsystem's equivalent of malloc.
- *
- ****************************************************************************/
-
-void *
-_cm_allocate (
-	u32                     size,
-	u32                     component,
-	NATIVE_CHAR             *module,
-	u32                     line)
-{
-	void                    *address = NULL;
-
-
-	/* Check for an inadvertent size of zero bytes */
-
-	if (!size) {
-		_REPORT_ERROR (module, line, component,
-				("Cm_allocate: Attempt to allocate zero bytes\n"));
-		size = 1;
-	}
-
-	address = acpi_os_allocate (size);
-	if (!address) {
-		/* Report allocation error */
-
-		_REPORT_ERROR (module, line, component,
-				("Cm_allocate: Could not allocate size %X\n", size));
-
-		return (NULL);
-	}
-
-
-	return (address);
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    _Cm_callocate
- *
- * PARAMETERS:  Size                - Size of the allocation
- *              Component           - Component type of caller
- *              Module              - Source file name of caller
- *              Line                - Line number of caller
- *
- * RETURN:      Address of the allocated memory on success, NULL on failure.
- *
- * DESCRIPTION: Subsystem equivalent of calloc.
- *
- ****************************************************************************/
-
-void *
-_cm_callocate (
-	u32                     size,
-	u32                     component,
-	NATIVE_CHAR             *module,
-	u32                     line)
-{
-	void                    *address = NULL;
-
-
-	/* Check for an inadvertent size of zero bytes */
-
-	if (!size) {
-		_REPORT_ERROR (module, line, component,
-				("Cm_callocate: Attempt to allocate zero bytes\n"));
-		return (NULL);
-	}
-
-
-	address = acpi_os_callocate (size);
-
-	if (!address) {
-		/* Report allocation error */
-
-		_REPORT_ERROR (module, line, component,
-				("Cm_callocate: Could not allocate size %X\n", size));
-		return (NULL);
-	}
-
-
-	return (address);
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    _Cm_free
- *
- * PARAMETERS:  Address             - Address of the memory to deallocate
- *              Component           - Component type of caller
- *              Module              - Source file name of caller
- *              Line                - Line number of caller
- *
- * RETURN:      None
- *
- * DESCRIPTION: Frees the memory at Address
- *
- ****************************************************************************/
-
-void
-_cm_free (
-	void                    *address,
-	u32                     component,
-	NATIVE_CHAR             *module,
-	u32                     line)
-{
-
-	if (NULL == address) {
-		_REPORT_ERROR (module, line, component,
-			("_Cm_free: Trying to delete a NULL address\n"));
-
-		return;
-	}
-
-
-	acpi_os_free (address);
-
-	return;
-}
-
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/common/cmclib.c linux/drivers/acpi/common/cmclib.c
--- v2.4.5/linux/drivers/acpi/common/cmclib.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/common/cmclib.c	Wed Dec 31 16:00:00 1969
@@ -1,818 +0,0 @@
-/******************************************************************************
- *
- * Module Name: cmclib - Local implementation of C library functions
- * $Revision: 32 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acevents.h"
-#include "achware.h"
-#include "acnamesp.h"
-#include "acinterp.h"
-#include "amlcode.h"
-
-/*
- * These implementations of standard C Library routines can optionally be
- * used if a C library is not available.  In general, they are less efficient
- * than an inline or assembly implementation
- */
-
-#define _COMPONENT          MISCELLANEOUS
-	 MODULE_NAME         ("cmclib")
-
-
-#ifndef ACPI_USE_SYSTEM_CLIBRARY
-
-/*******************************************************************************
- *
- * FUNCTION:    strlen
- *
- * PARAMETERS:  String              - Null terminated string
- *
- * RETURN:      Length
- *
- * DESCRIPTION: Returns the length of the input string
- *
- ******************************************************************************/
-
-
-NATIVE_UINT
-acpi_cm_strlen (
-	const NATIVE_CHAR       *string)
-{
-	NATIVE_UINT             length = 0;
-
-
-	/* Count the string until a null is encountered */
-
-	while (*string) {
-		length++;
-		string++;
-	}
-
-	return (length);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    strcpy
- *
- * PARAMETERS:  Dst_string      - Target of the copy
- *              Src_string      - The source string to copy
- *
- * RETURN:      Dst_string
- *
- * DESCRIPTION: Copy a null terminated string
- *
- ******************************************************************************/
-
-NATIVE_CHAR *
-acpi_cm_strcpy (
-	NATIVE_CHAR             *dst_string,
-	const NATIVE_CHAR       *src_string)
-{
-	NATIVE_CHAR             *string = dst_string;
-
-
-	/* Move bytes brute force */
-
-	while (*src_string) {
-		*string = *src_string;
-
-		string++;
-		src_string++;
-	}
-
-	/* Null terminate */
-
-	*string = 0;
-
-	return (dst_string);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    strncpy
- *
- * PARAMETERS:  Dst_string      - Target of the copy
- *              Src_string      - The source string to copy
- *              Count           - Maximum # of bytes to copy
- *
- * RETURN:      Dst_string
- *
- * DESCRIPTION: Copy a null terminated string, with a maximum length
- *
- ******************************************************************************/
-
-NATIVE_CHAR *
-acpi_cm_strncpy (
-	NATIVE_CHAR             *dst_string,
-	const NATIVE_CHAR       *src_string,
-	NATIVE_UINT             count)
-{
-	NATIVE_CHAR             *string = dst_string;
-
-
-	/* Copy the string */
-
-	for (string = dst_string;
-		count && (count--, (*string++ = *src_string++)); )
-	{;}
-
-	/* Pad with nulls if necessary */
-
-	while (count--) {
-		*string = 0;
-		string++;
-	}
-
-	/* Return original pointer */
-
-	return (dst_string);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    strcmp
- *
- * PARAMETERS:  String1         - First string
- *              String2         - Second string
- *
- * RETURN:      Index where strings mismatched, or 0 if strings matched
- *
- * DESCRIPTION: Compare two null terminated strings
- *
- ******************************************************************************/
-
-u32
-acpi_cm_strcmp (
-	const NATIVE_CHAR       *string1,
-	const NATIVE_CHAR       *string2)
-{
-
-
-	for ( ; (*string1 == *string2); string2++) {
-		if (!*string1++) {
-			return (0);
-		}
-	}
-
-
-	return ((unsigned char) *string1 - (unsigned char) *string2);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    strncmp
- *
- * PARAMETERS:  String1         - First string
- *              String2         - Second string
- *              Count           - Maximum # of bytes to compare
- *
- * RETURN:      Index where strings mismatched, or 0 if strings matched
- *
- * DESCRIPTION: Compare two null terminated strings, with a maximum length
- *
- ******************************************************************************/
-
-u32
-acpi_cm_strncmp (
-	const NATIVE_CHAR       *string1,
-	const NATIVE_CHAR       *string2,
-	NATIVE_UINT             count)
-{
-
-
-	for ( ; count-- && (*string1 == *string2); string2++) {
-		if (!*string1++) {
-			return (0);
-		}
-	}
-
-	return ((count == -1) ? 0 : ((unsigned char) *string1 -
-		(unsigned char) *string2));
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Strcat
- *
- * PARAMETERS:  Dst_string      - Target of the copy
- *              Src_string      - The source string to copy
- *
- * RETURN:      Dst_string
- *
- * DESCRIPTION: Append a null terminated string to a null terminated string
- *
- ******************************************************************************/
-
-NATIVE_CHAR *
-acpi_cm_strcat (
-	NATIVE_CHAR             *dst_string,
-	const NATIVE_CHAR       *src_string)
-{
-	NATIVE_CHAR             *string;
-
-
-	/* Find end of the destination string */
-
-	for (string = dst_string; *string++; ) { ; }
-
-	/* Concatinate the string */
-
-	for (--string; (*string++ = *src_string++); ) { ; }
-
-	return (dst_string);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    strncat
- *
- * PARAMETERS:  Dst_string      - Target of the copy
- *              Src_string      - The source string to copy
- *              Count           - Maximum # of bytes to copy
- *
- * RETURN:      Dst_string
- *
- * DESCRIPTION: Append a null terminated string to a null terminated string,
- *              with a maximum count.
- *
- ******************************************************************************/
-
-NATIVE_CHAR *
-acpi_cm_strncat (
-	NATIVE_CHAR             *dst_string,
-	const NATIVE_CHAR       *src_string,
-	NATIVE_UINT             count)
-{
-	NATIVE_CHAR             *string;
-
-
-	if (count) {
-		/* Find end of the destination string */
-
-		for (string = dst_string; *string++; ) { ; }
-
-		/* Concatinate the string */
-
-		for (--string; (*string++ = *src_string++) && --count; ) { ; }
-
-		/* Null terminate if necessary */
-
-		if (!count) {
-			*string = 0;
-		}
-	}
-
-	return (dst_string);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    memcpy
- *
- * PARAMETERS:  Dest        - Target of the copy
- *              Src         - Source buffer to copy
- *              Count       - Number of bytes to copy
- *
- * RETURN:      Dest
- *
- * DESCRIPTION: Copy arbitrary bytes of memory
- *
- ******************************************************************************/
-
-void *
-acpi_cm_memcpy (
-	void                    *dest,
-	const void              *src,
-	NATIVE_UINT             count)
-{
-	NATIVE_CHAR             *new = (NATIVE_CHAR *) dest;
-	NATIVE_CHAR             *old = (NATIVE_CHAR *) src;
-
-
-	while (count) {
-		*new = *old;
-		new++;
-		old++;
-		count--;
-	}
-
-	return (dest);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    memset
- *
- * PARAMETERS:  Dest        - Buffer to set
- *              Value       - Value to set each byte of memory
- *              Count       - Number of bytes to set
- *
- * RETURN:      Dest
- *
- * DESCRIPTION: Initialize a buffer to a known value.
- *
- ******************************************************************************/
-
-void *
-acpi_cm_memset (
-	void                    *dest,
-	NATIVE_UINT             value,
-	NATIVE_UINT             count)
-{
-	NATIVE_CHAR             *new = (NATIVE_CHAR *) dest;
-
-
-	while (count) {
-		*new = (char) value;
-		new++;
-		count--;
-	}
-
-	return (dest);
-}
-
-
-#define NEGATIVE    1
-#define POSITIVE    0
-
-
-#define _ACPI_XA     0x00    /* extra alphabetic - not supported */
-#define _ACPI_XS     0x40    /* extra space */
-#define _ACPI_BB     0x00    /* BEL, BS, etc. - not supported */
-#define _ACPI_CN     0x20    /* CR, FF, HT, NL, VT */
-#define _ACPI_DI     0x04    /* '0'-'9' */
-#define _ACPI_LO     0x02    /* 'a'-'z' */
-#define _ACPI_PU     0x10    /* punctuation */
-#define _ACPI_SP     0x08    /* space */
-#define _ACPI_UP     0x01    /* 'A'-'Z' */
-#define _ACPI_XD     0x80    /* '0'-'9', 'A'-'F', 'a'-'f' */
-
-static const u8 _acpi_ctype[257] = {
-	_ACPI_CN,            /* 0x0      0.     */
-	_ACPI_CN,            /* 0x1      1.     */
-	_ACPI_CN,            /* 0x2      2.     */
-	_ACPI_CN,            /* 0x3      3.     */
-	_ACPI_CN,            /* 0x4      4.     */
-	_ACPI_CN,            /* 0x5      5.     */
-	_ACPI_CN,            /* 0x6      6.     */
-	_ACPI_CN,            /* 0x7      7.     */
-	_ACPI_CN,            /* 0x8      8.     */
-	_ACPI_CN|_ACPI_SP,   /* 0x9      9.     */
-	_ACPI_CN|_ACPI_SP,   /* 0xA     10.     */
-	_ACPI_CN|_ACPI_SP,   /* 0xB     11.     */
-	_ACPI_CN|_ACPI_SP,   /* 0xC     12.     */
-	_ACPI_CN|_ACPI_SP,   /* 0xD     13.     */
-	_ACPI_CN,            /* 0xE     14.     */
-	_ACPI_CN,            /* 0xF     15.     */
-	_ACPI_CN,            /* 0x10    16.     */
-	_ACPI_CN,            /* 0x11    17.     */
-	_ACPI_CN,            /* 0x12    18.     */
-	_ACPI_CN,            /* 0x13    19.     */
-	_ACPI_CN,            /* 0x14    20.     */
-	_ACPI_CN,            /* 0x15    21.     */
-	_ACPI_CN,            /* 0x16    22.     */
-	_ACPI_CN,            /* 0x17    23.     */
-	_ACPI_CN,            /* 0x18    24.     */
-	_ACPI_CN,            /* 0x19    25.     */
-	_ACPI_CN,            /* 0x1A    26.     */
-	_ACPI_CN,            /* 0x1B    27.     */
-	_ACPI_CN,            /* 0x1C    28.     */
-	_ACPI_CN,            /* 0x1D    29.     */
-	_ACPI_CN,            /* 0x1E    30.     */
-	_ACPI_CN,            /* 0x1F    31.     */
-	_ACPI_XS|_ACPI_SP,   /* 0x20    32. ' ' */
-	_ACPI_PU,            /* 0x21    33. '!' */
-	_ACPI_PU,            /* 0x22    34. '"' */
-	_ACPI_PU,            /* 0x23    35. '#' */
-	_ACPI_PU,            /* 0x24    36. '$' */
-	_ACPI_PU,            /* 0x25    37. '%' */
-	_ACPI_PU,            /* 0x26    38. '&' */
-	_ACPI_PU,            /* 0x27    39. ''' */
-	_ACPI_PU,            /* 0x28    40. '(' */
-	_ACPI_PU,            /* 0x29    41. ')' */
-	_ACPI_PU,            /* 0x2A    42. '*' */
-	_ACPI_PU,            /* 0x2B    43. '+' */
-	_ACPI_PU,            /* 0x2C    44. ',' */
-	_ACPI_PU,            /* 0x2D    45. '-' */
-	_ACPI_PU,            /* 0x2E    46. '.' */
-	_ACPI_PU,            /* 0x2F    47. '/' */
-	_ACPI_XD|_ACPI_DI,   /* 0x30    48. '0' */
-	_ACPI_XD|_ACPI_DI,   /* 0x31    49. '1' */
-	_ACPI_XD|_ACPI_DI,   /* 0x32    50. '2' */
-	_ACPI_XD|_ACPI_DI,   /* 0x33    51. '3' */
-	_ACPI_XD|_ACPI_DI,   /* 0x34    52. '4' */
-	_ACPI_XD|_ACPI_DI,   /* 0x35    53. '5' */
-	_ACPI_XD|_ACPI_DI,   /* 0x36    54. '6' */
-	_ACPI_XD|_ACPI_DI,   /* 0x37    55. '7' */
-	_ACPI_XD|_ACPI_DI,   /* 0x38    56. '8' */
-	_ACPI_XD|_ACPI_DI,   /* 0x39    57. '9' */
-	_ACPI_PU,            /* 0x3A    58. ':' */
-	_ACPI_PU,            /* 0x3B    59. ';' */
-	_ACPI_PU,            /* 0x3C    60. '<' */
-	_ACPI_PU,            /* 0x3D    61. '=' */
-	_ACPI_PU,            /* 0x3E    62. '>' */
-	_ACPI_PU,            /* 0x3F    63. '?' */
-	_ACPI_PU,            /* 0x40    64. '@' */
-	_ACPI_XD|_ACPI_UP,   /* 0x41    65. 'A' */
-	_ACPI_XD|_ACPI_UP,   /* 0x42    66. 'B' */
-	_ACPI_XD|_ACPI_UP,   /* 0x43    67. 'C' */
-	_ACPI_XD|_ACPI_UP,   /* 0x44    68. 'D' */
-	_ACPI_XD|_ACPI_UP,   /* 0x45    69. 'E' */
-	_ACPI_XD|_ACPI_UP,   /* 0x46    70. 'F' */
-	_ACPI_UP,            /* 0x47    71. 'G' */
-	_ACPI_UP,            /* 0x48    72. 'H' */
-	_ACPI_UP,            /* 0x49    73. 'I' */
-	_ACPI_UP,            /* 0x4A    74. 'J' */
-	_ACPI_UP,            /* 0x4B    75. 'K' */
-	_ACPI_UP,            /* 0x4C    76. 'L' */
-	_ACPI_UP,            /* 0x4D    77. 'M' */
-	_ACPI_UP,            /* 0x4E    78. 'N' */
-	_ACPI_UP,            /* 0x4F    79. 'O' */
-	_ACPI_UP,            /* 0x50    80. 'P' */
-	_ACPI_UP,            /* 0x51    81. 'Q' */
-	_ACPI_UP,            /* 0x52    82. 'R' */
-	_ACPI_UP,            /* 0x53    83. 'S' */
-	_ACPI_UP,            /* 0x54    84. 'T' */
-	_ACPI_UP,            /* 0x55    85. 'U' */
-	_ACPI_UP,            /* 0x56    86. 'V' */
-	_ACPI_UP,            /* 0x57    87. 'W' */
-	_ACPI_UP,            /* 0x58    88. 'X' */
-	_ACPI_UP,            /* 0x59    89. 'Y' */
-	_ACPI_UP,            /* 0x5A    90. 'Z' */
-	_ACPI_PU,            /* 0x5B    91. '[' */
-	_ACPI_PU,            /* 0x5C    92. '\' */
-	_ACPI_PU,            /* 0x5D    93. ']' */
-	_ACPI_PU,            /* 0x5E    94. '^' */
-	_ACPI_PU,            /* 0x5F    95. '_' */
-	_ACPI_PU,            /* 0x60    96. '`' */
-	_ACPI_XD|_ACPI_LO,   /* 0x61    97. 'a' */
-	_ACPI_XD|_ACPI_LO,   /* 0x62    98. 'b' */
-	_ACPI_XD|_ACPI_LO,   /* 0x63    99. 'c' */
-	_ACPI_XD|_ACPI_LO,   /* 0x64   100. 'd' */
-	_ACPI_XD|_ACPI_LO,   /* 0x65   101. 'e' */
-	_ACPI_XD|_ACPI_LO,   /* 0x66   102. 'f' */
-	_ACPI_LO,            /* 0x67   103. 'g' */
-	_ACPI_LO,            /* 0x68   104. 'h' */
-	_ACPI_LO,            /* 0x69   105. 'i' */
-	_ACPI_LO,            /* 0x6A   106. 'j' */
-	_ACPI_LO,            /* 0x6B   107. 'k' */
-	_ACPI_LO,            /* 0x6C   108. 'l' */
-	_ACPI_LO,            /* 0x6D   109. 'm' */
-	_ACPI_LO,            /* 0x6E   110. 'n' */
-	_ACPI_LO,            /* 0x6F   111. 'o' */
-	_ACPI_LO,            /* 0x70   112. 'p' */
-	_ACPI_LO,            /* 0x71   113. 'q' */
-	_ACPI_LO,            /* 0x72   114. 'r' */
-	_ACPI_LO,            /* 0x73   115. 's' */
-	_ACPI_LO,            /* 0x74   116. 't' */
-	_ACPI_LO,            /* 0x75   117. 'u' */
-	_ACPI_LO,            /* 0x76   118. 'v' */
-	_ACPI_LO,            /* 0x77   119. 'w' */
-	_ACPI_LO,            /* 0x78   120. 'x' */
-	_ACPI_LO,            /* 0x79   121. 'y' */
-	_ACPI_LO,            /* 0x7A   122. 'z' */
-	_ACPI_PU,            /* 0x7B   123. '{' */
-	_ACPI_PU,            /* 0x7C   124. '|' */
-	_ACPI_PU,            /* 0x7D   125. '}' */
-	_ACPI_PU,            /* 0x7E   126. '~' */
-	_ACPI_CN,            /* 0x7F   127.     */
-
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  /* 0x80 to 0x8F    */
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  /* 0x90 to 0x9F    */
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  /* 0xA0 to 0xAF    */
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  /* 0xB0 to 0xBF    */
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  /* 0xC0 to 0xCF    */
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  /* 0xD0 to 0xDF    */
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  /* 0xE0 to 0xEF    */
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 0xF0 to 0x100   */
-};
-
-#define IS_UPPER(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_UP))
-#define IS_LOWER(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO))
-#define IS_DIGIT(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_DI))
-#define IS_SPACE(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_SP))
-#define IS_XDIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_XD))
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_to_upper
- *
- * PARAMETERS:
- *
- * RETURN:
- *
- * DESCRIPTION: Convert character to uppercase
- *
- ******************************************************************************/
-
-u32
-acpi_cm_to_upper (
-	u32                     c)
-{
-
-	return (IS_LOWER(c) ? ((c)-0x20) : (c));
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_to_lower
- *
- * PARAMETERS:
- *
- * RETURN:
- *
- * DESCRIPTION: Convert character to lowercase
- *
- ******************************************************************************/
-
-u32
-acpi_cm_to_lower (
-	u32                     c)
-{
-
-	return (IS_UPPER(c) ? ((c)+0x20) : (c));
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    strupr
- *
- * PARAMETERS:  Src_string      - The source string to convert to
- *
- * RETURN:      Src_string
- *
- * DESCRIPTION: Convert string to uppercase
- *
- ******************************************************************************/
-
-NATIVE_CHAR *
-acpi_cm_strupr (
-	NATIVE_CHAR             *src_string)
-{
-	NATIVE_CHAR             *string;
-
-
-	/* Walk entire string, uppercasing the letters */
-
-	for (string = src_string; *string; ) {
-		*string = (char) acpi_cm_to_upper (*string);
-		string++;
-	}
-
-
-	return (src_string);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    strstr
- *
- * PARAMETERS:  String1       -
- *              String2
- *
- * RETURN:
- *
- * DESCRIPTION: Checks if String2 occurs in String1. This is not really a
- *              full implementation of strstr, only sufficient for command
- *              matching
- *
- ******************************************************************************/
-
-NATIVE_CHAR *
-acpi_cm_strstr (
-	NATIVE_CHAR             *string1,
-	NATIVE_CHAR             *string2)
-{
-	NATIVE_CHAR             *string;
-
-
-	if (acpi_cm_strlen (string2) > acpi_cm_strlen (string1)) {
-		return (NULL);
-	}
-
-	/* Walk entire string, comparing the letters */
-
-	for (string = string1; *string2; ) {
-		if (*string2 != *string) {
-			return (NULL);
-		}
-
-		string2++;
-		string++;
-	}
-
-
-	return (string1);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    strtoul
- *
- * PARAMETERS:  String          - Null terminated string
- *              Terminater      - Where a pointer to the terminating byte is returned
- *              Base            - Radix of the string
- *
- * RETURN:      Converted value
- *
- * DESCRIPTION: Convert a string into an unsigned value.
- *
- ******************************************************************************/
-
-u32
-acpi_cm_strtoul (
-	const NATIVE_CHAR       *string,
-	NATIVE_CHAR             **terminator,
-	NATIVE_UINT             base)
-{
-	u32                     converted = 0;
-	u32                     index;
-	u32                     sign;
-	const NATIVE_CHAR       *string_start;
-	u32                     return_value = 0;
-	ACPI_STATUS             status = AE_OK;
-
-
-	/*
-	 * Save the value of the pointer to the buffer's first
-	 * character, save the current errno value, and then
-	 * skip over any white space in the buffer:
-	 */
-	string_start = string;
-	while (IS_SPACE (*string) || *string == '\t') {
-		++string;
-	}
-
-	/*
-	 * The buffer may contain an optional plus or minus sign.
-	 * If it does, then skip over it but remember what is was:
-	 */
-	if (*string == '-') {
-		sign = NEGATIVE;
-		++string;
-	}
-
-	else if (*string == '+') {
-		++string;
-		sign = POSITIVE;
-	}
-
-	else {
-		sign = POSITIVE;
-	}
-
-	/*
-	 * If the input parameter Base is zero, then we need to
-	 * determine if it is octal, decimal, or hexadecimal:
-	 */
-	if (base == 0) {
-		if (*string == '0') {
-			if (acpi_cm_to_lower (*(++string)) == 'x') {
-				base = 16;
-				++string;
-			}
-
-			else {
-				base = 8;
-			}
-		}
-
-		else {
-			base = 10;
-		}
-	}
-
-	else if (base < 2 || base > 36) {
-		/*
-		 * The specified Base parameter is not in the domain of
-		 * this function:
-		 */
-		goto done;
-	}
-
-	/*
-	 * For octal and hexadecimal bases, skip over the leading
-	 * 0 or 0x, if they are present.
-	 */
-	if (base == 8 && *string == '0') {
-		string++;
-	}
-
-	if (base == 16 &&
-		*string == '0' &&
-		acpi_cm_to_lower (*(++string)) == 'x')
-	{
-		string++;
-	}
-
-
-	/*
-	 * Main loop: convert the string to an unsigned long:
-	 */
-	while (*string) {
-		if (IS_DIGIT (*string)) {
-			index = *string - '0';
-		}
-
-		else {
-			index = acpi_cm_to_upper (*string);
-			if (IS_UPPER (index)) {
-				index = index - 'A' + 10;
-			}
-
-			else {
-				goto done;
-			}
-		}
-
-		if (index >= base) {
-			goto done;
-		}
-
-		/*
-		 * Check to see if value is out of range:
-		 */
-
-		if (return_value > ((ACPI_UINT32_MAX - (u32) index) /
-				   (u32) base))
-		{
-			status = AE_ERROR;
-			return_value = 0L;          /* reset */
-		}
-
-		else {
-			return_value *= base;
-			return_value += index;
-			converted = 1;
-		}
-
-		++string;
-	}
-
-done:
-	/*
-	 * If appropriate, update the caller's pointer to the next
-	 * unconverted character in the buffer.
-	 */
-	if (terminator) {
-		if (converted == 0 && return_value == 0L && string != NULL) {
-			*terminator = (NATIVE_CHAR *) string_start;
-		}
-
-		else {
-			*terminator = (NATIVE_CHAR *) string;
-		}
-	}
-
-	if (status == AE_ERROR) {
-		return_value = ACPI_UINT32_MAX;
-	}
-
-	/*
-	 * If a minus sign was present, then "the conversion is negated":
-	 */
-	if (sign == NEGATIVE) {
-		return_value = (ACPI_UINT32_MAX - return_value) + 1;
-	}
-
-	return (return_value);
-}
-
-#endif /* ACPI_USE_SYSTEM_CLIBRARY */
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/common/cmcopy.c linux/drivers/acpi/common/cmcopy.c
--- v2.4.5/linux/drivers/acpi/common/cmcopy.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/common/cmcopy.c	Wed Dec 31 16:00:00 1969
@@ -1,708 +0,0 @@
-/******************************************************************************
- *
- * Module Name: cmcopy - Internal to external object translation utilities
- *              $Revision: 66 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acinterp.h"
-#include "acnamesp.h"
-#include "amlcode.h"
-
-
-#define _COMPONENT          MISCELLANEOUS
-	 MODULE_NAME         ("cmcopy")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_copy_isimple_to_esimple
- *
- * PARAMETERS:  *Internal_object    - Pointer to the object we are examining
- *              *Buffer             - Where the object is returned
- *              *Space_used         - Where the data length is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: This function is called to place a simple object in a user
- *              buffer.
- *
- *              The buffer is assumed to have sufficient space for the object.
- *
- ******************************************************************************/
-
-static ACPI_STATUS
-acpi_cm_copy_isimple_to_esimple (
-	ACPI_OPERAND_OBJECT     *internal_object,
-	ACPI_OBJECT             *external_object,
-	u8                      *data_space,
-	u32                     *buffer_space_used)
-{
-	u32                     length = 0;
-	ACPI_STATUS             status = AE_OK;
-
-
-	/*
-	 * Check for NULL object case (could be an uninitialized
-	 * package element
-	 */
-
-	if (!internal_object) {
-		*buffer_space_used = 0;
-		return (AE_OK);
-	}
-
-	/* Always clear the external object */
-
-	MEMSET (external_object, 0, sizeof (ACPI_OBJECT));
-
-	/*
-	 * In general, the external object will be the same type as
-	 * the internal object
-	 */
-
-	external_object->type = internal_object->common.type;
-
-	/* However, only a limited number of external types are supported */
-
-	switch (internal_object->common.type)
-	{
-
-	case ACPI_TYPE_STRING:
-
-		length = internal_object->string.length + 1;
-		external_object->string.length = internal_object->string.length;
-		external_object->string.pointer = (NATIVE_CHAR *) data_space;
-		MEMCPY ((void *) data_space, (void *) internal_object->string.pointer, length);
-		break;
-
-
-	case ACPI_TYPE_BUFFER:
-
-		length = internal_object->buffer.length;
-		external_object->buffer.length = internal_object->buffer.length;
-		external_object->buffer.pointer = data_space;
-		MEMCPY ((void *) data_space, (void *) internal_object->buffer.pointer, length);
-		break;
-
-
-	case ACPI_TYPE_INTEGER:
-
-		external_object->integer.value= internal_object->integer.value;
-		break;
-
-
-	case INTERNAL_TYPE_REFERENCE:
-
-		/*
-		 * This is an object reference.  Attempt to dereference it.
-		 */
-
-		switch (internal_object->reference.op_code)
-		{
-		case AML_ZERO_OP:
-			external_object->type = ACPI_TYPE_INTEGER;
-			external_object->integer.value = 0;
-			break;
-
-		case AML_ONE_OP:
-			external_object->type = ACPI_TYPE_INTEGER;
-			external_object->integer.value = 1;
-			break;
-
-		case AML_ONES_OP:
-			external_object->type = ACPI_TYPE_INTEGER;
-			external_object->integer.value = ACPI_INTEGER_MAX;
-			break;
-
-		case AML_NAMEPATH_OP:
-			/*
-			 * This is a named reference, get the string.  We already know that
-			 * we have room for it, use max length
-			 */
-			length = MAX_STRING_LENGTH;
-			external_object->type = ACPI_TYPE_STRING;
-			external_object->string.pointer = (NATIVE_CHAR *) data_space;
-			status = acpi_ns_handle_to_pathname ((ACPI_HANDLE *) internal_object->reference.node,
-					 &length, (char *) data_space);
-			break;
-
-		default:
-			/*
-			 * Use the object type of "Any" to indicate a reference
-			 * to object containing a handle to an ACPI named object.
-			 */
-			external_object->type = ACPI_TYPE_ANY;
-			external_object->reference.handle = internal_object->reference.node;
-			break;
-		}
-		break;
-
-
-	case ACPI_TYPE_PROCESSOR:
-
-		external_object->processor.proc_id = internal_object->processor.proc_id;
-		external_object->processor.pblk_address = internal_object->processor.address;
-		external_object->processor.pblk_length = internal_object->processor.length;
-		break;
-
-
-	case ACPI_TYPE_POWER:
-
-		external_object->power_resource.system_level =
-				   internal_object->power_resource.system_level;
-
-		external_object->power_resource.resource_order =
-				   internal_object->power_resource.resource_order;
-		break;
-
-
-	default:
-		/*
-		 * There is no corresponding external object type
-		 */
-		return (AE_SUPPORT);
-		break;
-	}
-
-
-	*buffer_space_used = (u32) ROUND_UP_TO_NATIVE_WORD (length);
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_copy_ielement_to_eelement
- *
- * PARAMETERS:  ACPI_PKG_CALLBACK
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Copy one package element to another package element
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_copy_ielement_to_eelement (
-	u8                      object_type,
-	ACPI_OPERAND_OBJECT     *source_object,
-	ACPI_GENERIC_STATE      *state,
-	void                    *context)
-{
-	ACPI_STATUS             status = AE_OK;
-	ACPI_PKG_INFO           *info = (ACPI_PKG_INFO *) context;
-	u32                     object_space;
-	u32                     this_index;
-	ACPI_OBJECT             *target_object;
-
-
-	this_index      = state->pkg.index;
-	target_object   = (ACPI_OBJECT *)
-			   &((ACPI_OBJECT *)(state->pkg.dest_object))->package.elements[this_index];
-
-
-	switch (object_type)
-	{
-	case 0:
-
-		/*
-		 * This is a simple or null object -- get the size
-		 */
-
-		status = acpi_cm_copy_isimple_to_esimple (source_object,
-				  target_object, info->free_space, &object_space);
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-
-		break;
-
-	case 1:
-
-		/*
-		 * Build the package object
-		 */
-		target_object->type             = ACPI_TYPE_PACKAGE;
-		target_object->package.count    = source_object->package.count;
-		target_object->package.elements = (ACPI_OBJECT *) info->free_space;
-
-		/*
-		 * Pass the new package object back to the package walk routine
-		 */
-		state->pkg.this_target_obj = target_object;
-
-		/*
-		 * Save space for the array of objects (Package elements)
-		 * update the buffer length counter
-		 */
-		object_space = (u32) ROUND_UP_TO_NATIVE_WORD (
-				   target_object->package.count * sizeof (ACPI_OBJECT));
-		break;
-
-	default:
-		return (AE_BAD_PARAMETER);
-	}
-
-
-	info->free_space  += object_space;
-	info->length      += object_space;
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_copy_ipackage_to_epackage
- *
- * PARAMETERS:  *Internal_object    - Pointer to the object we are returning
- *              *Buffer             - Where the object is returned
- *              *Space_used         - Where the object length is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: This function is called to place a package object in a user
- *              buffer.  A package object by definition contains other objects.
- *
- *              The buffer is assumed to have sufficient space for the object.
- *              The caller must have verified the buffer length needed using the
- *              Acpi_cm_get_object_size function before calling this function.
- *
- ******************************************************************************/
-
-static ACPI_STATUS
-acpi_cm_copy_ipackage_to_epackage (
-	ACPI_OPERAND_OBJECT     *internal_object,
-	u8                      *buffer,
-	u32                     *space_used)
-{
-	ACPI_OBJECT             *external_object;
-	ACPI_STATUS             status;
-	ACPI_PKG_INFO           info;
-
-
-	/*
-	 * First package at head of the buffer
-	 */
-	external_object = (ACPI_OBJECT *) buffer;
-
-	/*
-	 * Free space begins right after the first package
-	 */
-	info.length      = 0;
-	info.object_space = 0;
-	info.num_packages = 1;
-	info.free_space  = buffer + ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
-
-
-	external_object->type              = internal_object->common.type;
-	external_object->package.count     = internal_object->package.count;
-	external_object->package.elements  = (ACPI_OBJECT *) info.free_space;
-
-
-	/*
-	 * Build an array of ACPI_OBJECTS in the buffer
-	 * and move the free space past it
-	 */
-
-	info.free_space += external_object->package.count *
-			  ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
-
-
-	status = acpi_cm_walk_package_tree (internal_object, external_object,
-			 acpi_cm_copy_ielement_to_eelement, &info);
-
-	*space_used = info.length;
-
-	return (status);
-
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_copy_iobject_to_eobject
- *
- * PARAMETERS:  *Internal_object    - The internal object to be converted
- *              *Buffer_ptr         - Where the object is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: This function is called to build an API object to be returned to
- *              the caller.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_copy_iobject_to_eobject (
-	ACPI_OPERAND_OBJECT     *internal_object,
-	ACPI_BUFFER             *ret_buffer)
-{
-	ACPI_STATUS             status;
-
-
-	if (IS_THIS_OBJECT_TYPE (internal_object, ACPI_TYPE_PACKAGE)) {
-		/*
-		 * Package object:  Copy all subobjects (including
-		 * nested packages)
-		 */
-		status = acpi_cm_copy_ipackage_to_epackage (internal_object,
-				  ret_buffer->pointer, &ret_buffer->length);
-	}
-
-	else {
-		/*
-		 * Build a simple object (no nested objects)
-		 */
-		status = acpi_cm_copy_isimple_to_esimple (internal_object,
-				  (ACPI_OBJECT *) ret_buffer->pointer,
-				  ((u8 *) ret_buffer->pointer +
-				  ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT))),
-				  &ret_buffer->length);
-		/*
-		 * build simple does not include the object size in the length
-		 * so we add it in here
-		 */
-		ret_buffer->length += sizeof (ACPI_OBJECT);
-	}
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_copy_esimple_to_isimple
- *
- * PARAMETERS:  *External_object   - The external object to be converted
- *              *Internal_object   - Where the internal object is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: This function copies an external object to an internal one.
- *              NOTE: Pointers can be copied, we don't need to copy data.
- *              (The pointers have to be valid in our address space no matter
- *              what we do with them!)
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_copy_esimple_to_isimple (
-	ACPI_OBJECT             *external_object,
-	ACPI_OPERAND_OBJECT     *internal_object)
-{
-
-
-	internal_object->common.type = (u8) external_object->type;
-
-	switch (external_object->type)
-	{
-
-	case ACPI_TYPE_STRING:
-
-		internal_object->string.length = external_object->string.length;
-		internal_object->string.pointer = external_object->string.pointer;
-		break;
-
-
-	case ACPI_TYPE_BUFFER:
-
-		internal_object->buffer.length = external_object->buffer.length;
-		internal_object->buffer.pointer = external_object->buffer.pointer;
-		break;
-
-
-	case ACPI_TYPE_INTEGER:
-		/*
-		 * Number is included in the object itself
-		 */
-		internal_object->integer.value  = external_object->integer.value;
-		break;
-
-
-	default:
-		return (AE_CTRL_RETURN_VALUE);
-		break;
-	}
-
-
-	return (AE_OK);
-}
-
-
-#ifdef ACPI_FUTURE_IMPLEMENTATION
-
-/* Code to convert packages that are parameters to control methods */
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_copy_epackage_to_ipackage
- *
- * PARAMETERS:  *Internal_object   - Pointer to the object we are returning
- *              *Buffer         - Where the object is returned
- *              *Space_used     - Where the length of the object is returned
- *
- * RETURN:      Status          - the status of the call
- *
- * DESCRIPTION: This function is called to place a package object in a user
- *              buffer.  A package object by definition contains other objects.
- *
- *              The buffer is assumed to have sufficient space for the object.
- *              The caller must have verified the buffer length needed using the
- *              Acpi_cm_get_object_size function before calling this function.
- *
- ******************************************************************************/
-
-static ACPI_STATUS
-acpi_cm_copy_epackage_to_ipackage (
-	ACPI_OPERAND_OBJECT     *internal_object,
-	u8                      *buffer,
-	u32                     *space_used)
-{
-	u8                      *free_space;
-	ACPI_OBJECT             *external_object;
-	u32                     length = 0;
-	u32                     this_index;
-	u32                     object_space = 0;
-	ACPI_OPERAND_OBJECT     *this_internal_obj;
-	ACPI_OBJECT             *this_external_obj;
-
-
-	/*
-	 * First package at head of the buffer
-	 */
-	external_object = (ACPI_OBJECT *)buffer;
-
-	/*
-	 * Free space begins right after the first package
-	 */
-	free_space = buffer + sizeof(ACPI_OBJECT);
-
-
-	external_object->type              = internal_object->common.type;
-	external_object->package.count     = internal_object->package.count;
-	external_object->package.elements  = (ACPI_OBJECT *)free_space;
-
-
-	/*
-	 * Build an array of ACPI_OBJECTS in the buffer
-	 * and move the free space past it
-	 */
-
-	free_space += external_object->package.count * sizeof(ACPI_OBJECT);
-
-
-	/* Call Walk_package */
-
-}
-
-#endif /* Future implementation */
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_copy_eobject_to_iobject
- *
- * PARAMETERS:  *Internal_object   - The external object to be converted
- *              *Buffer_ptr     - Where the internal object is returned
- *
- * RETURN:      Status          - the status of the call
- *
- * DESCRIPTION: Converts an external object to an internal object.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_copy_eobject_to_iobject (
-	ACPI_OBJECT             *external_object,
-	ACPI_OPERAND_OBJECT     *internal_object)
-{
-	ACPI_STATUS             status;
-
-
-	if (external_object->type == ACPI_TYPE_PACKAGE) {
-		/*
-		 * Package objects contain other objects (which can be objects)
-		 * buildpackage does it all
-		 *
-		 * TBD: Package conversion must be completed and tested
-		 * NOTE: this code converts packages as input parameters to
-		 * control methods only.  This is a very, very rare case.
-		 */
-/*
-		Status = Acpi_cm_copy_epackage_to_ipackage(Internal_object,
-				 Ret_buffer->Pointer,
-				 &Ret_buffer->Length);
-*/
-		return (AE_NOT_IMPLEMENTED);
-	}
-
-	else {
-		/*
-		 * Build a simple object (no nested objects)
-		 */
-		status = acpi_cm_copy_esimple_to_isimple (external_object, internal_object);
-		/*
-		 * build simple does not include the object size in the length
-		 * so we add it in here
-		 */
-	}
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_copy_ielement_to_ielement
- *
- * PARAMETERS:  ACPI_PKG_CALLBACK
- *
- * RETURN:      Status          - the status of the call
- *
- * DESCRIPTION: Copy one package element to another package element
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_copy_ielement_to_ielement (
-	u8                      object_type,
-	ACPI_OPERAND_OBJECT     *source_object,
-	ACPI_GENERIC_STATE      *state,
-	void                    *context)
-{
-	ACPI_STATUS             status = AE_OK;
-	u32                     this_index;
-	ACPI_OPERAND_OBJECT     **this_target_ptr;
-	ACPI_OPERAND_OBJECT     *target_object;
-
-
-	this_index    = state->pkg.index;
-	this_target_ptr = (ACPI_OPERAND_OBJECT **)
-			   &state->pkg.dest_object->package.elements[this_index];
-
-	switch (object_type)
-	{
-	case 0:
-
-		/*
-		 * This is a simple object, just copy it
-		 */
-		target_object = acpi_cm_create_internal_object (source_object->common.type);
-		if (!target_object) {
-			return (AE_NO_MEMORY);
-		}
-
-		status = acpi_aml_store_object_to_object (source_object, target_object,
-				  (ACPI_WALK_STATE *) context);
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-
-		*this_target_ptr = target_object;
-		break;
-
-
-	case 1:
-		/*
-		 * This object is a package - go down another nesting level
-		 * Create and build the package object
-		 */
-		target_object = acpi_cm_create_internal_object (ACPI_TYPE_PACKAGE);
-		if (!target_object) {
-			/* TBD: must delete package created up to this point */
-
-			return (AE_NO_MEMORY);
-		}
-
-		target_object->package.count = source_object->package.count;
-
-		/*
-		 * Pass the new package object back to the package walk routine
-		 */
-		state->pkg.this_target_obj = target_object;
-
-		/*
-		 * Store the object pointer in the parent package object
-		 */
-		*this_target_ptr = target_object;
-		break;
-
-	default:
-		return (AE_BAD_PARAMETER);
-	}
-
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_copy_ipackage_to_ipackage
- *
- * PARAMETERS:  *Source_obj     - Pointer to the source package object
- *              *Dest_obj       - Where the internal object is returned
- *
- * RETURN:      Status          - the status of the call
- *
- * DESCRIPTION: This function is called to copy an internal package object
- *              into another internal package object.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_copy_ipackage_to_ipackage (
-	ACPI_OPERAND_OBJECT     *source_obj,
-	ACPI_OPERAND_OBJECT     *dest_obj,
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_STATUS             status = AE_OK;
-
-
-	dest_obj->common.type   = source_obj->common.type;
-	dest_obj->package.count = source_obj->package.count;
-
-
-	/*
-	 * Create the object array and walk the source package tree
-	 */
-
-	dest_obj->package.elements = acpi_cm_callocate ((source_obj->package.count + 1) *
-			 sizeof (void *));
-	dest_obj->package.next_element = dest_obj->package.elements;
-
-	if (!dest_obj->package.elements) {
-		REPORT_ERROR (
-			("Aml_build_copy_internal_package_object: Package allocation failure\n"));
-		return (AE_NO_MEMORY);
-	}
-
-
-	status = acpi_cm_walk_package_tree (source_obj, dest_obj,
-			 acpi_cm_copy_ielement_to_ielement, walk_state);
-
-	return (status);
-}
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/common/cmdebug.c linux/drivers/acpi/common/cmdebug.c
--- v2.4.5/linux/drivers/acpi/common/cmdebug.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/common/cmdebug.c	Wed Dec 31 16:00:00 1969
@@ -1,559 +0,0 @@
-/******************************************************************************
- *
- * Module Name: cmdebug - Debug print routines
- *              $Revision: 64 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-
-#define _COMPONENT          MISCELLANEOUS
-	 MODULE_NAME         ("cmdebug")
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Get/Set debug level
- *
- * DESCRIPTION: Get or set value of the debug flag
- *
- *              These are used to allow user's to get/set the debug level
- *
- ****************************************************************************/
-
-
-u32
-get_debug_level (void)
-{
-
-	return (acpi_dbg_level);
-}
-
-void
-set_debug_level (
-	u32                     new_debug_level)
-{
-
-	acpi_dbg_level = new_debug_level;
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Function_trace
- *
- * PARAMETERS:  Module_name         - Caller's module name (for error output)
- *              Line_number         - Caller's line number (for error output)
- *              Component_id        - Caller's component ID (for error output)
- *              Function_name       - Name of Caller's function
- *
- * RETURN:      None
- *
- * DESCRIPTION: Function entry trace.  Prints only if TRACE_FUNCTIONS bit is
- *              set in Debug_level
- *
- ****************************************************************************/
-
-void
-function_trace (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id,
-	NATIVE_CHAR             *function_name)
-{
-
-	acpi_gbl_nesting_level++;
-
-	debug_print (module_name, line_number, component_id,
-			 TRACE_FUNCTIONS,
-			 " %2.2ld Entered Function: %s\n",
-			 acpi_gbl_nesting_level, function_name);
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Function_trace_ptr
- *
- * PARAMETERS:  Module_name         - Caller's module name (for error output)
- *              Line_number         - Caller's line number (for error output)
- *              Component_id        - Caller's component ID (for error output)
- *              Function_name       - Name of Caller's function
- *              Pointer             - Pointer to display
- *
- * RETURN:      None
- *
- * DESCRIPTION: Function entry trace.  Prints only if TRACE_FUNCTIONS bit is
- *              set in Debug_level
- *
- ****************************************************************************/
-
-void
-function_trace_ptr (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id,
-	NATIVE_CHAR             *function_name,
-	void                    *pointer)
-{
-
-	acpi_gbl_nesting_level++;
-	debug_print (module_name, line_number, component_id, TRACE_FUNCTIONS,
-			 " %2.2ld Entered Function: %s, %p\n",
-			 acpi_gbl_nesting_level, function_name, pointer);
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Function_trace_str
- *
- * PARAMETERS:  Module_name         - Caller's module name (for error output)
- *              Line_number         - Caller's line number (for error output)
- *              Component_id        - Caller's component ID (for error output)
- *              Function_name       - Name of Caller's function
- *              String              - Additional string to display
- *
- * RETURN:      None
- *
- * DESCRIPTION: Function entry trace.  Prints only if TRACE_FUNCTIONS bit is
- *              set in Debug_level
- *
- ****************************************************************************/
-
-void
-function_trace_str (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id,
-	NATIVE_CHAR             *function_name,
-	NATIVE_CHAR             *string)
-{
-
-	acpi_gbl_nesting_level++;
-	debug_print (module_name, line_number, component_id, TRACE_FUNCTIONS,
-			 " %2.2ld Entered Function: %s, %s\n",
-			 acpi_gbl_nesting_level, function_name, string);
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Function_trace_u32
- *
- * PARAMETERS:  Module_name         - Caller's module name (for error output)
- *              Line_number         - Caller's line number (for error output)
- *              Component_id        - Caller's component ID (for error output)
- *              Function_name       - Name of Caller's function
- *              Integer             - Integer to display
- *
- * RETURN:      None
- *
- * DESCRIPTION: Function entry trace.  Prints only if TRACE_FUNCTIONS bit is
- *              set in Debug_level
- *
- ****************************************************************************/
-
-void
-function_trace_u32 (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id,
-	NATIVE_CHAR             *function_name,
-	u32                     integer)
-{
-
-	acpi_gbl_nesting_level++;
-	debug_print (module_name, line_number, component_id, TRACE_FUNCTIONS,
-			 " %2.2ld Entered Function: %s, %lX\n",
-			 acpi_gbl_nesting_level, function_name, integer);
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Function_exit
- *
- * PARAMETERS:  Module_name         - Caller's module name (for error output)
- *              Line_number         - Caller's line number (for error output)
- *              Component_id        - Caller's component ID (for error output)
- *              Function_name       - Name of Caller's function
- *
- * RETURN:      None
- *
- * DESCRIPTION: Function exit trace.  Prints only if TRACE_FUNCTIONS bit is
- *              set in Debug_level
- *
- ****************************************************************************/
-
-void
-function_exit (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id,
-	NATIVE_CHAR             *function_name)
-{
-
-	debug_print (module_name, line_number, component_id, TRACE_FUNCTIONS,
-			 " %2.2ld Exiting Function: %s\n",
-			 acpi_gbl_nesting_level, function_name);
-
-	acpi_gbl_nesting_level--;
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Function_status_exit
- *
- * PARAMETERS:  Module_name         - Caller's module name (for error output)
- *              Line_number         - Caller's line number (for error output)
- *              Component_id        - Caller's component ID (for error output)
- *              Function_name       - Name of Caller's function
- *              Status              - Exit status code
- *
- * RETURN:      None
- *
- * DESCRIPTION: Function exit trace.  Prints only if TRACE_FUNCTIONS bit is
- *              set in Debug_level. Prints exit status also.
- *
- ****************************************************************************/
-
-void
-function_status_exit (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id,
-	NATIVE_CHAR             *function_name,
-	ACPI_STATUS             status)
-{
-
-	debug_print (module_name, line_number, component_id,
-		TRACE_FUNCTIONS,
-		" %2.2ld Exiting Function: %s, %s\n",
-		acpi_gbl_nesting_level,
-		function_name,
-		acpi_cm_format_exception (status));
-
-	acpi_gbl_nesting_level--;
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Function_value_exit
- *
- * PARAMETERS:  Module_name         - Caller's module name (for error output)
- *              Line_number         - Caller's line number (for error output)
- *              Component_id        - Caller's component ID (for error output)
- *              Function_name       - Name of Caller's function
- *              Value               - Value to be printed with exit msg
- *
- * RETURN:      None
- *
- * DESCRIPTION: Function exit trace.  Prints only if TRACE_FUNCTIONS bit is
- *              set in Debug_level. Prints exit value also.
- *
- ****************************************************************************/
-
-void
-function_value_exit (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id,
-	NATIVE_CHAR             *function_name,
-	ACPI_INTEGER            value)
-{
-
-	debug_print (module_name, line_number, component_id, TRACE_FUNCTIONS,
-			 " %2.2ld Exiting Function: %s, %X\n",
-			 acpi_gbl_nesting_level, function_name, value);
-
-	acpi_gbl_nesting_level--;
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Function_ptr_exit
- *
- * PARAMETERS:  Module_name         - Caller's module name (for error output)
- *              Line_number         - Caller's line number (for error output)
- *              Component_id        - Caller's component ID (for error output)
- *              Function_name       - Name of Caller's function
- *              Value               - Value to be printed with exit msg
- *
- * RETURN:      None
- *
- * DESCRIPTION: Function exit trace.  Prints only if TRACE_FUNCTIONS bit is
- *              set in Debug_level. Prints exit value also.
- *
- ****************************************************************************/
-
-void
-function_ptr_exit (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id,
-	NATIVE_CHAR             *function_name,
-	u8                      *ptr)
-{
-
-	debug_print (module_name, line_number, component_id, TRACE_FUNCTIONS,
-			 " %2.2ld Exiting Function: %s, %p\n",
-			 acpi_gbl_nesting_level, function_name, ptr);
-
-	acpi_gbl_nesting_level--;
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Debug_print
- *
- * PARAMETERS:  Module_name         - Caller's module name (for error output)
- *              Line_number         - Caller's line number (for error output)
- *              Component_id        - Caller's component ID (for error output)
- *              Print_level         - Requested debug print level
- *              Format              - Printf format field
- *              ...                 - Optional printf arguments
- *
- * RETURN:      None
- *
- * DESCRIPTION: Print error message with prefix consisting of the module name,
- *              line number, and component ID.
- *
- ****************************************************************************/
-
-void
-debug_print (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id,
-	u32                     print_level,
-	NATIVE_CHAR             *format,
-	...)
-{
-	va_list                 args;
-
-
-	/* Both the level and the component must be enabled */
-
-	if ((print_level & acpi_dbg_level) &&
-		(component_id & acpi_dbg_layer))
-	{
-		va_start (args, format);
-
-		acpi_os_printf ("%8s-%04d: ", module_name, line_number);
-		acpi_os_vprintf (format, args);
-	}
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Debug_print_prefix
- *
- * PARAMETERS:  Module_name         - Caller's module name (for error output)
- *              Line_number         - Caller's line number (for error output)
- *              Component_id        - Caller's component ID (for error output)
- *
- * RETURN:      None
- *
- * DESCRIPTION: Print the prefix part of an error message, consisting of the
- *              module name, and line number
- *
- ****************************************************************************/
-
-void
-debug_print_prefix (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number)
-{
-
-
-	acpi_os_printf ("%8s-%04d: ", module_name, line_number);
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Debug_print_raw
- *
- * PARAMETERS:  Format              - Printf format field
- *              ...                 - Optional printf arguments
- *
- * RETURN:      None
- *
- * DESCRIPTION: Print error message -- without module/line indentifiers
- *
- ****************************************************************************/
-
-void
-debug_print_raw (
-	NATIVE_CHAR             *format,
-	...)
-{
-	va_list                 args;
-
-
-	va_start (args, format);
-
-	acpi_os_vprintf (format, args);
-
-	va_end (args);
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Acpi_cm_dump_buffer
- *
- * PARAMETERS:  Buffer              - Buffer to dump
- *              Count               - Amount to dump, in bytes
- *              Component_iD        - Caller's component ID
- *
- * RETURN:      None
- *
- * DESCRIPTION: Generic dump buffer in both hex and ascii.
- *
- ****************************************************************************/
-
-void
-acpi_cm_dump_buffer (
-	u8                      *buffer,
-	u32                     count,
-	u32                     display,
-	u32                     component_id)
-{
-	u32                     i = 0;
-	u32                     j;
-	u32                     temp32;
-	u8                      buf_char;
-
-
-	/* Only dump the buffer if tracing is enabled */
-
-	if (!((TRACE_TABLES & acpi_dbg_level) &&
-		(component_id & acpi_dbg_layer)))
-	{
-		return;
-	}
-
-
-	/*
-	 * Nasty little dump buffer routine!
-	 */
-	while (i < count) {
-		/* Print current offset */
-
-		acpi_os_printf ("%05X  ", i);
-
-
-		/* Print 16 hex chars */
-
-		for (j = 0; j < 16;) {
-			if (i + j >= count) {
-				acpi_os_printf ("\n");
-				return;
-			}
-
-			/* Make sure that the s8 doesn't get sign-extended! */
-
-			switch (display)
-			{
-			/* Default is BYTE display */
-
-			default:
-
-				acpi_os_printf ("%02X ",
-						*((u8 *) &buffer[i + j]));
-				j += 1;
-				break;
-
-
-			case DB_WORD_DISPLAY:
-
-				MOVE_UNALIGNED16_TO_32 (&temp32,
-						 &buffer[i + j]);
-				acpi_os_printf ("%04X ", temp32);
-				j += 2;
-				break;
-
-
-			case DB_DWORD_DISPLAY:
-
-				MOVE_UNALIGNED32_TO_32 (&temp32,
-						 &buffer[i + j]);
-				acpi_os_printf ("%08X ", temp32);
-				j += 4;
-				break;
-
-
-			case DB_QWORD_DISPLAY:
-
-				MOVE_UNALIGNED32_TO_32 (&temp32,
-						 &buffer[i + j]);
-				acpi_os_printf ("%08X", temp32);
-
-				MOVE_UNALIGNED32_TO_32 (&temp32,
-						 &buffer[i + j + 4]);
-				acpi_os_printf ("%08X ", temp32);
-				j += 8;
-				break;
-			}
-		}
-
-
-		/*
-		 * Print the ASCII equivalent characters
-		 * But watch out for the bad unprintable ones...
-		 */
-
-		for (j = 0; j < 16; j++) {
-			if (i + j >= count) {
-				acpi_os_printf ("\n");
-				return;
-			}
-
-			buf_char = buffer[i + j];
-			if ((buf_char > 0x1F && buf_char < 0x2E) ||
-				(buf_char > 0x2F && buf_char < 0x61) ||
-				(buf_char > 0x60 && buf_char < 0x7F))
-			{
-				acpi_os_printf ("%c", buf_char);
-			}
-			else {
-				acpi_os_printf (".");
-			}
-		}
-
-		/* Done with that line. */
-
-		acpi_os_printf ("\n");
-		i += 16;
-	}
-
-	return;
-}
-
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/common/cmdelete.c linux/drivers/acpi/common/cmdelete.c
--- v2.4.5/linux/drivers/acpi/common/cmdelete.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/common/cmdelete.c	Wed Dec 31 16:00:00 1969
@@ -1,591 +0,0 @@
-/*******************************************************************************
- *
- * Module Name: cmdelete - object deletion and reference count utilities
- *              $Revision: 62 $
- *
- ******************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acinterp.h"
-#include "acnamesp.h"
-#include "actables.h"
-#include "acparser.h"
-
-#define _COMPONENT          MISCELLANEOUS
-	 MODULE_NAME         ("cmdelete")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_delete_internal_obj
- *
- * PARAMETERS:  *Object        - Pointer to the list to be deleted
- *
- * RETURN:      None
- *
- * DESCRIPTION: Low level object deletion, after reference counts have been
- *              updated (All reference counts, including sub-objects!)
- *
- ******************************************************************************/
-
-void
-acpi_cm_delete_internal_obj (
-	ACPI_OPERAND_OBJECT     *object)
-{
-	void                    *obj_pointer = NULL;
-	ACPI_OPERAND_OBJECT     *handler_desc;
-
-
-	if (!object) {
-		return;
-	}
-
-	/*
-	 * Must delete or free any pointers within the object that are not
-	 * actual ACPI objects (for example, a raw buffer pointer).
-	 */
-
-	switch (object->common.type)
-	{
-
-	case ACPI_TYPE_STRING:
-
-		/* Free the actual string buffer */
-
-		obj_pointer = object->string.pointer;
-		break;
-
-
-	case ACPI_TYPE_BUFFER:
-
-		/* Free the actual buffer */
-
-		obj_pointer = object->buffer.pointer;
-		break;
-
-
-	case ACPI_TYPE_PACKAGE:
-
-		/*
-		 * Elements of the package are not handled here, they are deleted
-		 * separately
-		 */
-
-		/* Free the (variable length) element pointer array */
-
-		obj_pointer = object->package.elements;
-		break;
-
-
-	case ACPI_TYPE_MUTEX:
-
-		acpi_os_delete_semaphore (object->mutex.semaphore);
-		break;
-
-
-	case ACPI_TYPE_EVENT:
-
-		acpi_os_delete_semaphore (object->event.semaphore);
-		object->event.semaphore = NULL;
-		break;
-
-
-	case ACPI_TYPE_METHOD:
-
-		/* Delete the method semaphore if it exists */
-
-		if (object->method.semaphore) {
-			acpi_os_delete_semaphore (object->method.semaphore);
-			object->method.semaphore = NULL;
-		}
-
-		break;
-
-
-	case ACPI_TYPE_REGION:
-
-
-		if (object->region.extra) {
-			/*
-			 * Free the Region_context if and only if the handler is one of the
-			 * default handlers -- and therefore, we created the context object
-			 * locally, it was not created by an external caller.
-			 */
-			handler_desc = object->region.addr_handler;
-			if ((handler_desc) &&
-				(handler_desc->addr_handler.hflags == ADDR_HANDLER_DEFAULT_INSTALLED))
-			{
-				obj_pointer = object->region.extra->extra.region_context;
-			}
-
-			/* Now we can free the Extra object */
-
-			acpi_cm_delete_object_desc (object->region.extra);
-		}
-		break;
-
-
-	case ACPI_TYPE_FIELD_UNIT:
-
-		if (object->field_unit.extra) {
-			acpi_cm_delete_object_desc (object->field_unit.extra);
-		}
-		break;
-
-	default:
-		break;
-	}
-
-
-	/*
-	 * Delete any allocated memory found above
-	 */
-
-	if (obj_pointer) {
-		if (!acpi_tb_system_table_pointer (obj_pointer)) {
-			acpi_cm_free (obj_pointer);
-		}
-	}
-
-
-	/* Only delete the object if it was dynamically allocated */
-
-
-	if (!(object->common.flags & AOPOBJ_STATIC_ALLOCATION)) {
-		acpi_cm_delete_object_desc (object);
-
-	}
-
-	return;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_delete_internal_object_list
- *
- * PARAMETERS:  *Obj_list       - Pointer to the list to be deleted
- *
- * RETURN:      Status          - the status of the call
- *
- * DESCRIPTION: This function deletes an internal object list, including both
- *              simple objects and package objects
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_delete_internal_object_list (
-	ACPI_OPERAND_OBJECT     **obj_list)
-{
-	ACPI_OPERAND_OBJECT     **internal_obj;
-
-
-	/* Walk the null-terminated internal list */
-
-	for (internal_obj = obj_list; *internal_obj; internal_obj++) {
-		/*
-		 * Check for a package
-		 * Simple objects are simply stored in the array and do not
-		 * need to be deleted separately.
-		 */
-
-		if (IS_THIS_OBJECT_TYPE ((*internal_obj), ACPI_TYPE_PACKAGE)) {
-			/* Delete the package */
-
-			/*
-			 * TBD: [Investigate] This might not be the right thing to do,
-			 * depending on how the internal package object was allocated!!!
-			 */
-			acpi_cm_delete_internal_obj (*internal_obj);
-		}
-
-	}
-
-	/* Free the combined parameter pointer list and object array */
-
-	acpi_cm_free (obj_list);
-
-	return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_update_ref_count
- *
- * PARAMETERS:  *Object         - Object whose ref count is to be updated
- *              Action          - What to do
- *
- * RETURN:      New ref count
- *
- * DESCRIPTION: Modify the ref count and return it.
- *
- ******************************************************************************/
-
-static void
-acpi_cm_update_ref_count (
-	ACPI_OPERAND_OBJECT     *object,
-	u32                     action)
-{
-	u16                     count;
-	u16                     new_count;
-
-
-	if (!object) {
-		return;
-	}
-
-
-	count = object->common.reference_count;
-	new_count = count;
-
-	/*
-	 * Reference count action (increment, decrement, or force delete)
-	 */
-
-	switch (action)
-	{
-
-	case REF_INCREMENT:
-
-		new_count++;
-		object->common.reference_count = new_count;
-
-		break;
-
-
-	case REF_DECREMENT:
-
-		if (count < 1) {
-			new_count = 0;
-		}
-
-		else {
-			new_count--;
-
-		}
-
-
-		object->common.reference_count = new_count;
-		if (new_count == 0) {
-			acpi_cm_delete_internal_obj (object);
-		}
-
-		break;
-
-
-	case REF_FORCE_DELETE:
-
-		new_count = 0;
-		object->common.reference_count = new_count;
-		acpi_cm_delete_internal_obj (object);
-		break;
-
-
-	default:
-
-		break;
-	}
-
-
-	/*
-	 * Sanity check the reference count, for debug purposes only.
-	 * (A deleted object will have a huge reference count)
-	 */
-
-
-	return;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_update_object_reference
- *
- * PARAMETERS:  *Object             - Increment ref count for this object
- *                                    and all sub-objects
- *              Action              - Either REF_INCREMENT or REF_DECREMENT or
- *                                    REF_FORCE_DELETE
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Increment the object reference count
- *
- * Object references are incremented when:
- * 1) An object is attached to a Node (namespace object)
- * 2) An object is copied (all subobjects must be incremented)
- *
- * Object references are decremented when:
- * 1) An object is detached from an Node
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_update_object_reference (
-	ACPI_OPERAND_OBJECT     *object,
-	u16                     action)
-{
-	ACPI_STATUS             status;
-	u32                     i;
-	ACPI_OPERAND_OBJECT     *next;
-	ACPI_OPERAND_OBJECT     *new;
-	ACPI_GENERIC_STATE       *state_list = NULL;
-	ACPI_GENERIC_STATE       *state;
-
-
-	/* Ignore a null object ptr */
-
-	if (!object) {
-		return (AE_OK);
-	}
-
-
-	/*
-	 * Make sure that this isn't a namespace handle or an AML pointer
-	 */
-
-	if (VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_NAMED)) {
-		return (AE_OK);
-	}
-
-	if (acpi_tb_system_table_pointer (object)) {
-		return (AE_OK);
-	}
-
-
-	state = acpi_cm_create_update_state (object, action);
-
-	while (state) {
-
-		object = state->update.object;
-		action = state->update.value;
-		acpi_cm_delete_generic_state (state);
-
-		/*
-		 * All sub-objects must have their reference count incremented also.
-		 * Different object types have different subobjects.
-		 */
-		switch (object->common.type)
-		{
-
-		case ACPI_TYPE_DEVICE:
-
-			status = acpi_cm_create_update_state_and_push (object->device.addr_handler,
-					   action, &state_list);
-			if (ACPI_FAILURE (status)) {
-				return (status);
-			}
-
-			acpi_cm_update_ref_count (object->device.sys_handler, action);
-			acpi_cm_update_ref_count (object->device.drv_handler, action);
-			break;
-
-
-		case INTERNAL_TYPE_ADDRESS_HANDLER:
-
-			/* Must walk list of address handlers */
-
-			next = object->addr_handler.next;
-			while (next) {
-				new = next->addr_handler.next;
-				acpi_cm_update_ref_count (next, action);
-
-				next = new;
-			}
-			break;
-
-
-		case ACPI_TYPE_PACKAGE:
-
-			/*
-			 * We must update all the sub-objects of the package
-			 * (Each of whom may have their own sub-objects, etc.
-			 */
-			for (i = 0; i < object->package.count; i++) {
-				/*
-				 * Push each element onto the stack for later processing.
-				 * Note: There can be null elements within the package,
-				 * these are simply ignored
-				 */
-
-				status = acpi_cm_create_update_state_and_push (
-						 object->package.elements[i], action, &state_list);
-				if (ACPI_FAILURE (status)) {
-					return (status);
-				}
-			}
-			break;
-
-
-		case ACPI_TYPE_FIELD_UNIT:
-
-			status = acpi_cm_create_update_state_and_push (
-					 object->field_unit.container, action, &state_list);
-
-			if (ACPI_FAILURE (status)) {
-				return (status);
-			}
-			break;
-
-
-		case INTERNAL_TYPE_DEF_FIELD:
-
-			status = acpi_cm_create_update_state_and_push (
-					 object->field.container, action, &state_list);
-			if (ACPI_FAILURE (status)) {
-				return (status);
-			}
-		   break;
-
-
-		case INTERNAL_TYPE_BANK_FIELD:
-
-			status = acpi_cm_create_update_state_and_push (
-					 object->bank_field.bank_select, action, &state_list);
-			if (ACPI_FAILURE (status)) {
-				return (status);
-			}
-
-			status = acpi_cm_create_update_state_and_push (
-					 object->bank_field.container, action, &state_list);
-			if (ACPI_FAILURE (status)) {
-				return (status);
-			}
-			break;
-
-
-		case ACPI_TYPE_REGION:
-
-	/* TBD: [Investigate]
-			Acpi_cm_update_ref_count (Object->Region.Addr_handler, Action);
-	*/
-/*
-			Status =
-				Acpi_cm_create_update_state_and_push (Object->Region.Addr_handler,
-						   Action, &State_list);
-			if (ACPI_FAILURE (Status)) {
-				return (Status);
-			}
-*/
-			break;
-
-
-		case INTERNAL_TYPE_REFERENCE:
-
-			break;
-		}
-
-
-		/*
-		 * Now we can update the count in the main object.  This can only
-		 * happen after we update the sub-objects in case this causes the
-		 * main object to be deleted.
-		 */
-
-		acpi_cm_update_ref_count (object, action);
-
-
-		/* Move on to the next object to be updated */
-
-		state = acpi_cm_pop_generic_state (&state_list);
-	}
-
-
-	return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_add_reference
- *
- * PARAMETERS:  *Object        - Object whose reference count is to be
- *                                  incremented
- *
- * RETURN:      None
- *
- * DESCRIPTION: Add one reference to an ACPI object
- *
- ******************************************************************************/
-
-void
-acpi_cm_add_reference (
-	ACPI_OPERAND_OBJECT     *object)
-{
-
-
-	/*
-	 * Ensure that we have a valid object
-	 */
-
-	if (!acpi_cm_valid_internal_object (object)) {
-		return;
-	}
-
-	/*
-	 * We have a valid ACPI internal object, now increment the reference count
-	 */
-
-	acpi_cm_update_object_reference (object, REF_INCREMENT);
-
-	return;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_remove_reference
- *
- * PARAMETERS:  *Object        - Object whose ref count will be decremented
- *
- * RETURN:      None
- *
- * DESCRIPTION: Decrement the reference count of an ACPI internal object
- *
- ******************************************************************************/
-
-void
-acpi_cm_remove_reference (
-	ACPI_OPERAND_OBJECT     *object)
-{
-
-
-	/*
-	 * Ensure that we have a valid object
-	 */
-
-	if (!acpi_cm_valid_internal_object (object)) {
-		return;
-	}
-
-	/*
-	 * Decrement the reference count, and only actually delete the object
-	 * if the reference count becomes 0.  (Must also decrement the ref count
-	 * of all subobjects!)
-	 */
-
-	acpi_cm_update_object_reference (object, REF_DECREMENT);
-
-	return;
-}
-
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/common/cmeval.c linux/drivers/acpi/common/cmeval.c
--- v2.4.5/linux/drivers/acpi/common/cmeval.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/common/cmeval.c	Wed Dec 31 16:00:00 1969
@@ -1,308 +0,0 @@
-/******************************************************************************
- *
- * Module Name: cmeval - Object evaluation
- *              $Revision: 21 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acnamesp.h"
-#include "acinterp.h"
-
-
-#define _COMPONENT          MISCELLANEOUS
-	 MODULE_NAME         ("cmeval")
-
-
-/****************************************************************************
- *
- * FUNCTION:    Acpi_cm_evaluate_numeric_object
- *
- * PARAMETERS:  *Object_name        - Object name to be evaluated
- *              Device_node         - Node for the device
- *              *Address            - Where the value is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: evaluates a numeric namespace object for a selected device
- *              and stores results in *Address.
- *
- *              NOTE: Internal function, no parameter validation
- *
- ***************************************************************************/
-
-ACPI_STATUS
-acpi_cm_evaluate_numeric_object (
-	NATIVE_CHAR             *object_name,
-	ACPI_NAMESPACE_NODE     *device_node,
-	ACPI_INTEGER            *address)
-{
-	ACPI_OPERAND_OBJECT     *obj_desc;
-	ACPI_STATUS             status;
-
-
-	/* Execute the method */
-
-	status = acpi_ns_evaluate_relative (device_node, object_name, NULL, &obj_desc);
-	if (ACPI_FAILURE (status)) {
-
-		return (status);
-	}
-
-
-	/* Did we get a return object? */
-
-	if (!obj_desc) {
-		return (AE_TYPE);
-	}
-
-	/* Is the return object of the correct type? */
-
-	if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
-		status = AE_TYPE;
-	}
-	else {
-		/*
-		 * Since the structure is a union, setting any field will set all
-		 * of the variables in the union
-		 */
-		*address = obj_desc->integer.value;
-	}
-
-	/* On exit, we must delete the return object */
-
-	acpi_cm_remove_reference (obj_desc);
-
-	return (status);
-}
-
-
-/****************************************************************************
- *
- * FUNCTION:    Acpi_cm_execute_HID
- *
- * PARAMETERS:  Device_node         - Node for the device
- *              *Hid                - Where the HID is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Executes the _HID control method that returns the hardware
- *              ID of the device.
- *
- *              NOTE: Internal function, no parameter validation
- *
- ***************************************************************************/
-
-ACPI_STATUS
-acpi_cm_execute_HID (
-	ACPI_NAMESPACE_NODE     *device_node,
-	DEVICE_ID               *hid)
-{
-	ACPI_OPERAND_OBJECT     *obj_desc;
-	ACPI_STATUS             status;
-
-
-	/* Execute the method */
-
-	status = acpi_ns_evaluate_relative (device_node,
-			 METHOD_NAME__HID, NULL, &obj_desc);
-	if (ACPI_FAILURE (status)) {
-
-
-		return (status);
-	}
-
-	/* Did we get a return object? */
-
-	if (!obj_desc) {
-		return (AE_TYPE);
-	}
-
-	/*
-	 *  A _HID can return either a Number (32 bit compressed EISA ID) or
-	 *  a string
-	 */
-
-	if ((obj_desc->common.type != ACPI_TYPE_INTEGER) &&
-		(obj_desc->common.type != ACPI_TYPE_STRING))
-	{
-		status = AE_TYPE;
-	}
-
-	else {
-		if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
-			/* Convert the Numeric HID to string */
-
-			acpi_aml_eisa_id_to_string ((u32) obj_desc->integer.value, hid->buffer);
-		}
-
-		else {
-			/* Copy the String HID from the returned object */
-
-			STRNCPY(hid->buffer, obj_desc->string.pointer, sizeof(hid->buffer));
-		}
-	}
-
-
-	/* On exit, we must delete the return object */
-
-	acpi_cm_remove_reference (obj_desc);
-
-	return (status);
-}
-
-
-/****************************************************************************
- *
- * FUNCTION:    Acpi_cm_execute_UID
- *
- * PARAMETERS:  Device_node         - Node for the device
- *              *Uid                - Where the UID is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Executes the _UID control method that returns the hardware
- *              ID of the device.
- *
- *              NOTE: Internal function, no parameter validation
- *
- ***************************************************************************/
-
-ACPI_STATUS
-acpi_cm_execute_UID (
-	ACPI_NAMESPACE_NODE     *device_node,
-	DEVICE_ID               *uid)
-{
-	ACPI_OPERAND_OBJECT     *obj_desc;
-	ACPI_STATUS             status;
-
-
-	/* Execute the method */
-
-	status = acpi_ns_evaluate_relative (device_node,
-			 METHOD_NAME__UID, NULL, &obj_desc);
-	if (ACPI_FAILURE (status)) {
-
-
-		return (status);
-	}
-
-	/* Did we get a return object? */
-
-	if (!obj_desc) {
-		return (AE_TYPE);
-	}
-
-	/*
-	 *  A _UID can return either a Number (32 bit compressed EISA ID) or
-	 *  a string
-	 */
-
-	if ((obj_desc->common.type != ACPI_TYPE_INTEGER) &&
-		(obj_desc->common.type != ACPI_TYPE_STRING))
-	{
-		status = AE_TYPE;
-	}
-
-	else {
-		if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
-			/* Convert the Numeric UID to string */
-
-			acpi_aml_unsigned_integer_to_string (obj_desc->integer.value, uid->buffer);
-		}
-
-		else {
-			/* Copy the String UID from the returned object */
-
-			STRNCPY(uid->buffer, obj_desc->string.pointer, sizeof(uid->buffer));
-		}
-	}
-
-
-	/* On exit, we must delete the return object */
-
-	acpi_cm_remove_reference (obj_desc);
-
-	return (status);
-}
-
-/****************************************************************************
- *
- * FUNCTION:    Acpi_cm_execute_STA
- *
- * PARAMETERS:  Device_node         - Node for the device
- *              *Flags              - Where the status flags are returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Executes _STA for selected device and stores results in
- *              *Flags.
- *
- *              NOTE: Internal function, no parameter validation
- *
- ***************************************************************************/
-
-ACPI_STATUS
-acpi_cm_execute_STA (
-	ACPI_NAMESPACE_NODE     *device_node,
-	u32                     *flags)
-{
-	ACPI_OPERAND_OBJECT     *obj_desc;
-	ACPI_STATUS             status;
-
-
-	/* Execute the method */
-
-	status = acpi_ns_evaluate_relative (device_node,
-			 METHOD_NAME__STA, NULL, &obj_desc);
-	if (AE_NOT_FOUND == status) {
-		*flags = 0x0F;
-		status = AE_OK;
-	}
-
-
-	else /* success */ {
-		/* Did we get a return object? */
-
-		if (!obj_desc) {
-			return (AE_TYPE);
-		}
-
-		/* Is the return object of the correct type? */
-
-		if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
-			status = AE_TYPE;
-		}
-
-		else {
-			/* Extract the status flags */
-
-			*flags = (u32) obj_desc->integer.value;
-		}
-
-		/* On exit, we must delete the return object */
-
-		acpi_cm_remove_reference (obj_desc);
-	}
-
-	return (status);
-}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/common/cmglobal.c linux/drivers/acpi/common/cmglobal.c
--- v2.4.5/linux/drivers/acpi/common/cmglobal.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/common/cmglobal.c	Wed Dec 31 16:00:00 1969
@@ -1,472 +0,0 @@
-/******************************************************************************
- *
- * Module Name: cmglobal - Global variables for the ACPI subsystem
- *              $Revision: 116 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#define DEFINE_ACPI_GLOBALS
-
-#include "acpi.h"
-#include "acevents.h"
-#include "acnamesp.h"
-#include "acinterp.h"
-#include "amlcode.h"
-
-
-#define _COMPONENT          MISCELLANEOUS
-	 MODULE_NAME         ("cmglobal")
-
-
-/******************************************************************************
- *
- * Static global variable initialization.
- *
- ******************************************************************************/
-
-/*
- * We want the debug switches statically initialized so they
- * are already set when the debugger is entered.
- */
-
-/* Debug switch - level and trace mask */
-
-u32                         acpi_dbg_level = NORMAL_DEFAULT;
-
-/* Debug switch - layer (component) mask */
-
-u32                         acpi_dbg_layer = COMPONENT_DEFAULT;
-u32                         acpi_gbl_nesting_level = 0;
-
-
-/* Debugger globals */
-
-u8                          acpi_gbl_db_terminate_threads = FALSE;
-u8                          acpi_gbl_method_executing = FALSE;
-
-/* System flags */
-
-u32                         acpi_gbl_system_flags = 0;
-u32                         acpi_gbl_startup_flags = 0;
-
-/* System starts unitialized! */
-u8                          acpi_gbl_shutdown = TRUE;
-
-
-u8                          acpi_gbl_decode_to8bit [8] = {1,2,4,8,16,32,64,128};
-
-
-/******************************************************************************
- *
- * Namespace globals
- *
- ******************************************************************************/
-
-
-/*
- * Names built-in to the interpreter
- *
- * Initial values are currently supported only for types String and Number.
- * To avoid type punning, both are specified as strings in this table.
- */
-
-PREDEFINED_NAMES            acpi_gbl_pre_defined_names[] =
-{
-	{"_GPE",    INTERNAL_TYPE_DEF_ANY},
-	{"_PR_",    INTERNAL_TYPE_DEF_ANY},
-	{"_SB_",    INTERNAL_TYPE_DEF_ANY},
-	{"_SI_",    INTERNAL_TYPE_DEF_ANY},
-	{"_TZ_",    INTERNAL_TYPE_DEF_ANY},
-	{"_REV",    ACPI_TYPE_INTEGER, "2"},
-	{"_OS_",    ACPI_TYPE_STRING, ACPI_OS_NAME},
-	{"_GL_",    ACPI_TYPE_MUTEX, "0"},
-
-	/* Table terminator */
-
-	{NULL,      ACPI_TYPE_ANY}
-};
-
-
-/*
- * Properties of the ACPI Object Types, both internal and external.
- *
- * Elements of Acpi_ns_properties are bit significant
- * and the table is indexed by values of ACPI_OBJECT_TYPE
- */
-
-u8                          acpi_gbl_ns_properties[] =
-{
-	NSP_NORMAL,                 /* 00 Any              */
-	NSP_NORMAL,                 /* 01 Number           */
-	NSP_NORMAL,                 /* 02 String           */
-	NSP_NORMAL,                 /* 03 Buffer           */
-	NSP_LOCAL,                  /* 04 Package          */
-	NSP_NORMAL,                 /* 05 Field_unit       */
-	NSP_NEWSCOPE | NSP_LOCAL,   /* 06 Device           */
-	NSP_LOCAL,                  /* 07 Acpi_event       */
-	NSP_NEWSCOPE | NSP_LOCAL,   /* 08 Method           */
-	NSP_LOCAL,                  /* 09 Mutex            */
-	NSP_LOCAL,                  /* 10 Region           */
-	NSP_NEWSCOPE | NSP_LOCAL,   /* 11 Power            */
-	NSP_NEWSCOPE | NSP_LOCAL,   /* 12 Processor        */
-	NSP_NEWSCOPE | NSP_LOCAL,   /* 13 Thermal          */
-	NSP_NORMAL,                 /* 14 Buffer_field     */
-	NSP_NORMAL,                 /* 15 Ddb_handle       */
-	NSP_NORMAL,                 /* 16 Debug Object     */
-	NSP_NORMAL,                 /* 17 Def_field        */
-	NSP_NORMAL,                 /* 18 Bank_field       */
-	NSP_NORMAL,                 /* 19 Index_field      */
-	NSP_NORMAL,                 /* 20 Reference        */
-	NSP_NORMAL,                 /* 21 Alias            */
-	NSP_NORMAL,                 /* 22 Notify           */
-	NSP_NORMAL,                 /* 23 Address Handler  */
-	NSP_NEWSCOPE | NSP_LOCAL,   /* 24 Resource         */
-	NSP_NORMAL,                 /* 25 Def_field_defn   */
-	NSP_NORMAL,                 /* 26 Bank_field_defn  */
-	NSP_NORMAL,                 /* 27 Index_field_defn */
-	NSP_NORMAL,                 /* 28 If               */
-	NSP_NORMAL,                 /* 29 Else             */
-	NSP_NORMAL,                 /* 30 While            */
-	NSP_NEWSCOPE,               /* 31 Scope            */
-	NSP_LOCAL,                  /* 32 Def_any          */
-	NSP_NORMAL,                 /* 33 Extra            */
-	NSP_NORMAL                  /* 34 Invalid          */
-};
-
-
-/* Hex to ASCII conversion table */
-
-NATIVE_CHAR                 acpi_gbl_hex_to_ascii[] =
-			  {'0','1','2','3','4','5','6','7',
-			  '8','9','A','B','C','D','E','F'};
-
-
-/******************************************************************************
- *
- * Table globals
- *
- * NOTE: This table includes ONLY the ACPI tables that the subsystem consumes.
- * it is NOT an exhaustive list of all possible ACPI tables.  All ACPI tables
- * that are not used by the subsystem are simply ignored.
- *
- ******************************************************************************/
-
-
-ACPI_TABLE_DESC             acpi_gbl_acpi_tables[NUM_ACPI_TABLES];
-
-
-ACPI_TABLE_SUPPORT          acpi_gbl_acpi_table_data[NUM_ACPI_TABLES] =
-{
-	/***********    Name,    Signature,  Signature size,    How many allowed?,   Supported?  Global typed pointer */
-
-	/* RSDP 0 */ {RSDP_NAME, RSDP_SIG, sizeof (RSDP_SIG)-1, ACPI_TABLE_SINGLE,   AE_OK,      NULL},
-	/* DSDT 1 */ {DSDT_SIG,  DSDT_SIG, sizeof (DSDT_SIG)-1, ACPI_TABLE_SINGLE,   AE_OK,      (void **) &acpi_gbl_DSDT},
-	/* FADT 2 */ {FADT_SIG,  FADT_SIG, sizeof (FADT_SIG)-1, ACPI_TABLE_SINGLE,   AE_OK,      (void **) &acpi_gbl_FADT},
-	/* FACS 3 */ {FACS_SIG,  FACS_SIG, sizeof (FACS_SIG)-1, ACPI_TABLE_SINGLE,   AE_OK,      (void **) &acpi_gbl_FACS},
-	/* PSDT 4 */ {PSDT_SIG,  PSDT_SIG, sizeof (PSDT_SIG)-1, ACPI_TABLE_MULTIPLE, AE_OK,      NULL},
-	/* SSDT 5 */ {SSDT_SIG,  SSDT_SIG, sizeof (SSDT_SIG)-1, ACPI_TABLE_MULTIPLE, AE_OK,      NULL},
-	/* XSDT 6 */ {XSDT_SIG,  XSDT_SIG, sizeof (RSDT_SIG)-1, ACPI_TABLE_SINGLE,   AE_OK,      NULL},
-};
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Acpi_cm_valid_object_type
- *
- * PARAMETERS:  None.
- *
- * RETURN:      TRUE if valid object type
- *
- * DESCRIPTION: Validate an object type
- *
- ****************************************************************************/
-
-u8
-acpi_cm_valid_object_type (
-	u32                     type)
-{
-
-	if (type > ACPI_TYPE_MAX) {
-		if ((type < INTERNAL_TYPE_BEGIN) ||
-			(type > INTERNAL_TYPE_MAX))
-		{
-			return (FALSE);
-		}
-	}
-
-	return (TRUE);
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Acpi_cm_format_exception
- *
- * PARAMETERS:  Status              - Acpi status to be formatted
- *
- * RETURN:      Formatted status string
- *
- * DESCRIPTION: Convert an ACPI exception to a string
- *
- ****************************************************************************/
-
-NATIVE_CHAR *
-acpi_cm_format_exception (
-	ACPI_STATUS             status)
-{
-	NATIVE_CHAR             *exception = "UNKNOWN_STATUS";
-	ACPI_STATUS             sub_status;
-
-
-	sub_status = (status & ~AE_CODE_MASK);
-
-
-	switch (status & AE_CODE_MASK)
-	{
-	case AE_CODE_ENVIRONMENTAL:
-
-		if (sub_status <= AE_CODE_ENV_MAX) {
-			exception = acpi_gbl_exception_names_env [sub_status];
-		}
-		break;
-
-	case AE_CODE_PROGRAMMER:
-
-		if (sub_status <= AE_CODE_PGM_MAX) {
-			exception = acpi_gbl_exception_names_pgm [sub_status -1];
-		}
-		break;
-
-	case AE_CODE_ACPI_TABLES:
-
-		if (sub_status <= AE_CODE_TBL_MAX) {
-			exception = acpi_gbl_exception_names_tbl [sub_status -1];
-		}
-		break;
-
-	case AE_CODE_AML:
-
-		if (sub_status <= AE_CODE_AML_MAX) {
-			exception = acpi_gbl_exception_names_aml [sub_status -1];
-		}
-		break;
-
-	case AE_CODE_CONTROL:
-
-		if (sub_status <= AE_CODE_CTRL_MAX) {
-			exception = acpi_gbl_exception_names_ctrl [sub_status -1];
-		}
-		break;
-
-	default:
-		break;
-	}
-
-
-	return (exception);
-}
-
-
-/****************************************************************************
- *
- * FUNCTION:    Acpi_cm_allocate_owner_id
- *
- * PARAMETERS:  Id_type         - Type of ID (method or table)
- *
- * DESCRIPTION: Allocate a table or method owner id
- *
- ***************************************************************************/
-
-ACPI_OWNER_ID
-acpi_cm_allocate_owner_id (
-	u32                     id_type)
-{
-	ACPI_OWNER_ID           owner_id = 0xFFFF;
-
-
-	acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
-
-	switch (id_type)
-	{
-	case OWNER_TYPE_TABLE:
-
-		owner_id = acpi_gbl_next_table_owner_id;
-		acpi_gbl_next_table_owner_id++;
-
-		if (acpi_gbl_next_table_owner_id == FIRST_METHOD_ID) {
-			acpi_gbl_next_table_owner_id = FIRST_TABLE_ID;
-		}
-		break;
-
-
-	case OWNER_TYPE_METHOD:
-
-		owner_id = acpi_gbl_next_method_owner_id;
-		acpi_gbl_next_method_owner_id++;
-
-		if (acpi_gbl_next_method_owner_id == FIRST_TABLE_ID) {
-			acpi_gbl_next_method_owner_id = FIRST_METHOD_ID;
-		}
-		break;
-	}
-
-
-	acpi_cm_release_mutex (ACPI_MTX_CACHES);
-
-	return (owner_id);
-}
-
-
-/****************************************************************************
- *
- * FUNCTION:    Acpi_cm_init_globals
- *
- * PARAMETERS:  none
- *
- * DESCRIPTION: Init library globals.  All globals that require specific
- *              initialization should be initialized here!
- *
- ***************************************************************************/
-
-void
-acpi_cm_init_globals (
-	void)
-{
-	u32                     i;
-
-
-	/* ACPI table structure */
-
-	for (i = 0; i < NUM_ACPI_TABLES; i++) {
-		acpi_gbl_acpi_tables[i].prev        = &acpi_gbl_acpi_tables[i];
-		acpi_gbl_acpi_tables[i].next        = &acpi_gbl_acpi_tables[i];
-		acpi_gbl_acpi_tables[i].pointer     = NULL;
-		acpi_gbl_acpi_tables[i].length      = 0;
-		acpi_gbl_acpi_tables[i].allocation  = ACPI_MEM_NOT_ALLOCATED;
-		acpi_gbl_acpi_tables[i].count       = 0;
-	}
-
-
-	/* Address Space handler array */
-
-	for (i = 0; i < ACPI_NUM_ADDRESS_SPACES; i++) {
-		acpi_gbl_address_spaces[i].handler  = NULL;
-		acpi_gbl_address_spaces[i].context  = NULL;
-	}
-
-	/* Mutex locked flags */
-
-	for (i = 0; i < NUM_MTX; i++) {
-		acpi_gbl_acpi_mutex_info[i].mutex   = NULL;
-		acpi_gbl_acpi_mutex_info[i].locked  = FALSE;
-		acpi_gbl_acpi_mutex_info[i].use_count = 0;
-	}
-
-	/* Global notify handlers */
-
-	acpi_gbl_sys_notify.handler         = NULL;
-	acpi_gbl_drv_notify.handler         = NULL;
-
-	/* Global "typed" ACPI table pointers */
-
-	acpi_gbl_RSDP                       = NULL;
-	acpi_gbl_XSDT                       = NULL;
-	acpi_gbl_FACS                       = NULL;
-	acpi_gbl_FADT                       = NULL;
-	acpi_gbl_DSDT                       = NULL;
-
-
-	/* Global Lock support */
-
-	acpi_gbl_global_lock_acquired       = FALSE;
-	acpi_gbl_global_lock_thread_count   = 0;
-
-	/* Miscellaneous variables */
-
-	acpi_gbl_system_flags               = 0;
-	acpi_gbl_startup_flags              = 0;
-	acpi_gbl_global_lock_set            = FALSE;
-	acpi_gbl_rsdp_original_location     = 0;
-	acpi_gbl_cm_single_step             = FALSE;
-	acpi_gbl_db_terminate_threads       = FALSE;
-	acpi_gbl_shutdown                   = FALSE;
-	acpi_gbl_ns_lookup_count            = 0;
-	acpi_gbl_ps_find_count              = 0;
-	acpi_gbl_acpi_hardware_present      = TRUE;
-	acpi_gbl_next_table_owner_id        = FIRST_TABLE_ID;
-	acpi_gbl_next_method_owner_id       = FIRST_METHOD_ID;
-	acpi_gbl_debugger_configuration     = DEBUGGER_THREADING;
-
-	/* Cache of small "state" objects */
-
-	acpi_gbl_generic_state_cache        = NULL;
-	acpi_gbl_generic_state_cache_depth  = 0;
-	acpi_gbl_state_cache_requests       = 0;
-	acpi_gbl_state_cache_hits           = 0;
-
-	acpi_gbl_parse_cache                = NULL;
-	acpi_gbl_parse_cache_depth          = 0;
-	acpi_gbl_parse_cache_requests       = 0;
-	acpi_gbl_parse_cache_hits           = 0;
-
-	acpi_gbl_ext_parse_cache            = NULL;
-	acpi_gbl_ext_parse_cache_depth      = 0;
-	acpi_gbl_ext_parse_cache_requests   = 0;
-	acpi_gbl_ext_parse_cache_hits       = 0;
-
-	acpi_gbl_object_cache               = NULL;
-	acpi_gbl_object_cache_depth         = 0;
-	acpi_gbl_object_cache_requests      = 0;
-	acpi_gbl_object_cache_hits          = 0;
-
-	acpi_gbl_walk_state_cache           = NULL;
-	acpi_gbl_walk_state_cache_depth     = 0;
-	acpi_gbl_walk_state_cache_requests  = 0;
-	acpi_gbl_walk_state_cache_hits      = 0;
-
-	/* Hardware oriented */
-
-	acpi_gbl_gpe0enable_register_save   = NULL;
-	acpi_gbl_gpe1_enable_register_save  = NULL;
-	acpi_gbl_original_mode              = SYS_MODE_UNKNOWN;   /*  original ACPI/legacy mode   */
-	acpi_gbl_gpe_registers              = NULL;
-	acpi_gbl_gpe_info                   = NULL;
-
-	/* Namespace */
-
-	acpi_gbl_root_node                  = NULL;
-
-	acpi_gbl_root_node_struct.name      = ACPI_ROOT_NAME;
-	acpi_gbl_root_node_struct.data_type = ACPI_DESC_TYPE_NAMED;
-	acpi_gbl_root_node_struct.type      = ACPI_TYPE_ANY;
-	acpi_gbl_root_node_struct.child     = NULL;
-	acpi_gbl_root_node_struct.peer      = NULL;
-	acpi_gbl_root_node_struct.object    = NULL;
-	acpi_gbl_root_node_struct.flags     = ANOBJ_END_OF_PEER_LIST;
-
-	/* Memory allocation metrics - compiled out in non-debug mode. */
-
-	INITIALIZE_ALLOCATION_METRICS();
-
-	return;
-}
-
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/common/cminit.c linux/drivers/acpi/common/cminit.c
--- v2.4.5/linux/drivers/acpi/common/cminit.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/common/cminit.c	Wed Dec 31 16:00:00 1969
@@ -1,250 +0,0 @@
-/******************************************************************************
- *
- * Module Name: cminit - Common ACPI subsystem initialization
- *              $Revision: 93 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "achware.h"
-#include "acnamesp.h"
-#include "acevents.h"
-#include "acparser.h"
-#include "acdispat.h"
-
-#define _COMPONENT          MISCELLANEOUS
-	 MODULE_NAME         ("cminit")
-
-
-#define ACPI_OFFSET(d,o)    ((u32) &(((d *)0)->o))
-#define ACPI_FADT_OFFSET(o) ACPI_OFFSET (FADT_DESCRIPTOR, o)
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_fadt_register_error
- *
- * PARAMETERS:  *Register_name          - Pointer to string identifying register
- *              Value                   - Actual register contents value
- *              Acpi_test_spec_section  - TDS section containing assertion
- *              Acpi_assertion          - Assertion number being tested
- *
- * RETURN:      AE_BAD_VALUE
- *
- * DESCRIPTION: Display failure message and link failure to TDS assertion
- *
- ******************************************************************************/
-
-static ACPI_STATUS
-acpi_cm_fadt_register_error (
-	NATIVE_CHAR             *register_name,
-	u32                     value,
-	u32                     offset)
-{
-
-	REPORT_ERROR (
-		("Invalid FADT value %s=%lX at offset %lX FADT=%p\n",
-		register_name, value, offset, acpi_gbl_FADT));
-
-
-	return (AE_BAD_VALUE);
-}
-
-
-/******************************************************************************
- *
- * FUNCTION:    Acpi_cm_validate_fadt
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Validate various ACPI registers in the FADT
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_validate_fadt (
-	void)
-{
-	ACPI_STATUS                 status = AE_OK;
-
-
-	/*
-	 * Verify Fixed ACPI Description Table fields,
-	 * but don't abort on any problems, just display error
-	 */
-
-	if (acpi_gbl_FADT->pm1_evt_len < 4) {
-		status = acpi_cm_fadt_register_error ("PM1_EVT_LEN",
-				  (u32) acpi_gbl_FADT->pm1_evt_len,
-				  ACPI_FADT_OFFSET (pm1_evt_len));
-	}
-
-	if (!acpi_gbl_FADT->pm1_cnt_len) {
-		status = acpi_cm_fadt_register_error ("PM1_CNT_LEN", 0,
-				  ACPI_FADT_OFFSET (pm1_cnt_len));
-	}
-
-	if (!ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm1a_evt_blk.address)) {
-		status = acpi_cm_fadt_register_error ("X_PM1a_EVT_BLK", 0,
-				  ACPI_FADT_OFFSET (Xpm1a_evt_blk.address));
-	}
-
-	if (!ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm1a_cnt_blk.address)) {
-		status = acpi_cm_fadt_register_error ("X_PM1a_CNT_BLK", 0,
-				  ACPI_FADT_OFFSET (Xpm1a_cnt_blk.address));
-	}
-
-	if (!ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm_tmr_blk.address)) {
-		status = acpi_cm_fadt_register_error ("X_PM_TMR_BLK", 0,
-				  ACPI_FADT_OFFSET (Xpm_tmr_blk.address));
-	}
-
-	if ((ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm2_cnt_blk.address) &&
-		!acpi_gbl_FADT->pm2_cnt_len))
-	{
-		status = acpi_cm_fadt_register_error ("PM2_CNT_LEN",
-				  (u32) acpi_gbl_FADT->pm2_cnt_len,
-				  ACPI_FADT_OFFSET (pm2_cnt_len));
-	}
-
-	if (acpi_gbl_FADT->pm_tm_len < 4) {
-		status = acpi_cm_fadt_register_error ("PM_TM_LEN",
-				  (u32) acpi_gbl_FADT->pm_tm_len,
-				  ACPI_FADT_OFFSET (pm_tm_len));
-	}
-
-	/* length of GPE blocks must be a multiple of 2 */
-
-
-	if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) &&
-		(acpi_gbl_FADT->gpe0blk_len & 1))
-	{
-		status = acpi_cm_fadt_register_error ("(x)GPE0_BLK_LEN",
-				  (u32) acpi_gbl_FADT->gpe0blk_len,
-				  ACPI_FADT_OFFSET (gpe0blk_len));
-	}
-
-	if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) &&
-		(acpi_gbl_FADT->gpe1_blk_len & 1))
-	{
-		status = acpi_cm_fadt_register_error ("(x)GPE1_BLK_LEN",
-				  (u32) acpi_gbl_FADT->gpe1_blk_len,
-				  ACPI_FADT_OFFSET (gpe1_blk_len));
-	}
-
-	return (status);
-}
-
-
-/******************************************************************************
- *
- * FUNCTION:    Acpi_cm_terminate
- *
- * PARAMETERS:  none
- *
- * RETURN:      none
- *
- * DESCRIPTION: free memory allocated for table storage.
- *
- ******************************************************************************/
-
-void
-acpi_cm_terminate (void)
-{
-
-
-	/* Free global tables, etc. */
-
-	if (acpi_gbl_gpe0enable_register_save) {
-		acpi_cm_free (acpi_gbl_gpe0enable_register_save);
-	}
-
-	if (acpi_gbl_gpe1_enable_register_save) {
-		acpi_cm_free (acpi_gbl_gpe1_enable_register_save);
-	}
-
-
-	return;
-}
-
-
-/******************************************************************************
- *
- * FUNCTION:    Acpi_cm_subsystem_shutdown
- *
- * PARAMETERS:  none
- *
- * RETURN:      none
- *
- * DESCRIPTION: Shutdown the various subsystems.  Don't delete the mutex
- *              objects here -- because the AML debugger may be still running.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_subsystem_shutdown (void)
-{
-
-	/* Just exit if subsystem is already shutdown */
-
-	if (acpi_gbl_shutdown) {
-		return (AE_OK);
-	}
-
-	/* Subsystem appears active, go ahead and shut it down */
-
-	acpi_gbl_shutdown = TRUE;
-
-	/* Close the Namespace */
-
-	acpi_ns_terminate ();
-
-	/* Close the Acpi_event Handling */
-
-	acpi_ev_terminate ();
-
-	/* Close the globals */
-
-	acpi_cm_terminate ();
-
-	/* Flush the local cache(s) */
-
-	acpi_cm_delete_generic_state_cache ();
-	acpi_cm_delete_object_cache ();
-	acpi_ds_delete_walk_state_cache ();
-
-	/* Close the Parser */
-
-	/* TBD: [Restructure] Acpi_ps_terminate () */
-
-	acpi_ps_delete_parse_cache ();
-
-	/* Debug only - display leftover memory allocation, if any */
-#ifdef ENABLE_DEBUGGER
-	acpi_cm_dump_current_allocations (ACPI_UINT32_MAX, NULL);
-#endif
-
-	return (AE_OK);
-}
-
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/common/cmobject.c linux/drivers/acpi/common/cmobject.c
--- v2.4.5/linux/drivers/acpi/common/cmobject.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/common/cmobject.c	Wed Dec 31 16:00:00 1969
@@ -1,618 +0,0 @@
-/******************************************************************************
- *
- * Module Name: cmobject - ACPI object create/delete/size/cache routines
- *              $Revision: 36 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acinterp.h"
-#include "acnamesp.h"
-#include "actables.h"
-#include "amlcode.h"
-
-
-#define _COMPONENT          MISCELLANEOUS
-	 MODULE_NAME         ("cmobject")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    _Cm_create_internal_object
- *
- * PARAMETERS:  Address             - Address of the memory to deallocate
- *              Component           - Component type of caller
- *              Module              - Source file name of caller
- *              Line                - Line number of caller
- *              Type                - ACPI Type of the new object
- *
- * RETURN:      Object              - The new object.  Null on failure
- *
- * DESCRIPTION: Create and initialize a new internal object.
- *
- * NOTE:        We always allocate the worst-case object descriptor because
- *              these objects are cached, and we want them to be
- *              one-size-satisifies-any-request.  This in itself may not be
- *              the most memory efficient, but the efficiency of the object
- *              cache should more than make up for this!
- *
- ******************************************************************************/
-
-ACPI_OPERAND_OBJECT  *
-_cm_create_internal_object (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id,
-	OBJECT_TYPE_INTERNAL    type)
-{
-	ACPI_OPERAND_OBJECT     *object;
-
-
-	/* Allocate the raw object descriptor */
-
-	object = _cm_allocate_object_desc (module_name, line_number, component_id);
-	if (!object) {
-		/* Allocation failure */
-
-		return (NULL);
-	}
-
-	/* Save the object type in the object descriptor */
-
-	object->common.type = type;
-
-	/* Init the reference count */
-
-	object->common.reference_count = 1;
-
-	/* Any per-type initialization should go here */
-
-
-	return (object);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_valid_internal_object
- *
- * PARAMETERS:  Operand             - Object to be validated
- *
- * RETURN:      Validate a pointer to be an ACPI_OPERAND_OBJECT
- *
- ******************************************************************************/
-
-u8
-acpi_cm_valid_internal_object (
-	void                    *object)
-{
-
-	/* Check for a null pointer */
-
-	if (!object) {
-		return (FALSE);
-	}
-
-	/* Check for a pointer within one of the ACPI tables */
-
-	if (acpi_tb_system_table_pointer (object)) {
-		return (FALSE);
-	}
-
-	/* Check the descriptor type field */
-
-	if (!VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_INTERNAL)) {
-		/* Not an ACPI internal object, do some further checking */
-
-
-
-
-		return (FALSE);
-	}
-
-
-	/* The object appears to be a valid ACPI_OPERAND_OBJECT  */
-
-	return (TRUE);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    _Cm_allocate_object_desc
- *
- * PARAMETERS:  Module_name         - Caller's module name (for error output)
- *              Line_number         - Caller's line number (for error output)
- *              Component_id        - Caller's component ID (for error output)
- *              Message             - Error message to use on failure
- *
- * RETURN:      Pointer to newly allocated object descriptor.  Null on error
- *
- * DESCRIPTION: Allocate a new object descriptor.  Gracefully handle
- *              error conditions.
- *
- ******************************************************************************/
-
-void *
-_cm_allocate_object_desc (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id)
-{
-	ACPI_OPERAND_OBJECT     *object;
-
-
-	acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
-
-	acpi_gbl_object_cache_requests++;
-
-	/* Check the cache first */
-
-	if (acpi_gbl_object_cache) {
-		/* There is an object available, use it */
-
-		object = acpi_gbl_object_cache;
-		acpi_gbl_object_cache = object->cache.next;
-		object->cache.next = NULL;
-
-		acpi_gbl_object_cache_hits++;
-		acpi_gbl_object_cache_depth--;
-
-		acpi_cm_release_mutex (ACPI_MTX_CACHES);
-	}
-
-	else {
-		/* The cache is empty, create a new object */
-
-		acpi_cm_release_mutex (ACPI_MTX_CACHES);
-
-		/* Attempt to allocate new descriptor */
-
-		object = _cm_callocate (sizeof (ACPI_OPERAND_OBJECT), component_id,
-				  module_name, line_number);
-		if (!object) {
-			/* Allocation failed */
-
-			_REPORT_ERROR (module_name, line_number, component_id,
-					  ("Could not allocate an object descriptor\n"));
-
-			return (NULL);
-		}
-
-		/* Memory allocation metrics - compiled out in non debug mode. */
-
-		INCREMENT_OBJECT_METRICS (sizeof (ACPI_OPERAND_OBJECT));
-	}
-
-	/* Mark the descriptor type */
-
-	object->common.data_type = ACPI_DESC_TYPE_INTERNAL;
-
-	return (object);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_delete_object_desc
- *
- * PARAMETERS:  Object          - Acpi internal object to be deleted
- *
- * RETURN:      None.
- *
- * DESCRIPTION: Free an ACPI object descriptor or add it to the object cache
- *
- ******************************************************************************/
-
-void
-acpi_cm_delete_object_desc (
-	ACPI_OPERAND_OBJECT     *object)
-{
-
-
-	/* Make sure that the object isn't already in the cache */
-
-	if (object->common.data_type == (ACPI_DESC_TYPE_INTERNAL | ACPI_CACHED_OBJECT)) {
-		return;
-	}
-
-	/* Object must be an ACPI_OPERAND_OBJECT  */
-
-	if (object->common.data_type != ACPI_DESC_TYPE_INTERNAL) {
-		return;
-	}
-
-
-	/* If cache is full, just free this object */
-
-	if (acpi_gbl_object_cache_depth >= MAX_OBJECT_CACHE_DEPTH) {
-		/*
-		 * Memory allocation metrics.  Call the macro here since we only
-		 * care about dynamically allocated objects.
-		 */
-		DECREMENT_OBJECT_METRICS (sizeof (ACPI_OPERAND_OBJECT));
-
-		acpi_cm_free (object);
-		return;
-	}
-
-	acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
-
-	/* Clear the entire object.  This is important! */
-
-	MEMSET (object, 0, sizeof (ACPI_OPERAND_OBJECT));
-	object->common.data_type = ACPI_DESC_TYPE_INTERNAL | ACPI_CACHED_OBJECT;
-
-	/* Put the object at the head of the global cache list */
-
-	object->cache.next = acpi_gbl_object_cache;
-	acpi_gbl_object_cache = object;
-	acpi_gbl_object_cache_depth++;
-
-
-	acpi_cm_release_mutex (ACPI_MTX_CACHES);
-	return;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_delete_object_cache
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Purge the global state object cache.  Used during subsystem
- *              termination.
- *
- ******************************************************************************/
-
-void
-acpi_cm_delete_object_cache (
-	void)
-{
-	ACPI_OPERAND_OBJECT     *next;
-
-
-	/* Traverse the global cache list */
-
-	while (acpi_gbl_object_cache) {
-		/* Delete one cached state object */
-
-		next = acpi_gbl_object_cache->cache.next;
-		acpi_gbl_object_cache->cache.next = NULL;
-
-		/*
-		 * Memory allocation metrics.  Call the macro here since we only
-		 * care about dynamically allocated objects.
-		 */
-		DECREMENT_OBJECT_METRICS (sizeof (ACPI_OPERAND_OBJECT));
-
-		acpi_cm_free (acpi_gbl_object_cache);
-		acpi_gbl_object_cache = next;
-		acpi_gbl_object_cache_depth--;
-	}
-
-	return;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_init_static_object
- *
- * PARAMETERS:  Obj_desc            - Pointer to a "static" object - on stack
- *                                    or in the data segment.
- *
- * RETURN:      None.
- *
- * DESCRIPTION: Initialize a static object.  Sets flags to disallow dynamic
- *              deletion of the object.
- *
- ******************************************************************************/
-
-void
-acpi_cm_init_static_object (
-	ACPI_OPERAND_OBJECT     *obj_desc)
-{
-
-
-	if (!obj_desc) {
-		return;
-	}
-
-
-	/*
-	 * Clear the entire descriptor
-	 */
-	MEMSET ((void *) obj_desc, 0, sizeof (ACPI_OPERAND_OBJECT));
-
-
-	/*
-	 * Initialize the header fields
-	 * 1) This is an ACPI_OPERAND_OBJECT  descriptor
-	 * 2) The size is the full object (worst case)
-	 * 3) The flags field indicates static allocation
-	 * 4) Reference count starts at one (not really necessary since the
-	 *    object can't be deleted, but keeps everything sane)
-	 */
-
-	obj_desc->common.data_type      = ACPI_DESC_TYPE_INTERNAL;
-	obj_desc->common.flags          = AOPOBJ_STATIC_ALLOCATION;
-	obj_desc->common.reference_count = 1;
-
-	return;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_get_simple_object_size
- *
- * PARAMETERS:  *Internal_object    - Pointer to the object we are examining
- *              *Ret_length         - Where the length is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: This function is called to determine the space required to
- *              contain a simple object for return to an API user.
- *
- *              The length includes the object structure plus any additional
- *              needed space.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_get_simple_object_size (
-	ACPI_OPERAND_OBJECT     *internal_object,
-	u32                     *obj_length)
-{
-	u32                     length;
-	ACPI_STATUS             status = AE_OK;
-
-
-	/* Handle a null object (Could be a uninitialized package element -- which is legal) */
-
-	if (!internal_object) {
-		*obj_length = 0;
-		return (AE_OK);
-	}
-
-
-	/* Start with the length of the Acpi object */
-
-	length = sizeof (ACPI_OBJECT);
-
-	if (VALID_DESCRIPTOR_TYPE (internal_object, ACPI_DESC_TYPE_NAMED)) {
-		/* Object is a named object (reference), just return the length */
-
-		*obj_length = (u32) ROUND_UP_TO_NATIVE_WORD (length);
-		return (status);
-	}
-
-
-	/*
-	 * The final length depends on the object type
-	 * Strings and Buffers are packed right up against the parent object and
-	 * must be accessed bytewise or there may be alignment problems.
-	 *
-	 * TBD:[Investigate] do strings and buffers require alignment also?
-	 */
-
-	switch (internal_object->common.type)
-	{
-
-	case ACPI_TYPE_STRING:
-
-		length += internal_object->string.length + 1;
-		break;
-
-
-	case ACPI_TYPE_BUFFER:
-
-		length += internal_object->buffer.length;
-		break;
-
-
-	case ACPI_TYPE_INTEGER:
-	case ACPI_TYPE_PROCESSOR:
-	case ACPI_TYPE_POWER:
-
-		/*
-		 * No extra data for these types
-		 */
-		break;
-
-
-	case INTERNAL_TYPE_REFERENCE:
-
-		/*
-		 * The only type that should be here is opcode AML_NAMEPATH_OP -- since
-		 * this means an object reference
-		 */
-		if (internal_object->reference.op_code != AML_NAMEPATH_OP) {
-			status = AE_TYPE;
-		}
-		break;
-
-
-	default:
-
-		status = AE_TYPE;
-		break;
-	}
-
-
-	/*
-	 * Account for the space required by the object rounded up to the next
-	 * multiple of the machine word size.  This keeps each object aligned
-	 * on a machine word boundary. (preventing alignment faults on some
-	 * machines.)
-	 */
-	*obj_length = (u32) ROUND_UP_TO_NATIVE_WORD (length);
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_copy_package_to_internal
- *
- * PARAMETERS:  ACPI_PKG_CALLBACK
- *
- * RETURN:      Status          - the status of the call
- *
- * DESCRIPTION:
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_get_element_length (
-	u8                      object_type,
-	ACPI_OPERAND_OBJECT     *source_object,
-	ACPI_GENERIC_STATE      *state,
-	void                    *context)
-{
-	ACPI_STATUS             status = AE_OK;
-	ACPI_PKG_INFO           *info = (ACPI_PKG_INFO *) context;
-	u32                     object_space;
-
-
-	switch (object_type)
-	{
-	case 0:
-
-		/*
-		 * Simple object - just get the size (Null object/entry is handled
-		 * here also) and sum it into the running package length
-		 */
-		status = acpi_cm_get_simple_object_size (source_object, &object_space);
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-
-		info->length += object_space;
-		break;
-
-
-	case 1:
-		/* Package - nothing much to do here, let the walk handle it */
-
-		info->num_packages++;
-		state->pkg.this_target_obj = NULL;
-		break;
-
-	default:
-		return (AE_BAD_PARAMETER);
-	}
-
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_get_package_object_size
- *
- * PARAMETERS:  *Internal_object    - Pointer to the object we are examining
- *              *Ret_length         - Where the length is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: This function is called to determine the space required to
- *              contain a package object for return to an API user.
- *
- *              This is moderately complex since a package contains other
- *              objects including packages.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_get_package_object_size (
-	ACPI_OPERAND_OBJECT     *internal_object,
-	u32                     *obj_length)
-{
-	ACPI_STATUS             status;
-	ACPI_PKG_INFO           info;
-
-
-	info.length      = 0;
-	info.object_space = 0;
-	info.num_packages = 1;
-
-	status = acpi_cm_walk_package_tree (internal_object, NULL,
-			 acpi_cm_get_element_length, &info);
-
-	/*
-	 * We have handled all of the objects in all levels of the package.
-	 * just add the length of the package objects themselves.
-	 * Round up to the next machine word.
-	 */
-	info.length += ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)) *
-			  info.num_packages;
-
-	/* Return the total package length */
-
-	*obj_length = info.length;
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_get_object_size
- *
- * PARAMETERS:  *Internal_object    - Pointer to the object we are examining
- *              *Ret_length         - Where the length will be returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: This function is called to determine the space required to
- *              contain an object for return to an API user.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_get_object_size(
-	ACPI_OPERAND_OBJECT     *internal_object,
-	u32                     *obj_length)
-{
-	ACPI_STATUS             status;
-
-
-	if ((VALID_DESCRIPTOR_TYPE (internal_object, ACPI_DESC_TYPE_INTERNAL)) &&
-		(IS_THIS_OBJECT_TYPE (internal_object, ACPI_TYPE_PACKAGE)))
-	{
-		status = acpi_cm_get_package_object_size (internal_object, obj_length);
-	}
-
-	else {
-		status = acpi_cm_get_simple_object_size (internal_object, obj_length);
-	}
-
-	return (status);
-}
-
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/common/cmutils.c linux/drivers/acpi/common/cmutils.c
--- v2.4.5/linux/drivers/acpi/common/cmutils.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/common/cmutils.c	Wed Dec 31 16:00:00 1969
@@ -1,952 +0,0 @@
-/*******************************************************************************
- *
- * Module Name: cmutils - common utility procedures
- *              $Revision: 27 $
- *
- ******************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acevents.h"
-#include "achware.h"
-#include "acnamesp.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acdebug.h"
-
-
-#define _COMPONENT          MISCELLANEOUS
-	 MODULE_NAME         ("cmutils")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_valid_acpi_name
- *
- * PARAMETERS:  Character           - The character to be examined
- *
- * RETURN:      1 if Character may appear in a name, else 0
- *
- * DESCRIPTION: Check for a valid ACPI name.  Each character must be one of:
- *              1) Upper case alpha
- *              2) numeric
- *              3) underscore
- *
- ******************************************************************************/
-
-u8
-acpi_cm_valid_acpi_name (
-	u32                     name)
-{
-	NATIVE_CHAR             *name_ptr = (NATIVE_CHAR *) &name;
-	u32                     i;
-
-
-	for (i = 0; i < ACPI_NAME_SIZE; i++) {
-		if (!((name_ptr[i] == '_') ||
-			  (name_ptr[i] >= 'A' && name_ptr[i] <= 'Z') ||
-			  (name_ptr[i] >= '0' && name_ptr[i] <= '9')))
-		{
-			return (FALSE);
-		}
-	}
-
-
-	return (TRUE);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_valid_acpi_character
- *
- * PARAMETERS:  Character           - The character to be examined
- *
- * RETURN:      1 if Character may appear in a name, else 0
- *
- * DESCRIPTION: Check for a printable character
- *
- ******************************************************************************/
-
-u8
-acpi_cm_valid_acpi_character (
-	NATIVE_CHAR             character)
-{
-
-	return ((u8)   ((character == '_') ||
-			   (character >= 'A' && character <= 'Z') ||
-			   (character >= '0' && character <= '9')));
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_mutex_initialize
- *
- * PARAMETERS:  None.
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Create the system mutex objects.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_mutex_initialize (
-	void)
-{
-	u32                     i;
-	ACPI_STATUS             status;
-
-
-	/*
-	 * Create each of the predefined mutex objects
-	 */
-	for (i = 0; i < NUM_MTX; i++) {
-		status = acpi_cm_create_mutex (i);
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-	}
-
-	return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_mutex_terminate
- *
- * PARAMETERS:  None.
- *
- * RETURN:      None.
- *
- * DESCRIPTION: Delete all of the system mutex objects.
- *
- ******************************************************************************/
-
-void
-acpi_cm_mutex_terminate (
-	void)
-{
-	u32                     i;
-
-
-	/*
-	 * Delete each predefined mutex object
-	 */
-	for (i = 0; i < NUM_MTX; i++) {
-		acpi_cm_delete_mutex (i);
-	}
-
-	return;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_create_mutex
- *
- * PARAMETERS:  Mutex_iD        - ID of the mutex to be created
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Create a mutex object.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_create_mutex (
-	ACPI_MUTEX_HANDLE       mutex_id)
-{
-	ACPI_STATUS             status = AE_OK;
-
-
-	if (mutex_id > MAX_MTX) {
-		return (AE_BAD_PARAMETER);
-	}
-
-
-	if (!acpi_gbl_acpi_mutex_info[mutex_id].mutex) {
-		status = acpi_os_create_semaphore (1, 1,
-				   &acpi_gbl_acpi_mutex_info[mutex_id].mutex);
-		acpi_gbl_acpi_mutex_info[mutex_id].locked = FALSE;
-		acpi_gbl_acpi_mutex_info[mutex_id].use_count = 0;
-	}
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_delete_mutex
- *
- * PARAMETERS:  Mutex_iD        - ID of the mutex to be deleted
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Delete a mutex object.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_delete_mutex (
-	ACPI_MUTEX_HANDLE       mutex_id)
-{
-	ACPI_STATUS             status;
-
-
-	if (mutex_id > MAX_MTX) {
-		return (AE_BAD_PARAMETER);
-	}
-
-
-	status = acpi_os_delete_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex);
-
-	acpi_gbl_acpi_mutex_info[mutex_id].mutex = NULL;
-	acpi_gbl_acpi_mutex_info[mutex_id].locked = FALSE;
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_acquire_mutex
- *
- * PARAMETERS:  Mutex_iD        - ID of the mutex to be acquired
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Acquire a mutex object.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_acquire_mutex (
-	ACPI_MUTEX_HANDLE       mutex_id)
-{
-	ACPI_STATUS             status;
-
-
-	if (mutex_id > MAX_MTX) {
-		return (AE_BAD_PARAMETER);
-	}
-
-
-	status = acpi_os_wait_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex,
-			   1, WAIT_FOREVER);
-
-	if (ACPI_SUCCESS (status)) {
-		acpi_gbl_acpi_mutex_info[mutex_id].locked = TRUE;
-		acpi_gbl_acpi_mutex_info[mutex_id].use_count++;
-	}
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_release_mutex
- *
- * PARAMETERS:  Mutex_iD        - ID of the mutex to be released
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Release a mutex object.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_release_mutex (
-	ACPI_MUTEX_HANDLE       mutex_id)
-{
-	ACPI_STATUS             status;
-
-
-	if (mutex_id > MAX_MTX) {
-		return (AE_BAD_PARAMETER);
-	}
-
-
-	acpi_gbl_acpi_mutex_info[mutex_id].locked = FALSE; /* Mark before unlocking */
-
-	status = acpi_os_signal_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex, 1);
-
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_create_update_state_and_push
- *
- * PARAMETERS:  *Object         - Object to be added to the new state
- *              Action          - Increment/Decrement
- *              State_list      - List the state will be added to
- *
- * RETURN:      None
- *
- * DESCRIPTION: Create a new state and push it
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_create_update_state_and_push (
-	ACPI_OPERAND_OBJECT     *object,
-	u16                     action,
-	ACPI_GENERIC_STATE      **state_list)
-{
-	ACPI_GENERIC_STATE       *state;
-
-
-	/* Ignore null objects; these are expected */
-
-	if (!object) {
-		return (AE_OK);
-	}
-
-	state = acpi_cm_create_update_state (object, action);
-	if (!state) {
-		return (AE_NO_MEMORY);
-	}
-
-
-	acpi_cm_push_generic_state (state_list, state);
-	return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_create_pkg_state_and_push
- *
- * PARAMETERS:  *Object         - Object to be added to the new state
- *              Action          - Increment/Decrement
- *              State_list      - List the state will be added to
- *
- * RETURN:      None
- *
- * DESCRIPTION: Create a new state and push it
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_create_pkg_state_and_push (
-	void                    *internal_object,
-	void                    *external_object,
-	u16                     index,
-	ACPI_GENERIC_STATE      **state_list)
-{
-	ACPI_GENERIC_STATE       *state;
-
-
-	state = acpi_cm_create_pkg_state (internal_object, external_object, index);
-	if (!state) {
-		return (AE_NO_MEMORY);
-	}
-
-
-	acpi_cm_push_generic_state (state_list, state);
-	return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_push_generic_state
- *
- * PARAMETERS:  List_head           - Head of the state stack
- *              State               - State object to push
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Push a state object onto a state stack
- *
- ******************************************************************************/
-
-void
-acpi_cm_push_generic_state (
-	ACPI_GENERIC_STATE      **list_head,
-	ACPI_GENERIC_STATE      *state)
-{
-	/* Push the state object onto the front of the list (stack) */
-
-	state->common.next = *list_head;
-	*list_head = state;
-
-	return;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_pop_generic_state
- *
- * PARAMETERS:  List_head           - Head of the state stack
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Pop a state object from a state stack
- *
- ******************************************************************************/
-
-ACPI_GENERIC_STATE *
-acpi_cm_pop_generic_state (
-	ACPI_GENERIC_STATE      **list_head)
-{
-	ACPI_GENERIC_STATE      *state;
-
-
-	/* Remove the state object at the head of the list (stack) */
-
-	state = *list_head;
-	if (state) {
-		/* Update the list head */
-
-		*list_head = state->common.next;
-	}
-
-	return (state);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_create_generic_state
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Create a generic state object.  Attempt to obtain one from
- *              the global state cache;  If none available, create a new one.
- *
- ******************************************************************************/
-
-ACPI_GENERIC_STATE *
-acpi_cm_create_generic_state (void)
-{
-	ACPI_GENERIC_STATE      *state;
-
-
-	acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
-
-	acpi_gbl_state_cache_requests++;
-
-	/* Check the cache first */
-
-	if (acpi_gbl_generic_state_cache) {
-		/* There is an object available, use it */
-
-		state = acpi_gbl_generic_state_cache;
-		acpi_gbl_generic_state_cache = state->common.next;
-		state->common.next = NULL;
-
-		acpi_gbl_state_cache_hits++;
-		acpi_gbl_generic_state_cache_depth--;
-
-		acpi_cm_release_mutex (ACPI_MTX_CACHES);
-
-	}
-
-	else {
-		/* The cache is empty, create a new object */
-
-		acpi_cm_release_mutex (ACPI_MTX_CACHES);
-
-		state = acpi_cm_callocate (sizeof (ACPI_GENERIC_STATE));
-	}
-
-	/* Initialize */
-
-	if (state) {
-		/* Always zero out the object before init */
-
-		MEMSET (state, 0, sizeof (ACPI_GENERIC_STATE));
-
-		state->common.data_type = ACPI_DESC_TYPE_STATE;
-	}
-
-	return (state);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_create_update_state
- *
- * PARAMETERS:  Object              - Initial Object to be installed in the
- *                                    state
- *              Action              - Update action to be performed
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
- *              to update reference counts and delete complex objects such
- *              as packages.
- *
- ******************************************************************************/
-
-ACPI_GENERIC_STATE *
-acpi_cm_create_update_state (
-	ACPI_OPERAND_OBJECT     *object,
-	u16                     action)
-{
-	ACPI_GENERIC_STATE      *state;
-
-
-	/* Create the generic state object */
-
-	state = acpi_cm_create_generic_state ();
-	if (!state) {
-		return (NULL);
-	}
-
-	/* Init fields specific to the update struct */
-
-	state->update.object = object;
-	state->update.value  = action;
-
-	return (state);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_create_pkg_state
- *
- * PARAMETERS:  Object              - Initial Object to be installed in the
- *                                    state
- *              Action              - Update action to be performed
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
- *              to update reference counts and delete complex objects such
- *              as packages.
- *
- ******************************************************************************/
-
-ACPI_GENERIC_STATE *
-acpi_cm_create_pkg_state (
-	void                    *internal_object,
-	void                    *external_object,
-	u16                     index)
-{
-	ACPI_GENERIC_STATE      *state;
-
-
-	/* Create the generic state object */
-
-	state = acpi_cm_create_generic_state ();
-	if (!state) {
-		return (NULL);
-	}
-
-	/* Init fields specific to the update struct */
-
-	state->pkg.source_object = (ACPI_OPERAND_OBJECT *) internal_object;
-	state->pkg.dest_object  = external_object;
-	state->pkg.index        = index;
-	state->pkg.num_packages = 1;
-
-	return (state);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_create_control_state
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Create a "Control State" - a flavor of the generic state used
- *              to support nested IF/WHILE constructs in the AML.
- *
- ******************************************************************************/
-
-ACPI_GENERIC_STATE *
-acpi_cm_create_control_state (
-	void)
-{
-	ACPI_GENERIC_STATE      *state;
-
-
-	/* Create the generic state object */
-
-	state = acpi_cm_create_generic_state ();
-	if (!state) {
-		return (NULL);
-	}
-
-
-	/* Init fields specific to the control struct */
-
-	state->common.state = CONTROL_CONDITIONAL_EXECUTING;
-
-	return (state);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_delete_generic_state
- *
- * PARAMETERS:  State               - The state object to be deleted
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Put a state object back into the global state cache.  The object
- *              is not actually freed at this time.
- *
- ******************************************************************************/
-
-void
-acpi_cm_delete_generic_state (
-	ACPI_GENERIC_STATE      *state)
-{
-
-	/* If cache is full, just free this state object */
-
-	if (acpi_gbl_generic_state_cache_depth >= MAX_STATE_CACHE_DEPTH) {
-		acpi_cm_free (state);
-	}
-
-	/* Otherwise put this object back into the cache */
-
-	else {
-		acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
-
-		/* Clear the state */
-
-		MEMSET (state, 0, sizeof (ACPI_GENERIC_STATE));
-		state->common.data_type = ACPI_DESC_TYPE_STATE;
-
-		/* Put the object at the head of the global cache list */
-
-		state->common.next = acpi_gbl_generic_state_cache;
-		acpi_gbl_generic_state_cache = state;
-		acpi_gbl_generic_state_cache_depth++;
-
-
-		acpi_cm_release_mutex (ACPI_MTX_CACHES);
-	}
-	return;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_delete_generic_state_cache
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Purge the global state object cache.  Used during subsystem
- *              termination.
- *
- ******************************************************************************/
-
-void
-acpi_cm_delete_generic_state_cache (
-	void)
-{
-	ACPI_GENERIC_STATE      *next;
-
-
-	/* Traverse the global cache list */
-
-	while (acpi_gbl_generic_state_cache) {
-		/* Delete one cached state object */
-
-		next = acpi_gbl_generic_state_cache->common.next;
-		acpi_cm_free (acpi_gbl_generic_state_cache);
-		acpi_gbl_generic_state_cache = next;
-		acpi_gbl_generic_state_cache_depth--;
-	}
-
-	return;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_resolve_package_references
- *
- * PARAMETERS:  Obj_desc        - The Package object on which to resolve refs
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Walk through a package and turn internal references into values
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_resolve_package_references (
-	ACPI_OPERAND_OBJECT     *obj_desc)
-{
-	u32                     count;
-	ACPI_OPERAND_OBJECT     *sub_object;
-
-
-	if (obj_desc->common.type != ACPI_TYPE_PACKAGE) {
-		/* The object must be a package */
-
-		REPORT_ERROR (("Must resolve Package Refs on a Package\n"));
-		return(AE_ERROR);
-	}
-
-	/*
-	 * TBD: what about nested packages? */
-
-	for (count = 0; count < obj_desc->package.count; count++) {
-		sub_object = obj_desc->package.elements[count];
-
-		if (sub_object->common.type == INTERNAL_TYPE_REFERENCE) {
-			if (sub_object->reference.op_code == AML_ZERO_OP) {
-				sub_object->common.type = ACPI_TYPE_INTEGER;
-				sub_object->integer.value = 0;
-			}
-			else if (sub_object->reference.op_code == AML_ONE_OP) {
-				sub_object->common.type = ACPI_TYPE_INTEGER;
-				sub_object->integer.value = 1;
-			}
-			else if (sub_object->reference.op_code == AML_ONES_OP) {
-				sub_object->common.type = ACPI_TYPE_INTEGER;
-				sub_object->integer.value = ACPI_INTEGER_MAX;
-			}
-		}
-	}
-
-	return(AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_cm_walk_package_tree
- *
- * PARAMETERS:  Obj_desc        - The Package object on which to resolve refs
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Walk through a package
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_cm_walk_package_tree (
-	ACPI_OPERAND_OBJECT     *source_object,
-	void                    *target_object,
-	ACPI_PKG_CALLBACK       walk_callback,
-	void                    *context)
-{
-	ACPI_STATUS             status = AE_OK;
-	ACPI_GENERIC_STATE      *state_list = NULL;
-	ACPI_GENERIC_STATE      *state;
-	u32                     this_index;
-	ACPI_OPERAND_OBJECT     *this_source_obj;
-
-
-	state = acpi_cm_create_pkg_state (source_object, target_object, 0);
-	if (!state) {
-		return (AE_NO_MEMORY);
-	}
-
-	while (state) {
-		this_index       = state->pkg.index;
-		this_source_obj  = (ACPI_OPERAND_OBJECT *)
-				   state->pkg.source_object->package.elements[this_index];
-
-		/*
-		 * Check for
-		 * 1) An uninitialized package element.  It is completely
-		 *      legal to declare a package and leave it uninitialized
-		 * 2) Not an internal object - can be a namespace node instead
-		 * 3) Any type other than a package.  Packages are handled in else case below.
-		 */
-		if ((!this_source_obj) ||
-			(!VALID_DESCRIPTOR_TYPE (
-					this_source_obj, ACPI_DESC_TYPE_INTERNAL)) ||
-			(!IS_THIS_OBJECT_TYPE (
-					this_source_obj, ACPI_TYPE_PACKAGE)))
-		{
-
-			status = walk_callback (0, this_source_obj, state, context);
-			if (ACPI_FAILURE (status)) {
-				/* TBD: must delete package created up to this point */
-
-				return (status);
-			}
-
-			state->pkg.index++;
-			while (state->pkg.index >= state->pkg.source_object->package.count) {
-				/*
-				 * We've handled all of the objects at this level,  This means
-				 * that we have just completed a package.  That package may
-				 * have contained one or more packages itself.
-				 *
-				 * Delete this state and pop the previous state (package).
-				 */
-				acpi_cm_delete_generic_state (state);
-				state = acpi_cm_pop_generic_state (&state_list);
-
-
-				/* Finished when there are no more states */
-
-				if (!state) {
-					/*
-					 * We have handled all of the objects in the top level
-					 * package just add the length of the package objects
-					 * and exit
-					 */
-					return (AE_OK);
-				}
-
-				/*
-				 * Go back up a level and move the index past the just
-				 * completed package object.
-				 */
-				state->pkg.index++;
-			}
-		}
-
-		else {
-			/* This is a sub-object of type package */
-
-			status = walk_callback (1, this_source_obj, state, context);
-			if (ACPI_FAILURE (status)) {
-				/* TBD: must delete package created up to this point */
-
-				return (status);
-			}
-
-
-			/*
-			 * The callback above returned a new target package object.
-			 */
-
-			/*
-			 * Push the current state and create a new one
-			 */
-			acpi_cm_push_generic_state (&state_list, state);
-			state = acpi_cm_create_pkg_state (this_source_obj, state->pkg.this_target_obj, 0);
-			if (!state) {
-				/* TBD: must delete package created up to this point */
-
-				return (AE_NO_MEMORY);
-			}
-		}
-	}
-
-	/* We should never get here */
-
-	return (AE_AML_INTERNAL);
-
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    _Report_error
- *
- * PARAMETERS:  Module_name         - Caller's module name (for error output)
- *              Line_number         - Caller's line number (for error output)
- *              Component_id        - Caller's component ID (for error output)
- *              Message             - Error message to use on failure
- *
- * RETURN:      None
- *
- * DESCRIPTION: Print error message
- *
- ******************************************************************************/
-
-void
-_report_error (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id)
-{
-
-
-	acpi_os_printf ("%8s-%04d: *** Error: ", module_name, line_number);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    _Report_warning
- *
- * PARAMETERS:  Module_name         - Caller's module name (for error output)
- *              Line_number         - Caller's line number (for error output)
- *              Component_id        - Caller's component ID (for error output)
- *              Message             - Error message to use on failure
- *
- * RETURN:      None
- *
- * DESCRIPTION: Print warning message
- *
- ******************************************************************************/
-
-void
-_report_warning (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id)
-{
-
-	acpi_os_printf ("%8s-%04d: *** Warning: ", module_name, line_number);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    _Report_info
- *
- * PARAMETERS:  Module_name         - Caller's module name (for error output)
- *              Line_number         - Caller's line number (for error output)
- *              Component_id        - Caller's component ID (for error output)
- *              Message             - Error message to use on failure
- *
- * RETURN:      None
- *
- * DESCRIPTION: Print information message
- *
- ******************************************************************************/
-
-void
-_report_info (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id)
-{
-
-	acpi_os_printf ("%8s-%04d: *** Info: ", module_name, line_number);
-}
-
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/common/cmxface.c linux/drivers/acpi/common/cmxface.c
--- v2.4.5/linux/drivers/acpi/common/cmxface.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/common/cmxface.c	Wed Dec 31 16:00:00 1969
@@ -1,396 +0,0 @@
-/******************************************************************************
- *
- * Module Name: cmxface - External interfaces for "global" ACPI functions
- *              $Revision: 64 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acevents.h"
-#include "achware.h"
-#include "acnamesp.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acdebug.h"
-
-
-#define _COMPONENT          MISCELLANEOUS
-	 MODULE_NAME         ("cmxface")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_initialize_subsystem
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Initializes all global variables.  This is the first function
- *              called, so any early initialization belongs here.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_initialize_subsystem (
-	void)
-{
-	ACPI_STATUS             status;
-
-
-	/* Initialize all globals used by the subsystem */
-
-	acpi_cm_init_globals ();
-
-	/* Initialize the OS-Dependent layer */
-
-	status = acpi_os_initialize ();
-	if (ACPI_FAILURE (status)) {
-		REPORT_ERROR (("OSD failed to initialize, %s\n",
-			acpi_cm_format_exception (status)));
-		return (status);
-	}
-
-	/* Create the default mutex objects */
-
-	status = acpi_cm_mutex_initialize ();
-	if (ACPI_FAILURE (status)) {
-		REPORT_ERROR (("Global mutex creation failure, %s\n",
-			acpi_cm_format_exception (status)));
-		return (status);
-	}
-
-	/*
-	 * Initialize the namespace manager and
-	 * the root of the namespace tree
-	 */
-
-	status = acpi_ns_root_initialize ();
-	if (ACPI_FAILURE (status)) {
-		REPORT_ERROR (("Namespace initialization failure, %s\n",
-			acpi_cm_format_exception (status)));
-		return (status);
-	}
-
-
-	/* If configured, initialize the AML debugger */
-
-	DEBUGGER_EXEC (acpi_db_initialize ());
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_enable_subsystem
- *
- * PARAMETERS:  Flags           - Init/enable Options
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Completes the subsystem initialization including hardware.
- *              Puts system into ACPI mode if it isn't already.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_enable_subsystem (
-	u32                     flags)
-{
-	ACPI_STATUS             status = AE_OK;
-
-
-	/* Sanity check the FADT for valid values */
-
-	status = acpi_cm_validate_fadt ();
-	if (ACPI_FAILURE (status)) {
-		return (status);
-	}
-
-	/*
-	 * Install the default Op_region handlers. These are
-	 * installed unless other handlers have already been
-	 * installed via the Install_address_space_handler interface
-	 */
-
-	if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
-		status = acpi_ev_install_default_address_space_handlers ();
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-	}
-
-	/*
-	 * We must initialize the hardware before we can enable ACPI.
-	 */
-
-	if (!(flags & ACPI_NO_HARDWARE_INIT)) {
-		status = acpi_hw_initialize ();
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-	}
-
-	/*
-	 * Enable ACPI on this platform
-	 */
-
-	if (!(flags & ACPI_NO_ACPI_ENABLE)) {
-		status = acpi_enable ();
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-	}
-
-	/*
-	 * Note:
-	 * We must have the hardware AND events initialized before we can execute
-	 * ANY control methods SAFELY.  Any control method can require ACPI hardware
-	 * support, so the hardware MUST be initialized before execution!
-	 */
-
-	if (!(flags & ACPI_NO_EVENT_INIT)) {
-		status = acpi_ev_initialize ();
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-	}
-
-
-	/*
-	 * Initialize all device objects in the namespace
-	 * This runs the _STA and _INI methods.
-	 */
-
-	if (!(flags & ACPI_NO_DEVICE_INIT)) {
-		status = acpi_ns_initialize_devices ();
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-	}
-
-
-	/*
-	 * Initialize the objects that remain uninitialized.  This
-	 * runs the executable AML that is part of the declaration of Op_regions
-	 * and Fields.
-	 */
-
-	if (!(flags & ACPI_NO_OBJECT_INIT)) {
-		status = acpi_ns_initialize_objects ();
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-	}
-
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_terminate
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Shutdown the ACPI subsystem.  Release all resources.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_terminate (void)
-{
-
-	/* Terminate the AML Debuger if present */
-
-	DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE);
-
-	/* TBD: [Investigate] This is no longer needed?*/
-/*    Acpi_cm_release_mutex (ACPI_MTX_DEBUG_CMD_READY); */
-
-
-	/* Shutdown and free all resources */
-
-	acpi_cm_subsystem_shutdown ();
-
-
-	/* Free the mutex objects */
-
-	acpi_cm_mutex_terminate ();
-
-
-	/* Now we can shutdown the OS-dependent layer */
-
-	acpi_os_terminate ();
-
-	return (AE_OK);
-}
-
-
-/******************************************************************************
- *
- * FUNCTION:    Acpi_get_system_info
- *
- * PARAMETERS:  Out_buffer      - a pointer to a buffer to receive the
- *                                resources for the device
- *              Buffer_length   - the number of bytes available in the buffer
- *
- * RETURN:      Status          - the status of the call
- *
- * DESCRIPTION: This function is called to get information about the current
- *              state of the ACPI subsystem.  It will return system information
- *              in the Out_buffer.
- *
- *              If the function fails an appropriate status will be returned
- *              and the value of Out_buffer is undefined.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_get_system_info (
-	ACPI_BUFFER             *out_buffer)
-{
-	ACPI_SYSTEM_INFO        *info_ptr;
-	u32                     i;
-
-
-	/*
-	 *  Must have a valid buffer
-	 */
-	if ((!out_buffer)         ||
-		(!out_buffer->pointer))
-	{
-		return (AE_BAD_PARAMETER);
-	}
-
-	if (out_buffer->length < sizeof (ACPI_SYSTEM_INFO)) {
-		/*
-		 *  Caller's buffer is too small
-		 */
-		out_buffer->length = sizeof (ACPI_SYSTEM_INFO);
-
-		return (AE_BUFFER_OVERFLOW);
-	}
-
-
-	/*
-	 *  Set return length and get data
-	 */
-	out_buffer->length = sizeof (ACPI_SYSTEM_INFO);
-	info_ptr = (ACPI_SYSTEM_INFO *) out_buffer->pointer;
-
-	info_ptr->acpi_ca_version   = ACPI_CA_VERSION;
-
-	/* System flags (ACPI capabilities) */
-
-	info_ptr->flags             = acpi_gbl_system_flags;
-
-	/* Timer resolution - 24 or 32 bits  */
-	if (!acpi_gbl_FADT) {
-		info_ptr->timer_resolution = 0;
-	}
-	else if (acpi_gbl_FADT->tmr_val_ext == 0) {
-		info_ptr->timer_resolution = 24;
-	}
-	else {
-		info_ptr->timer_resolution = 32;
-	}
-
-	/* Clear the reserved fields */
-
-	info_ptr->reserved1         = 0;
-	info_ptr->reserved2         = 0;
-
-	/* Current debug levels */
-
-	info_ptr->debug_layer       = acpi_dbg_layer;
-	info_ptr->debug_level       = acpi_dbg_level;
-
-	/* Current status of the ACPI tables, per table type */
-
-	info_ptr->num_table_types = NUM_ACPI_TABLES;
-	for (i = 0; i < NUM_ACPI_TABLES; i++) {
-		info_ptr->table_info[i].count = acpi_gbl_acpi_tables[i].count;
-	}
-
-	return (AE_OK);
-}
-
-
-/******************************************************************************
- *
- * FUNCTION:    Acpi_format_exception
- *
- * PARAMETERS:  Out_buffer      - a pointer to a buffer to receive the
- *                                exception name
- *
- * RETURN:      Status          - the status of the call
- *
- * DESCRIPTION: This function translates an ACPI exception into an ASCII string.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_format_exception (
-	ACPI_STATUS             exception,
-	ACPI_BUFFER             *out_buffer)
-{
-	u32                     length;
-	NATIVE_CHAR             *formatted_exception;
-
-
-	/*
-	 *  Must have a valid buffer
-	 */
-	if ((!out_buffer)         ||
-		(!out_buffer->pointer))
-	{
-		return (AE_BAD_PARAMETER);
-	}
-
-
-	/* Convert the exception code (Handles bad exception codes) */
-
-	formatted_exception = acpi_cm_format_exception (exception);
-
-	/*
-	 * Get length of string and check if it will fit in caller's buffer
-	 */
-
-	length = STRLEN (formatted_exception);
-	if (out_buffer->length < length) {
-		out_buffer->length = length;
-		return (AE_BUFFER_OVERFLOW);
-	}
-
-
-	/* Copy the string, all done */
-
-	STRCPY (out_buffer->pointer, formatted_exception);
-
-	return (AE_OK);
-}
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/cpu.c linux/drivers/acpi/cpu.c
--- v2.4.5/linux/drivers/acpi/cpu.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/cpu.c	Wed Dec 31 16:00:00 1969
@@ -1,353 +0,0 @@
-/*
- *  cpu.c - Processor handling
- *
- *  Copyright (C) 2000 Andrew Henroid
- *  Copyright (C) 2001 Andrew Grover
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/pm.h>
-#include <linux/acpi.h>
-#include "acpi.h"
-#include "driver.h"
-
-#define _COMPONENT	OS_DEPENDENT
-	MODULE_NAME	("cpu")
-
-u32 acpi_c2_exit_latency = ACPI_INFINITE;
-u32 acpi_c3_exit_latency = ACPI_INFINITE;
-u32 acpi_c2_enter_latency = ACPI_INFINITE;
-u32 acpi_c3_enter_latency = ACPI_INFINITE;
-u32 acpi_use_idle = TRUE;
-
-u32 acpi_c1_count = 0;
-u32 acpi_c2_count = 0;
-u32 acpi_c3_count = 0;
-
-static u32 acpi_pblk = ACPI_INVALID;
-static int acpi_c2_tested = 0;
-static int acpi_c3_tested = 0;
-static int acpi_max_c_state = 1;
-static int acpi_pm_tmr_len = 24;
-
-#define CPU_POWER_STATES	3
-#define MAX_C2_LATENCY		100
-#define MAX_C3_LATENCY		1000
-
-#define ACPI_STATE_C1		0
-#define ACPI_STATE_C2		1
-#define ACPI_STATE_C3		2
-
-/*
- * Clear busmaster activity flag
- */
-static inline void
-acpi_clear_bm_activity(void)
-{
-	acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, BM_STS, 1);
-}
-
-/*
- * Returns 1 if there has been busmaster activity
- */
-static inline int
-acpi_bm_activity(void)
-{
-	return acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, BM_STS);
-}
-
-/*
- * Set system to sleep through busmaster requests
- */
-static void
-acpi_sleep_on_busmaster(void)
-{
-	acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 1);
-}
-
-/*
- * Set system to wake on busmaster requests
- */
-static void
-acpi_wake_on_busmaster(void)
-{
-	acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 0);
-}
-
-u32
-acpi_read_pm_timer(void)
-{
-	return acpi_hw_register_read(ACPI_MTX_LOCK, PM_TIMER);
-}
-
-/*
- * Do a compare, accounting for 24/32bit rollover
- */
-static u32
-acpi_compare_pm_timers(u32 first, u32 second)
-{
-	if (first < second) {
-		return (second - first);
-	} else {
-		if (acpi_pm_tmr_len == 24)
-			return (second + (0xFFFFFF - first));
-		else
-			return (second + (0xFFFFFFFF - first));
-	}
-}
-
-
-/*
- * Idle loop (uniprocessor only)
- */
-static void
-acpi_idle(void)
-{
-	static int sleep_level = 1;
-	FADT_DESCRIPTOR *fadt = &acpi_fadt;
-
-	/*
-	 * start from the previous sleep level.
-	 * if not initialized, we goto sleep1
-	 */
-	if (sleep_level == 1
-	    || acpi_max_c_state < 2)
-		goto sleep1;
-
-	if (sleep_level == 2
-	    || acpi_max_c_state < 3)
-		goto sleep2;
-
-sleep3:
-	sleep_level = 3;
-	if (!acpi_c3_tested) {
-		DEBUG_PRINT(ACPI_INFO, ("C3 works\n"));
-		acpi_c3_tested = 1;
-	}
-	acpi_wake_on_busmaster();
-	if (fadt->Xpm2_cnt_blk.address)
-		goto sleep3_with_arbiter;
-
-	for (;;) {
-		unsigned long time;
-		unsigned long diff;
-		
-		__cli();
-		if (current->need_resched)
-			goto out;
-		if (acpi_bm_activity())
-			goto sleep2;
-
-		time = acpi_read_pm_timer();
-		acpi_c3_count++;
-		inb(acpi_pblk + ACPI_P_LVL3);
-		/* Dummy read, force synchronization with the PMU */
-		acpi_read_pm_timer();
-		diff = acpi_compare_pm_timers(time, acpi_read_pm_timer());
-
-		__sti();
-		if (diff < acpi_c3_exit_latency)
-			goto sleep1;
-	}
-
-sleep3_with_arbiter:
-	for (;;) {
-		unsigned long time;
-		unsigned long diff;
-
-		__cli();
-		if (current->need_resched)
-			goto out;
-		if (acpi_bm_activity())
-			goto sleep2;
-
-		time = acpi_read_pm_timer();
-		
-		/* Disable arbiter, park on CPU */
-		acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 1);
-		acpi_c3_count++;
-		inb(acpi_pblk + ACPI_P_LVL3);
-		/* Dummy read, force synchronization with the PMU */
-		acpi_read_pm_timer();
-		diff = acpi_compare_pm_timers(time, acpi_read_pm_timer());
-		/* Enable arbiter again.. */
-		acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 0);
-
-		__sti();
-		if (diff < acpi_c3_exit_latency)
-			goto sleep1;
-	}
-
-sleep2:
-	sleep_level = 2;
-	if (!acpi_c2_tested) {
-		DEBUG_PRINT(ACPI_INFO, ("C2 works\n"));
-		acpi_c2_tested = 1;
-	}
-	acpi_wake_on_busmaster();	/* Required to track BM activity.. */
-	for (;;) {
-		unsigned long time;
-		unsigned long diff;
-
-		__cli();
-		if (current->need_resched)
-			goto out;
-
-		time = acpi_read_pm_timer();
-		acpi_c2_count++;
-		inb(acpi_pblk + ACPI_P_LVL2);
-		/* Dummy read, force synchronization with the PMU */
-		acpi_read_pm_timer();
-		diff = acpi_compare_pm_timers(time, acpi_read_pm_timer());
-
-		__sti();
-		if (diff < acpi_c2_exit_latency)
-			goto sleep1;
-		if (acpi_bm_activity()) {
-			acpi_clear_bm_activity();
-			continue;
-		}
-		if (diff > acpi_c3_enter_latency
-		    && acpi_max_c_state >= 3)
-			goto sleep3;
-	}
-
-sleep1:
-	sleep_level = 1;
-	acpi_sleep_on_busmaster();
-	for (;;) {
-		unsigned long time;
-		unsigned long diff;
-
-		__cli();
-		if (current->need_resched)
-			goto out;
-		time = acpi_read_pm_timer();
-		acpi_c1_count++;
-		safe_halt();
-		diff = acpi_compare_pm_timers(time, acpi_read_pm_timer());
-		if (diff > acpi_c2_enter_latency
-		    && acpi_max_c_state >= 2)
-			goto sleep2;
-	}
-
-out:
-	__sti();
-}
-
-/*
- * Get processor information
- */
-static ACPI_STATUS
-acpi_found_cpu(ACPI_HANDLE handle, u32 level, void *ctx, void **value)
-{
-	ACPI_OBJECT obj;
-	ACPI_BUFFER buf;
-
-	buf.length = sizeof(obj);
-	buf.pointer = &obj;
-	if (!ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buf)))
-		return AE_OK;
-
-	DEBUG_PRINT(ACPI_INFO, ("PBLK %d @ 0x%04x:%d\n",
-			obj.processor.proc_id,
-			obj.processor.pblk_address,
-			obj.processor.pblk_length));
-
-	if (acpi_pblk != ACPI_INVALID
-	    || !obj.processor.pblk_address
-	    || obj.processor.pblk_length != 6)
-		return AE_OK;
-
-	acpi_pblk = obj.processor.pblk_address;
-
-	if (acpi_fadt.plvl2_lat
-	    && acpi_fadt.plvl2_lat <= MAX_C2_LATENCY) {
-		acpi_c2_exit_latency
-			= ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl2_lat);
-		acpi_c2_enter_latency
-			= ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl2_lat * 4);
-		acpi_max_c_state = 2;
-
-		printk(KERN_INFO "ACPI: System firmware supports: C2");
-			
-		if (acpi_fadt.plvl3_lat
-		    && acpi_fadt.plvl3_lat <= MAX_C3_LATENCY) {
-			acpi_c3_exit_latency
-				= ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl3_lat);
-			acpi_c3_enter_latency
-				= ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl3_lat * 12);
-			acpi_max_c_state = 3;
-
-			printk(" C3");
-		}
-
-		printk("\n");
-	}
-
-	printk(KERN_INFO "ACPI: plvl2lat=%d plvl3lat=%d\n", acpi_fadt.plvl2_lat, acpi_fadt.plvl3_lat);
-	printk(KERN_INFO "ACPI: C2 enter=%d C2 exit=%d\n", acpi_c2_enter_latency, acpi_c2_exit_latency);
-	printk(KERN_INFO "ACPI: C3 enter=%d C3 exit=%d\n", acpi_c3_enter_latency, acpi_c3_exit_latency);
-
-	return AE_OK;
-}
-
-static int
-acpi_pm_timer_init(void)
-{
-	FADT_DESCRIPTOR *fadt = &acpi_fadt;
-
-	if (fadt->tmr_val_ext) {
-		acpi_pm_tmr_len = 32;
-	} else {
-		acpi_pm_tmr_len = 24;
-	}
-
-	DEBUG_PRINT(ACPI_INFO, ("PM Timer width: %d bits\n", acpi_pm_tmr_len));
-
-	return AE_OK;
-}
-
-int
-acpi_cpu_init(void)
-{
-	acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
-			    ACPI_ROOT_OBJECT,
-			    ACPI_UINT32_MAX,
-			    acpi_found_cpu,
-			    NULL,
-			    NULL);
-
-	acpi_pm_timer_init();
-
-	if (acpi_use_idle) {
-#ifdef CONFIG_SMP
-		if (smp_num_cpus == 1)
-			pm_idle = acpi_idle;
-#else
-		pm_idle = acpi_idle;
-#endif
-		printk(KERN_INFO "ACPI: Using ACPI idle\n");
-		printk(KERN_INFO "ACPI: If experiencing system slowness, try adding \"acpi=no-idle\" to cmdline\n");
-	}
-	else {
-		printk(KERN_INFO "ACPI: Not using ACPI idle\n");
-	}
-
-	return 0;
-}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/debugger/dbcmds.c linux/drivers/acpi/debugger/dbcmds.c
--- v2.4.5/linux/drivers/acpi/debugger/dbcmds.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/debugger/dbcmds.c	Wed Jun 20 17:47:39 2001
@@ -0,0 +1,987 @@
+/*******************************************************************************
+ *
+ * Module Name: dbcmds - debug commands and output routines
+ *              $Revision: 60 $
+ *
+ ******************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "acdispat.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+#include "acparser.h"
+#include "acevents.h"
+#include "acinterp.h"
+#include "acdebug.h"
+#include "actables.h"
+#include "acresrc.h"
+
+#ifdef ENABLE_DEBUGGER
+
+#define _COMPONENT          ACPI_DEBUGGER
+	 MODULE_NAME         ("dbcmds")
+
+
+/*
+ * Arguments for the Objects command
+ * These object types map directly to the ACPI_TYPES
+ */
+
+ARGUMENT_INFO               acpi_db_object_types [] =
+{ {"ANY"},
+	{"NUMBERS"},
+	{"STRINGS"},
+	{"BUFFERS"},
+	{"PACKAGES"},
+	{"FIELDS"},
+	{"DEVICES"},
+	{"EVENTS"},
+	{"METHODS"},
+	{"MUTEXES"},
+	{"REGIONS"},
+	{"POWERRESOURCES"},
+	{"PROCESSORS"},
+	{"THERMALZONES"},
+	{"BUFFERFIELDS"},
+	{"DDBHANDLES"},
+	{NULL}           /* Must be null terminated */
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_walk_for_references
+ *
+ * PARAMETERS:  Callback from Walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check if this namespace object refers to the target object
+ *              that is passed in as the context value.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_db_walk_for_references (
+	ACPI_HANDLE             obj_handle,
+	u32                     nesting_level,
+	void                    *context,
+	void                    **return_value)
+{
+	ACPI_OPERAND_OBJECT     *obj_desc = (ACPI_OPERAND_OBJECT *) context;
+	ACPI_NAMESPACE_NODE     *node = (ACPI_NAMESPACE_NODE *) obj_handle;
+
+
+	/* Check for match against the namespace node itself */
+
+	if (node == (void *) obj_desc) {
+		acpi_os_printf ("Object is a Node [%4.4s]\n", &node->name);
+	}
+
+	/* Check for match against the object attached to the node */
+
+	if (node->object == obj_desc) {
+		acpi_os_printf ("Reference at Node->Object %p [%4.4s]\n", node, &node->name);
+	}
+
+	/* Check first child for a match */
+	/* TBD: [Investigate] probably now obsolete with new datastructure */
+
+	if (node->child == (void *) obj_desc) {
+		acpi_os_printf ("Reference at Node->Child %p [%4.4s]\n", node, &node->name);
+	}
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_find_references
+ *
+ * PARAMETERS:  Object_arg      - String with hex value of the object
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Search namespace for all references to the input object
+ *
+ ******************************************************************************/
+
+void
+acpi_db_find_references (
+	NATIVE_CHAR             *object_arg)
+{
+	ACPI_OPERAND_OBJECT     *obj_desc;
+
+
+	/* Convert string to object pointer */
+
+	obj_desc = (ACPI_OPERAND_OBJECT *) STRTOUL (object_arg, NULL, 16);
+
+	/* Search all nodes in namespace */
+
+	acpi_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+			  acpi_db_walk_for_references, (void *) obj_desc, NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_display_locks
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display information about internal mutexes.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_locks (void)
+{
+	u32                     i;
+
+
+	for (i = 0; i < MAX_MTX; i++) {
+		acpi_os_printf ("%26s : %s\n", acpi_ut_get_mutex_name (i),
+				 acpi_gbl_acpi_mutex_info[i].owner_id == ACPI_MUTEX_NOT_ACQUIRED
+						? "Locked" : "Unlocked");
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_display_table_info
+ *
+ * PARAMETERS:  Table_arg       - String with name of table to be displayed
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display information about loaded tables.  Current
+ *              implementation displays all loaded tables.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_table_info (
+	NATIVE_CHAR             *table_arg)
+{
+	u32                     i;
+
+
+	for (i = 0; i < NUM_ACPI_TABLES; i++) {
+		if (acpi_gbl_acpi_tables[i].pointer) {
+			acpi_os_printf ("%s at %p length %X\n", acpi_gbl_acpi_table_data[i].name,
+					 acpi_gbl_acpi_tables[i].pointer, acpi_gbl_acpi_tables[i].length);
+		}
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_unload_acpi_table
+ *
+ * PARAMETERS:  Table_arg       - Name of the table to be unloaded
+ *              Instance_arg    - Which instance of the table to unload (if
+ *                                there are multiple tables of the same type)
+ *
+ * RETURN:      Nonde
+ *
+ * DESCRIPTION: Unload an ACPI table.
+ *              Instance is not implemented
+ *
+ ******************************************************************************/
+
+void
+acpi_db_unload_acpi_table (
+	NATIVE_CHAR             *table_arg,
+	NATIVE_CHAR             *instance_arg)
+{
+	u32                     i;
+	ACPI_STATUS             status;
+
+
+	/* Search all tables for the target type */
+
+	for (i = 0; i < NUM_ACPI_TABLES; i++) {
+		if (!STRNCMP (table_arg, acpi_gbl_acpi_table_data[i].signature, acpi_gbl_acpi_table_data[i].sig_length)) {
+			/* Found the table, unload it */
+
+			status = acpi_unload_table (i);
+			if (ACPI_SUCCESS (status)) {
+				acpi_os_printf ("[%s] unloaded and uninstalled\n", table_arg);
+			}
+			else {
+				acpi_os_printf ("%s, while unloading [%s]\n", acpi_ut_format_exception (status), table_arg);
+			}
+
+			return;
+		}
+	}
+
+	acpi_os_printf ("Unknown table type [%s]\n", table_arg);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_set_method_breakpoint
+ *
+ * PARAMETERS:  Location            - AML offset of breakpoint
+ *              Walk_state          - Current walk info
+ *              Op                  - Current Op (from parse walk)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Set a breakpoint in a control method at the specified
+ *              AML offset
+ *
+ ******************************************************************************/
+
+void
+acpi_db_set_method_breakpoint (
+	NATIVE_CHAR             *location,
+	ACPI_WALK_STATE         *walk_state,
+	ACPI_PARSE_OBJECT       *op)
+{
+	u32                     address;
+
+
+	if (!op) {
+		acpi_os_printf ("There is no method currently executing\n");
+		return;
+	}
+
+	/* Get and verify the breakpoint address */
+
+	address = STRTOUL (location, NULL, 16);
+	if (address <= op->aml_offset) {
+		acpi_os_printf ("Breakpoint %X is beyond current address %X\n", address, op->aml_offset);
+	}
+
+	/* Save breakpoint in current walk */
+
+	walk_state->method_breakpoint = address;
+	acpi_os_printf ("Breakpoint set at AML offset %X\n", address);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_set_method_call_breakpoint
+ *
+ * PARAMETERS:  Op                  - Current Op (from parse walk)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Set a breakpoint in a control method at the specified
+ *              AML offset
+ *
+ ******************************************************************************/
+
+void
+acpi_db_set_method_call_breakpoint (
+	ACPI_PARSE_OBJECT       *op)
+{
+
+
+	if (!op) {
+		acpi_os_printf ("There is no method currently executing\n");
+		return;
+	}
+
+
+	acpi_gbl_step_to_next_call = TRUE;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_disassemble_aml
+ *
+ * PARAMETERS:  Statements          - Number of statements to disassemble
+ *              Op                  - Current Op (from parse walk)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
+ *              of statements specified.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_disassemble_aml (
+	NATIVE_CHAR             *statements,
+	ACPI_PARSE_OBJECT       *op)
+{
+	u32                     num_statements = 8;
+
+
+	if (!op) {
+		acpi_os_printf ("There is no method currently executing\n");
+		return;
+	}
+
+	if (statements) {
+		num_statements = STRTOUL (statements, NULL, 0);
+	}
+
+
+	acpi_db_display_op (NULL, op, num_statements);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_dump_namespace
+ *
+ * PARAMETERS:  Start_arg       - Node to begin namespace dump
+ *              Depth_arg       - Maximum tree depth to be dumped
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Dump entire namespace or a subtree.  Each node is displayed
+ *              with type and other information.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_dump_namespace (
+	NATIVE_CHAR             *start_arg,
+	NATIVE_CHAR             *depth_arg)
+{
+	ACPI_HANDLE             subtree_entry = acpi_gbl_root_node;
+	u32                     max_depth = ACPI_UINT32_MAX;
+
+
+	/* No argument given, just start at the root and dump entire namespace */
+
+	if (start_arg) {
+		/* Check if numeric argument, must be a Node */
+
+		if ((start_arg[0] >= 0x30) && (start_arg[0] <= 0x39)) {
+			subtree_entry = (ACPI_HANDLE) STRTOUL (start_arg, NULL, 16);
+			if (!acpi_os_readable (subtree_entry, sizeof (ACPI_NAMESPACE_NODE))) {
+				acpi_os_printf ("Address %p is invalid in this address space\n", subtree_entry);
+				return;
+			}
+
+			if (!VALID_DESCRIPTOR_TYPE ((subtree_entry), ACPI_DESC_TYPE_NAMED)) {
+				acpi_os_printf ("Address %p is not a valid Named object\n", subtree_entry);
+				return;
+			}
+		}
+
+		/* Alpha argument */
+
+		else {
+			/* The parameter is a name string that must be resolved to a Named obj*/
+
+			subtree_entry = acpi_db_local_ns_lookup (start_arg);
+			if (!subtree_entry) {
+				subtree_entry = acpi_gbl_root_node;
+			}
+		}
+
+		/* Now we can check for the depth argument */
+
+		if (depth_arg) {
+			max_depth = STRTOUL (depth_arg, NULL, 0);
+		}
+	}
+
+
+	acpi_db_set_output_destination (DB_DUPLICATE_OUTPUT);
+	acpi_os_printf ("ACPI Namespace (from %p subtree):\n", subtree_entry);
+
+	/* Display the subtree */
+
+	acpi_db_set_output_destination (DB_REDIRECTABLE_OUTPUT);
+	acpi_ns_dump_objects (ACPI_TYPE_ANY, max_depth, ACPI_UINT32_MAX, subtree_entry);
+	acpi_db_set_output_destination (DB_CONSOLE_OUTPUT);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_dump_namespace_by_owner
+ *
+ * PARAMETERS:  Owner_arg       - Owner ID whose nodes will be displayed
+ *              Depth_arg       - Maximum tree depth to be dumped
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Dump elements of the namespace that are owned by the Owner_id.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_dump_namespace_by_owner (
+	NATIVE_CHAR             *owner_arg,
+	NATIVE_CHAR             *depth_arg)
+{
+	ACPI_HANDLE             subtree_entry = acpi_gbl_root_node;
+	u32                     max_depth = ACPI_UINT32_MAX;
+	u16                     owner_id;
+
+
+	owner_id = (u16) STRTOUL (owner_arg, NULL, 0);
+
+
+	/* Now we can check for the depth argument */
+
+	if (depth_arg) {
+		max_depth = STRTOUL (depth_arg, NULL, 0);
+	}
+
+
+	acpi_db_set_output_destination (DB_DUPLICATE_OUTPUT);
+	acpi_os_printf ("ACPI Namespace by owner %X:\n", owner_id);
+
+	/* Display the subtree */
+
+	acpi_db_set_output_destination (DB_REDIRECTABLE_OUTPUT);
+	acpi_ns_dump_objects (ACPI_TYPE_ANY, max_depth, owner_id, subtree_entry);
+	acpi_db_set_output_destination (DB_CONSOLE_OUTPUT);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_send_notify
+ *
+ * PARAMETERS:  Name            - Name of ACPI object to send the notify to
+ *              Value           - Value of the notify to send.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Send an ACPI notification.  The value specified is sent to the
+ *              named object as an ACPI notify.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_send_notify (
+	NATIVE_CHAR             *name,
+	u32                     value)
+{
+	ACPI_NAMESPACE_NODE     *node;
+
+
+	/* Translate name to an Named object */
+
+	node = acpi_db_local_ns_lookup (name);
+	if (!node) {
+		return;
+	}
+
+	/* Decode Named object type */
+
+	switch (node->type) {
+	case ACPI_TYPE_DEVICE:
+	case ACPI_TYPE_THERMAL:
+
+		 /* Send the notify */
+
+		acpi_ev_queue_notify_request (node, value);
+		break;
+
+	default:
+		acpi_os_printf ("Named object is not a device or a thermal object\n");
+		break;
+	}
+
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_set_method_data
+ *
+ * PARAMETERS:  Type_arg        - L for local, A for argument
+ *              Index_arg       - which one
+ *              Value_arg       - Value to set.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Set a local or argument for the running control method.
+ *              NOTE: only object supported is Number.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_set_method_data (
+	NATIVE_CHAR             *type_arg,
+	NATIVE_CHAR             *index_arg,
+	NATIVE_CHAR             *value_arg)
+{
+	NATIVE_CHAR             type;
+	u32                     index;
+	u32                     value;
+	ACPI_WALK_STATE         *walk_state;
+	ACPI_OPERAND_OBJECT     *obj_desc;
+
+
+	/* Validate Type_arg */
+
+	STRUPR (type_arg);
+	type = type_arg[0];
+	if ((type != 'L') &&
+		(type != 'A')) {
+		acpi_os_printf ("Invalid SET operand: %s\n", type_arg);
+		return;
+	}
+
+	/* Get the index and value */
+
+	index = STRTOUL (index_arg, NULL, 16);
+	value = STRTOUL (value_arg, NULL, 16);
+
+	walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list);
+	if (!walk_state) {
+		acpi_os_printf ("There is no method currently executing\n");
+		return;
+	}
+
+
+	/* Create and initialize the new object */
+
+	obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+	if (!obj_desc) {
+		acpi_os_printf ("Could not create an internal object\n");
+		return;
+	}
+
+	obj_desc->integer.value = value;
+
+
+	/* Store the new object into the target */
+
+	switch (type) {
+	case 'A':
+
+		/* Set a method argument */
+
+		if (index > MTH_NUM_ARGS) {
+			acpi_os_printf ("Arg%d - Invalid argument name\n", index);
+			return;
+		}
+
+		acpi_ds_store_object_to_local (AML_ARG_OP, index, obj_desc, walk_state);
+		obj_desc = walk_state->arguments[index].object;
+
+		acpi_os_printf ("Arg%d: ", index);
+		acpi_db_display_internal_object (obj_desc, walk_state);
+		break;
+
+	case 'L':
+
+		/* Set a method local */
+
+		if (index > MTH_NUM_LOCALS) {
+			acpi_os_printf ("Local%d - Invalid local variable name\n", index);
+			return;
+		}
+
+		acpi_ds_store_object_to_local (AML_LOCAL_OP, index, obj_desc, walk_state);
+		obj_desc = walk_state->local_variables[index].object;
+
+		acpi_os_printf ("Local%d: ", index);
+		acpi_db_display_internal_object (obj_desc, walk_state);
+		break;
+
+	default:
+		break;
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_walk_for_specific_objects
+ *
+ * PARAMETERS:  Callback from Walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Display short info about objects in the namespace
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_db_walk_for_specific_objects (
+	ACPI_HANDLE             obj_handle,
+	u32                     nesting_level,
+	void                    *context,
+	void                    **return_value)
+{
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	ACPI_STATUS             status;
+	u32                     buf_size;
+	NATIVE_CHAR             buffer[64];
+
+
+	obj_desc = ((ACPI_NAMESPACE_NODE *)obj_handle)->object;
+	buf_size = sizeof (buffer) / sizeof (*buffer);
+
+	/* Get and display the full pathname to this object */
+
+	status = acpi_ns_handle_to_pathname (obj_handle, &buf_size, buffer);
+
+	if (ACPI_FAILURE (status)) {
+		acpi_os_printf ("Could Not get pathname for object %p\n", obj_handle);
+		return (AE_OK);
+	}
+
+	acpi_os_printf ("%32s", buffer);
+
+
+	/* Display short information about the object */
+
+	if (obj_desc) {
+		switch (obj_desc->common.type) {
+		case ACPI_TYPE_METHOD:
+			acpi_os_printf (" #Args %d Concurrency %X", obj_desc->method.param_count, obj_desc->method.concurrency);
+			break;
+
+		case ACPI_TYPE_INTEGER:
+			acpi_os_printf (" Value %X", obj_desc->integer.value);
+			break;
+
+		case ACPI_TYPE_STRING:
+			acpi_os_printf (" \"%s\"", obj_desc->string.pointer);
+			break;
+
+		case ACPI_TYPE_REGION:
+			acpi_os_printf (" Space_id %X Address %X Length %X", obj_desc->region.space_id, obj_desc->region.address, obj_desc->region.length);
+			break;
+
+		case ACPI_TYPE_PACKAGE:
+			acpi_os_printf (" #Elements %X", obj_desc->package.count);
+			break;
+
+		case ACPI_TYPE_BUFFER:
+			acpi_os_printf (" Length %X", obj_desc->buffer.length);
+			break;
+		}
+	}
+
+	acpi_os_printf ("\n");
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_display_objects
+ *
+ * PARAMETERS:  Obj_type_arg        - Type of object to display
+ *              Display_count_arg   - Max depth to display
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display objects in the namespace of the requested type
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_db_display_objects (
+	NATIVE_CHAR             *obj_type_arg,
+	NATIVE_CHAR             *display_count_arg)
+{
+	ACPI_OBJECT_TYPE8       type;
+
+
+	/* Get the object type */
+
+	type = acpi_db_match_argument (obj_type_arg, acpi_db_object_types);
+	if (type == ACPI_TYPE_NOT_FOUND) {
+		acpi_os_printf ("Invalid or unsupported argument\n");
+		return (AE_OK);
+	}
+
+	acpi_db_set_output_destination (DB_DUPLICATE_OUTPUT);
+	acpi_os_printf ("Objects of type [%s] defined in the current ACPI Namespace: \n", acpi_ut_get_type_name (type));
+
+	acpi_db_set_output_destination (DB_REDIRECTABLE_OUTPUT);
+
+	/* Walk the namespace from the root */
+
+	acpi_walk_namespace (type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+			   acpi_db_walk_for_specific_objects, (void *) &type, NULL);
+
+	acpi_db_set_output_destination (DB_CONSOLE_OUTPUT);
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_walk_and_match_name
+ *
+ * PARAMETERS:  Callback from Walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Find a particular name/names within the namespace.  Wildcards
+ *              are supported -- '?' matches any character.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_db_walk_and_match_name (
+	ACPI_HANDLE             obj_handle,
+	u32                     nesting_level,
+	void                    *context,
+	void                    **return_value)
+{
+	ACPI_STATUS             status;
+	NATIVE_CHAR             *requested_name = (NATIVE_CHAR *) context;
+	u32                     i;
+	u32                     buf_size;
+	NATIVE_CHAR             buffer[96];
+
+
+	/* Check for a name match */
+
+	for (i = 0; i < 4; i++) {
+		/* Wildcard support */
+
+		if ((requested_name[i] != '?') &&
+			(requested_name[i] != ((NATIVE_CHAR *) (&((ACPI_NAMESPACE_NODE *) obj_handle)->name))[i])) {
+			/* No match, just exit */
+
+			return (AE_OK);
+		}
+	}
+
+
+	/* Get the full pathname to this object */
+
+	buf_size = sizeof (buffer) / sizeof (*buffer);
+
+	status = acpi_ns_handle_to_pathname (obj_handle, &buf_size, buffer);
+	if (ACPI_FAILURE (status)) {
+		acpi_os_printf ("Could Not get pathname for object %p\n", obj_handle);
+	}
+
+	else {
+		acpi_os_printf ("%32s (%p) - %s\n", buffer, obj_handle,
+			acpi_ut_get_type_name (((ACPI_NAMESPACE_NODE *) obj_handle)->type));
+	}
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_find_name_in_namespace
+ *
+ * PARAMETERS:  Name_arg        - The 4-character ACPI name to find.
+ *                                wildcards are supported.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Search the namespace for a given name (with wildcards)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_db_find_name_in_namespace (
+	NATIVE_CHAR             *name_arg)
+{
+
+	if (STRLEN (name_arg) > 4) {
+		acpi_os_printf ("Name must be no longer than 4 characters\n");
+		return (AE_OK);
+	}
+
+	/* Walk the namespace from the root */
+
+	acpi_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+			   acpi_db_walk_and_match_name, name_arg, NULL);
+
+	acpi_db_set_output_destination (DB_CONSOLE_OUTPUT);
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_set_scope
+ *
+ * PARAMETERS:  Name                - New scope path
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Set the "current scope" as maintained by this utility.
+ *              The scope is used as a prefix to ACPI paths.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_set_scope (
+	NATIVE_CHAR             *name)
+{
+
+	if (!name || name[0] == 0) {
+		acpi_os_printf ("Current scope: %s\n", scope_buf);
+		return;
+	}
+
+	acpi_db_prep_namestring (name);
+
+	/* TBD: [Future] Validate scope here */
+
+	if (name[0] == '\\') {
+		STRCPY (scope_buf, name);
+		STRCAT (scope_buf, "\\");
+	}
+
+	else {
+		STRCAT (scope_buf, name);
+		STRCAT (scope_buf, "\\");
+	}
+
+	acpi_os_printf ("New scope: %s\n", scope_buf);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_display_resources
+ *
+ * PARAMETERS:  Object_arg      - String with hex value of the object
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION:
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_resources (
+	NATIVE_CHAR             *object_arg)
+{
+#ifndef _IA16
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	ACPI_STATUS             status;
+	ACPI_BUFFER             return_obj;
+
+
+	acpi_db_set_output_destination (DB_REDIRECTABLE_OUTPUT);
+
+	/* Convert string to object pointer */
+
+	obj_desc = (ACPI_OPERAND_OBJECT *) STRTOUL (object_arg, NULL, 16);
+
+	/* Prepare for a return object of arbitrary size */
+
+	return_obj.pointer          = buffer;
+	return_obj.length           = BUFFER_SIZE;
+
+	/* _PRT */
+
+	acpi_os_printf ("Evaluating _PRT\n");
+
+	status = acpi_evaluate_object (obj_desc, "_PRT", NULL, &return_obj);
+	if (ACPI_FAILURE (status)) {
+		acpi_os_printf ("Could not obtain _PRT: %s\n", acpi_ut_format_exception (status));
+		goto go_cRS;
+	}
+
+	return_obj.pointer          = buffer;
+	return_obj.length           = BUFFER_SIZE;
+
+	status = acpi_get_irq_routing_table (obj_desc, &return_obj);
+	if (ACPI_FAILURE (status)) {
+		acpi_os_printf ("Get_irq_routing_table failed: %s\n", acpi_ut_format_exception (status));
+		goto go_cRS;
+	}
+
+
+	acpi_rs_dump_irq_list((u8 *)buffer);
+
+	/* _CRS */
+go_cRS:
+	acpi_os_printf ("Evaluating _CRS\n");
+
+	return_obj.pointer          = buffer;
+	return_obj.length           = BUFFER_SIZE;
+
+	status = acpi_evaluate_object (obj_desc, "_CRS", NULL, &return_obj);
+	if (ACPI_FAILURE (status)) {
+		acpi_os_printf ("Could not obtain _CRS: %s\n", acpi_ut_format_exception (status));
+		goto go_pRS;
+	}
+
+	return_obj.pointer          = buffer;
+	return_obj.length           = BUFFER_SIZE;
+
+	status = acpi_get_current_resources (obj_desc, &return_obj);
+	if (ACPI_FAILURE (status)) {
+		acpi_os_printf ("Acpi_get_current_resources failed: %s\n", acpi_ut_format_exception (status));
+		goto go_pRS;
+	}
+
+	acpi_rs_dump_resource_list ((ACPI_RESOURCE *) buffer);
+
+	/* _PRS */
+go_pRS:
+	acpi_os_printf ("Evaluating _PRS\n");
+
+	return_obj.pointer          = buffer;
+	return_obj.length           = BUFFER_SIZE;
+
+	status = acpi_evaluate_object (obj_desc, "_PRS", NULL, &return_obj);
+	if (ACPI_FAILURE (status)) {
+		acpi_os_printf ("Could not obtain _PRS: %s\n", acpi_ut_format_exception (status));
+		goto cleanup;
+	}
+
+	return_obj.pointer          = buffer;
+	return_obj.length           = BUFFER_SIZE;
+
+	status = acpi_get_possible_resources (obj_desc, &return_obj);
+	if (ACPI_FAILURE (status)) {
+		acpi_os_printf ("Acpi_get_possible_resources failed: %s\n", acpi_ut_format_exception (status));
+		goto cleanup;
+	}
+
+	acpi_rs_dump_resource_list ((ACPI_RESOURCE *) buffer);
+
+
+cleanup:
+
+	acpi_db_set_output_destination (DB_CONSOLE_OUTPUT);
+	return;
+#endif
+
+}
+
+
+#endif /* ENABLE_DEBUGGER */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/debugger/dbdisasm.c linux/drivers/acpi/debugger/dbdisasm.c
--- v2.4.5/linux/drivers/acpi/debugger/dbdisasm.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/debugger/dbdisasm.c	Wed Jun 20 17:47:39 2001
@@ -0,0 +1,674 @@
+/*******************************************************************************
+ *
+ * Module Name: dbdisasm - parser op tree display routines
+ *              $Revision: 40 $
+ *
+ ******************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+#include "acdebug.h"
+
+
+#ifdef ENABLE_DEBUGGER
+
+#define _COMPONENT          ACPI_DEBUGGER
+	 MODULE_NAME         ("dbdisasm")
+
+
+#define MAX_SHOW_ENTRY      128
+#define BLOCK_PAREN         1
+#define BLOCK_BRACE         2
+#define DB_NO_OP_INFO       "            [%2.2d]  "
+#define DB_FULL_OP_INFO     "%5.5X #%4.4X [%2.2d]  "
+
+
+NATIVE_CHAR                 *INDENT_STRING = "....";
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_block_type
+ *
+ * PARAMETERS:  Op              - Object to be examined
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Type of block for this op (parens or braces)
+ *
+ ******************************************************************************/
+
+u32
+acpi_db_block_type (
+	ACPI_PARSE_OBJECT       *op)
+{
+
+	switch (op->opcode) {
+	case AML_METHOD_OP:
+		return (BLOCK_BRACE);
+		break;
+
+	default:
+		break;
+	}
+
+	return (BLOCK_PAREN);
+
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ps_display_object_pathname
+ *
+ * PARAMETERS:  Op              - Object whose pathname is to be obtained
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Diplay the pathname associated with a named object.  Two
+ *              versions. One searches the parse tree (for parser-only
+ *              applications suchas Acpi_dump), and the other searches the
+ *              ACPI namespace (the parse tree is probably deleted)
+ *
+ ******************************************************************************/
+
+#ifdef PARSER_ONLY
+
+ACPI_STATUS
+acpi_ps_display_object_pathname (
+	ACPI_PARSE_OBJECT       *op)
+{
+	ACPI_PARSE_OBJECT       *target_op;
+
+
+	/* Search parent tree up to the root if necessary */
+
+	target_op = acpi_ps_find (op, op->value.name, 0, 0);
+	if (!target_op) {
+		/*
+		 * Didn't find the name in the parse tree.  This may be
+		 * a problem, or it may simply be one of the predefined names
+		 * (such as _OS_).  Rather than worry about looking up all
+		 * the predefined names, just display the name as given
+		 */
+
+		acpi_os_printf (" **** Path not found in parse tree");
+	}
+
+	else {
+		/* The target was found, print the name and complete path */
+
+		acpi_os_printf (" (Path ");
+		acpi_db_display_path (target_op);
+		acpi_os_printf (")");
+	}
+
+	return (AE_OK);
+}
+
+#else
+
+ACPI_STATUS
+acpi_ps_display_object_pathname (
+	ACPI_PARSE_OBJECT       *op)
+{
+	ACPI_STATUS             status;
+	ACPI_NAMESPACE_NODE     *node;
+	NATIVE_CHAR             buffer[MAX_SHOW_ENTRY];
+	u32                     buffer_size = MAX_SHOW_ENTRY;
+
+
+	acpi_os_printf (" (Path ");
+
+	/* Just get the Node out of the Op object */
+
+	node = op->node;
+	if (!node) {
+		/*
+		 * No Named obj,  so we can't get the pathname since the object
+		 * is not in the namespace.  This can happen during single
+		 * stepping where a dynamic named object is *about* to be created.
+		 */
+		return (AE_OK);
+	}
+
+	/* Convert Named_desc/handle to a full pathname */
+
+	status = acpi_ns_handle_to_pathname (node, &buffer_size, buffer);
+	if (ACPI_FAILURE (status)) {
+		acpi_os_printf ("****Could not get pathname****)");
+		return (status);
+	}
+
+	acpi_os_printf ("%s)", buffer);
+	return (AE_OK);
+}
+
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_display_op
+ *
+ * PARAMETERS:  Origin          - Starting object
+ *              Num_opcodes     - Max number of opcodes to be displayed
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display parser object and its children
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_op (
+	ACPI_WALK_STATE         *walk_state,
+	ACPI_PARSE_OBJECT       *origin,
+	u32                     num_opcodes)
+{
+	ACPI_PARSE_OBJECT       *op = origin;
+	ACPI_PARSE_OBJECT       *arg;
+	ACPI_PARSE_OBJECT       *depth;
+	u32                     depth_count = 0;
+	u32                     last_depth = 0;
+	u32                     i;
+	u32                     j;
+
+
+	if (op) {
+		while (op) {
+			/* indentation */
+
+			depth_count = 0;
+			if (!opt_verbose) {
+				depth_count++;
+			}
+
+			/* Determine the nesting depth of this argument */
+
+			for (depth = op->parent; depth; depth = depth->parent) {
+				arg = acpi_ps_get_arg (depth, 0);
+				while (arg && arg != origin) {
+					arg = arg->next;
+				}
+
+				if (arg) {
+					break;
+				}
+
+				depth_count++;
+			}
+
+
+			/* Open a new block if we are nested further than last time */
+
+			if (depth_count > last_depth) {
+				VERBOSE_PRINT ((DB_NO_OP_INFO, last_depth));
+				for (i = 0; i < last_depth; i++) {
+					acpi_os_printf (INDENT_STRING);
+				}
+
+				if (acpi_db_block_type (op) == BLOCK_PAREN) {
+					acpi_os_printf ("(\n");
+				}
+				else {
+					acpi_os_printf ("{\n");
+				}
+			}
+
+			/* Close a block if we are nested less than last time */
+
+			else if (depth_count < last_depth) {
+				for (j = 0; j < (last_depth - depth_count); j++) {
+					VERBOSE_PRINT ((DB_NO_OP_INFO, last_depth - j));
+					for (i = 0; i < (last_depth - j - 1); i++) {
+						acpi_os_printf (INDENT_STRING);
+					}
+
+					if (acpi_db_block_type (op) == BLOCK_PAREN) {
+						acpi_os_printf (")\n");
+					}
+					else {
+						acpi_os_printf ("}\n");
+					}
+				}
+			}
+
+			/* In verbose mode, print the AML offset, opcode and depth count */
+
+			VERBOSE_PRINT ((DB_FULL_OP_INFO, (unsigned) op->aml_offset, op->opcode, depth_count));
+
+
+			/* Indent the output according to the depth count */
+
+			for (i = 0; i < depth_count; i++) {
+				acpi_os_printf (INDENT_STRING);
+			}
+
+
+			/* Now print the opcode */
+
+			acpi_db_display_opcode (walk_state, op);
+
+			/* Resolve a name reference */
+
+			if ((op->opcode == AML_INT_NAMEPATH_OP && op->value.name)  &&
+				(op->parent) &&
+				(opt_verbose)) {
+				acpi_ps_display_object_pathname (op);
+			}
+
+			acpi_os_printf ("\n");
+
+			/* Get the next node in the tree */
+
+			op = acpi_ps_get_depth_next (origin, op);
+			last_depth = depth_count;
+
+			num_opcodes--;
+			if (!num_opcodes) {
+				op = NULL;
+			}
+		}
+
+		/* Close the last block(s) */
+
+		depth_count = last_depth -1;
+		for (i = 0; i < last_depth; i++) {
+			VERBOSE_PRINT ((DB_NO_OP_INFO, last_depth - i));
+			for (j = 0; j < depth_count; j++) {
+				acpi_os_printf (INDENT_STRING);
+			}
+			acpi_os_printf ("}\n");
+			depth_count--;
+		}
+
+	}
+
+	else {
+		acpi_db_display_opcode (walk_state, op);
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_display_namestring
+ *
+ * PARAMETERS:  Name                - ACPI Name string to store
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display namestring. Handles prefix characters
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_namestring (
+	NATIVE_CHAR             *name)
+{
+	u32                     seg_count;
+	u8                      do_dot = FALSE;
+
+
+	if (!name) {
+		acpi_os_printf ("<NULL NAME PTR>");
+		return;
+	}
+
+	if (acpi_ps_is_prefix_char (GET8 (name))) {
+		/* append prefix character */
+
+		acpi_os_printf ("%1c", GET8 (name));
+		name++;
+	}
+
+	switch (GET8 (name)) {
+	case AML_DUAL_NAME_PREFIX:
+		seg_count = 2;
+		name++;
+		break;
+
+	case AML_MULTI_NAME_PREFIX_OP:
+		seg_count = (u32) GET8 (name + 1);
+		name += 2;
+		break;
+
+	default:
+		seg_count = 1;
+		break;
+	}
+
+	while (seg_count--) {
+		/* append Name segment */
+
+		if (do_dot) {
+			/* append dot */
+
+			acpi_os_printf (".");
+		}
+
+		acpi_os_printf ("%4.4s", name);
+		do_dot = TRUE;
+
+		name += 4;
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_display_path
+ *
+ * PARAMETERS:  Op                  - Named Op whose path is to be constructed
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Walk backwards from current scope and display the name
+ *              of each previous level of scope up to the root scope
+ *              (like "pwd" does with file systems)
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_path (
+	ACPI_PARSE_OBJECT       *op)
+{
+	ACPI_PARSE_OBJECT       *prev;
+	ACPI_PARSE_OBJECT       *search;
+	u32                     name;
+	u8                      do_dot = FALSE;
+	ACPI_PARSE_OBJECT       *name_path;
+
+
+	/* We are only interested in named objects */
+
+	if (!acpi_ps_is_node_op (op->opcode)) {
+		return;
+	}
+
+
+	if (acpi_ps_is_create_field_op (op->opcode)) {
+		/* Field creation - check for a fully qualified namepath */
+
+		if (op->opcode == AML_CREATE_FIELD_OP) {
+			name_path = acpi_ps_get_arg (op, 3);
+		}
+		else {
+			name_path = acpi_ps_get_arg (op, 2);
+		}
+
+		if ((name_path) &&
+			(name_path->value.string) &&
+			(name_path->value.string[0] == '\\')) {
+			acpi_db_display_namestring (name_path->value.string);
+			return;
+		}
+	}
+
+	prev = NULL;            /* Start with Root Node */
+
+	while (prev != op) {
+		/* Search upwards in the tree to find scope with "prev" as its parent */
+
+		search = op;
+		for (; ;) {
+			if (search->parent == prev) {
+				break;
+			}
+
+			/* Go up one level */
+
+			search = search->parent;
+		}
+
+		if (prev && !acpi_ps_is_field_op (search->opcode)) {
+			/* below root scope, append scope name */
+
+			if (do_dot) {
+				/* append dot */
+
+				acpi_os_printf (".");
+			}
+
+			if (acpi_ps_is_create_field_op (search->opcode)) {
+				if (op->opcode == AML_CREATE_FIELD_OP) {
+					name_path = acpi_ps_get_arg (op, 3);
+				}
+				else {
+					name_path = acpi_ps_get_arg (op, 2);
+				}
+
+				if ((name_path) &&
+					(name_path->value.string)) {
+					acpi_os_printf ("%4.4s", name_path->value.string);
+				}
+			}
+
+			else {
+				name = acpi_ps_get_name (search);
+				acpi_os_printf ("%4.4s", &name);
+			}
+
+			do_dot = TRUE;
+		}
+
+		prev = search;
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_display_opcode
+ *
+ * PARAMETERS:  Op                  - Op that is to be printed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Store printed op in a Buffer and return its length
+ *              (or -1 if out of space)
+ *
+ * NOTE: Terse mode prints out ASL-like code.  Verbose mode adds more info.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_opcode (
+	ACPI_WALK_STATE         *walk_state,
+	ACPI_PARSE_OBJECT       *op)
+{
+	u8                      *byte_data;
+	u32                     byte_count;
+	u32                     i;
+	ACPI_OPCODE_INFO        *opc = NULL;
+	u32                     name;
+
+
+	if (!op) {
+		acpi_os_printf ("<NULL OP PTR>");
+	}
+
+
+	/* op and arguments */
+
+	switch (op->opcode) {
+
+	case AML_BYTE_OP:
+
+		if (opt_verbose) {
+			acpi_os_printf ("(u8) 0x%2.2X", op->value.integer & ACPI_UINT8_MAX);
+		}
+
+		else {
+			acpi_os_printf ("0x%2.2X", op->value.integer & ACPI_UINT8_MAX);
+		}
+
+		break;
+
+
+	case AML_WORD_OP:
+
+		if (opt_verbose) {
+			acpi_os_printf ("(u16) 0x%4.4X", op->value.integer & ACPI_UINT16_MAX);
+		}
+
+		else {
+			acpi_os_printf ("0x%4.4X", op->value.integer & ACPI_UINT16_MAX);
+		}
+
+		break;
+
+
+	case AML_DWORD_OP:
+
+		if (opt_verbose) {
+			acpi_os_printf ("(u32) 0x%8.8X", op->value.integer);
+		}
+
+		else {
+			acpi_os_printf ("0x%8.8X", op->value.integer);
+		}
+
+		break;
+
+
+	case AML_STRING_OP:
+
+		if (op->value.string) {
+			acpi_os_printf ("\"%s\"", op->value.string);
+		}
+
+		else {
+			acpi_os_printf ("<\"NULL STRING PTR\">");
+		}
+
+		break;
+
+
+	case AML_INT_STATICSTRING_OP:
+
+		if (op->value.string) {
+			acpi_os_printf ("\"%s\"", op->value.string);
+		}
+
+		else {
+			acpi_os_printf ("\"<NULL STATIC STRING PTR>\"");
+		}
+
+		break;
+
+
+	case AML_INT_NAMEPATH_OP:
+
+		acpi_db_display_namestring (op->value.name);
+		break;
+
+
+	case AML_INT_NAMEDFIELD_OP:
+
+		acpi_os_printf ("Named_field (Length 0x%8.8X)  ", op->value.integer);
+		break;
+
+
+	case AML_INT_RESERVEDFIELD_OP:
+
+		acpi_os_printf ("Reserved_field (Length 0x%8.8X) ", op->value.integer);
+		break;
+
+
+	case AML_INT_ACCESSFIELD_OP:
+
+		acpi_os_printf ("Access_field (Length 0x%8.8X) ", op->value.integer);
+		break;
+
+
+	case AML_INT_BYTELIST_OP:
+
+		if (opt_verbose) {
+			acpi_os_printf ("Byte_list   (Length 0x%8.8X)  ", op->value.integer);
+		}
+
+		else {
+			acpi_os_printf ("0x%2.2X", op->value.integer);
+
+			byte_count = op->value.integer;
+			byte_data = ((ACPI_PARSE2_OBJECT *) op)->data;
+
+			for (i = 0; i < byte_count; i++) {
+				acpi_os_printf (", 0x%2.2X", byte_data[i]);
+			}
+		}
+
+		break;
+
+
+	default:
+
+		/* Just get the opcode name and print it */
+
+		opc = acpi_ps_get_opcode_info (op->opcode);
+		acpi_os_printf ("%s", opc->name);
+
+
+#ifndef PARSER_ONLY
+		if ((op->opcode == AML_INT_RETURN_VALUE_OP) &&
+			(walk_state->results) &&
+			(walk_state->results->results.num_results)) {
+			acpi_db_decode_internal_object (walk_state->results->results.obj_desc [walk_state->results->results.num_results-1]);
+		}
+#endif
+
+		break;
+	}
+
+
+	if (!opc) {
+		/* If there is another element in the list, add a comma */
+
+		if (op->next) {
+			acpi_os_printf (",");
+		}
+	}
+
+
+	/*
+	 * If this is a named opcode, print the associated name value
+	 */
+
+	if (op && acpi_ps_is_named_op (op->opcode)) {
+		name = acpi_ps_get_name (op);
+		acpi_os_printf (" %4.4s", &name);
+
+		if (opt_verbose) {
+			acpi_os_printf (" (Path \\");
+			acpi_db_display_path (op);
+			acpi_os_printf (")");
+		}
+	}
+}
+
+
+#endif  /* ENABLE_DEBUGGER */
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/debugger/dbdisply.c linux/drivers/acpi/debugger/dbdisply.c
--- v2.4.5/linux/drivers/acpi/debugger/dbdisply.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/debugger/dbdisply.c	Wed Jun 20 17:47:39 2001
@@ -0,0 +1,780 @@
+/*******************************************************************************
+ *
+ * Module Name: dbdisply - debug display commands
+ *              $Revision: 45 $
+ *
+ ******************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "amlcode.h"
+#include "acdispat.h"
+#include "acnamesp.h"
+#include "acparser.h"
+#include "acevents.h"
+#include "acinterp.h"
+#include "acdebug.h"
+
+
+#ifdef ENABLE_DEBUGGER
+
+
+#define _COMPONENT          ACPI_DEBUGGER
+	 MODULE_NAME         ("dbdisply")
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_get_pointer
+ *
+ * PARAMETERS:  Target          - Pointer to string to be converted
+ *
+ * RETURN:      Converted pointer
+ *
+ * DESCRIPTION: Convert an ascii pointer value to a real value
+ *
+ *****************************************************************************/
+
+void *
+acpi_db_get_pointer (
+	void                    *target)
+{
+	void                    *obj_ptr;
+
+
+#ifdef _IA16
+#include <stdio.h>
+
+	/* Have to handle 16-bit pointers of the form segment:offset */
+
+	if (!sscanf (target, "%p", &obj_ptr)) {
+		acpi_os_printf ("Invalid pointer: %s\n", target);
+		return (NULL);
+	}
+
+#else
+
+	/* Simple flat pointer */
+
+	obj_ptr = (void *) STRTOUL (target, NULL, 16);
+
+#endif
+
+	return (obj_ptr);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_dump_parser_descriptor
+ *
+ * PARAMETERS:  Op              - A parser Op descriptor
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display a formatted parser object
+ *
+ ******************************************************************************/
+
+void
+acpi_db_dump_parser_descriptor (
+	ACPI_PARSE_OBJECT       *op)
+{
+	ACPI_OPCODE_INFO        *info;
+
+
+	info = acpi_ps_get_opcode_info (op->opcode);
+
+	acpi_os_printf ("Parser Op Descriptor:\n");
+	acpi_os_printf ("%20.20s : %4.4X\n", "Opcode", op->opcode);
+
+	DEBUG_ONLY_MEMBERS (acpi_os_printf ("%20.20s : %s\n", "Opcode Name", info->name));
+
+	acpi_os_printf ("%20.20s : %p\n", "Value/Arg_list", op->value);
+	acpi_os_printf ("%20.20s : %p\n", "Parent", op->parent);
+	acpi_os_printf ("%20.20s : %p\n", "Next_op", op->next);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_decode_and_display_object
+ *
+ * PARAMETERS:  Target          - String with object to be displayed.  Names
+ *                                and hex pointers are supported.
+ *              Output_type     - Byte, Word, Dword, or Qword (B|W|D|Q)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display a formatted ACPI object
+ *
+ ******************************************************************************/
+
+void
+acpi_db_decode_and_display_object (
+	NATIVE_CHAR             *target,
+	NATIVE_CHAR             *output_type)
+{
+	void                    *obj_ptr;
+	ACPI_NAMESPACE_NODE     *node;
+	u32                     display = DB_BYTE_DISPLAY;
+	NATIVE_CHAR             buffer[80];
+	ACPI_BUFFER             ret_buf;
+	ACPI_STATUS             status;
+	u32                     size;
+
+
+	if (!target) {
+		return;
+	}
+
+	/* Decode the output type */
+
+	if (output_type) {
+		STRUPR (output_type);
+		if (output_type[0] == 'W') {
+			display = DB_WORD_DISPLAY;
+		}
+		else if (output_type[0] == 'D') {
+			display = DB_DWORD_DISPLAY;
+		}
+		else if (output_type[0] == 'Q') {
+			display = DB_QWORD_DISPLAY;
+		}
+	}
+
+
+	ret_buf.length = sizeof (buffer);
+	ret_buf.pointer = buffer;
+
+	/* Differentiate between a number and a name */
+
+	if ((target[0] >= 0x30) && (target[0] <= 0x39)) {
+		obj_ptr = acpi_db_get_pointer (target);
+		if (!acpi_os_readable (obj_ptr, 16)) {
+			acpi_os_printf ("Address %p is invalid in this address space\n", obj_ptr);
+			return;
+		}
+
+		/* Decode the object type */
+
+		if (VALID_DESCRIPTOR_TYPE ((obj_ptr), ACPI_DESC_TYPE_NAMED)) {
+			/* This is a Node */
+
+			if (!acpi_os_readable (obj_ptr, sizeof (ACPI_NAMESPACE_NODE))) {
+				acpi_os_printf ("Cannot read entire Named object at address %p\n", obj_ptr);
+				return;
+			}
+
+			node = obj_ptr;
+			goto dump_nte;
+		}
+
+		else if (VALID_DESCRIPTOR_TYPE ((obj_ptr), ACPI_DESC_TYPE_INTERNAL)) {
+			/* This is an ACPI OBJECT */
+
+			if (!acpi_os_readable (obj_ptr, sizeof (ACPI_OPERAND_OBJECT))) {
+				acpi_os_printf ("Cannot read entire ACPI object at address %p\n", obj_ptr);
+				return;
+			}
+
+			acpi_ut_dump_buffer (obj_ptr, sizeof (ACPI_OPERAND_OBJECT), display, ACPI_UINT32_MAX);
+			acpi_ex_dump_object_descriptor (obj_ptr, 1);
+		}
+
+		else if (VALID_DESCRIPTOR_TYPE ((obj_ptr), ACPI_DESC_TYPE_PARSER)) {
+			/* This is an Parser Op object */
+
+			if (!acpi_os_readable (obj_ptr, sizeof (ACPI_PARSE_OBJECT))) {
+				acpi_os_printf ("Cannot read entire Parser object at address %p\n", obj_ptr);
+				return;
+			}
+
+
+			acpi_ut_dump_buffer (obj_ptr, sizeof (ACPI_PARSE_OBJECT), display, ACPI_UINT32_MAX);
+			acpi_db_dump_parser_descriptor ((ACPI_PARSE_OBJECT *) obj_ptr);
+		}
+
+		else {
+			size = 16;
+			if (acpi_os_readable (obj_ptr, 64)) {
+				size = 64;
+			}
+
+			/* Just dump some memory */
+
+			acpi_ut_dump_buffer (obj_ptr, size, display, ACPI_UINT32_MAX);
+		}
+
+		return;
+	}
+
+
+	/* The parameter is a name string that must be resolved to a Named obj */
+
+	node = acpi_db_local_ns_lookup (target);
+	if (!node) {
+		return;
+	}
+
+
+dump_nte:
+	/* Now dump the Named obj */
+
+	status = acpi_get_name (node, ACPI_FULL_PATHNAME, &ret_buf);
+	if (ACPI_FAILURE (status)) {
+		acpi_os_printf ("Could not convert name to pathname\n");
+	}
+
+	else {
+		acpi_os_printf ("Object Pathname: %s\n", ret_buf.pointer);
+	}
+
+	if (!acpi_os_readable (node, sizeof (ACPI_NAMESPACE_NODE))) {
+		acpi_os_printf ("Invalid Named object at address %p\n", node);
+		return;
+	}
+
+	acpi_ut_dump_buffer ((void *) node, sizeof (ACPI_NAMESPACE_NODE), display, ACPI_UINT32_MAX);
+	acpi_ex_dump_node (node, 1);
+
+	if (node->object) {
+		acpi_os_printf ("\n_attached Object (%p):\n", node->object);
+		if (!acpi_os_readable (node->object, sizeof (ACPI_OPERAND_OBJECT))) {
+			acpi_os_printf ("Invalid internal ACPI Object at address %p\n", node->object);
+			return;
+		}
+
+		acpi_ut_dump_buffer (node->object, sizeof (ACPI_OPERAND_OBJECT), display, ACPI_UINT32_MAX);
+		acpi_ex_dump_object_descriptor (node->object, 1);
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_decode_internal_object
+ *
+ * PARAMETERS:  Obj_desc        - Object to be displayed
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Short display of an internal object.  Numbers and Strings.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_decode_internal_object (
+	ACPI_OPERAND_OBJECT     *obj_desc)
+{
+	u32                     i;
+
+
+	if (!obj_desc) {
+		return;
+	}
+
+	acpi_os_printf (" %s", acpi_ut_get_type_name (obj_desc->common.type));
+
+	switch (obj_desc->common.type) {
+	case ACPI_TYPE_INTEGER:
+		acpi_os_printf (" %.8X", obj_desc->integer.value);
+		break;
+
+	case ACPI_TYPE_STRING:
+		acpi_os_printf ("(%d) \"%.16s\"...",
+				obj_desc->string.length, obj_desc->string.pointer);
+		break;
+
+	case ACPI_TYPE_BUFFER:
+		acpi_os_printf ("(%d)", obj_desc->buffer.length);
+		for (i = 0; (i < 8) && (i < obj_desc->buffer.length); i++) {
+			acpi_os_printf (" %2.2X", obj_desc->buffer.pointer[i]);
+		}
+		break;
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_display_internal_object
+ *
+ * PARAMETERS:  Obj_desc        - Object to be displayed
+ *              Walk_state      - Current walk state
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Short display of an internal object
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_internal_object (
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	ACPI_WALK_STATE         *walk_state)
+{
+	u8                      type;
+
+
+	acpi_os_printf ("%p ", obj_desc);
+
+	if (!obj_desc) {
+		acpi_os_printf ("<Null_obj>\n");
+		return;
+	}
+
+
+	/* Decode the object type */
+
+	else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_PARSER)) {
+		acpi_os_printf ("<Parser> ");
+	}
+
+	else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
+		acpi_os_printf ("<Node>          Name %4.4s Type-%s",
+				  &((ACPI_NAMESPACE_NODE *)obj_desc)->name,
+				  acpi_ut_get_type_name (((ACPI_NAMESPACE_NODE *) obj_desc)->type));
+		if (((ACPI_NAMESPACE_NODE *) obj_desc)->flags & ANOBJ_METHOD_ARG) {
+			acpi_os_printf (" [Method Arg]");
+		}
+		if (((ACPI_NAMESPACE_NODE *) obj_desc)->flags & ANOBJ_METHOD_LOCAL) {
+			acpi_os_printf (" [Method Local]");
+		}
+	}
+
+	else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) {
+		acpi_os_printf ("<Obj> ");
+		type = obj_desc->common.type;
+		if (type > INTERNAL_TYPE_MAX) {
+			acpi_os_printf (" Type %x [Invalid Type]", type);
+			return;
+		}
+
+		/* Decode the ACPI object type */
+
+		switch (obj_desc->common.type) {
+		case INTERNAL_TYPE_REFERENCE:
+			switch (obj_desc->reference.opcode) {
+			case AML_ZERO_OP:
+				acpi_os_printf ("[Const]   Number %.8X", 0);
+				break;
+
+			case AML_ONES_OP:
+				acpi_os_printf ("[Const]   Number %.8X", ACPI_UINT32_MAX);
+				break;
+
+			case AML_ONE_OP:
+				acpi_os_printf ("[Const]   Number %.8X", 1);
+				break;
+
+			case AML_LOCAL_OP:
+				acpi_os_printf ("[Local%d] ", obj_desc->reference.offset);
+				if (walk_state) {
+					obj_desc = walk_state->local_variables[obj_desc->reference.offset].object;
+					acpi_db_decode_internal_object (obj_desc);
+				}
+				break;
+
+			case AML_ARG_OP:
+				acpi_os_printf ("[Arg%d]   ", obj_desc->reference.offset);
+				if (walk_state) {
+					obj_desc = walk_state->arguments[obj_desc->reference.offset].object;
+					acpi_db_decode_internal_object (obj_desc);
+				}
+				break;
+
+			case AML_DEBUG_OP:
+				acpi_os_printf ("[Debug] ");
+				break;
+
+			case AML_INDEX_OP:
+				acpi_os_printf ("[Index]   ");
+				acpi_db_decode_internal_object (obj_desc->reference.object);
+				break;
+
+			default:
+				break;
+
+			}
+			break;
+
+		default:
+			acpi_os_printf ("         ");
+			acpi_db_decode_internal_object (obj_desc);
+			break;
+		}
+	}
+
+	else {
+		acpi_os_printf ("<Not a valid ACPI Object Descriptor> ");
+	}
+
+	acpi_os_printf ("\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_display_method_info
+ *
+ * PARAMETERS:  Start_op        - Root of the control method parse tree
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display information about the current method
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_method_info (
+	ACPI_PARSE_OBJECT       *start_op)
+{
+	ACPI_WALK_STATE         *walk_state;
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	ACPI_NAMESPACE_NODE     *node;
+	ACPI_PARSE_OBJECT       *root_op;
+	ACPI_PARSE_OBJECT       *op;
+	ACPI_OPCODE_INFO        *op_info;
+	u32                     num_ops = 0;
+	u32                     num_operands = 0;
+	u32                     num_operators = 0;
+	u32                     num_remaining_ops = 0;
+	u32                     num_remaining_operands = 0;
+	u32                     num_remaining_operators = 0;
+	u32                     num_args;
+	u32                     concurrency;
+	u8                      count_remaining = FALSE;
+
+
+	walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list);
+	if (!walk_state) {
+		acpi_os_printf ("There is no method currently executing\n");
+		return;
+	}
+
+	obj_desc = walk_state->method_desc;
+	node = walk_state->method_node;
+
+	num_args = obj_desc->method.param_count;
+	concurrency = obj_desc->method.concurrency;
+
+	acpi_os_printf ("Currently executing control method is [%4.4s]\n", &node->name);
+	acpi_os_printf ("%X arguments, max concurrency = %X\n", num_args, concurrency);
+
+
+	root_op = start_op;
+	while (root_op->parent) {
+		root_op = root_op->parent;
+	}
+
+	op = root_op;
+
+	while (op) {
+		if (op == start_op) {
+			count_remaining = TRUE;
+		}
+
+		num_ops++;
+		if (count_remaining) {
+			num_remaining_ops++;
+		}
+
+		op_info = acpi_ps_get_opcode_info (op->opcode);
+		if (ACPI_GET_OP_TYPE (op_info) != ACPI_OP_TYPE_OPCODE) {
+			/* Bad opcode or ASCII character */
+
+			continue;
+		}
+
+
+		/* Decode the opcode */
+
+		switch (ACPI_GET_OP_CLASS (op_info)) {
+		case OPTYPE_CONSTANT:           /* argument type only */
+		case OPTYPE_LITERAL:            /* argument type only */
+		case OPTYPE_DATA_TERM:          /* argument type only */
+		case OPTYPE_LOCAL_VARIABLE:     /* argument type only */
+		case OPTYPE_METHOD_ARGUMENT:    /* argument type only */
+			if (count_remaining) {
+				num_remaining_operands++;
+			}
+
+			num_operands++;
+			break;
+
+		default:
+			if (count_remaining) {
+				num_remaining_operators++;
+			}
+
+			num_operators++;
+			break;
+		}
+
+
+		op = acpi_ps_get_depth_next (start_op, op);
+	}
+
+	acpi_os_printf ("Method contains:     %X AML Opcodes - %X Operators, %X Operands\n",
+			 num_ops, num_operators, num_operands);
+
+	acpi_os_printf ("Remaining to execute: %X AML Opcodes - %X Operators, %X Operands\n",
+			 num_remaining_ops, num_remaining_operators, num_remaining_operands);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_display_locals
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display all locals for the currently running control method
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_locals (void)
+{
+	u32                     i;
+	ACPI_WALK_STATE         *walk_state;
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	ACPI_NAMESPACE_NODE     *node;
+
+
+	walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list);
+	if (!walk_state) {
+		acpi_os_printf ("There is no method currently executing\n");
+		return;
+	}
+
+	obj_desc = walk_state->method_desc;
+	node = walk_state->method_node;
+
+
+	acpi_os_printf ("Local Variables for method [%4.4s]:\n", &node->name);
+
+	for (i = 0; i < MTH_NUM_LOCALS; i++) {
+		obj_desc = walk_state->local_variables[i].object;
+		acpi_os_printf ("Local%d: ", i);
+		acpi_db_display_internal_object (obj_desc, walk_state);
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_display_arguments
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display all arguments for the currently running control method
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_arguments (void)
+{
+	u32                     i;
+	ACPI_WALK_STATE         *walk_state;
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	u32                     num_args;
+	u32                     concurrency;
+	ACPI_NAMESPACE_NODE     *node;
+
+
+	walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list);
+	if (!walk_state) {
+		acpi_os_printf ("There is no method currently executing\n");
+		return;
+	}
+
+	obj_desc = walk_state->method_desc;
+	node = walk_state->method_node;
+
+	num_args = obj_desc->method.param_count;
+	concurrency = obj_desc->method.concurrency;
+
+	acpi_os_printf ("Method [%4.4s] has %X arguments, max concurrency = %X\n", &node->name, num_args, concurrency);
+
+	for (i = 0; i < num_args; i++) {
+		obj_desc = walk_state->arguments[i].object;
+		acpi_os_printf ("Arg%d: ", i);
+		acpi_db_display_internal_object (obj_desc, walk_state);
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_display_results
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display current contents of a method result stack
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_results (void)
+{
+	u32                     i;
+	ACPI_WALK_STATE         *walk_state;
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	u32                     num_results = 0;
+	ACPI_NAMESPACE_NODE     *node;
+
+
+	walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list);
+	if (!walk_state) {
+		acpi_os_printf ("There is no method currently executing\n");
+		return;
+	}
+
+	obj_desc = walk_state->method_desc;
+	node = walk_state->method_node;
+
+	if (walk_state->results) {
+		num_results = walk_state->results->results.num_results;
+	}
+
+	acpi_os_printf ("Method [%4.4s] has %X stacked result objects\n", &node->name, num_results);
+
+	for (i = 0; i < num_results; i++) {
+		obj_desc = walk_state->results->results.obj_desc[i];
+		acpi_os_printf ("Result%d: ", i);
+		acpi_db_display_internal_object (obj_desc, walk_state);
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_display_calling_tree
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display current calling tree of nested control methods
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_calling_tree (void)
+{
+	u32                     i;
+	ACPI_WALK_STATE         *walk_state;
+	ACPI_NAMESPACE_NODE     *node;
+
+
+	walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list);
+	if (!walk_state) {
+		acpi_os_printf ("There is no method currently executing\n");
+		return;
+	}
+
+	node = walk_state->method_node;
+
+	acpi_os_printf ("Current Control Method Call Tree\n");
+
+	for (i = 0; walk_state; i++) {
+		node = walk_state->method_node;
+
+		acpi_os_printf ("  [%4.4s]\n", &node->name);
+
+		walk_state = walk_state->next;
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_display_result_object
+ *
+ * PARAMETERS:  Obj_desc        - Object to be displayed
+ *              Walk_state      - Current walk state
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display the result of an AML opcode
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_result_object (
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	ACPI_WALK_STATE         *walk_state)
+{
+
+	/* TBD: [Future] We don't always want to display the result.
+	 * For now, only display if single stepping
+	 * however, this output is very useful in other contexts also
+	 */
+
+	if (!acpi_gbl_cm_single_step) {
+		return;
+	}
+
+	acpi_os_printf ("Result_obj: ");
+	acpi_db_display_internal_object (obj_desc, walk_state);
+	acpi_os_printf ("\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_display_argument_object
+ *
+ * PARAMETERS:  Obj_desc        - Object to be displayed
+ *              Walk_state      - Current walk state
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display the result of an AML opcode
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_argument_object (
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	ACPI_WALK_STATE         *walk_state)
+{
+
+
+	if (!acpi_gbl_cm_single_step) {
+		return;
+	}
+
+	acpi_os_printf ("Arg_obj: ");
+	acpi_db_display_internal_object (obj_desc, walk_state);
+}
+
+#endif /* ENABLE_DEBUGGER */
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/debugger/dbexec.c linux/drivers/acpi/debugger/dbexec.c
--- v2.4.5/linux/drivers/acpi/debugger/dbexec.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/debugger/dbexec.c	Wed Jun 20 17:47:39 2001
@@ -0,0 +1,341 @@
+/*******************************************************************************
+ *
+ * Module Name: dbexec - debugger control method execution
+ *              $Revision: 26 $
+ *
+ ******************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "acdispat.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+#include "acparser.h"
+#include "acevents.h"
+#include "acinterp.h"
+#include "acdebug.h"
+#include "actables.h"
+
+#ifdef ENABLE_DEBUGGER
+
+#define _COMPONENT          ACPI_DEBUGGER
+	 MODULE_NAME         ("dbexec")
+
+
+DB_METHOD_INFO              info;
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_execute_method
+ *
+ * PARAMETERS:  Info            - Valid info segment
+ *              Return_obj      - Where to put return object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute a control method.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_db_execute_method (
+	DB_METHOD_INFO          *info,
+	ACPI_BUFFER             *return_obj)
+{
+	ACPI_STATUS             status;
+	ACPI_OBJECT_LIST        param_objects;
+	ACPI_OBJECT             params[MTH_NUM_ARGS];
+	u32                     i;
+
+
+	if (output_to_file && !acpi_dbg_level) {
+		acpi_os_printf ("Warning: debug output is not enabled!\n");
+	}
+
+	/* Are there arguments to the method? */
+
+	if (info->args && info->args[0]) {
+		for (i = 0; info->args[i] && i < MTH_NUM_ARGS; i++) {
+			params[i].type              = ACPI_TYPE_INTEGER;
+			params[i].integer.value     = STRTOUL (info->args[i], NULL, 16);
+		}
+
+		param_objects.pointer       = params;
+		param_objects.count         = i;
+	}
+
+	else {
+		/* Setup default parameters */
+
+		params[0].type              = ACPI_TYPE_INTEGER;
+		params[0].integer.value     = 0x01020304;
+
+		params[1].type              = ACPI_TYPE_STRING;
+		params[1].string.length     = 12;
+		params[1].string.pointer    = "AML Debugger";
+
+		param_objects.pointer       = params;
+		param_objects.count         = 2;
+	}
+
+	/* Prepare for a return object of arbitrary size */
+
+	return_obj->pointer          = buffer;
+	return_obj->length           = BUFFER_SIZE;
+
+
+	/* Do the actual method execution */
+
+	status = acpi_evaluate_object (NULL, info->pathname, &param_objects, return_obj);
+
+	acpi_gbl_cm_single_step = FALSE;
+	acpi_gbl_method_executing = FALSE;
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_execute_setup
+ *
+ * PARAMETERS:  Info            - Valid method info
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Setup info segment prior to method execution
+ *
+ ******************************************************************************/
+
+void
+acpi_db_execute_setup (
+	DB_METHOD_INFO          *info)
+{
+
+	/* Catenate the current scope to the supplied name */
+
+	info->pathname[0] = 0;
+	if ((info->name[0] != '\\') &&
+		(info->name[0] != '/')) {
+		STRCAT (info->pathname, scope_buf);
+	}
+
+	STRCAT (info->pathname, info->name);
+	acpi_db_prep_namestring (info->pathname);
+
+	acpi_db_set_output_destination (DB_DUPLICATE_OUTPUT);
+	acpi_os_printf ("Executing %s\n", info->pathname);
+
+	if (info->flags & EX_SINGLE_STEP) {
+		acpi_gbl_cm_single_step = TRUE;
+		acpi_db_set_output_destination (DB_CONSOLE_OUTPUT);
+	}
+
+	else {
+		/* No single step, allow redirection to a file */
+
+		acpi_db_set_output_destination (DB_REDIRECTABLE_OUTPUT);
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_execute
+ *
+ * PARAMETERS:  Name                - Name of method to execute
+ *              Args                - Parameters to the method
+ *              Flags               - single step/no single step
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute a control method.  Name is relative to the current
+ *              scope.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_execute (
+	NATIVE_CHAR             *name,
+	NATIVE_CHAR             **args,
+	u32                     flags)
+{
+	ACPI_STATUS             status;
+	ACPI_BUFFER             return_obj;
+
+
+	info.name = name;
+	info.args = args;
+	info.flags = flags;
+
+	acpi_db_execute_setup (&info);
+	status = acpi_db_execute_method (&info, &return_obj);
+
+
+	if (ACPI_FAILURE (status)) {
+		acpi_os_printf ("Execution of %s failed with status %s\n",
+			info.pathname, acpi_ut_format_exception (status));
+	}
+
+	else {
+		/* Display a return object, if any */
+
+		if (return_obj.length) {
+			acpi_os_printf ("Execution of %s returned object %p Buflen %X\n",
+				info.pathname, return_obj.pointer, return_obj.length);
+			acpi_db_dump_object (return_obj.pointer, 1);
+		}
+	}
+
+	acpi_db_set_output_destination (DB_CONSOLE_OUTPUT);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_method_thread
+ *
+ * PARAMETERS:  Context             - Execution info segment
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Debugger execute thread.  Waits for a command line, then
+ *              simply dispatches it.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_method_thread (
+	void                    *context)
+{
+	ACPI_STATUS             status;
+	DB_METHOD_INFO          *info = context;
+	u32                     i;
+	ACPI_BUFFER             return_obj;
+
+
+	for (i = 0; i < info->num_loops; i++) {
+		status = acpi_db_execute_method (info, &return_obj);
+		if (ACPI_SUCCESS (status)) {
+			if (return_obj.length) {
+				acpi_os_printf ("Execution of %s returned object %p Buflen %X\n",
+					info->pathname, return_obj.pointer, return_obj.length);
+				acpi_db_dump_object (return_obj.pointer, 1);
+			}
+		}
+	}
+
+
+	/* Signal our completion */
+
+	acpi_os_signal_semaphore (info->thread_gate, 1);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_create_execution_threads
+ *
+ * PARAMETERS:  Num_threads_arg         - Number of threads to create
+ *              Num_loops_arg           - Loop count for the thread(s)
+ *              Method_name_arg         - Control method to execute
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Create threads to execute method(s)
+ *
+ ******************************************************************************/
+
+void
+acpi_db_create_execution_threads (
+	NATIVE_CHAR             *num_threads_arg,
+	NATIVE_CHAR             *num_loops_arg,
+	NATIVE_CHAR             *method_name_arg)
+{
+	ACPI_STATUS             status;
+	u32                     num_threads;
+	u32                     num_loops;
+	u32                     i;
+	ACPI_HANDLE             thread_gate;
+
+
+	/* Get the arguments */
+
+	num_threads = STRTOUL (num_threads_arg, NULL, 0);
+	num_loops = STRTOUL (num_loops_arg, NULL, 0);
+
+	if (!num_threads || !num_loops) {
+		acpi_os_printf ("Bad argument: Threads %X, Loops %X\n", num_threads, num_loops);
+		return;
+	}
+
+
+	/* Create the synchronization semaphore */
+
+	status = acpi_os_create_semaphore (1, 0, &thread_gate);
+	if (ACPI_FAILURE (status)) {
+		acpi_os_printf ("Could not create semaphore, %s\n", acpi_ut_format_exception (status));
+		return;
+	}
+
+	/* Setup the context to be passed to each thread */
+
+	info.name = method_name_arg;
+	info.args = NULL;
+	info.flags = 0;
+	info.num_loops = num_loops;
+	info.thread_gate = thread_gate;
+
+	acpi_db_execute_setup (&info);
+
+
+	/* Create the threads */
+
+	acpi_os_printf ("Creating %X threads to execute %X times each\n", num_threads, num_loops);
+
+	for (i = 0; i < (num_threads); i++) {
+		acpi_os_queue_for_execution (OSD_PRIORITY_MED, acpi_db_method_thread, &info);
+	}
+
+
+	/* Wait for all threads to complete */
+
+	i = num_threads;
+	while (i)   /* Brain damage for OSD implementations that only support wait of 1 unit */ {
+		status = acpi_os_wait_semaphore (thread_gate, 1, WAIT_FOREVER);
+		i--;
+	}
+
+	/* Cleanup and exit */
+
+	acpi_os_delete_semaphore (thread_gate);
+
+	acpi_db_set_output_destination (DB_DUPLICATE_OUTPUT);
+	acpi_os_printf ("All threads (%X) have completed\n", num_threads);
+	acpi_db_set_output_destination (DB_CONSOLE_OUTPUT);
+}
+
+
+#endif /* ENABLE_DEBUGGER */
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/debugger/dbfileio.c linux/drivers/acpi/debugger/dbfileio.c
--- v2.4.5/linux/drivers/acpi/debugger/dbfileio.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/debugger/dbfileio.c	Wed Jun 20 17:47:39 2001
@@ -0,0 +1,378 @@
+/*******************************************************************************
+ *
+ * Module Name: dbfileio - Debugger file I/O commands.  These can't usually
+ *              be used when running the debugger in Ring 0 (Kernel mode)
+ *              $Revision: 41 $
+ *
+ ******************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acdebug.h"
+#include "acnamesp.h"
+#include "acparser.h"
+#include "acevents.h"
+#include "actables.h"
+
+#ifdef ENABLE_DEBUGGER
+
+#define _COMPONENT          ACPI_DEBUGGER
+	 MODULE_NAME         ("dbfileio")
+
+
+ACPI_PARSE_OBJECT           *root;
+
+#ifdef ACPI_APPLICATION
+#include <stdio.h>
+FILE                        *debug_file = NULL;
+#endif
+
+
+/*
+ * NOTE: this is here for lack of a better place.  It is used in all
+ *  flavors of the debugger, need LCD file
+ */
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_match_argument
+ *
+ * PARAMETERS:  User_argument           - User command line
+ *              Arguments               - Array of commands to match against
+ *
+ * RETURN:      Index into command array or ACPI_TYPE_NOT_FOUND if not found
+ *
+ * DESCRIPTION: Search command array for a command match
+ *
+ ******************************************************************************/
+
+ACPI_OBJECT_TYPE8
+acpi_db_match_argument (
+	NATIVE_CHAR             *user_argument,
+	ARGUMENT_INFO           *arguments)
+{
+	u32                     i;
+
+
+	if (!user_argument || user_argument[0] == 0) {
+		return (ACPI_TYPE_NOT_FOUND);
+	}
+
+	for (i = 0; arguments[i].name; i++) {
+		if (STRSTR (arguments[i].name, user_argument) == arguments[i].name) {
+			return ((ACPI_OBJECT_TYPE8) i);
+		}
+	}
+
+	/* Argument not recognized */
+
+	return (ACPI_TYPE_NOT_FOUND);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_close_debug_file
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: If open, close the current debug output file
+ *
+ ******************************************************************************/
+
+void
+acpi_db_close_debug_file (
+	void)
+{
+
+#ifdef ACPI_APPLICATION
+
+	if (debug_file) {
+	   fclose (debug_file);
+	   debug_file = NULL;
+	   output_to_file = FALSE;
+	   acpi_os_printf ("Debug output file %s closed\n", debug_filename);
+	}
+#endif
+
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_open_debug_file
+ *
+ * PARAMETERS:  Name                - Filename to open
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Open a file where debug output will be directed.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_open_debug_file (
+	NATIVE_CHAR             *name)
+{
+
+#ifdef ACPI_APPLICATION
+
+	acpi_db_close_debug_file ();
+	debug_file = fopen (name, "w+");
+	if (debug_file) {
+		acpi_os_printf ("Debug output file %s opened\n", name);
+		STRCPY (debug_filename, name);
+		output_to_file = TRUE;
+	}
+	else {
+		acpi_os_printf ("Could not open debug file %s\n", name);
+	}
+
+#endif
+}
+
+
+#ifdef ACPI_APPLICATION
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_load_table
+ *
+ * PARAMETERS:  fp              - File that contains table
+ *              Table_ptr       - Return value, buffer with table
+ *              Table_lenght    - Return value, length of table
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Load the DSDT from the file pointer
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_db_load_table(
+	FILE                    *fp,
+	ACPI_TABLE_HEADER       **table_ptr,
+	u32                     *table_length)
+{
+	ACPI_TABLE_HEADER       table_header;
+	u8                      *aml_ptr;
+	u32                     aml_length;
+	u32                     actual;
+	ACPI_STATUS             status;
+
+
+	/* Read the table header */
+
+	if (fread (&table_header, 1, sizeof (table_header), fp) != sizeof (ACPI_TABLE_HEADER)) {
+		acpi_os_printf ("Couldn't read the table header\n");
+		return (AE_BAD_SIGNATURE);
+	}
+
+
+	/* Validate the table header/length */
+
+	status = acpi_tb_validate_table_header (&table_header);
+	if ((ACPI_FAILURE (status)) ||
+		(table_header.length > 524288)) /* 1/2 Mbyte should be enough */ {
+		acpi_os_printf ("Table header is invalid!\n");
+		return (AE_ERROR);
+	}
+
+
+	/* We only support a limited number of table types */
+
+	if (STRNCMP ((char *) table_header.signature, DSDT_SIG, 4) &&
+		STRNCMP ((char *) table_header.signature, PSDT_SIG, 4) &&
+		STRNCMP ((char *) table_header.signature, SSDT_SIG, 4)) {
+		acpi_os_printf ("Table signature is invalid\n");
+		return (AE_ERROR);
+	}
+
+	/* Allocate a buffer for the table */
+
+	*table_length = table_header.length;
+	*table_ptr = (ACPI_TABLE_HEADER *) acpi_ut_allocate ((size_t) *table_length);
+	if (!*table_ptr) {
+		acpi_os_printf ("Could not allocate memory for the table (size=%X)\n", table_header.length);
+		return (AE_NO_MEMORY);
+	}
+
+
+	aml_ptr     = (u8 *) *table_ptr + sizeof (table_header);
+	aml_length  = *table_length - sizeof (table_header);
+
+	/* Copy the header to the buffer */
+
+	MEMCPY (*table_ptr, &table_header, sizeof (table_header));
+
+	/* Get the rest of the table */
+
+	actual = fread (aml_ptr, 1, (size_t) aml_length, fp);
+	if (actual == aml_length) {
+		return (AE_OK);
+	}
+
+	if (actual > 0) {
+		acpi_os_printf ("Warning - reading table, asked for %X got %X\n", aml_length, actual);
+	   return (AE_OK);
+	}
+
+
+	acpi_os_printf ("Error - could not read the table file\n");
+	acpi_ut_free (*table_ptr);
+	*table_ptr = NULL;
+	*table_length = 0;
+
+	return (AE_ERROR);
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Ae_local_load_table
+ *
+ * PARAMETERS:  Table_ptr       - pointer to a buffer containing the entire
+ *                                table to be loaded
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to load a table from the caller's
+ *              buffer.  The buffer must contain an entire ACPI Table including
+ *              a valid header.  The header fields will be verified, and if it
+ *              is determined that the table is invalid, the call will fail.
+ *
+ *              If the call fails an appropriate status will be returned.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+ae_local_load_table (
+	ACPI_TABLE_HEADER       *table_ptr)
+{
+	ACPI_STATUS             status;
+	ACPI_TABLE_DESC         table_info;
+
+
+	if (!table_ptr) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	/* Install the new table into the local data structures */
+
+	table_info.pointer = table_ptr;
+
+	status = acpi_tb_install_table (NULL, &table_info);
+	if (ACPI_FAILURE (status)) {
+		/* Free table allocated by Acpi_tb_get_table */
+
+		acpi_tb_delete_single_table (&table_info);
+		return (status);
+	}
+
+
+#ifndef PARSER_ONLY
+	status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node);
+	if (ACPI_FAILURE (status)) {
+		/* Uninstall table and free the buffer */
+
+		acpi_tb_uninstall_table (table_info.installed_desc);
+		return (status);
+	}
+#endif
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_load_acpi_table
+ *
+ * PARAMETERS:  Filname         - File where table is located
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Load an ACPI table from a file
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_db_load_acpi_table (
+	NATIVE_CHAR             *filename)
+{
+#ifdef ACPI_APPLICATION
+	FILE                    *fp;
+	ACPI_STATUS             status;
+	ACPI_TABLE_HEADER       *table_ptr;
+	u32                     table_length;
+
+
+	/* Open the file */
+
+	fp = fopen (filename, "rb");
+	if (!fp) {
+		acpi_os_printf ("Could not open file %s\n", filename);
+		return (AE_ERROR);
+	}
+
+
+	/* Get the entire file */
+
+	acpi_os_printf ("Loading Acpi table from file %s\n", filename);
+	status = acpi_db_load_table (fp, &table_ptr, &table_length);
+	fclose(fp);
+
+	if (ACPI_FAILURE (status)) {
+		acpi_os_printf ("Couldn't get table from the file\n");
+		return (status);
+	}
+
+
+	/* Attempt to recognize and install the table */
+	status = ae_local_load_table (table_ptr);
+
+	if (ACPI_FAILURE (status)) {
+		if (status == AE_EXIST) {
+			acpi_os_printf ("Table %4.4s is already installed\n",
+					  &table_ptr->signature);
+		}
+		else {
+			acpi_os_printf ("Could not install table, %s\n",
+					  acpi_ut_format_exception (status));
+		}
+		acpi_ut_free (table_ptr);
+		return (status);
+	}
+
+	acpi_os_printf ("%4.4s at %p successfully installed and loaded\n",
+			  &table_ptr->signature, table_ptr);
+
+	acpi_gbl_acpi_hardware_present = FALSE;
+
+#endif  /* ACPI_APPLICATION */
+	return (AE_OK);
+}
+
+
+#endif  /* ENABLE_DEBUGGER */
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/debugger/dbhistry.c linux/drivers/acpi/debugger/dbhistry.c
--- v2.4.5/linux/drivers/acpi/debugger/dbhistry.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/debugger/dbhistry.c	Wed Jun 20 17:47:39 2001
@@ -0,0 +1,199 @@
+/******************************************************************************
+ *
+ * Module Name: dbhistry - debugger HISTORY command
+ *              $Revision: 18 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "acdispat.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+#include "acparser.h"
+#include "acevents.h"
+#include "acinterp.h"
+#include "acdebug.h"
+#include "actables.h"
+
+#ifdef ENABLE_DEBUGGER
+
+#define _COMPONENT          ACPI_DEBUGGER
+	 MODULE_NAME         ("dbhistry")
+
+
+#define HI_NO_HISTORY       0
+#define HI_RECORD_HISTORY   1
+#define HISTORY_SIZE        20
+
+
+typedef struct history_info
+{
+	NATIVE_CHAR             command[80];
+	u32                     cmd_num;
+
+} HISTORY_INFO;
+
+
+HISTORY_INFO                history_buffer[HISTORY_SIZE];
+u16                         lo_history = 0;
+u16                         num_history = 0;
+u16                         next_history_index = 0;
+u32                         next_cmd_num = 1;
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_add_to_history
+ *
+ * PARAMETERS:  Command_line    - Command to add
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Add a command line to the history buffer.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_add_to_history (
+	NATIVE_CHAR             *command_line)
+{
+
+
+	/* Put command into the next available slot */
+
+	STRCPY (history_buffer[next_history_index].command, command_line);
+	history_buffer[next_history_index].cmd_num = next_cmd_num;
+
+	/* Adjust indexes */
+
+	if ((num_history == HISTORY_SIZE) &&
+		(next_history_index == lo_history)) {
+		lo_history++;
+		if (lo_history >= HISTORY_SIZE) {
+			lo_history = 0;
+		}
+	}
+
+	next_history_index++;
+	if (next_history_index >= HISTORY_SIZE) {
+		next_history_index = 0;
+	}
+
+
+	next_cmd_num++;
+	if (num_history < HISTORY_SIZE) {
+		num_history++;
+	}
+
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_display_history
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display the contents of the history buffer
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_history (void)
+{
+	NATIVE_UINT             i;
+	u16                     history_index;
+
+
+	history_index = lo_history;
+
+	/* Dump entire history buffer */
+
+	for (i = 0; i < num_history; i++) {
+		acpi_os_printf ("%ld %s\n", history_buffer[history_index].cmd_num, history_buffer[history_index].command);
+
+		history_index++;
+		if (history_index >= HISTORY_SIZE) {
+			history_index = 0;
+		}
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_get_from_history
+ *
+ * PARAMETERS:  Command_num_arg         - String containing the number of the
+ *                                        command to be retrieved
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Get a command from the history buffer
+ *
+ ******************************************************************************/
+
+NATIVE_CHAR *
+acpi_db_get_from_history (
+	NATIVE_CHAR             *command_num_arg)
+{
+	NATIVE_UINT             i;
+	u16                     history_index;
+	u32                     cmd_num;
+
+
+	if (command_num_arg == NULL) {
+		cmd_num = next_cmd_num - 1;
+	}
+
+	else {
+		cmd_num = STRTOUL (command_num_arg, NULL, 0);
+	}
+
+
+	/* Search history buffer */
+
+	history_index = lo_history;
+	for (i = 0; i < num_history; i++) {
+		if (history_buffer[history_index].cmd_num == cmd_num) {
+			/* Found the commnad, return it */
+
+			return (history_buffer[history_index].command);
+		}
+
+
+		history_index++;
+		if (history_index >= HISTORY_SIZE) {
+			history_index = 0;
+		}
+	}
+
+	acpi_os_printf ("Invalid history number: %d\n", history_index);
+	return (NULL);
+}
+
+
+#endif /* ENABLE_DEBUGGER */
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/debugger/dbinput.c linux/drivers/acpi/debugger/dbinput.c
--- v2.4.5/linux/drivers/acpi/debugger/dbinput.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/debugger/dbinput.c	Wed Jun 20 17:47:39 2001
@@ -0,0 +1,909 @@
+/*******************************************************************************
+ *
+ * Module Name: dbinput - user front-end to the AML debugger
+ *              $Revision: 61 $
+ *
+ ******************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "actables.h"
+#include "acnamesp.h"
+#include "acinterp.h"
+#include "acdebug.h"
+
+
+#ifdef ENABLE_DEBUGGER
+
+#define _COMPONENT          ACPI_DEBUGGER
+	 MODULE_NAME         ("dbinput")
+
+
+/*
+ * Globals that are specific to the debugger
+ */
+
+NATIVE_CHAR             line_buf[80];
+NATIVE_CHAR             parsed_buf[80];
+NATIVE_CHAR             scope_buf[40];
+NATIVE_CHAR             debug_filename[40];
+NATIVE_CHAR             *args[DB_MAX_ARGS];
+NATIVE_CHAR             *buffer;
+NATIVE_CHAR             *filename = NULL;
+u8                      output_to_file = FALSE;
+
+
+u32                     acpi_gbl_db_debug_level = 0x0FFFFFFF;
+u32                     acpi_gbl_db_console_debug_level = NORMAL_DEFAULT | TRACE_TABLES;
+u8                      acpi_gbl_db_output_flags = DB_CONSOLE_OUTPUT;
+
+
+u8                      opt_tables      = FALSE;
+u8                      opt_disasm      = FALSE;
+u8                      opt_stats       = FALSE;
+u8                      opt_parse_jit   = FALSE;
+u8                      opt_verbose     = TRUE;
+u8                      opt_ini_methods = TRUE;
+
+
+/*
+ * Top-level debugger commands.
+ *
+ * This list of commands must match the string table below it
+ */
+
+enum acpi_ex_debugger_commands
+{
+	CMD_NOT_FOUND = 0,
+	CMD_NULL,
+	CMD_ALLOCATIONS,
+	CMD_ARGS,
+	CMD_ARGUMENTS,
+	CMD_BREAKPOINT,
+	CMD_CALL,
+	CMD_CLOSE,
+	CMD_DEBUG,
+	CMD_DUMP,
+	CMD_ENABLEACPI,
+	CMD_EVENT,
+	CMD_EXECUTE,
+	CMD_EXIT,
+	CMD_FIND,
+	CMD_GO,
+	CMD_HELP,
+	CMD_HELP2,
+	CMD_HISTORY,
+	CMD_HISTORY_EXE,
+	CMD_HISTORY_LAST,
+	CMD_INFORMATION,
+	CMD_INTO,
+	CMD_LEVEL,
+	CMD_LIST,
+	CMD_LOAD,
+	CMD_LOCALS,
+	CMD_LOCKS,
+	CMD_METHODS,
+	CMD_NAMESPACE,
+	CMD_NOTIFY,
+	CMD_OBJECT,
+	CMD_OPEN,
+	CMD_OWNER,
+	CMD_PREFIX,
+	CMD_QUIT,
+	CMD_REFERENCES,
+	CMD_RESOURCES,
+	CMD_RESULTS,
+	CMD_SET,
+	CMD_STATS,
+	CMD_STOP,
+	CMD_TABLES,
+	CMD_TERMINATE,
+	CMD_THREADS,
+	CMD_TREE,
+	CMD_UNLOAD
+};
+
+#define CMD_FIRST_VALID     2
+
+
+COMMAND_INFO                commands[] =
+{ {"<NOT FOUND>",  0},
+	{"<NULL>",       0},
+	{"ALLOCATIONS",  0},
+	{"ARGS",         0},
+	{"ARGUMENTS",    0},
+	{"BREAKPOINT",   1},
+	{"CALL",         0},
+	{"CLOSE",        0},
+	{"DEBUG",        1},
+	{"DUMP",         1},
+	{"ENABLEACPI",   0},
+	{"EVENT",        1},
+	{"EXECUTE",      1},
+	{"EXIT",         0},
+	{"FIND",         1},
+	{"GO",           0},
+	{"HELP",         0},
+	{"?",            0},
+	{"HISTORY",      0},
+	{"!",            1},
+	{"!!",           0},
+	{"INFORMATION",  0},
+	{"INTO",         0},
+	{"LEVEL",        0},
+	{"LIST",         0},
+	{"LOAD",         1},
+	{"LOCALS",       0},
+	{"LOCKS",        0},
+	{"METHODS",      0},
+	{"NAMESPACE",    0},
+	{"NOTIFY",       2},
+	{"OBJECT",       1},
+	{"OPEN",         1},
+	{"OWNER",        1},
+	{"PREFIX",       0},
+	{"QUIT",         0},
+	{"REFERENCES",   1},
+	{"RESOURCES",    1},
+	{"RESULTS",      0},
+	{"SET",          3},
+	{"STATS",        0},
+	{"STOP",         0},
+	{"TABLES",       0},
+	{"TERMINATE",    0},
+	{"THREADS",      3},
+	{"TREE",         0},
+	{"UNLOAD",       0},
+	{NULL,           0}
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_display_help
+ *
+ * PARAMETERS:  Help_type       - Subcommand (optional)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print a usage message.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_help (
+	NATIVE_CHAR             *help_type)
+{
+
+
+	/* No parameter, just give the overview */
+
+	if (!help_type)
+	{
+		acpi_os_printf ("ACPI CA Debugger Commands\n\n");
+		acpi_os_printf ("The following classes of commands are available. Help is available for\n");
+		acpi_os_printf ("each class by entering \"help <class_name>\"\n\n");
+		acpi_os_printf ("  [GENERAL]       General-Purpose Commands\n");
+		acpi_os_printf ("  [NAMESPACE]     Namespace Access Commands\n");
+		acpi_os_printf ("  [METHOD]        Control Method Execution Commands\n");
+		acpi_os_printf ("  [FILE]          File I/O Commands\n");
+		return;
+
+	}
+
+
+	/*
+	 * Parameter is the command class
+	 *
+	 * The idea here is to keep each class of commands smaller than a screenful
+	 */
+
+	switch (help_type[0])
+	{
+	case 'G':
+		acpi_os_printf ("\n_general-Purpose Commands\n\n");
+		acpi_os_printf ("Allocations                       Display list of current memory allocations\n");
+		acpi_os_printf ("Dump <Address>|<Namepath>\n");
+		acpi_os_printf ("   [Byte|Word|Dword|Qword]        Display ACPI objects or memory\n");
+		acpi_os_printf ("Enable_acpi                       Enable ACPI (hardware) mode\n");
+		acpi_os_printf ("Help                              This help screen\n");
+		acpi_os_printf ("History                           Display command history buffer\n");
+		acpi_os_printf ("Level [<Debug_level>] [console]   Get/Set debug level for file or console\n");
+		acpi_os_printf ("Locks                             Current status of internal mutexes\n");
+		acpi_os_printf ("Quit or Exit                      Exit this command\n");
+		acpi_os_printf ("Stats [Allocations|Memory|Misc\n");
+		acpi_os_printf ("     |Objects|Tables]             Display namespace and memory statistics\n");
+		acpi_os_printf ("Tables                            Display info about loaded ACPI tables\n");
+		acpi_os_printf ("Unload                            Unload an ACPI table\n");
+		acpi_os_printf ("! <Command_number>                Execute command from history buffer\n");
+		acpi_os_printf ("!!                                Execute last command again\n");
+		return;
+
+	case 'N':
+		acpi_os_printf ("\n_namespace Access Commands\n\n");
+		acpi_os_printf ("Debug <Namepath> [Arguments]      Single Step a control method\n");
+		acpi_os_printf ("Event <F|G> <Value>               Generate Acpi_event (Fixed/GPE)\n");
+		acpi_os_printf ("Execute <Namepath> [Arguments]    Execute control method\n");
+		acpi_os_printf ("Find <Name> (? is wildcard)       Find ACPI name(s) with wildcards\n");
+		acpi_os_printf ("Method                            Display list of loaded control methods\n");
+		acpi_os_printf ("Namespace [<Addr>|<Path>] [Depth] Display loaded namespace tree/subtree\n");
+		acpi_os_printf ("Notify <Name_path> <Value>        Send a notification\n");
+		acpi_os_printf ("Objects <Object_type>             Display all objects of the given type\n");
+		acpi_os_printf ("Owner <Owner_id> [Depth]          Display loaded namespace by object owner\n");
+		acpi_os_printf ("Prefix [<Name_path>]              Set or Get current execution prefix\n");
+		acpi_os_printf ("References <Addr>                 Find all references to object at addr\n");
+		acpi_os_printf ("Resources xxx                     Get and display resources\n");
+		acpi_os_printf ("Terminate                         Delete namespace and all internal objects\n");
+		acpi_os_printf ("Thread <Threads><Loops><Name_path> Spawn threads to execute method(s)\n");
+		return;
+
+	case 'M':
+		acpi_os_printf ("\n_control Method Execution Commands\n\n");
+		acpi_os_printf ("Arguments (or Args)               Display method arguments\n");
+		acpi_os_printf ("Breakpoint <Aml_offset>           Set an AML execution breakpoint\n");
+		acpi_os_printf ("Call                              Run to next control method invocation\n");
+		acpi_os_printf ("Go                                Allow method to run to completion\n");
+		acpi_os_printf ("Information                       Display info about the current method\n");
+		acpi_os_printf ("Into                              Step into (not over) a method call\n");
+		acpi_os_printf ("List [# of Aml Opcodes]           Display method ASL statements\n");
+		acpi_os_printf ("Locals                            Display method local variables\n");
+		acpi_os_printf ("Results                           Display method result stack\n");
+		acpi_os_printf ("Set <A|L> <#> <Value>             Set method data (Arguments/Locals)\n");
+		acpi_os_printf ("Stop                              Terminate control method\n");
+		acpi_os_printf ("Tree                              Display control method calling tree\n");
+		acpi_os_printf ("<Enter>                           Single step next AML opcode (over calls)\n");
+		return;
+
+	case 'F':
+		acpi_os_printf ("\n_file I/O Commands\n\n");
+		acpi_os_printf ("Close                             Close debug output file\n");
+		acpi_os_printf ("Open <Output Filename>            Open a file for debug output\n");
+		acpi_os_printf ("Load <Input Filename>             Load ACPI table from a file\n");
+		return;
+
+	default:
+		acpi_os_printf ("Unrecognized Command Class: %x\n", help_type);
+		return;
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_get_next_token
+ *
+ * PARAMETERS:  String          - Command buffer
+ *              Next            - Return value, end of next token
+ *
+ * RETURN:      Pointer to the start of the next token.
+ *
+ * DESCRIPTION: Command line parsing.  Get the next token on the command line
+ *
+ ******************************************************************************/
+
+NATIVE_CHAR *
+acpi_db_get_next_token (
+	NATIVE_CHAR             *string,
+	NATIVE_CHAR             **next)
+{
+	NATIVE_CHAR             *start;
+
+	/* At end of buffer? */
+
+	if (!string || !(*string))
+	{
+		return (NULL);
+	}
+
+
+	/* Get rid of any spaces at the beginning */
+
+	if (*string == ' ')
+	{
+		while (*string && (*string == ' '))
+		{
+			string++;
+		}
+
+		if (!(*string))
+		{
+			return (NULL);
+		}
+	}
+
+	start = string;
+
+	/* Find end of token */
+
+	while (*string && (*string != ' '))
+	{
+		string++;
+	}
+
+
+	if (!(*string))
+	{
+		*next = NULL;
+	}
+
+	else
+	{
+		*string = 0;
+		*next = string + 1;
+	}
+
+	return (start);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_get_line
+ *
+ * PARAMETERS:  Input_buffer        - Command line buffer
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Get the next command line from the user.  Gets entire line
+ *              up to the next newline
+ *
+ ******************************************************************************/
+
+u32
+acpi_db_get_line (
+	NATIVE_CHAR             *input_buffer)
+{
+	u32                     i;
+	u32                     count;
+	NATIVE_CHAR             *next;
+	NATIVE_CHAR             *this;
+
+
+	STRCPY (parsed_buf, input_buffer);
+	STRUPR (parsed_buf);
+
+	this = parsed_buf;
+	for (i = 0; i < DB_MAX_ARGS; i++)
+	{
+		args[i] = acpi_db_get_next_token (this, &next);
+		if (!args[i])
+		{
+			break;
+		}
+
+		this = next;
+	}
+
+
+	/* Uppercase the actual command */
+
+	if (args[0])
+	{
+		STRUPR (args[0]);
+	}
+
+	count = i;
+	if (count)
+	{
+		count--;  /* Number of args only */
+	}
+
+	return (count);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_match_command
+ *
+ * PARAMETERS:  User_command            - User command line
+ *
+ * RETURN:      Index into command array, -1 if not found
+ *
+ * DESCRIPTION: Search command array for a command match
+ *
+ ******************************************************************************/
+
+u32
+acpi_db_match_command (
+	NATIVE_CHAR             *user_command)
+{
+	u32                     i;
+
+
+	if (!user_command || user_command[0] == 0)
+	{
+		return (CMD_NULL);
+	}
+
+	for (i = CMD_FIRST_VALID; commands[i].name; i++)
+	{
+		if (STRSTR (commands[i].name, user_command) == commands[i].name)
+		{
+			return (i);
+		}
+	}
+
+	/* Command not recognized */
+
+	return (CMD_NOT_FOUND);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_command_dispatch
+ *
+ * PARAMETERS:  Input_buffer        - Command line buffer
+ *              Walk_state          - Current walk
+ *              Op                  - Current (executing) parse op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Command dispatcher.  Called from two places:
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_db_command_dispatch (
+	NATIVE_CHAR             *input_buffer,
+	ACPI_WALK_STATE         *walk_state,
+	ACPI_PARSE_OBJECT       *op)
+{
+	u32                     temp;
+	u32                     command_index;
+	u32                     param_count;
+	NATIVE_CHAR             *command_line;
+	ACPI_STATUS             status = AE_CTRL_TRUE;
+
+
+	/* If Acpi_terminate has been called, terminate this thread */
+
+	if (acpi_gbl_db_terminate_threads)
+	{
+		return (AE_CTRL_TERMINATE);
+	}
+
+	param_count = acpi_db_get_line (input_buffer);
+	command_index = acpi_db_match_command (args[0]);
+	temp = 0;
+
+	/* Verify that we have the minimum number of params */
+
+	if (param_count < commands[command_index].min_args)
+	{
+		acpi_os_printf ("%d parameters entered, [%s] requires %d parameters\n",
+				  param_count, commands[command_index].name, commands[command_index].min_args);
+		return (AE_CTRL_TRUE);
+	}
+
+	/* Decode and dispatch the command */
+
+	switch (command_index)
+	{
+	case CMD_NULL:
+		if (op)
+		{
+			return (AE_OK);
+		}
+		break;
+
+	case CMD_ALLOCATIONS:
+		acpi_ut_dump_current_allocations ((u32) -1, NULL);
+		break;
+
+	case CMD_ARGS:
+	case CMD_ARGUMENTS:
+		acpi_db_display_arguments ();
+		break;
+
+	case CMD_BREAKPOINT:
+		acpi_db_set_method_breakpoint (args[1], walk_state, op);
+		break;
+
+	case CMD_CALL:
+		acpi_db_set_method_call_breakpoint (op);
+		status = AE_OK;
+		break;
+
+	case CMD_CLOSE:
+		acpi_db_close_debug_file ();
+		break;
+
+	case CMD_DEBUG:
+		acpi_db_execute (args[1], &args[2], EX_SINGLE_STEP);
+		break;
+
+	case CMD_DUMP:
+		acpi_db_decode_and_display_object (args[1], args[2]);
+		break;
+
+	case CMD_ENABLEACPI:
+		status = acpi_enable();
+		if (ACPI_FAILURE(status))
+		{
+			acpi_os_printf("Acpi_enable failed (Status=%X)\n", status);
+			return (status);
+		}
+		break;
+
+	case CMD_EVENT:
+		acpi_os_printf ("Event command not implemented\n");
+		break;
+
+	case CMD_EXECUTE:
+		acpi_db_execute (args[1], &args[2], EX_NO_SINGLE_STEP);
+		break;
+
+	case CMD_FIND:
+		acpi_db_find_name_in_namespace (args[1]);
+		break;
+
+	case CMD_GO:
+		acpi_gbl_cm_single_step = FALSE;
+		return (AE_OK);
+
+	case CMD_HELP:
+	case CMD_HELP2:
+		acpi_db_display_help (args[1]);
+		break;
+
+	case CMD_HISTORY:
+		acpi_db_display_history ();
+		break;
+
+	case CMD_HISTORY_EXE:
+		command_line = acpi_db_get_from_history (args[1]);
+		if (!command_line)
+		{
+			return (AE_CTRL_TRUE);
+		}
+
+		status = acpi_db_command_dispatch (command_line, walk_state, op);
+		if (ACPI_SUCCESS (status))
+		{
+			status = AE_CTRL_TRUE;
+		}
+		return (status);
+		break;
+
+	case CMD_HISTORY_LAST:
+		command_line = acpi_db_get_from_history (NULL);
+		if (!command_line)
+		{
+			return (AE_CTRL_TRUE);
+		}
+
+		status = acpi_db_command_dispatch (command_line, walk_state, op);
+		if (ACPI_SUCCESS (status))
+		{
+			status = AE_CTRL_TRUE;
+		}
+		return (status);
+
+	case CMD_INFORMATION:
+		acpi_db_display_method_info (op);
+		break;
+
+	case CMD_INTO:
+		if (op)
+		{
+			acpi_gbl_cm_single_step = TRUE;
+
+/* TBD: Must get current walk state */
+			/* Acpi_gbl_Method_breakpoint = 0; */
+			return (AE_OK);
+		}
+		break;
+
+	case CMD_LEVEL:
+		if (param_count == 0)
+		{
+			acpi_os_printf ("Current debug level for file output is:  %8.8lX\n", acpi_gbl_db_debug_level);
+			acpi_os_printf ("Current debug level for console output is: %8.8lX\n", acpi_gbl_db_console_debug_level);
+		}
+		else if (param_count == 2)
+		{
+			temp = acpi_gbl_db_console_debug_level;
+			acpi_gbl_db_console_debug_level = STRTOUL (args[1], NULL, 16);
+			acpi_os_printf ("Debug Level for console output was %8.8lX, now %8.8lX\n", temp, acpi_gbl_db_console_debug_level);
+		}
+		else
+		{
+			temp = acpi_gbl_db_debug_level;
+			acpi_gbl_db_debug_level = STRTOUL (args[1], NULL, 16);
+			acpi_os_printf ("Debug Level for file output was %8.8lX, now %8.8lX\n", temp, acpi_gbl_db_debug_level);
+		}
+		break;
+
+	case CMD_LIST:
+		acpi_db_disassemble_aml (args[1], op);
+		break;
+
+	case CMD_LOAD:
+		status = acpi_db_load_acpi_table (args[1]);
+		if (ACPI_FAILURE (status))
+		{
+			return (status);
+		}
+		break;
+
+	case CMD_LOCKS:
+		acpi_db_display_locks ();
+		break;
+
+	case CMD_LOCALS:
+		acpi_db_display_locals ();
+		break;
+
+	case CMD_METHODS:
+		acpi_db_display_objects ("METHOD", args[1]);
+		break;
+
+	case CMD_NAMESPACE:
+		acpi_db_dump_namespace (args[1], args[2]);
+		break;
+
+	case CMD_NOTIFY:
+		temp = STRTOUL (args[2], NULL, 0);
+		acpi_db_send_notify (args[1], temp);
+		break;
+
+	case CMD_OBJECT:
+		acpi_db_display_objects (STRUPR (args[1]), args[2]);
+		break;
+
+	case CMD_OPEN:
+		acpi_db_open_debug_file (args[1]);
+		break;
+
+	case CMD_OWNER:
+		acpi_db_dump_namespace_by_owner (args[1], args[2]);
+		break;
+
+	case CMD_PREFIX:
+		acpi_db_set_scope (args[1]);
+		break;
+
+	case CMD_REFERENCES:
+		acpi_db_find_references (args[1]);
+		break;
+
+	case CMD_RESOURCES:
+		acpi_db_display_resources (args[1]);
+		break;
+
+	case CMD_RESULTS:
+		acpi_db_display_results ();
+		break;
+
+	case CMD_SET:
+		acpi_db_set_method_data (args[1], args[2], args[3]);
+		break;
+
+	case CMD_STATS:
+		acpi_db_display_statistics (args[1]);
+		break;
+
+	case CMD_STOP:
+		return (AE_AML_ERROR);
+		break;
+
+	case CMD_TABLES:
+		acpi_db_display_table_info (args[1]);
+		break;
+
+	case CMD_TERMINATE:
+		acpi_db_set_output_destination (DB_REDIRECTABLE_OUTPUT);
+		acpi_ut_subsystem_shutdown ();
+
+		/* TBD: [Restructure] Need some way to re-initialize without re-creating the semaphores! */
+
+		/*  Acpi_initialize (NULL); */
+		break;
+
+	case CMD_THREADS:
+		acpi_db_create_execution_threads (args[1], args[2], args[3]);
+		break;
+
+	case CMD_TREE:
+		acpi_db_display_calling_tree ();
+		break;
+
+	case CMD_UNLOAD:
+		acpi_db_unload_acpi_table (args[1], args[2]);
+		break;
+
+	case CMD_EXIT:
+	case CMD_QUIT:
+		if (op)
+		{
+			acpi_os_printf ("Method execution terminated\n");
+			return (AE_CTRL_TERMINATE);
+		}
+
+		if (!output_to_file)
+		{
+			acpi_dbg_level = DEBUG_DEFAULT;
+		}
+
+		/* Shutdown */
+
+		/* Acpi_ut_subsystem_shutdown (); */
+		acpi_db_close_debug_file ();
+
+		acpi_gbl_db_terminate_threads = TRUE;
+
+		return (AE_CTRL_TERMINATE);
+
+	case CMD_NOT_FOUND:
+		acpi_os_printf ("Unknown Command\n");
+		return (AE_CTRL_TRUE);
+	}
+
+
+	/* Add all commands that come here to the history buffer */
+
+	acpi_db_add_to_history (input_buffer);
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_execute_thread
+ *
+ * PARAMETERS:  Context         - Not used
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Debugger execute thread.  Waits for a command line, then
+ *              simply dispatches it.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_execute_thread (
+	void                    *context)
+{
+	ACPI_STATUS             status = AE_OK;
+
+
+	while (status != AE_CTRL_TERMINATE)
+	{
+		acpi_gbl_method_executing = FALSE;
+		acpi_gbl_step_to_next_call = FALSE;
+
+		acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_READY);
+		status = acpi_db_command_dispatch (line_buf, NULL, NULL);
+		acpi_ut_release_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_single_thread
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Debugger execute thread.  Waits for a command line, then
+ *              simply dispatches it.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_single_thread (
+	void)
+{
+	ACPI_STATUS             status = AE_OK;
+
+
+	acpi_gbl_method_executing = FALSE;
+	acpi_gbl_step_to_next_call = FALSE;
+
+	status = acpi_db_command_dispatch (line_buf, NULL, NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_user_commands
+ *
+ * PARAMETERS:  Prompt              - User prompt (depends on mode)
+ *              Op                  - Current executing parse op
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Command line execution for the AML debugger.  Commands are
+ *              matched and dispatched here.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_db_user_commands (
+	NATIVE_CHAR             prompt,
+	ACPI_PARSE_OBJECT       *op)
+{
+	ACPI_STATUS             status = AE_OK;
+
+
+	/* TBD: [Restructure] Need a separate command line buffer for step mode */
+
+	while (!acpi_gbl_db_terminate_threads)
+	{
+		/* Force output to console until a command is entered */
+
+		acpi_db_set_output_destination (DB_CONSOLE_OUTPUT);
+
+		/* Different prompt if method is executing */
+
+		if (!acpi_gbl_method_executing)
+		{
+			acpi_os_printf ("%1c ", DB_COMMAND_PROMPT);
+		}
+		else
+		{
+			acpi_os_printf ("%1c ", DB_EXECUTE_PROMPT);
+		}
+
+		/* Get the user input line */
+
+		acpi_os_get_line (line_buf);
+
+
+		/* Check for single or multithreaded debug */
+
+		if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED)
+		{
+			/*
+			 * Signal the debug thread that we have a command to execute,
+			 * and wait for the command to complete.
+			 */
+
+			acpi_ut_release_mutex (ACPI_MTX_DEBUG_CMD_READY);
+			acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
+		}
+
+		else
+		{
+			/* Just call to the command line interpreter */
+
+			acpi_db_single_thread ();
+		}
+	}
+
+
+	/*
+	 * Only this thread (the original thread) should actually terminate the subsystem,
+	 * because all the semaphores are deleted during termination
+	 */
+	acpi_terminate ();
+
+	return (status);
+}
+
+
+#endif  /* ENABLE_DEBUGGER */
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/debugger/dbstats.c linux/drivers/acpi/debugger/dbstats.c
--- v2.4.5/linux/drivers/acpi/debugger/dbstats.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/debugger/dbstats.c	Wed Jun 20 17:47:39 2001
@@ -0,0 +1,456 @@
+/*******************************************************************************
+ *
+ * Module Name: dbstats - Generation and display of ACPI table statistics
+ *              $Revision: 40 $
+ *
+ ******************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <acpi.h>
+#include <acdebug.h>
+#include <amlcode.h>
+#include <acparser.h>
+#include <acnamesp.h>
+
+#ifdef ENABLE_DEBUGGER
+
+#define _COMPONENT          ACPI_DEBUGGER
+	 MODULE_NAME         ("dbstats")
+
+/*
+ * Statistics subcommands
+ */
+ARGUMENT_INFO               acpi_db_stat_types [] =
+{ {"ALLOCATIONS"},
+	{"OBJECTS"},
+	{"MEMORY"},
+	{"MISC"},
+	{"TABLES"},
+	{"SIZES"},
+	{NULL}           /* Must be null terminated */
+};
+
+#define CMD_ALLOCATIONS     0
+#define CMD_OBJECTS         1
+#define CMD_MEMORY          2
+#define CMD_MISC            3
+#define CMD_TABLES          4
+#define CMD_SIZES           5
+
+
+/*
+ * Statistic globals
+ */
+u16                         acpi_gbl_obj_type_count[INTERNAL_TYPE_NODE_MAX+1];
+u16                         acpi_gbl_node_type_count[INTERNAL_TYPE_NODE_MAX+1];
+u16                         acpi_gbl_obj_type_count_misc;
+u16                         acpi_gbl_node_type_count_misc;
+u32                         num_nodes;
+u32                         num_objects;
+
+
+u32                         size_of_parse_tree;
+u32                         size_of_method_trees;
+u32                         size_of_node_entries;
+u32                         size_of_acpi_objects;
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_enumerate_object
+ *
+ * PARAMETERS:  Obj_desc            - Object to be counted
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Add this object to the global counts, by object type.
+ *              Recursively handles subobjects and packages.
+ *
+ *              [TBD] Restructure - remove recursion.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_enumerate_object (
+	ACPI_OPERAND_OBJECT     *obj_desc)
+{
+	u32                     type;
+	u32                     i;
+
+
+	if (!obj_desc)
+	{
+		return;
+	}
+
+
+	/* Enumerate this object first */
+
+	num_objects++;
+
+	type = obj_desc->common.type;
+	if (type > INTERNAL_TYPE_NODE_MAX)
+	{
+		acpi_gbl_obj_type_count_misc++;
+	}
+	else
+	{
+		acpi_gbl_obj_type_count [type]++;
+	}
+
+	/* Count the sub-objects */
+
+	switch (type)
+	{
+	case ACPI_TYPE_PACKAGE:
+		for (i = 0; i< obj_desc->package.count; i++)
+		{
+			acpi_db_enumerate_object (obj_desc->package.elements[i]);
+		}
+		break;
+
+	case ACPI_TYPE_DEVICE:
+		acpi_db_enumerate_object (obj_desc->device.sys_handler);
+		acpi_db_enumerate_object (obj_desc->device.drv_handler);
+		acpi_db_enumerate_object (obj_desc->device.addr_handler);
+		break;
+
+	case ACPI_TYPE_REGION:
+		acpi_db_enumerate_object (obj_desc->region.addr_handler);
+		break;
+
+	case ACPI_TYPE_POWER:
+		acpi_db_enumerate_object (obj_desc->power_resource.sys_handler);
+		acpi_db_enumerate_object (obj_desc->power_resource.drv_handler);
+		break;
+
+	case ACPI_TYPE_PROCESSOR:
+		acpi_db_enumerate_object (obj_desc->processor.sys_handler);
+		acpi_db_enumerate_object (obj_desc->processor.drv_handler);
+		acpi_db_enumerate_object (obj_desc->processor.addr_handler);
+		break;
+
+	case ACPI_TYPE_THERMAL:
+		acpi_db_enumerate_object (obj_desc->thermal_zone.sys_handler);
+		acpi_db_enumerate_object (obj_desc->thermal_zone.drv_handler);
+		acpi_db_enumerate_object (obj_desc->thermal_zone.addr_handler);
+		break;
+	}
+}
+
+
+#ifndef PARSER_ONLY
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_classify_one_object
+ *
+ * PARAMETERS:  Callback for Walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Enumerate both the object descriptor (including subobjects) and
+ *              the parent namespace node.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_db_classify_one_object (
+	ACPI_HANDLE             obj_handle,
+	u32                     nesting_level,
+	void                    *context,
+	void                    **return_value)
+{
+	ACPI_NAMESPACE_NODE     *node;
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	u32                     type;
+
+
+	num_nodes++;
+
+	node = (ACPI_NAMESPACE_NODE *) obj_handle;
+	obj_desc = ((ACPI_NAMESPACE_NODE *) obj_handle)->object;
+
+	acpi_db_enumerate_object (obj_desc);
+
+	type = node->type;
+	if (type > INTERNAL_TYPE_INVALID)
+	{
+		acpi_gbl_node_type_count_misc++;
+	}
+
+	else
+	{
+		acpi_gbl_node_type_count [type]++;
+	}
+
+	return AE_OK;
+
+
+	/* TBD: These need to be counted during the initial parsing phase */
+	/*
+	if (Acpi_ps_is_named_op (Op->Opcode))
+	{
+		Num_nodes++;
+	}
+
+	if (Is_method)
+	{
+		Num_method_elements++;
+	}
+
+	Num_grammar_elements++;
+	Op = Acpi_ps_get_depth_next (Root, Op);
+
+	Size_of_parse_tree          = (Num_grammar_elements - Num_method_elements) * (u32) sizeof (ACPI_PARSE_OBJECT);
+	Size_of_method_trees        = Num_method_elements * (u32) sizeof (ACPI_PARSE_OBJECT);
+	Size_of_node_entries        = Num_nodes * (u32) sizeof (ACPI_NAMESPACE_NODE);
+	Size_of_acpi_objects        = Num_nodes * (u32) sizeof (ACPI_OPERAND_OBJECT);
+
+	*/
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_count_namespace_objects
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Count and classify the entire namespace, including all
+ *              namespace nodes and attached objects.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_db_count_namespace_objects (
+	void)
+{
+	u32                     i;
+
+
+	num_nodes = 0;
+	num_objects = 0;
+
+	acpi_gbl_obj_type_count_misc = 0;
+	for (i = 0; i < INTERNAL_TYPE_INVALID; i++)
+	{
+		acpi_gbl_obj_type_count [i] = 0;
+		acpi_gbl_node_type_count [i] = 0;
+	}
+
+	acpi_ns_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+			   FALSE, acpi_db_classify_one_object, NULL, NULL);
+
+	return (AE_OK);
+}
+
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_display_statistics
+ *
+ * PARAMETERS:  Type_arg        - Subcommand
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Display various statistics
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_db_display_statistics (
+	NATIVE_CHAR             *type_arg)
+{
+	u32                     i;
+	u32                     type;
+
+
+	if (!acpi_gbl_DSDT)
+	{
+		acpi_os_printf ("*** Warning: There is no DSDT loaded\n");
+	}
+
+	if (!type_arg)
+	{
+		acpi_os_printf ("The following subcommands are available:\n  ALLOCATIONS, OBJECTS, MEMORY, MISC, SIZES, TABLES\n");
+		return (AE_OK);
+	}
+
+	STRUPR (type_arg);
+	type = acpi_db_match_argument (type_arg, acpi_db_stat_types);
+	if (type == (u32) -1)
+	{
+		acpi_os_printf ("Invalid or unsupported argument\n");
+		return (AE_OK);
+	}
+
+#ifndef PARSER_ONLY
+
+	acpi_db_count_namespace_objects ();
+#endif
+
+
+	switch (type)
+	{
+#ifndef PARSER_ONLY
+	case CMD_ALLOCATIONS:
+		acpi_ut_dump_allocation_info ();
+		break;
+#endif
+
+	case CMD_TABLES:
+
+		acpi_os_printf ("ACPI Table Information:\n\n");
+		if (acpi_gbl_DSDT)
+		{
+			acpi_os_printf ("DSDT Length:................% 7ld (%X)\n", acpi_gbl_DSDT->length, acpi_gbl_DSDT->length);
+		}
+		break;
+
+	case CMD_OBJECTS:
+
+		acpi_os_printf ("\n_objects defined in the current namespace:\n\n");
+
+		acpi_os_printf ("%16.16s % 10.10s % 10.10s\n", "ACPI_TYPE", "NODES", "OBJECTS");
+
+		for (i = 0; i < INTERNAL_TYPE_NODE_MAX; i++)
+		{
+			acpi_os_printf ("%16.16s % 10ld% 10ld\n", acpi_ut_get_type_name (i),
+				acpi_gbl_node_type_count [i], acpi_gbl_obj_type_count [i]);
+		}
+		acpi_os_printf ("%16.16s % 10ld% 10ld\n", "Misc/Unknown",
+			acpi_gbl_node_type_count_misc, acpi_gbl_obj_type_count_misc);
+
+		acpi_os_printf ("%16.16s % 10ld% 10ld\n", "TOTALS:",
+			num_nodes, num_objects);
+
+
+/*
+		Acpi_os_printf ("\n");
+
+		Acpi_os_printf ("ASL/AML Grammar Usage:\n\n");
+		Acpi_os_printf ("Elements Inside Methods:....% 7ld\n", Num_method_elements);
+		Acpi_os_printf ("Elements Outside Methods:...% 7ld\n", Num_grammar_elements - Num_method_elements);
+		Acpi_os_printf ("Total Grammar Elements:.....% 7ld\n", Num_grammar_elements);
+*/
+		break;
+
+	case CMD_MEMORY:
+
+		acpi_os_printf ("\n_dynamic Memory Estimates:\n\n");
+		acpi_os_printf ("Parse Tree without Methods:.% 7ld\n", size_of_parse_tree);
+		acpi_os_printf ("Control Method Parse Trees:.% 7ld (If parsed simultaneously)\n", size_of_method_trees);
+		acpi_os_printf ("Namespace Nodes:............% 7ld (%d nodes)\n", sizeof (ACPI_NAMESPACE_NODE) * num_nodes, num_nodes);
+		acpi_os_printf ("Named Internal Objects......% 7ld\n", size_of_acpi_objects);
+		acpi_os_printf ("State Cache size............% 7ld\n", acpi_gbl_generic_state_cache_depth * sizeof (ACPI_GENERIC_STATE));
+		acpi_os_printf ("Parse Cache size............% 7ld\n", acpi_gbl_parse_cache_depth * sizeof (ACPI_PARSE_OBJECT));
+		acpi_os_printf ("Object Cache size...........% 7ld\n", acpi_gbl_object_cache_depth * sizeof (ACPI_OPERAND_OBJECT));
+		acpi_os_printf ("Walk_state Cache size........% 7ld\n", acpi_gbl_walk_state_cache_depth * sizeof (ACPI_WALK_STATE));
+
+		acpi_os_printf ("\n");
+
+		acpi_os_printf ("Cache Statistics:\n\n");
+		acpi_os_printf ("State Cache requests........% 7ld\n", acpi_gbl_state_cache_requests);
+		acpi_os_printf ("State Cache hits............% 7ld\n", acpi_gbl_state_cache_hits);
+		acpi_os_printf ("State Cache depth...........% 7ld (%d remaining entries)\n", acpi_gbl_generic_state_cache_depth,
+				  MAX_STATE_CACHE_DEPTH - acpi_gbl_generic_state_cache_depth);
+		acpi_os_printf ("Parse Cache requests........% 7ld\n", acpi_gbl_parse_cache_requests);
+		acpi_os_printf ("Parse Cache hits............% 7ld\n", acpi_gbl_parse_cache_hits);
+		acpi_os_printf ("Parse Cache depth...........% 7ld (%d remaining entries)\n", acpi_gbl_parse_cache_depth,
+				  MAX_PARSE_CACHE_DEPTH - acpi_gbl_parse_cache_depth);
+		acpi_os_printf ("Ext Parse Cache requests....% 7ld\n", acpi_gbl_ext_parse_cache_requests);
+		acpi_os_printf ("Ext Parse Cache hits........% 7ld\n", acpi_gbl_ext_parse_cache_hits);
+		acpi_os_printf ("Ext Parse Cache depth.......% 7ld (%d remaining entries)\n", acpi_gbl_ext_parse_cache_depth,
+				  MAX_EXTPARSE_CACHE_DEPTH - acpi_gbl_ext_parse_cache_depth);
+		acpi_os_printf ("Object Cache requests.......% 7ld\n", acpi_gbl_object_cache_requests);
+		acpi_os_printf ("Object Cache hits...........% 7ld\n", acpi_gbl_object_cache_hits);
+		acpi_os_printf ("Object Cache depth..........% 7ld (%d remaining entries)\n", acpi_gbl_object_cache_depth,
+				  MAX_OBJECT_CACHE_DEPTH - acpi_gbl_object_cache_depth);
+		acpi_os_printf ("Walk_state Cache requests....% 7ld\n", acpi_gbl_walk_state_cache_requests);
+		acpi_os_printf ("Walk_state Cache hits........% 7ld\n", acpi_gbl_walk_state_cache_hits);
+		acpi_os_printf ("Walk_state Cache depth.......% 7ld (%d remaining entries)\n", acpi_gbl_walk_state_cache_depth,
+				  MAX_WALK_CACHE_DEPTH - acpi_gbl_walk_state_cache_depth);
+		break;
+
+	case CMD_MISC:
+
+		acpi_os_printf ("\n_miscellaneous Statistics:\n\n");
+		acpi_os_printf ("Calls to Acpi_ps_find:.. ........% 7ld\n", acpi_gbl_ps_find_count);
+		acpi_os_printf ("Calls to Acpi_ns_lookup:..........% 7ld\n", acpi_gbl_ns_lookup_count);
+
+		acpi_os_printf ("\n");
+
+		acpi_os_printf ("Mutex usage:\n\n");
+		for (i = 0; i < NUM_MTX; i++)
+		{
+			acpi_os_printf ("%-28s:     % 7ld\n", acpi_ut_get_mutex_name (i), acpi_gbl_acpi_mutex_info[i].use_count);
+		}
+		break;
+
+
+	case CMD_SIZES:
+
+		acpi_os_printf ("\n_internal object sizes:\n\n");
+
+		acpi_os_printf ("Common         %3d\n", sizeof (ACPI_OBJECT_COMMON));
+		acpi_os_printf ("Number         %3d\n", sizeof (ACPI_OBJECT_INTEGER));
+		acpi_os_printf ("String         %3d\n", sizeof (ACPI_OBJECT_STRING));
+		acpi_os_printf ("Buffer         %3d\n", sizeof (ACPI_OBJECT_BUFFER));
+		acpi_os_printf ("Package        %3d\n", sizeof (ACPI_OBJECT_PACKAGE));
+		acpi_os_printf ("Buffer_field   %3d\n", sizeof (ACPI_OBJECT_BUFFER_FIELD));
+		acpi_os_printf ("Device         %3d\n", sizeof (ACPI_OBJECT_DEVICE));
+		acpi_os_printf ("Event          %3d\n", sizeof (ACPI_OBJECT_EVENT));
+		acpi_os_printf ("Method         %3d\n", sizeof (ACPI_OBJECT_METHOD));
+		acpi_os_printf ("Mutex          %3d\n", sizeof (ACPI_OBJECT_MUTEX));
+		acpi_os_printf ("Region         %3d\n", sizeof (ACPI_OBJECT_REGION));
+		acpi_os_printf ("Power_resource %3d\n", sizeof (ACPI_OBJECT_POWER_RESOURCE));
+		acpi_os_printf ("Processor      %3d\n", sizeof (ACPI_OBJECT_PROCESSOR));
+		acpi_os_printf ("Thermal_zone   %3d\n", sizeof (ACPI_OBJECT_THERMAL_ZONE));
+		acpi_os_printf ("Region_field   %3d\n", sizeof (ACPI_OBJECT_REGION_FIELD));
+		acpi_os_printf ("Bank_field     %3d\n", sizeof (ACPI_OBJECT_BANK_FIELD));
+		acpi_os_printf ("Index_field    %3d\n", sizeof (ACPI_OBJECT_INDEX_FIELD));
+		acpi_os_printf ("Reference      %3d\n", sizeof (ACPI_OBJECT_REFERENCE));
+		acpi_os_printf ("Notify_handler %3d\n", sizeof (ACPI_OBJECT_NOTIFY_HANDLER));
+		acpi_os_printf ("Addr_handler   %3d\n", sizeof (ACPI_OBJECT_ADDR_HANDLER));
+		acpi_os_printf ("Extra          %3d\n", sizeof (ACPI_OBJECT_EXTRA));
+
+		acpi_os_printf ("\n");
+
+		acpi_os_printf ("Parse_object   %3d\n", sizeof (ACPI_PARSE_OBJECT));
+		acpi_os_printf ("Parse2_object  %3d\n", sizeof (ACPI_PARSE2_OBJECT));
+		acpi_os_printf ("Operand_object %3d\n", sizeof (ACPI_OPERAND_OBJECT));
+		acpi_os_printf ("Namespace_node %3d\n", sizeof (ACPI_NAMESPACE_NODE));
+
+		break;
+
+	}
+
+	acpi_os_printf ("\n");
+	return (AE_OK);
+}
+
+
+#endif /* ENABLE_DEBUGGER  */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/debugger/dbutils.c linux/drivers/acpi/debugger/dbutils.c
--- v2.4.5/linux/drivers/acpi/debugger/dbutils.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/debugger/dbutils.c	Wed Jun 20 17:47:39 2001
@@ -0,0 +1,354 @@
+/*******************************************************************************
+ *
+ * Module Name: dbutils - AML debugger utilities
+ *              $Revision: 37 $
+ *
+ ******************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+#include "acparser.h"
+#include "acevents.h"
+#include "acinterp.h"
+#include "acdebug.h"
+#include "acdispat.h"
+
+
+#ifdef ENABLE_DEBUGGER
+
+#define _COMPONENT          ACPI_DEBUGGER
+	 MODULE_NAME         ("dbutils")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_set_output_destination
+ *
+ * PARAMETERS:  Output_flags        - Current flags word
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Set the current destination for debugger output.  Alos sets
+ *              the debug output level accordingly.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_set_output_destination (
+	u32                     output_flags)
+{
+
+	acpi_gbl_db_output_flags = (u8) output_flags;
+
+	if (output_flags & DB_REDIRECTABLE_OUTPUT) {
+		if (output_to_file) {
+			acpi_dbg_level = acpi_gbl_db_debug_level;
+		}
+	}
+	else {
+		acpi_dbg_level = acpi_gbl_db_console_debug_level;
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_dump_buffer
+ *
+ * PARAMETERS:  Address             - Pointer to the buffer
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print a portion of a buffer
+ *
+ ******************************************************************************/
+
+void
+acpi_db_dump_buffer (
+	u32                     address)
+{
+
+	acpi_os_printf ("\n_location %X:\n", address);
+
+	acpi_dbg_level |= TRACE_TABLES;
+	acpi_ut_dump_buffer ((u8 *) address, 64, DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_dump_object
+ *
+ * PARAMETERS:  Obj_desc        - External ACPI object to dump
+ *              Level           - Nesting level.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Dump the contents of an ACPI external object
+ *
+ ******************************************************************************/
+
+void
+acpi_db_dump_object (
+	ACPI_OBJECT             *obj_desc,
+	u32                     level)
+{
+	u32                     i;
+
+
+	if (!obj_desc) {
+		acpi_os_printf ("[Null Object]\n");
+		return;
+	}
+
+	for (i = 0; i < level; i++) {
+		acpi_os_printf (" ");
+	}
+
+	switch (obj_desc->type) {
+	case ACPI_TYPE_ANY:
+
+		acpi_os_printf ("[Object Reference] Value: %p\n", obj_desc->reference.handle);
+		break;
+
+
+	case ACPI_TYPE_INTEGER:
+		acpi_os_printf ("[Number] Value: %ld (%lX)\n", obj_desc->integer.value, obj_desc->integer.value);
+		break;
+
+
+	case ACPI_TYPE_STRING:
+
+		acpi_os_printf ("[String] Value: ");
+		for (i = 0; i < obj_desc->string.length; i++) {
+			acpi_os_printf ("%c", obj_desc->string.pointer[i]);
+		}
+		acpi_os_printf ("\n");
+		break;
+
+
+	case ACPI_TYPE_BUFFER:
+
+		acpi_os_printf ("[Buffer] Value: ");
+		acpi_ut_dump_buffer ((u8 *) obj_desc->buffer.pointer, obj_desc->buffer.length, DB_DWORD_DISPLAY, _COMPONENT);
+		break;
+
+
+	case ACPI_TYPE_PACKAGE:
+
+		acpi_os_printf ("[Package] Contains %d Elements: \n", obj_desc->package.count);
+
+		for (i = 0; i < obj_desc->package.count; i++) {
+			acpi_db_dump_object (&obj_desc->package.elements[i], level+1);
+		}
+		break;
+
+
+	case INTERNAL_TYPE_REFERENCE:
+		acpi_os_printf ("[Object Reference] Value: %p\n", obj_desc->reference.handle);
+		break;
+
+	case ACPI_TYPE_PROCESSOR:
+		acpi_os_printf ("[Processor]\n");
+		break;
+
+	case ACPI_TYPE_POWER:
+		acpi_os_printf ("[Power Resource]\n");
+		break;
+
+	default:
+
+		acpi_os_printf ("[Unknown Type] %X \n", obj_desc->type);
+		break;
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_prep_namestring
+ *
+ * PARAMETERS:  Name            - String to prepare
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Translate all forward slashes and dots to backslashes.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_prep_namestring (
+	NATIVE_CHAR             *name)
+{
+
+
+	if (!name) {
+		return;
+	}
+
+	STRUPR (name);
+
+	/* Convert a leading forward slash to a backslash */
+
+	if (*name == '/') {
+		*name = '\\';
+	}
+
+	/* Ignore a leading backslash, this is the root prefix */
+
+	if (*name == '\\') {
+		name++;
+	}
+
+	/* Convert all slash path separators to dots */
+
+	while (*name) {
+		if ((*name == '/') ||
+			(*name == '\\')) {
+			*name = '.';
+		}
+
+		name++;
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_second_pass_parse
+ *
+ * PARAMETERS:  Root            - Root of the parse tree
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Second pass parse of the ACPI tables.  We need to wait until
+ *              second pass to parse the control methods
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_db_second_pass_parse (
+	ACPI_PARSE_OBJECT       *root)
+{
+	ACPI_PARSE_OBJECT       *op = root;
+	ACPI_PARSE2_OBJECT      *method;
+	ACPI_PARSE_OBJECT       *search_op;
+	ACPI_PARSE_OBJECT       *start_op;
+	ACPI_STATUS             status = AE_OK;
+	u32                     base_aml_offset;
+
+
+	acpi_os_printf ("Pass two parse ....\n");
+
+	while (op) {
+		if (op->opcode == AML_METHOD_OP) {
+			method = (ACPI_PARSE2_OBJECT *) op;
+			status = acpi_ps_parse_aml (op, method->data, method->length, 0,
+					 NULL, NULL, NULL, acpi_ds_load1_begin_op, acpi_ds_load1_end_op);
+
+
+			base_aml_offset = (method->value.arg)->aml_offset + 1;
+			start_op = (method->value.arg)->next;
+			search_op = start_op;
+
+			while (search_op) {
+				search_op->aml_offset += base_aml_offset;
+				search_op = acpi_ps_get_depth_next (start_op, search_op);
+			}
+
+		}
+
+		if (op->opcode == AML_REGION_OP) {
+			/* TBD: [Investigate] this isn't quite the right thing to do! */
+			/*
+			 *
+			 * Method = (ACPI_DEFERRED_OP *) Op;
+			 * Status = Acpi_ps_parse_aml (Op, Method->Body, Method->Body_length);
+			 */
+		}
+
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+
+		op = acpi_ps_get_depth_next (root, op);
+	}
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_local_ns_lookup
+ *
+ * PARAMETERS:  Name            - Name to lookup
+ *
+ * RETURN:      Pointer to a namespace node
+ *
+ * DESCRIPTION: Lookup a name in the ACPI namespace
+ *
+ ******************************************************************************/
+
+ACPI_NAMESPACE_NODE *
+acpi_db_local_ns_lookup (
+	NATIVE_CHAR             *name)
+{
+	NATIVE_CHAR             *internal_path;
+	ACPI_STATUS             status;
+	ACPI_NAMESPACE_NODE     *node = NULL;
+
+
+	acpi_db_prep_namestring (name);
+
+	/* Build an internal namestring */
+
+	status = acpi_ns_internalize_name (name, &internal_path);
+	if (ACPI_FAILURE (status)) {
+		acpi_os_printf ("Invalid namestring: %s\n", name);
+		return (NULL);
+	}
+
+	/* Lookup the name */
+
+	/* TBD: [Investigate] what scope do we use? */
+	/* Use the root scope for the start of the search */
+
+	status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY, IMODE_EXECUTE,
+			   NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE, NULL, &node);
+
+	if (ACPI_FAILURE (status)) {
+		acpi_os_printf ("Could not locate name: %s %s\n", name, acpi_ut_format_exception (status));
+	}
+
+
+	acpi_ut_free (internal_path);
+
+	return (node);
+}
+
+
+#endif /* ENABLE_DEBUGGER */
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/debugger/dbxface.c linux/drivers/acpi/debugger/dbxface.c
--- v2.4.5/linux/drivers/acpi/debugger/dbxface.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/debugger/dbxface.c	Wed Jun 20 17:47:39 2001
@@ -0,0 +1,317 @@
+/*******************************************************************************
+ *
+ * Module Name: dbxface - AML Debugger external interfaces
+ *              $Revision: 37 $
+ *
+ ******************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+#include "acparser.h"
+#include "acevents.h"
+#include "acinterp.h"
+#include "acdebug.h"
+
+
+#ifdef ENABLE_DEBUGGER
+
+#define _COMPONENT          ACPI_DEBUGGER
+	 MODULE_NAME         ("dbxface")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_single_step
+ *
+ * PARAMETERS:  Walk_state      - Current walk
+ *              Op              - Current executing op
+ *              Op_type         - Type of the current AML Opcode
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Called just before execution of an AML opcode.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_db_single_step (
+	ACPI_WALK_STATE         *walk_state,
+	ACPI_PARSE_OBJECT       *op,
+	u8                      op_type)
+{
+	ACPI_PARSE_OBJECT       *next;
+	ACPI_STATUS             status = AE_OK;
+	u32                     original_debug_level;
+	ACPI_PARSE_OBJECT       *display_op;
+
+
+	/* Is there a breakpoint set? */
+
+	if (walk_state->method_breakpoint) {
+		/* Check if the breakpoint has been reached or passed */
+
+		if (walk_state->method_breakpoint <= op->aml_offset) {
+			/* Hit the breakpoint, resume single step, reset breakpoint */
+
+			acpi_os_printf ("***Break*** at AML offset %X\n", op->aml_offset);
+			acpi_gbl_cm_single_step = TRUE;
+			acpi_gbl_step_to_next_call = FALSE;
+			walk_state->method_breakpoint = 0;
+		}
+	}
+
+
+	/*
+	 * Check if this is an opcode that we are interested in --
+	 * namely, opcodes that have arguments
+	 */
+
+	if (op->opcode == AML_INT_NAMEDFIELD_OP) {
+		return (AE_OK);
+	}
+
+	switch (op_type) {
+	case OPTYPE_UNDEFINED:
+	case OPTYPE_CONSTANT:           /* argument type only */
+	case OPTYPE_LITERAL:            /* argument type only */
+	case OPTYPE_DATA_TERM:          /* argument type only */
+	case OPTYPE_LOCAL_VARIABLE:     /* argument type only */
+	case OPTYPE_METHOD_ARGUMENT:    /* argument type only */
+		return (AE_OK);
+		break;
+
+	case OPTYPE_NAMED_OBJECT:
+		switch (op->opcode) {
+		case AML_INT_NAMEPATH_OP:
+			return (AE_OK);
+			break;
+		}
+	}
+
+
+	/*
+	 * Under certain debug conditions, display this opcode and its operands
+	 */
+
+	if ((output_to_file)                    ||
+		(acpi_gbl_cm_single_step)           ||
+		(acpi_dbg_level & TRACE_PARSE)) {
+		if ((output_to_file)                ||
+			(acpi_dbg_level & TRACE_PARSE)) {
+			acpi_os_printf ("\n[Aml_debug] Next AML Opcode to execute:\n");
+		}
+
+		/*
+		 * Display this op (and only this op - zero out the NEXT field temporarily,
+		 * and disable parser trace output for the duration of the display because
+		 * we don't want the extraneous debug output)
+		 */
+
+		original_debug_level = acpi_dbg_level;
+		acpi_dbg_level &= ~(TRACE_PARSE | TRACE_FUNCTIONS);
+		next = op->next;
+		op->next = NULL;
+
+
+		display_op = op;
+		if (op->parent) {
+			if ((op->parent->opcode == AML_IF_OP) ||
+				(op->parent->opcode == AML_WHILE_OP)) {
+				display_op = op->parent;
+			}
+		}
+
+		/* Now we can display it */
+
+		acpi_db_display_op (walk_state, display_op, ACPI_UINT32_MAX);
+
+		if ((op->opcode == AML_IF_OP) ||
+			(op->opcode == AML_WHILE_OP)) {
+			if (walk_state->control_state->common.value) {
+				acpi_os_printf ("Predicate was TRUE, executed block\n");
+			}
+			else {
+				acpi_os_printf ("Predicate is FALSE, skipping block\n");
+			}
+		}
+
+		else if (op->opcode == AML_ELSE_OP) {
+			/* TBD */
+		}
+
+
+		/* Restore everything */
+
+		op->next = next;
+		acpi_os_printf ("\n");
+		acpi_dbg_level = original_debug_level;
+   }
+
+
+	/* If we are not single stepping, just continue executing the method */
+
+	if (!acpi_gbl_cm_single_step) {
+		return (AE_OK);
+	}
+
+
+	/*
+	 * If we are executing a step-to-call command,
+	 * Check if this is a method call.
+	 */
+
+	if (acpi_gbl_step_to_next_call) {
+		if (op->opcode != AML_INT_METHODCALL_OP) {
+			/* Not a method call, just keep executing */
+
+			return (AE_OK);
+		}
+
+		/* Found a method call, stop executing */
+
+		acpi_gbl_step_to_next_call = FALSE;
+	}
+
+
+	/*
+	 * If the next opcode is a method call, we will "step over" it
+	 * by default.
+	 */
+
+	if (op->opcode == AML_INT_METHODCALL_OP) {
+		acpi_gbl_cm_single_step = FALSE; /* No more single step while executing called method */
+
+		/* Set the breakpoint on the call, it will stop execution as soon as we return */
+
+		/* TBD: [Future] don't kill the user breakpoint! */
+
+		walk_state->method_breakpoint = /* Op->Aml_offset + */ 1; /* Must be non-zero! */
+	}
+
+
+	/* TBD: [Investigate] what are the namespace locking issues here */
+
+	/* Acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); */
+
+	/* Go into the command loop and await next user command */
+
+	acpi_gbl_method_executing = TRUE;
+	status = AE_CTRL_TRUE;
+	while (status == AE_CTRL_TRUE) {
+		if (acpi_gbl_debugger_configuration == DEBUGGER_MULTI_THREADED) {
+			/* Handshake with the front-end that gets user command lines */
+
+			acpi_ut_release_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
+			acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_READY);
+		}
+
+		else {
+			/* Single threaded, we must get a command line ourselves */
+
+			/* Force output to console until a command is entered */
+
+			acpi_db_set_output_destination (DB_CONSOLE_OUTPUT);
+
+			/* Different prompt if method is executing */
+
+			if (!acpi_gbl_method_executing) {
+				acpi_os_printf ("%1c ", DB_COMMAND_PROMPT);
+			}
+			else {
+				acpi_os_printf ("%1c ", DB_EXECUTE_PROMPT);
+			}
+
+			/* Get the user input line */
+
+			acpi_os_get_line (line_buf);
+		}
+
+		status = acpi_db_command_dispatch (line_buf, walk_state, op);
+	}
+
+	/* Acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); */
+
+
+	/* User commands complete, continue execution of the interrupted method */
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_initialize
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Init and start debugger
+ *
+ ******************************************************************************/
+
+int
+acpi_db_initialize (void)
+{
+
+
+	/* Init globals */
+
+	buffer = acpi_os_allocate (BUFFER_SIZE);
+
+	/* Initial scope is the root */
+
+	scope_buf [0] = '\\';
+	scope_buf [1] = 0;
+
+
+	/*
+	 * If configured for multi-thread support, the debug executor runs in
+	 * a separate thread so that the front end can be in another address
+	 * space, environment, or even another machine.
+	 */
+
+	if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) {
+		/* These were created with one unit, grab it */
+
+		acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
+		acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_READY);
+
+		/* Create the debug execution thread to execute commands */
+
+		acpi_os_queue_for_execution (0, acpi_db_execute_thread, NULL);
+	}
+
+	if (!opt_verbose) {
+		INDENT_STRING = "    ";
+		opt_disasm = TRUE;
+		opt_stats = FALSE;
+	}
+
+
+	return (0);
+}
+
+
+#endif /* ENABLE_DEBUGGER */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/dispatcher/Makefile linux/drivers/acpi/dispatcher/Makefile
--- v2.4.5/linux/drivers/acpi/dispatcher/Makefile	Fri Dec 29 14:07:21 2000
+++ linux/drivers/acpi/dispatcher/Makefile	Wed Jun 20 17:47:39 2001
@@ -1,16 +1,12 @@
 #
 # Makefile for all Linux ACPI interpreter subdirectories
+# EXCEPT for the ospm directory
 #
 
-O_TARGET := ../$(shell basename `pwd`).o
+O_TARGET := $(notdir $(CURDIR)).o
 
 obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c))
 
-EXTRA_CFLAGS += -I../include
-
 EXTRA_CFLAGS += $(ACPI_CFLAGS)
 
 include $(TOPDIR)/Rules.make
-
-clean:
-	$(RM) *.o 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/dispatcher/dsfield.c linux/drivers/acpi/dispatcher/dsfield.c
--- v2.4.5/linux/drivers/acpi/dispatcher/dsfield.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/dispatcher/dsfield.c	Wed Jun 20 17:47:39 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: dsfield - Dispatcher field routines
- *              $Revision: 31 $
+ *              $Revision: 41 $
  *
  *****************************************************************************/
 
@@ -31,7 +31,7 @@
 #include "acnamesp.h"
 
 
-#define _COMPONENT          DISPATCHER
+#define _COMPONENT          ACPI_DISPATCHER
 	 MODULE_NAME         ("dsfield")
 
 
@@ -51,7 +51,8 @@
  * FUNCTION:    Acpi_ds_create_field
  *
  * PARAMETERS:  Op              - Op containing the Field definition and args
- *              Region_node - Object for the containing Operation Region
+ *              Region_node     - Object for the containing Operation Region
+ *  `           Walk_state      - Current method state
  *
  * RETURN:      Status
  *
@@ -69,7 +70,6 @@
 	ACPI_PARSE_OBJECT       *arg;
 	ACPI_NAMESPACE_NODE     *node;
 	u8                      field_flags;
-	u8                      access_attribute = 0;
 	u32                     field_bit_position = 0;
 
 
@@ -78,10 +78,8 @@
 	arg = op->value.arg;
 	if (!region_node) {
 		status = acpi_ns_lookup (walk_state->scope_info, arg->value.name,
-				 ACPI_TYPE_REGION, IMODE_EXECUTE,
-				 NS_SEARCH_PARENT, walk_state,
-				 &region_node);
-
+				  ACPI_TYPE_REGION, IMODE_EXECUTE,
+				  NS_SEARCH_PARENT, walk_state, &region_node);
 		if (ACPI_FAILURE (status)) {
 			return (status);
 		}
@@ -96,37 +94,31 @@
 
 	arg = arg->next;
 	while (arg) {
-		switch (arg->opcode)
-		{
-		case AML_RESERVEDFIELD_OP:
+		switch (arg->opcode) {
+		case AML_INT_RESERVEDFIELD_OP:
 
 			field_bit_position += arg->value.size;
 			break;
 
 
-		case AML_ACCESSFIELD_OP:
+		case AML_INT_ACCESSFIELD_OP:
 
 			/*
 			 * Get a new Access_type and Access_attribute for all
 			 * entries (until end or another Access_as keyword)
 			 */
-
-			access_attribute = (u8) arg->value.integer;
-			field_flags     = (u8)
-					  ((field_flags & FIELD_ACCESS_TYPE_MASK) ||
-					  ((u8) (arg->value.integer >> 8)));
+			field_flags = (u8) ((field_flags & FIELD_ACCESS_TYPE_MASK) ||
+					   ((u8) (arg->value.integer >> 8)));
 			break;
 
 
-		case AML_NAMEDFIELD_OP:
+		case AML_INT_NAMEDFIELD_OP:
 
 			status = acpi_ns_lookup (walk_state->scope_info,
 					  (NATIVE_CHAR *) &((ACPI_PARSE2_OBJECT *)arg)->name,
-					  INTERNAL_TYPE_DEF_FIELD,
-					  IMODE_LOAD_PASS1,
+					  INTERNAL_TYPE_REGION_FIELD, IMODE_LOAD_PASS1,
 					  NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
 					  NULL, &node);
-
 			if (ACPI_FAILURE (status)) {
 				return (status);
 			}
@@ -136,9 +128,8 @@
 			 * the object stack
 			 */
 
-			status = acpi_aml_prep_def_field_value (node, region_node, field_flags,
-					  access_attribute, field_bit_position, arg->value.size);
-
+			status = acpi_ex_prep_region_field_value (node, region_node, field_flags,
+					  field_bit_position, arg->value.size);
 			if (ACPI_FAILURE (status)) {
 				return (status);
 			}
@@ -161,7 +152,8 @@
  * FUNCTION:    Acpi_ds_create_bank_field
  *
  * PARAMETERS:  Op              - Op containing the Field definition and args
- *              Region_node - Object for the containing Operation Region
+ *              Region_node     - Object for the containing Operation Region
+ *  `           Walk_state      - Current method state
  *
  * RETURN:      Status
  *
@@ -181,7 +173,6 @@
 	ACPI_NAMESPACE_NODE     *node;
 	u32                     bank_value;
 	u8                      field_flags;
-	u8                      access_attribute = 0;
 	u32                     field_bit_position = 0;
 
 
@@ -190,10 +181,8 @@
 	arg = op->value.arg;
 	if (!region_node) {
 		status = acpi_ns_lookup (walk_state->scope_info, arg->value.name,
-				 ACPI_TYPE_REGION, IMODE_EXECUTE,
-				 NS_SEARCH_PARENT, walk_state,
-				 &region_node);
-
+				  ACPI_TYPE_REGION, IMODE_EXECUTE,
+				  NS_SEARCH_PARENT, walk_state, &region_node);
 		if (ACPI_FAILURE (status)) {
 			return (status);
 		}
@@ -204,11 +193,9 @@
 	arg = arg->next;
 
 	status = acpi_ns_lookup (walk_state->scope_info, arg->value.string,
-			 INTERNAL_TYPE_BANK_FIELD_DEFN,
-			 IMODE_LOAD_PASS1,
-			 NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
-			 NULL, &register_node);
-
+			  INTERNAL_TYPE_BANK_FIELD_DEFN, IMODE_LOAD_PASS1,
+			  NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
+			  NULL, &register_node);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
@@ -228,37 +215,31 @@
 
 	arg = arg->next;
 	while (arg) {
-		switch (arg->opcode)
-		{
-		case AML_RESERVEDFIELD_OP:
+		switch (arg->opcode) {
+		case AML_INT_RESERVEDFIELD_OP:
 
 			field_bit_position += arg->value.size;
 			break;
 
 
-		case AML_ACCESSFIELD_OP:
+		case AML_INT_ACCESSFIELD_OP:
 
 			/*
 			 * Get a new Access_type and Access_attribute for
 			 * all entries (until end or another Access_as keyword)
 			 */
-
-			access_attribute = (u8) arg->value.integer;
-			field_flags     = (u8)
-					  ((field_flags & FIELD_ACCESS_TYPE_MASK) ||
-					  ((u8) (arg->value.integer >> 8)));
+			field_flags = (u8) ((field_flags & FIELD_ACCESS_TYPE_MASK) ||
+					 ((u8) (arg->value.integer >> 8)));
 			break;
 
 
-		case AML_NAMEDFIELD_OP:
+		case AML_INT_NAMEDFIELD_OP:
 
 			status = acpi_ns_lookup (walk_state->scope_info,
 					  (NATIVE_CHAR *) &((ACPI_PARSE2_OBJECT *)arg)->name,
-					  INTERNAL_TYPE_DEF_FIELD,
-					  IMODE_LOAD_PASS1,
+					  INTERNAL_TYPE_REGION_FIELD, IMODE_LOAD_PASS1,
 					  NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
 					  NULL, &node);
-
 			if (ACPI_FAILURE (status)) {
 				return (status);
 			}
@@ -268,10 +249,9 @@
 			 * the object stack
 			 */
 
-			status = acpi_aml_prep_bank_field_value (node, region_node, register_node,
-					  bank_value, field_flags, access_attribute,
-					  field_bit_position, arg->value.size);
-
+			status = acpi_ex_prep_bank_field_value (node, region_node, register_node,
+					  bank_value, field_flags, field_bit_position,
+					  arg->value.size);
 			if (ACPI_FAILURE (status)) {
 				return (status);
 			}
@@ -295,7 +275,8 @@
  * FUNCTION:    Acpi_ds_create_index_field
  *
  * PARAMETERS:  Op              - Op containing the Field definition and args
- *              Region_node - Object for the containing Operation Region
+ *              Region_node     - Object for the containing Operation Region
+ *  `           Walk_state      - Current method state
  *
  * RETURN:      Status
  *
@@ -306,7 +287,7 @@
 ACPI_STATUS
 acpi_ds_create_index_field (
 	ACPI_PARSE_OBJECT       *op,
-	ACPI_HANDLE             region_node,
+	ACPI_NAMESPACE_NODE     *region_node,
 	ACPI_WALK_STATE         *walk_state)
 {
 	ACPI_STATUS             status;
@@ -315,7 +296,6 @@
 	ACPI_NAMESPACE_NODE     *index_register_node;
 	ACPI_NAMESPACE_NODE     *data_register_node;
 	u8                      field_flags;
-	u8                      access_attribute = 0;
 	u32                     field_bit_position = 0;
 
 
@@ -324,10 +304,9 @@
 	/* First arg is the name of the Index register */
 
 	status = acpi_ns_lookup (walk_state->scope_info, arg->value.string,
-			 ACPI_TYPE_ANY, IMODE_LOAD_PASS1,
-			 NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
-			 NULL, &index_register_node);
-
+			  ACPI_TYPE_ANY, IMODE_LOAD_PASS1,
+			  NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
+			  NULL, &index_register_node);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
@@ -337,11 +316,9 @@
 	arg = arg->next;
 
 	status = acpi_ns_lookup (walk_state->scope_info, arg->value.string,
-			 INTERNAL_TYPE_INDEX_FIELD_DEFN,
-			 IMODE_LOAD_PASS1,
-			 NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
-			 NULL, &data_register_node);
-
+			  INTERNAL_TYPE_INDEX_FIELD_DEFN, IMODE_LOAD_PASS1,
+			  NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
+			  NULL, &data_register_node);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
@@ -357,37 +334,31 @@
 
 	arg = arg->next;
 	while (arg) {
-		switch (arg->opcode)
-		{
-		case AML_RESERVEDFIELD_OP:
+		switch (arg->opcode) {
+		case AML_INT_RESERVEDFIELD_OP:
 
 			field_bit_position += arg->value.size;
 			break;
 
 
-		case AML_ACCESSFIELD_OP:
+		case AML_INT_ACCESSFIELD_OP:
 
 			/*
 			 * Get a new Access_type and Access_attribute for all
 			 * entries (until end or another Access_as keyword)
 			 */
-
-			access_attribute = (u8) arg->value.integer;
-			field_flags     = (u8)
-					   ((field_flags & FIELD_ACCESS_TYPE_MASK) ||
-					   ((u8) (arg->value.integer >> 8)));
+			field_flags = (u8) ((field_flags & FIELD_ACCESS_TYPE_MASK) ||
+					 ((u8) (arg->value.integer >> 8)));
 			break;
 
 
-		case AML_NAMEDFIELD_OP:
+		case AML_INT_NAMEDFIELD_OP:
 
 			status = acpi_ns_lookup (walk_state->scope_info,
-					 (NATIVE_CHAR *) &((ACPI_PARSE2_OBJECT *)arg)->name,
-					 INTERNAL_TYPE_INDEX_FIELD,
-					 IMODE_LOAD_PASS1,
-					 NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
-					 NULL, &node);
-
+					  (NATIVE_CHAR *) &((ACPI_PARSE2_OBJECT *)arg)->name,
+					  INTERNAL_TYPE_INDEX_FIELD, IMODE_LOAD_PASS1,
+					  NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
+					  NULL, &node);
 			if (ACPI_FAILURE (status)) {
 				return (status);
 			}
@@ -397,10 +368,9 @@
 			 * the object stack
 			 */
 
-			status = acpi_aml_prep_index_field_value (node, index_register_node, data_register_node,
-					  field_flags, access_attribute,
+			status = acpi_ex_prep_index_field_value (node, index_register_node,
+					  data_register_node, field_flags,
 					  field_bit_position, arg->value.size);
-
 			if (ACPI_FAILURE (status)) {
 				return (status);
 			}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/dispatcher/dsmethod.c linux/drivers/acpi/dispatcher/dsmethod.c
--- v2.4.5/linux/drivers/acpi/dispatcher/dsmethod.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/dispatcher/dsmethod.c	Wed Jun 20 17:47:39 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: dsmethod - Parser/Interpreter interface - control method parsing
- *              $Revision: 56 $
+ *              $Revision: 63 $
  *
  *****************************************************************************/
 
@@ -34,7 +34,7 @@
 #include "acdebug.h"
 
 
-#define _COMPONENT          DISPATCHER
+#define _COMPONENT          ACPI_DISPATCHER
 	 MODULE_NAME         ("dsmethod")
 
 
@@ -85,9 +85,9 @@
 	 /* Create a mutex for the method if there is a concurrency limit */
 
 	if ((obj_desc->method.concurrency != INFINITE_CONCURRENCY) &&
-		(!obj_desc->method.semaphore))
-	{
-		status = acpi_os_create_semaphore (1,obj_desc->method.concurrency,
+		(!obj_desc->method.semaphore)) {
+		status = acpi_os_create_semaphore (obj_desc->method.concurrency,
+				   obj_desc->method.concurrency,
 				   &obj_desc->method.semaphore);
 		if (ACPI_FAILURE (status)) {
 			return (status);
@@ -98,7 +98,6 @@
 	 * Allocate a new parser op to be the root of the parsed
 	 * method tree
 	 */
-
 	op = acpi_ps_alloc_op (AML_METHOD_OP);
 	if (!op) {
 		return (AE_NO_MEMORY);
@@ -113,15 +112,13 @@
 	/*
 	 * Parse the method, first pass
 	 *
-	 * The first pass load is
-	 * where newly declared named objects are
+	 * The first pass load is where newly declared named objects are
 	 * added into the namespace.  Actual evaluation of
 	 * the named objects (what would be called a "second
 	 * pass") happens during the actual execution of the
 	 * method so that operands to the named objects can
 	 * take on dynamic run-time values.
 	 */
-
 	status = acpi_ps_parse_aml (op, obj_desc->method.pcode,
 			   obj_desc->method.pcode_length,
 			   ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE,
@@ -134,7 +131,7 @@
 
 	/* Get a new Owner_id for objects created by this method */
 
-	owner_id = acpi_cm_allocate_owner_id (OWNER_TYPE_METHOD);
+	owner_id = acpi_ut_allocate_owner_id (OWNER_TYPE_METHOD);
 	obj_desc->method.owning_id = owner_id;
 
 	/* Install the parsed tree in the method object */
@@ -142,7 +139,6 @@
 
 	acpi_ps_delete_parse_tree (op);
 
-
 	return (status);
 }
 
@@ -151,8 +147,9 @@
  *
  * FUNCTION:    Acpi_ds_begin_method_execution
  *
- * PARAMETERS:  Method_node        - Node of the method
+ * PARAMETERS:  Method_node         - Node of the method
  *              Obj_desc            - The method object
+ *              Calling_method_node - Caller of this method (if non-null)
  *
  * RETURN:      Status
  *
@@ -167,7 +164,8 @@
 ACPI_STATUS
 acpi_ds_begin_method_execution (
 	ACPI_NAMESPACE_NODE     *method_node,
-	ACPI_OPERAND_OBJECT     *obj_desc)
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	ACPI_NAMESPACE_NODE     *calling_method_node)
 {
 	ACPI_STATUS             status = AE_OK;
 
@@ -176,34 +174,41 @@
 		return (AE_NULL_ENTRY);
 	}
 
-	obj_desc = acpi_ns_get_attached_object (method_node);
-	if (!obj_desc) {
-		return (AE_NULL_OBJECT);
-	}
-
 
 	/*
 	 * If there is a concurrency limit on this method, we need to
-	 * obtain a unit from the method semaphore.  This releases the
-	 * interpreter if we block
+	 * obtain a unit from the method semaphore.
 	 */
-
 	if (obj_desc->method.semaphore) {
-		status = acpi_aml_system_wait_semaphore (obj_desc->method.semaphore,
+		/*
+		 * Allow recursive method calls, up to the reentrancy/concurrency
+		 * limit imposed by the SERIALIZED rule and the Sync_level method
+		 * parameter.
+		 *
+		 * The point of this code is to avoid permanently blocking a
+		 * thread that is making recursive method calls.
+		 */
+		if (method_node == calling_method_node) {
+			if (obj_desc->method.thread_count >= obj_desc->method.concurrency) {
+				return (AE_AML_METHOD_LIMIT);
+			}
+		}
+
+		/*
+		 * Get a unit from the method semaphore. This releases the
+		 * interpreter if we block
+		 */
+		status = acpi_ex_system_wait_semaphore (obj_desc->method.semaphore,
 				 WAIT_FOREVER);
 	}
 
 
 	/*
-	 * Increment the method parse tree thread count since there
-	 * is one additional thread executing in it.  If configured
-	 * for deletion-on-exit, the parse tree will be deleted when
-	 * the last thread completes execution of the method
+	 * Increment the method parse tree thread count since it has been
+	 * reentered one more time (even if it is the same thread)
 	 */
-
 	obj_desc->method.thread_count++;
 
-
 	return (status);
 }
 
@@ -238,7 +243,6 @@
 	/*
 	 * Get the namespace entry for the control method we are about to call
 	 */
-
 	method_node = this_walk_state->method_call_node;
 	if (!method_node) {
 		return (AE_NULL_ENTRY);
@@ -252,12 +256,12 @@
 
 	/* Init for new method, wait on concurrency semaphore */
 
-	status = acpi_ds_begin_method_execution (method_node, obj_desc);
+	status = acpi_ds_begin_method_execution (method_node, obj_desc,
+			  this_walk_state->method_node);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
 
-
 	/* Create and initialize a new parser state */
 
 	parser_state = acpi_ps_create_state (obj_desc->method.pcode,
@@ -307,7 +311,6 @@
 	 * stack.  Operands on the previous walk state stack always
 	 * start at index 0.
 	 */
-
 	status = acpi_ds_method_data_init_args (&this_walk_state->operands[0],
 			 this_walk_state->num_operands,
 			 next_walk_state);
@@ -335,9 +338,8 @@
 	 * Delete the operands on the previous walkstate operand stack
 	 * (they were copied to new objects)
 	 */
-
 	for (i = 0; i < obj_desc->method.param_count; i++) {
-		acpi_cm_remove_reference (this_walk_state->operands [i]);
+		acpi_ut_remove_reference (this_walk_state->operands [i]);
 		this_walk_state->operands [i] = NULL;
 	}
 
@@ -386,10 +388,9 @@
 			 * Get the return value (if any) from the previous method.
 			 * NULL if no return value
 			 */
-
 			status = acpi_ds_result_push (return_desc, walk_state);
 			if (ACPI_FAILURE (status)) {
-				acpi_cm_remove_reference (return_desc);
+				acpi_ut_remove_reference (return_desc);
 				return (status);
 			}
 		}
@@ -399,7 +400,7 @@
 			 * Delete the return value if it will not be used by the
 			 * calling method
 			 */
-			acpi_cm_remove_reference (return_desc);
+			acpi_ut_remove_reference (return_desc);
 		}
 
 	}
@@ -427,7 +428,6 @@
 acpi_ds_terminate_control_method (
 	ACPI_WALK_STATE         *walk_state)
 {
-	ACPI_STATUS             status;
 	ACPI_OPERAND_OBJECT     *obj_desc;
 	ACPI_NAMESPACE_NODE     *method_node;
 
@@ -448,15 +448,14 @@
 	 * If this is the last thread executing the method,
 	 * we have additional cleanup to perform
 	 */
-
-	acpi_cm_acquire_mutex (ACPI_MTX_PARSER);
+	acpi_ut_acquire_mutex (ACPI_MTX_PARSER);
 
 
 	/* Signal completion of the execution of this method if necessary */
 
 	if (walk_state->method_desc->method.semaphore) {
-		status = acpi_os_signal_semaphore (
-				 walk_state->method_desc->method.semaphore, 1);
+		acpi_os_signal_semaphore (
+			walk_state->method_desc->method.semaphore, 1);
 	}
 
 	/* Decrement the thread count on the method parse tree */
@@ -470,11 +469,12 @@
 		 * The method Node is stored in the walk state
 		 */
 		method_node = walk_state->method_node;
+
 		/*
 		 * Delete any namespace entries created immediately underneath
 		 * the method
 		 */
-		acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+		acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 		if (method_node->child) {
 			acpi_ns_delete_namespace_subtree (method_node);
 		}
@@ -484,10 +484,10 @@
 		 * the namespace
 		 */
 		acpi_ns_delete_namespace_by_owner (walk_state->method_desc->method.owning_id);
-		acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+		acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 	}
 
-	acpi_cm_release_mutex (ACPI_MTX_PARSER);
+	acpi_ut_release_mutex (ACPI_MTX_PARSER);
 	return (AE_OK);
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/dispatcher/dsmthdat.c linux/drivers/acpi/dispatcher/dsmthdat.c
--- v2.4.5/linux/drivers/acpi/dispatcher/dsmthdat.c	Mon Jan 29 10:15:58 2001
+++ linux/drivers/acpi/dispatcher/dsmthdat.c	Wed Jun 20 17:47:39 2001
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: dsmthdat - control method arguments and local variables
- *              $Revision: 39 $
+ *              $Revision: 46 $
  *
  ******************************************************************************/
 
@@ -32,7 +32,7 @@
 #include "acnamesp.h"
 
 
-#define _COMPONENT          DISPATCHER
+#define _COMPONENT          ACPI_DISPATCHER
 	 MODULE_NAME         ("dsmthdat")
 
 
@@ -60,7 +60,7 @@
 
 	/*
 	 * Walk_state fields are initialized to zero by the
-	 * Acpi_cm_callocate().
+	 * Acpi_ut_callocate().
 	 *
 	 * An Node is assigned to each argument and local so
 	 * that Ref_of() can return a pointer to the Node.
@@ -125,7 +125,7 @@
 
 			/* Was given a ref when stored */
 
-			acpi_cm_remove_reference (object);
+			acpi_ut_remove_reference (object);
 	   }
 	}
 
@@ -141,7 +141,7 @@
 
 			 /* Was given a ref when stored */
 
-			acpi_cm_remove_reference (object);
+			acpi_ut_remove_reference (object);
 		}
 	}
 
@@ -182,16 +182,15 @@
 
 	for (pindex = mindex = 0;
 		(mindex < MTH_NUM_ARGS) && (pindex < max_param_count);
-		mindex++)
-	{
+		mindex++) {
 		if (params[pindex]) {
 			/*
 			 * A valid parameter.
 			 * Set the current method argument to the
 			 * Params[Pindex++] argument object descriptor
 			 */
-			status = acpi_ds_method_data_set_value (MTH_TYPE_ARG, mindex,
-					 params[pindex], walk_state);
+			status = acpi_ds_store_object_to_local (AML_ARG_OP, mindex,
+					  params[pindex], walk_state);
 			if (ACPI_FAILURE (status)) {
 				break;
 			}
@@ -212,7 +211,7 @@
  *
  * FUNCTION:    Acpi_ds_method_data_get_entry
  *
- * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
+ * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
  *              Index               - Which local_var or argument to get
  *              Entry               - Pointer to where a pointer to the stack
  *                                    entry is returned.
@@ -220,13 +219,13 @@
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Get the address of the stack entry given by Type:Index
+ * DESCRIPTION: Get the address of the object entry given by Opcode:Index
  *
  ******************************************************************************/
 
 ACPI_STATUS
 acpi_ds_method_data_get_entry (
-	u32                     type,
+	u16                     opcode,
 	u32                     index,
 	ACPI_WALK_STATE         *walk_state,
 	ACPI_OPERAND_OBJECT     ***entry)
@@ -235,31 +234,30 @@
 
 	/*
 	 * Get the requested object.
-	 * The stack "Type" is either a Local_variable or an Argument
+	 * The stack "Opcode" is either a Local_variable or an Argument
 	 */
 
-	switch (type)
-	{
+	switch (opcode) {
 
-	case MTH_TYPE_LOCAL:
+	case AML_LOCAL_OP:
 
 		if (index > MTH_MAX_LOCAL) {
 			return (AE_BAD_PARAMETER);
 		}
 
-		*entry =
-			(ACPI_OPERAND_OBJECT  **) &walk_state->local_variables[index].object;
+		*entry = (ACPI_OPERAND_OBJECT  **)
+				 &walk_state->local_variables[index].object;
 		break;
 
 
-	case MTH_TYPE_ARG:
+	case AML_ARG_OP:
 
 		if (index > MTH_MAX_ARG) {
 			return (AE_BAD_PARAMETER);
 		}
 
-		*entry =
-			(ACPI_OPERAND_OBJECT  **) &walk_state->arguments[index].object;
+		*entry = (ACPI_OPERAND_OBJECT  **)
+				 &walk_state->arguments[index].object;
 		break;
 
 
@@ -276,20 +274,20 @@
  *
  * FUNCTION:    Acpi_ds_method_data_set_entry
  *
- * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
+ * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
  *              Index               - Which local_var or argument to get
  *              Object              - Object to be inserted into the stack entry
  *              Walk_state          - Current walk state object
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Insert an object onto the method stack at entry Type:Index.
+ * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index.
  *
  ******************************************************************************/
 
 ACPI_STATUS
 acpi_ds_method_data_set_entry (
-	u32                     type,
+	u16                     opcode,
 	u32                     index,
 	ACPI_OPERAND_OBJECT     *object,
 	ACPI_WALK_STATE         *walk_state)
@@ -300,14 +298,14 @@
 
 	/* Get a pointer to the stack entry to set */
 
-	status = acpi_ds_method_data_get_entry (type, index, walk_state, &entry);
+	status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
 
 	/* Increment ref count so object can't be deleted while installed */
 
-	acpi_cm_add_reference (object);
+	acpi_ut_add_reference (object);
 
 	/* Install the object into the stack entry */
 
@@ -321,7 +319,7 @@
  *
  * FUNCTION:    Acpi_ds_method_data_get_type
  *
- * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
+ * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
  *              Index               - Which local_var or argument whose type
  *                                      to get
  *              Walk_state          - Current walk state object
@@ -331,9 +329,9 @@
  *
  ******************************************************************************/
 
-OBJECT_TYPE_INTERNAL
+ACPI_OBJECT_TYPE8
 acpi_ds_method_data_get_type (
-	u32                     type,
+	u16                     opcode,
 	u32                     index,
 	ACPI_WALK_STATE         *walk_state)
 {
@@ -344,7 +342,7 @@
 
 	/* Get a pointer to the requested stack entry */
 
-	status = acpi_ds_method_data_get_entry (type, index, walk_state, &entry);
+	status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry);
 	if (ACPI_FAILURE (status)) {
 		return ((ACPI_TYPE_NOT_FOUND));
 	}
@@ -366,9 +364,9 @@
 
 /*******************************************************************************
  *
- * FUNCTION:    Acpi_ds_method_data_get_nte
+ * FUNCTION:    Acpi_ds_method_data_get_node
  *
- * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
+ * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
  *              Index               - Which local_var or argument whose type
  *                                      to get
  *              Walk_state          - Current walk state object
@@ -378,18 +376,17 @@
  ******************************************************************************/
 
 ACPI_NAMESPACE_NODE *
-acpi_ds_method_data_get_nte (
-	u32                     type,
+acpi_ds_method_data_get_node (
+	u16                     opcode,
 	u32                     index,
 	ACPI_WALK_STATE         *walk_state)
 {
 	ACPI_NAMESPACE_NODE     *node = NULL;
 
 
-	switch (type)
-	{
+	switch (opcode) {
 
-	case MTH_TYPE_LOCAL:
+	case AML_LOCAL_OP:
 
 		if (index > MTH_MAX_LOCAL) {
 			return (node);
@@ -399,7 +396,7 @@
 		break;
 
 
-	case MTH_TYPE_ARG:
+	case AML_ARG_OP:
 
 		if (index > MTH_MAX_ARG) {
 			return (node);
@@ -422,7 +419,7 @@
  *
  * FUNCTION:    Acpi_ds_method_data_get_value
  *
- * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
+ * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
  *              Index               - Which local_var or argument to get
  *              Walk_state          - Current walk state object
  *              *Dest_desc          - Ptr to Descriptor into which selected Arg
@@ -432,13 +429,13 @@
  *
  * DESCRIPTION: Retrieve value of selected Arg or Local from the method frame
  *              at the current top of the method stack.
- *              Used only in Acpi_aml_resolve_to_value().
+ *              Used only in Acpi_ex_resolve_to_value().
  *
  ******************************************************************************/
 
 ACPI_STATUS
 acpi_ds_method_data_get_value (
-	u32                     type,
+	u16                     opcode,
 	u32                     index,
 	ACPI_WALK_STATE         *walk_state,
 	ACPI_OPERAND_OBJECT     **dest_desc)
@@ -457,7 +454,7 @@
 
 	/* Get a pointer to the requested method stack entry */
 
-	status = acpi_ds_method_data_get_entry (type, index, walk_state, &entry);
+	status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
@@ -478,14 +475,13 @@
 		 * before it was initialized.  Either case is an error.
 		 */
 
-		switch (type)
-		{
-		case MTH_TYPE_ARG:
+		switch (opcode) {
+		case AML_ARG_OP:
 
 			return (AE_AML_UNINITIALIZED_ARG);
 			break;
 
-		case MTH_TYPE_LOCAL:
+		case AML_LOCAL_OP:
 
 			return (AE_AML_UNINITIALIZED_LOCAL);
 			break;
@@ -499,7 +495,7 @@
 	 */
 
 	*dest_desc = object;
-	acpi_cm_add_reference (object);
+	acpi_ut_add_reference (object);
 
 	return (AE_OK);
 }
@@ -509,20 +505,20 @@
  *
  * FUNCTION:    Acpi_ds_method_data_delete_value
  *
- * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
+ * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
  *              Index               - Which local_var or argument to delete
  *              Walk_state          - Current walk state object
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Delete the entry at Type:Index on the method stack.  Inserts
+ * DESCRIPTION: Delete the entry at Opcode:Index on the method stack.  Inserts
  *              a null into the stack slot after the object is deleted.
  *
  ******************************************************************************/
 
 ACPI_STATUS
 acpi_ds_method_data_delete_value (
-	u32                     type,
+	u16                     opcode,
 	u32                     index,
 	ACPI_WALK_STATE         *walk_state)
 {
@@ -533,7 +529,7 @@
 
 	/* Get a pointer to the requested entry */
 
-	status = acpi_ds_method_data_get_entry (type, index, walk_state, &entry);
+	status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
@@ -551,14 +547,13 @@
 
 
 	if ((object) &&
-		(VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_INTERNAL)))
-	{
+		(VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_INTERNAL))) {
 		/*
 		 * There is a valid object in this slot
 		 * Decrement the reference count by one to balance the
 		 * increment when the object was stored in the slot.
 		 */
-		acpi_cm_remove_reference (object);
+		acpi_ut_remove_reference (object);
 	}
 
 
@@ -568,9 +563,9 @@
 
 /*******************************************************************************
  *
- * FUNCTION:    Acpi_ds_method_data_set_value
+ * FUNCTION:    Acpi_ds_store_object_to_local
  *
- * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
+ * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
  *              Index               - Which local_var or argument to set
  *              Src_desc            - Value to be stored
  *              Walk_state          - Current walk state
@@ -584,8 +579,8 @@
  ******************************************************************************/
 
 ACPI_STATUS
-acpi_ds_method_data_set_value (
-	u32                     type,
+acpi_ds_store_object_to_local (
+	u16                     opcode,
 	u32                     index,
 	ACPI_OPERAND_OBJECT     *src_desc,
 	ACPI_WALK_STATE         *walk_state)
@@ -603,7 +598,7 @@
 
 	/* Get a pointer to the requested method stack entry */
 
-	status = acpi_ds_method_data_get_entry (type, index, walk_state, &entry);
+	status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry);
 	if (ACPI_FAILURE (status)) {
 		goto cleanup;
 	}
@@ -638,9 +633,8 @@
 		 * Weird, but true.
 		 */
 
-		if ((type == MTH_TYPE_ARG) &&
-			(VALID_DESCRIPTOR_TYPE (*entry, ACPI_DESC_TYPE_NAMED)))
-		{
+		if ((opcode == AML_ARG_OP) &&
+			(VALID_DESCRIPTOR_TYPE (*entry, ACPI_DESC_TYPE_NAMED))) {
 			/* Detach an existing object from the Node */
 
 			acpi_ns_detach_object ((ACPI_NAMESPACE_NODE *) *entry);
@@ -655,20 +649,22 @@
 		}
 
 
+#ifdef ACPI_ENABLE_IMPLICIT_CONVERSION
 		/*
 		 * Perform "Implicit conversion" of the new object to the type of the
 		 * existing object
 		 */
-		status = acpi_aml_convert_to_target_type ((*entry)->common.type, &src_desc, walk_state);
+		status = acpi_ex_convert_to_target_type ((*entry)->common.type, &src_desc, walk_state);
 		if (ACPI_FAILURE (status)) {
 			goto cleanup;
 		}
+#endif
 
 		/*
 		 * Delete the existing object
 		 * before storing the new one
 		 */
-		acpi_ds_method_data_delete_value (type, index, walk_state);
+		acpi_ds_method_data_delete_value (opcode, index, walk_state);
 	}
 
 
@@ -678,7 +674,7 @@
 	 * Install the new object in the stack entry
 	 * (increments the object reference count by one)
 	 */
-	status = acpi_ds_method_data_set_entry (type, index, src_desc, walk_state);
+	status = acpi_ds_method_data_set_entry (opcode, index, src_desc, walk_state);
 	if (ACPI_FAILURE (status)) {
 		goto cleanup;
 	}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/dispatcher/dsobject.c linux/drivers/acpi/dispatcher/dsobject.c
--- v2.4.5/linux/drivers/acpi/dispatcher/dsobject.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/dispatcher/dsobject.c	Wed Jun 20 17:47:39 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: dsobject - Dispatcher object management routines
- *              $Revision: 57 $
+ *              $Revision: 65 $
  *
  *****************************************************************************/
 
@@ -31,7 +31,7 @@
 #include "acinterp.h"
 #include "acnamesp.h"
 
-#define _COMPONENT          DISPATCHER
+#define _COMPONENT          ACPI_DISPATCHER
 	 MODULE_NAME         ("dsobject")
 
 
@@ -62,12 +62,15 @@
 	void                    *context,
 	void                    **return_value)
 {
-	OBJECT_TYPE_INTERNAL    type;
+	ACPI_OBJECT_TYPE8       type;
 	ACPI_STATUS             status;
 	ACPI_INIT_WALK_INFO     *info = (ACPI_INIT_WALK_INFO *) context;
 	u8                      table_revision;
 
 
+	PROC_NAME ("Ds_init_one_object");
+
+
 	info->object_count++;
 	table_revision = info->table_desc->pointer->revision;
 
@@ -77,8 +80,7 @@
 	 */
 
 	if (((ACPI_NAMESPACE_NODE *) obj_handle)->owner_id !=
-			info->table_desc->table_id)
-	{
+			info->table_desc->table_id) {
 		return (AE_OK);
 	}
 
@@ -87,8 +89,7 @@
 
 	type = acpi_ns_get_type (obj_handle);
 
-	switch (type)
-	{
+	switch (type) {
 
 	case ACPI_TYPE_REGION:
 
@@ -174,9 +175,8 @@
 
 	/* Walk entire namespace from the supplied root */
 
-	status = acpi_walk_namespace (ACPI_TYPE_ANY, start_node,
-			  ACPI_UINT32_MAX, acpi_ds_init_one_object,
-			  &info, NULL);
+	status = acpi_walk_namespace (ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
+			  acpi_ds_init_one_object, &info, NULL);
 
 	return (AE_OK);
 }
@@ -212,6 +212,9 @@
 	ACPI_OPCODE_INFO        *op_info;
 
 
+	PROC_NAME ("Ds_init_object_from_op");
+
+
 	op_info = acpi_ps_get_opcode_info (opcode);
 	if (ACPI_GET_OP_TYPE (op_info) != ACPI_OP_TYPE_OPCODE) {
 		/* Unknown opcode */
@@ -222,8 +225,7 @@
 
 	/* Get and prepare the first argument */
 
-	switch ((*obj_desc)->common.type)
-	{
+	switch ((*obj_desc)->common.type) {
 	case ACPI_TYPE_BUFFER:
 
 		/* First arg is a number */
@@ -234,23 +236,23 @@
 
 		/* Resolve the object (could be an arg or local) */
 
-		status = acpi_aml_resolve_to_value (&arg_desc, walk_state);
+		status = acpi_ex_resolve_to_value (&arg_desc, walk_state);
 		if (ACPI_FAILURE (status)) {
-			acpi_cm_remove_reference (arg_desc);
+			acpi_ut_remove_reference (arg_desc);
 			return (status);
 		}
 
 		/* We are expecting a number */
 
 		if (arg_desc->common.type != ACPI_TYPE_INTEGER) {
-			acpi_cm_remove_reference (arg_desc);
+			acpi_ut_remove_reference (arg_desc);
 			return (AE_TYPE);
 		}
 
 		/* Get the value, delete the internal object */
 
 		(*obj_desc)->buffer.length = (u32) arg_desc->integer.value;
-		acpi_cm_remove_reference (arg_desc);
+		acpi_ut_remove_reference (arg_desc);
 
 		/* Allocate the buffer */
 
@@ -262,7 +264,7 @@
 
 		else {
 			(*obj_desc)->buffer.pointer =
-					  acpi_cm_callocate ((*obj_desc)->buffer.length);
+					  acpi_ut_callocate ((*obj_desc)->buffer.length);
 
 			if (!(*obj_desc)->buffer.pointer) {
 				return (AE_NO_MEMORY);
@@ -279,7 +281,7 @@
 		arg = op->value.arg;
 		byte_list = (ACPI_PARSE2_OBJECT *) arg->next;
 		if (byte_list) {
-			if (byte_list->opcode != AML_BYTELIST_OP) {
+			if (byte_list->opcode != AML_INT_BYTELIST_OP) {
 				return (AE_TYPE);
 			}
 
@@ -300,7 +302,7 @@
 		 *  so that it is deleted.  Error checking is done
 		 *  within the remove reference function.
 		 */
-		acpi_cm_remove_reference(*obj_desc);
+		acpi_ut_remove_reference(*obj_desc);
 
 		status = acpi_ds_build_internal_object (walk_state, op, obj_desc);
 		break;
@@ -322,13 +324,12 @@
 
 	case INTERNAL_TYPE_REFERENCE:
 
-		switch (ACPI_GET_OP_CLASS (op_info))
-		{
+		switch (ACPI_GET_OP_CLASS (op_info)) {
 		case OPTYPE_LOCAL_VARIABLE:
 
 			/* Split the opcode into a base opcode + offset */
 
-			(*obj_desc)->reference.op_code = AML_LOCAL_OP;
+			(*obj_desc)->reference.opcode = AML_LOCAL_OP;
 			(*obj_desc)->reference.offset = opcode - AML_LOCAL_OP;
 			break;
 
@@ -336,19 +337,19 @@
 
 			/* Split the opcode into a base opcode + offset */
 
-			(*obj_desc)->reference.op_code = AML_ARG_OP;
+			(*obj_desc)->reference.opcode = AML_ARG_OP;
 			(*obj_desc)->reference.offset = opcode - AML_ARG_OP;
 			break;
 
 		default: /* Constants, Literals, etc.. */
 
-			if (op->opcode == AML_NAMEPATH_OP) {
+			if (op->opcode == AML_INT_NAMEPATH_OP) {
 				/* Node was saved in Op */
 
 				(*obj_desc)->reference.node = op->node;
 			}
 
-			(*obj_desc)->reference.op_code = opcode;
+			(*obj_desc)->reference.opcode = opcode;
 			break;
 		}
 
@@ -385,13 +386,13 @@
 	ACPI_OPERAND_OBJECT     **obj_desc_ptr)
 {
 	ACPI_OPERAND_OBJECT     *obj_desc;
-	OBJECT_TYPE_INTERNAL    type;
+	ACPI_OBJECT_TYPE8       type;
 	ACPI_STATUS             status;
 	u32                     length;
 	char                    *name;
 
 
-	if (op->opcode == AML_NAMEPATH_OP) {
+	if (op->opcode == AML_INT_NAMEPATH_OP) {
 		/*
 		 * This is an object reference.  If The name was
 		 * previously looked up in the NS, it is stored in this op.
@@ -414,7 +415,7 @@
 					if (name) {
 						REPORT_WARNING (("Reference %s at AML %X not found\n",
 								 name, op->aml_offset));
-						acpi_cm_free (name);
+						acpi_ut_free (name);
 					}
 					else {
 						REPORT_WARNING (("Reference %s at AML %X not found\n",
@@ -444,16 +445,14 @@
 
 	/* Create and init the internal ACPI object */
 
-	obj_desc = acpi_cm_create_internal_object (type);
+	obj_desc = acpi_ut_create_internal_object (type);
 	if (!obj_desc) {
 		return (AE_NO_MEMORY);
 	}
 
-	status = acpi_ds_init_object_from_op (walk_state, op,
-			 op->opcode, &obj_desc);
-
+	status = acpi_ds_init_object_from_op (walk_state, op, op->opcode, &obj_desc);
 	if (ACPI_FAILURE (status)) {
-		acpi_cm_remove_reference (obj_desc);
+		acpi_ut_remove_reference (obj_desc);
 		return (status);
 	}
 
@@ -488,7 +487,7 @@
 	ACPI_STATUS             status = AE_OK;
 
 
-	obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_PACKAGE);
+	obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_PACKAGE);
 	if (!obj_desc) {
 		return (AE_NO_MEMORY);
 	}
@@ -505,15 +504,10 @@
 	 */
 
 	obj_desc->package.elements =
-			 acpi_cm_callocate ((obj_desc->package.count + 1) *
-			 sizeof (void *));
+		acpi_ut_callocate ((obj_desc->package.count + 1) * sizeof (void *));
 
 	if (!obj_desc->package.elements) {
-		/* Package vector allocation failure   */
-
-		REPORT_ERROR (("Ds_build_internal_package_obj: Package vector allocation failure\n"));
-
-		acpi_cm_delete_object_desc (obj_desc);
+		acpi_ut_delete_object_desc (obj_desc);
 		return (AE_NO_MEMORY);
 	}
 
@@ -568,13 +562,11 @@
 
 
 	if (op->opcode == AML_PACKAGE_OP) {
-		status = acpi_ds_build_internal_package_obj (walk_state, op,
-				  obj_desc_ptr);
+		status = acpi_ds_build_internal_package_obj (walk_state, op, obj_desc_ptr);
 	}
 
 	else {
-		status = acpi_ds_build_internal_simple_obj (walk_state, op,
-				  obj_desc_ptr);
+		status = acpi_ds_build_internal_simple_obj (walk_state, op, obj_desc_ptr);
 	}
 
 	return (status);
@@ -613,8 +605,7 @@
 
 	/* Build an internal object for the argument(s) */
 
-	status = acpi_ds_build_internal_object (walk_state,
-			 op->value.arg, &obj_desc);
+	status = acpi_ds_build_internal_object (walk_state, op->value.arg, &obj_desc);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
@@ -626,8 +617,7 @@
 
 	/* Init obj */
 
-	status = acpi_ns_attach_object ((ACPI_HANDLE) node, obj_desc,
-			   (u8) node->type);
+	status = acpi_ns_attach_object (node, obj_desc, (u8) node->type);
 	if (ACPI_FAILURE (status)) {
 		goto cleanup;
 	}
@@ -637,7 +627,7 @@
 
 cleanup:
 
-	acpi_cm_remove_reference (obj_desc);
+	acpi_ut_remove_reference (obj_desc);
 
 	return (status);
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/dispatcher/dsopcode.c linux/drivers/acpi/dispatcher/dsopcode.c
--- v2.4.5/linux/drivers/acpi/dispatcher/dsopcode.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/dispatcher/dsopcode.c	Wed Jun 20 17:47:39 2001
@@ -2,7 +2,7 @@
  *
  * Module Name: dsopcode - Dispatcher Op Region support and handling of
  *                         "control" opcodes
- *              $Revision: 32 $
+ *              $Revision: 44 $
  *
  *****************************************************************************/
 
@@ -34,25 +34,25 @@
 #include "acevents.h"
 #include "actables.h"
 
-#define _COMPONENT          DISPATCHER
+#define _COMPONENT          ACPI_DISPATCHER
 	 MODULE_NAME         ("dsopcode")
 
 
 /*****************************************************************************
  *
- * FUNCTION:    Acpi_ds_get_field_unit_arguments
+ * FUNCTION:    Acpi_ds_get_buffer_field_arguments
  *
- * PARAMETERS:  Obj_desc        - A valid Field_unit object
+ * PARAMETERS:  Obj_desc        - A valid Buffer_field object
  *
  * RETURN:      Status.
  *
- * DESCRIPTION: Get Field_unit Buffer and Index. This implements the late
+ * DESCRIPTION: Get Buffer_field Buffer and Index. This implements the late
  *              evaluation of these field attributes.
  *
  ****************************************************************************/
 
 ACPI_STATUS
-acpi_ds_get_field_unit_arguments (
+acpi_ds_get_buffer_field_arguments (
 	ACPI_OPERAND_OBJECT     *obj_desc)
 {
 	ACPI_OPERAND_OBJECT     *extra_desc;
@@ -68,10 +68,10 @@
 	}
 
 
-	/* Get the AML pointer (method object) and Field_unit node */
+	/* Get the AML pointer (method object) and Buffer_field node */
 
-	extra_desc = obj_desc->field_unit.extra;
-	node = obj_desc->field_unit.node;
+	extra_desc = obj_desc->buffer_field.extra;
+	node = obj_desc->buffer_field.node;
 
 	/*
 	 * Allocate a new parser op to be the root of the parsed
@@ -94,7 +94,7 @@
 		return (status);
 	}
 
-	/* Pass1: Parse the entire Field_unit declaration */
+	/* Pass1: Parse the entire Buffer_field declaration */
 
 	status = acpi_ps_parse_aml (op, extra_desc->extra.pcode,
 			  extra_desc->extra.pcode_length, 0,
@@ -138,8 +138,8 @@
 	 * The pseudo-method object is no longer needed since the region is
 	 * now initialized
 	 */
-	acpi_cm_remove_reference (obj_desc->field_unit.extra);
-	obj_desc->field_unit.extra = NULL;
+	acpi_ut_remove_reference (obj_desc->buffer_field.extra);
+	obj_desc->buffer_field.extra = NULL;
 
 	return (status);
 }
@@ -278,29 +278,45 @@
 
 /*****************************************************************************
  *
- * FUNCTION:    Acpi_ds_eval_field_unit_operands
+ * FUNCTION:    Acpi_ds_eval_buffer_field_operands
  *
- * PARAMETERS:  Op              - A valid Field_unit Op object
+ * PARAMETERS:  Op              - A valid Buffer_field Op object
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Get Field_unit Buffer and Index
- *              Called from Acpi_ds_exec_end_op during Field_unit parse tree walk
+ * DESCRIPTION: Get Buffer_field Buffer and Index
+ *              Called from Acpi_ds_exec_end_op during Buffer_field parse tree walk
+ *
+ * ACPI SPECIFICATION REFERENCES:
+ *  Each of the Buffer Field opcodes is defined as specified in in-line
+ *  comments below. For each one, use the following definitions.
+ *
+ *  Def_bit_field   :=  Bit_field_op    Src_buf Bit_idx Destination
+ *  Def_byte_field  :=  Byte_field_op   Src_buf Byte_idx Destination
+ *  Def_create_field := Create_field_op Src_buf Bit_idx Num_bits Name_string
+ *  Def_dWord_field :=  DWord_field_op  Src_buf Byte_idx Destination
+ *  Def_word_field  :=  Word_field_op   Src_buf Byte_idx Destination
+ *  Bit_index       :=  Term_arg=>Integer
+ *  Byte_index      :=  Term_arg=>Integer
+ *  Destination     :=  Name_string
+ *  Num_bits        :=  Term_arg=>Integer
+ *  Source_buf      :=  Term_arg=>Buffer
  *
  ****************************************************************************/
 
 ACPI_STATUS
-acpi_ds_eval_field_unit_operands (
+acpi_ds_eval_buffer_field_operands (
 	ACPI_WALK_STATE         *walk_state,
 	ACPI_PARSE_OBJECT       *op)
 {
 	ACPI_STATUS             status;
-	ACPI_OPERAND_OBJECT     *field_desc;
+	ACPI_OPERAND_OBJECT     *obj_desc;
 	ACPI_NAMESPACE_NODE     *node;
 	ACPI_PARSE_OBJECT       *next_op;
 	u32                     offset;
 	u32                     bit_offset;
-	u16                     bit_count;
+	u32                     bit_count;
+	u8                      field_flags;
 
 
 	ACPI_OPERAND_OBJECT     *res_desc = NULL;
@@ -311,12 +327,14 @@
 
 
 	/*
-	 * This is where we evaluate the address and length fields of the Op_field_unit declaration
+	 * This is where we evaluate the address and length fields of the
+	 * Create_xxx_field declaration
 	 */
 
 	node =  op->node;
 
 	/* Next_op points to the op that holds the Buffer */
+
 	next_op = op->value.arg;
 
 	/* Acpi_evaluate/create the address and length operands */
@@ -326,15 +344,15 @@
 		return (status);
 	}
 
-	field_desc = acpi_ns_get_attached_object (node);
-	if (!field_desc) {
+	obj_desc = acpi_ns_get_attached_object (node);
+	if (!obj_desc) {
 		return (AE_NOT_EXIST);
 	}
 
 
 	/* Resolve the operands */
 
-	status = acpi_aml_resolve_operands (op->opcode, WALK_OPERANDS, walk_state);
+	status = acpi_ex_resolve_operands (op->opcode, WALK_OPERANDS, walk_state);
 
 	/* Get the operands */
 
@@ -359,7 +377,7 @@
 
 	/*
 	 * If Res_desc is a Name, it will be a direct name pointer after
-	 * Acpi_aml_resolve_operands()
+	 * Acpi_ex_resolve_operands()
 	 */
 
 	if (!VALID_DESCRIPTOR_TYPE (res_desc, ACPI_DESC_TYPE_NAMED)) {
@@ -372,61 +390,77 @@
 	 * Setup the Bit offsets and counts, according to the opcode
 	 */
 
-	switch (op->opcode)
-	{
+	switch (op->opcode) {
+
+	/* Def_create_field */
+
+	case AML_CREATE_FIELD_OP:
+
+		/* Offset is in bits, count is in bits */
+
+		bit_offset  = offset;
+		bit_count   = (u32) cnt_desc->integer.value;
+		field_flags = ACCESS_BYTE_ACC;
+		break;
+
 
 	/* Def_create_bit_field */
 
-	case AML_BIT_FIELD_OP:
+	case AML_CREATE_BIT_FIELD_OP:
 
-		/* Offset is in bits, Field is a bit */
+		/* Offset is in bits, Field is one bit */
 
-		bit_offset = offset;
-		bit_count = 1;
+		bit_offset  = offset;
+		bit_count   = 1;
+		field_flags = ACCESS_BYTE_ACC;
 		break;
 
 
 	/* Def_create_byte_field */
 
-	case AML_BYTE_FIELD_OP:
+	case AML_CREATE_BYTE_FIELD_OP:
 
-		/* Offset is in bytes, field is a byte */
+		/* Offset is in bytes, field is one byte */
 
-		bit_offset = 8 * offset;
-		bit_count = 8;
+		bit_offset  = 8 * offset;
+		bit_count   = 8;
+		field_flags = ACCESS_BYTE_ACC;
 		break;
 
 
 	/* Def_create_word_field */
 
-	case AML_WORD_FIELD_OP:
+	case AML_CREATE_WORD_FIELD_OP:
 
-		/* Offset is in bytes, field is a word */
+		/* Offset is in bytes, field is one word */
 
-		bit_offset = 8 * offset;
-		bit_count = 16;
+		bit_offset  = 8 * offset;
+		bit_count   = 16;
+		field_flags = ACCESS_WORD_ACC;
 		break;
 
 
 	/* Def_create_dWord_field */
 
-	case AML_DWORD_FIELD_OP:
+	case AML_CREATE_DWORD_FIELD_OP:
 
-		/* Offset is in bytes, field is a dword */
+		/* Offset is in bytes, field is one dword */
 
-		bit_offset = 8 * offset;
-		bit_count = 32;
+		bit_offset  = 8 * offset;
+		bit_count   = 32;
+		field_flags = ACCESS_DWORD_ACC;
 		break;
 
 
-	/* Def_create_field */
+	/* Def_create_qWord_field */
 
-	case AML_CREATE_FIELD_OP:
+	case AML_CREATE_QWORD_FIELD_OP:
 
-		/* Offset is in bits, count is in bits */
+		/* Offset is in bytes, field is one qword */
 
-		bit_offset = offset;
-		bit_count = (u16) cnt_desc->integer.value;
+		bit_offset  = 8 * offset;
+		bit_count   = 64;
+		field_flags = ACCESS_QWORD_ACC;
 		break;
 
 
@@ -441,35 +475,35 @@
 	 * Setup field according to the object type
 	 */
 
-	switch (src_desc->common.type)
-	{
+	switch (src_desc->common.type) {
 
 	/* Source_buff :=  Term_arg=>Buffer */
 
 	case ACPI_TYPE_BUFFER:
 
-		if (bit_offset + (u32) bit_count >
-			(8 * (u32) src_desc->buffer.length))
-		{
+		if ((bit_offset + bit_count) >
+			(8 * (u32) src_desc->buffer.length)) {
 			status = AE_AML_BUFFER_LIMIT;
 			goto cleanup;
 		}
 
 
-		/* Construct the remainder of the field object */
+		/*
+		 * Initialize areas of the field object that are common to all fields
+		 * For Field_flags, use LOCK_RULE = 0 (NO_LOCK), UPDATE_RULE = 0 (UPDATE_PRESERVE)
+		 */
+		status = acpi_ex_prep_common_field_object (obj_desc, field_flags,
+				  bit_offset, bit_count);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
 
-		field_desc->field_unit.access     = (u8) ACCESS_ANY_ACC;
-		field_desc->field_unit.lock_rule  = (u8) GLOCK_NEVER_LOCK;
-		field_desc->field_unit.update_rule = (u8) UPDATE_PRESERVE;
-		field_desc->field_unit.length     = bit_count;
-		field_desc->field_unit.bit_offset = (u8) (bit_offset % 8);
-		field_desc->field_unit.offset     = DIV_8 (bit_offset);
-		field_desc->field_unit.container  = src_desc;
+		obj_desc->buffer_field.buffer_obj = src_desc;
 
-		/* Reference count for Src_desc inherits Field_desc count */
+		/* Reference count for Src_desc inherits Obj_desc count */
 
 		src_desc->common.reference_count = (u16) (src_desc->common.reference_count +
-				   field_desc->common.reference_count);
+				  obj_desc->common.reference_count);
 
 		break;
 
@@ -478,8 +512,6 @@
 
 	default:
 
-		if ((src_desc->common.type > (u8) INTERNAL_TYPE_REFERENCE) ||
-			!acpi_cm_valid_object_type (src_desc->common.type))
 
 
 		status = AE_AML_OPERAND_TYPE;
@@ -490,7 +522,7 @@
 	if (AML_CREATE_FIELD_OP == op->opcode) {
 		/* Delete object descriptor unique to Create_field */
 
-		acpi_cm_remove_reference (cnt_desc);
+		acpi_ut_remove_reference (cnt_desc);
 		cnt_desc = NULL;
 	}
 
@@ -499,23 +531,23 @@
 
 	/* Always delete the operands */
 
-	acpi_cm_remove_reference (off_desc);
-	acpi_cm_remove_reference (src_desc);
+	acpi_ut_remove_reference (off_desc);
+	acpi_ut_remove_reference (src_desc);
 
 	if (AML_CREATE_FIELD_OP == op->opcode) {
-		acpi_cm_remove_reference (cnt_desc);
+		acpi_ut_remove_reference (cnt_desc);
 	}
 
 	/* On failure, delete the result descriptor */
 
 	if (ACPI_FAILURE (status)) {
-		acpi_cm_remove_reference (res_desc); /* Result descriptor */
+		acpi_ut_remove_reference (res_desc); /* Result descriptor */
 	}
 
 	else {
-		/* Now the address and length are valid for this op_field_unit */
+		/* Now the address and length are valid for this Buffer_field */
 
-		field_desc->field_unit.flags |= AOPOBJ_DATA_VALID;
+		obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID;
 	}
 
 	return (status);
@@ -568,7 +600,7 @@
 
 	/* Resolve the length and address operands to numbers */
 
-	status = acpi_aml_resolve_operands (op->opcode, WALK_OPERANDS, walk_state);
+	status = acpi_ex_resolve_operands (op->opcode, WALK_OPERANDS, walk_state);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
@@ -586,7 +618,7 @@
 	operand_desc = walk_state->operands[walk_state->num_operands - 1];
 
 	obj_desc->region.length = (u32) operand_desc->integer.value;
-	acpi_cm_remove_reference (operand_desc);
+	acpi_ut_remove_reference (operand_desc);
 
 	/*
 	 * Get the address and save it
@@ -595,7 +627,7 @@
 	operand_desc = walk_state->operands[walk_state->num_operands - 2];
 
 	obj_desc->region.address = (ACPI_PHYSICAL_ADDRESS) operand_desc->integer.value;
-	acpi_cm_remove_reference (operand_desc);
+	acpi_ut_remove_reference (operand_desc);
 
 
 	/* Now the address and length are valid for this opregion */
@@ -629,8 +661,10 @@
 	ACPI_GENERIC_STATE      *control_state;
 
 
-	switch (op->opcode)
-	{
+	PROC_NAME ("Ds_exec_begin_control_op");
+
+
+	switch (op->opcode) {
 	case AML_IF_OP:
 	case AML_WHILE_OP:
 
@@ -640,13 +674,13 @@
 		 * to handle nesting.
 		 */
 
-		control_state = acpi_cm_create_control_state ();
+		control_state = acpi_ut_create_control_state ();
 		if (!control_state) {
 			status = AE_NO_MEMORY;
 			break;
 		}
 
-		acpi_cm_push_generic_state (&walk_state->control_state, control_state);
+		acpi_ut_push_generic_state (&walk_state->control_state, control_state);
 
 		/*
 		 * Save a pointer to the predicate for multiple executions
@@ -708,8 +742,10 @@
 	ACPI_GENERIC_STATE      *control_state;
 
 
-	switch (op->opcode)
-	{
+	PROC_NAME ("Ds_exec_end_control_op");
+
+
+	switch (op->opcode) {
 	case AML_IF_OP:
 
 		/*
@@ -718,18 +754,15 @@
 		 */
 
 		walk_state->last_predicate =
-				(u8) walk_state->control_state->common.value;
+			(u8) walk_state->control_state->common.value;
 
 		/*
 		 * Pop the control state that was created at the start
 		 * of the IF and free it
 		 */
 
-		control_state =
-				acpi_cm_pop_generic_state (&walk_state->control_state);
-
-		acpi_cm_delete_generic_state (control_state);
-
+		control_state = acpi_ut_pop_generic_state (&walk_state->control_state);
+		acpi_ut_delete_generic_state (control_state);
 		break;
 
 
@@ -746,15 +779,12 @@
 			status = AE_CTRL_PENDING;
 		}
 
-
 		/* Pop this control state and free it */
 
-		control_state =
-				acpi_cm_pop_generic_state (&walk_state->control_state);
+		control_state = acpi_ut_pop_generic_state (&walk_state->control_state);
 
 		walk_state->aml_last_while = control_state->control.aml_predicate_start;
-		acpi_cm_delete_generic_state (control_state);
-
+		acpi_ut_delete_generic_state (control_state);
 		break;
 
 
@@ -779,8 +809,7 @@
 			 * an arg or local), resolve it now because it may
 			 * cease to exist at the end of the method.
 			 */
-
-			status = acpi_aml_resolve_to_value (&walk_state->operands [0], walk_state);
+			status = acpi_ex_resolve_to_value (&walk_state->operands [0], walk_state);
 			if (ACPI_FAILURE (status)) {
 				return (status);
 			}
@@ -795,19 +824,24 @@
 		}
 
 		else if ((walk_state->results) &&
-				 (walk_state->results->results.num_results > 0))
-		{
+				 (walk_state->results->results.num_results > 0)) {
 			/*
 			 * The return value has come from a previous calculation.
 			 *
 			 * If value being returned is a Reference (such as
 			 * an arg or local), resolve it now because it may
 			 * cease to exist at the end of the method.
+			 *
+			 * Allow references created by the Index operator to return unchanged.
 			 */
 
-			status = acpi_aml_resolve_to_value (&walk_state->results->results.obj_desc [0], walk_state);
-			if (ACPI_FAILURE (status)) {
-				return (status);
+			if (VALID_DESCRIPTOR_TYPE (walk_state->results->results.obj_desc [0], ACPI_DESC_TYPE_INTERNAL) &&
+				((walk_state->results->results.obj_desc [0])->common.type == INTERNAL_TYPE_REFERENCE) &&
+				((walk_state->results->results.obj_desc [0])->reference.opcode != AML_INDEX_OP)) {
+					status = acpi_ex_resolve_to_value (&walk_state->results->results.obj_desc [0], walk_state);
+					if (ACPI_FAILURE (status)) {
+						return (status);
+					}
 			}
 
 			walk_state->return_desc = walk_state->results->results.obj_desc [0];
@@ -817,7 +851,7 @@
 			/* No return operand */
 
 			if (walk_state->num_operands) {
-				acpi_cm_remove_reference (walk_state->operands [0]);
+				acpi_ut_remove_reference (walk_state->operands [0]);
 			}
 
 			walk_state->operands [0]    = NULL;
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/dispatcher/dsutils.c linux/drivers/acpi/dispatcher/dsutils.c
--- v2.4.5/linux/drivers/acpi/dispatcher/dsutils.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/dispatcher/dsutils.c	Wed Jun 20 17:47:39 2001
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: dsutils - Dispatcher utilities
- *              $Revision: 52 $
+ *              $Revision: 58 $
  *
  ******************************************************************************/
 
@@ -32,7 +32,7 @@
 #include "acnamesp.h"
 #include "acdebug.h"
 
-#define _COMPONENT          PARSER
+#define _COMPONENT          ACPI_DISPATCHER
 	 MODULE_NAME         ("dsutils")
 
 
@@ -93,15 +93,13 @@
 	 * as an operand later.
 	 */
 
-	switch (ACPI_GET_OP_CLASS (parent_info))
-	{
+	switch (ACPI_GET_OP_CLASS (parent_info)) {
 	/*
 	 * In these cases, the parent will never use the return object
 	 */
 	case OPTYPE_CONTROL:        /* IF, ELSE, WHILE only */
 
-		switch (op->parent->opcode)
-		{
+		switch (op->parent->opcode) {
 		case AML_RETURN_OP:
 
 			/* Never delete the return value associated with a return opcode */
@@ -118,8 +116,7 @@
 			 */
 
 			if ((walk_state->control_state->common.state == CONTROL_PREDICATE_EXECUTING) &&
-				(walk_state->control_state->control.predicate_op == op))
-			{
+				(walk_state->control_state->control.predicate_op == op)) {
 				return (TRUE);
 			}
 
@@ -136,14 +133,13 @@
 		 * These opcodes allow Term_arg(s) as operands and therefore
 		 * method calls.  The result is used.
 		 */
-		if ((op->parent->opcode == AML_REGION_OP)       ||
-			(op->parent->opcode == AML_CREATE_FIELD_OP) ||
-			(op->parent->opcode == AML_BIT_FIELD_OP)    ||
-			(op->parent->opcode == AML_BYTE_FIELD_OP)   ||
-			(op->parent->opcode == AML_WORD_FIELD_OP)   ||
-			(op->parent->opcode == AML_DWORD_FIELD_OP)  ||
-			(op->parent->opcode == AML_QWORD_FIELD_OP))
-		{
+		if ((op->parent->opcode == AML_REGION_OP)               ||
+			(op->parent->opcode == AML_CREATE_FIELD_OP)         ||
+			(op->parent->opcode == AML_CREATE_BIT_FIELD_OP)     ||
+			(op->parent->opcode == AML_CREATE_BYTE_FIELD_OP)    ||
+			(op->parent->opcode == AML_CREATE_WORD_FIELD_OP)    ||
+			(op->parent->opcode == AML_CREATE_DWORD_FIELD_OP)   ||
+			(op->parent->opcode == AML_CREATE_QWORD_FIELD_OP)) {
 			return (TRUE);
 		}
 
@@ -206,7 +202,7 @@
 
 		status = acpi_ds_result_pop (&obj_desc, walk_state);
 		if (ACPI_SUCCESS (status)) {
-			acpi_cm_remove_reference (result_obj);
+			acpi_ut_remove_reference (result_obj);
 		}
 	}
 
@@ -239,7 +235,7 @@
 	ACPI_STATUS             status = AE_OK;
 	NATIVE_CHAR             *name_string;
 	u32                     name_length;
-	OBJECT_TYPE_INTERNAL    data_type;
+	ACPI_OBJECT_TYPE8       data_type;
 	ACPI_OPERAND_OBJECT     *obj_desc;
 	ACPI_PARSE_OBJECT       *parent_op;
 	u16                     opcode;
@@ -249,15 +245,12 @@
 
 	/* A valid name must be looked up in the namespace */
 
-	if ((arg->opcode == AML_NAMEPATH_OP) &&
-		(arg->value.string))
-	{
+	if ((arg->opcode == AML_INT_NAMEPATH_OP) &&
+		(arg->value.string)) {
 		/* Get the entire name string from the AML stream */
 
-		status = acpi_aml_get_name_string (ACPI_TYPE_ANY,
-				   arg->value.buffer,
-				   &name_string,
-				   &name_length);
+		status = acpi_ex_get_name_string (ACPI_TYPE_ANY, arg->value.buffer,
+				  &name_string, &name_length);
 
 		if (ACPI_FAILURE (status)) {
 			return (status);
@@ -277,10 +270,9 @@
 
 		parent_op = arg->parent;
 		if ((acpi_ps_is_node_op (parent_op->opcode)) &&
-			(parent_op->opcode != AML_METHODCALL_OP) &&
+			(parent_op->opcode != AML_INT_METHODCALL_OP) &&
 			(parent_op->opcode != AML_REGION_OP) &&
-			(parent_op->opcode != AML_NAMEPATH_OP))
-		{
+			(parent_op->opcode != AML_INT_NAMEPATH_OP)) {
 			/* Enter name into namespace if not found */
 
 			interpreter_mode = IMODE_LOAD_PASS2;
@@ -300,7 +292,7 @@
 
 		/* Free the namestring created above */
 
-		acpi_cm_free (name_string);
+		acpi_ut_free (name_string);
 
 		/*
 		 * The only case where we pass through (ignore) a NOT_FOUND
@@ -347,7 +339,7 @@
 	else {
 		/* Check for null name case */
 
-		if (arg->opcode == AML_NAMEPATH_OP) {
+		if (arg->opcode == AML_INT_NAMEPATH_OP) {
 			/*
 			 * If the name is null, this means that this is an
 			 * optional result parameter that was not specified
@@ -381,7 +373,6 @@
 			 * Use value that was already previously returned
 			 * by the evaluation of this argument
 			 */
-
 			status = acpi_ds_result_pop_from_bottom (&obj_desc, walk_state);
 			if (ACPI_FAILURE (status)) {
 				/*
@@ -396,7 +387,7 @@
 		else {
 			/* Create an ACPI_INTERNAL_OBJECT for the argument */
 
-			obj_desc = acpi_cm_create_internal_object (data_type);
+			obj_desc = acpi_ut_create_internal_object (data_type);
 			if (!obj_desc) {
 				return (AE_NO_MEMORY);
 			}
@@ -406,7 +397,7 @@
 			status = acpi_ds_init_object_from_op (walk_state, arg,
 					 opcode, &obj_desc);
 			if (ACPI_FAILURE (status)) {
-				acpi_cm_delete_object_desc (obj_desc);
+				acpi_ut_delete_object_desc (obj_desc);
 				return (status);
 			}
 	   }
@@ -509,11 +500,11 @@
 
 	/*
 	 * TBD: [Investigate] Note from previous parser:
-	 *   Ref_of problem with Acpi_aml_resolve_to_value() conversion.
+	 *   Ref_of problem with Acpi_ex_resolve_to_value() conversion.
 	 */
 
 	for (i = 0; i < walk_state->num_operands; i++) {
-		status = acpi_aml_resolve_to_value (&walk_state->operands[i], walk_state);
+		status = acpi_ex_resolve_to_value (&walk_state->operands[i], walk_state);
 		if (ACPI_FAILURE (status)) {
 			break;
 		}
@@ -538,16 +529,19 @@
  *
  ******************************************************************************/
 
-OBJECT_TYPE_INTERNAL
+ACPI_OBJECT_TYPE8
 acpi_ds_map_opcode_to_data_type (
 	u16                     opcode,
 	u32                     *out_flags)
 {
-	OBJECT_TYPE_INTERNAL    data_type = INTERNAL_TYPE_INVALID;
+	ACPI_OBJECT_TYPE8       data_type = INTERNAL_TYPE_INVALID;
 	ACPI_OPCODE_INFO        *op_info;
 	u32                     flags = 0;
 
 
+	PROC_NAME ("Ds_map_opcode_to_data_type");
+
+
 	op_info = acpi_ps_get_opcode_info (opcode);
 	if (ACPI_GET_OP_TYPE (op_info) != ACPI_OP_TYPE_OPCODE) {
 		/* Unknown opcode */
@@ -555,13 +549,11 @@
 		return (data_type);
 	}
 
-	switch (ACPI_GET_OP_CLASS (op_info))
-	{
+	switch (ACPI_GET_OP_CLASS (op_info)) {
 
 	case OPTYPE_LITERAL:
 
-		switch (opcode)
-		{
+		switch (opcode) {
 		case AML_BYTE_OP:
 		case AML_WORD_OP:
 		case AML_DWORD_OP:
@@ -575,7 +567,7 @@
 			data_type = ACPI_TYPE_STRING;
 			break;
 
-		case AML_NAMEPATH_OP:
+		case AML_INT_NAMEPATH_OP:
 			data_type = INTERNAL_TYPE_REFERENCE;
 			break;
 
@@ -587,8 +579,7 @@
 
 	case OPTYPE_DATA_TERM:
 
-		switch (opcode)
-		{
+		switch (opcode) {
 		case AML_BUFFER_OP:
 
 			data_type = ACPI_TYPE_BUFFER;
@@ -675,17 +666,16 @@
  *
  ******************************************************************************/
 
-OBJECT_TYPE_INTERNAL
+ACPI_OBJECT_TYPE8
 acpi_ds_map_named_opcode_to_data_type (
 	u16                     opcode)
 {
-	OBJECT_TYPE_INTERNAL    data_type;
+	ACPI_OBJECT_TYPE8       data_type;
 
 
 	/* Decode Opcode */
 
-	switch (opcode)
-	{
+	switch (opcode) {
 	case AML_SCOPE_OP:
 		data_type = INTERNAL_TYPE_SCOPE;
 		break;
@@ -710,8 +700,8 @@
 		data_type = ACPI_TYPE_PROCESSOR;
 		break;
 
-	case AML_DEF_FIELD_OP:                          /* Def_field_op */
-		data_type = INTERNAL_TYPE_DEF_FIELD_DEFN;
+	case AML_FIELD_OP:                              /* Field_op */
+		data_type = INTERNAL_TYPE_FIELD_DEFN;
 		break;
 
 	case AML_INDEX_FIELD_OP:                        /* Index_field_op */
@@ -722,12 +712,12 @@
 		data_type = INTERNAL_TYPE_BANK_FIELD_DEFN;
 		break;
 
-	case AML_NAMEDFIELD_OP:                         /* NO CASE IN ORIGINAL  */
+	case AML_INT_NAMEDFIELD_OP:                     /* NO CASE IN ORIGINAL  */
 		data_type = ACPI_TYPE_ANY;
 		break;
 
 	case AML_NAME_OP:                               /* Name_op - special code in original */
-	case AML_NAMEPATH_OP:
+	case AML_INT_NAMEPATH_OP:
 		data_type = ACPI_TYPE_ANY;
 		break;
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/dispatcher/dswexec.c linux/drivers/acpi/dispatcher/dswexec.c
--- v2.4.5/linux/drivers/acpi/dispatcher/dswexec.c	Mon Jan 29 10:15:58 2001
+++ linux/drivers/acpi/dispatcher/dswexec.c	Wed Jun 20 17:47:39 2001
@@ -2,7 +2,7 @@
  *
  * Module Name: dswexec - Dispatcher method execution callbacks;
  *                        dispatch to interpreter.
- *              $Revision: 55 $
+ *              $Revision: 61 $
  *
  *****************************************************************************/
 
@@ -34,7 +34,7 @@
 #include "acdebug.h"
 
 
-#define _COMPONENT          DISPATCHER
+#define _COMPONENT          ACPI_DISPATCHER
 	 MODULE_NAME         ("dswexec")
 
 
@@ -75,7 +75,7 @@
 			return (status);
 		}
 
-		status = acpi_aml_resolve_to_value (&walk_state->operands [0], walk_state);
+		status = acpi_ex_resolve_to_value (&walk_state->operands [0], walk_state);
 		if (ACPI_FAILURE (status)) {
 			return (status);
 		}
@@ -101,7 +101,7 @@
 
 	/* Truncate the predicate to 32-bits if necessary */
 
-	acpi_aml_truncate_for32bit_table (obj_desc, walk_state);
+	acpi_ex_truncate_for32bit_table (obj_desc, walk_state);
 
 	/*
 	 * Save the result of the predicate evaluation on
@@ -134,7 +134,7 @@
 	 * we don't need it anymore)
 	 */
 
-	acpi_cm_remove_reference (obj_desc);
+	acpi_ut_remove_reference (obj_desc);
 
 	walk_state->control_state->common.state = CONTROL_NORMAL;
 
@@ -194,8 +194,7 @@
 
 	if ((walk_state->control_state) &&
 		(walk_state->control_state->common.state ==
-			CONTROL_CONDITIONAL_EXECUTING))
-	{
+			CONTROL_CONDITIONAL_EXECUTING)) {
 		walk_state->control_state->common.state = CONTROL_PREDICATE_EXECUTING;
 
 		/* Save start of predicate */
@@ -208,7 +207,7 @@
 
 	/* We want to send namepaths to the load code */
 
-	if (op->opcode == AML_NAMEPATH_OP) {
+	if (op->opcode == AML_INT_NAMEPATH_OP) {
 		op_info->flags = OPTYPE_NAMED_OBJECT;
 	}
 
@@ -217,8 +216,7 @@
 	 * Handle the opcode based upon the opcode type
 	 */
 
-	switch (ACPI_GET_OP_CLASS (op_info))
-	{
+	switch (ACPI_GET_OP_CLASS (op_info)) {
 	case OPTYPE_CONTROL:
 
 		status = acpi_ds_result_stack_push (walk_state);
@@ -308,11 +306,9 @@
 	u16                     opcode;
 	u8                      optype;
 	ACPI_PARSE_OBJECT       *next_op;
-	ACPI_NAMESPACE_NODE     *node;
 	ACPI_PARSE_OBJECT       *first_arg;
 	ACPI_OPERAND_OBJECT     *result_obj = NULL;
 	ACPI_OPCODE_INFO        *op_info;
-	u32                     operand_index;
 
 
 	opcode = (u16) op->opcode;
@@ -342,8 +338,7 @@
 
 	/* Decode the opcode */
 
-	switch (optype)
-	{
+	switch (optype) {
 	case OPTYPE_UNDEFINED:
 
 		return (AE_NOT_IMPLEMENTED);
@@ -383,9 +378,6 @@
 			goto cleanup;
 		}
 
-		operand_index = walk_state->num_operands - 1;
-
-
 		/* Done with this result state (Now that operand stack is built) */
 
 		status = acpi_ds_result_stack_pop (walk_state);
@@ -393,13 +385,12 @@
 			goto cleanup;
 		}
 
-		switch (optype)
-		{
+		switch (optype) {
 		case OPTYPE_MONADIC1:
 
 			/* 1 Operand, 0 External_result, 0 Internal_result */
 
-			status = acpi_aml_exec_monadic1 (opcode, walk_state);
+			status = acpi_ex_monadic1 (opcode, walk_state);
 			break;
 
 
@@ -407,7 +398,7 @@
 
 			/* 1 Operand, 0 External_result, 1 Internal_result */
 
-			status = acpi_aml_exec_monadic2 (opcode, walk_state, &result_obj);
+			status = acpi_ex_monadic2 (opcode, walk_state, &result_obj);
 			break;
 
 
@@ -415,7 +406,7 @@
 
 			/* 1 Operand, 1 External_result, 1 Internal_result */
 
-			status = acpi_aml_exec_monadic2_r (opcode, walk_state, &result_obj);
+			status = acpi_ex_monadic2_r (opcode, walk_state, &result_obj);
 			break;
 
 
@@ -423,7 +414,7 @@
 
 			/* 2 Operands, 0 External_result, 0 Internal_result */
 
-			status = acpi_aml_exec_dyadic1 (opcode, walk_state);
+			status = acpi_ex_dyadic1 (opcode, walk_state);
 			break;
 
 
@@ -431,7 +422,7 @@
 
 			/* 2 Operands, 0 External_result, 1 Internal_result */
 
-			status = acpi_aml_exec_dyadic2 (opcode, walk_state, &result_obj);
+			status = acpi_ex_dyadic2 (opcode, walk_state, &result_obj);
 			break;
 
 
@@ -439,7 +430,7 @@
 
 			/* 2 Operands, 1 or 2 External_results, 1 Internal_result */
 
-			status = acpi_aml_exec_dyadic2_r (opcode, walk_state, &result_obj);
+			status = acpi_ex_dyadic2_r (opcode, walk_state, &result_obj);
 			break;
 
 
@@ -447,7 +438,7 @@
 
 			/* 2 Operands, 0 External_result, 1 Internal_result */
 
-			status = acpi_aml_exec_dyadic2_s (opcode, walk_state, &result_obj);
+			status = acpi_ex_dyadic2_s (opcode, walk_state, &result_obj);
 			break;
 
 
@@ -455,7 +446,7 @@
 
 			/* 3 Operands, 1 External_result, 1 Internal_result */
 
-			status = acpi_aml_exec_index (walk_state, &result_obj);
+			status = acpi_ex_index (walk_state, &result_obj);
 			break;
 
 
@@ -463,7 +454,7 @@
 
 			/* 6 Operands, 0 External_result, 1 Internal_result */
 
-			status = acpi_aml_exec_match (walk_state, &result_obj);
+			status = acpi_ex_match (walk_state, &result_obj);
 			break;
 
 
@@ -471,7 +462,7 @@
 
 			/* 1 or 2 operands, 0 Internal Result */
 
-			status = acpi_aml_exec_reconfiguration (opcode, walk_state);
+			status = acpi_ex_reconfiguration (opcode, walk_state);
 			break;
 
 
@@ -479,7 +470,7 @@
 
 			/* 3 Operands, 0 External_result, 0 Internal_result */
 
-			status = acpi_aml_exec_fatal (walk_state);
+			status = acpi_ex_fatal (walk_state);
 			break;
 		}
 
@@ -488,8 +479,7 @@
 		 * current result stack
 		 */
 		if (ACPI_SUCCESS (status) &&
-			result_obj)
-		{
+			result_obj) {
 			status = acpi_ds_result_push (result_obj, walk_state);
 		}
 
@@ -515,7 +505,6 @@
 		/* Next_op points to the op that holds the method name */
 
 		next_op = first_arg;
-		node = next_op->node;
 
 		/* Next_op points to first argument op */
 
@@ -562,7 +551,7 @@
 			break;
 		}
 
-		status = acpi_ds_eval_field_unit_operands (walk_state, op);
+		status = acpi_ds_eval_buffer_field_operands (walk_state, op);
 		break;
 
 
@@ -573,8 +562,7 @@
 			break;
 		}
 
-		switch (op->opcode)
-		{
+		switch (op->opcode) {
 		case AML_REGION_OP:
 
 			status = acpi_ds_eval_region_operands (walk_state, op);
@@ -617,7 +605,7 @@
 	 * ACPI 2.0 support for 64-bit integers:
 	 * Truncate numeric result value if we are executing from a 32-bit ACPI table
 	 */
-	acpi_aml_truncate_for32bit_table (result_obj, walk_state);
+	acpi_ex_truncate_for32bit_table (result_obj, walk_state);
 
 	/*
 	 * Check if we just completed the evaluation of a
@@ -627,8 +615,7 @@
 	if ((walk_state->control_state) &&
 		(walk_state->control_state->common.state ==
 			CONTROL_PREDICATE_EXECUTING) &&
-		(walk_state->control_state->control.predicate_op == op))
-	{
+		(walk_state->control_state->control.predicate_op == op)) {
 		status = acpi_ds_get_predicate_value (walk_state, op, (u32) result_obj);
 		result_obj = NULL;
 	}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/dispatcher/dswload.c linux/drivers/acpi/dispatcher/dswload.c
--- v2.4.5/linux/drivers/acpi/dispatcher/dswload.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/dispatcher/dswload.c	Wed Jun 20 17:47:39 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: dswload - Dispatcher namespace load callbacks
- *              $Revision: 26 $
+ *              $Revision: 37 $
  *
  *****************************************************************************/
 
@@ -33,11 +33,11 @@
 #include "acevents.h"
 
 
-#define _COMPONENT          DISPATCHER
+#define _COMPONENT          ACPI_DISPATCHER
 	 MODULE_NAME         ("dswload")
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ds_load1_begin_op
  *
@@ -49,7 +49,7 @@
  *
  * DESCRIPTION: Descending callback used during the loading of ACPI tables.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_ds_load1_begin_op (
@@ -60,10 +60,12 @@
 {
 	ACPI_NAMESPACE_NODE     *node;
 	ACPI_STATUS             status;
-	OBJECT_TYPE_INTERNAL    data_type;
+	ACPI_OBJECT_TYPE8       data_type;
 	NATIVE_CHAR             *path;
 
 
+	PROC_NAME ("Ds_load1_begin_op");
+
 	/* We are only interested in opcodes that have an associated name */
 
 	if (!acpi_ps_is_named_op (opcode)) {
@@ -92,9 +94,8 @@
 	 * as we go downward in the parse tree.  Any necessary subobjects that involve
 	 * arguments to the opcode must be created as we go back up the parse tree later.
 	 */
-	status = acpi_ns_lookup (walk_state->scope_info, path,
-			 data_type, IMODE_LOAD_PASS1,
-			 NS_NO_UPSEARCH, walk_state, &(node));
+	status = acpi_ns_lookup (walk_state->scope_info, path, data_type,
+			  IMODE_LOAD_PASS1, NS_NO_UPSEARCH, walk_state, &(node));
 
 	if (ACPI_FAILURE (status)) {
 		return (status);
@@ -128,7 +129,7 @@
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ds_load1_end_op
  *
@@ -141,16 +142,17 @@
  * DESCRIPTION: Ascending callback used during the loading of the namespace,
  *              both control methods and everything else.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_ds_load1_end_op (
 	ACPI_WALK_STATE         *walk_state,
 	ACPI_PARSE_OBJECT       *op)
 {
-	OBJECT_TYPE_INTERNAL    data_type;
+	ACPI_OBJECT_TYPE8       data_type;
 
 
+	PROC_NAME ("Ds_load1_end_op");
 	/* We are only interested in opcodes that have an associated name */
 
 	if (!acpi_ps_is_named_op (op->opcode)) {
@@ -177,7 +179,6 @@
 	/* Pop the scope stack */
 
 	if (acpi_ns_opens_scope (data_type)) {
-
 		acpi_ds_scope_stack_pop (walk_state);
 	}
 
@@ -186,7 +187,7 @@
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ds_load2_begin_op
  *
@@ -198,7 +199,7 @@
  *
  * DESCRIPTION: Descending callback used during the loading of ACPI tables.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_ds_load2_begin_op (
@@ -209,16 +210,17 @@
 {
 	ACPI_NAMESPACE_NODE     *node;
 	ACPI_STATUS             status;
-	OBJECT_TYPE_INTERNAL    data_type;
+	ACPI_OBJECT_TYPE8       data_type;
 	NATIVE_CHAR             *buffer_ptr;
 	void                    *original = NULL;
 
 
+	PROC_NAME ("Ds_load2_begin_op");
+
 	/* We only care about Namespace opcodes here */
 
 	if (!acpi_ps_is_namespace_op (opcode) &&
-		opcode != AML_NAMEPATH_OP)
-	{
+		opcode != AML_INT_NAMEPATH_OP) {
 		return (AE_OK);
 	}
 
@@ -233,7 +235,7 @@
 		/*
 		 * Get the name we are going to enter or lookup in the namespace
 		 */
-		if (opcode == AML_NAMEPATH_OP) {
+		if (opcode == AML_INT_NAMEPATH_OP) {
 			/* For Namepath op, get the path string */
 
 			buffer_ptr = op->value.string;
@@ -261,15 +263,14 @@
 	data_type = acpi_ds_map_named_opcode_to_data_type (opcode);
 
 
-	if (opcode == AML_DEF_FIELD_OP      ||
+	if (opcode == AML_FIELD_OP          ||
 		opcode == AML_BANK_FIELD_OP     ||
-		opcode == AML_INDEX_FIELD_OP)
-	{
+		opcode == AML_INDEX_FIELD_OP) {
 		node = NULL;
 		status = AE_OK;
 	}
 
-	else if (opcode == AML_NAMEPATH_OP) {
+	else if (opcode == AML_INT_NAMEPATH_OP) {
 		/*
 		 * The Name_path is an object reference to an existing object. Don't enter the
 		 * name into the namespace, but look it up for use later
@@ -302,10 +303,8 @@
 		 * as we go downward in the parse tree.  Any necessary subobjects that involve
 		 * arguments to the opcode must be created as we go back up the parse tree later.
 		 */
-		status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr,
-				 data_type, IMODE_EXECUTE,
-				 NS_NO_UPSEARCH, walk_state,
-				 &(node));
+		status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, data_type,
+				  IMODE_EXECUTE, NS_NO_UPSEARCH, walk_state, &(node));
 	}
 
 	if (ACPI_SUCCESS (status)) {
@@ -332,12 +331,11 @@
 
 	}
 
-
 	return (status);
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ds_load2_end_op
  *
@@ -350,7 +348,7 @@
  * DESCRIPTION: Ascending callback used during the loading of the namespace,
  *              both control methods and everything else.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_ds_load2_end_op (
@@ -358,12 +356,13 @@
 	ACPI_PARSE_OBJECT       *op)
 {
 	ACPI_STATUS             status = AE_OK;
-	OBJECT_TYPE_INTERNAL    data_type;
+	ACPI_OBJECT_TYPE8      data_type;
 	ACPI_NAMESPACE_NODE     *node;
 	ACPI_PARSE_OBJECT       *arg;
 	ACPI_NAMESPACE_NODE     *new_node;
 
 
+	PROC_NAME ("Ds_load2_end_op");
 	if (!acpi_ps_is_namespace_object_op (op->opcode)) {
 		return (AE_OK);
 	}
@@ -422,6 +421,7 @@
 	 * AML_CREATEBYTEFIELD
 	 * AML_CREATEWORDFIELD
 	 * AML_CREATEDWORDFIELD
+	 * AML_CREATEQWORDFIELD
 	 * AML_METHODCALL
 	 */
 
@@ -430,14 +430,14 @@
 
 	arg = op->value.arg;
 
-	switch (op->opcode)
-	{
+	switch (op->opcode) {
 
 	case AML_CREATE_FIELD_OP:
-	case AML_BIT_FIELD_OP:
-	case AML_BYTE_FIELD_OP:
-	case AML_WORD_FIELD_OP:
-	case AML_DWORD_FIELD_OP:
+	case AML_CREATE_BIT_FIELD_OP:
+	case AML_CREATE_BYTE_FIELD_OP:
+	case AML_CREATE_WORD_FIELD_OP:
+	case AML_CREATE_DWORD_FIELD_OP:
+	case AML_CREATE_QWORD_FIELD_OP:
 
 		/*
 		 * Create the field object, but the field buffer and index must
@@ -455,58 +455,59 @@
 			arg = acpi_ps_get_arg (op, 2);
 		}
 
+		if (!arg) {
+			status = AE_AML_NO_OPERAND;
+			goto cleanup;
+		}
+
 		/*
 		 * Enter the Name_string into the namespace
 		 */
-
-		status = acpi_ns_lookup (walk_state->scope_info,
-				 arg->value.string,
-				 INTERNAL_TYPE_DEF_ANY,
-				 IMODE_LOAD_PASS1,
+		status = acpi_ns_lookup (walk_state->scope_info, arg->value.string,
+				 INTERNAL_TYPE_DEF_ANY, IMODE_LOAD_PASS1,
 				 NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
 				 walk_state, &(new_node));
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
 
-		if (ACPI_SUCCESS (status)) {
-			/* We could put the returned object (Node) on the object stack for later, but
-			 * for now, we will put it in the "op" object that the parser uses, so we
-			 * can get it again at the end of this scope
-			 */
-			op->node = new_node;
+		/* We could put the returned object (Node) on the object stack for later, but
+		 * for now, we will put it in the "op" object that the parser uses, so we
+		 * can get it again at the end of this scope
+		 */
+		op->node = new_node;
 
+		/*
+		 * If there is no object attached to the node, this node was just created and
+		 * we need to create the field object.  Otherwise, this was a lookup of an
+		 * existing node and we don't want to create the field object again.
+		 */
+		if (!new_node->object) {
 			/*
-			 * If there is no object attached to the node, this node was just created and
-			 * we need to create the field object.  Otherwise, this was a lookup of an
-			 * existing node and we don't want to create the field object again.
+			 * The Field definition is not fully parsed at this time.
+			 * (We must save the address of the AML for the buffer and index operands)
 			 */
-			if (!new_node->object) {
-				/*
-				 * The Field definition is not fully parsed at this time.
-				 * (We must save the address of the AML for the buffer and index operands)
-				 */
-				status = acpi_aml_exec_create_field (((ACPI_PARSE2_OBJECT *) op)->data,
-						   ((ACPI_PARSE2_OBJECT *) op)->length,
-						   new_node, walk_state);
-			}
+			status = acpi_ex_create_buffer_field (((ACPI_PARSE2_OBJECT *) op)->data,
+					  ((ACPI_PARSE2_OBJECT *) op)->length,
+					  new_node, walk_state);
 		}
-
-
 		break;
 
 
-	case AML_METHODCALL_OP:
+	case AML_INT_METHODCALL_OP:
 
 		/*
 		 * Lookup the method name and save the Node
 		 */
 
 		status = acpi_ns_lookup (walk_state->scope_info, arg->value.string,
-				 ACPI_TYPE_ANY, IMODE_LOAD_PASS2,
-				 NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE,
-				 walk_state, &(new_node));
+				  ACPI_TYPE_ANY, IMODE_LOAD_PASS2,
+				  NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE,
+				  walk_state, &(new_node));
 
 		if (ACPI_SUCCESS (status)) {
 
-/* has name already been resolved by here ??*/
+			/* TBD: has name already been resolved by here ??*/
 
 			/* TBD: [Restructure] Make sure that what we found is indeed a method! */
 			/* We didn't search for a method on purpose, to see if the name would resolve! */
@@ -526,7 +527,7 @@
 
 		/* Nothing to do other than enter object into namespace */
 
-		status = acpi_aml_exec_create_processor (op, (ACPI_HANDLE) node);
+		status = acpi_ex_create_processor (op, node);
 		if (ACPI_FAILURE (status)) {
 			goto cleanup;
 		}
@@ -538,7 +539,7 @@
 
 		/* Nothing to do other than enter object into namespace */
 
-		status = acpi_aml_exec_create_power_resource (op, (ACPI_HANDLE) node);
+		status = acpi_ex_create_power_resource (op, node);
 		if (ACPI_FAILURE (status)) {
 			goto cleanup;
 		}
@@ -553,13 +554,11 @@
 		break;
 
 
-	case AML_DEF_FIELD_OP:
+	case AML_FIELD_OP:
 
 		arg = op->value.arg;
 
-		status = acpi_ds_create_field (op,
-				  arg->node,
-				  walk_state);
+		status = acpi_ds_create_field (op, arg->node, walk_state);
 		break;
 
 
@@ -567,8 +566,7 @@
 
 		arg = op->value.arg;
 
-		status = acpi_ds_create_index_field (op,
-				   (ACPI_HANDLE) arg->node,
+		status = acpi_ds_create_index_field (op, (ACPI_HANDLE) arg->node,
 				   walk_state);
 		break;
 
@@ -576,9 +574,7 @@
 	case AML_BANK_FIELD_OP:
 
 		arg = op->value.arg;
-		status = acpi_ds_create_bank_field (op,
-				   arg->node,
-				   walk_state);
+		status = acpi_ds_create_bank_field (op, arg->node, walk_state);
 		break;
 
 
@@ -588,11 +584,10 @@
 	case AML_METHOD_OP:
 
 		if (!node->object) {
-			status = acpi_aml_exec_create_method (((ACPI_PARSE2_OBJECT *) op)->data,
+			status = acpi_ex_create_method (((ACPI_PARSE2_OBJECT *) op)->data,
 					   ((ACPI_PARSE2_OBJECT *) op)->length,
-					   arg->value.integer, (ACPI_HANDLE) node);
+					   arg->value.integer, node);
 		}
-
 		break;
 
 
@@ -603,7 +598,7 @@
 			goto cleanup;
 		}
 
-		status = acpi_aml_exec_create_mutex (walk_state);
+		status = acpi_ex_create_mutex (walk_state);
 		break;
 
 
@@ -614,7 +609,7 @@
 			goto cleanup;
 		}
 
-		status = acpi_aml_exec_create_event (walk_state);
+		status = acpi_ex_create_event (walk_state);
 		break;
 
 
@@ -624,16 +619,13 @@
 			break;
 		}
 
-
 		/*
 		 * The Op_region is not fully parsed at this time. Only valid argument is the Space_id.
 		 * (We must save the address of the AML of the address and length operands)
 		 */
-
-		status = acpi_aml_exec_create_region (((ACPI_PARSE2_OBJECT *) op)->data,
-				   ((ACPI_PARSE2_OBJECT *) op)->length,
-				   (ACPI_ADDRESS_SPACE_TYPE) arg->value.integer,
-				   walk_state);
+		status = acpi_ex_create_region (((ACPI_PARSE2_OBJECT *) op)->data,
+				  ((ACPI_PARSE2_OBJECT *) op)->length,
+						 (ACPI_ADR_SPACE_TYPE) arg->value.integer, walk_state);
 
 		break;
 
@@ -647,7 +639,7 @@
 			goto cleanup;
 		}
 
-		status = acpi_aml_exec_create_alias (walk_state);
+		status = acpi_ex_create_alias (walk_state);
 		break;
 
 
@@ -666,7 +658,7 @@
 		break;
 
 
-	case AML_NAMEPATH_OP:
+	case AML_INT_NAMEPATH_OP:
 
 		break;
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/dispatcher/dswscope.c linux/drivers/acpi/dispatcher/dswscope.c
--- v2.4.5/linux/drivers/acpi/dispatcher/dswscope.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/dispatcher/dswscope.c	Wed Jun 20 17:47:39 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: dswscope - Scope stack manipulation
- *              $Revision: 42 $
+ *              $Revision: 45 $
  *
  *****************************************************************************/
 
@@ -29,7 +29,7 @@
 #include "acdispat.h"
 
 
-#define _COMPONENT          NAMESPACE
+#define _COMPONENT          ACPI_DISPATCHER
 	 MODULE_NAME         ("dswscope")
 
 
@@ -60,7 +60,7 @@
 		scope_info = walk_state->scope_info;
 		walk_state->scope_info = scope_info->scope.next;
 
-		acpi_cm_delete_generic_state (scope_info);
+		acpi_ut_delete_generic_state (scope_info);
 	}
 }
 
@@ -80,7 +80,7 @@
 ACPI_STATUS
 acpi_ds_scope_stack_push (
 	ACPI_NAMESPACE_NODE     *node,
-	OBJECT_TYPE_INTERNAL    type,
+	ACPI_OBJECT_TYPE8       type,
 	ACPI_WALK_STATE         *walk_state)
 {
 	ACPI_GENERIC_STATE      *scope_info;
@@ -95,14 +95,14 @@
 
 	/* Make sure object type is valid */
 
-	if (!acpi_aml_validate_object_type (type)) {
+	if (!acpi_ex_validate_object_type (type)) {
 		REPORT_WARNING (("Ds_scope_stack_push: type code out of range\n"));
 	}
 
 
 	/* Allocate a new scope object */
 
-	scope_info = acpi_cm_create_generic_state ();
+	scope_info = acpi_ut_create_generic_state ();
 	if (!scope_info) {
 		return (AE_NO_MEMORY);
 	}
@@ -114,7 +114,7 @@
 
 	/* Push new scope object onto stack */
 
-	acpi_cm_push_generic_state (&walk_state->scope_info, scope_info);
+	acpi_ut_push_generic_state (&walk_state->scope_info, scope_info);
 
 	return (AE_OK);
 }
@@ -148,12 +148,12 @@
 	 * Pop scope info object off the stack.
 	 */
 
-	scope_info = acpi_cm_pop_generic_state (&walk_state->scope_info);
+	scope_info = acpi_ut_pop_generic_state (&walk_state->scope_info);
 	if (!scope_info) {
 		return (AE_STACK_UNDERFLOW);
 	}
 
-	acpi_cm_delete_generic_state (scope_info);
+	acpi_ut_delete_generic_state (scope_info);
 
 	return (AE_OK);
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/dispatcher/dswstate.c linux/drivers/acpi/dispatcher/dswstate.c
--- v2.4.5/linux/drivers/acpi/dispatcher/dswstate.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/dispatcher/dswstate.c	Wed Jun 20 17:47:39 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: dswstate - Dispatcher parse tree walk management routines
- *              $Revision: 38 $
+ *              $Revision: 45 $
  *
  *****************************************************************************/
 
@@ -31,7 +31,7 @@
 #include "acnamesp.h"
 #include "acinterp.h"
 
-#define _COMPONENT          DISPATCHER
+#define _COMPONENT          ACPI_DISPATCHER
 	 MODULE_NAME         ("dswstate")
 
 
@@ -57,6 +57,9 @@
 	ACPI_GENERIC_STATE      *state;
 
 
+	PROC_NAME ("Ds_result_insert");
+
+
 	state = walk_state->results;
 	if (!state) {
 		return (AE_NOT_EXIST);
@@ -100,6 +103,9 @@
 	ACPI_GENERIC_STATE      *state;
 
 
+	PROC_NAME ("Ds_result_remove");
+
+
 	state = walk_state->results;
 	if (!state) {
 		return (AE_NOT_EXIST);
@@ -147,6 +153,9 @@
 	ACPI_GENERIC_STATE      *state;
 
 
+	PROC_NAME ("Ds_result_pop");
+
+
 	state = walk_state->results;
 	if (!state) {
 		return (AE_OK);
@@ -199,6 +208,9 @@
 	ACPI_GENERIC_STATE      *state;
 
 
+	PROC_NAME ("Ds_result_pop_from_bottom");
+
+
 	state = walk_state->results;
 	if (!state) {
 		return (AE_NOT_EXIST);
@@ -254,6 +266,9 @@
 	ACPI_GENERIC_STATE      *state;
 
 
+	PROC_NAME ("Ds_result_push");
+
+
 	state = walk_state->results;
 	if (!state) {
 		return (AE_AML_INTERNAL);
@@ -295,12 +310,12 @@
 	ACPI_GENERIC_STATE      *state;
 
 
-	state = acpi_cm_create_generic_state ();
+	state = acpi_ut_create_generic_state ();
 	if (!state) {
 		return (AE_NO_MEMORY);
 	}
 
-	acpi_cm_push_generic_state (&walk_state->results, state);
+	acpi_ut_push_generic_state (&walk_state->results, state);
 
 	return (AE_OK);
 }
@@ -332,9 +347,9 @@
 	}
 
 
-	state = acpi_cm_pop_generic_state (&walk_state->results);
+	state = acpi_ut_pop_generic_state (&walk_state->results);
 
-	acpi_cm_delete_generic_state (state);
+	acpi_ut_delete_generic_state (state);
 
 	return (AE_OK);
 }
@@ -364,7 +379,7 @@
 
 	for (i = 0; i < OBJ_NUM_OPERANDS; i++) {
 		if (walk_state->operands[i]) {
-			acpi_cm_remove_reference (walk_state->operands[i]);
+			acpi_ut_remove_reference (walk_state->operands[i]);
 			walk_state->operands[i] = NULL;
 		}
 	}
@@ -432,10 +447,10 @@
 	/* Check for stack underflow */
 
 	if (walk_state->num_operands == 0) {
+		*object = NULL;
 		return (AE_AML_NO_OPERAND);
 	}
 
-
 	/* Pop the stack */
 
 	walk_state->num_operands--;
@@ -443,6 +458,7 @@
 	/* Check for a valid operand */
 
 	if (!walk_state->operands [walk_state->num_operands]) {
+		*object = NULL;
 		return (AE_AML_NO_OPERAND);
 	}
 
@@ -529,7 +545,7 @@
 		walk_state->num_operands--;
 		obj_desc = walk_state->operands [walk_state->num_operands];
 		if (obj_desc) {
-			acpi_cm_remove_reference (walk_state->operands [walk_state->num_operands]);
+			acpi_ut_remove_reference (walk_state->operands [walk_state->num_operands]);
 			walk_state->operands [walk_state->num_operands] = NULL;
 		}
 	}
@@ -696,7 +712,7 @@
 	ACPI_STATUS             status;
 
 
-	acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
+	acpi_ut_acquire_mutex (ACPI_MTX_CACHES);
 	acpi_gbl_walk_state_cache_requests++;
 
 	/* Check the cache first */
@@ -710,17 +726,17 @@
 		acpi_gbl_walk_state_cache_hits++;
 		acpi_gbl_walk_state_cache_depth--;
 
-		acpi_cm_release_mutex (ACPI_MTX_CACHES);
+		acpi_ut_release_mutex (ACPI_MTX_CACHES);
 	}
 
 	else {
 		/* The cache is empty, create a new object */
 
-		/* Avoid deadlock with Acpi_cm_callocate */
+		/* Avoid deadlock with Acpi_ut_callocate */
 
-		acpi_cm_release_mutex (ACPI_MTX_CACHES);
+		acpi_ut_release_mutex (ACPI_MTX_CACHES);
 
-		walk_state = acpi_cm_callocate (sizeof (ACPI_WALK_STATE));
+		walk_state = acpi_ut_callocate (sizeof (ACPI_WALK_STATE));
 		if (!walk_state) {
 			return (NULL);
 		}
@@ -730,6 +746,7 @@
 	walk_state->owner_id        = owner_id;
 	walk_state->origin          = origin;
 	walk_state->method_desc     = mth_desc;
+	walk_state->walk_list       = walk_list;
 
 	/* Init the method args/local */
 
@@ -787,7 +804,7 @@
 		state = walk_state->control_state;
 		walk_state->control_state = state->common.next;
 
-		acpi_cm_delete_generic_state (state);
+		acpi_ut_delete_generic_state (state);
 	}
 
 	/* Always must free any linked parse states */
@@ -796,7 +813,7 @@
 		state = walk_state->scope_info;
 		walk_state->scope_info = state->common.next;
 
-		acpi_cm_delete_generic_state (state);
+		acpi_ut_delete_generic_state (state);
 	}
 
 	/* Always must free any stacked result states */
@@ -805,20 +822,20 @@
 		state = walk_state->results;
 		walk_state->results = state->common.next;
 
-		acpi_cm_delete_generic_state (state);
+		acpi_ut_delete_generic_state (state);
 	}
 
 
 	/* If walk cache is full, just free this wallkstate object */
 
 	if (acpi_gbl_walk_state_cache_depth >= MAX_WALK_CACHE_DEPTH) {
-		acpi_cm_free (walk_state);
+		acpi_ut_free (walk_state);
 	}
 
 	/* Otherwise put this object back into the cache */
 
 	else {
-		acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
+		acpi_ut_acquire_mutex (ACPI_MTX_CACHES);
 
 		/* Clear the state */
 
@@ -832,7 +849,7 @@
 		acpi_gbl_walk_state_cache_depth++;
 
 
-		acpi_cm_release_mutex (ACPI_MTX_CACHES);
+		acpi_ut_release_mutex (ACPI_MTX_CACHES);
 	}
 
 	return;
@@ -865,7 +882,7 @@
 		/* Delete one cached state object */
 
 		next = acpi_gbl_walk_state_cache->next;
-		acpi_cm_free (acpi_gbl_walk_state_cache);
+		acpi_ut_free (acpi_gbl_walk_state_cache);
 		acpi_gbl_walk_state_cache = next;
 		acpi_gbl_walk_state_cache_depth--;
 	}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/driver.c linux/drivers/acpi/driver.c
--- v2.4.5/linux/drivers/acpi/driver.c	Tue May 22 09:38:51 2001
+++ linux/drivers/acpi/driver.c	Wed Jun 20 17:47:39 2001
@@ -2,6 +2,7 @@
  *  driver.c - ACPI driver
  *
  *  Copyright (C) 2000 Andrew Henroid
+ *  Copyright (C) 2001 Andrew Grover
  *
  *  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
@@ -21,6 +22,10 @@
  * Changes
  * David Woodhouse <dwmw2@redhat.com> 2000-12-6
  * - Fix interruptible_sleep_on() races
+ * Andrew Grover <andrew.grover@intel.com> 2001-2-28
+ * - Major revamping
+ * Peter Breuer <ptb@it.uc3m.es> 2001-5-20
+ * - parse boot time params.
  */
 
 #include <linux/config.h>
@@ -39,416 +44,44 @@
 
 #ifdef CONFIG_ACPI_KERNEL_CONFIG
 #include <asm/efi.h>
-#define ACPI_CAN_USE_EFI_STRUCT
+#define ACPI_USE_EFI
 #endif
 
 
 #define _COMPONENT	OS_DEPENDENT
 	MODULE_NAME	("driver")
 
-struct acpi_run_entry
-{
-	void (*callback)(void*);
-	void *context;
-	struct tq_struct task;
-};
-
-static spinlock_t acpi_event_lock = SPIN_LOCK_UNLOCKED;
-static volatile u32 acpi_event_status = 0;
-static volatile acpi_sstate_t acpi_event_state = ACPI_STATE_S0;
-static DECLARE_WAIT_QUEUE_HEAD(acpi_event_wait);
-
-static volatile int acpi_thread_pid = -1;
-
-static int acpi_start = 1;
-
-/************************************************/
-/* DECLARE_TASK_QUEUE is defined in             */
-/* /usr/src/linux/include/linux/tqueue.h        */
-/* So, acpi_thread_run is a pointer to a        */
-/* tq_struct structure,defined in the same file.*/
-/************************************************/
-static DECLARE_TASK_QUEUE(acpi_thread_run);
-
-static DECLARE_WAIT_QUEUE_HEAD(acpi_thread_wait);
-
-static struct ctl_table_header *acpi_sysctl = NULL;
-
-/*
- * Examine/modify value
- */
-static int 
-acpi_do_ulong(ctl_table * ctl,
-	      int write,
-	      struct file *file,
-	      void *buffer,
-	      size_t * len)
-{
-	char str[2 * sizeof(unsigned long) + 4], *strend;
-	unsigned long val;
-	int size;
-
-	if (!write) {
-		if (file->f_pos) {
-			*len = 0;
-			return 0;
-		}
-
-		val = *(unsigned long *) ctl->data;
-		size = sprintf(str, "0x%08lx\n", val);
-		if (*len >= size) {
-			copy_to_user(buffer, str, size);
-			*len = size;
-		}
-		else
-			*len = 0;
-	}
-	else {
-		size = sizeof(str) - 1;
-		if (size > *len)
-			size = *len;
-		copy_from_user(str, buffer, size);
-		str[size] = '\0';
-		val = simple_strtoul(str, &strend, 0);
-		if (strend == str)
-			return -EINVAL;
-		*(unsigned long *) ctl->data = val;
-	}
-
-	file->f_pos += *len;
-	return 0;
-}
-
-static int 
-acpi_do_pm_timer(ctl_table * ctl,
-	      int write,
-	      struct file *file,
-	      void *buffer,
-	      size_t * len)
-{
-	int size;
-	u32 val = 0;
-
-	char str[12];
-
-	if (file->f_pos) {
-		*len = 0;
-		return 0;
-	}
-
-	val = acpi_read_pm_timer();
-
-	size = sprintf(str, "0x%08x\n", val);
-	if (*len >= size) {
-		copy_to_user(buffer, str, size);
-		*len = size;
-	}
-	else
-		*len = 0;
-
-	file->f_pos += *len;
-
-	return 0;
-}
-
-/*
- * Handle ACPI event
- */
-static u32
-acpi_event(void *context)
-{
-	unsigned long flags;
-	int event = (int)(long)context;
-	int mask = 0;
-
-	switch (event) {
-	case ACPI_EVENT_POWER_BUTTON:
-		mask = ACPI_PWRBTN;
-		break;
-	case ACPI_EVENT_SLEEP_BUTTON:
-		mask = ACPI_SLPBTN;
-		break;
-	default:
-		return AE_ERROR;
-	}
-
-	if (mask) {
-		// notify process waiting on /dev/acpi
-		spin_lock_irqsave(&acpi_event_lock, flags);
-		acpi_event_status |= mask;
-		spin_unlock_irqrestore(&acpi_event_lock, flags);
-		acpi_event_state = acpi_sleep_state;
-		wake_up_interruptible(&acpi_event_wait);
-	}
-
-	return AE_OK;
-}
-
-/*
- * Wait for next event
- */
-static int
-acpi_do_event(ctl_table * ctl,
-	      int write,
-	      struct file *file,
-	      void *buffer,
-	      size_t * len)
-{
-	u32 event_status = 0;
-	acpi_sstate_t event_state = 0;
-	char str[27];
-	int size;
-
-	if (write)
-		return -EPERM;
-	if (*len < sizeof(str)) {
-		*len = 0;
-		return 0;
-	}
-
-	while (!event_status) {
-		unsigned long flags;
-		DECLARE_WAITQUEUE(wait, current);
-
-		set_current_state(TASK_INTERRUPTIBLE);
-		add_wait_queue(&acpi_event_wait, &wait);
-
-		// we need an atomic exchange here
-		spin_lock_irqsave(&acpi_event_lock, flags);
-		event_status = acpi_event_status;
-		acpi_event_status = 0;
-		spin_unlock_irqrestore(&acpi_event_lock, flags);
-		event_state = acpi_event_state;
-
-		if (!event_status)
-			schedule();
-
-		remove_wait_queue(&acpi_event_wait, &wait);
-		set_current_state(TASK_RUNNING);
-
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-	}
-
-	size = sprintf(str,
-		       "0x%08x 0x%08x 0x%01x\n",
-		       event_status,
-		       0,
-		       event_state);
-	copy_to_user(buffer, str, size);
-	*len = size;
-	file->f_pos += size;
-
-	return 0;
-}
-
-/*
- * Enter system sleep state
- */
-/*static int 
-acpi_do_sleep(ctl_table * ctl,
-	      int write,
-	      struct file *file,
-	      void *buffer,
-	      size_t * len)
-{
-	if (!write) {
-		if (file->f_pos) {
-			*len = 0;
-			return 0;
-		}
-	}
-	else {
-		int status = acpi_enter_sx(ACPI_STATE_S1);
-		if (status)
-			return status;
-	}
-	file->f_pos += *len;
-	return 0;
-}*/
-
-
-/*
- * Output important ACPI tables to proc
- */
-static int 
-acpi_do_table(ctl_table * ctl,
-	      int write,
-	      struct file *file,
-	      void *buffer,
-	      size_t * len)
-{
-	u32 table_type;
-	size_t size;
-	ACPI_BUFFER buf;
-	u8* data;
-
-	table_type = (u32) ctl->data;
-	size = 0;
-	buf.length = 0;
-	buf.pointer = NULL;
-
-	/* determine what buffer size we will need */
-	if (acpi_get_table(table_type, 1, &buf) != AE_BUFFER_OVERFLOW) {
-		*len = 0;
-		return 0;
-	}
-
-	buf.pointer = kmalloc(buf.length, GFP_KERNEL);
-	if (!buf.pointer) {
-		return -ENOMEM;
-	}
-
-	/* get the table for real */
-	if (!ACPI_SUCCESS(acpi_get_table(table_type, 1, &buf))) {
-		kfree(buf.pointer);
-		*len = 0;
-		return 0;
-	}
-
-	if (file->f_pos < buf.length) {
-		data = buf.pointer + file->f_pos;
-		size = buf.length - file->f_pos;
-		if (size > *len)
-			size = *len;
-		if (copy_to_user(buffer, data, size)) {
-			kfree(buf.pointer);
-			return -EFAULT;
-		}
-	}
+FADT_DESCRIPTOR acpi_fadt;
 
-	kfree(buf.pointer);
-
-	*len = size;
-	file->f_pos += size;
-	return 0;
-}
-
-/********************************************************************/
-/*              R U N    Q U E U E D   C A L L B A C K              */
-/*                                                                  */
-/* The "callback" function address that was tramped through via     */
-/* "acpi_run" below is finally called and executed. If we trace all */
-/* this down, the function is acpi_ev_asynch_execute_gpe_method, in */ 
-/* evevent.c   The only other function that is ever queued is       */
-/* acpi_ev_global_lock_thread in evmisc.c.                          */
-/********************************************************************/
-static void
-acpi_run_exec(void *context)
-{
-	struct acpi_run_entry *entry
-		= (struct acpi_run_entry*) context;
-	(*entry->callback)(entry->context);
-	kfree(entry);
-}
+static int acpi_disabled = 0;
 
 /*
- * Queue for execution by the ACPI thread
+ * Start the interpreter
  */
 int
-acpi_run(void (*callback)(void*), void *context)
-{
-	struct acpi_run_entry *entry;
-
-	entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
-	if (!entry)
-		return -1;
-
-	memset(entry, 0, sizeof(entry));
-	entry->callback = callback;
-	entry->context = context;
-	entry->task.routine = acpi_run_exec;
-	entry->task.data = entry;
-
-	queue_task(&entry->task, &acpi_thread_run);
-
-	if (waitqueue_active(&acpi_thread_wait))
-		wake_up(&acpi_thread_wait);
-
-	return 0;
-}
-
-static struct ctl_table acpi_table[] =
-{
-	{ACPI_P_LVL2_LAT, "c2_exit_latency",
-	 &acpi_c2_exit_latency, sizeof(acpi_c2_exit_latency),
-	 0644, NULL, &acpi_do_ulong},
-
-	{ACPI_ENTER_LVL2_LAT, "c2_enter_latency",
-	 &acpi_c2_enter_latency, sizeof(acpi_c2_enter_latency),
-	 0644, NULL, &acpi_do_ulong},
-
-	{ACPI_P_LVL3_LAT, "c3_exit_latency",
-	 &acpi_c3_exit_latency, sizeof(acpi_c3_exit_latency),
-	 0644, NULL, &acpi_do_ulong},
-
-	{ACPI_ENTER_LVL3_LAT, "c3_enter_latency",
-	 &acpi_c3_enter_latency, sizeof(acpi_c3_enter_latency),
-	 0644, NULL, &acpi_do_ulong},
-
-	{ACPI_C1_COUNT, "c1_count",
-	 &acpi_c1_count, sizeof(acpi_c1_count),
-	 0644, NULL, &acpi_do_ulong},
-
-	{ACPI_C2_COUNT, "c2_count",
-	 &acpi_c2_count, sizeof(acpi_c2_count),
-	 0644, NULL, &acpi_do_ulong},
-
-	{ACPI_C3_COUNT, "c3_count",
-	 &acpi_c3_count, sizeof(acpi_c3_count),
-	 0644, NULL, &acpi_do_ulong},
-
-	
-/* until it actually works */
-/*	{ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &acpi_do_sleep},*/
-
-	{ACPI_EVENT, "event", NULL, 0, 0400, NULL, &acpi_do_event},
-
-	{ACPI_FADT, "fadt", (void *) ACPI_TABLE_FADT, sizeof(int),
-	 0444, NULL, &acpi_do_table},
-	
-	{ACPI_DSDT, "dsdt", (void *) ACPI_TABLE_DSDT, sizeof(int),
-	 0444, NULL, &acpi_do_table},
-
-	{ACPI_FACS, "facs", (void *) ACPI_TABLE_FACS, sizeof(int),
-	 0444, NULL, &acpi_do_table},
-
-	{ACPI_XSDT, "xsdt", (void *) ACPI_TABLE_XSDT, sizeof(int),
-	 0444, NULL, &acpi_do_table},
-
-	{ACPI_PMTIMER, "pm_timer", NULL, 0, 0444, NULL, &acpi_do_pm_timer},
-	
-	{0}
-};
-
-static struct ctl_table acpi_dir_table[] =
-{
-	{CTL_ACPI, "acpi", NULL, 0, 0555, acpi_table},
-	{0}
-};
-
-/*
- * Initialize and run interpreter within a kernel thread
- */
-static int
-acpi_thread(void *context)
+acpi_init(void)
 {
 	ACPI_PHYSICAL_ADDRESS	rsdp_phys;
 	ACPI_BUFFER		buffer;
 	ACPI_SYSTEM_INFO	sys_info;
 
-	/*
-	 * initialize
-	 */
-	daemonize();
-	strcpy(current->comm, "kacpid");
+	if (PM_IS_ACTIVE()) {
+		printk(KERN_NOTICE "ACPI: APM is already active, exiting\n");
+		return -ENODEV;
+	}
+
+
+	if (acpi_disabled) {
+		printk(KERN_NOTICE "ACPI: disabled by cmdline, exiting\n");
+		return -ENODEV;
+	}
 
 	if (!ACPI_SUCCESS(acpi_initialize_subsystem())) {
 		printk(KERN_ERR "ACPI: Driver initialization failed\n");
 		return -ENODEV;
 	}
 
-#ifndef ACPI_CAN_USE_EFI_STRUCT
+#ifndef ACPI_USE_EFI
 	if (!ACPI_SUCCESS(acpi_find_root_pointer(&rsdp_phys))) {
 		printk(KERN_ERR "ACPI: System description tables not found\n");
 		return -ENODEV;
@@ -456,12 +89,22 @@
 #else
 	rsdp_phys = efi.acpi;
 #endif
-		
-	if (!ACPI_SUCCESS(acpi_find_and_load_tables(rsdp_phys)))
+
+	/* from this point on, on error we must call acpi_terminate() */
+
+	if (!ACPI_SUCCESS(acpi_load_tables(rsdp_phys))) {
+		printk(KERN_ERR "ACPI: System description table load failed\n");
+		acpi_terminate();
 		return -ENODEV;
+	}
 
-	if (PM_IS_ACTIVE()) {
-		printk(KERN_NOTICE "ACPI: APM is already active, exiting\n");
+	/* get a separate copy of the FADT for use by other drivers */
+	memset(&acpi_fadt, 0, sizeof(acpi_fadt));
+	buffer.pointer = &acpi_fadt;
+	buffer.length = sizeof(acpi_fadt);
+
+	if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_FADT, 1, &buffer))) {
+		printk(KERN_ERR "ACPI: Could not get FADT\n");
 		acpi_terminate();
 		return -ENODEV;
 	}
@@ -483,129 +126,37 @@
 		return -ENODEV;
 	}
 
-	printk(KERN_ERR "ACPI: Subsystem enabled\n");
+	printk(KERN_INFO "ACPI: Subsystem enabled\n");
 
 	pm_active = 1;
 
-	acpi_cpu_init();
-	acpi_sys_init();
-	acpi_ec_init();
-	acpi_power_init();
-
-	/* 
-	 * Non-intuitive: 0 means pwr and sleep are implemented using the fixed
-	 * feature model, so we install handlers. 1 means a control method
-	 * implementation, or none at all, so do nothing. See ACPI spec.
-	 */
-	if (acpi_fadt.pwr_button == 0) {
-		if (!ACPI_SUCCESS(acpi_install_fixed_event_handler(
-			ACPI_EVENT_POWER_BUTTON,
-			acpi_event,
-			(void *) ACPI_EVENT_POWER_BUTTON))) {
-			printk(KERN_ERR "ACPI: power button enable failed\n");
-		}
-	}
-
-	if (acpi_fadt.sleep_button == 0) {
-		if (!ACPI_SUCCESS(acpi_install_fixed_event_handler(
-			ACPI_EVENT_SLEEP_BUTTON,
-			acpi_event,
-			(void *) ACPI_EVENT_SLEEP_BUTTON))) {
-			printk(KERN_ERR "ACPI: sleep button enable failed\n");
-		}
-	}
-
-	acpi_sysctl = register_sysctl_table(acpi_dir_table, 1);
-
-	/*
-	 * run
-	 */
-	for (;;) {
-		DECLARE_WAITQUEUE(wait, current);
-
-		set_current_state(TASK_INTERRUPTIBLE);
-		add_wait_queue(&acpi_thread_wait, &wait);
-
-		if (list_empty(&acpi_thread_run))
-			schedule();
-
-		remove_wait_queue(&acpi_thread_wait, &wait);
-		set_current_state(TASK_RUNNING);
-
-		if (signal_pending(current))
-			break;
-
-		run_task_queue(&acpi_thread_run);
-	}
-
-	/*
-	 * terminate
-	 */
-	unregister_sysctl_table(acpi_sysctl);
-
-	/* do not terminate, because we need acpi in order to shut down */
-	/*acpi_terminate();*/
-
-	acpi_thread_pid = -1;
-
 	return 0;
 }
 
 /*
- * Start the interpreter
- */
-int __init
-acpi_init(void)
-{
-	if (acpi_start) {
-		acpi_thread_pid = kernel_thread(acpi_thread,
-					NULL,
-					(CLONE_FS | CLONE_FILES
-					 | CLONE_SIGHAND | SIGCHLD));
-	}
-	else {
-		printk(KERN_INFO "ACPI: Disabled\n");
-	}
-
-	return ((acpi_thread_pid >= 0) ? 0:-ENODEV);
-}
-
-/*
  * Terminate the interpreter
  */
-void __exit
+void
 acpi_exit(void)
 {
-	int count;
+	acpi_terminate();
 
-	if (!kill_proc(acpi_thread_pid, SIGTERM, 1)) {
-		// wait until thread terminates (at most 5 seconds)
-		count = 5 * HZ;
-		while (acpi_thread_pid >= 0 && --count) {
-			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(1);
-		}
-	}
-
-	pm_idle = NULL;
-	pm_power_off = NULL;
 	pm_active = 0;
+
+	printk(KERN_ERR "ACPI: Subsystem disabled\n");
 }
 
 module_init(acpi_init);
 module_exit(acpi_exit);
 
 #ifndef MODULE
-static int __init acpi_setup(char *str)
-{
-	while ((str != NULL) && (*str != '\0')) {
-		if (strncmp(str, "no-idle", 7) == 0)
-			acpi_use_idle = 0;
-		if (strncmp(str, "off", 3) == 0)
-			acpi_start = 0;
-		str = strchr(str, ',');
-		if (str != NULL)
-			str += strspn(str, ", \t");
+static int __init acpi_setup(char *str) {
+	while (str && *str) {
+	if (strncmp(str, "off", 3) == 0)
+		acpi_disabled = 1;
+	str = strchr(str, ',');
+	if (str)
+		str += strspn(str, ", \t");
 	}
 	return 1;
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/driver.h linux/drivers/acpi/driver.h
--- v2.4.5/linux/drivers/acpi/driver.h	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/driver.h	Wed Jun 20 17:47:39 2001
@@ -69,11 +69,4 @@
 
 extern volatile acpi_sstate_t acpi_sleep_state;
 
-/*
- * table.c
- */
-extern FADT_DESCRIPTOR acpi_fadt;
-
-int acpi_find_and_load_tables(u64 rsdp);
-
 #endif /* __DRIVER_H */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ec.c linux/drivers/acpi/ec.c
--- v2.4.5/linux/drivers/acpi/ec.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/ec.c	Wed Dec 31 16:00:00 1969
@@ -1,600 +0,0 @@
-/*
- *  ec.c - Embedded controller support
- *
- *  Copyright (C) 2000 Andrew Henroid
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/kernel.h>
-#include <linux/acpi.h>
-#include <linux/slab.h>
-#include "acpi.h"
-#include "driver.h"
-#include "ec.h"
-
-#define _COMPONENT	OS_DEPENDENT
-	MODULE_NAME	("ec")
-
-#define ACPI_EC_HID	"PNP0C09"
-
-enum
-{
-	ACPI_EC_SMI = 0x40,
-	ACPI_EC_SCI = 0x20,
-	ACPI_EC_BURST = 0x10,
-	ACPI_EC_CMD = 0x08,
-	ACPI_EC_IBF = 0x02,
-	ACPI_EC_OBF = 0x01
-};
-
-enum
-{
-	ACPI_EC_READ = 0x80,
-	ACPI_EC_WRITE = 0x81,
-	ACPI_EC_BURST_ENABLE = 0x82,
-	ACPI_EC_BURST_DISABLE = 0x83,
-	ACPI_EC_QUERY = 0x84,
-};
-
-typedef struct
-{
-	ACPI_HANDLE		acpi_handle;
-	u32			gpe_bit;
-	ACPI_IO_ADDRESS 	status_port;
-	ACPI_IO_ADDRESS 	data_port;
-	u32			need_global_lock;
-} ec_context_t;
-
-
-typedef struct 
-{
-    ec_context_t	*ec;
-    u8			data;
-
-} EC_QUERY_DATA;
-
-static char object_name[] = {'_', 'Q', '0', '0', '\0'};
-
-static char hex[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
-
-
-static ACPI_STATUS
-ec_io_wait (
-    ec_context_t              *ec,
-    EC_EVENT                wait_event)
-{
-    EC_STATUS               ec_status = 0;
-    UINT32                  i = 100;
-
-    if (!ec || ((wait_event != EC_EVENT_OUTPUT_BUFFER_FULL) 
-        && (wait_event != EC_EVENT_INPUT_BUFFER_EMPTY)))
-        return(AE_BAD_PARAMETER);
-
-    /* 
-     * Wait for Event:
-     * ---------------
-     * Poll the EC status register waiting for the event to occur.
-     * Note that we'll wait a maximum of 1ms in 10us chunks.
-     */
-    switch (wait_event) {
-    case EC_EVENT_OUTPUT_BUFFER_FULL:
-        do {
-            ec_status = acpi_os_in8(ec->status_port);
-            if (ec_status & EC_FLAG_OUTPUT_BUFFER)
-                return(AE_OK);
-            acpi_os_sleep_usec(10);
-        } while (--i>0);
-        break;
-    case EC_EVENT_INPUT_BUFFER_EMPTY:
-        do {
-            ec_status = acpi_os_in8(ec->status_port);
-            if (!(ec_status & EC_FLAG_INPUT_BUFFER))
-                return(AE_OK);
-            acpi_os_sleep_usec(10);
-        } while (--i>0);
-        break;
-    }
-
-    return(AE_TIME);
-}
-
-static ACPI_STATUS
-ec_io_read (
-    ec_context_t              *ec,
-    ACPI_IO_ADDRESS         io_port,
-    UINT8                   *data,
-    EC_EVENT                wait_event)
-{
-    ACPI_STATUS             status = AE_OK;
-
-    if (!ec || !data)
-        return(AE_BAD_PARAMETER);
-
-    *data = acpi_os_in8(io_port);
-
-    if (wait_event)
-        status = ec_io_wait(ec, wait_event);
-
-    return(status);
-}
-
-static ACPI_STATUS
-ec_io_write (
-    ec_context_t              *ec,
-    ACPI_IO_ADDRESS         io_port,
-    UINT8                   data,
-    EC_EVENT                wait_event)
-{
-    ACPI_STATUS             status = AE_OK;
-
-    if (!ec)
-        return(AE_BAD_PARAMETER);
-
-    acpi_os_out8(io_port, data);
-
-    if (wait_event)
-        status = ec_io_wait(ec, wait_event);
-
-    return(status);
-}
-
-static ACPI_STATUS
-ec_read (
-    ec_context_t              *ec,
-    UINT8                   address,
-    UINT8                   *data)
-{
-    ACPI_STATUS             status = AE_OK;
-
-    FUNCTION_TRACE("ec_read");
-
-    if (!ec || !data)
-        return_ACPI_STATUS(AE_BAD_PARAMETER);
-
-    status = ec_io_write(ec, ec->status_port, EC_COMMAND_READ, EC_EVENT_INPUT_BUFFER_EMPTY);
-    if (ACPI_FAILURE(status)) {
-        DEBUG_PRINT(ACPI_WARN, ("Unable to send 'read command' to EC.\n"));
-        return_ACPI_STATUS(status);
-    }
-
-    status = ec_io_write(ec, ec->data_port, address, EC_EVENT_OUTPUT_BUFFER_FULL);
-    if (ACPI_FAILURE(status)) {
-        DEBUG_PRINT(ACPI_WARN, ("Unable to send 'read address' to EC.\n"));
-        return_ACPI_STATUS(status);
-    }
-
-    status = ec_io_read(ec, ec->data_port, data, EC_EVENT_NONE);
-
-    DEBUG_PRINT(ACPI_INFO, ("Read data[0x%02x] from address[0x%02x] on ec.\n", (*data), address));
-
-    return_ACPI_STATUS(status);
-}
-
-static ACPI_STATUS
-ec_write (
-    ec_context_t              *ec,
-    UINT8                   address,
-    UINT8                   data)
-{
-    ACPI_STATUS             status = AE_OK;
-
-    FUNCTION_TRACE("ec_write");
-
-    if (!ec)
-        return_ACPI_STATUS(AE_BAD_PARAMETER);
-
-    status = ec_io_write(ec, ec->status_port, EC_COMMAND_WRITE, EC_EVENT_INPUT_BUFFER_EMPTY);
-    if (ACPI_FAILURE(status)) {
-        DEBUG_PRINT(ACPI_WARN, ("Unable to send 'write command' to EC.\n"));
-        return_ACPI_STATUS(status);
-    }
-
-    status = ec_io_write(ec, ec->data_port, address, EC_EVENT_INPUT_BUFFER_EMPTY);
-    if (ACPI_FAILURE(status)) {
-        DEBUG_PRINT(ACPI_WARN, ("Unable to send 'write address' to EC.\n"));
-        return_ACPI_STATUS(status);
-    }
-
-    status = ec_io_write(ec, ec->data_port, data, EC_EVENT_INPUT_BUFFER_EMPTY);
-    if (ACPI_FAILURE(status)) {
-        DEBUG_PRINT(ACPI_WARN, ("Unable to send 'write data' to EC.\n"));
-        return_ACPI_STATUS(status);
-    }
-
-    DEBUG_PRINT(ACPI_INFO, ("Wrote data[0x%02x] to address[0x%02x] on ec.\n", data, address));
-
-    return_ACPI_STATUS(status);
-}
-
-static ACPI_STATUS
-ec_transaction (
-    ec_context_t              *ec,
-    EC_REQUEST              *request)
-{
-    ACPI_STATUS             status = AE_OK;
-
-    FUNCTION_TRACE("ec_transaction");
-
-    if (!ec || !request)
-        return_ACPI_STATUS(AE_BAD_PARAMETER);
-
-    /*
-     * Obtaining semaphore (mutex) to serialize all EC transactions.
-     */
-    /*
-    DEBUG_PRINT(ACPI_INFO, ("Calling acpi_os_wait_semaphore(%p, 1, %d)\n", ec->mutex, EC_DEFAULT_TIMEOUT));
-    status = acpi_os_wait_semaphore(ec->mutex, 1, EC_DEFAULT_TIMEOUT);
-    if (ACPI_FAILURE(status))
-        return_ACPI_STATUS(status);
-    */
-
-    /*
-     * Perform the transaction.
-     */
-    switch (request->command) {
-
-    case EC_COMMAND_READ:
-        status = ec_read(ec, request->address, &(request->data));
-        break;
-
-    case EC_COMMAND_WRITE:
-        status = ec_write(ec, request->address, request->data);
-        break;
-
-    default:
-        status = AE_SUPPORT;
-        break;
-    }
-
-    /*
-     * Signal the semaphore (mutex) to indicate transaction completion.
-     */
-    /*
-    DEBUG_PRINT(ACPI_INFO, ("Calling acpi_os_signal_semaphore(%p, 1)\n", ec->mutex));
-    acpi_os_signal_semaphore(ec->mutex, 1);
-    */
-
-    return_ACPI_STATUS(status);
-}
-
-
-static void
-ec_query_handler (
-    void                    *context)
-{
-    ACPI_STATUS             status = AE_OK;
-    EC_QUERY_DATA           *ec_q = (EC_QUERY_DATA*)context;
-
-    FUNCTION_TRACE("ec_query_handler");
-
-    if (!ec_q || !ec_q->ec) {
-        DEBUG_PRINT(ACPI_ERROR, ("Invalid (NULL) context.\n"));
-        return_VOID;
-    }
-
-    /*
-     * Evaluate _Qxx:
-     * --------------
-     * Evaluate corresponding _Qxx method.  Note that a zero query
-     * value indicates a spurious EC_SCI (no such thing as _Q00).
-     */
-    object_name[2] = hex[((ec_q->data >> 4) & 0x0F)];
-    object_name[3] = hex[(ec_q->data & 0x0F)];
-
-    DEBUG_PRINT(ACPI_INFO, ("Read query data[0x%02x] from ec - evaluating [%s].\n", ec_q->data, object_name));
-
-    status = acpi_evaluate_object(ec_q->ec->acpi_handle, object_name, NULL, NULL);
-
-    kfree(ec_q);
-
-    return_VOID;
-}
-
-/*
- * handle GPE
- */
-static void
-ec_gpe_handler(void *context)
-{
-    ACPI_STATUS             status = AE_OK;
-    ec_context_t            *ec = (ec_context_t *) context;
-    EC_QUERY_DATA           *ec_q = NULL;
-    EC_STATUS               ec_status = 0;
-
-    FUNCTION_TRACE("ec_gpe_handler");
-
-    if (!ec) {
-        DEBUG_PRINT(ACPI_INFO, ("Invalid (NULL) context.\n"));
-        return_VOID;
-    }
-
-    // GET SPINLOCK!
-
-    /*
-     * EC_SCI?
-     * -------
-     * Check the EC_SCI bit to see if this is an EC_SCI event.  If not (e.g.
-     * OBF/IBE) just return, as we already poll to detect these events.
-     */
-    ec_status = acpi_os_in8(ec->status_port);
-    DEBUG_PRINT(ACPI_INFO, ("EC Status Register: [0x%02x]\n", ec_status));
-    if (!(ec_status & EC_FLAG_SCI))
-        return_VOID;
-
-    DEBUG_PRINT(ACPI_INFO, ("EC_SCI detected - running QUERY.\n"));
-
-    // TODO: Need GFP_ATOMIC 'switch' for OSL interface...
-    ec_q = kmalloc(sizeof(EC_QUERY_DATA), GFP_ATOMIC);
-    if (!ec_q) {
-        DEBUG_PRINT(ACPI_INFO, ("Memory allocation failure.\n"));
-        return_VOID;
-    }
-
-    ec_q->ec = ec;
-    ec_q->data = 0;
-
-    /*
-     * Run Query:
-     * ----------
-     * Query the EC to find out which _Qxx method we need to evaluate.
-     * Note that successful completion of the query causes the EC_SCI
-     * bit to be cleared (and thus clearing the interrupt source).
-     */
-    status = ec_io_write(ec, ec->status_port, EC_COMMAND_QUERY, EC_EVENT_OUTPUT_BUFFER_FULL);
-    if (ACPI_FAILURE(status)) {
-        DEBUG_PRINT(ACPI_WARN, ("Unable to send 'query command' to EC.\n"));
-        goto End;
-    }
-
-    status = ec_io_read(ec, ec->data_port, &(ec_q->data), EC_EVENT_NONE);
-    if (ACPI_FAILURE(status)) {
-        DEBUG_PRINT(ACPI_WARN, ("Error reading query data.\n"));
-        goto End;
-    }
-
-    // RELEASE SPINLOCK!
-
-    if (!ec_q->data) {
-        DEBUG_PRINT(ACPI_WARN, ("Spurious EC SCI detected.\n"));
-        status = AE_ERROR;
-        goto End;
-    }
-
-    /*
-     * Defer _Qxx Execution:
-     * ---------------------
-     * Can't evaluate this method now 'cause we're at interrupt-level.
-     */
-    status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE, ec_query_handler, ec_q);
-    if (ACPI_FAILURE(status)) {
-        DEBUG_PRINT(ACPI_ERROR, ("Unable to defer _Qxx method evaluation.\n"));
-        goto End;
-    }
-
-End:
-    if (ACPI_FAILURE(status))
-        kfree(ec_q);
-    
-    return_VOID;
-}
-
-static ACPI_STATUS
-ec_region_setup (
-    ACPI_HANDLE handle,
-    u32 function,
-    void *handler_context,
-    void **region_context)
-{
-	FUNCTION_TRACE("acpi_ec_region_setup");
-
-	if (function == ACPI_REGION_DEACTIVATE)
-	{
-		if (*region_context)
-		{
-			acpi_cm_free (*region_context);
-			*region_context = NULL;
-		}
-
-		return_ACPI_STATUS (AE_OK);
-	}
-
-	*region_context = NULL;
-
-	return_ACPI_STATUS (AE_OK);
-}
-
-/*****************************************************************************
- * 
- * FUNCTION:    ec_region_handler
- *
- * PARAMETERS:  function            - Read or Write operation
- *              address             - Where in the space to read or write
- *              bit_width            - Field width in bits (8, 16, or 32)
- *              value               - Pointer to in or out value
- *              context             - context pointer
- *
- * RETURN:      <TBD>
- *
- * DESCRIPTION: Handler for the Embedded Controller (EC) address space 
- *              (Op Region)
- *
- ****************************************************************************/
-
-static ACPI_STATUS
-ec_region_handler (
-    UINT32                  function,
-    ACPI_PHYSICAL_ADDRESS   address,
-    UINT32                  bit_width,
-    UINT32                  *value,
-    void                    *handler_context,
-    void                    *region_context)
-{
-    ACPI_STATUS             status = AE_OK;
-    ec_context_t              *ec = NULL;
-    EC_REQUEST              ec_request;
-
-    FUNCTION_TRACE("ec_space_handler");
-
-    if (address > 0xFF || bit_width != 8 || !value || !handler_context)
-        return_ACPI_STATUS(AE_BAD_PARAMETER);
-
-    ec = (ec_context_t*)handler_context;
-
-    switch (function) {
-
-    case ADDRESS_SPACE_READ:
-        ec_request.command = EC_COMMAND_READ;
-        ec_request.address = address;
-        ec_request.data = 0;
-        break;
-
-    case ADDRESS_SPACE_WRITE:
-        ec_request.command = EC_COMMAND_WRITE;
-        ec_request.address = address;
-        ec_request.data = (UINT8)(*value);
-        break;
-
-    default:
-        DEBUG_PRINT(ACPI_WARN, ("Received request with invalid function [0x%08X].\n", function));
-        return_ACPI_STATUS(AE_BAD_PARAMETER);
-        break;
-    }
-
-    DEBUG_PRINT(ACPI_INFO, ("device[ec] command[0x%02X] address[0x%02X] data[0x%02X]\n", ec_request.command, ec_request.address, ec_request.data));
-
-    /*
-     * Perform the Transaction.
-     */
-    status = ec_transaction(ec, &ec_request);
-    if (ACPI_SUCCESS(status))
-        (*value) = (UINT32)ec_request.data;
-
-    return_ACPI_STATUS(status);
-}
-
-/*
- * Get Embedded Controller information
- */
-static ACPI_STATUS
-found_ec(
-	ACPI_HANDLE handle,
-	u32 level, 
-	void *ctx, 
-	void **value)
-{
-	ACPI_STATUS status;
-	ACPI_OBJECT obj;
-	ACPI_BUFFER buf;
-	RESOURCE *res;
-	ec_context_t *ec_cxt;
-
-	buf.length = 0;
-	buf.pointer = NULL;
-	if (acpi_get_current_resources(handle, &buf) != AE_BUFFER_OVERFLOW)
-		return AE_OK;
-
-	buf.pointer = kmalloc(buf.length, GFP_KERNEL);
-	if (!buf.pointer)
-		return AE_NO_MEMORY;
-
-	if (!ACPI_SUCCESS(acpi_get_current_resources(handle, &buf))) {
-		kfree(buf.pointer);
-		return AE_OK;
-	}
-
-	ec_cxt = kmalloc(sizeof(ec_context_t), GFP_KERNEL);
-	if (!ec_cxt) {
-		kfree(buf.pointer);
-		return AE_NO_MEMORY;
-	}
-
-	ec_cxt->acpi_handle = handle;
-
-	res = (RESOURCE*) buf.pointer;
-	ec_cxt->data_port = res->data.io.min_base_address;
-	res = NEXT_RESOURCE(res);
-	ec_cxt->status_port = (int) res->data.io.min_base_address;
-
-	kfree(buf.pointer);
-
-	/* determine GPE bit */
-	/* BUG: in acpi 2.0 this could return a package */
-	buf.length = sizeof(obj);
-	buf.pointer = &obj;
-	if (!ACPI_SUCCESS(acpi_evaluate_object(handle, "_GPE", NULL, &buf))
-		|| obj.type != ACPI_TYPE_INTEGER)
-		return AE_OK;
-
-	ec_cxt->gpe_bit = obj.integer.value;
-
-	/* determine if we need the Global Lock when accessing */
-	buf.length = sizeof(obj);
-	buf.pointer = &obj;
-
-	status = acpi_evaluate_object(handle, "_GLK", NULL, &buf);
-	if (status == AE_NOT_FOUND)
-		ec_cxt->need_global_lock = 0;
-	else if (!ACPI_SUCCESS(status) || obj.type != ACPI_TYPE_INTEGER) {
-		DEBUG_PRINT(ACPI_ERROR, ("_GLK failed\n"));
-		return AE_OK;
-	}
-
-	ec_cxt->need_global_lock = obj.integer.value;
-
-	printk(KERN_INFO "ACPI: found EC @ (0x%02x,0x%02x,GPE %d GL %d)\n",
-		ec_cxt->data_port, ec_cxt->status_port, ec_cxt->gpe_bit,
-		ec_cxt->need_global_lock);
-
-	if (!ACPI_SUCCESS(acpi_install_gpe_handler(
-		ec_cxt->gpe_bit,
-		ACPI_EVENT_EDGE_TRIGGERED,
-		ec_gpe_handler,
-		ec_cxt))) {
-		
-		REPORT_ERROR(("Could not install GPE handler for EC.\n"));
-		return AE_OK;
-	}
-
-	status = acpi_install_address_space_handler (handle, ADDRESS_SPACE_EC, 
-		    ec_region_handler, ec_region_setup, ec_cxt);
-
-	if (!ACPI_SUCCESS(status)) {
-		REPORT_ERROR(("Could not install EC address "
-			"space handler, error %s\n", acpi_cm_format_exception (status)));
-	}
-	
-	return AE_OK;
-}
-
-int
-acpi_ec_init(void)
-{
-	acpi_get_devices(ACPI_EC_HID, 
-			found_ec,
-			NULL,
-			NULL);
-
-	return 0;
-}
-
-int
-acpi_ec_terminate(void)
-{
-	/* TODO */	
-	/* walk list of EC's */
-	/* free their context and release resources */
-	return 0;
-}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ec.h linux/drivers/acpi/ec.h
--- v2.4.5/linux/drivers/acpi/ec.h	Fri Dec 29 14:07:21 2000
+++ linux/drivers/acpi/ec.h	Wed Dec 31 16:00:00 1969
@@ -1,100 +0,0 @@
-/*
- *  Copyright (C) 2000 Andrew Grover
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#ifndef __EC_H__
-#define __EC_H__
-
-// TODO: Linux-specific
-#include <linux/spinlock.h>
-#include <asm/semaphore.h>
-
-#include <actypes.h>
-#include <acexcep.h>
-
-/*****************************************************************************
- *                             Types & Other Defines
- *****************************************************************************/
-
-#define EC_DEFAULT_TIMEOUT              1000            /* 1 second */
-#define EC_GPE_UNKNOWN                  0xFFFFFFFF
-#define EC_PORT_UNKNOWN                 0x00000000
-#define EC_BURST_ENABLE_ACKNOWLEDGE     0x90
-
-/* 
- * EC_COMMAND:
- * -----------
- */
-typedef UINT8                           EC_COMMAND;
-
-#define EC_COMMAND_UNKNOWN              ((EC_COMMAND) 0x00)
-#define EC_COMMAND_READ                 ((EC_COMMAND) 0x80)
-#define EC_COMMAND_WRITE                ((EC_COMMAND) 0x81)
-#define EC_COMMAND_QUERY                ((EC_COMMAND) 0x84)
-
-/*
- * EC_STATUS:
- * ----------
- * The encoding of the EC status register is illustrated below.
- * Note that a set bit (1) indicates the property is TRUE
- * (e.g. if bit 0 is set then the output buffer is full).
- * +-+-+-+-+-+-+-+-+
- * |7|6|5|4|3|2|1|0|    
- * +-+-+-+-+-+-+-+-+
- *  | | | | | | | |
- *  | | | | | | | +- Output Buffer Full (OBF)?
- *  | | | | | | +--- Input Buffer Full (IBF)?
- *  | | | | | +----- <reserved>
- *  | | | | +------- data Register is command Byte?
- *  | | | +--------- Burst Mode Enabled?
- *  | | +----------- SCI event?
- *  | +------------- SMI event?
- *  +--------------- <Reserved>
- *
- */
-typedef UINT8                           EC_STATUS;
-
-#define EC_FLAG_OUTPUT_BUFFER           ((EC_STATUS) 0x01)
-#define EC_FLAG_INPUT_BUFFER            ((EC_STATUS) 0x02)
-#define EC_FLAG_BURST_MODE              ((EC_STATUS) 0x10)
-#define EC_FLAG_SCI                     ((EC_STATUS) 0x20)
-
-/* 
- * EC_EVENT:
- * ---------
- */
-typedef UINT8                           EC_EVENT;
-
-#define EC_EVENT_UNKNOWN                ((EC_EVENT) 0x00)
-#define EC_EVENT_NONE                   ((EC_EVENT) 0x00)
-#define EC_EVENT_OUTPUT_BUFFER_FULL		((EC_EVENT) 0x01)
-#define EC_EVENT_INPUT_BUFFER_EMPTY  	((EC_EVENT) 0x02)
-#define EC_EVENT_SCI                    ((EC_EVENT) 0x03)
-
-/*
- * EC_REQUEST:
- * -----------
- */
-typedef struct
-{
-    EC_COMMAND              command;
-    UINT8                   address;
-    UINT8                   data;
-} EC_REQUEST;
-
-#endif  /* __EC_H__ */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/events/Makefile linux/drivers/acpi/events/Makefile
--- v2.4.5/linux/drivers/acpi/events/Makefile	Fri Dec 29 14:07:21 2000
+++ linux/drivers/acpi/events/Makefile	Wed Jun 20 17:47:39 2001
@@ -1,16 +1,12 @@
 #
 # Makefile for all Linux ACPI interpreter subdirectories
+# EXCEPT for the ospm directory
 #
 
-O_TARGET := ../$(shell basename `pwd`).o
+O_TARGET := $(notdir $(CURDIR)).o
 
 obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c))
 
-EXTRA_CFLAGS += -I../include
-
 EXTRA_CFLAGS += $(ACPI_CFLAGS)
 
 include $(TOPDIR)/Rules.make
-
-clean:
-	$(RM) *.o 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/events/evevent.c linux/drivers/acpi/events/evevent.c
--- v2.4.5/linux/drivers/acpi/events/evevent.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/events/evevent.c	Wed Jun 20 17:47:39 2001
@@ -2,7 +2,7 @@
  *
  * Module Name: evevent - Fixed and General Purpose Acpi_event
  *                          handling and dispatch
- *              $Revision: 34 $
+ *              $Revision: 43 $
  *
  *****************************************************************************/
 
@@ -28,13 +28,12 @@
 #include "achware.h"
 #include "acevents.h"
 #include "acnamesp.h"
-#include "accommon.h"
 
-#define _COMPONENT          EVENT_HANDLING
+#define _COMPONENT          ACPI_EVENTS
 	 MODULE_NAME         ("evevent")
 
 
-/**************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_initialize
  *
@@ -46,7 +45,7 @@
  *              configured, disables SCI event sources, installs the SCI
  *              handler
  *
- *************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_ev_initialize (
@@ -114,7 +113,7 @@
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_fixed_event_initialize
  *
@@ -133,7 +132,7 @@
 
 	/* Initialize the structure that keeps track of fixed event handlers */
 
-	for (i = 0; i < NUM_FIXED_EVENTS; i++) {
+	for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
 		acpi_gbl_fixed_event_handlers[i].handler = NULL;
 		acpi_gbl_fixed_event_handlers[i].context = NULL;
 	}
@@ -148,7 +147,7 @@
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_fixed_event_detect
  *
@@ -179,32 +178,28 @@
 	/* power management timer roll over */
 
 	if ((status_register & ACPI_STATUS_PMTIMER) &&
-		(enable_register & ACPI_ENABLE_PMTIMER))
-	{
+		(enable_register & ACPI_ENABLE_PMTIMER)) {
 		int_status |= acpi_ev_fixed_event_dispatch (ACPI_EVENT_PMTIMER);
 	}
 
-	/* global event (BIOS want's the global lock) */
+	/* global event (BIOS wants the global lock) */
 
 	if ((status_register & ACPI_STATUS_GLOBAL) &&
-		(enable_register & ACPI_ENABLE_GLOBAL))
-	{
+		(enable_register & ACPI_ENABLE_GLOBAL)) {
 		int_status |= acpi_ev_fixed_event_dispatch (ACPI_EVENT_GLOBAL);
 	}
 
 	/* power button event */
 
 	if ((status_register & ACPI_STATUS_POWER_BUTTON) &&
-		(enable_register & ACPI_ENABLE_POWER_BUTTON))
-	{
+		(enable_register & ACPI_ENABLE_POWER_BUTTON)) {
 		int_status |= acpi_ev_fixed_event_dispatch (ACPI_EVENT_POWER_BUTTON);
 	}
 
 	/* sleep button event */
 
 	if ((status_register & ACPI_STATUS_SLEEP_BUTTON) &&
-		(enable_register & ACPI_ENABLE_SLEEP_BUTTON))
-	{
+		(enable_register & ACPI_ENABLE_SLEEP_BUTTON)) {
 		int_status |= acpi_ev_fixed_event_dispatch (ACPI_EVENT_SLEEP_BUTTON);
 	}
 
@@ -212,7 +207,7 @@
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_fixed_event_dispatch
  *
@@ -233,8 +228,7 @@
 
 	/* Clear the status bit */
 
-	switch (event)
-	{
+	switch (event) {
 	case ACPI_EVENT_PMTIMER:
 		register_id = TMR_STS;
 		break;
@@ -286,7 +280,7 @@
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_gpe_initialize
  *
@@ -339,7 +333,7 @@
 	 * Allocate the Gpe information block
 	 */
 
-	acpi_gbl_gpe_registers = acpi_cm_callocate (acpi_gbl_gpe_register_count *
+	acpi_gbl_gpe_registers = acpi_ut_callocate (acpi_gbl_gpe_register_count *
 			 sizeof (ACPI_GPE_REGISTERS));
 	if (!acpi_gbl_gpe_registers) {
 		return (AE_NO_MEMORY);
@@ -351,16 +345,16 @@
 	 * Initialization to zeros is sufficient
 	 */
 
-	acpi_gbl_gpe_info = acpi_cm_callocate (MUL_8 (acpi_gbl_gpe_register_count) *
+	acpi_gbl_gpe_info = acpi_ut_callocate (MUL_8 (acpi_gbl_gpe_register_count) *
 			 sizeof (ACPI_GPE_LEVEL_INFO));
 	if (!acpi_gbl_gpe_info) {
-		acpi_cm_free (acpi_gbl_gpe_registers);
+		acpi_ut_free (acpi_gbl_gpe_registers);
 		return (AE_NO_MEMORY);
 	}
 
 	/* Set the Gpe validation table to GPE_INVALID */
 
-	MEMSET (acpi_gbl_gpe_valid, (int) ACPI_GPE_INVALID, NUM_GPE);
+	MEMSET (acpi_gbl_gpe_valid, (int) ACPI_GPE_INVALID, ACPI_NUM_GPE);
 
 	/*
 	 * Initialize the Gpe information and validation blocks.  A goal of these
@@ -430,7 +424,7 @@
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_save_method_info
  *
@@ -464,6 +458,9 @@
 	u8                      type;
 
 
+	PROC_NAME ("Ev_save_method_info");
+
+
 	/* Extract the name from the object and convert to a string */
 
 	MOVE_UNALIGNED32_TO_32 (name, &((ACPI_NAMESPACE_NODE *) obj_handle)->name);
@@ -520,7 +517,7 @@
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_init_gpe_control_methods
  *
@@ -557,7 +554,7 @@
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_gpe_detect
  *
@@ -623,7 +620,7 @@
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_asynch_execute_gpe_method
  *
@@ -650,9 +647,9 @@
 	/*
 	 * Take a snapshot of the GPE info for this level
 	 */
-	acpi_cm_acquire_mutex (ACPI_MTX_EVENTS);
+	acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
 	gpe_info = acpi_gbl_gpe_info [gpe_number];
-	acpi_cm_release_mutex (ACPI_MTX_EVENTS);
+	acpi_ut_release_mutex (ACPI_MTX_EVENTS);
 
 	/*
 	 * Method Handler (_Lxx, _Exx):
@@ -681,7 +678,7 @@
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_gpe_dispatch
  *
@@ -706,7 +703,6 @@
 {
 	ACPI_GPE_LEVEL_INFO     gpe_info;
 
-	/*DEBUG_INCREMENT_EVENT_COUNT (EVENT_GENERAL);*/
 
 	/*
 	 * Valid GPE number?
@@ -751,8 +747,7 @@
 	 */
 	else if (gpe_info.method_handle) {
 		if (ACPI_FAILURE(acpi_os_queue_for_execution (OSD_PRIORITY_GPE,
-			acpi_ev_asynch_execute_gpe_method, (void*)(NATIVE_UINT)gpe_number)))
-		{
+			acpi_ev_asynch_execute_gpe_method, (void*) gpe_number))) {
 			/*
 			 * Shoudn't occur, but if it does report an error. Note that
 			 * the GPE will remain disabled until the ACPI Core Subsystem
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/events/evmisc.c linux/drivers/acpi/events/evmisc.c
--- v2.4.5/linux/drivers/acpi/events/evmisc.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/events/evmisc.c	Wed Jun 20 17:47:40 2001
@@ -2,7 +2,7 @@
  *
  * Module Name: evmisc - ACPI device notification handler dispatch
  *                       and ACPI Global Lock support
- *              $Revision: 22 $
+ *              $Revision: 31 $
  *
  *****************************************************************************/
 
@@ -30,13 +30,13 @@
 #include "acinterp.h"
 #include "achware.h"
 
-#define _COMPONENT          EVENT_HANDLING
+#define _COMPONENT          ACPI_EVENTS
 	 MODULE_NAME         ("evmisc")
 
 
-/**************************************************************************
+/*******************************************************************************
  *
- * FUNCTION:    Acpi_ev_notify_dispatch
+ * FUNCTION:    Acpi_ev_queue_notify_request
  *
  * PARAMETERS:
  *
@@ -45,16 +45,20 @@
  * DESCRIPTION: Dispatch a device notification event to a previously
  *              installed handler.
  *
- *************************************************************************/
+ ******************************************************************************/
 
-void
-acpi_ev_notify_dispatch (
-	ACPI_HANDLE             device,
+ACPI_STATUS
+acpi_ev_queue_notify_request (
+	ACPI_NAMESPACE_NODE     *node,
 	u32                     notify_value)
 {
 	ACPI_OPERAND_OBJECT     *obj_desc;
-	ACPI_OPERAND_OBJECT     *handler_obj;
-	NOTIFY_HANDLER          handler;
+	ACPI_OPERAND_OBJECT     *handler_obj = NULL;
+	ACPI_GENERIC_STATE      *notify_info;
+	ACPI_STATUS             status = AE_OK;
+
+
+	PROC_NAME ("Ev_queue_notify_request");
 
 
 	/*
@@ -64,9 +68,7 @@
 	 * initiate soft-off or sleep operation?
 	 */
 
-
-	switch (notify_value)
-	{
+	switch (notify_value) {
 	case 0:
 		break;
 
@@ -85,67 +87,136 @@
 
 
 	/*
-	 * Invoke a global notify handler if installed.
-	 * This is done _before_ we invoke the per-device handler attached to the device.
+	 * Get the notify object attached to the device Node
 	 */
 
-	if (notify_value <= MAX_SYS_NOTIFY) {
-		/* Global system notification handler */
+	obj_desc = acpi_ns_get_attached_object (node);
+	if (obj_desc) {
 
-		if (acpi_gbl_sys_notify.handler) {
-			acpi_gbl_sys_notify.handler (device, notify_value,
-					  acpi_gbl_sys_notify.context);
+		/* We have the notify object, Get the right handler */
+
+		switch (node->type) {
+		case ACPI_TYPE_DEVICE:
+			if (notify_value <= MAX_SYS_NOTIFY) {
+				handler_obj = obj_desc->device.sys_handler;
+			}
+			else {
+				handler_obj = obj_desc->device.drv_handler;
+			}
+			break;
+
+		case ACPI_TYPE_THERMAL:
+			if (notify_value <= MAX_SYS_NOTIFY) {
+				handler_obj = obj_desc->thermal_zone.sys_handler;
+			}
+			else {
+				handler_obj = obj_desc->thermal_zone.drv_handler;
+			}
+			break;
 		}
 	}
 
-	else {
-		/* Global driver notification handler */
 
-		if (acpi_gbl_drv_notify.handler) {
-			acpi_gbl_drv_notify.handler (device, notify_value,
-					  acpi_gbl_drv_notify.context);
+	/* If there is any handler to run, schedule the dispatcher */
+
+	if ((acpi_gbl_sys_notify.handler && (notify_value <= MAX_SYS_NOTIFY)) ||
+		(acpi_gbl_drv_notify.handler && (notify_value > MAX_SYS_NOTIFY)) ||
+		handler_obj) {
+
+		notify_info = acpi_ut_create_generic_state ();
+		if (!notify_info) {
+			return (AE_NO_MEMORY);
+		}
+
+		notify_info->notify.node      = node;
+		notify_info->notify.value     = (u16) notify_value;
+		notify_info->notify.handler_obj = handler_obj;
+
+		status = acpi_os_queue_for_execution (OSD_PRIORITY_HIGH,
+				  acpi_ev_notify_dispatch, notify_info);
+		if (ACPI_FAILURE (status)) {
+			acpi_ut_delete_generic_state (notify_info);
 		}
 	}
 
+	if (!handler_obj) {
+		/* There is no per-device notify handler for this device */
 
-	/*
-	 * Get the notify object which must be attached to the device Node
-	 */
+	}
 
-	obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) device);
-	if (!obj_desc) {
-		/* There can be no notify handler for this device */
+	return (status);
+}
 
-		return;
-	}
 
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ev_notify_dispatch
+ *
+ * PARAMETERS:
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Dispatch a device notification event to a previously
+ *              installed handler.
+ *
+ ******************************************************************************/
+
+void
+acpi_ev_notify_dispatch (
+	void                    *context)
+{
+	ACPI_GENERIC_STATE      *notify_info = (ACPI_GENERIC_STATE *) context;
+	ACPI_NOTIFY_HANDLER     global_handler = NULL;
+	void                    *global_context = NULL;
+	ACPI_OPERAND_OBJECT     *handler_obj;
 
-	/* We have the notify object, Get the right handler */
 
-	if (notify_value <= MAX_SYS_NOTIFY) {
-		handler_obj = obj_desc->device.sys_handler;
+	/*
+	 * We will invoke a global notify handler if installed.
+	 * This is done _before_ we invoke the per-device handler attached to the device.
+	 */
+
+	if (notify_info->notify.value <= MAX_SYS_NOTIFY) {
+		/* Global system notification handler */
+
+		if (acpi_gbl_sys_notify.handler) {
+			global_handler = acpi_gbl_sys_notify.handler;
+			global_context = acpi_gbl_sys_notify.context;
+		}
 	}
+
 	else {
-		handler_obj = obj_desc->device.drv_handler;
+		/* Global driver notification handler */
+
+		if (acpi_gbl_drv_notify.handler) {
+			global_handler = acpi_gbl_drv_notify.handler;
+			global_context = acpi_gbl_drv_notify.context;
+		}
 	}
 
-	/* Validate the handler */
 
-	if (!handler_obj) {
-		/* There is no notify handler for this device */
+	/* Invoke the system handler first, if present */
 
-		return;
+	if (global_handler) {
+		global_handler (notify_info->notify.node, notify_info->notify.value, global_context);
 	}
 
-	/* There is a handler, invoke it */
+	/* Now invoke the per-device handler, if present */
 
-	handler = handler_obj->notify_handler.handler;
-	handler (device, notify_value, handler_obj->notify_handler.context);
+	handler_obj = notify_info->notify.handler_obj;
+	if (handler_obj) {
+		handler_obj->notify_handler.handler (notify_info->notify.node, notify_info->notify.value,
+				  handler_obj->notify_handler.context);
+	}
 
+
+	/* All done with the info object */
+
+	acpi_ut_delete_generic_state (notify_info);
 }
 
 
-/***************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_global_lock_thread
  *
@@ -155,7 +226,7 @@
  *              Global Lock.  Simply signal all threads that are waiting
  *              for the lock.
  *
- **************************************************************************/
+ ******************************************************************************/
 
 static void
 acpi_ev_global_lock_thread (
@@ -173,7 +244,7 @@
 }
 
 
-/***************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_global_lock_handler
  *
@@ -183,7 +254,7 @@
  *              release interrupt occurs.  Grab the global lock and queue
  *              the global lock thread for execution
  *
- **************************************************************************/
+ ******************************************************************************/
 
 static u32
 acpi_ev_global_lock_handler (
@@ -216,7 +287,7 @@
 }
 
 
-/***************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_init_global_lock_handler
  *
@@ -224,7 +295,7 @@
  *
  * DESCRIPTION: Install a handler for the global lock release event
  *
- **************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_ev_init_global_lock_handler (void)
@@ -232,14 +303,27 @@
 	ACPI_STATUS             status;
 
 
+	acpi_gbl_global_lock_present = TRUE;
 	status = acpi_install_fixed_event_handler (ACPI_EVENT_GLOBAL,
 			  acpi_ev_global_lock_handler, NULL);
 
+	/*
+	 * If the global lock does not exist on this platform, the attempt
+	 * to enable GBL_STS will fail (the GBL_EN bit will not stick)
+	 * Map to AE_OK, but mark global lock as not present.
+	 * Any attempt to actually use the global lock will be flagged
+	 * with an error.
+	 */
+	if (status == AE_NO_HARDWARE_RESPONSE) {
+		acpi_gbl_global_lock_present = FALSE;
+		status = AE_OK;
+	}
+
 	return (status);
 }
 
 
-/***************************************************************************
+/******************************************************************************
  *
  * FUNCTION:    Acpi_ev_acquire_global_lock
  *
@@ -247,7 +331,7 @@
  *
  * DESCRIPTION: Attempt to gain ownership of the Global Lock.
  *
- **************************************************************************/
+ *****************************************************************************/
 
 ACPI_STATUS
 acpi_ev_acquire_global_lock(void)
@@ -257,6 +341,12 @@
 	void                    *global_lock;
 
 
+	/* Make sure that we actually have a global lock */
+
+	if (!acpi_gbl_global_lock_present) {
+		return (AE_NO_GLOBAL_LOCK);
+	}
+
 	/* One more thread wants the global lock */
 
 	acpi_gbl_global_lock_thread_count++;
@@ -283,7 +373,6 @@
 	   /* We got the lock */
 
 		acpi_gbl_global_lock_acquired = TRUE;
-
 		return (AE_OK);
 	}
 
@@ -298,20 +387,19 @@
 	  * Since this wait will block, we must release the interpreter
 	  */
 
-	status = acpi_aml_system_wait_semaphore (acpi_gbl_global_lock_semaphore,
+	status = acpi_ex_system_wait_semaphore (acpi_gbl_global_lock_semaphore,
 			  ACPI_UINT32_MAX);
-
 	return (status);
 }
 
 
-/***************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_release_global_lock
  *
  * DESCRIPTION: Releases ownership of the Global Lock.
  *
- **************************************************************************/
+ ******************************************************************************/
 
 void
 acpi_ev_release_global_lock (void)
@@ -321,7 +409,7 @@
 
 
 	if (!acpi_gbl_global_lock_thread_count) {
-		REPORT_WARNING(("Releasing a non-acquired Global Lock\n"));
+		REPORT_WARNING(("Global Lock has not be acquired, cannot release\n"));
 		return;
 	}
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/events/evregion.c linux/drivers/acpi/events/evregion.c
--- v2.4.5/linux/drivers/acpi/events/evregion.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/events/evregion.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: evregion - ACPI Address_space (Op_region) handler dispatch
- *              $Revision: 96 $
+ *              $Revision: 103 $
  *
  *****************************************************************************/
 
@@ -30,11 +30,11 @@
 #include "acinterp.h"
 #include "amlcode.h"
 
-#define _COMPONENT          EVENT_HANDLING
+#define _COMPONENT          ACPI_EVENTS
 	 MODULE_NAME         ("evregion")
 
 
-/**************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_install_default_address_space_handlers
  *
@@ -44,7 +44,7 @@
  *
  * DESCRIPTION: Installs the core subsystem address space handlers.
  *
- *************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_ev_install_default_address_space_handlers (
@@ -70,29 +70,26 @@
 	 */
 
 	status = acpi_install_address_space_handler (acpi_gbl_root_node,
-			   ADDRESS_SPACE_SYSTEM_MEMORY,
+			   ACPI_ADR_SPACE_SYSTEM_MEMORY,
 			   ACPI_DEFAULT_HANDLER, NULL, NULL);
 	if ((ACPI_FAILURE (status)) &&
-		(status != AE_EXIST))
-	{
+		(status != AE_EXIST)) {
 		return (status);
 	}
 
 	status = acpi_install_address_space_handler (acpi_gbl_root_node,
-			   ADDRESS_SPACE_SYSTEM_IO,
+			   ACPI_ADR_SPACE_SYSTEM_IO,
 			   ACPI_DEFAULT_HANDLER, NULL, NULL);
 	if ((ACPI_FAILURE (status)) &&
-		(status != AE_EXIST))
-	{
+		(status != AE_EXIST)) {
 		return (status);
 	}
 
 	status = acpi_install_address_space_handler (acpi_gbl_root_node,
-			   ADDRESS_SPACE_PCI_CONFIG,
+			   ACPI_ADR_SPACE_PCI_CONFIG,
 			   ACPI_DEFAULT_HANDLER, NULL, NULL);
 	if ((ACPI_FAILURE (status)) &&
-		(status != AE_EXIST))
-	{
+		(status != AE_EXIST)) {
 		return (status);
 	}
 
@@ -103,7 +100,7 @@
 
 /* TBD: [Restructure] Move elsewhere */
 
-/**************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_execute_reg_method
  *
@@ -114,7 +111,7 @@
  *
  * DESCRIPTION: Execute _REG method for a region
  *
- *************************************************************************/
+ ******************************************************************************/
 
 static ACPI_STATUS
 acpi_ev_execute_reg_method (
@@ -141,8 +138,8 @@
 	 *          Passed as a parameter
 	 */
 
-	acpi_cm_init_static_object (&space_id_desc);
-	acpi_cm_init_static_object (&function_desc);
+	acpi_ut_init_static_object (&space_id_desc);
+	acpi_ut_init_static_object (&function_desc);
 
 	/*
 	 *  Method requires two parameters.
@@ -168,7 +165,7 @@
 }
 
 
-/**************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_address_space_dispatch
  *
@@ -184,7 +181,7 @@
  * DESCRIPTION: Dispatch an address space or operation region access to
  *              a previously installed handler.
  *
- *************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_ev_address_space_dispatch (
@@ -195,28 +192,27 @@
 	u32                     *value)
 {
 	ACPI_STATUS             status;
-	ADDRESS_SPACE_HANDLER   handler;
-	ADDRESS_SPACE_SETUP     region_setup;
+	ACPI_ADR_SPACE_HANDLER  handler;
+	ACPI_ADR_SPACE_SETUP    region_setup;
 	ACPI_OPERAND_OBJECT     *handler_desc;
 	void                    *region_context = NULL;
 
 
 	/*
-	 *  Check for an installed handler
+	 * Ensure that there is a handler associated with this region
 	 */
 	handler_desc = region_obj->region.addr_handler;
-
 	if (!handler_desc) {
 		return(AE_NOT_EXIST);
 	}
 
 	/*
-	 *  It may be the case that the region has never been initialized
-	 *  Some types of regions require special init code
+	 * It may be the case that the region has never been initialized
+	 * Some types of regions require special init code
 	 */
 	if (!(region_obj->region.flags & AOPOBJ_INITIALIZED)) {
 		/*
-		 *  This region has not been initialized yet, do it
+		 * This region has not been initialized yet, do it
 		 */
 		region_setup = handler_desc->addr_handler.setup;
 		if (!region_setup) {
@@ -230,15 +226,14 @@
 		 * We must exit the interpreter because the region setup will potentially
 		 * execute control methods
 		 */
-		acpi_aml_exit_interpreter ();
+		acpi_ex_exit_interpreter ();
 
 		status = region_setup (region_obj, ACPI_REGION_ACTIVATE,
-				  handler_desc->addr_handler.context,
-				  &region_context);
+				  handler_desc->addr_handler.context, &region_context);
 
 		/* Re-enter the interpreter */
 
-		acpi_aml_enter_interpreter ();
+		acpi_ex_enter_interpreter ();
 
 		/*
 		 *  Init routine may fail
@@ -267,7 +262,7 @@
 		 *  exit the interpreter because the handler *might* block -- we don't
 		 *  know what it will do, so we can't hold the lock on the intepreter.
 		 */
-		acpi_aml_exit_interpreter();
+		acpi_ex_exit_interpreter();
 	}
 
 	/*
@@ -282,13 +277,13 @@
 		/* We just returned from a non-default handler, we must re-enter the
 		interpreter */
 
-		acpi_aml_enter_interpreter ();
+		acpi_ex_enter_interpreter ();
 	}
 
 	return (status);
 }
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_disassociate_region_from_handler
  *
@@ -310,7 +305,7 @@
 	ACPI_OPERAND_OBJECT     *handler_obj;
 	ACPI_OPERAND_OBJECT     *obj_desc;
 	ACPI_OPERAND_OBJECT     **last_obj_ptr;
-	ADDRESS_SPACE_SETUP     region_setup;
+	ACPI_ADR_SPACE_SETUP    region_setup;
 	void                    *region_context;
 	ACPI_STATUS             status;
 
@@ -349,7 +344,7 @@
 			obj_desc->region.next = NULL;           /* Must clear field */
 
 			if (acpi_ns_is_locked) {
-				acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+				acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 			}
 
 			/*
@@ -358,7 +353,7 @@
 			acpi_ev_execute_reg_method (region_obj, 0);
 
 			if (acpi_ns_is_locked) {
-				acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+				acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 			}
 
 			/*
@@ -366,8 +361,7 @@
 			 */
 			region_setup = handler_obj->addr_handler.setup;
 			status = region_setup (region_obj, ACPI_REGION_DEACTIVATE,
-					  handler_obj->addr_handler.context,
-					  &region_context);
+					  handler_obj->addr_handler.context, &region_context);
 
 			/*
 			 *  Init routine may fail, Just ignore errors
@@ -407,7 +401,7 @@
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_associate_region_and_handler
  *
@@ -456,20 +450,20 @@
 	 *  Last thing, tell all users that this region is usable
 	 */
 	if (acpi_ns_is_locked) {
-		acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+		acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 	}
 
 	status = acpi_ev_execute_reg_method (region_obj, 1);
 
 	if (acpi_ns_is_locked) {
-		acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+		acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 	}
 
 	return (status);
 }
 
 
-/****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_addr_handler_helper
  *
@@ -486,7 +480,7 @@
  *              This is because the existing handler is closer in proximity
  *              to any more regions than the one we are trying to install.
  *
- ***************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_ev_addr_handler_helper (
@@ -502,6 +496,9 @@
 	ACPI_STATUS             status;
 
 
+	PROC_NAME ("Ev_addr_handler_helper");
+
+
 	handler_obj = (ACPI_OPERAND_OBJECT *) context;
 
 	/* Parameter validation */
@@ -524,14 +521,13 @@
 
 	if ((node->type != ACPI_TYPE_DEVICE) &&
 		(node->type != ACPI_TYPE_REGION) &&
-		(node != acpi_gbl_root_node))
-	{
+		(node != acpi_gbl_root_node)) {
 		return (AE_OK);
 	}
 
 	/* Check for an existing internal object */
 
-	obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) node);
+	obj_desc = acpi_ns_get_attached_object (node);
 	if (!obj_desc) {
 		/*
 		 *  The object DNE, we don't care about it
@@ -555,7 +551,6 @@
 				/*
 				 *  It's for the same address space
 				 */
-
 				/*
 				 *  Since the object we found it on was a device, then it
 				 *  means that someone has already installed a handler for
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/events/evrgnini.c linux/drivers/acpi/events/evrgnini.c
--- v2.4.5/linux/drivers/acpi/events/evrgnini.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/events/evrgnini.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: evrgnini- ACPI Address_space (Op_region) init
- *              $Revision: 33 $
+ *              $Revision: 40 $
  *
  *****************************************************************************/
 
@@ -30,11 +30,11 @@
 #include "acinterp.h"
 #include "amlcode.h"
 
-#define _COMPONENT          EVENT_HANDLING
+#define _COMPONENT          ACPI_EVENTS
 	 MODULE_NAME         ("evrgnini")
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_system_memory_region_setup
  *
@@ -47,7 +47,7 @@
  *
  * DESCRIPTION: Do any prep work for region handling, a nop for now
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_ev_system_memory_region_setup (
@@ -59,7 +59,7 @@
 
 	if (function == ACPI_REGION_DEACTIVATE) {
 		if (*region_context) {
-			acpi_cm_free (*region_context);
+			acpi_ut_free (*region_context);
 			*region_context = NULL;
 		}
 		return (AE_OK);
@@ -68,7 +68,7 @@
 
 	/* Activate.  Create a new context */
 
-	*region_context = acpi_cm_callocate (sizeof (MEM_HANDLER_CONTEXT));
+	*region_context = acpi_ut_callocate (sizeof (ACPI_MEM_SPACE_CONTEXT));
 	if (!(*region_context)) {
 		return (AE_NO_MEMORY);
 	}
@@ -77,7 +77,7 @@
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_io_space_region_setup
  *
@@ -90,7 +90,7 @@
  *
  * DESCRIPTION: Do any prep work for region handling
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_ev_io_space_region_setup (
@@ -99,6 +99,7 @@
 	void                    *handler_context,
 	void                    **region_context)
 {
+
 	if (function == ACPI_REGION_DEACTIVATE) {
 		*region_context = NULL;
 	}
@@ -110,7 +111,7 @@
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_pci_config_region_setup
  *
@@ -125,7 +126,7 @@
  *
  * MUTEX:       Assumes namespace is not locked
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_ev_pci_config_region_setup (
@@ -136,25 +137,25 @@
 {
 	ACPI_STATUS             status = AE_OK;
 	ACPI_INTEGER            temp;
-	PCI_HANDLER_CONTEXT     *pci_context = *region_context;
+	ACPI_PCI_SPACE_CONTEXT  *pci_context = *region_context;
 	ACPI_OPERAND_OBJECT     *handler_obj;
 	ACPI_NAMESPACE_NODE     *node;
 	ACPI_OPERAND_OBJECT     *region_obj = (ACPI_OPERAND_OBJECT *) handle;
-	DEVICE_ID               object_hID;
+	ACPI_DEVICE_ID          object_hID;
 
-	handler_obj = region_obj->region.addr_handler;
 
+	handler_obj = region_obj->region.addr_handler;
 	if (!handler_obj) {
 		/*
 		 *  No installed handler. This shouldn't happen because the dispatch
 		 *  routine checks before we get here, but we check again just in case.
 		 */
-		return(AE_NOT_EXIST);
+		return (AE_NOT_EXIST);
 	}
 
 	if (function == ACPI_REGION_DEACTIVATE) {
 		if (pci_context) {
-			acpi_cm_free (pci_context);
+			acpi_ut_free (pci_context);
 			*region_context = NULL;
 		}
 
@@ -164,7 +165,7 @@
 
 	/* Create a new context */
 
-	pci_context = acpi_cm_callocate (sizeof(PCI_HANDLER_CONTEXT));
+	pci_context = acpi_ut_callocate (sizeof (ACPI_PCI_SPACE_CONTEXT));
 	if (!pci_context) {
 		return (AE_NO_MEMORY);
 	}
@@ -178,22 +179,20 @@
 	 *  First get device and function numbers from the _ADR object
 	 *  in the parent's scope.
 	 */
-	ACPI_ASSERT(region_obj->region.node);
+	ACPI_ASSERT (region_obj->region.node);
 
 	node = acpi_ns_get_parent_object (region_obj->region.node);
 
 
 	/* Acpi_evaluate the _ADR object */
 
-	status = acpi_cm_evaluate_numeric_object (METHOD_NAME__ADR, node, &temp);
+	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, node, &temp);
+
 	/*
 	 *  The default is zero, since the allocation above zeroed the data, just
 	 *  do nothing on failures.
 	 */
 	if (ACPI_SUCCESS (status)) {
-		/*
-		 *  Got it..
-		 */
 		pci_context->dev_func = (u32) temp;
 	}
 
@@ -215,40 +214,31 @@
 		 * Node is currently the parent object
 		 */
 		while (node != acpi_gbl_root_node) {
-			status = acpi_cm_execute_HID(node, &object_hID);
-
+			status = acpi_ut_execute_HID (node, &object_hID);
 			if (ACPI_SUCCESS (status)) {
-				if (!(STRNCMP(object_hID.buffer, PCI_ROOT_HID_STRING,
-						   sizeof (PCI_ROOT_HID_STRING))))
-				{
-					acpi_install_address_space_handler(node,
-							   ADDRESS_SPACE_PCI_CONFIG,
+				if (!(STRNCMP (object_hID.buffer, PCI_ROOT_HID_STRING,
+						   sizeof (PCI_ROOT_HID_STRING)))) {
+					acpi_install_address_space_handler (node,
+							   ACPI_ADR_SPACE_PCI_CONFIG,
 							   ACPI_DEFAULT_HANDLER, NULL, NULL);
-
 					break;
 				}
 			}
 
-			node = acpi_ns_get_parent_object(node);
+			node = acpi_ns_get_parent_object (node);
 		}
 	}
 	else {
 		node = handler_obj->addr_handler.node;
 	}
 
-	status = acpi_cm_evaluate_numeric_object (METHOD_NAME__SEG, node, &temp);
+	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__SEG, node, &temp);
 	if (ACPI_SUCCESS (status)) {
-		/*
-		 *  Got it..
-		 */
 		pci_context->seg = (u32) temp;
 	}
 
-	status = acpi_cm_evaluate_numeric_object (METHOD_NAME__BBN, node, &temp);
+	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__BBN, node, &temp);
 	if (ACPI_SUCCESS (status)) {
-		/*
-		 *  Got it..
-		 */
 		pci_context->bus = (u32) temp;
 	}
 
@@ -258,7 +248,7 @@
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_default_region_setup
  *
@@ -271,7 +261,7 @@
  *
  * DESCRIPTION: Do any prep work for region handling
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_ev_default_region_setup (
@@ -280,6 +270,7 @@
 	void                    *handler_context,
 	void                    **region_context)
 {
+
 	if (function == ACPI_REGION_DEACTIVATE) {
 		*region_context = NULL;
 	}
@@ -291,7 +282,7 @@
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ev_initialize_region
  *
@@ -307,7 +298,7 @@
  *
  *              This also performs address space specific intialization.  For
  *              example, PCI regions must have an _ADR object that contains
- *              a PCI address in the scope of the defintion.  This address is
+ *              a PCI address in the scope of the definition.  This address is
  *              required to perform an access to PCI config space.
  *
  ******************************************************************************/
@@ -317,20 +308,20 @@
 	ACPI_OPERAND_OBJECT     *region_obj,
 	u8                      acpi_ns_locked)
 {
-	ACPI_OPERAND_OBJECT    *handler_obj;
-	ACPI_OPERAND_OBJECT    *obj_desc;
-	ACPI_ADDRESS_SPACE_TYPE space_id;
-	ACPI_NAMESPACE_NODE    *node;
+	ACPI_OPERAND_OBJECT     *handler_obj;
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	ACPI_ADR_SPACE_TYPE     space_id;
+	ACPI_NAMESPACE_NODE     *node;
 	ACPI_STATUS             status;
-	ACPI_NAMESPACE_NODE    *method_node;
-	ACPI_NAME              *reg_name_ptr = (ACPI_NAME *) METHOD_NAME__REG;
+	ACPI_NAMESPACE_NODE     *method_node;
+	ACPI_NAME               *reg_name_ptr = (ACPI_NAME *) METHOD_NAME__REG;
 
 
 	if (!region_obj) {
 		return (AE_BAD_PARAMETER);
 	}
 
-	ACPI_ASSERT(region_obj->region.node);
+	ACPI_ASSERT (region_obj->region.node);
 
 	node = acpi_ns_get_parent_object (region_obj->region.node);
 	space_id = region_obj->region.space_id;
@@ -362,13 +353,12 @@
 		 *  Check to see if a handler exists
 		 */
 		handler_obj = NULL;
-		obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) node);
+		obj_desc = acpi_ns_get_attached_object (node);
 		if (obj_desc) {
 			/*
 			 *  can only be a handler if the object exists
 			 */
-			switch (node->type)
-			{
+			switch (node->type) {
 			case ACPI_TYPE_DEVICE:
 
 				handler_obj = obj_desc->device.addr_handler;
@@ -394,7 +384,8 @@
 					/*
 					 *  Found it! Now update the region and the handler
 					 */
-					acpi_ev_associate_region_and_handler (handler_obj, region_obj, acpi_ns_locked);
+					acpi_ev_associate_region_and_handler (handler_obj, region_obj,
+							acpi_ns_locked);
 					return (AE_OK);
 				}
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/events/evsci.c linux/drivers/acpi/events/evsci.c
--- v2.4.5/linux/drivers/acpi/events/evsci.c	Tue Mar  6 19:44:36 2001
+++ linux/drivers/acpi/events/evsci.c	Wed Jun 20 17:47:40 2001
@@ -2,7 +2,7 @@
  *
  * Module Name: evsci - System Control Interrupt configuration and
  *                      legacy to ACPI mode state transition functions
- *              $Revision: 69 $
+ *              $Revision: 72 $
  *
  ******************************************************************************/
 
@@ -30,7 +30,7 @@
 #include "acevents.h"
 
 
-#define _COMPONENT          EVENT_HANDLING
+#define _COMPONENT          ACPI_EVENTS
 	 MODULE_NAME         ("evsci")
 
 
@@ -172,21 +172,6 @@
 
 /*******************************************************************************
  *
- * FUNCTION:    Acpi_ev_sci_count
- *
- * PARAMETERS:  Event       Event that generated an SCI.
- *
- * RETURN:      Number of SCI's for requested event since last time
- *              Sci_occurred() was called for this event.
- *
- * DESCRIPTION: Checks to see if SCI has been generated from requested source
- *              since the last time this function was called.
- *
- ******************************************************************************/
-
-
-/*******************************************************************************
- *
  * FUNCTION:    Acpi_ev_restore_acpi_state
  *
  * PARAMETERS:  none
@@ -209,8 +194,7 @@
 		/* Restore the fixed events */
 
 		if (acpi_hw_register_read (ACPI_MTX_LOCK, PM1_EN) !=
-				acpi_gbl_pm1_enable_register_save)
-		{
+				acpi_gbl_pm1_enable_register_save) {
 			acpi_hw_register_write (ACPI_MTX_LOCK, PM1_EN,
 				acpi_gbl_pm1_enable_register_save);
 		}
@@ -225,8 +209,7 @@
 
 		for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe0blk_len); index++) {
 			if (acpi_hw_register_read (ACPI_MTX_LOCK, GPE0_EN_BLOCK | index) !=
-					acpi_gbl_gpe0enable_register_save[index])
-			{
+					acpi_gbl_gpe0enable_register_save[index]) {
 				acpi_hw_register_write (ACPI_MTX_LOCK, GPE0_EN_BLOCK | index,
 					acpi_gbl_gpe0enable_register_save[index]);
 			}
@@ -237,8 +220,7 @@
 		if (acpi_gbl_FADT->gpe1_blk_len) {
 			for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe1_blk_len); index++) {
 				if (acpi_hw_register_read (ACPI_MTX_LOCK, GPE1_EN_BLOCK | index) !=
-					acpi_gbl_gpe1_enable_register_save[index])
-				{
+					acpi_gbl_gpe1_enable_register_save[index]) {
 					acpi_hw_register_write (ACPI_MTX_LOCK, GPE1_EN_BLOCK | index,
 						acpi_gbl_gpe1_enable_register_save[index]);
 				}
@@ -276,11 +258,11 @@
 	 */
 
 	if (acpi_gbl_gpe_registers) {
-		acpi_cm_free (acpi_gbl_gpe_registers);
+		acpi_ut_free (acpi_gbl_gpe_registers);
 	}
 
 	if (acpi_gbl_gpe_info) {
-		acpi_cm_free (acpi_gbl_gpe_info);
+		acpi_ut_free (acpi_gbl_gpe_info);
 	}
 
 	return;
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/events/evxface.c linux/drivers/acpi/events/evxface.c
--- v2.4.5/linux/drivers/acpi/events/evxface.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/events/evxface.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: evxface - External interfaces for ACPI events
- *              $Revision: 101 $
+ *              $Revision: 110 $
  *
  *****************************************************************************/
 
@@ -31,11 +31,11 @@
 #include "amlcode.h"
 #include "acinterp.h"
 
-#define _COMPONENT          EVENT_HANDLING
+#define _COMPONENT          ACPI_EVENTS
 	 MODULE_NAME         ("evxface")
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_install_fixed_event_handler
  *
@@ -54,19 +54,26 @@
 ACPI_STATUS
 acpi_install_fixed_event_handler (
 	u32                     event,
-	FIXED_EVENT_HANDLER     handler,
+	ACPI_EVENT_HANDLER      handler,
 	void                    *context)
 {
-	ACPI_STATUS             status = AE_OK;
+	ACPI_STATUS             status;
 
 
-	/* Sanity check the parameters. */
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/* Parameter validation */
 
-	if (event >= NUM_FIXED_EVENTS) {
+	if (event > ACPI_EVENT_MAX) {
 		return (AE_BAD_PARAMETER);
 	}
 
-	acpi_cm_acquire_mutex (ACPI_MTX_EVENTS);
+	acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
 
 	/* Don't allow two handlers. */
 
@@ -81,26 +88,23 @@
 	acpi_gbl_fixed_event_handlers[event].handler = handler;
 	acpi_gbl_fixed_event_handlers[event].context = context;
 
-	status = acpi_enable_event(event, ACPI_EVENT_FIXED);
-
-	if (!ACPI_SUCCESS(status)) {
+	status = acpi_enable_event (event, ACPI_EVENT_FIXED);
+	if (!ACPI_SUCCESS (status)) {
 		/* Remove the handler */
 
 		acpi_gbl_fixed_event_handlers[event].handler = NULL;
 		acpi_gbl_fixed_event_handlers[event].context = NULL;
-
-		status = AE_ERROR;
-		goto cleanup;
 	}
 
 
+
 cleanup:
-	acpi_cm_release_mutex (ACPI_MTX_EVENTS);
+	acpi_ut_release_mutex (ACPI_MTX_EVENTS);
 	return (status);
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_remove_fixed_event_handler
  *
@@ -116,40 +120,44 @@
 ACPI_STATUS
 acpi_remove_fixed_event_handler (
 	u32                     event,
-	FIXED_EVENT_HANDLER     handler)
+	ACPI_EVENT_HANDLER      handler)
 {
 	ACPI_STATUS             status = AE_OK;
 
 
-	/* Sanity check the parameters. */
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/* Parameter validation */
 
-	if (event >= NUM_FIXED_EVENTS) {
+	if (event > ACPI_EVENT_MAX) {
 		return (AE_BAD_PARAMETER);
 	}
 
-	acpi_cm_acquire_mutex (ACPI_MTX_EVENTS);
+	acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
 
 	/* Disable the event before removing the handler - just in case... */
 
 	status = acpi_disable_event(event, ACPI_EVENT_FIXED);
 
-	if (!ACPI_SUCCESS(status)) {
-		status = AE_ERROR;
-		acpi_cm_release_mutex (ACPI_MTX_EVENTS);
-		return (status);
-	}
-
-	/* Remove the handler */
+	/* Always Remove the handler */
 
 	acpi_gbl_fixed_event_handlers[event].handler = NULL;
 	acpi_gbl_fixed_event_handlers[event].context = NULL;
 
-	acpi_cm_release_mutex (ACPI_MTX_EVENTS);
+
+
+
+	acpi_ut_release_mutex (ACPI_MTX_EVENTS);
 	return (status);
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_install_notify_handler
  *
@@ -170,7 +178,7 @@
 acpi_install_notify_handler (
 	ACPI_HANDLE             device,
 	u32                     handler_type,
-	NOTIFY_HANDLER          handler,
+	ACPI_NOTIFY_HANDLER     handler,
 	void                    *context)
 {
 	ACPI_OPERAND_OBJECT     *obj_desc;
@@ -179,15 +187,21 @@
 	ACPI_STATUS             status = AE_OK;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/* Parameter validation */
 
 	if ((!handler) ||
-		(handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE))
-	{
+		(handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
 		return (AE_BAD_PARAMETER);
 	}
 
-	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 
 	/* Convert and validate the device handle */
 
@@ -210,8 +224,7 @@
 		if (((handler_type == ACPI_SYSTEM_NOTIFY) &&
 			  acpi_gbl_sys_notify.handler) ||
 			((handler_type == ACPI_DEVICE_NOTIFY) &&
-			  acpi_gbl_drv_notify.handler))
-		{
+			  acpi_gbl_drv_notify.handler)) {
 			status = AE_EXIST;
 			goto unlock_and_exit;
 		}
@@ -243,15 +256,14 @@
 		if ((device_node->type != ACPI_TYPE_DEVICE)    &&
 			(device_node->type != ACPI_TYPE_PROCESSOR) &&
 			(device_node->type != ACPI_TYPE_POWER)     &&
-			(device_node->type != ACPI_TYPE_THERMAL))
-		{
+			(device_node->type != ACPI_TYPE_THERMAL)) {
 			status = AE_BAD_PARAMETER;
 			goto unlock_and_exit;
 		}
 
 		/* Check for an existing internal object */
 
-		obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) device_node);
+		obj_desc = acpi_ns_get_attached_object (device_node);
 		if (obj_desc) {
 
 			/* Object exists - make sure there's no handler */
@@ -259,8 +271,7 @@
 			if (((handler_type == ACPI_SYSTEM_NOTIFY) &&
 				  obj_desc->device.sys_handler) ||
 				((handler_type == ACPI_DEVICE_NOTIFY) &&
-				  obj_desc->device.drv_handler))
-			{
+				  obj_desc->device.drv_handler)) {
 				status = AE_EXIST;
 				goto unlock_and_exit;
 			}
@@ -269,7 +280,7 @@
 		else {
 			/* Create a new object */
 
-			obj_desc = acpi_cm_create_internal_object (device_node->type);
+			obj_desc = acpi_ut_create_internal_object (device_node->type);
 			if (!obj_desc) {
 				status = AE_NO_MEMORY;
 				goto unlock_and_exit;
@@ -278,7 +289,6 @@
 			/* Attach new object to the Node */
 
 			status = acpi_ns_attach_object (device, obj_desc, (u8) device_node->type);
-
 			if (ACPI_FAILURE (status)) {
 				goto unlock_and_exit;
 			}
@@ -286,7 +296,7 @@
 
 		/* Install the handler */
 
-		notify_obj = acpi_cm_create_internal_object (INTERNAL_TYPE_NOTIFY);
+		notify_obj = acpi_ut_create_internal_object (INTERNAL_TYPE_NOTIFY);
 		if (!notify_obj) {
 			status = AE_NO_MEMORY;
 			goto unlock_and_exit;
@@ -300,18 +310,19 @@
 		if (handler_type == ACPI_SYSTEM_NOTIFY) {
 			obj_desc->device.sys_handler = notify_obj;
 		}
+
 		else /* ACPI_DEVICE_NOTIFY */ {
 			obj_desc->device.drv_handler = notify_obj;
 		}
 	}
 
 unlock_and_exit:
-	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 	return (status);
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_remove_notify_handler
  *
@@ -330,22 +341,29 @@
 acpi_remove_notify_handler (
 	ACPI_HANDLE             device,
 	u32                     handler_type,
-	NOTIFY_HANDLER          handler)
+	ACPI_NOTIFY_HANDLER     handler)
 {
 	ACPI_OPERAND_OBJECT     *notify_obj;
 	ACPI_OPERAND_OBJECT     *obj_desc;
 	ACPI_NAMESPACE_NODE     *device_node;
 	ACPI_STATUS             status = AE_OK;
 
+
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/* Parameter validation */
 
 	if ((!handler) ||
-		(handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE))
-	{
+		(handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
 		return (AE_BAD_PARAMETER);
 	}
 
-	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 
 	/* Convert and validate the device handle */
 
@@ -364,8 +382,7 @@
 		if (((handler_type == ACPI_SYSTEM_NOTIFY) &&
 			  !acpi_gbl_sys_notify.handler) ||
 			((handler_type == ACPI_DEVICE_NOTIFY) &&
-			  !acpi_gbl_drv_notify.handler))
-		{
+			  !acpi_gbl_drv_notify.handler)) {
 			status = AE_NOT_EXIST;
 			goto unlock_and_exit;
 		}
@@ -393,15 +410,14 @@
 		if ((device_node->type != ACPI_TYPE_DEVICE)    &&
 			(device_node->type != ACPI_TYPE_PROCESSOR) &&
 			(device_node->type != ACPI_TYPE_POWER)     &&
-			(device_node->type != ACPI_TYPE_THERMAL))
-		{
+			(device_node->type != ACPI_TYPE_THERMAL)) {
 			status = AE_BAD_PARAMETER;
 			goto unlock_and_exit;
 		}
 
 		/* Check for an existing internal object */
 
-		obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) device_node);
+		obj_desc = acpi_ns_get_attached_object (device_node);
 		if (!obj_desc) {
 			status = AE_NOT_EXIST;
 			goto unlock_and_exit;
@@ -417,8 +433,7 @@
 		}
 
 		if ((!notify_obj) ||
-			(notify_obj->notify_handler.handler != handler))
-		{
+			(notify_obj->notify_handler.handler != handler)) {
 			status = AE_BAD_PARAMETER;
 			goto unlock_and_exit;
 		}
@@ -432,17 +447,17 @@
 			obj_desc->device.drv_handler = NULL;
 		}
 
-		acpi_cm_remove_reference (notify_obj);
+		acpi_ut_remove_reference (notify_obj);
 	}
 
 
 unlock_and_exit:
-	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 	return (status);
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_install_gpe_handler
  *
@@ -463,14 +478,22 @@
 acpi_install_gpe_handler (
 	u32                     gpe_number,
 	u32                     type,
-	GPE_HANDLER             handler,
+	ACPI_GPE_HANDLER        handler,
 	void                    *context)
 {
 	ACPI_STATUS             status = AE_OK;
 
+
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/* Parameter validation */
 
-	if (!handler || (gpe_number > NUM_GPE)) {
+	if (!handler || (gpe_number > ACPI_GPE_MAX)) {
 		return (AE_BAD_PARAMETER);
 	}
 
@@ -480,7 +503,7 @@
 		return (AE_BAD_PARAMETER);
 	}
 
-	acpi_cm_acquire_mutex (ACPI_MTX_EVENTS);
+	acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
 
 	/* Make sure that there isn't a handler there already */
 
@@ -501,12 +524,12 @@
 	acpi_hw_enable_gpe (gpe_number);
 
 cleanup:
-	acpi_cm_release_mutex (ACPI_MTX_EVENTS);
+	acpi_ut_release_mutex (ACPI_MTX_EVENTS);
 	return (status);
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_remove_gpe_handler
  *
@@ -522,14 +545,21 @@
 ACPI_STATUS
 acpi_remove_gpe_handler (
 	u32                     gpe_number,
-	GPE_HANDLER             handler)
+	ACPI_GPE_HANDLER        handler)
 {
 	ACPI_STATUS             status = AE_OK;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/* Parameter validation */
 
-	if (!handler || (gpe_number > NUM_GPE)) {
+	if (!handler || (gpe_number > ACPI_GPE_MAX)) {
 		return (AE_BAD_PARAMETER);
 	}
 
@@ -543,7 +573,7 @@
 
 	acpi_hw_disable_gpe (gpe_number);
 
-	acpi_cm_acquire_mutex (ACPI_MTX_EVENTS);
+	acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
 
 	/* Make sure that the installed handler is the same */
 
@@ -559,12 +589,12 @@
 	acpi_gbl_gpe_info[gpe_number].context = NULL;
 
 cleanup:
-	acpi_cm_release_mutex (ACPI_MTX_EVENTS);
+	acpi_ut_release_mutex (ACPI_MTX_EVENTS);
 	return (status);
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_acquire_global_lock
  *
@@ -583,7 +613,17 @@
 	ACPI_STATUS             status;
 
 
-	acpi_aml_enter_interpreter ();
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	status = acpi_ex_enter_interpreter ();
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
 
 	/*
 	 * TBD: [Restructure] add timeout param to internal interface, and
@@ -591,13 +631,13 @@
 	 */
 
 	status = acpi_ev_acquire_global_lock ();
-	acpi_aml_exit_interpreter ();
+	acpi_ex_exit_interpreter ();
 
 	return (status);
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_release_global_lock
  *
@@ -613,6 +653,16 @@
 acpi_release_global_lock (
 	void)
 {
+	ACPI_STATUS             status;
+
+
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	acpi_ev_release_global_lock ();
 	return (AE_OK);
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/events/evxfevnt.c linux/drivers/acpi/events/evxfevnt.c
--- v2.4.5/linux/drivers/acpi/events/evxfevnt.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/events/evxfevnt.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable
- *              $Revision: 28 $
+ *              $Revision: 33 $
  *
  *****************************************************************************/
 
@@ -31,11 +31,11 @@
 #include "amlcode.h"
 #include "acinterp.h"
 
-#define _COMPONENT          EVENT_HANDLING
+#define _COMPONENT          ACPI_EVENTS
 	 MODULE_NAME         ("evxfevnt")
 
 
-/**************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_enable
  *
@@ -45,7 +45,7 @@
  *
  * DESCRIPTION: Transfers the system into ACPI mode.
  *
- *************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_enable (void)
@@ -76,7 +76,7 @@
 }
 
 
-/**************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_disable
  *
@@ -87,7 +87,7 @@
  * DESCRIPTION: Returns the system to original ACPI/legacy mode, and
  *              uninstalls the SCI interrupt handler.
  *
- *************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_disable (void)
@@ -95,6 +95,13 @@
 	ACPI_STATUS             status;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/* Restore original mode  */
 
 	status = acpi_hw_set_mode (acpi_gbl_original_mode);
@@ -111,7 +118,7 @@
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_enable_event
  *
@@ -133,17 +140,22 @@
 	u32                     register_id;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/* The Type must be either Fixed Acpi_event or GPE */
 
-	switch (type)
-	{
+	switch (type) {
 
 	case ACPI_EVENT_FIXED:
 
 		/* Decode the Fixed Acpi_event */
 
-		switch (event)
-		{
+		switch (event) {
 		case ACPI_EVENT_PMTIMER:
 			register_id = TMR_EN;
 			break;
@@ -177,7 +189,7 @@
 		acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 1);
 
 		if (1 != acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, register_id)) {
-			return (AE_ERROR);
+			return (AE_NO_HARDWARE_RESPONSE);
 		}
 
 		break;
@@ -187,9 +199,8 @@
 
 		/* Ensure that we have a valid GPE number */
 
-		if ((event >= NUM_GPE) ||
-			(acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID))
-		{
+		if ((event > ACPI_GPE_MAX) ||
+			(acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) {
 			return (AE_BAD_PARAMETER);
 		}
 
@@ -210,7 +221,7 @@
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_disable_event
  *
@@ -232,17 +243,22 @@
 	u32                     register_id;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/* The Type must be either Fixed Acpi_event or GPE */
 
-	switch (type)
-	{
+	switch (type) {
 
 	case ACPI_EVENT_FIXED:
 
 		/* Decode the Fixed Acpi_event */
 
-		switch (event)
-		{
+		switch (event) {
 		case ACPI_EVENT_PMTIMER:
 			register_id = TMR_EN;
 			break;
@@ -276,7 +292,7 @@
 		acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 0);
 
 		if (0 != acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, register_id)) {
-			return (AE_ERROR);
+			return (AE_NO_HARDWARE_RESPONSE);
 		}
 
 		break;
@@ -286,9 +302,8 @@
 
 		/* Ensure that we have a valid GPE number */
 
-		if ((event >= NUM_GPE) ||
-			(acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID))
-		{
+		if ((event > ACPI_GPE_MAX) ||
+			(acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) {
 			return (AE_BAD_PARAMETER);
 		}
 
@@ -306,7 +321,7 @@
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_clear_event
  *
@@ -328,17 +343,22 @@
 	u32                     register_id;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/* The Type must be either Fixed Acpi_event or GPE */
 
-	switch (type)
-	{
+	switch (type) {
 
 	case ACPI_EVENT_FIXED:
 
 		/* Decode the Fixed Acpi_event */
 
-		switch (event)
-		{
+		switch (event) {
 		case ACPI_EVENT_PMTIMER:
 			register_id = TMR_STS;
 			break;
@@ -377,9 +397,8 @@
 
 		/* Ensure that we have a valid GPE number */
 
-		if ((event >= NUM_GPE) ||
-			(acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID))
-		{
+		if ((event > ACPI_GPE_MAX) ||
+			(acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) {
 			return (AE_BAD_PARAMETER);
 		}
 
@@ -397,7 +416,7 @@
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_get_event_status
  *
@@ -423,6 +442,13 @@
 	u32                     register_id;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	if (!event_status) {
 		return (AE_BAD_PARAMETER);
 	}
@@ -430,15 +456,13 @@
 
 	/* The Type must be either Fixed Acpi_event or GPE */
 
-	switch (type)
-	{
+	switch (type) {
 
 	case ACPI_EVENT_FIXED:
 
 		/* Decode the Fixed Acpi_event */
 
-		switch (event)
-		{
+		switch (event) {
 		case ACPI_EVENT_PMTIMER:
 			register_id = TMR_STS;
 			break;
@@ -474,9 +498,8 @@
 
 		/* Ensure that we have a valid GPE number */
 
-		if ((event >= NUM_GPE) ||
-			(acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID))
-		{
+		if ((event > ACPI_GPE_MAX) ||
+			(acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) {
 			return (AE_BAD_PARAMETER);
 		}
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/events/evxfregn.c linux/drivers/acpi/events/evxfregn.c
--- v2.4.5/linux/drivers/acpi/events/evxfregn.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/events/evxfregn.c	Wed Jun 20 17:47:40 2001
@@ -2,7 +2,7 @@
  *
  * Module Name: evxfregn - External Interfaces, ACPI Operation Regions and
  *                         Address Spaces.
- *              $Revision: 27 $
+ *              $Revision: 34 $
  *
  *****************************************************************************/
 
@@ -32,11 +32,11 @@
 #include "amlcode.h"
 #include "acinterp.h"
 
-#define _COMPONENT          EVENT_HANDLING
+#define _COMPONENT          ACPI_EVENTS
 	 MODULE_NAME         ("evxfregn")
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_install_address_space_handler
  *
@@ -55,29 +55,35 @@
 ACPI_STATUS
 acpi_install_address_space_handler (
 	ACPI_HANDLE             device,
-	ACPI_ADDRESS_SPACE_TYPE space_id,
-	ADDRESS_SPACE_HANDLER   handler,
-	ADDRESS_SPACE_SETUP     setup,
+	ACPI_ADR_SPACE_TYPE     space_id,
+	ACPI_ADR_SPACE_HANDLER  handler,
+	ACPI_ADR_SPACE_SETUP    setup,
 	void                    *context)
 {
 	ACPI_OPERAND_OBJECT     *obj_desc;
 	ACPI_OPERAND_OBJECT     *handler_obj;
 	ACPI_NAMESPACE_NODE     *node;
 	ACPI_STATUS             status = AE_OK;
-	OBJECT_TYPE_INTERNAL    type;
+	ACPI_OBJECT_TYPE8       type;
 	u16                     flags = 0;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/* Parameter validation */
 
 	if ((!device)   ||
 		((!handler)  && (handler != ACPI_DEFAULT_HANDLER)) ||
-		(space_id > ACPI_MAX_ADDRESS_SPACE))
-	{
+		(space_id > ACPI_MAX_ADDRESS_SPACE)) {
 		return (AE_BAD_PARAMETER);
 	}
 
-	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 
 	/* Convert and validate the device handle */
 
@@ -96,8 +102,7 @@
 	if ((node->type != ACPI_TYPE_DEVICE)     &&
 		(node->type != ACPI_TYPE_PROCESSOR)  &&
 		(node->type != ACPI_TYPE_THERMAL)    &&
-		(node != acpi_gbl_root_node))
-	{
+		(node != acpi_gbl_root_node)) {
 		status = AE_BAD_PARAMETER;
 		goto unlock_and_exit;
 	}
@@ -105,20 +110,19 @@
 	if (handler == ACPI_DEFAULT_HANDLER) {
 		flags = ADDR_HANDLER_DEFAULT_INSTALLED;
 
-		switch (space_id)
-		{
-		case ADDRESS_SPACE_SYSTEM_MEMORY:
-			handler = acpi_aml_system_memory_space_handler;
+		switch (space_id) {
+		case ACPI_ADR_SPACE_SYSTEM_MEMORY:
+			handler = acpi_ex_system_memory_space_handler;
 			setup = acpi_ev_system_memory_region_setup;
 			break;
 
-		case ADDRESS_SPACE_SYSTEM_IO:
-			handler = acpi_aml_system_io_space_handler;
+		case ACPI_ADR_SPACE_SYSTEM_IO:
+			handler = acpi_ex_system_io_space_handler;
 			setup = acpi_ev_io_space_region_setup;
 			break;
 
-		case ADDRESS_SPACE_PCI_CONFIG:
-			handler = acpi_aml_pci_config_space_handler;
+		case ACPI_ADR_SPACE_PCI_CONFIG:
+			handler = acpi_ex_pci_config_space_handler;
 			setup = acpi_ev_pci_config_region_setup;
 			break;
 
@@ -140,7 +144,7 @@
 	 *  Check for an existing internal object
 	 */
 
-	obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) node);
+	obj_desc = acpi_ns_get_attached_object (node);
 	if (obj_desc) {
 		/*
 		 *  The object exists.
@@ -178,7 +182,7 @@
 			type = node->type;
 		}
 
-		obj_desc = acpi_cm_create_internal_object (type);
+		obj_desc = acpi_ut_create_internal_object (type);
 		if (!obj_desc) {
 			status = AE_NO_MEMORY;
 			goto unlock_and_exit;
@@ -192,7 +196,7 @@
 
 		status = acpi_ns_attach_object (node, obj_desc, (u8) type);
 		if (ACPI_FAILURE (status)) {
-			acpi_cm_remove_reference (obj_desc);
+			acpi_ut_remove_reference (obj_desc);
 			goto unlock_and_exit;
 		}
 	}
@@ -204,7 +208,7 @@
 	 *  So, we just allocate the object for the handler and link it
 	 *  into the list.
 	 */
-	handler_obj = acpi_cm_create_internal_object (INTERNAL_TYPE_ADDRESS_HANDLER);
+	handler_obj = acpi_ut_create_internal_object (INTERNAL_TYPE_ADDRESS_HANDLER);
 	if (!handler_obj) {
 		status = AE_NO_MEMORY;
 		goto unlock_and_exit;
@@ -247,12 +251,12 @@
 
 
 unlock_and_exit:
-	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 	return (status);
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_remove_address_space_handler
  *
@@ -268,8 +272,8 @@
 ACPI_STATUS
 acpi_remove_address_space_handler (
 	ACPI_HANDLE             device,
-	ACPI_ADDRESS_SPACE_TYPE space_id,
-	ADDRESS_SPACE_HANDLER   handler)
+	ACPI_ADR_SPACE_TYPE     space_id,
+	ACPI_ADR_SPACE_HANDLER  handler)
 {
 	ACPI_OPERAND_OBJECT     *obj_desc;
 	ACPI_OPERAND_OBJECT     *handler_obj;
@@ -279,16 +283,22 @@
 	ACPI_STATUS             status = AE_OK;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/* Parameter validation */
 
 	if ((!device)   ||
 		((!handler)  && (handler != ACPI_DEFAULT_HANDLER)) ||
-		(space_id > ACPI_MAX_ADDRESS_SPACE))
-	{
+		(space_id > ACPI_MAX_ADDRESS_SPACE)) {
 		return (AE_BAD_PARAMETER);
 	}
 
-	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 
 	/* Convert and validate the device handle */
 
@@ -301,7 +311,7 @@
 
 	/* Make sure the internal object exists */
 
-	obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) node);
+	obj_desc = acpi_ns_get_attached_object (node);
 	if (!obj_desc) {
 		/*
 		 *  The object DNE.
@@ -337,7 +347,7 @@
 				 *  The region is just inaccessible as indicated to
 				 *  the _REG method
 				 */
-				acpi_ev_disassociate_region_from_handler(region_obj, FALSE);
+				acpi_ev_disassociate_region_from_handler(region_obj, TRUE);
 
 				/*
 				 *  Walk the list, since we took the first region and it
@@ -356,8 +366,8 @@
 			/*
 			 *  Now we can delete the handler object
 			 */
-			acpi_cm_remove_reference (handler_obj);
-			acpi_cm_remove_reference (handler_obj);
+			acpi_ut_remove_reference (handler_obj);
+			acpi_ut_remove_reference (handler_obj);
 
 			goto unlock_and_exit;
 		}
@@ -377,7 +387,7 @@
 
 
 unlock_and_exit:
-	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 	return (status);
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/Makefile linux/drivers/acpi/executer/Makefile
--- v2.4.5/linux/drivers/acpi/executer/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/Makefile	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,12 @@
+#
+# Makefile for all Linux ACPI interpreter subdirectories
+# EXCEPT for the ospm directory
+#
+
+O_TARGET := $(notdir $(CURDIR)).o
+
+obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c))
+
+EXTRA_CFLAGS += $(ACPI_CFLAGS)
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exconfig.c linux/drivers/acpi/executer/exconfig.c
--- v2.4.5/linux/drivers/acpi/executer/exconfig.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exconfig.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,304 @@
+/******************************************************************************
+ *
+ * Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes)
+ *              $Revision: 34 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "acinterp.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+#include "acevents.h"
+#include "actables.h"
+#include "acdispat.h"
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exconfig")
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_load_table_op
+ *
+ * PARAMETERS:  Rgn_desc        - Op region where the table will be obtained
+ *              Ddb_handle      - Where a handle to the table will be returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Load an ACPI table
+ *
+ ****************************************************************************/
+
+static ACPI_STATUS
+acpi_ex_load_table_op (
+	ACPI_OPERAND_OBJECT     *rgn_desc,
+	ACPI_HANDLE             *ddb_handle)
+{
+	ACPI_STATUS             status;
+	ACPI_OPERAND_OBJECT     *table_desc = NULL;
+	u8                      *table_ptr;
+	u8                      *table_data_ptr;
+	ACPI_TABLE_HEADER       table_header;
+	ACPI_TABLE_DESC         table_info;
+	u32                     i;
+
+
+	/* TBD: [Unhandled] Object can be either a field or an opregion */
+
+
+	/* Get the table header */
+
+	table_header.length = 0;
+	for (i = 0; i < sizeof (ACPI_TABLE_HEADER); i++) {
+		status = acpi_ev_address_space_dispatch (rgn_desc, ACPI_READ_ADR_SPACE,
+				   (ACPI_PHYSICAL_ADDRESS) i, 8,
+				   (u32 *) ((u8 *) &table_header + i));
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+	}
+
+	/* Allocate a buffer for the entire table */
+
+	table_ptr = acpi_ut_allocate (table_header.length);
+	if (!table_ptr) {
+		return (AE_NO_MEMORY);
+	}
+
+	/* Copy the header to the buffer */
+
+	MEMCPY (table_ptr, &table_header, sizeof (ACPI_TABLE_HEADER));
+	table_data_ptr = table_ptr + sizeof (ACPI_TABLE_HEADER);
+
+
+	/* Get the table from the op region */
+
+	for (i = 0; i < table_header.length; i++) {
+		status = acpi_ev_address_space_dispatch (rgn_desc, ACPI_READ_ADR_SPACE,
+				   (ACPI_PHYSICAL_ADDRESS) i, 8,
+				   (u32 *) (table_data_ptr + i));
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+	}
+
+
+	/* Table must be either an SSDT or a PSDT */
+
+	if ((!STRNCMP (table_header.signature,
+			  acpi_gbl_acpi_table_data[ACPI_TABLE_PSDT].signature,
+			  acpi_gbl_acpi_table_data[ACPI_TABLE_PSDT].sig_length)) &&
+		(!STRNCMP (table_header.signature,
+				 acpi_gbl_acpi_table_data[ACPI_TABLE_SSDT].signature,
+				 acpi_gbl_acpi_table_data[ACPI_TABLE_SSDT].sig_length))) {
+		status = AE_BAD_SIGNATURE;
+		goto cleanup;
+	}
+
+	/* Create an object to be the table handle */
+
+	table_desc = acpi_ut_create_internal_object (INTERNAL_TYPE_REFERENCE);
+	if (!table_desc) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+
+
+	/* Install the new table into the local data structures */
+
+	table_info.pointer     = (ACPI_TABLE_HEADER *) table_ptr;
+	table_info.length      = table_header.length;
+	table_info.allocation  = ACPI_MEM_ALLOCATED;
+	table_info.base_pointer = table_ptr;
+
+	status = acpi_tb_install_table (NULL, &table_info);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	/* Add the table to the namespace */
+
+	/* TBD: [Restructure] - change to whatever new interface is appropriate */
+/*
+	Status = Acpi_load_namespace ();
+	if (ACPI_FAILURE (Status))
+	{
+*/
+		/* TBD: [Errors] Unload the table on failure ? */
+/*
+		goto Cleanup;
+	}
+*/
+
+
+	/* TBD: [Investigate] we need a pointer to the table desc */
+
+	/* Init the table handle */
+
+	table_desc->reference.opcode = AML_LOAD_OP;
+	table_desc->reference.object = table_info.installed_desc;
+
+	*ddb_handle = table_desc;
+
+	return (status);
+
+
+cleanup:
+
+	acpi_ut_free (table_desc);
+	acpi_ut_free (table_ptr);
+	return (status);
+
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_unload_table
+ *
+ * PARAMETERS:  Ddb_handle          - Handle to a previously loaded table
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Unload an ACPI table
+ *
+ ****************************************************************************/
+
+static ACPI_STATUS
+acpi_ex_unload_table (
+	ACPI_HANDLE             ddb_handle)
+{
+	ACPI_STATUS             status = AE_NOT_IMPLEMENTED;
+	ACPI_OPERAND_OBJECT     *table_desc = (ACPI_OPERAND_OBJECT *) ddb_handle;
+	ACPI_TABLE_DESC         *table_info;
+
+
+	/* Validate the handle */
+	/* Although the handle is partially validated in Acpi_ex_reconfiguration(),
+	 *  when it calls Acpi_ex_resolve_operands(), the handle is more completely
+	 *  validated here.
+	 */
+
+	if ((!ddb_handle) ||
+		(!VALID_DESCRIPTOR_TYPE (ddb_handle, ACPI_DESC_TYPE_INTERNAL)) ||
+		(((ACPI_OPERAND_OBJECT  *)ddb_handle)->common.type !=
+				INTERNAL_TYPE_REFERENCE)) {
+		return (AE_BAD_PARAMETER);
+	}
+
+
+	/* Get the actual table descriptor from the Ddb_handle */
+
+	table_info = (ACPI_TABLE_DESC *) table_desc->reference.object;
+
+	/*
+	 * Delete the entire namespace under this table Node
+	 * (Offset contains the Table_id)
+	 */
+
+	status = acpi_ns_delete_namespace_by_owner (table_info->table_id);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/* Delete the table itself */
+
+	acpi_tb_uninstall_table (table_info->installed_desc);
+
+	/* Delete the table descriptor (Ddb_handle) */
+
+	acpi_ut_remove_reference (table_desc);
+
+	return (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_reconfiguration
+ *
+ * PARAMETERS:  Opcode              - The opcode to be executed
+ *              Walk_state          - Current state of the parse tree walk
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Reconfiguration opcodes such as LOAD and UNLOAD
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+acpi_ex_reconfiguration (
+	u16                     opcode,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_STATUS             status;
+	ACPI_OPERAND_OBJECT     *region_desc = NULL;
+	ACPI_HANDLE             *ddb_handle;
+
+
+	/* Resolve the operands */
+
+	status = acpi_ex_resolve_operands (opcode, WALK_OPERANDS, walk_state);
+	/* Get the table handle, common for both opcodes */
+
+	status |= acpi_ds_obj_stack_pop_object ((ACPI_OPERAND_OBJECT **) &ddb_handle,
+			 walk_state);
+
+	switch (opcode) {
+
+	case AML_LOAD_OP:
+
+		/* Get the region or field descriptor */
+
+		status |= acpi_ds_obj_stack_pop_object (&region_desc, walk_state);
+		if (ACPI_FAILURE (status)) {
+			acpi_ut_remove_reference (region_desc);
+			return (status);
+		}
+
+		status = acpi_ex_load_table_op (region_desc, ddb_handle);
+		break;
+
+
+	case AML_UNLOAD_OP:
+
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+
+		status = acpi_ex_unload_table (ddb_handle);
+		break;
+
+
+	default:
+
+		status = AE_AML_BAD_OPCODE;
+		break;
+	}
+
+
+	return (status);
+}
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exconvrt.c linux/drivers/acpi/executer/exconvrt.c
--- v2.4.5/linux/drivers/acpi/executer/exconvrt.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exconvrt.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,518 @@
+/******************************************************************************
+ *
+ * Module Name: exconvrt - Object conversion routines
+ *              $Revision: 13 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "acnamesp.h"
+#include "acinterp.h"
+#include "acevents.h"
+#include "amlcode.h"
+#include "acdispat.h"
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exconvrt")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_convert_to_integer
+ *
+ * PARAMETERS:  *Obj_desc       - Object to be converted.  Must be an
+ *                                Integer, Buffer, or String
+ *              Walk_state      - Current method state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert an ACPI Object to an integer.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_convert_to_integer (
+	ACPI_OPERAND_OBJECT     **obj_desc,
+	ACPI_WALK_STATE         *walk_state)
+{
+	u32                     i;
+	ACPI_OPERAND_OBJECT     *ret_desc;
+	u32                     count;
+	char                    *pointer;
+	ACPI_INTEGER            result;
+	u32                     integer_size = sizeof (ACPI_INTEGER);
+
+
+	switch ((*obj_desc)->common.type) {
+	case ACPI_TYPE_INTEGER:
+		return (AE_OK);
+
+	case ACPI_TYPE_STRING:
+		pointer = (*obj_desc)->string.pointer;
+		count = (*obj_desc)->string.length;
+		break;
+
+	case ACPI_TYPE_BUFFER:
+		pointer = (char *) (*obj_desc)->buffer.pointer;
+		count = (*obj_desc)->buffer.length;
+		break;
+
+	default:
+		return (AE_TYPE);
+	}
+
+	/*
+	 * Create a new integer
+	 */
+	ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+	if (!ret_desc) {
+		return (AE_NO_MEMORY);
+	}
+
+
+	/* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */
+
+	if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) {
+		/*
+		 * We are running a method that exists in a 32-bit ACPI table.
+		 * Truncate the value to 32 bits by zeroing out the upper 32-bit field
+		 */
+		integer_size = sizeof (u32);
+	}
+
+
+	/*
+	 * Convert the buffer/string to an integer.  Note that both buffers and
+	 * strings are treated as raw data - we don't convert ascii to hex for
+	 * strings.
+	 *
+	 * There are two terminating conditions for the loop:
+	 * 1) The size of an integer has been reached, or
+	 * 2) The end of the buffer or string has been reached
+	 */
+	result = 0;
+
+	/* Transfer no more than an integer's worth of data */
+
+	if (count > integer_size) {
+		count = integer_size;
+	}
+
+	/*
+	 * String conversion is different than Buffer conversion
+	 */
+	switch ((*obj_desc)->common.type) {
+	case ACPI_TYPE_STRING:
+
+		/* TBD: Need to use 64-bit STRTOUL */
+
+		/*
+		 * Convert string to an integer
+		 * String must be hexadecimal as per the ACPI specification
+		 */
+
+		result = STRTOUL (pointer, NULL, 16);
+		break;
+
+
+	case ACPI_TYPE_BUFFER:
+
+		/*
+		 * Buffer conversion - we simply grab enough raw data from the
+		 * buffer to fill an integer
+		 */
+		for (i = 0; i < count; i++) {
+			/*
+			 * Get next byte and shift it into the Result.
+			 * Little endian is used, meaning that the first byte of the buffer
+			 * is the LSB of the integer
+			 */
+			result |= (((ACPI_INTEGER) pointer[i]) << (i * 8));
+		}
+
+		break;
+	}
+
+	/* Save the Result, delete original descriptor, store new descriptor */
+
+	ret_desc->integer.value = result;
+
+	if (walk_state->opcode != AML_STORE_OP) {
+		acpi_ut_remove_reference (*obj_desc);
+	}
+
+	*obj_desc = ret_desc;
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_convert_to_buffer
+ *
+ * PARAMETERS:  *Obj_desc       - Object to be converted.  Must be an
+ *                                Integer, Buffer, or String
+ *              Walk_state      - Current method state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert an ACPI Object to an Buffer
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_convert_to_buffer (
+	ACPI_OPERAND_OBJECT     **obj_desc,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_OPERAND_OBJECT     *ret_desc;
+	u32                     i;
+	u32                     integer_size = sizeof (ACPI_INTEGER);
+	u8                      *new_buf;
+
+
+	switch ((*obj_desc)->common.type) {
+	case ACPI_TYPE_INTEGER:
+
+		/*
+		 * Create a new Buffer
+		 */
+		ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
+		if (!ret_desc) {
+			return (AE_NO_MEMORY);
+		}
+
+		/* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */
+
+		if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) {
+			/*
+			 * We are running a method that exists in a 32-bit ACPI table.
+			 * Truncate the value to 32 bits by zeroing out the upper
+			 * 32-bit field
+			 */
+			integer_size = sizeof (u32);
+		}
+
+		/* Need enough space for one integers */
+
+		ret_desc->buffer.length = integer_size;
+		new_buf = acpi_ut_callocate (integer_size);
+		if (!new_buf) {
+			REPORT_ERROR
+				(("Ex_dyadic2_r/Concat_op: Buffer allocation failure\n"));
+			acpi_ut_remove_reference (ret_desc);
+			return (AE_NO_MEMORY);
+		}
+
+		/* Copy the integer to the buffer */
+
+		for (i = 0; i < integer_size; i++) {
+			new_buf[i] = (u8) ((*obj_desc)->integer.value >> (i * 8));
+		}
+		ret_desc->buffer.pointer = new_buf;
+
+		/* Return the new buffer descriptor */
+
+		if (walk_state->opcode != AML_STORE_OP) {
+			acpi_ut_remove_reference (*obj_desc);
+		}
+		*obj_desc = ret_desc;
+		break;
+
+
+	case ACPI_TYPE_STRING:
+		break;
+
+
+	case ACPI_TYPE_BUFFER:
+		break;
+
+
+	default:
+		return (AE_TYPE);
+		break;
+   }
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_convert_to_string
+ *
+ * PARAMETERS:  *Obj_desc       - Object to be converted.  Must be an
+ *                                Integer, Buffer, or String
+ *              Walk_state      - Current method state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert an ACPI Object to a string
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_convert_to_string (
+	ACPI_OPERAND_OBJECT     **obj_desc,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_OPERAND_OBJECT     *ret_desc;
+	u32                     i;
+	u32                     index;
+	u32                     integer_size = sizeof (ACPI_INTEGER);
+	u8                      *new_buf;
+	u8                      *pointer;
+
+
+	switch ((*obj_desc)->common.type) {
+	case ACPI_TYPE_INTEGER:
+
+		/*
+		 * Create a new String
+		 */
+		ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
+		if (!ret_desc) {
+			return (AE_NO_MEMORY);
+		}
+
+		/* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */
+
+		if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) {
+			/*
+			 * We are running a method that exists in a 32-bit ACPI table.
+			 * Truncate the value to 32 bits by zeroing out the upper
+			 * 32-bit field
+			 */
+			integer_size = sizeof (u32);
+		}
+
+		/* Need enough space for one ASCII integer plus null terminator */
+
+		ret_desc->string.length = (integer_size * 2) + 1;
+		new_buf = acpi_ut_callocate (ret_desc->string.length);
+		if (!new_buf) {
+			REPORT_ERROR
+				(("Ex_convert_to_string: Buffer allocation failure\n"));
+			acpi_ut_remove_reference (ret_desc);
+			return (AE_NO_MEMORY);
+		}
+
+		/* Copy the integer to the buffer */
+
+		for (i = 0; i < (integer_size * 2); i++) {
+			new_buf[i] = acpi_gbl_hex_to_ascii [((*obj_desc)->integer.value >> (i * 4)) & 0xF];
+		}
+
+		/* Null terminate */
+
+		new_buf [i] = 0;
+		ret_desc->buffer.pointer = new_buf;
+
+		/* Return the new buffer descriptor */
+
+		if (walk_state->opcode != AML_STORE_OP) {
+			acpi_ut_remove_reference (*obj_desc);
+		}
+		*obj_desc = ret_desc;
+
+		return (AE_OK);
+
+
+	case ACPI_TYPE_BUFFER:
+
+		if (((*obj_desc)->buffer.length * 3) > ACPI_MAX_STRING_CONVERSION) {
+			return (AE_AML_STRING_LIMIT);
+		}
+
+		/*
+		 * Create a new String
+		 */
+		ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
+		if (!ret_desc) {
+			return (AE_NO_MEMORY);
+		}
+
+		/* Need enough space for one ASCII integer plus null terminator */
+
+		ret_desc->string.length = (*obj_desc)->buffer.length * 3;
+		new_buf = acpi_ut_callocate (ret_desc->string.length + 1);
+		if (!new_buf) {
+			REPORT_ERROR
+				(("Ex_convert_to_string: Buffer allocation failure\n"));
+			acpi_ut_remove_reference (ret_desc);
+			return (AE_NO_MEMORY);
+		}
+
+		/*
+		 * Convert each byte of the buffer to two ASCII characters plus a space.
+		 */
+		pointer = (*obj_desc)->buffer.pointer;
+		index = 0;
+		for (i = 0; i < (*obj_desc)->buffer.length; i++) {
+			new_buf[index + 0] = acpi_gbl_hex_to_ascii [pointer[i] & 0x0F];
+			new_buf[index + 1] = acpi_gbl_hex_to_ascii [(pointer[i] >> 4) & 0x0F];
+			new_buf[index + 2] = ' ';
+			index += 3;
+		}
+
+		/* Null terminate */
+
+		new_buf [index] = 0;
+		ret_desc->buffer.pointer = new_buf;
+
+		/* Return the new buffer descriptor */
+
+		if (walk_state->opcode != AML_STORE_OP) {
+			acpi_ut_remove_reference (*obj_desc);
+		}
+		*obj_desc = ret_desc;
+		break;
+
+
+	case ACPI_TYPE_STRING:
+		break;
+
+
+	default:
+		return (AE_TYPE);
+		break;
+   }
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_convert_to_target_type
+ *
+ * PARAMETERS:  *Obj_desc       - Object to be converted.
+ *              Walk_state      - Current method state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION:
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_convert_to_target_type (
+	ACPI_OBJECT_TYPE8       destination_type,
+	ACPI_OPERAND_OBJECT     **obj_desc,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_STATUS             status = AE_OK;
+
+
+	/*
+	 * If required by the target,
+	 * perform implicit conversion on the source before we store it.
+	 */
+
+	switch (GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args)) {
+	case ARGI_SIMPLE_TARGET:
+	case ARGI_FIXED_TARGET:
+	case ARGI_INTEGER_REF:      /* Handles Increment, Decrement cases */
+
+		switch (destination_type) {
+		case INTERNAL_TYPE_REGION_FIELD:
+			/*
+			 * Named field can always handle conversions
+			 */
+			break;
+
+		default:
+			/* No conversion allowed for these types */
+
+			if (destination_type != (*obj_desc)->common.type) {
+				status = AE_TYPE;
+			}
+		}
+		break;
+
+
+	case ARGI_TARGETREF:
+
+		switch (destination_type) {
+		case ACPI_TYPE_INTEGER:
+		case ACPI_TYPE_BUFFER_FIELD:
+		case INTERNAL_TYPE_BANK_FIELD:
+		case INTERNAL_TYPE_INDEX_FIELD:
+			/*
+			 * These types require an Integer operand.  We can convert
+			 * a Buffer or a String to an Integer if necessary.
+			 */
+			status = acpi_ex_convert_to_integer (obj_desc, walk_state);
+			break;
+
+
+		case ACPI_TYPE_STRING:
+
+			/*
+			 * The operand must be a String.  We can convert an
+			 * Integer or Buffer if necessary
+			 */
+			status = acpi_ex_convert_to_string (obj_desc, walk_state);
+			break;
+
+
+		case ACPI_TYPE_BUFFER:
+
+			/*
+			 * The operand must be a String.  We can convert an
+			 * Integer or Buffer if necessary
+			 */
+			status = acpi_ex_convert_to_buffer (obj_desc, walk_state);
+			break;
+		}
+		break;
+
+
+	case ARGI_REFERENCE:
+		/*
+		 * Create_xxxx_field cases - we are storing the field object into the name
+		 */
+		break;
+
+
+	default:
+		status = AE_AML_INTERNAL;
+	}
+
+
+	/*
+	 * Source-to-Target conversion semantics:
+	 *
+	 * If conversion to the target type cannot be performed, then simply
+	 * overwrite the target with the new object and type.
+	 */
+	if (status == AE_TYPE) {
+		status = AE_OK;
+	}
+
+	return (status);
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/excreate.c linux/drivers/acpi/executer/excreate.c
--- v2.4.5/linux/drivers/acpi/executer/excreate.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/excreate.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,706 @@
+/******************************************************************************
+ *
+ * Module Name: excreate - Named object creation
+ *              $Revision: 63 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "acinterp.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+#include "acevents.h"
+#include "acdispat.h"
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("excreate")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_create_buffer_field
+ *
+ * PARAMETERS:  Opcode              - The opcode to be executed
+ *              Operands            - List of operands for the opcode
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute Create_field operators: Create_bit_field_op,
+ *              Create_byte_field_op, Create_word_field_op, Create_dWord_field_op,
+ *              Create_field_op (which define fields in buffers)
+ *
+ * ALLOCATION:  Deletes Create_field_op's count operand descriptor
+ *
+ *
+ *  ACPI SPECIFICATION REFERENCES:
+ *  Def_create_bit_field := Create_bit_field_op Src_buf Bit_idx   Name_string
+ *  Def_create_byte_field := Create_byte_field_op Src_buf Byte_idx Name_string
+ *  Def_create_dWord_field := Create_dWord_field_op Src_buf Byte_idx Name_string
+ *  Def_create_field    :=  Create_field_op     Src_buf Bit_idx   Num_bits    Name_string
+ *  Def_create_word_field := Create_word_field_op Src_buf Byte_idx Name_string
+ *  Bit_index           :=  Term_arg=>Integer
+ *  Byte_index          :=  Term_arg=>Integer
+ *  Num_bits            :=  Term_arg=>Integer
+ *  Source_buff         :=  Term_arg=>Buffer
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_create_buffer_field (
+	u8                      *aml_ptr,
+	u32                     aml_length,
+	ACPI_NAMESPACE_NODE     *node,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_STATUS             status;
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	ACPI_OPERAND_OBJECT     *tmp_desc;
+
+
+	/* Create the descriptor */
+
+	obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER_FIELD);
+	if (!obj_desc) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+
+
+	/*
+	 * Allocate a method object for this field unit
+	 */
+
+	obj_desc->buffer_field.extra = acpi_ut_create_internal_object (
+			   INTERNAL_TYPE_EXTRA);
+	if (!obj_desc->buffer_field.extra) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+
+	/*
+	 * Remember location in AML stream of the field unit
+	 * opcode and operands -- since the buffer and index
+	 * operands must be evaluated.
+	 */
+
+	obj_desc->buffer_field.extra->extra.pcode     = aml_ptr;
+	obj_desc->buffer_field.extra->extra.pcode_length = aml_length;
+	obj_desc->buffer_field.node = node;
+
+
+	/*
+	 * This operation is supposed to cause the destination Name to refer
+	 * to the defined Buffer_field -- it must not store the constructed
+	 * Buffer_field object (or its current value) in some location that the
+	 * Name may already be pointing to.  So, if the Name currently contains
+	 * a reference which would cause Acpi_ex_store() to perform an indirect
+	 * store rather than setting the value of the Name itself, clobber that
+	 * reference before calling Acpi_ex_store().
+	 */
+
+	/* Type of Name's existing value */
+
+	switch (acpi_ns_get_type (node)) {
+
+	case ACPI_TYPE_BUFFER_FIELD:
+	case INTERNAL_TYPE_ALIAS:
+	case INTERNAL_TYPE_REGION_FIELD:
+	case INTERNAL_TYPE_BANK_FIELD:
+	case INTERNAL_TYPE_INDEX_FIELD:
+
+		tmp_desc = acpi_ns_get_attached_object (node);
+		if (tmp_desc) {
+			/*
+			 * There is an existing object here;  delete it and zero out the
+			 * object field within the Node
+			 */
+
+			acpi_ut_remove_reference (tmp_desc);
+			acpi_ns_attach_object ((ACPI_NAMESPACE_NODE *) node, NULL,
+					 ACPI_TYPE_ANY);
+		}
+
+		/* Set the type to ANY (or the store below will fail) */
+
+		((ACPI_NAMESPACE_NODE *) node)->type = ACPI_TYPE_ANY;
+
+		break;
+
+
+	default:
+
+		break;
+	}
+
+
+	/* Store constructed field descriptor in result location */
+
+	status = acpi_ex_store (obj_desc, (ACPI_OPERAND_OBJECT *) node,
+			  walk_state);
+
+	/*
+	 * If the field descriptor was not physically stored (or if a failure
+	 * above), we must delete it
+	 */
+	if (obj_desc->common.reference_count <= 1) {
+		acpi_ut_remove_reference (obj_desc);
+	}
+
+
+	return (AE_OK);
+
+
+cleanup:
+
+	/* Delete region object and method subobject */
+
+	if (obj_desc) {
+		/* Remove deletes both objects! */
+
+		acpi_ut_remove_reference (obj_desc);
+		obj_desc = NULL;
+	}
+
+	return (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_create_alias
+ *
+ * PARAMETERS:  Walk_state           - Current state, contains List of
+ *                                      operands for the opcode
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a new named alias
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+acpi_ex_create_alias (
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_NAMESPACE_NODE     *source_node;
+	ACPI_NAMESPACE_NODE     *alias_node;
+	ACPI_STATUS             status;
+
+
+	/* Get the source/alias operands (both namespace nodes) */
+
+	status = acpi_ds_obj_stack_pop_object ((ACPI_OPERAND_OBJECT **) &source_node,
+			 walk_state);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/*
+	 * Don't pop it, it gets removed in the calling routine
+	 */
+	alias_node = acpi_ds_obj_stack_get_value (0, walk_state);
+
+	/* Add an additional reference to the object */
+
+	acpi_ut_add_reference (source_node->object);
+
+	/*
+	 * Attach the original source Node to the new Alias Node.
+	 */
+	status = acpi_ns_attach_object (alias_node, source_node->object,
+			   source_node->type);
+
+
+	/*
+	 * The new alias assumes the type of the source, but it points
+	 * to the same object.  The reference count of the object has two
+	 * additional references to prevent deletion out from under either the
+	 * source or the alias Node
+	 */
+
+	/* Since both operands are Nodes, we don't need to delete them */
+
+	return (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_create_event
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a new event object
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+acpi_ex_create_event (
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_STATUS             status;
+	ACPI_OPERAND_OBJECT     *obj_desc;
+
+
+ BREAKPOINT3;
+
+	obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_EVENT);
+	if (!obj_desc) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+
+	/* Create the actual OS semaphore */
+
+	/* TBD: [Investigate] should be created with 0 or 1 units? */
+
+	status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 1,
+			   &obj_desc->event.semaphore);
+	if (ACPI_FAILURE (status)) {
+		acpi_ut_remove_reference (obj_desc);
+		goto cleanup;
+	}
+
+	/* Attach object to the Node */
+
+	status = acpi_ns_attach_object (acpi_ds_obj_stack_get_value (0, walk_state),
+			   obj_desc, (u8) ACPI_TYPE_EVENT);
+	if (ACPI_FAILURE (status)) {
+		acpi_os_delete_semaphore (obj_desc->event.semaphore);
+		acpi_ut_remove_reference (obj_desc);
+		goto cleanup;
+	}
+
+
+cleanup:
+
+	return (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_create_mutex
+ *
+ * PARAMETERS:  Interpreter_mode    - Current running mode (load1/Load2/Exec)
+ *              Operands            - List of operands for the opcode
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a new mutex object
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+acpi_ex_create_mutex (
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_STATUS             status = AE_OK;
+	ACPI_OPERAND_OBJECT     *sync_desc;
+	ACPI_OPERAND_OBJECT     *obj_desc;
+
+
+	/* Get the operand */
+
+	status = acpi_ds_obj_stack_pop_object (&sync_desc, walk_state);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/* Attempt to allocate a new object */
+
+	obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_MUTEX);
+	if (!obj_desc) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+
+	/* Create the actual OS semaphore */
+
+	status = acpi_os_create_semaphore (1, 1, &obj_desc->mutex.semaphore);
+	if (ACPI_FAILURE (status)) {
+		acpi_ut_remove_reference (obj_desc);
+		goto cleanup;
+	}
+
+	obj_desc->mutex.sync_level = (u8) sync_desc->integer.value;
+
+	/* Obj_desc was on the stack top, and the name is below it */
+
+	status = acpi_ns_attach_object (acpi_ds_obj_stack_get_value (0, walk_state),
+			  obj_desc, (u8) ACPI_TYPE_MUTEX);
+	if (ACPI_FAILURE (status)) {
+		acpi_os_delete_semaphore (obj_desc->mutex.semaphore);
+		acpi_ut_remove_reference (obj_desc);
+		goto cleanup;
+	}
+
+
+cleanup:
+
+	/* Always delete the operand */
+
+	acpi_ut_remove_reference (sync_desc);
+
+	return (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_create_region
+ *
+ * PARAMETERS:  Aml_ptr             - Pointer to the region declaration AML
+ *              Aml_length          - Max length of the declaration AML
+ *              Operands            - List of operands for the opcode
+ *              Interpreter_mode    - Load1/Load2/Execute
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a new operation region object
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+acpi_ex_create_region (
+	u8                      *aml_ptr,
+	u32                     aml_length,
+	u8                      region_space,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_STATUS             status;
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	ACPI_NAMESPACE_NODE     *node;
+
+
+	/*
+	 * Space ID must be one of the predefined IDs, or in the user-defined
+	 * range
+	 */
+	if ((region_space >= NUM_REGION_TYPES) &&
+		(region_space < USER_REGION_BEGIN)) {
+		REPORT_ERROR (("Invalid Address_space type %X\n", region_space));
+		return (AE_AML_INVALID_SPACE_ID);
+	}
+
+
+	/* Get the Node from the object stack  */
+
+	node = (ACPI_NAMESPACE_NODE *) acpi_ds_obj_stack_get_value (0, walk_state);
+
+	/* Create the region descriptor */
+
+	obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_REGION);
+	if (!obj_desc) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+
+	/*
+	 * Allocate a method object for this region.
+	 */
+
+	obj_desc->region.extra = acpi_ut_create_internal_object (
+			 INTERNAL_TYPE_EXTRA);
+	if (!obj_desc->region.extra) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+
+	/*
+	 * Remember location in AML stream of address & length
+	 * operands since they need to be evaluated at run time.
+	 */
+
+	obj_desc->region.extra->extra.pcode      = aml_ptr;
+	obj_desc->region.extra->extra.pcode_length = aml_length;
+
+	/* Init the region from the operands */
+
+	obj_desc->region.space_id     = region_space;
+	obj_desc->region.address      = 0;
+	obj_desc->region.length       = 0;
+
+
+	/* Install the new region object in the parent Node */
+
+	obj_desc->region.node = node;
+
+	status = acpi_ns_attach_object (node, obj_desc,
+			  (u8) ACPI_TYPE_REGION);
+
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	/*
+	 * If we have a valid region, initialize it
+	 * Namespace is NOT locked at this point.
+	 */
+
+	status = acpi_ev_initialize_region (obj_desc, FALSE);
+
+	if (ACPI_FAILURE (status)) {
+		/*
+		 *  If AE_NOT_EXIST is returned, it is not fatal
+		 *  because many regions get created before a handler
+		 *  is installed for said region.
+		 */
+		if (AE_NOT_EXIST == status) {
+			status = AE_OK;
+		}
+	}
+
+cleanup:
+
+	if (ACPI_FAILURE (status)) {
+		/* Delete region object and method subobject */
+
+		if (obj_desc) {
+			/* Remove deletes both objects! */
+
+			acpi_ut_remove_reference (obj_desc);
+			obj_desc = NULL;
+		}
+	}
+
+	return (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_create_processor
+ *
+ * PARAMETERS:  Op              - Op containing the Processor definition and
+ *                                args
+ *              Processor_node  - Parent Node for the processor object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a new processor object and populate the fields
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+acpi_ex_create_processor (
+	ACPI_PARSE_OBJECT       *op,
+	ACPI_NAMESPACE_NODE     *processor_node)
+{
+	ACPI_STATUS             status;
+	ACPI_PARSE_OBJECT       *arg;
+	ACPI_OPERAND_OBJECT     *obj_desc;
+
+
+	obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_PROCESSOR);
+	if (!obj_desc) {
+		return (AE_NO_MEMORY);
+	}
+
+	/* Install the new processor object in the parent Node */
+
+	status = acpi_ns_attach_object (processor_node, obj_desc,
+			   (u8) ACPI_TYPE_PROCESSOR);
+	if (ACPI_FAILURE (status)) {
+		acpi_ut_delete_object_desc (obj_desc);
+		return (status);
+	}
+
+	/* Get first arg and verify existence */
+
+	arg = op->value.arg;
+	if (!arg) {
+		return (AE_AML_NO_OPERAND);
+	}
+
+	/* First arg is the Processor ID */
+
+	obj_desc->processor.proc_id = (u8) arg->value.integer;
+
+	/* Get second arg and verify existence */
+
+	arg = arg->next;
+	if (!arg) {
+		return (AE_AML_NO_OPERAND);
+	}
+
+	/* Second arg is the PBlock Address */
+
+	obj_desc->processor.address = (ACPI_IO_ADDRESS) arg->value.integer;
+
+	/* Get third arg and verify existence */
+
+	arg = arg->next;
+	if (!arg) {
+		return (AE_AML_NO_OPERAND);
+	}
+
+	/* Third arg is the PBlock Length */
+
+	obj_desc->processor.length = (u8) arg->value.integer;
+	return (AE_OK);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_create_power_resource
+ *
+ * PARAMETERS:  Op              - Op containing the Power_resource definition
+ *                                and args
+ *              Power_node      - Parent Node for the power object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a new Power_resource object and populate the fields
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+acpi_ex_create_power_resource (
+	ACPI_PARSE_OBJECT       *op,
+	ACPI_NAMESPACE_NODE     *power_node)
+{
+	ACPI_STATUS             status;
+	ACPI_PARSE_OBJECT       *arg;
+	ACPI_OPERAND_OBJECT     *obj_desc;
+
+
+	obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_POWER);
+	if (!obj_desc) {
+		return (AE_NO_MEMORY);
+	}
+
+	/* Install the new power resource object in the parent Node */
+
+	status = acpi_ns_attach_object (power_node, obj_desc,
+			  (u8) ACPI_TYPE_POWER);
+	if (ACPI_FAILURE (status)) {
+		return(status);
+	}
+
+
+	/* Get first arg and verify existence */
+
+	arg = op->value.arg;
+	if (!arg) {
+		return (AE_AML_NO_OPERAND);
+	}
+
+	/* First arg is the System_level */
+
+	obj_desc->power_resource.system_level = (u8) arg->value.integer;
+
+	/* Get second arg and check existence */
+
+	arg = arg->next;
+	if (!arg) {
+		return (AE_AML_NO_OPERAND);
+	}
+
+	/* Second arg is the PBlock Address */
+
+	obj_desc->power_resource.resource_order = (u16) arg->value.integer;
+
+	return (AE_OK);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_create_method
+ *
+ * PARAMETERS:  Aml_ptr         - First byte of the method's AML
+ *              Aml_length      - AML byte count for this method
+ *              Method_flags    - AML method flag byte
+ *              Method          - Method Node
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a new method object
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+acpi_ex_create_method (
+	u8                      *aml_ptr,
+	u32                     aml_length,
+	u32                     method_flags,
+	ACPI_NAMESPACE_NODE     *method)
+{
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	ACPI_STATUS             status;
+
+
+	/* Create a new method object */
+
+	obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_METHOD);
+	if (!obj_desc) {
+	   return (AE_NO_MEMORY);
+	}
+
+	/* Get the method's AML pointer/length from the Op */
+
+	obj_desc->method.pcode      = aml_ptr;
+	obj_desc->method.pcode_length = aml_length;
+
+	/*
+	 * First argument is the Method Flags (contains parameter count for the
+	 * method)
+	 */
+
+	obj_desc->method.method_flags = (u8) method_flags;
+	obj_desc->method.param_count = (u8) (method_flags &
+			  METHOD_FLAGS_ARG_COUNT);
+
+	/*
+	 * Get the concurrency count.  If required, a semaphore will be
+	 * created for this method when it is parsed.
+	 */
+	if (method_flags & METHOD_FLAGS_SERIALIZED) {
+		/*
+		 * ACPI 1.0: Concurrency = 1
+		 * ACPI 2.0: Concurrency = (Sync_level (in method declaration) + 1)
+		 */
+		obj_desc->method.concurrency = (u8)
+				  (((method_flags & METHOD_FLAGS_SYNCH_LEVEL) >> 4) + 1);
+	}
+
+	else {
+		obj_desc->method.concurrency = INFINITE_CONCURRENCY;
+	}
+
+	/* Attach the new object to the method Node */
+
+	status = acpi_ns_attach_object (method, obj_desc, (u8) ACPI_TYPE_METHOD);
+	if (ACPI_FAILURE (status)) {
+		acpi_ut_delete_object_desc (obj_desc);
+	}
+
+	return (status);
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exdump.c linux/drivers/acpi/executer/exdump.c
--- v2.4.5/linux/drivers/acpi/executer/exdump.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exdump.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,41 @@
+/******************************************************************************
+ *
+ * Module Name: exdump - Interpreter debug output routines
+ *              $Revision: 114 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acinterp.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+#include "actables.h"
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exdump")
+
+
+/*
+ * The following routines are used for debug output only
+ */
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exdyadic.c linux/drivers/acpi/executer/exdyadic.c
--- v2.4.5/linux/drivers/acpi/executer/exdyadic.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exdyadic.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,874 @@
+/******************************************************************************
+ *
+ * Module Name: exdyadic - ACPI AML (p-code) execution for dyadic operators
+ *              $Revision: 77 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "acnamesp.h"
+#include "acinterp.h"
+#include "acevents.h"
+#include "amlcode.h"
+#include "acdispat.h"
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exdyadic")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_do_concatenate
+ *
+ * PARAMETERS:  *Obj_desc       - Object to be converted.  Must be an
+ *                                Integer, Buffer, or String
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Concatenate two objects OF THE SAME TYPE.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_do_concatenate (
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	ACPI_OPERAND_OBJECT     *obj_desc2,
+	ACPI_OPERAND_OBJECT     **actual_ret_desc,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_STATUS             status;
+	u32                     i;
+	ACPI_INTEGER            this_integer;
+	ACPI_OPERAND_OBJECT     *ret_desc;
+	NATIVE_CHAR             *new_buf;
+	u32                     integer_size = sizeof (ACPI_INTEGER);
+
+
+	/*
+	 * There are three cases to handle:
+	 * 1) Two Integers concatenated to produce a buffer
+	 * 2) Two Strings concatenated to produce a string
+	 * 3) Two Buffers concatenated to produce a buffer
+	 */
+	switch (obj_desc->common.type) {
+	case ACPI_TYPE_INTEGER:
+
+		/* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */
+
+		if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) {
+			/*
+			 * We are running a method that exists in a 32-bit ACPI table.
+			 * Truncate the value to 32 bits by zeroing out the upper
+			 * 32-bit field
+			 */
+			integer_size = sizeof (u32);
+		}
+
+		/* Result of two integers is a buffer */
+
+		ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
+		if (!ret_desc) {
+			return (AE_NO_MEMORY);
+		}
+
+		/* Need enough space for two integers */
+
+		ret_desc->buffer.length = integer_size * 2;
+		new_buf = acpi_ut_callocate (ret_desc->buffer.length);
+		if (!new_buf) {
+			REPORT_ERROR
+				(("Ex_do_concatenate: Buffer allocation failure\n"));
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		ret_desc->buffer.pointer = (u8 *) new_buf;
+
+		/* Convert the first integer */
+
+		this_integer = obj_desc->integer.value;
+		for (i = 0; i < integer_size; i++) {
+			new_buf[i] = (u8) this_integer;
+			this_integer >>= 8;
+		}
+
+		/* Convert the second integer */
+
+		this_integer = obj_desc2->integer.value;
+		for (; i < (integer_size * 2); i++) {
+			new_buf[i] = (u8) this_integer;
+			this_integer >>= 8;
+		}
+
+		break;
+
+
+	case ACPI_TYPE_STRING:
+
+		ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
+		if (!ret_desc) {
+			return (AE_NO_MEMORY);
+		}
+
+		/* Operand1 is string  */
+
+		new_buf = acpi_ut_allocate (obj_desc->string.length +
+				  obj_desc2->string.length + 1);
+		if (!new_buf) {
+			REPORT_ERROR
+				(("Ex_do_concatenate: String allocation failure\n"));
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		STRCPY (new_buf, obj_desc->string.pointer);
+		STRCPY (new_buf + obj_desc->string.length,
+				  obj_desc2->string.pointer);
+
+		/* Point the return object to the new string */
+
+		ret_desc->string.pointer = new_buf;
+		ret_desc->string.length = obj_desc->string.length +=
+				  obj_desc2->string.length;
+		break;
+
+
+	case ACPI_TYPE_BUFFER:
+
+		/* Operand1 is a buffer */
+
+		ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
+		if (!ret_desc) {
+			return (AE_NO_MEMORY);
+		}
+
+		new_buf = acpi_ut_allocate (obj_desc->buffer.length +
+				  obj_desc2->buffer.length);
+		if (!new_buf) {
+			REPORT_ERROR
+				(("Ex_do_concatenate: Buffer allocation failure\n"));
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		MEMCPY (new_buf, obj_desc->buffer.pointer,
+				  obj_desc->buffer.length);
+		MEMCPY (new_buf + obj_desc->buffer.length, obj_desc2->buffer.pointer,
+				  obj_desc2->buffer.length);
+
+		/*
+		 * Point the return object to the new buffer
+		 */
+
+		ret_desc->buffer.pointer    = (u8 *) new_buf;
+		ret_desc->buffer.length     = obj_desc->buffer.length +
+				 obj_desc2->buffer.length;
+		break;
+
+	default:
+		status = AE_AML_INTERNAL;
+		ret_desc = NULL;
+	}
+
+
+	*actual_ret_desc = ret_desc;
+	return (AE_OK);
+
+
+cleanup:
+
+	acpi_ut_remove_reference (ret_desc);
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_dyadic1
+ *
+ * PARAMETERS:  Opcode              - The opcode to be executed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute Type 1 dyadic operator with numeric operands:
+ *              Notify_op
+ *
+ * ALLOCATION:  Deletes both operands
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_dyadic1 (
+	u16                     opcode,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_OPERAND_OBJECT     *obj_desc = NULL;
+	ACPI_OPERAND_OBJECT     *val_desc = NULL;
+	ACPI_NAMESPACE_NODE     *node;
+	ACPI_STATUS             status = AE_OK;
+
+
+	/* Resolve all operands */
+
+	status = acpi_ex_resolve_operands (opcode, WALK_OPERANDS, walk_state);
+	/* Get the operands */
+
+	status |= acpi_ds_obj_stack_pop_object (&val_desc, walk_state);
+	status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
+	if (ACPI_FAILURE (status)) {
+		/* Invalid parameters on object stack  */
+
+		goto cleanup;
+	}
+
+
+	/* Examine the opcode */
+
+	switch (opcode) {
+
+	/* Def_notify  :=  Notify_op   Notify_object   Notify_value */
+
+	case AML_NOTIFY_OP:
+
+		/* The Obj_desc is actually an Node */
+
+		node = (ACPI_NAMESPACE_NODE *) obj_desc;
+		obj_desc = NULL;
+
+		/* Object must be a device or thermal zone */
+
+		if (node && val_desc) {
+			switch (node->type) {
+			case ACPI_TYPE_DEVICE:
+			case ACPI_TYPE_THERMAL:
+
+				/*
+				 * Dispatch the notify to the appropriate handler
+				 * NOTE: the request is queued for execution after this method
+				 * completes.  The notify handlers are NOT invoked synchronously
+				 * from this thread -- because handlers may in turn run other
+				 * control methods.
+				 */
+
+				status = acpi_ev_queue_notify_request (node,
+						 (u32) val_desc->integer.value);
+				break;
+
+			default:
+				status = AE_AML_OPERAND_TYPE;
+				break;
+			}
+		}
+		break;
+
+	default:
+
+		REPORT_ERROR (("Acpi_ex_dyadic1: Unknown dyadic opcode %X\n", opcode));
+		status = AE_AML_BAD_OPCODE;
+	}
+
+
+cleanup:
+
+	/* Always delete both operands */
+
+	acpi_ut_remove_reference (val_desc);
+	acpi_ut_remove_reference (obj_desc);
+
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_dyadic2_r
+ *
+ * PARAMETERS:  Opcode              - The opcode to be executed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute Type 2 dyadic operator with numeric operands and
+ *              one or two result operands.
+ *
+ * ALLOCATION:  Deletes one operand descriptor -- other remains on stack
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_dyadic2_r (
+	u16                     opcode,
+	ACPI_WALK_STATE         *walk_state,
+	ACPI_OPERAND_OBJECT     **return_desc)
+{
+	ACPI_OPERAND_OBJECT     *obj_desc   = NULL;
+	ACPI_OPERAND_OBJECT     *obj_desc2  = NULL;
+	ACPI_OPERAND_OBJECT     *res_desc   = NULL;
+	ACPI_OPERAND_OBJECT     *res_desc2  = NULL;
+	ACPI_OPERAND_OBJECT     *ret_desc   = NULL;
+	ACPI_OPERAND_OBJECT     *ret_desc2  = NULL;
+	ACPI_STATUS             status      = AE_OK;
+	u32                     num_operands = 3;
+
+
+	/* Resolve all operands */
+
+	status = acpi_ex_resolve_operands (opcode, WALK_OPERANDS, walk_state);
+	/* Get all operands */
+
+	if (AML_DIVIDE_OP == opcode) {
+		num_operands = 4;
+		status |= acpi_ds_obj_stack_pop_object (&res_desc2, walk_state);
+	}
+
+	status |= acpi_ds_obj_stack_pop_object (&res_desc, walk_state);
+	status |= acpi_ds_obj_stack_pop_object (&obj_desc2, walk_state);
+	status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+
+	/* Create an internal return object if necessary */
+
+	switch (opcode) {
+	case AML_ADD_OP:
+	case AML_BIT_AND_OP:
+	case AML_BIT_NAND_OP:
+	case AML_BIT_OR_OP:
+	case AML_BIT_NOR_OP:
+	case AML_BIT_XOR_OP:
+	case AML_DIVIDE_OP:
+	case AML_MULTIPLY_OP:
+	case AML_SHIFT_LEFT_OP:
+	case AML_SHIFT_RIGHT_OP:
+	case AML_SUBTRACT_OP:
+
+		ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!ret_desc) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		break;
+	}
+
+
+	/*
+	 * Execute the opcode
+	 */
+
+	switch (opcode) {
+
+	/* Def_add :=  Add_op  Operand1    Operand2    Result  */
+
+	case AML_ADD_OP:
+
+		ret_desc->integer.value = obj_desc->integer.value +
+				 obj_desc2->integer.value;
+		break;
+
+
+	/* Def_and :=  And_op  Operand1    Operand2    Result  */
+
+	case AML_BIT_AND_OP:
+
+		ret_desc->integer.value = obj_desc->integer.value &
+				 obj_desc2->integer.value;
+		break;
+
+
+	/* Def_nAnd := NAnd_op Operand1    Operand2    Result  */
+
+	case AML_BIT_NAND_OP:
+
+		ret_desc->integer.value = ~(obj_desc->integer.value &
+				   obj_desc2->integer.value);
+		break;
+
+
+	/* Def_or  :=  Or_op   Operand1    Operand2    Result  */
+
+	case AML_BIT_OR_OP:
+
+		ret_desc->integer.value = obj_desc->integer.value |
+				 obj_desc2->integer.value;
+		break;
+
+
+	/* Def_nOr :=  NOr_op  Operand1    Operand2    Result  */
+
+	case AML_BIT_NOR_OP:
+
+		ret_desc->integer.value = ~(obj_desc->integer.value |
+				   obj_desc2->integer.value);
+		break;
+
+
+	/* Def_xOr :=  XOr_op  Operand1    Operand2    Result  */
+
+	case AML_BIT_XOR_OP:
+
+		ret_desc->integer.value = obj_desc->integer.value ^
+				 obj_desc2->integer.value;
+		break;
+
+
+	/* Def_divide  :=  Divide_op Dividend Divisor Remainder Quotient */
+
+	case AML_DIVIDE_OP:
+
+		if (!obj_desc2->integer.value) {
+			REPORT_ERROR
+				(("Ex_dyadic2_r/Divide_op: Divide by zero\n"));
+
+			status = AE_AML_DIVIDE_BY_ZERO;
+			goto cleanup;
+		}
+
+		ret_desc2 = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!ret_desc2) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		/* Remainder (modulo) */
+
+		ret_desc->integer.value  = ACPI_MODULO (obj_desc->integer.value,
+				  obj_desc2->integer.value);
+
+		/* Result (what we used to call the quotient) */
+
+		ret_desc2->integer.value = ACPI_DIVIDE (obj_desc->integer.value,
+				  obj_desc2->integer.value);
+		break;
+
+
+	/* Def_multiply := Multiply_op Operand1    Operand2    Result  */
+
+	case AML_MULTIPLY_OP:
+
+		ret_desc->integer.value = obj_desc->integer.value *
+				 obj_desc2->integer.value;
+		break;
+
+
+	/* Def_shift_left  :=  Shift_left_op Operand Shift_count Result */
+
+	case AML_SHIFT_LEFT_OP:
+
+		ret_desc->integer.value = obj_desc->integer.value <<
+				 obj_desc2->integer.value;
+		break;
+
+
+	/* Def_shift_right :=  Shift_right_op  Operand Shift_count Result  */
+
+	case AML_SHIFT_RIGHT_OP:
+
+		ret_desc->integer.value = obj_desc->integer.value >>
+				 obj_desc2->integer.value;
+		break;
+
+
+	/* Def_subtract := Subtract_op Operand1    Operand2    Result  */
+
+	case AML_SUBTRACT_OP:
+
+		ret_desc->integer.value = obj_desc->integer.value -
+				 obj_desc2->integer.value;
+		break;
+
+
+	/* Def_concat  :=  Concat_op   Data1   Data2   Result  */
+
+	case AML_CONCAT_OP:
+
+
+		/*
+		 * Convert the second operand if necessary.  The first operand
+		 * determines the type of the second operand, (See the Data Types
+		 * section of the ACPI specification.)  Both object types are
+		 * guaranteed to be either Integer/String/Buffer by the operand
+		 * resolution mechanism above.
+		 */
+
+		switch (obj_desc->common.type) {
+		case ACPI_TYPE_INTEGER:
+			status = acpi_ex_convert_to_integer (&obj_desc2, walk_state);
+			break;
+
+		case ACPI_TYPE_STRING:
+			status = acpi_ex_convert_to_string (&obj_desc2, walk_state);
+			break;
+
+		case ACPI_TYPE_BUFFER:
+			status = acpi_ex_convert_to_buffer (&obj_desc2, walk_state);
+			break;
+
+		default:
+			status = AE_AML_INTERNAL;
+		}
+
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+
+
+		/*
+		 * Both operands are now known to be the same object type
+		 * (Both are Integer, String, or Buffer), and we can now perform the
+		 * concatenation.
+		 */
+		status = acpi_ex_do_concatenate (obj_desc, obj_desc2, &ret_desc, walk_state);
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+		break;
+
+
+	default:
+
+		REPORT_ERROR (("Acpi_ex_dyadic2_r: Unknown dyadic opcode %X\n",
+				opcode));
+		status = AE_AML_BAD_OPCODE;
+		goto cleanup;
+	}
+
+
+	/*
+	 * Store the result of the operation (which is now in Obj_desc) into
+	 * the result descriptor, or the location pointed to by the result
+	 * descriptor (Res_desc).
+	 */
+
+	status = acpi_ex_store (ret_desc, res_desc, walk_state);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	if (AML_DIVIDE_OP == opcode) {
+		status = acpi_ex_store (ret_desc2, res_desc2, walk_state);
+
+		/*
+		 * Since the remainder is not returned, remove a reference to
+		 * the object we created earlier
+		 */
+
+		acpi_ut_remove_reference (ret_desc2);
+	}
+
+
+cleanup:
+
+	/* Always delete the operands */
+
+	acpi_ut_remove_reference (obj_desc);
+	acpi_ut_remove_reference (obj_desc2);
+
+
+	/* Delete return object on error */
+
+	if (ACPI_FAILURE (status)) {
+		/* On failure, delete the result ops */
+
+		acpi_ut_remove_reference (res_desc);
+		acpi_ut_remove_reference (res_desc2);
+
+		if (ret_desc) {
+			/* And delete the internal return object */
+
+			acpi_ut_remove_reference (ret_desc);
+			ret_desc = NULL;
+		}
+	}
+
+	/* Set the return object and exit */
+
+	*return_desc = ret_desc;
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_dyadic2_s
+ *
+ * PARAMETERS:  Opcode              - The opcode to be executed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute Type 2 dyadic synchronization operator
+ *
+ * ALLOCATION:  Deletes one operand descriptor -- other remains on stack
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_dyadic2_s (
+	u16                     opcode,
+	ACPI_WALK_STATE         *walk_state,
+	ACPI_OPERAND_OBJECT     **return_desc)
+{
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	ACPI_OPERAND_OBJECT     *time_desc;
+	ACPI_OPERAND_OBJECT     *ret_desc = NULL;
+	ACPI_STATUS             status;
+
+
+	/* Resolve all operands */
+
+	status = acpi_ex_resolve_operands (opcode, WALK_OPERANDS, walk_state);
+	/* Get all operands */
+
+	status |= acpi_ds_obj_stack_pop_object (&time_desc, walk_state);
+	status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
+	if (ACPI_FAILURE (status)) {
+		/* Invalid parameters on object stack  */
+
+		goto cleanup;
+	}
+
+
+	/* Create the internal return object */
+
+	ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+	if (!ret_desc) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+
+	/* Default return value is FALSE, operation did not time out */
+
+	ret_desc->integer.value = 0;
+
+
+	/* Examine the opcode */
+
+	switch (opcode) {
+
+	/* Def_acquire :=  Acquire_op  Mutex_object Timeout */
+
+	case AML_ACQUIRE_OP:
+
+		status = acpi_ex_acquire_mutex (time_desc, obj_desc, walk_state);
+		break;
+
+
+	/* Def_wait := Wait_op Acpi_event_object Timeout */
+
+	case AML_WAIT_OP:
+
+		status = acpi_ex_system_wait_event (time_desc, obj_desc);
+		break;
+
+
+	default:
+
+		REPORT_ERROR (("Acpi_ex_dyadic2_s: Unknown dyadic synchronization opcode %X\n", opcode));
+		status = AE_AML_BAD_OPCODE;
+		goto cleanup;
+	}
+
+
+	/*
+	 * Return a boolean indicating if operation timed out
+	 * (TRUE) or not (FALSE)
+	 */
+
+	if (status == AE_TIME) {
+		ret_desc->integer.value = ACPI_INTEGER_MAX;  /* TRUE, op timed out */
+		status = AE_OK;
+	}
+
+
+cleanup:
+
+	/* Delete params */
+
+	acpi_ut_remove_reference (time_desc);
+	acpi_ut_remove_reference (obj_desc);
+
+	/* Delete return object on error */
+
+	if (ACPI_FAILURE (status) &&
+		(ret_desc)) {
+		acpi_ut_remove_reference (ret_desc);
+		ret_desc = NULL;
+	}
+
+
+	/* Set the return object and exit */
+
+	*return_desc = ret_desc;
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_dyadic2
+ *
+ * PARAMETERS:  Opcode              - The opcode to be executed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute Type 2 dyadic operator with numeric operands and
+ *              no result operands
+ *
+ * ALLOCATION:  Deletes one operand descriptor -- other remains on stack
+ *              containing result value
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_dyadic2 (
+	u16                     opcode,
+	ACPI_WALK_STATE         *walk_state,
+	ACPI_OPERAND_OBJECT     **return_desc)
+{
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	ACPI_OPERAND_OBJECT     *obj_desc2;
+	ACPI_OPERAND_OBJECT     *ret_desc = NULL;
+	ACPI_STATUS             status;
+	u8                      lboolean;
+
+
+	/* Resolve all operands */
+
+	status = acpi_ex_resolve_operands (opcode, WALK_OPERANDS, walk_state);
+	/* Get all operands */
+
+	status |= acpi_ds_obj_stack_pop_object (&obj_desc2, walk_state);
+	status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
+	if (ACPI_FAILURE (status)) {
+		/* Invalid parameters on object stack  */
+
+		goto cleanup;
+	}
+
+
+	/* Create the internal return object */
+
+	ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+	if (!ret_desc) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+
+	/*
+	 * Execute the Opcode
+	 */
+
+	lboolean = FALSE;
+	switch (opcode) {
+
+	/* Def_lAnd := LAnd_op Operand1    Operand2    */
+
+	case AML_LAND_OP:
+
+		lboolean = (u8) (obj_desc->integer.value &&
+				  obj_desc2->integer.value);
+		break;
+
+
+	/* Def_lEqual  :=  LEqual_op   Operand1    Operand2    */
+
+	case AML_LEQUAL_OP:
+
+		lboolean = (u8) (obj_desc->integer.value ==
+				  obj_desc2->integer.value);
+		break;
+
+
+	/* Def_lGreater := LGreater_op Operand1    Operand2    */
+
+	case AML_LGREATER_OP:
+
+		lboolean = (u8) (obj_desc->integer.value >
+				  obj_desc2->integer.value);
+		break;
+
+
+	/* Def_lLess   :=  LLess_op Operand1   Operand2    */
+
+	case AML_LLESS_OP:
+
+		lboolean = (u8) (obj_desc->integer.value <
+				  obj_desc2->integer.value);
+		break;
+
+
+	/* Def_lOr :=  LOr_op  Operand1    Operand2    */
+
+	case AML_LOR_OP:
+
+		lboolean = (u8) (obj_desc->integer.value ||
+				  obj_desc2->integer.value);
+		break;
+
+
+	default:
+
+		REPORT_ERROR (("Acpi_ex_dyadic2: Unknown dyadic opcode %X\n", opcode));
+		status = AE_AML_BAD_OPCODE;
+		goto cleanup;
+		break;
+	}
+
+
+	/* Set return value to logical TRUE (all ones) or FALSE (zero) */
+
+	if (lboolean) {
+		ret_desc->integer.value = ACPI_INTEGER_MAX;
+	}
+	else {
+		ret_desc->integer.value = 0;
+	}
+
+
+cleanup:
+
+	/* Always delete operands */
+
+	acpi_ut_remove_reference (obj_desc);
+	acpi_ut_remove_reference (obj_desc2);
+
+
+	/* Delete return object on error */
+
+	if (ACPI_FAILURE (status) &&
+		(ret_desc)) {
+		acpi_ut_remove_reference (ret_desc);
+		ret_desc = NULL;
+	}
+
+
+	/* Set the return object and exit */
+
+	*return_desc = ret_desc;
+	return (status);
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exfield.c linux/drivers/acpi/executer/exfield.c
--- v2.4.5/linux/drivers/acpi/executer/exfield.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exfield.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,498 @@
+/******************************************************************************
+ *
+ * Module Name: exfield - ACPI AML (p-code) execution - field manipulation
+ *              $Revision: 90 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acdispat.h"
+#include "acinterp.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+#include "achware.h"
+#include "acevents.h"
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exfield")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_read_data_from_field
+ *
+ * PARAMETERS:  Mode                - ACPI_READ or ACPI_WRITE
+ *              *Field_node         - Parent node for field to be accessed
+ *              *Buffer             - Value(s) to be read or written
+ *              Buffer_length       - Number of bytes to transfer
+ *
+ * RETURN:      Status3
+ *
+ * DESCRIPTION: Read or write a named field
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_read_data_from_field (
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	ACPI_OPERAND_OBJECT     **ret_buffer_desc)
+{
+	ACPI_STATUS             status;
+	ACPI_OPERAND_OBJECT     *buffer_desc;
+	u32                     length;
+	void                    *buffer;
+
+
+	/* Parameter validation */
+
+	if (!obj_desc) {
+		return (AE_AML_NO_OPERAND);
+	}
+
+	/*
+	 * Allocate a buffer for the contents of the field.
+	 *
+	 * If the field is larger than the size of an ACPI_INTEGER, create
+	 * a BUFFER to hold it.  Otherwise, use an INTEGER.  This allows
+	 * the use of arithmetic operators on the returned value if the
+	 * field size is equal or smaller than an Integer.
+	 *
+	 * Note: Field.length is in bits.
+	 */
+
+	length = ROUND_BITS_UP_TO_BYTES (obj_desc->field.bit_length);
+
+	if (length > sizeof (ACPI_INTEGER)) {
+		/* Field is too large for an Integer, create a Buffer instead */
+
+		buffer_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
+		if (!buffer_desc) {
+			return (AE_NO_MEMORY);
+		}
+
+		/* Create the actual read buffer */
+
+		buffer_desc->buffer.pointer = acpi_ut_callocate (length);
+		if (!buffer_desc->buffer.pointer) {
+			acpi_ut_remove_reference (buffer_desc);
+			return (AE_NO_MEMORY);
+		}
+
+		buffer_desc->buffer.length = length;
+		buffer = buffer_desc->buffer.pointer;
+	}
+
+	else {
+		/* Field will fit within an Integer (normal case) */
+
+		buffer_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!buffer_desc) {
+			return (AE_NO_MEMORY);
+		}
+
+		length = sizeof (buffer_desc->integer.value);
+		buffer = &buffer_desc->integer.value;
+	}
+
+
+	/* Read from the appropriate field */
+
+	switch (obj_desc->common.type) {
+	case ACPI_TYPE_BUFFER_FIELD:
+		status = acpi_ex_access_buffer_field (ACPI_READ, obj_desc, buffer, length);
+		break;
+
+	case INTERNAL_TYPE_REGION_FIELD:
+		status = acpi_ex_access_region_field (ACPI_READ, obj_desc, buffer, length);
+		break;
+
+	case INTERNAL_TYPE_BANK_FIELD:
+		status = acpi_ex_access_bank_field (ACPI_READ, obj_desc, buffer, length);
+		break;
+
+	case INTERNAL_TYPE_INDEX_FIELD:
+		status = acpi_ex_access_index_field (ACPI_READ, obj_desc, buffer, length);
+		break;
+
+	default:
+		status = AE_AML_INTERNAL;
+	}
+
+
+	if (ACPI_FAILURE (status)) {
+		acpi_ut_remove_reference (buffer_desc);
+	}
+
+	else if (ret_buffer_desc) {
+		*ret_buffer_desc = buffer_desc;
+	}
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_write_data_to_field
+ *
+ * PARAMETERS:  Mode                - ACPI_READ or ACPI_WRITE
+ *              *Field_node         - Parent node for field to be accessed
+ *              *Buffer             - Value(s) to be read or written
+ *              Buffer_length       - Number of bytes to transfer
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Read or write a named field
+ *
+ ******************************************************************************/
+
+
+ACPI_STATUS
+acpi_ex_write_data_to_field (
+	ACPI_OPERAND_OBJECT     *source_desc,
+	ACPI_OPERAND_OBJECT     *obj_desc)
+{
+	ACPI_STATUS             status;
+	u32                     length;
+	void                    *buffer;
+
+
+	/* Parameter validation */
+
+	if (!source_desc || !obj_desc) {
+		return (AE_AML_NO_OPERAND);
+	}
+
+
+	/*
+	 * Get a pointer to the data to be written
+	 */
+	switch (source_desc->common.type) {
+	case ACPI_TYPE_INTEGER:
+		buffer = &source_desc->integer.value;
+		length = sizeof (source_desc->integer.value);
+		break;
+
+	case ACPI_TYPE_BUFFER:
+		buffer = source_desc->buffer.pointer;
+		length = source_desc->buffer.length;
+		break;
+
+	case ACPI_TYPE_STRING:
+		buffer = source_desc->string.pointer;
+		length = source_desc->string.length;
+		break;
+
+	default:
+		return (AE_AML_OPERAND_TYPE);
+	}
+
+
+	/*
+	 * Decode the type of field to be written
+	 */
+	switch (obj_desc->common.type) {
+	case ACPI_TYPE_BUFFER_FIELD:
+		status = acpi_ex_access_buffer_field (ACPI_WRITE, obj_desc, buffer, length);
+		break;
+
+	case INTERNAL_TYPE_REGION_FIELD:
+		status = acpi_ex_access_region_field (ACPI_WRITE, obj_desc, buffer, length);
+		break;
+
+	case INTERNAL_TYPE_BANK_FIELD:
+		status = acpi_ex_access_bank_field (ACPI_WRITE, obj_desc, buffer, length);
+		break;
+
+	case INTERNAL_TYPE_INDEX_FIELD:
+		status = acpi_ex_access_index_field (ACPI_WRITE, obj_desc, buffer, length);
+		break;
+
+	default:
+		return (AE_AML_INTERNAL);
+	}
+
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_access_buffer_field
+ *
+ * PARAMETERS:  Mode                - ACPI_READ or ACPI_WRITE
+ *              *Field_node         - Parent node for field to be accessed
+ *              *Buffer             - Value(s) to be read or written
+ *              Buffer_length       - Number of bytes to transfer
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Read or write a named field
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_access_buffer_field (
+	u32                     mode,
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	void                    *buffer,
+	u32                     buffer_length)
+{
+	ACPI_STATUS             status;
+
+
+	/*
+	 * If the Buffer_field arguments have not been previously evaluated,
+	 * evaluate them now and save the results.
+	 */
+	if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
+		status = acpi_ds_get_buffer_field_arguments (obj_desc);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+	}
+
+
+	status = acpi_ex_common_access_field (mode, obj_desc, buffer, buffer_length);
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_access_region_field
+ *
+ * PARAMETERS:  Mode                - ACPI_READ or ACPI_WRITE
+ *              *Field_node         - Parent node for field to be accessed
+ *              *Buffer             - Value(s) to be read or written
+ *              Buffer_length       - Number of bytes to transfer
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Read or write a named field
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_access_region_field (
+	u32                     mode,
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	void                    *buffer,
+	u32                     buffer_length)
+{
+	ACPI_STATUS             status;
+	u8                      locked;
+
+
+	/*
+	 * Get the global lock if needed
+	 */
+	locked = acpi_ex_acquire_global_lock (obj_desc->field.lock_rule);
+
+	status = acpi_ex_common_access_field (mode, obj_desc, buffer, buffer_length);
+
+
+	/*
+	 * Release global lock if we acquired it earlier
+	 */
+	acpi_ex_release_global_lock (locked);
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_access_bank_field
+ *
+ * PARAMETERS:  Mode                - ACPI_READ or ACPI_WRITE
+ *              *Field_node         - Parent node for field to be accessed
+ *              *Buffer             - Value(s) to be read or written
+ *              Buffer_length       - Number of bytes to transfer
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Read or write a Bank Field
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_access_bank_field (
+	u32                     mode,
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	void                    *buffer,
+	u32                     buffer_length)
+{
+	ACPI_STATUS             status;
+	u8                      locked;
+
+
+	/*
+	 * Get the global lock if needed
+	 */
+	locked = acpi_ex_acquire_global_lock (obj_desc->bank_field.lock_rule);
+
+
+	/*
+	 * Write the Bank_value to the Bank_register to select the bank.
+	 * The Bank_value for this Bank_field is specified in the
+	 * Bank_field ASL declaration. The Bank_register is always a Field in
+	 * an operation region.
+	 */
+
+	status = acpi_ex_common_access_field (ACPI_WRITE,
+			 obj_desc->bank_field.bank_register_obj,
+			 &obj_desc->bank_field.value,
+			 sizeof (obj_desc->bank_field.value));
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	/*
+	 * The bank was successfully selected, now read or write the actual
+	 * data.
+	 */
+	status = acpi_ex_common_access_field (mode, obj_desc, buffer, buffer_length);
+
+
+cleanup:
+	/*
+	 * Release global lock if we acquired it earlier
+	 */
+	acpi_ex_release_global_lock (locked);
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_access_index_field
+ *
+ * PARAMETERS:  Mode                - ACPI_READ or ACPI_WRITE
+ *              *Field_node         - Parent node for field to be accessed
+ *              *Buffer             - Value(s) to be read or written
+ *              Buffer_length       - Number of bytes to transfer
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Read or write a Index Field
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_access_index_field (
+	u32                     mode,
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	void                    *buffer,
+	u32                     buffer_length)
+{
+	ACPI_STATUS             status;
+	u8                      locked;
+
+
+	/*
+	 * Get the global lock if needed
+	 */
+	locked = acpi_ex_acquire_global_lock (obj_desc->index_field.lock_rule);
+
+
+	/*
+	 * Set Index value to select proper Data register
+	 */
+	status = acpi_ex_common_access_field (ACPI_WRITE,
+			 obj_desc->index_field.index_obj,
+			 &obj_desc->index_field.value,
+			 sizeof (obj_desc->index_field.value));
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	/* Now read/write the data register */
+
+	status = acpi_ex_common_access_field (mode, obj_desc->index_field.data_obj,
+			  buffer, buffer_length);
+
+cleanup:
+	/*
+	 * Release global lock if we acquired it earlier
+	 */
+	acpi_ex_release_global_lock (locked);
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_common_access_field
+ *
+ * PARAMETERS:  Mode                - ACPI_READ or ACPI_WRITE
+ *              *Field_node         - Parent node for field to be accessed
+ *              *Buffer             - Value(s) to be read or written
+ *              Buffer_length       - Size of buffer, in bytes.  Must be large
+ *                                    enough for all bits of the field.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Read or write a named field
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_common_access_field (
+	u32                     mode,
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	void                    *buffer,
+	u32                     buffer_length)
+{
+	ACPI_STATUS             status;
+
+
+	/* Perform the actual read or write of the field */
+
+	switch (mode) {
+	case ACPI_READ:
+
+		status = acpi_ex_extract_from_field (obj_desc, buffer, buffer_length);
+		break;
+
+
+	case ACPI_WRITE:
+
+		status = acpi_ex_insert_into_field (obj_desc, buffer, buffer_length);
+		break;
+
+
+	default:
+
+		status = AE_BAD_PARAMETER;
+		break;
+	}
+
+
+	return (status);
+}
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exfldio.c linux/drivers/acpi/executer/exfldio.c
--- v2.4.5/linux/drivers/acpi/executer/exfldio.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exfldio.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,827 @@
+/******************************************************************************
+ *
+ * Module Name: exfldio - Aml Field I/O
+ *              $Revision: 57 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acinterp.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+#include "achware.h"
+#include "acevents.h"
+#include "acdispat.h"
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exfldio")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_setup_field
+ *
+ * PARAMETERS:  *Obj_desc           - Field to be read or written
+ *              Field_datum_byte_offset  - Current offset into the field
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Common processing for Acpi_ex_extract_from_field and
+ *              Acpi_ex_insert_into_field
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_setup_field (
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	u32                     field_datum_byte_offset)
+{
+	ACPI_STATUS             status = AE_OK;
+	ACPI_OPERAND_OBJECT     *rgn_desc;
+
+
+	/* Parameter validation */
+
+	rgn_desc = obj_desc->common_field.region_obj;
+	if (!obj_desc || !rgn_desc) {
+		return (AE_AML_NO_OPERAND);
+	}
+
+	if (ACPI_TYPE_REGION != rgn_desc->common.type) {
+		return (AE_AML_OPERAND_TYPE);
+	}
+
+
+	/*
+	 * If the Region Address and Length have not been previously evaluated,
+	 * evaluate them now and save the results.
+	 */
+	if (!(rgn_desc->region.flags & AOPOBJ_DATA_VALID)) {
+
+		status = acpi_ds_get_region_arguments (rgn_desc);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+	}
+
+
+	/*
+	 * Validate the request.  The entire request from the byte offset for a
+	 * length of one field datum (access width) must fit within the region.
+	 * (Region length is specified in bytes)
+	 */
+	if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset +
+			   field_datum_byte_offset +
+			   obj_desc->common_field.access_byte_width)) {
+		if (rgn_desc->region.length < obj_desc->common_field.access_byte_width) {
+			/*
+			 * This is the case where the Access_type (Acc_word, etc.) is wider
+			 * than the region itself.  For example, a region of length one
+			 * byte, and a field with Dword access specified.
+			 */
+		}
+
+		/*
+		 * Offset rounded up to next multiple of field width
+		 * exceeds region length, indicate an error
+		 */
+		return (AE_AML_REGION_LIMIT);
+	}
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_read_field_datum
+ *
+ * PARAMETERS:  *Obj_desc           - Field to be read
+ *              *Value              - Where to store value (must be 32 bits)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Retrieve the value of the given field
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_read_field_datum (
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	u32                     field_datum_byte_offset,
+	u32                     *value)
+{
+	ACPI_STATUS             status;
+	ACPI_OPERAND_OBJECT     *rgn_desc;
+	ACPI_PHYSICAL_ADDRESS   address;
+	u32                     local_value;
+
+
+	if (!value) {
+		local_value = 0;
+		value = &local_value;   /*  support reads without saving value  */
+	}
+
+	/* Clear the entire return buffer first, [Very Important!] */
+
+	*value = 0;
+
+
+	/*
+	 * Buffer_fields - Read from a Buffer
+	 * Other Fields - Read from a Operation Region.
+	 */
+	switch (obj_desc->common.type) {
+	case ACPI_TYPE_BUFFER_FIELD:
+
+		/*
+		 * For Buffer_fields, we only need to copy the data from the
+		 * source buffer.  Length is the field width in bytes.
+		 */
+		MEMCPY (value, (obj_desc->buffer_field.buffer_obj)->buffer.pointer
+				  + obj_desc->buffer_field.base_byte_offset + field_datum_byte_offset,
+				  obj_desc->common_field.access_byte_width);
+		status = AE_OK;
+		break;
+
+
+	case INTERNAL_TYPE_REGION_FIELD:
+	case INTERNAL_TYPE_BANK_FIELD:
+
+		/*
+		 * For other fields, we need to go through an Operation Region
+		 * (Only types that will get here are Region_fields and Bank_fields)
+		 */
+		status = acpi_ex_setup_field (obj_desc, field_datum_byte_offset);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+
+
+		/*
+		 * The physical address of this field datum is:
+		 *
+		 * 1) The base of the region, plus
+		 * 2) The base offset of the field, plus
+		 * 3) The current offset into the field
+		 */
+		rgn_desc = obj_desc->common_field.region_obj;
+		address = rgn_desc->region.address + obj_desc->common_field.base_byte_offset +
+				 field_datum_byte_offset;
+
+
+		/* Invoke the appropriate Address_space/Op_region handler */
+
+		status = acpi_ev_address_space_dispatch (rgn_desc, ACPI_READ_ADR_SPACE,
+				  address, obj_desc->common_field.access_bit_width, value);
+
+		break;
+
+
+	default:
+
+		status = AE_AML_INTERNAL;
+		break;
+	}
+
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_get_buffer_datum
+ *
+ * PARAMETERS:  Merged_datum        - Value to store
+ *              Buffer              - Receiving buffer
+ *              Byte_granularity    - 1/2/4 Granularity of the field
+ *                                    (aka Datum Size)
+ *              Offset              - Datum offset into the buffer
+ *
+ * RETURN:      none
+ *
+ * DESCRIPTION: Store the merged datum to the buffer according to the
+ *              byte granularity
+ *
+ ******************************************************************************/
+
+static void
+acpi_ex_get_buffer_datum(
+	u32                     *datum,
+	void                    *buffer,
+	u32                     byte_granularity,
+	u32                     offset)
+{
+
+	switch (byte_granularity) {
+	case ACPI_FIELD_BYTE_GRANULARITY:
+		*datum = ((u8 *) buffer) [offset];
+		break;
+
+	case ACPI_FIELD_WORD_GRANULARITY:
+		MOVE_UNALIGNED16_TO_32 (datum, &(((u16 *) buffer) [offset]));
+		break;
+
+	case ACPI_FIELD_DWORD_GRANULARITY:
+		MOVE_UNALIGNED32_TO_32 (datum, &(((u32 *) buffer) [offset]));
+		break;
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_set_buffer_datum
+ *
+ * PARAMETERS:  Merged_datum        - Value to store
+ *              Buffer              - Receiving buffer
+ *              Byte_granularity    - 1/2/4 Granularity of the field
+ *                                    (aka Datum Size)
+ *              Offset              - Datum offset into the buffer
+ *
+ * RETURN:      none
+ *
+ * DESCRIPTION: Store the merged datum to the buffer according to the
+ *              byte granularity
+ *
+ ******************************************************************************/
+
+static void
+acpi_ex_set_buffer_datum (
+	u32                     merged_datum,
+	void                    *buffer,
+	u32                     byte_granularity,
+	u32                     offset)
+{
+
+	switch (byte_granularity) {
+	case ACPI_FIELD_BYTE_GRANULARITY:
+		((u8 *) buffer) [offset] = (u8) merged_datum;
+		break;
+
+	case ACPI_FIELD_WORD_GRANULARITY:
+		MOVE_UNALIGNED16_TO_16 (&(((u16 *) buffer)[offset]), &merged_datum);
+		break;
+
+	case ACPI_FIELD_DWORD_GRANULARITY:
+		MOVE_UNALIGNED32_TO_32 (&(((u32 *) buffer)[offset]), &merged_datum);
+		break;
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_extract_from_field
+ *
+ * PARAMETERS:  *Obj_desc           - Field to be read
+ *              *Value              - Where to store value
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Retrieve the value of the given field
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_extract_from_field (
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	void                    *buffer,
+	u32                     buffer_length)
+{
+	ACPI_STATUS             status;
+	u32                     field_datum_byte_offset;
+	u32                     datum_offset;
+	u32                     previous_raw_datum;
+	u32                     this_raw_datum = 0;
+	u32                     merged_datum = 0;
+	u32                     byte_field_length;
+	u32                     datum_count;
+
+
+	/*
+	 * The field must fit within the caller's buffer
+	 */
+	byte_field_length = ROUND_BITS_UP_TO_BYTES (obj_desc->common_field.bit_length);
+	if (byte_field_length > buffer_length) {
+		return (AE_BUFFER_OVERFLOW);
+	}
+
+	/* Convert field byte count to datum count, round up if necessary */
+
+	datum_count = ROUND_UP_TO (byte_field_length, obj_desc->common_field.access_byte_width);
+
+
+	/*
+	 * Clear the caller's buffer (the whole buffer length as given)
+	 * This is very important, especially in the cases where a byte is read,
+	 * but the buffer is really a u32 (4 bytes).
+	 */
+	MEMSET (buffer, 0, buffer_length);
+
+	/* Read the first raw datum to prime the loop */
+
+	field_datum_byte_offset = 0;
+	datum_offset= 0;
+
+	status = acpi_ex_read_field_datum (obj_desc, field_datum_byte_offset, &previous_raw_datum);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+
+	/* We might actually be done if the request fits in one datum */
+
+	if ((datum_count == 1) &&
+		(obj_desc->common_field.access_flags & AFIELD_SINGLE_DATUM)) {
+		/* 1) Shift the valid data bits down to start at bit 0 */
+
+		merged_datum = (previous_raw_datum >> obj_desc->common_field.start_field_bit_offset);
+
+		/* 2) Mask off any upper unused bits (bits not part of the field) */
+
+		if (obj_desc->common_field.end_buffer_valid_bits) {
+			merged_datum &= MASK_BITS_ABOVE (obj_desc->common_field.end_buffer_valid_bits);
+		}
+
+		/* Store the datum to the caller buffer */
+
+		acpi_ex_set_buffer_datum (merged_datum, buffer, obj_desc->common_field.access_byte_width,
+				datum_offset);
+
+		return (AE_OK);
+	}
+
+
+	/* We need to get more raw data to complete one or more field data */
+
+	while (datum_offset < datum_count) {
+		field_datum_byte_offset += obj_desc->common_field.access_byte_width;
+
+		/*
+		 * If the field is aligned on a byte boundary, we don't want
+		 * to perform a final read, since this would potentially read
+		 * past the end of the region.
+		 *
+		 * TBD: [Investigate] It may make more sense to just split the aligned
+		 * and non-aligned cases since the aligned case is so very simple,
+		 */
+		if ((obj_desc->common_field.start_field_bit_offset != 0)  ||
+			((obj_desc->common_field.start_field_bit_offset == 0) &&
+			(datum_offset < (datum_count -1)))) {
+			/*
+			 * Get the next raw datum, it contains some or all bits
+			 * of the current field datum
+			 */
+			status = acpi_ex_read_field_datum (obj_desc, field_datum_byte_offset, &this_raw_datum);
+			if (ACPI_FAILURE (status)) {
+				return (status);
+			}
+		}
+
+		/*
+		 * Create the (possibly) merged datum to be stored to the caller buffer
+		 */
+		if (obj_desc->common_field.start_field_bit_offset == 0) {
+			/* Field is not skewed and we can just copy the datum */
+
+			merged_datum = previous_raw_datum;
+		}
+
+		else {
+			/*
+			 * Put together the appropriate bits of the two raw data to make a
+			 * single complete field datum
+			 *
+			 * 1) Normalize the first datum down to bit 0
+			 */
+			merged_datum = (previous_raw_datum >> obj_desc->common_field.start_field_bit_offset);
+
+			/* 2) Insert the second datum "above" the first datum */
+
+			merged_datum |= (this_raw_datum << obj_desc->common_field.datum_valid_bits);
+
+			if ((datum_offset >= (datum_count -1))) {
+				/*
+				 * This is the last iteration of the loop.  We need to clear
+				 * any unused bits (bits that are not part of this field) that
+				 * came from the last raw datum before we store the final
+				 * merged datum into the caller buffer.
+				 */
+				if (obj_desc->common_field.end_buffer_valid_bits) {
+					merged_datum &=
+						MASK_BITS_ABOVE (obj_desc->common_field.end_buffer_valid_bits);
+				}
+			}
+		}
+
+
+		/*
+		 * Store the merged field datum in the caller's buffer, according to
+		 * the granularity of the field (size of each datum).
+		 */
+		acpi_ex_set_buffer_datum (merged_datum, buffer, obj_desc->common_field.access_byte_width,
+				datum_offset);
+
+		/*
+		 * Save the raw datum that was just acquired since it may contain bits
+		 * of the *next* field datum.  Update offsets
+		 */
+		previous_raw_datum = this_raw_datum;
+		datum_offset++;
+	}
+
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_write_field_datum
+ *
+ * PARAMETERS:  *Obj_desc           - Field to be set
+ *              Value               - Value to store
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Store the value into the given field
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+acpi_ex_write_field_datum (
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	u32                     field_datum_byte_offset,
+	u32                     value)
+{
+	ACPI_STATUS             status = AE_OK;
+	ACPI_OPERAND_OBJECT     *rgn_desc = NULL;
+	ACPI_PHYSICAL_ADDRESS   address;
+
+
+	/*
+	 * Buffer_fields - Read from a Buffer
+	 * Other Fields - Read from a Operation Region.
+	 */
+	switch (obj_desc->common.type) {
+	case ACPI_TYPE_BUFFER_FIELD:
+
+		/*
+		 * For Buffer_fields, we only need to copy the data to the
+		 * target buffer.  Length is the field width in bytes.
+		 */
+		MEMCPY ((obj_desc->buffer_field.buffer_obj)->buffer.pointer
+				+ obj_desc->buffer_field.base_byte_offset + field_datum_byte_offset,
+				&value, obj_desc->common_field.access_byte_width);
+		status = AE_OK;
+		break;
+
+
+	case INTERNAL_TYPE_REGION_FIELD:
+	case INTERNAL_TYPE_BANK_FIELD:
+
+		/*
+		 * For other fields, we need to go through an Operation Region
+		 * (Only types that will get here are Region_fields and Bank_fields)
+		 */
+		status = acpi_ex_setup_field (obj_desc, field_datum_byte_offset);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+
+		/*
+		 * The physical address of this field datum is:
+		 *
+		 * 1) The base of the region, plus
+		 * 2) The base offset of the field, plus
+		 * 3) The current offset into the field
+		 */
+		rgn_desc = obj_desc->common_field.region_obj;
+		address = rgn_desc->region.address +
+				 obj_desc->common_field.base_byte_offset +
+				 field_datum_byte_offset;
+
+		/* Invoke the appropriate Address_space/Op_region handler */
+
+		status = acpi_ev_address_space_dispatch (rgn_desc, ACPI_WRITE_ADR_SPACE,
+				  address, obj_desc->common_field.access_bit_width, &value);
+
+
+
+		break;
+
+
+	default:
+
+		status = AE_AML_INTERNAL;
+		break;
+	}
+
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_write_field_datum_with_update_rule
+ *
+ * PARAMETERS:  *Obj_desc           - Field to be set
+ *              Value               - Value to store
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Apply the field update rule to a field write
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+acpi_ex_write_field_datum_with_update_rule (
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	u32                     mask,
+	u32                     field_value,
+	u32                     field_datum_byte_offset)
+{
+	ACPI_STATUS             status = AE_OK;
+	u32                     merged_value;
+	u32                     current_value;
+
+
+	/* Start with the new bits  */
+
+	merged_value = field_value;
+
+
+	/* If the mask is all ones, we don't need to worry about the update rule */
+
+	if (mask != ACPI_UINT32_MAX) {
+		/* Decode the update rule */
+
+		switch (obj_desc->common_field.update_rule) {
+
+		case UPDATE_PRESERVE:
+
+			/*
+			 * Check if update rule needs to be applied (not if mask is all
+			 * ones)  The left shift drops the bits we want to ignore.
+			 */
+			if ((~mask << (sizeof (mask) * 8 -
+					  obj_desc->common_field.access_bit_width)) != 0) {
+				/*
+				 * Read the current contents of the byte/word/dword containing
+				 * the field, and merge with the new field value.
+				 */
+				status = acpi_ex_read_field_datum (obj_desc, field_datum_byte_offset,
+						  &current_value);
+				merged_value |= (current_value & ~mask);
+			}
+			break;
+
+
+		case UPDATE_WRITE_AS_ONES:
+
+			/* Set positions outside the field to all ones */
+
+			merged_value |= ~mask;
+			break;
+
+
+		case UPDATE_WRITE_AS_ZEROS:
+
+			/* Set positions outside the field to all zeros */
+
+			merged_value &= mask;
+			break;
+
+
+		default:
+			return (AE_AML_OPERAND_VALUE);
+			break;
+		}
+	}
+
+
+	/* Write the merged value */
+
+	status = acpi_ex_write_field_datum (obj_desc, field_datum_byte_offset,
+			  merged_value);
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_insert_into_field
+ *
+ * PARAMETERS:  *Obj_desc           - Field to be set
+ *              Buffer              - Value to store
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Store the value into the given field
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_insert_into_field (
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	void                    *buffer,
+	u32                     buffer_length)
+{
+	ACPI_STATUS             status;
+	u32                     field_datum_byte_offset;
+	u32                     datum_offset;
+	u32                     mask;
+	u32                     merged_datum;
+	u32                     previous_raw_datum;
+	u32                     this_raw_datum;
+	u32                     byte_field_length;
+	u32                     datum_count;
+
+
+	/*
+	 * Incoming buffer must be at least as long as the field, we do not
+	 * allow "partial" field writes.  We do not care if the buffer is
+	 * larger than the field, this typically happens when an integer is
+	 * written to a field that is actually smaller than an integer.
+	 */
+	byte_field_length = ROUND_BITS_UP_TO_BYTES (obj_desc->common_field.bit_length);
+	if (buffer_length < byte_field_length) {
+		/* TBD: Need a better error code */
+
+		return (AE_BUFFER_OVERFLOW);
+	}
+
+	/* Convert byte count to datum count, round up if necessary */
+
+	datum_count = ROUND_UP_TO (byte_field_length, obj_desc->common_field.access_byte_width);
+
+
+	/*
+	 * Break the request into up to three parts (similar to an I/O request):
+	 * 1) non-aligned part at start
+	 * 2) aligned part in middle
+	 * 3) non-aligned part at the end
+	 */
+	field_datum_byte_offset = 0;
+	datum_offset= 0;
+
+	/* Get a single datum from the caller's buffer */
+
+	acpi_ex_get_buffer_datum (&previous_raw_datum, buffer,
+			obj_desc->common_field.access_byte_width, datum_offset);
+
+	/*
+	 * Part1:
+	 * Write a partial field datum if field does not begin on a datum boundary
+	 * Note: The code in this section also handles the aligned case
+	 *
+	 * Construct Mask with 1 bits where the field is, 0 bits elsewhere
+	 * (Only the bottom 5 bits of Bit_length are valid for a shift operation)
+	 *
+	 * Mask off bits that are "below" the field (if any)
+	 */
+	mask = MASK_BITS_BELOW (obj_desc->common_field.start_field_bit_offset);
+
+	/* If the field fits in one datum, may need to mask upper bits */
+
+	if ((obj_desc->common_field.access_flags & AFIELD_SINGLE_DATUM) &&
+		 obj_desc->common_field.end_field_valid_bits) {
+		/* There are bits above the field, mask them off also */
+
+		mask &= MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits);
+	}
+
+	/* Shift and mask the value into the field position */
+
+	merged_datum = (previous_raw_datum << obj_desc->common_field.start_field_bit_offset);
+	merged_datum &= mask;
+
+	/* Apply the update rule (if necessary) and write the datum to the field */
+
+	status = acpi_ex_write_field_datum_with_update_rule (obj_desc, mask, merged_datum,
+			   field_datum_byte_offset);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/* If the entire field fits within one datum, we are done. */
+
+	if ((datum_count == 1) &&
+	   (obj_desc->common_field.access_flags & AFIELD_SINGLE_DATUM)) {
+		return (AE_OK);
+	}
+
+	/*
+	 * Part2:
+	 * Write the aligned data.
+	 *
+	 * We don't need to worry about the update rule for these data, because
+	 * all of the bits in each datum are part of the field.
+	 *
+	 * The last datum must be special cased because it might contain bits
+	 * that are not part of the field -- therefore the "update rule" must be
+	 * applied in Part3 below.
+	 */
+	while (datum_offset < datum_count) {
+		datum_offset++;
+		field_datum_byte_offset += obj_desc->common_field.access_byte_width;
+
+		/*
+		 * Get the next raw buffer datum.  It may contain bits of the previous
+		 * field datum
+		 */
+		acpi_ex_get_buffer_datum (&this_raw_datum, buffer,
+				obj_desc->common_field.access_byte_width, datum_offset);
+
+		/* Create the field datum based on the field alignment */
+
+		if (obj_desc->common_field.start_field_bit_offset != 0) {
+			/*
+			 * Put together appropriate bits of the two raw buffer data to make
+			 * a single complete field datum
+			 */
+			merged_datum =
+				(previous_raw_datum >> obj_desc->common_field.datum_valid_bits) |
+				(this_raw_datum << obj_desc->common_field.start_field_bit_offset);
+		}
+
+		else {
+			/* Field began aligned on datum boundary */
+
+			merged_datum = this_raw_datum;
+		}
+
+
+		/*
+		 * Special handling for the last datum if the field does NOT end on
+		 * a datum boundary.  Update Rule must be applied to the bits outside
+		 * the field.
+		 */
+		if ((datum_offset == datum_count)           &&
+			obj_desc->common_field.end_field_valid_bits) {
+			/*
+			 * Part3:
+			 * This is the last datum and the field does not end on a datum boundary.
+			 * Build the partial datum and write with the update rule.
+			 */
+
+			/* Mask off the unused bits above (after) the end-of-field */
+
+			mask = MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits);
+			merged_datum &= mask;
+
+			/* Write the last datum with the update rule */
+
+			status = acpi_ex_write_field_datum_with_update_rule (obj_desc, mask,
+					  merged_datum, field_datum_byte_offset);
+			if (ACPI_FAILURE (status)) {
+				return (status);
+			}
+		}
+
+		else {
+			/* Normal case -- write the completed datum */
+
+			status = acpi_ex_write_field_datum (obj_desc,
+					  field_datum_byte_offset, merged_datum);
+			if (ACPI_FAILURE (status)) {
+				return (status);
+			}
+		}
+
+		/*
+		 * Save the most recent datum since it may contain bits of the *next*
+		 * field datum.  Update current byte offset.
+		 */
+		previous_raw_datum = this_raw_datum;
+	}
+
+
+	return (status);
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exmisc.c linux/drivers/acpi/executer/exmisc.c
--- v2.4.5/linux/drivers/acpi/executer/exmisc.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exmisc.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,513 @@
+
+/******************************************************************************
+ *
+ * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes
+ *              $Revision: 77 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "acinterp.h"
+#include "amlcode.h"
+#include "acdispat.h"
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exmisc")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_fatal
+ *
+ * PARAMETERS:  none
+ *
+ * RETURN:      Status.  If the OS returns from the OSD call, we just keep
+ *              on going.
+ *
+ * DESCRIPTION: Execute Fatal operator
+ *
+ * ACPI SPECIFICATION REFERENCES:
+ *  Def_fatal   :=  Fatal_op Fatal_type Fatal_code  Fatal_arg
+ *  Fatal_type  :=  Byte_data
+ *  Fatal_code  :=  DWord_data
+ *  Fatal_arg   :=  Term_arg=>Integer
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_fatal (
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_OPERAND_OBJECT     *type_desc;
+	ACPI_OPERAND_OBJECT     *code_desc;
+	ACPI_OPERAND_OBJECT     *arg_desc;
+	ACPI_STATUS             status;
+
+
+	/* Resolve operands */
+
+	status = acpi_ex_resolve_operands (AML_FATAL_OP, WALK_OPERANDS, walk_state);
+	/* Get operands */
+
+	status |= acpi_ds_obj_stack_pop_object (&arg_desc, walk_state);
+	status |= acpi_ds_obj_stack_pop_object (&code_desc, walk_state);
+	status |= acpi_ds_obj_stack_pop_object (&type_desc, walk_state);
+	if (ACPI_FAILURE (status)) {
+		/* Invalid parameters on object stack  */
+
+		goto cleanup;
+	}
+
+
+	/* Def_fatal   :=  Fatal_op Fatal_type Fatal_code  Fatal_arg   */
+
+
+	/*
+	 * TBD: [Unhandled] call OSD interface to notify OS of fatal error
+	 * requiring shutdown!
+	 */
+
+
+cleanup:
+
+	/* Free the operands */
+
+	acpi_ut_remove_reference (arg_desc);
+	acpi_ut_remove_reference (code_desc);
+	acpi_ut_remove_reference (type_desc);
+
+
+	/* If we get back from the OS call, we might as well keep going. */
+
+	REPORT_WARNING (("An AML \"fatal\" Opcode (Fatal_op) was executed\n"));
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_index
+ *
+ * PARAMETERS:  none
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute Index operator
+ *
+ * ALLOCATION:  Deletes one operand descriptor -- other remains on stack
+ *
+ *  ACPI SPECIFICATION REFERENCES:
+ *  Def_index   :=  Index_op Buff_pkg_obj Index_value Result
+ *  Index_value :=  Term_arg=>Integer
+ *  Name_string :=  <Root_char Name_path> | <Prefix_path Name_path>
+ *  Result      :=  Super_name
+ *  Super_name  :=  Name_string | Arg_obj | Local_obj | Debug_obj | Def_index
+ *                             Local4_op | Local5_op | Local6_op | Local7_op
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_index (
+	ACPI_WALK_STATE         *walk_state,
+	ACPI_OPERAND_OBJECT     **return_desc)
+{
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	ACPI_OPERAND_OBJECT     *idx_desc;
+	ACPI_OPERAND_OBJECT     *res_desc;
+	ACPI_OPERAND_OBJECT     *ret_desc = NULL;
+	ACPI_OPERAND_OBJECT     *tmp_desc;
+	ACPI_STATUS             status;
+
+
+	/* Resolve operands */
+	/* First operand can be either a package or a buffer */
+
+	status = acpi_ex_resolve_operands (AML_INDEX_OP, WALK_OPERANDS, walk_state);
+	/* Get all operands */
+
+	status |= acpi_ds_obj_stack_pop_object (&res_desc, walk_state);
+	status |= acpi_ds_obj_stack_pop_object (&idx_desc, walk_state);
+	status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
+	if (ACPI_FAILURE (status)) {
+		/* Invalid parameters on object stack  */
+
+		goto cleanup;
+	}
+
+
+	/* Create the internal return object */
+
+	ret_desc = acpi_ut_create_internal_object (INTERNAL_TYPE_REFERENCE);
+	if (!ret_desc) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+
+
+	/*
+	 * At this point, the Obj_desc operand is either a Package or a Buffer
+	 */
+
+	if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
+		/* Object to be indexed is a Package */
+
+		if (idx_desc->integer.value >= obj_desc->package.count) {
+			status = AE_AML_PACKAGE_LIMIT;
+			goto cleanup;
+		}
+
+		if ((res_desc->common.type == INTERNAL_TYPE_REFERENCE) &&
+			(res_desc->reference.opcode == AML_ZERO_OP)) {
+			/*
+			 * There is no actual result descriptor (the Zero_op Result
+			 * descriptor is a placeholder), so just delete the placeholder and
+			 * return a reference to the package element
+			 */
+
+			acpi_ut_remove_reference (res_desc);
+		}
+
+		else {
+			/*
+			 * Each element of the package is an internal object.  Get the one
+			 * we are after.
+			 */
+
+			tmp_desc                      = obj_desc->package.elements[idx_desc->integer.value];
+			ret_desc->reference.opcode    = AML_INDEX_OP;
+			ret_desc->reference.target_type = tmp_desc->common.type;
+			ret_desc->reference.object    = tmp_desc;
+
+			status = acpi_ex_store (ret_desc, res_desc, walk_state);
+			ret_desc->reference.object    = NULL;
+		}
+
+		/*
+		 * The local return object must always be a reference to the package element,
+		 * not the element itself.
+		 */
+		ret_desc->reference.opcode    = AML_INDEX_OP;
+		ret_desc->reference.target_type = ACPI_TYPE_PACKAGE;
+		ret_desc->reference.where     = &obj_desc->package.elements[idx_desc->integer.value];
+	}
+
+	else {
+		/* Object to be indexed is a Buffer */
+
+		if (idx_desc->integer.value >= obj_desc->buffer.length) {
+			status = AE_AML_BUFFER_LIMIT;
+			goto cleanup;
+		}
+
+		ret_desc->reference.opcode      = AML_INDEX_OP;
+		ret_desc->reference.target_type = ACPI_TYPE_BUFFER_FIELD;
+		ret_desc->reference.object      = obj_desc;
+		ret_desc->reference.offset      = (u32) idx_desc->integer.value;
+
+		status = acpi_ex_store (ret_desc, res_desc, walk_state);
+	}
+
+
+cleanup:
+
+	/* Always delete operands */
+
+	acpi_ut_remove_reference (obj_desc);
+	acpi_ut_remove_reference (idx_desc);
+
+	/* Delete return object on error */
+
+	if (ACPI_FAILURE (status)) {
+		acpi_ut_remove_reference (res_desc);
+
+		if (ret_desc) {
+			acpi_ut_remove_reference (ret_desc);
+			ret_desc = NULL;
+		}
+	}
+
+	/* Set the return object and exit */
+
+	*return_desc = ret_desc;
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_match
+ *
+ * PARAMETERS:  none
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute Match operator
+ *
+ * ACPI SPECIFICATION REFERENCES:
+ *  Def_match   :=  Match_op Search_pkg Opcode1     Operand1
+ *                              Opcode2 Operand2    Start_index
+ *  Opcode1     :=  Byte_data: MTR, MEQ, MLE, MLT, MGE, or MGT
+ *  Opcode2     :=  Byte_data: MTR, MEQ, MLE, MLT, MGE, or MGT
+ *  Operand1    :=  Term_arg=>Integer
+ *  Operand2    :=  Term_arg=>Integer
+ *  Search_pkg  :=  Term_arg=>Package_object
+ *  Start_index :=  Term_arg=>Integer
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_match (
+	ACPI_WALK_STATE         *walk_state,
+	ACPI_OPERAND_OBJECT     **return_desc)
+{
+	ACPI_OPERAND_OBJECT     *pkg_desc;
+	ACPI_OPERAND_OBJECT     *op1_desc;
+	ACPI_OPERAND_OBJECT     *V1_desc;
+	ACPI_OPERAND_OBJECT     *op2_desc;
+	ACPI_OPERAND_OBJECT     *V2_desc;
+	ACPI_OPERAND_OBJECT     *start_desc;
+	ACPI_OPERAND_OBJECT     *ret_desc = NULL;
+	ACPI_STATUS             status;
+	u32                     index;
+	u32                     match_value = (u32) -1;
+
+
+	/* Resolve all operands */
+
+	status = acpi_ex_resolve_operands (AML_MATCH_OP, WALK_OPERANDS, walk_state);
+	/* Get all operands */
+
+	status |= acpi_ds_obj_stack_pop_object (&start_desc, walk_state);
+	status |= acpi_ds_obj_stack_pop_object (&V2_desc, walk_state);
+	status |= acpi_ds_obj_stack_pop_object (&op2_desc, walk_state);
+	status |= acpi_ds_obj_stack_pop_object (&V1_desc, walk_state);
+	status |= acpi_ds_obj_stack_pop_object (&op1_desc, walk_state);
+	status |= acpi_ds_obj_stack_pop_object (&pkg_desc, walk_state);
+
+	if (ACPI_FAILURE (status)) {
+		/* Invalid parameters on object stack  */
+
+		goto cleanup;
+	}
+
+	/* Validate match comparison sub-opcodes */
+
+	if ((op1_desc->integer.value > MAX_MATCH_OPERATOR) ||
+		(op2_desc->integer.value > MAX_MATCH_OPERATOR)) {
+		status = AE_AML_OPERAND_VALUE;
+		goto cleanup;
+	}
+
+	index = (u32) start_desc->integer.value;
+	if (index >= (u32) pkg_desc->package.count) {
+		status = AE_AML_PACKAGE_LIMIT;
+		goto cleanup;
+	}
+
+	ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+	if (!ret_desc) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+
+	}
+
+	/*
+	 * Examine each element until a match is found.  Within the loop,
+	 * "continue" signifies that the current element does not match
+	 * and the next should be examined.
+	 * Upon finding a match, the loop will terminate via "break" at
+	 * the bottom.  If it terminates "normally", Match_value will be -1
+	 * (its initial value) indicating that no match was found.  When
+	 * returned as a Number, this will produce the Ones value as specified.
+	 */
+
+	for ( ; index < pkg_desc->package.count; ++index) {
+		/*
+		 * Treat any NULL or non-numeric elements as non-matching.
+		 * TBD [Unhandled] - if an element is a Name,
+		 *      should we examine its value?
+		 */
+		if (!pkg_desc->package.elements[index] ||
+			ACPI_TYPE_INTEGER != pkg_desc->package.elements[index]->common.type) {
+			continue;
+		}
+
+		/*
+		 * Within these switch statements:
+		 *      "break" (exit from the switch) signifies a match;
+		 *      "continue" (proceed to next iteration of enclosing
+		 *          "for" loop) signifies a non-match.
+		 */
+		switch (op1_desc->integer.value) {
+
+		case MATCH_MTR:   /* always true */
+
+			break;
+
+
+		case MATCH_MEQ:   /* true if equal   */
+
+			if (pkg_desc->package.elements[index]->integer.value
+				 != V1_desc->integer.value) {
+				continue;
+			}
+			break;
+
+
+		case MATCH_MLE:   /* true if less than or equal  */
+
+			if (pkg_desc->package.elements[index]->integer.value
+				 > V1_desc->integer.value) {
+				continue;
+			}
+			break;
+
+
+		case MATCH_MLT:   /* true if less than   */
+
+			if (pkg_desc->package.elements[index]->integer.value
+				 >= V1_desc->integer.value) {
+				continue;
+			}
+			break;
+
+
+		case MATCH_MGE:   /* true if greater than or equal   */
+
+			if (pkg_desc->package.elements[index]->integer.value
+				 < V1_desc->integer.value) {
+				continue;
+			}
+			break;
+
+
+		case MATCH_MGT:   /* true if greater than    */
+
+			if (pkg_desc->package.elements[index]->integer.value
+				 <= V1_desc->integer.value) {
+				continue;
+			}
+			break;
+
+
+		default:    /* undefined   */
+
+			continue;
+		}
+
+
+		switch(op2_desc->integer.value) {
+
+		case MATCH_MTR:
+
+			break;
+
+
+		case MATCH_MEQ:
+
+			if (pkg_desc->package.elements[index]->integer.value
+				 != V2_desc->integer.value) {
+				continue;
+			}
+			break;
+
+
+		case MATCH_MLE:
+
+			if (pkg_desc->package.elements[index]->integer.value
+				 > V2_desc->integer.value) {
+				continue;
+			}
+			break;
+
+
+		case MATCH_MLT:
+
+			if (pkg_desc->package.elements[index]->integer.value
+				 >= V2_desc->integer.value) {
+				continue;
+			}
+			break;
+
+
+		case MATCH_MGE:
+
+			if (pkg_desc->package.elements[index]->integer.value
+				 < V2_desc->integer.value) {
+				continue;
+			}
+			break;
+
+
+		case MATCH_MGT:
+
+			if (pkg_desc->package.elements[index]->integer.value
+				 <= V2_desc->integer.value) {
+				continue;
+			}
+			break;
+
+
+		default:
+
+			continue;
+		}
+
+		/* Match found: exit from loop */
+
+		match_value = index;
+		break;
+	}
+
+	/* Match_value is the return value */
+
+	ret_desc->integer.value = match_value;
+
+
+cleanup:
+
+	/* Free the operands */
+
+	acpi_ut_remove_reference (start_desc);
+	acpi_ut_remove_reference (V2_desc);
+	acpi_ut_remove_reference (op2_desc);
+	acpi_ut_remove_reference (V1_desc);
+	acpi_ut_remove_reference (op1_desc);
+	acpi_ut_remove_reference (pkg_desc);
+
+
+	/* Delete return object on error */
+
+	if (ACPI_FAILURE (status) &&
+		(ret_desc)) {
+		acpi_ut_remove_reference (ret_desc);
+		ret_desc = NULL;
+	}
+
+
+	/* Set the return object and exit */
+
+	*return_desc = ret_desc;
+	return (status);
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exmonad.c linux/drivers/acpi/executer/exmonad.c
--- v2.4.5/linux/drivers/acpi/executer/exmonad.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exmonad.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,972 @@
+
+/******************************************************************************
+ *
+ * Module Name: exmonad - ACPI AML (p-code) execution for monadic operators
+ *              $Revision: 99 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "acdispat.h"
+#include "acinterp.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exmonad")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_get_object_reference
+ *
+ * PARAMETERS:  Obj_desc        - Create a reference to this object
+ *              Ret_desc        - Where to store the reference
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Obtain and return a "reference" to the target object
+ *              Common code for the Ref_of_op and the Cond_ref_of_op.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+acpi_ex_get_object_reference (
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	ACPI_OPERAND_OBJECT     **ret_desc,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_STATUS             status = AE_OK;
+
+
+	if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) {
+		if (obj_desc->common.type != INTERNAL_TYPE_REFERENCE) {
+			*ret_desc = NULL;
+			status = AE_TYPE;
+			goto cleanup;
+		}
+
+		/*
+		 * Not a Name -- an indirect name pointer would have
+		 * been converted to a direct name pointer in Acpi_ex_resolve_operands
+		 */
+		switch (obj_desc->reference.opcode) {
+		case AML_LOCAL_OP:
+		case AML_ARG_OP:
+
+			*ret_desc = (void *) acpi_ds_method_data_get_node (obj_desc->reference.opcode,
+					  obj_desc->reference.offset, walk_state);
+			break;
+
+		default:
+
+			*ret_desc = NULL;
+			status = AE_AML_INTERNAL;
+			goto cleanup;
+		}
+
+	}
+
+	else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
+		/* Must be a named object;  Just return the Node */
+
+		*ret_desc = obj_desc;
+	}
+
+	else {
+		*ret_desc = NULL;
+		status = AE_TYPE;
+	}
+
+
+cleanup:
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_monadic1
+ *
+ * PARAMETERS:  Opcode              - The opcode to be executed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on
+ *              object stack
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_monadic1 (
+	u16                     opcode,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	ACPI_STATUS             status;
+
+
+	/* Resolve all operands */
+
+	status = acpi_ex_resolve_operands (opcode, WALK_OPERANDS, walk_state);
+	/* Get all operands */
+
+	status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+
+	/* Examine the opcode */
+
+	switch (opcode) {
+
+	/*  Def_release :=  Release_op  Mutex_object */
+
+	case AML_RELEASE_OP:
+
+		status = acpi_ex_release_mutex (obj_desc, walk_state);
+		break;
+
+
+	/*  Def_reset   :=  Reset_op    Acpi_event_object */
+
+	case AML_RESET_OP:
+
+		status = acpi_ex_system_reset_event (obj_desc);
+		break;
+
+
+	/*  Def_signal  :=  Signal_op   Acpi_event_object */
+
+	case AML_SIGNAL_OP:
+
+		status = acpi_ex_system_signal_event (obj_desc);
+		break;
+
+
+	/*  Def_sleep   :=  Sleep_op    Msec_time   */
+
+	case AML_SLEEP_OP:
+
+		acpi_ex_system_do_suspend ((u32) obj_desc->integer.value);
+		break;
+
+
+	/*  Def_stall   :=  Stall_op    Usec_time   */
+
+	case AML_STALL_OP:
+
+		acpi_ex_system_do_stall ((u32) obj_desc->integer.value);
+		break;
+
+
+	/*  Unknown opcode  */
+
+	default:
+
+		REPORT_ERROR (("Acpi_ex_monadic1: Unknown monadic opcode %X\n",
+			opcode));
+		status = AE_AML_BAD_OPCODE;
+		break;
+
+	} /* switch */
+
+
+cleanup:
+
+	/* Always delete the operand */
+
+	acpi_ut_remove_reference (obj_desc);
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_monadic2_r
+ *
+ * PARAMETERS:  Opcode              - The opcode to be executed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute Type 2 monadic operator with numeric operand and
+ *              result operand on operand stack
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_monadic2_r (
+	u16                     opcode,
+	ACPI_WALK_STATE         *walk_state,
+	ACPI_OPERAND_OBJECT     **return_desc)
+{
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	ACPI_OPERAND_OBJECT     *res_desc;
+	ACPI_OPERAND_OBJECT     *ret_desc = NULL;
+	ACPI_OPERAND_OBJECT     *ret_desc2 = NULL;
+	u32                     res_val;
+	ACPI_STATUS             status;
+	u32                     i;
+	u32                     j;
+	ACPI_INTEGER            digit;
+
+
+	/* Resolve all operands */
+
+	status = acpi_ex_resolve_operands (opcode, WALK_OPERANDS, walk_state);
+	/* Get all operands */
+
+	status |= acpi_ds_obj_stack_pop_object (&res_desc, walk_state);
+	status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+
+	/* Create a return object of type NUMBER for most opcodes */
+
+	switch (opcode) {
+	case AML_BIT_NOT_OP:
+	case AML_FIND_SET_LEFT_BIT_OP:
+	case AML_FIND_SET_RIGHT_BIT_OP:
+	case AML_FROM_BCD_OP:
+	case AML_TO_BCD_OP:
+	case AML_COND_REF_OF_OP:
+
+		ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!ret_desc) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		break;
+	}
+
+
+	switch (opcode) {
+	/*  Def_not :=  Not_op  Operand Result  */
+
+	case AML_BIT_NOT_OP:
+
+		ret_desc->integer.value = ~obj_desc->integer.value;
+		break;
+
+
+	/*  Def_find_set_left_bit := Find_set_left_bit_op Operand Result */
+
+	case AML_FIND_SET_LEFT_BIT_OP:
+
+		ret_desc->integer.value = obj_desc->integer.value;
+
+		/*
+		 * Acpi specification describes Integer type as a little
+		 * endian unsigned value, so this boundary condition is valid.
+		 */
+		for (res_val = 0; ret_desc->integer.value && res_val < ACPI_INTEGER_BIT_SIZE; ++res_val) {
+			ret_desc->integer.value >>= 1;
+		}
+
+		ret_desc->integer.value = res_val;
+		break;
+
+
+	/*  Def_find_set_right_bit := Find_set_right_bit_op Operand Result */
+
+	case AML_FIND_SET_RIGHT_BIT_OP:
+
+		ret_desc->integer.value = obj_desc->integer.value;
+
+		/*
+		 * Acpi specification describes Integer type as a little
+		 * endian unsigned value, so this boundary condition is valid.
+		 */
+		for (res_val = 0; ret_desc->integer.value && res_val < ACPI_INTEGER_BIT_SIZE; ++res_val) {
+			ret_desc->integer.value <<= 1;
+		}
+
+		/* Since returns must be 1-based, subtract from 33 (65) */
+
+		ret_desc->integer.value = res_val == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - res_val;
+		break;
+
+
+	/*  Def_from_bDC := From_bCDOp  BCDValue    Result  */
+
+	case AML_FROM_BCD_OP:
+
+		/*
+		 * The 64-bit ACPI integer can hold 16 4-bit BCD integers
+		 */
+		ret_desc->integer.value = 0;
+		for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) {
+			/* Get one BCD digit */
+
+			digit = (ACPI_INTEGER) ((obj_desc->integer.value >> (i * 4)) & 0xF);
+
+			/* Check the range of the digit */
+
+			if (digit > 9) {
+				status = AE_AML_NUMERIC_OVERFLOW;
+				goto cleanup;
+			}
+
+			if (digit > 0) {
+				/* Sum into the result with the appropriate power of 10 */
+
+				for (j = 0; j < i; j++) {
+					digit *= 10;
+				}
+
+				ret_desc->integer.value += digit;
+			}
+		}
+		break;
+
+
+	/*  Def_to_bDC  :=  To_bCDOp Operand Result */
+
+	case AML_TO_BCD_OP:
+
+
+		if (obj_desc->integer.value > ACPI_MAX_BCD_VALUE) {
+			status = AE_AML_NUMERIC_OVERFLOW;
+			goto cleanup;
+		}
+
+		ret_desc->integer.value = 0;
+		for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) {
+			/* Divide by nth factor of 10 */
+
+			digit = obj_desc->integer.value;
+			for (j = 0; j < i; j++) {
+				digit /= 10;
+			}
+
+			/* Create the BCD digit */
+
+			if (digit > 0) {
+				ret_desc->integer.value += (ACPI_MODULO (digit, 10) << (i * 4));
+			}
+		}
+		break;
+
+
+	/*  Def_cond_ref_of     :=  Cond_ref_of_op  Source_object   Result  */
+
+	case AML_COND_REF_OF_OP:
+
+		/*
+		 * This op is a little strange because the internal return value is
+		 * different than the return value stored in the result descriptor
+		 * (There are really two return values)
+		 */
+
+		if ((ACPI_NAMESPACE_NODE *) obj_desc == acpi_gbl_root_node) {
+			/*
+			 * This means that the object does not exist in the namespace,
+			 * return FALSE
+			 */
+
+			ret_desc->integer.value = 0;
+
+			/*
+			 * Must delete the result descriptor since there is no reference
+			 * being returned
+			 */
+
+			acpi_ut_remove_reference (res_desc);
+			goto cleanup;
+		}
+
+		/* Get the object reference and store it */
+
+		status = acpi_ex_get_object_reference (obj_desc, &ret_desc2, walk_state);
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+
+		status = acpi_ex_store (ret_desc2, res_desc, walk_state);
+
+		/* The object exists in the namespace, return TRUE */
+
+		ret_desc->integer.value = ACPI_INTEGER_MAX;
+		goto cleanup;
+		break;
+
+
+	case AML_STORE_OP:
+
+		/*
+		 * A store operand is typically a number, string, buffer or lvalue
+		 * TBD: [Unhandled] What about a store to a package?
+		 */
+
+		/*
+		 * Do the store, and be careful about deleting the source object,
+		 * since the object itself may have been stored.
+		 */
+
+		status = acpi_ex_store (obj_desc, res_desc, walk_state);
+		if (ACPI_FAILURE (status)) {
+			/* On failure, just delete the Obj_desc */
+
+			acpi_ut_remove_reference (obj_desc);
+		}
+
+		else {
+			/*
+			 * Normally, we would remove a reference on the Obj_desc parameter;
+			 * But since it is being used as the internal return object
+			 * (meaning we would normally increment it), the two cancel out,
+			 * and we simply don't do anything.
+			 */
+			*return_desc = obj_desc;
+		}
+
+		obj_desc = NULL;
+		return (status);
+
+		break;
+
+
+	case AML_DEBUG_OP:
+
+		/* Reference, returning an Reference */
+
+		return (AE_OK);
+		break;
+
+
+	/*
+	 * These are obsolete opcodes
+	 */
+
+	/*  Def_shift_left_bit  :=  Shift_left_bit_op   Source          Bit_num */
+	/*  Def_shift_right_bit :=  Shift_right_bit_op  Source          Bit_num */
+
+	case AML_SHIFT_LEFT_BIT_OP:
+	case AML_SHIFT_RIGHT_BIT_OP:
+
+		status = AE_SUPPORT;
+		goto cleanup;
+		break;
+
+
+	default:
+
+		REPORT_ERROR (("Acpi_ex_monadic2_r: Unknown monadic opcode %X\n",
+			opcode));
+		status = AE_AML_BAD_OPCODE;
+		goto cleanup;
+	}
+
+
+	status = acpi_ex_store (ret_desc, res_desc, walk_state);
+
+
+cleanup:
+	/* Always delete the operand object */
+
+	acpi_ut_remove_reference (obj_desc);
+
+	/* Delete return object(s) on error */
+
+	if (ACPI_FAILURE (status)) {
+		acpi_ut_remove_reference (res_desc); /* Result descriptor */
+		if (ret_desc) {
+			acpi_ut_remove_reference (ret_desc);
+			ret_desc = NULL;
+		}
+	}
+
+	/* Set the return object and exit */
+
+	*return_desc = ret_desc;
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_monadic2
+ *
+ * PARAMETERS:  Opcode              - The opcode to be executed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute Type 2 monadic operator with numeric operand:
+ *              Deref_of_op, Ref_of_op, Size_of_op, Type_op, Increment_op,
+ *              Decrement_op, LNot_op,
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_monadic2 (
+	u16                     opcode,
+	ACPI_WALK_STATE         *walk_state,
+	ACPI_OPERAND_OBJECT     **return_desc)
+{
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	ACPI_OPERAND_OBJECT     *tmp_desc;
+	ACPI_OPERAND_OBJECT     *ret_desc = NULL;
+	ACPI_STATUS             resolve_status;
+	ACPI_STATUS             status;
+	u32                     type;
+	ACPI_INTEGER            value;
+
+
+	/* Attempt to resolve the operands */
+
+	resolve_status = acpi_ex_resolve_operands (opcode, WALK_OPERANDS, walk_state);
+	/* Always get all operands */
+
+	status = acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
+
+	/* Now we can check the status codes */
+
+	if (ACPI_FAILURE (resolve_status)) {
+		goto cleanup;
+	}
+
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+
+	/* Get the operand and decode the opcode */
+
+
+	switch (opcode) {
+
+	/*  Def_lNot := LNot_op Operand */
+
+	case AML_LNOT_OP:
+
+		ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!ret_desc) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		ret_desc->integer.value = !obj_desc->integer.value;
+		break;
+
+
+	/*  Def_decrement   :=  Decrement_op Target */
+	/*  Def_increment   :=  Increment_op Target */
+
+	case AML_DECREMENT_OP:
+	case AML_INCREMENT_OP:
+
+		/*
+		 * Since we are expecting an Reference on the top of the stack, it
+		 * can be either an Node or an internal object.
+		 *
+		 * TBD: [Future] This may be the prototype code for all cases where
+		 * an Reference is expected!! 10/99
+		 */
+
+		if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
+			ret_desc = obj_desc;
+		}
+
+		else {
+			/*
+			 * Duplicate the Reference in a new object so that we can resolve it
+			 * without destroying the original Reference object
+			 */
+
+			ret_desc = acpi_ut_create_internal_object (INTERNAL_TYPE_REFERENCE);
+			if (!ret_desc) {
+				status = AE_NO_MEMORY;
+				goto cleanup;
+			}
+
+			ret_desc->reference.opcode = obj_desc->reference.opcode;
+			ret_desc->reference.offset = obj_desc->reference.offset;
+			ret_desc->reference.object = obj_desc->reference.object;
+		}
+
+
+		/*
+		 * Convert the Ret_desc Reference to a Number
+		 * (This deletes the original Ret_desc)
+		 */
+
+		status = acpi_ex_resolve_operands (AML_LNOT_OP, &ret_desc, walk_state);
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+
+		/* Do the actual increment or decrement */
+
+		if (AML_INCREMENT_OP == opcode) {
+			ret_desc->integer.value++;
+		}
+		else {
+			ret_desc->integer.value--;
+		}
+
+		/* Store the result back in the original descriptor */
+
+		status = acpi_ex_store (ret_desc, obj_desc, walk_state);
+
+		/* Objdesc was just deleted (because it is an Reference) */
+
+		obj_desc = NULL;
+
+		break;
+
+
+	/*  Def_object_type :=  Object_type_op  Source_object   */
+
+	case AML_TYPE_OP:
+
+		if (INTERNAL_TYPE_REFERENCE == obj_desc->common.type) {
+			/*
+			 * Not a Name -- an indirect name pointer would have
+			 * been converted to a direct name pointer in Resolve_operands
+			 */
+			switch (obj_desc->reference.opcode) {
+			case AML_ZERO_OP:
+			case AML_ONE_OP:
+			case AML_ONES_OP:
+
+				/* Constants are of type Number */
+
+				type = ACPI_TYPE_INTEGER;
+				break;
+
+
+			case AML_DEBUG_OP:
+
+				/* Per 1.0b spec, Debug object is of type Debug_object */
+
+				type = ACPI_TYPE_DEBUG_OBJECT;
+				break;
+
+
+			case AML_INDEX_OP:
+
+				/* Get the type of this reference (index into another object) */
+
+				type = obj_desc->reference.target_type;
+				if (type == ACPI_TYPE_PACKAGE) {
+					/*
+					 * The main object is a package, we want to get the type
+					 * of the individual package element that is referenced by
+					 * the index.
+					 */
+					type = (*(obj_desc->reference.where))->common.type;
+				}
+
+				break;
+
+
+			case AML_LOCAL_OP:
+			case AML_ARG_OP:
+
+				type = acpi_ds_method_data_get_type (obj_desc->reference.opcode,
+						  obj_desc->reference.offset, walk_state);
+				break;
+
+
+			default:
+
+				REPORT_ERROR (("Acpi_ex_monadic2/Type_op: Internal error - Unknown Reference subtype %X\n",
+					obj_desc->reference.opcode));
+				status = AE_AML_INTERNAL;
+				goto cleanup;
+			}
+		}
+
+		else {
+			/*
+			 * It's not a Reference, so it must be a direct name pointer.
+			 */
+			type = acpi_ns_get_type ((ACPI_NAMESPACE_NODE *) obj_desc);
+
+			/* Convert internal types to external types */
+
+			switch (type) {
+			case INTERNAL_TYPE_REGION_FIELD:
+			case INTERNAL_TYPE_BANK_FIELD:
+			case INTERNAL_TYPE_INDEX_FIELD:
+
+				type = ACPI_TYPE_FIELD_UNIT;
+			}
+
+		}
+
+		/* Allocate a descriptor to hold the type. */
+
+		ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!ret_desc) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		ret_desc->integer.value = type;
+		break;
+
+
+	/*  Def_size_of :=  Size_of_op  Source_object   */
+
+	case AML_SIZE_OF_OP:
+
+		if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
+			obj_desc = acpi_ns_get_attached_object ((ACPI_NAMESPACE_NODE *) obj_desc);
+		}
+
+		if (!obj_desc) {
+			value = 0;
+		}
+
+		else {
+			switch (obj_desc->common.type) {
+
+			case ACPI_TYPE_BUFFER:
+
+				value = obj_desc->buffer.length;
+				break;
+
+
+			case ACPI_TYPE_STRING:
+
+				value = obj_desc->string.length;
+				break;
+
+
+			case ACPI_TYPE_PACKAGE:
+
+				value = obj_desc->package.count;
+				break;
+
+			case INTERNAL_TYPE_REFERENCE:
+
+				value = 4;
+				break;
+
+			default:
+
+				status = AE_AML_OPERAND_TYPE;
+				goto cleanup;
+			}
+		}
+
+		/*
+		 * Now that we have the size of the object, create a result
+		 * object to hold the value
+		 */
+
+		ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!ret_desc) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		ret_desc->integer.value = value;
+		break;
+
+
+	/*  Def_ref_of  :=  Ref_of_op   Source_object   */
+
+	case AML_REF_OF_OP:
+
+		status = acpi_ex_get_object_reference (obj_desc, &ret_desc, walk_state);
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+		break;
+
+
+	/*  Def_deref_of := Deref_of_op Obj_reference   */
+
+	case AML_DEREF_OF_OP:
+
+
+		/* Check for a method local or argument */
+
+		if (!VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
+			/*
+			 * Must resolve/dereference the local/arg reference first
+			 */
+			switch (obj_desc->reference.opcode) {
+			/* Set Obj_desc to the value of the local/arg */
+
+			case AML_LOCAL_OP:
+			case AML_ARG_OP:
+
+				acpi_ds_method_data_get_value (obj_desc->reference.opcode,
+						obj_desc->reference.offset, walk_state, &tmp_desc);
+
+				/*
+				 * Delete our reference to the input object and
+				 * point to the object just retrieved
+				 */
+				acpi_ut_remove_reference (obj_desc);
+				obj_desc = tmp_desc;
+				break;
+
+			default:
+
+				/* Index op - handled below */
+				break;
+			}
+		}
+
+
+		/* Obj_desc may have changed from the code above */
+
+		if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
+			/* Get the actual object from the Node (This is the dereference) */
+
+			ret_desc = ((ACPI_NAMESPACE_NODE *) obj_desc)->object;
+
+			/* Returning a pointer to the object, add another reference! */
+
+			acpi_ut_add_reference (ret_desc);
+		}
+
+		else {
+			/*
+			 * This must be a reference object produced by the Index
+			 * ASL operation -- check internal opcode
+			 */
+
+			if ((obj_desc->reference.opcode != AML_INDEX_OP) &&
+				(obj_desc->reference.opcode != AML_REF_OF_OP)) {
+				status = AE_TYPE;
+				goto cleanup;
+			}
+
+
+			switch (obj_desc->reference.opcode) {
+			case AML_INDEX_OP:
+
+				/*
+				 * Supported target types for the Index operator are
+				 * 1) A Buffer
+				 * 2) A Package
+				 */
+
+				if (obj_desc->reference.target_type == ACPI_TYPE_BUFFER_FIELD) {
+					/*
+					 * The target is a buffer, we must create a new object that
+					 * contains one element of the buffer, the element pointed
+					 * to by the index.
+					 *
+					 * NOTE: index into a buffer is NOT a pointer to a
+					 * sub-buffer of the main buffer, it is only a pointer to a
+					 * single element (byte) of the buffer!
+					 */
+					ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+					if (!ret_desc) {
+						status = AE_NO_MEMORY;
+						goto cleanup;
+					}
+
+					tmp_desc = obj_desc->reference.object;
+					ret_desc->integer.value =
+						tmp_desc->buffer.pointer[obj_desc->reference.offset];
+
+					/* TBD: [Investigate] (see below) Don't add an additional
+					 * ref!
+					 */
+				}
+
+				else if (obj_desc->reference.target_type == ACPI_TYPE_PACKAGE) {
+					/*
+					 * The target is a package, we want to return the referenced
+					 * element of the package.  We must add another reference to
+					 * this object, however.
+					 */
+
+					ret_desc = *(obj_desc->reference.where);
+					if (!ret_desc) {
+						/*
+						 * We can't return a NULL dereferenced value.  This is
+						 * an uninitialized package element and is thus a
+						 * severe error.
+						 */
+
+						status = AE_AML_UNINITIALIZED_ELEMENT;
+						goto cleanup;
+					}
+
+					acpi_ut_add_reference (ret_desc);
+				}
+
+				else {
+					status = AE_AML_OPERAND_TYPE;
+					goto cleanup;
+				}
+
+				break;
+
+
+			case AML_REF_OF_OP:
+
+				ret_desc = obj_desc->reference.object;
+
+				/* Add another reference to the object! */
+
+				acpi_ut_add_reference (ret_desc);
+				break;
+			}
+		}
+
+		break;
+
+
+	default:
+
+		REPORT_ERROR (("Acpi_ex_monadic2: Unknown monadic opcode %X\n",
+			opcode));
+		status = AE_AML_BAD_OPCODE;
+		goto cleanup;
+	}
+
+
+cleanup:
+
+	if (obj_desc) {
+		acpi_ut_remove_reference (obj_desc);
+	}
+
+	/* Delete return object on error */
+
+	if (ACPI_FAILURE (status) &&
+		(ret_desc)) {
+		acpi_ut_remove_reference (ret_desc);
+		ret_desc = NULL;
+	}
+
+	*return_desc = ret_desc;
+	return (status);
+}
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exmutex.c linux/drivers/acpi/executer/exmutex.c
--- v2.4.5/linux/drivers/acpi/executer/exmutex.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exmutex.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,281 @@
+
+/******************************************************************************
+ *
+ * Module Name: exmutex - ASL Mutex Acquire/Release functions
+ *              $Revision: 5 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acinterp.h"
+#include "acnamesp.h"
+#include "achware.h"
+#include "acevents.h"
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exmutex")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_unlink_mutex
+ *
+ * PARAMETERS:  *Obj_desc           - The mutex to be unlinked
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Remove a mutex from the "Acquired_mutex" list
+ *
+ ******************************************************************************/
+
+void
+acpi_ex_unlink_mutex (
+	ACPI_OPERAND_OBJECT     *obj_desc)
+{
+
+	if (obj_desc->mutex.next) {
+		(obj_desc->mutex.next)->mutex.prev = obj_desc->mutex.prev;
+	}
+	if (obj_desc->mutex.prev) {
+		(obj_desc->mutex.prev)->mutex.next = obj_desc->mutex.next;
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_link_mutex
+ *
+ * PARAMETERS:  *Obj_desc           - The mutex to be linked
+ *              *List_head          - head of the "Acquired_mutex" list
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Add a mutex to the "Acquired_mutex" list for this walk
+ *
+ ******************************************************************************/
+
+void
+acpi_ex_link_mutex (
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	ACPI_OPERAND_OBJECT     *list_head)
+{
+
+	/* This object will be the first object in the list */
+
+	obj_desc->mutex.prev = list_head;
+	obj_desc->mutex.next = list_head->mutex.next;
+
+	/* Update old first object to point back to this object */
+
+	if (list_head->mutex.next) {
+		(list_head->mutex.next)->mutex.prev = obj_desc;
+	}
+
+	/* Update list head */
+
+	list_head->mutex.next = obj_desc;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_acquire_mutex
+ *
+ * PARAMETERS:  *Time_desc          - The 'time to delay' object descriptor
+ *              *Obj_desc           - The object descriptor for this op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Acquire an AML mutex
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_acquire_mutex (
+	ACPI_OPERAND_OBJECT     *time_desc,
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_STATUS             status;
+
+
+	if (!obj_desc) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Current Sync must be less than or equal to the sync level of the
+	 * mutex.  This mechanism provides some deadlock prevention
+	 */
+	if (walk_state->current_sync_level > obj_desc->mutex.sync_level) {
+		return (AE_AML_MUTEX_ORDER);
+	}
+
+	/*
+	 * If the mutex is already owned by this thread,
+	 * just increment the acquisition depth
+	 */
+	if (obj_desc->mutex.owner == walk_state) {
+		obj_desc->mutex.acquisition_depth++;
+		return (AE_OK);
+	}
+
+	/* Acquire the mutex, wait if necessary */
+
+	status = acpi_ex_system_acquire_mutex (time_desc, obj_desc);
+	if (ACPI_FAILURE (status)) {
+		/* Includes failure from a timeout on Time_desc */
+
+		return (status);
+	}
+
+	/* Have the mutex, update mutex and walk info */
+
+	obj_desc->mutex.owner = walk_state;
+	obj_desc->mutex.acquisition_depth = 1;
+	walk_state->current_sync_level = obj_desc->mutex.sync_level;
+
+	/* Link the mutex to the walk state for force-unlock at method exit */
+
+	acpi_ex_link_mutex (obj_desc, (ACPI_OPERAND_OBJECT *)
+			 &(walk_state->walk_list->acquired_mutex_list));
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_release_mutex
+ *
+ * PARAMETERS:  *Obj_desc           - The object descriptor for this op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Release a previously acquired Mutex.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_release_mutex (
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_STATUS             status;
+
+
+	if (!obj_desc) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	/*  The mutex must have been previously acquired in order to release it */
+
+	if (!obj_desc->mutex.owner) {
+		return (AE_AML_MUTEX_NOT_ACQUIRED);
+	}
+
+	/* The Mutex is owned, but this thread must be the owner */
+
+	if (obj_desc->mutex.owner != walk_state) {
+		return (AE_AML_NOT_OWNER);
+	}
+
+	/*
+	 * The sync level of the mutex must be less than or
+	 * equal to the current sync level
+	 */
+	if (obj_desc->mutex.sync_level > walk_state->current_sync_level) {
+		return (AE_AML_MUTEX_ORDER);
+	}
+
+	/*
+	 * Match multiple Acquires with multiple Releases
+	 */
+	obj_desc->mutex.acquisition_depth--;
+	if (obj_desc->mutex.acquisition_depth != 0) {
+		/* Just decrement the depth and return */
+
+		return (AE_OK);
+	}
+
+
+	/* Release the mutex */
+
+	status = acpi_ex_system_release_mutex (obj_desc);
+
+	/* Update the mutex and walk state */
+
+	obj_desc->mutex.owner = NULL;
+	walk_state->current_sync_level = obj_desc->mutex.sync_level;
+
+	/* Unlink the mutex from the owner's list */
+
+	acpi_ex_unlink_mutex (obj_desc);
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_release_all_mutexes
+ *
+ * PARAMETERS:  *Mutex_list           - Head of the mutex list
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Release all mutexes in the list
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_release_all_mutexes (
+	ACPI_OPERAND_OBJECT     *list_head)
+{
+	ACPI_OPERAND_OBJECT     *next = list_head->mutex.next;
+	ACPI_OPERAND_OBJECT     *this;
+
+
+	/*
+	 * Traverse the list of owned mutexes, releasing each one.
+	 */
+	while (next) {
+		this = next;
+		next = this->mutex.next;
+
+		/* Mark mutex un-owned */
+
+		this->mutex.owner = NULL;
+		this->mutex.prev = NULL;
+		this->mutex.next = NULL;
+		this->mutex.acquisition_depth = 0;
+
+		 /* Release the mutex */
+
+		acpi_ex_system_release_mutex (this);
+	}
+
+	return (AE_OK);
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exnames.c linux/drivers/acpi/executer/exnames.c
--- v2.4.5/linux/drivers/acpi/executer/exnames.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exnames.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,387 @@
+
+/******************************************************************************
+ *
+ * Module Name: exnames - interpreter/scanner name load/execute
+ *              $Revision: 79 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acinterp.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exnames")
+
+
+/* AML Package Length encodings */
+
+#define ACPI_AML_PACKAGE_TYPE1   0x40
+#define ACPI_AML_PACKAGE_TYPE2   0x4000
+#define ACPI_AML_PACKAGE_TYPE3   0x400000
+#define ACPI_AML_PACKAGE_TYPE4   0x40000000
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_allocate_name_string
+ *
+ * PARAMETERS:  Prefix_count        - Count of parent levels. Special cases:
+ *                                    (-1) = root,  0 = none
+ *              Num_name_segs       - count of 4-character name segments
+ *
+ * RETURN:      A pointer to the allocated string segment.  This segment must
+ *              be deleted by the caller.
+ *
+ * DESCRIPTION: Allocate a buffer for a name string. Ensure allocated name
+ *              string is long enough, and set up prefix if any.
+ *
+ ******************************************************************************/
+
+NATIVE_CHAR *
+acpi_ex_allocate_name_string (
+	u32                     prefix_count,
+	u32                     num_name_segs)
+{
+	NATIVE_CHAR             *temp_ptr;
+	NATIVE_CHAR             *name_string;
+	u32                      size_needed;
+
+
+	/*
+	 * Allow room for all \ and ^ prefixes, all segments, and a Multi_name_prefix.
+	 * Also, one byte for the null terminator.
+	 * This may actually be somewhat longer than needed.
+	 */
+
+	if (prefix_count == (u32) -1) {
+		/* Special case for root */
+
+		size_needed = 1 + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
+	}
+	else {
+		size_needed = prefix_count + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
+	}
+
+	/*
+	 * Allocate a buffer for the name.
+	 * This buffer must be deleted by the caller!
+	 */
+
+	name_string = acpi_ut_allocate (size_needed);
+	if (!name_string) {
+		REPORT_ERROR (("Ex_allocate_name_string: name allocation failure\n"));
+		return (NULL);
+	}
+
+	temp_ptr = name_string;
+
+	/* Set up Root or Parent prefixes if needed */
+
+	if (prefix_count == (u32) -1) {
+		*temp_ptr++ = AML_ROOT_PREFIX;
+	}
+
+	else {
+		while (prefix_count--) {
+			*temp_ptr++ = AML_PARENT_PREFIX;
+		}
+	}
+
+
+	/* Set up Dual or Multi prefixes if needed */
+
+	if (num_name_segs > 2) {
+		/* Set up multi prefixes   */
+
+		*temp_ptr++ = AML_MULTI_NAME_PREFIX_OP;
+		*temp_ptr++ = (char) num_name_segs;
+	}
+
+	else if (2 == num_name_segs) {
+		/* Set up dual prefixes */
+
+		*temp_ptr++ = AML_DUAL_NAME_PREFIX;
+	}
+
+	/*
+	 * Terminate string following prefixes. Acpi_ex_name_segment() will
+	 * append the segment(s)
+	 */
+
+	*temp_ptr = 0;
+
+	return (name_string);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_name_segment
+ *
+ * PARAMETERS:  Interpreter_mode    - Current running mode (load1/Load2/Exec)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute a name segment (4 bytes)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_name_segment (
+	u8                      **in_aml_address,
+	NATIVE_CHAR             *name_string)
+{
+	u8                      *aml_address = *in_aml_address;
+	ACPI_STATUS             status = AE_OK;
+	u32                     index;
+	NATIVE_CHAR             char_buf[5];
+
+
+	/*
+	 * If first character is a digit, then we know that we aren't looking at a
+	 * valid name segment
+	 */
+	char_buf[0] = *aml_address;
+
+	if ('0' <= char_buf[0] && char_buf[0] <= '9') {
+		return (AE_CTRL_PENDING);
+	}
+
+	for (index = 4;
+		(index > 0) && (acpi_ut_valid_acpi_character (*aml_address));
+		--index) {
+		char_buf[4 - index] = *aml_address++;
+	}
+
+
+	/* Valid name segment  */
+
+	if (0 == index) {
+		/* Found 4 valid characters */
+
+		char_buf[4] = '\0';
+
+		if (name_string) {
+			STRCAT (name_string, char_buf);
+		}
+
+	}
+
+	else if (4 == index) {
+		/*
+		 * First character was not a valid name character,
+		 * so we are looking at something other than a name.
+		 */
+		status = AE_CTRL_PENDING;
+	}
+
+	else {
+		/* Segment started with one or more valid characters, but fewer than 4 */
+
+		status = AE_AML_BAD_NAME;
+	}
+
+	*in_aml_address = aml_address;
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_get_name_string
+ *
+ * PARAMETERS:  Data_type           - Data type to be associated with this name
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Get a name, including any prefixes.
+ *
+ ******************************************************************************/
+
+
+ACPI_STATUS
+acpi_ex_get_name_string (
+	ACPI_OBJECT_TYPE8       data_type,
+	u8                      *in_aml_address,
+	NATIVE_CHAR             **out_name_string,
+	u32                     *out_name_length)
+{
+	ACPI_STATUS             status = AE_OK;
+	u8                      *aml_address = in_aml_address;
+	NATIVE_CHAR             *name_string = NULL;
+	u32                     num_segments;
+	u32                     prefix_count = 0;
+	u8                      prefix = 0;
+	u8                      has_prefix = FALSE;
+
+
+	if (INTERNAL_TYPE_REGION_FIELD == data_type  ||
+		INTERNAL_TYPE_BANK_FIELD == data_type    ||
+		INTERNAL_TYPE_INDEX_FIELD == data_type) {
+		/* Disallow prefixes for types associated with Field_unit names */
+
+		name_string = acpi_ex_allocate_name_string (0, 1);
+		if (!name_string) {
+			status = AE_NO_MEMORY;
+		}
+		else {
+			status = acpi_ex_name_segment (&aml_address, name_string);
+		}
+	}
+
+	else {
+		/*
+		 * Data_type is not a field name.
+		 * Examine first character of name for root or parent prefix operators
+		 */
+
+		switch (*aml_address) {
+
+		case AML_ROOT_PREFIX:
+
+			prefix = *aml_address++;
+			/*
+			 * Remember that we have a Root_prefix --
+			 * see comment in Acpi_ex_allocate_name_string()
+			 */
+			prefix_count = (u32) -1;
+			has_prefix = TRUE;
+			break;
+
+
+		case AML_PARENT_PREFIX:
+
+			/* Increment past possibly multiple parent prefixes */
+
+			do {
+				prefix = *aml_address++;
+				++prefix_count;
+
+			} while (*aml_address == AML_PARENT_PREFIX);
+			has_prefix = TRUE;
+			break;
+
+
+		default:
+
+			break;
+		}
+
+
+		/* Examine first character of name for name segment prefix operator */
+
+		switch (*aml_address) {
+
+		case AML_DUAL_NAME_PREFIX:
+
+			prefix = *aml_address++;
+			name_string = acpi_ex_allocate_name_string (prefix_count, 2);
+			if (!name_string) {
+				status = AE_NO_MEMORY;
+				break;
+			}
+
+			/* Indicate that we processed a prefix */
+			has_prefix = TRUE;
+
+			status = acpi_ex_name_segment (&aml_address, name_string);
+			if (ACPI_SUCCESS (status)) {
+				status = acpi_ex_name_segment (&aml_address, name_string);
+			}
+			break;
+
+
+		case AML_MULTI_NAME_PREFIX_OP:
+
+			prefix = *aml_address++;
+			/* Fetch count of segments remaining in name path */
+
+			num_segments = *aml_address++;
+
+			name_string = acpi_ex_allocate_name_string (prefix_count, num_segments);
+			if (!name_string) {
+				status = AE_NO_MEMORY;
+				break;
+			}
+
+			/* Indicate that we processed a prefix */
+			has_prefix = TRUE;
+
+			while (num_segments &&
+					(status = acpi_ex_name_segment (&aml_address, name_string)) == AE_OK) {
+				--num_segments;
+			}
+
+			break;
+
+
+		case 0:
+
+			/* Null_name valid as of 8-12-98 ASL/AML Grammar Update */
+
+
+			/* Consume the NULL byte */
+
+			aml_address++;
+			name_string = acpi_ex_allocate_name_string (prefix_count, 0);
+			if (!name_string) {
+				status = AE_NO_MEMORY;
+				break;
+			}
+
+			break;
+
+
+		default:
+
+			/* Name segment string */
+
+			name_string = acpi_ex_allocate_name_string (prefix_count, 1);
+			if (!name_string) {
+				status = AE_NO_MEMORY;
+				break;
+			}
+
+			status = acpi_ex_name_segment (&aml_address, name_string);
+			break;
+
+		}   /* Switch (Peek_op ())   */
+	}
+
+
+	if (AE_CTRL_PENDING == status && has_prefix) {
+		/* Ran out of segments after processing a prefix */
+
+		REPORT_ERROR (
+			("Ex_do_name: Malformed Name at %p\n", name_string));
+		status = AE_AML_BAD_NAME;
+	}
+
+
+	*out_name_string = name_string;
+	*out_name_length = (u32) (aml_address - in_aml_address);
+
+	return (status);
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exprep.c linux/drivers/acpi/executer/exprep.c
--- v2.4.5/linux/drivers/acpi/executer/exprep.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exprep.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,459 @@
+
+/******************************************************************************
+ *
+ * Module Name: exprep - ACPI AML (p-code) execution - field prep utilities
+ *              $Revision: 90 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acinterp.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+#include "acparser.h"
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exprep")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_decode_field_access_type
+ *
+ * PARAMETERS:  Access          - Encoded field access bits
+ *              Length          - Field length.
+ *
+ * RETURN:      Field granularity (8, 16, or 32)
+ *
+ * DESCRIPTION: Decode the Access_type bits of a field definition.
+ *
+ ******************************************************************************/
+
+static u32
+acpi_ex_decode_field_access_type (
+	u32                     access,
+	u16                     length)
+{
+
+	switch (access) {
+	case ACCESS_ANY_ACC:
+
+		/* Use the length to set the access type */
+
+		if (length <= 8) {
+			return (8);
+		}
+		else if (length <= 16) {
+			return (16);
+		}
+		else if (length <= 32) {
+			return (32);
+		}
+		else if (length <= 64) {
+			return (64);
+		}
+
+		/* Default is 8 (byte) */
+
+		return (8);
+		break;
+
+	case ACCESS_BYTE_ACC:
+		return (8);
+		break;
+
+	case ACCESS_WORD_ACC:
+		return (16);
+		break;
+
+	case ACCESS_DWORD_ACC:
+		return (32);
+		break;
+
+	case ACCESS_QWORD_ACC:  /* ACPI 2.0 */
+		return (64);
+		break;
+
+	default:
+		/* Invalid field access type */
+
+		return (0);
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_prep_common_field_object
+ *
+ * PARAMETERS:  Obj_desc            - The field object
+ *              Field_flags         - Access, Lock_rule, and Update_rule.
+ *                                    The format of a Field_flag is described
+ *                                    in the ACPI specification
+ *              Field_bit_position  - Field start position
+ *              Field_bit_length    - Field length in number of bits
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initialize the areas of the field object that are common
+ *              to the various types of fields.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_prep_common_field_object (
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	u8                      field_flags,
+	u32                     field_bit_position,
+	u32                     field_bit_length)
+{
+	u32                     access_bit_width;
+	u32                     nearest_byte_address;
+
+
+	/*
+	 * Note: the structure being initialized is the
+	 * ACPI_COMMON_FIELD_INFO;  No structure fields outside of the common area
+	 * are initialized by this procedure.
+	 */
+
+	/* Demultiplex the Field_flags byte */
+
+	obj_desc->common_field.lock_rule = (u8) ((field_flags & LOCK_RULE_MASK)
+			 >> LOCK_RULE_SHIFT);
+	obj_desc->common_field.update_rule = (u8) ((field_flags & UPDATE_RULE_MASK)
+			 >> UPDATE_RULE_SHIFT);
+	/* Other misc fields */
+
+	obj_desc->common_field.bit_length = (u16) field_bit_length;
+
+	/* Decode the access type so we can compute offsets */
+
+	access_bit_width = acpi_ex_decode_field_access_type (
+			   ((field_flags & ACCESS_TYPE_MASK) >> ACCESS_TYPE_SHIFT),
+			   obj_desc->field.bit_length);
+	if (!access_bit_width) {
+		return (AE_AML_OPERAND_VALUE);
+	}
+
+	/* Setup width (access granularity) fields */
+
+	obj_desc->common_field.access_bit_width = (u8) access_bit_width;         /* 8, 16, 32, 64 */
+	obj_desc->common_field.access_byte_width = (u8) DIV_8 (access_bit_width); /* 1, 2,  4,  8 */
+
+	if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
+		/*
+		 * Buffer_field access can be on any byte boundary, so the
+		 * granularity is always 8
+		 */
+		access_bit_width = 8;
+	}
+
+
+	/*
+	 * Base_byte_offset is the address of the start of the field within the region. It is
+	 * the byte address of the first *datum* (field-width data unit) of the field.
+	 * (i.e., the first datum that contains at least the first *bit* of the field.)
+	 */
+	nearest_byte_address                      = ROUND_BITS_DOWN_TO_BYTES (field_bit_position);
+	obj_desc->common_field.base_byte_offset   = ROUND_DOWN (nearest_byte_address,
+			   DIV_8 (access_bit_width));
+
+	/*
+	 * Start_field_bit_offset is the offset of the first bit of the field within a field datum.
+	 * This is calculated as the number of bits from the Base_byte_offset. In other words,
+	 * the start of the field is relative to a byte address, regardless of the access type
+	 * of the field.
+	 */
+	obj_desc->common_field.start_field_bit_offset = (u8) (MOD_8 (field_bit_position));
+
+	/*
+	 * Datum_valid_bits is the number of valid field bits in the first field datum.
+	 */
+	obj_desc->common_field.datum_valid_bits   = (u8) (access_bit_width -
+			   obj_desc->common_field.start_field_bit_offset);
+
+	/*
+	 * Valid bits -- the number of bits that compose a partial datum,
+	 * 1) At the end of the field within the region (arbitrary starting bit offset)
+	 * 2) At the end of a buffer used to contain the field (starting offset always zero)
+	 */
+	obj_desc->common_field.end_field_valid_bits = (u8) ((obj_desc->common_field.start_field_bit_offset +
+			   field_bit_length) % access_bit_width);
+	obj_desc->common_field.end_buffer_valid_bits = (u8) (field_bit_length % access_bit_width); /* Start_buffer_bit_offset always = 0 */
+
+
+	/*
+	 * Does the entire field fit within a single field access element
+	 * (datum)?  (without crossing a datum boundary)
+	 */
+	if ((obj_desc->common_field.start_field_bit_offset + obj_desc->common_field.bit_length) <=
+		(u16) obj_desc->common_field.access_bit_width) {
+		obj_desc->common_field.access_flags |= AFIELD_SINGLE_DATUM;
+	}
+
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_prep_region_field_value
+ *
+ * PARAMETERS:  Node                - Owning Node
+ *              Region_node         - Region in which field is being defined
+ *              Field_flags         - Access, Lock_rule, and Update_rule.
+ *              Field_bit_position  - Field start position
+ *              Field_bit_length    - Field length in number of bits
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Construct an ACPI_OPERAND_OBJECT  of type Def_field and
+ *              connect it to the parent Node.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_prep_region_field_value (
+	ACPI_NAMESPACE_NODE     *node,
+	ACPI_HANDLE             region_node,
+	u8                      field_flags,
+	u32                     field_bit_position,
+	u32                     field_bit_length)
+{
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	u32                     type;
+	ACPI_STATUS             status;
+
+
+	/* Parameter validation */
+
+	if (!region_node) {
+		return (AE_AML_NO_OPERAND);
+	}
+
+	type = acpi_ns_get_type (region_node);
+	if (type != ACPI_TYPE_REGION) {
+		return (AE_AML_OPERAND_TYPE);
+	}
+
+	/* Allocate a new object */
+
+	obj_desc = acpi_ut_create_internal_object (INTERNAL_TYPE_REGION_FIELD);
+	if (!obj_desc) {
+		return (AE_NO_MEMORY);
+	}
+
+
+	/* Obj_desc and Region valid */
+
+	/* Initialize areas of the object that are common to all fields */
+
+	status = acpi_ex_prep_common_field_object (obj_desc, field_flags,
+			  field_bit_position, field_bit_length);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/* Initialize areas of the object that are specific to this field type */
+
+	obj_desc->field.region_obj = acpi_ns_get_attached_object (region_node);
+
+	/* An additional reference for the container */
+
+	acpi_ut_add_reference (obj_desc->field.region_obj);
+
+
+	/* Debug info */
+
+
+	/*
+	 * Store the constructed descriptor (Obj_desc) into the parent Node,
+	 * preserving the current type of that Named_obj.
+	 */
+	status = acpi_ns_attach_object (node, obj_desc, (u8) acpi_ns_get_type (node));
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_prep_bank_field_value
+ *
+ * PARAMETERS:  Node                - Owning Node
+ *              Region_node         - Region in which field is being defined
+ *              Bank_register_node  - Bank selection register node
+ *              Bank_val            - Value to store in selection register
+ *              Field_flags         - Access, Lock_rule, and Update_rule
+ *              Field_bit_position  - Field start position
+ *              Field_bit_length    - Field length in number of bits
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Construct an object of type Bank_field and attach it to the
+ *              parent Node.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_prep_bank_field_value (
+	ACPI_NAMESPACE_NODE     *node,
+	ACPI_NAMESPACE_NODE     *region_node,
+	ACPI_NAMESPACE_NODE     *bank_register_node,
+	u32                     bank_val,
+	u8                      field_flags,
+	u32                     field_bit_position,
+	u32                     field_bit_length)
+{
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	u32                     type;
+	ACPI_STATUS             status;
+
+
+	/* Parameter validation */
+
+	if (!region_node) {
+		return (AE_AML_NO_OPERAND);
+	}
+
+	type = acpi_ns_get_type (region_node);
+	if (type != ACPI_TYPE_REGION) {
+		return (AE_AML_OPERAND_TYPE);
+	}
+
+	/* Allocate a new object */
+
+	obj_desc = acpi_ut_create_internal_object (INTERNAL_TYPE_BANK_FIELD);
+	if (!obj_desc) {
+		return (AE_NO_MEMORY);
+	}
+
+	/*  Obj_desc and Region valid   */
+
+	/* Initialize areas of the object that are common to all fields */
+
+	status = acpi_ex_prep_common_field_object (obj_desc, field_flags,
+			  field_bit_position, field_bit_length);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/* Initialize areas of the object that are specific to this field type */
+
+	obj_desc->bank_field.value         = bank_val;
+	obj_desc->bank_field.region_obj    = acpi_ns_get_attached_object (region_node);
+	obj_desc->bank_field.bank_register_obj = acpi_ns_get_attached_object (bank_register_node);
+
+	/* An additional reference for the attached objects */
+
+	acpi_ut_add_reference (obj_desc->bank_field.region_obj);
+	acpi_ut_add_reference (obj_desc->bank_field.bank_register_obj);
+
+	/* Debug info */
+
+
+	/*
+	 * Store the constructed descriptor (Obj_desc) into the parent Node,
+	 * preserving the current type of that Named_obj.
+	 */
+	status = acpi_ns_attach_object (node, obj_desc, (u8) acpi_ns_get_type (node));
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_prep_index_field_value
+ *
+ * PARAMETERS:  Node                - Owning Node
+ *              Index_reg           - Index register
+ *              Data_reg            - Data register
+ *              Field_flags         - Access, Lock_rule, and Update_rule
+ *              Field_bit_position  - Field start position
+ *              Field_bit_length    - Field length in number of bits
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Construct an ACPI_OPERAND_OBJECT  of type Index_field and
+ *              connect it to the parent Node.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_prep_index_field_value (
+	ACPI_NAMESPACE_NODE     *node,
+	ACPI_NAMESPACE_NODE     *index_reg,
+	ACPI_NAMESPACE_NODE     *data_reg,
+	u8                      field_flags,
+	u32                     field_bit_position,
+	u32                     field_bit_length)
+{
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	ACPI_STATUS             status;
+
+
+	/* Parameter validation */
+
+	if (!index_reg || !data_reg) {
+		return (AE_AML_NO_OPERAND);
+	}
+
+	/* Allocate a new object descriptor */
+
+	obj_desc = acpi_ut_create_internal_object (INTERNAL_TYPE_INDEX_FIELD);
+	if (!obj_desc) {
+		return (AE_NO_MEMORY);
+	}
+
+	/* Initialize areas of the object that are common to all fields */
+
+	status = acpi_ex_prep_common_field_object (obj_desc, field_flags,
+			  field_bit_position, field_bit_length);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/* Initialize areas of the object that are specific to this field type */
+
+	obj_desc->index_field.data_obj = acpi_ns_get_attached_object (data_reg);
+	obj_desc->index_field.index_obj = acpi_ns_get_attached_object (index_reg);
+	obj_desc->index_field.value  = (u32) (field_bit_position /
+			  obj_desc->field.access_bit_width);
+
+	/* An additional reference for the attached objects */
+
+	acpi_ut_add_reference (obj_desc->index_field.data_obj);
+	acpi_ut_add_reference (obj_desc->index_field.index_obj);
+
+	/* Debug info */
+
+
+	/*
+	 * Store the constructed descriptor (Obj_desc) into the parent Node,
+	 * preserving the current type of that Named_obj.
+	 */
+	status = acpi_ns_attach_object (node, obj_desc, (u8) acpi_ns_get_type (node));
+	return (status);
+}
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exregion.c linux/drivers/acpi/executer/exregion.c
--- v2.4.5/linux/drivers/acpi/executer/exregion.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exregion.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,409 @@
+
+/******************************************************************************
+ *
+ * Module Name: exregion - ACPI default Op_region (address space) handlers
+ *              $Revision: 48 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acinterp.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+#include "achware.h"
+#include "acevents.h"
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exregion")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_system_memory_space_handler
+ *
+ * PARAMETERS:  Function            - Read or Write operation
+ *              Address             - Where in the space to read or write
+ *              Bit_width           - Field width in bits (8, 16, or 32)
+ *              Value               - Pointer to in or out value
+ *              Handler_context     - Pointer to Handler's context
+ *              Region_context      - Pointer to context specific to the
+ *                                      accessed region
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Handler for the System Memory address space (Op Region)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_system_memory_space_handler (
+	u32                     function,
+	ACPI_PHYSICAL_ADDRESS   address,
+	u32                     bit_width,
+	u32                     *value,
+	void                    *handler_context,
+	void                    *region_context)
+{
+	ACPI_STATUS             status = AE_OK;
+	void                    *logical_addr_ptr = NULL;
+	ACPI_MEM_SPACE_CONTEXT  *mem_info = region_context;
+	u32                     length;
+
+
+	/* Validate and translate the bit width */
+
+	switch (bit_width) {
+	case 8:
+		length = 1;
+		break;
+
+	case 16:
+		length = 2;
+		break;
+
+	case 32:
+		length = 4;
+		break;
+
+	default:
+		return (AE_AML_OPERAND_VALUE);
+		break;
+	}
+
+
+	/*
+	 * Does the request fit into the cached memory mapping?
+	 * Is 1) Address below the current mapping? OR
+	 *    2) Address beyond the current mapping?
+	 */
+
+	if ((address < mem_info->mapped_physical_address) ||
+		(((ACPI_INTEGER) address + length) >
+			((ACPI_INTEGER) mem_info->mapped_physical_address + mem_info->mapped_length))) {
+		/*
+		 * The request cannot be resolved by the current memory mapping;
+		 * Delete the existing mapping and create a new one.
+		 */
+
+		if (mem_info->mapped_length) {
+			/* Valid mapping, delete it */
+
+			acpi_os_unmap_memory (mem_info->mapped_logical_address,
+					   mem_info->mapped_length);
+		}
+
+		mem_info->mapped_length = 0; /* In case of failure below */
+
+		/* Create a new mapping starting at the address given */
+
+		status = acpi_os_map_memory (address, SYSMEM_REGION_WINDOW_SIZE,
+				  (void **) &mem_info->mapped_logical_address);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+
+		/* TBD: should these pointers go to 64-bit in all cases ? */
+
+		mem_info->mapped_physical_address = address;
+		mem_info->mapped_length = SYSMEM_REGION_WINDOW_SIZE;
+	}
+
+
+	/*
+	 * Generate a logical pointer corresponding to the address we want to
+	 * access
+	 */
+
+	/* TBD: should these pointers go to 64-bit in all cases ? */
+
+	logical_addr_ptr = mem_info->mapped_logical_address +
+			  ((ACPI_INTEGER) address - (ACPI_INTEGER) mem_info->mapped_physical_address);
+
+	/* Perform the memory read or write */
+
+	switch (function) {
+
+	case ACPI_READ_ADR_SPACE:
+
+		switch (bit_width) {
+		case 8:
+			*value = (u32)* (u8 *) logical_addr_ptr;
+			break;
+
+		case 16:
+			MOVE_UNALIGNED16_TO_32 (value, logical_addr_ptr);
+			break;
+
+		case 32:
+			MOVE_UNALIGNED32_TO_32 (value, logical_addr_ptr);
+			break;
+		}
+
+		break;
+
+
+	case ACPI_WRITE_ADR_SPACE:
+
+		switch (bit_width) {
+		case 8:
+			*(u8 *) logical_addr_ptr = (u8) *value;
+			break;
+
+		case 16:
+			MOVE_UNALIGNED16_TO_16 (logical_addr_ptr, value);
+			break;
+
+		case 32:
+			MOVE_UNALIGNED32_TO_32 (logical_addr_ptr, value);
+			break;
+		}
+
+		break;
+
+
+	default:
+		status = AE_BAD_PARAMETER;
+		break;
+	}
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_system_io_space_handler
+ *
+ * PARAMETERS:  Function            - Read or Write operation
+ *              Address             - Where in the space to read or write
+ *              Bit_width           - Field width in bits (8, 16, or 32)
+ *              Value               - Pointer to in or out value
+ *              Handler_context     - Pointer to Handler's context
+ *              Region_context      - Pointer to context specific to the
+ *                                      accessed region
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Handler for the System IO address space (Op Region)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_system_io_space_handler (
+	u32                     function,
+	ACPI_PHYSICAL_ADDRESS   address,
+	u32                     bit_width,
+	u32                     *value,
+	void                    *handler_context,
+	void                    *region_context)
+{
+	ACPI_STATUS             status = AE_OK;
+
+
+	/* Decode the function parameter */
+
+	switch (function) {
+
+	case ACPI_READ_ADR_SPACE:
+
+		switch (bit_width) {
+		/* I/O Port width */
+
+		case 8:
+			*value = (u32) acpi_os_in8 ((ACPI_IO_ADDRESS) address);
+			break;
+
+		case 16:
+			*value = (u32) acpi_os_in16 ((ACPI_IO_ADDRESS) address);
+			break;
+
+		case 32:
+			*value = acpi_os_in32 ((ACPI_IO_ADDRESS) address);
+			break;
+
+		default:
+			status = AE_AML_OPERAND_VALUE;
+		}
+
+		break;
+
+
+	case ACPI_WRITE_ADR_SPACE:
+
+		switch (bit_width) {
+		/* I/O Port width */
+		case 8:
+			acpi_os_out8 ((ACPI_IO_ADDRESS) address, (u8) *value);
+			break;
+
+		case 16:
+			acpi_os_out16 ((ACPI_IO_ADDRESS) address, (u16) *value);
+			break;
+
+		case 32:
+			acpi_os_out32 ((ACPI_IO_ADDRESS) address, *value);
+			break;
+
+		default:
+			status = AE_AML_OPERAND_VALUE;
+		}
+
+		break;
+
+
+	default:
+		status = AE_BAD_PARAMETER;
+		break;
+	}
+
+	return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_pci_config_space_handler
+ *
+ * PARAMETERS:  Function            - Read or Write operation
+ *              Address             - Where in the space to read or write
+ *              Bit_width           - Field width in bits (8, 16, or 32)
+ *              Value               - Pointer to in or out value
+ *              Handler_context     - Pointer to Handler's context
+ *              Region_context      - Pointer to context specific to the
+ *                                      accessed region
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Handler for the PCI Config address space (Op Region)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_pci_config_space_handler (
+	u32                     function,
+	ACPI_PHYSICAL_ADDRESS   address,
+	u32                     bit_width,
+	u32                     *value,
+	void                    *handler_context,
+	void                    *region_context)
+{
+	ACPI_STATUS             status = AE_OK;
+	u32                     pci_bus;
+	u32                     dev_func;
+	u8                      pci_reg;
+	ACPI_PCI_SPACE_CONTEXT  *PCIcontext;
+
+
+	/*
+	 *  The arguments to Acpi_os(Read|Write)Pci_cfg(Byte|Word|Dword) are:
+	 *
+	 *  Seg_bus - 0xSSSSBBBB    - SSSS is the PCI bus segment
+	 *                            BBBB is the PCI bus number
+	 *
+	 *  Dev_func - 0xDDDDFFFF   - DDDD is the PCI device number
+	 *                            FFFF is the PCI device function number
+	 *
+	 *  Reg_num - Config space register must be < 40h
+	 *
+	 *  Value - input value for write, output for read
+	 *
+	 */
+
+	PCIcontext = (ACPI_PCI_SPACE_CONTEXT *) region_context;
+
+	pci_bus = LOWORD (PCIcontext->seg) << 16;
+	pci_bus |= LOWORD (PCIcontext->bus);
+
+	dev_func = PCIcontext->dev_func;
+
+	pci_reg = (u8) address;
+
+	switch (function) {
+
+	case ACPI_READ_ADR_SPACE:
+
+		*value  = 0;
+
+		switch (bit_width) {
+		/* PCI Register width */
+
+		case 8:
+			status = acpi_os_read_pci_cfg_byte (pci_bus, dev_func, pci_reg,
+					   (u8 *) value);
+			break;
+
+		case 16:
+			status = acpi_os_read_pci_cfg_word (pci_bus, dev_func, pci_reg,
+					   (u16 *) value);
+			break;
+
+		case 32:
+			status = acpi_os_read_pci_cfg_dword (pci_bus, dev_func, pci_reg,
+					   value);
+			break;
+
+		default:
+			status = AE_AML_OPERAND_VALUE;
+
+		} /* Switch bit_width */
+
+		break;
+
+
+	case ACPI_WRITE_ADR_SPACE:
+
+		switch (bit_width) {
+		/* PCI Register width */
+
+		case 8:
+			status = acpi_os_write_pci_cfg_byte (pci_bus, dev_func, pci_reg,
+					 *(u8 *) value);
+			break;
+
+		case 16:
+			status = acpi_os_write_pci_cfg_word (pci_bus, dev_func, pci_reg,
+					 *(u16 *) value);
+			break;
+
+		case 32:
+			status = acpi_os_write_pci_cfg_dword (pci_bus, dev_func, pci_reg,
+					 *value);
+			break;
+
+		default:
+			status = AE_AML_OPERAND_VALUE;
+
+		} /* Switch bit_width */
+
+		break;
+
+
+	default:
+
+		status = AE_BAD_PARAMETER;
+		break;
+
+	}
+
+	return (status);
+}
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exresnte.c linux/drivers/acpi/executer/exresnte.c
--- v2.4.5/linux/drivers/acpi/executer/exresnte.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exresnte.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,320 @@
+
+/******************************************************************************
+ *
+ * Module Name: exresnte - AML Interpreter object resolution
+ *              $Revision: 37 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "amlcode.h"
+#include "acparser.h"
+#include "acdispat.h"
+#include "acinterp.h"
+#include "acnamesp.h"
+#include "actables.h"
+#include "acevents.h"
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exresnte")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_resolve_node_to_value
+ *
+ * PARAMETERS:  Stack_ptr       - Pointer to a location on a stack that contains
+ *                                a pointer to a Node
+ *              Walk_state      - Current state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Resolve a Namespace node (AKA a "direct name pointer") to
+ *              a valued object
+ *
+ * Note: for some of the data types, the pointer attached to the Node
+ * can be either a pointer to an actual internal object or a pointer into the
+ * AML stream itself.  These types are currently:
+ *
+ *      ACPI_TYPE_INTEGER
+ *      ACPI_TYPE_STRING
+ *      ACPI_TYPE_BUFFER
+ *      ACPI_TYPE_MUTEX
+ *      ACPI_TYPE_PACKAGE
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_resolve_node_to_value (
+	ACPI_NAMESPACE_NODE     **stack_ptr,
+	ACPI_WALK_STATE         *walk_state)
+
+{
+	ACPI_STATUS             status = AE_OK;
+	ACPI_OPERAND_OBJECT     *val_desc;
+	ACPI_OPERAND_OBJECT     *obj_desc = NULL;
+	ACPI_NAMESPACE_NODE     *node;
+	u8                      *aml_pointer = NULL;
+	ACPI_OBJECT_TYPE8       entry_type;
+	ACPI_INTEGER            temp_val;
+	u8                      attached_aml_pointer = FALSE;
+	u8                      aml_opcode = 0;
+
+
+	/*
+	 * The stack pointer points to a ACPI_NAMESPACE_NODE (Node).  Get the
+	 * object that is attached to the Node.
+	 */
+
+	node      = *stack_ptr;
+	val_desc  = acpi_ns_get_attached_object (node);
+	entry_type = acpi_ns_get_type ((ACPI_HANDLE) node);
+
+	/*
+	 * The Val_desc attached to the Node can be either:
+	 * 1) An internal ACPI object
+	 * 2) A pointer into the AML stream (into one of the ACPI system tables)
+	 */
+
+	if (acpi_tb_system_table_pointer (val_desc)) {
+		/* CAN THIS EVERY HAPPEN NOW?  TBD!!! */
+
+		attached_aml_pointer = TRUE;
+		aml_opcode = *((u8 *) val_desc);
+		aml_pointer = ((u8 *) val_desc) + 1;
+
+	}
+
+
+	/*
+	 * Several Entry_types do not require further processing, so
+	 *  we will return immediately
+	 */
+	/* Devices rarely have an attached object, return the Node
+	 *  and Method locals and arguments have a pseudo-Node
+	 */
+	if (entry_type == ACPI_TYPE_DEVICE ||
+		(node->flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) {
+		return (AE_OK);
+	}
+
+	if (!val_desc) {
+		return (AE_AML_NO_OPERAND);
+	}
+
+	/*
+	 * Action is based on the type of the Node, which indicates the type
+	 * of the attached object or pointer
+	 */
+	switch (entry_type) {
+
+	case ACPI_TYPE_PACKAGE:
+
+		if (attached_aml_pointer) {
+			/*
+			 * This means that the package initialization is not parsed
+			 * -- should not happen
+			 */
+			return (AE_NOT_IMPLEMENTED);
+		}
+
+		/* Val_desc is an internal object in all cases by the time we get here */
+
+		if (ACPI_TYPE_PACKAGE != val_desc->common.type) {
+			return (AE_AML_OPERAND_TYPE);
+		}
+
+		/* Return an additional reference to the object */
+
+		obj_desc = val_desc;
+		acpi_ut_add_reference (obj_desc);
+		break;
+
+
+	case ACPI_TYPE_BUFFER:
+
+		if (attached_aml_pointer) {
+			/*
+			 * This means that the buffer initialization is not parsed
+			 * -- should not happen
+			 */
+			return (AE_NOT_IMPLEMENTED);
+		}
+
+		/* Val_desc is an internal object in all cases by the time we get here */
+
+		if (ACPI_TYPE_BUFFER != val_desc->common.type) {
+			return (AE_AML_OPERAND_TYPE);
+		}
+
+		/* Return an additional reference to the object */
+
+		obj_desc = val_desc;
+		acpi_ut_add_reference (obj_desc);
+		break;
+
+
+	case ACPI_TYPE_STRING:
+
+		if (attached_aml_pointer) {
+			/* Allocate a new string object */
+
+			obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
+			if (!obj_desc) {
+				return (AE_NO_MEMORY);
+			}
+
+			/* Init the internal object */
+
+			obj_desc->string.pointer = (NATIVE_CHAR *) aml_pointer;
+			obj_desc->string.length = STRLEN (obj_desc->string.pointer);
+		}
+
+		else {
+			if (ACPI_TYPE_STRING != val_desc->common.type) {
+				return (AE_AML_OPERAND_TYPE);
+			}
+
+			/* Return an additional reference to the object */
+
+			obj_desc = val_desc;
+			acpi_ut_add_reference (obj_desc);
+		}
+
+		break;
+
+
+	case ACPI_TYPE_INTEGER:
+
+		/*
+		 * The Node has an attached internal object, make sure that it's a
+		 * number
+		 */
+
+		if (ACPI_TYPE_INTEGER != val_desc->common.type) {
+			return (AE_AML_OPERAND_TYPE);
+		}
+
+		/* Return an additional reference to the object */
+
+		obj_desc = val_desc;
+		acpi_ut_add_reference (obj_desc);
+		break;
+
+
+	case ACPI_TYPE_BUFFER_FIELD:
+	case INTERNAL_TYPE_REGION_FIELD:
+	case INTERNAL_TYPE_BANK_FIELD:
+	case INTERNAL_TYPE_INDEX_FIELD:
+
+		status = acpi_ex_read_data_from_field (val_desc, &obj_desc);
+		break;
+
+
+	/*
+	 * For these objects, just return the object attached to the Node
+	 */
+
+	case ACPI_TYPE_MUTEX:
+	case ACPI_TYPE_METHOD:
+	case ACPI_TYPE_POWER:
+	case ACPI_TYPE_PROCESSOR:
+	case ACPI_TYPE_THERMAL:
+	case ACPI_TYPE_EVENT:
+	case ACPI_TYPE_REGION:
+
+
+		/* Return an additional reference to the object */
+
+		obj_desc = val_desc;
+		acpi_ut_add_reference (obj_desc);
+		break;
+
+
+	/* TYPE_Any is untyped, and thus there is no object associated with it */
+
+	case ACPI_TYPE_ANY:
+
+		return (AE_AML_OPERAND_TYPE);  /* Cannot be AE_TYPE */
+		break;
+
+
+	/*
+	 * The only named references allowed are named constants
+	 *   e.g. -- Name (\OSFL, Ones)
+	 */
+	case INTERNAL_TYPE_REFERENCE:
+
+		switch (val_desc->reference.opcode) {
+
+		case AML_ZERO_OP:
+
+			temp_val = 0;
+			break;
+
+		case AML_ONE_OP:
+
+			temp_val = 1;
+			break;
+
+		case AML_ONES_OP:
+
+			temp_val = ACPI_INTEGER_MAX;
+			break;
+
+		default:
+
+			return (AE_AML_BAD_OPCODE);
+		}
+
+		/* Create object for result */
+
+		obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!obj_desc) {
+			return (AE_NO_MEMORY);
+		}
+
+		obj_desc->integer.value = temp_val;
+
+		/* Truncate value if we are executing from a 32-bit ACPI table */
+
+		acpi_ex_truncate_for32bit_table (obj_desc, walk_state);
+		break;
+
+
+	/* Default case is for unknown types */
+
+	default:
+
+		return (AE_AML_OPERAND_TYPE);
+
+	} /* switch (Entry_type) */
+
+
+	/* Put the object descriptor on the stack */
+
+	*stack_ptr = (void *) obj_desc;
+	return (status);
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exresolv.c linux/drivers/acpi/executer/exresolv.c
--- v2.4.5/linux/drivers/acpi/executer/exresolv.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exresolv.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,401 @@
+
+/******************************************************************************
+ *
+ * Module Name: exresolv - AML Interpreter object resolution
+ *              $Revision: 95 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "amlcode.h"
+#include "acparser.h"
+#include "acdispat.h"
+#include "acinterp.h"
+#include "acnamesp.h"
+#include "actables.h"
+#include "acevents.h"
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exresolv")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_get_buffer_field_value
+ *
+ * PARAMETERS:  *Obj_desc           - Pointer to a Buffer_field
+ *              *Result_desc        - Pointer to an empty descriptor which will
+ *                                    become an Integer with the field's value
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Retrieve the value from a Buffer_field
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_get_buffer_field_value (
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	ACPI_OPERAND_OBJECT     *result_desc)
+{
+	ACPI_STATUS             status;
+	u32                     mask;
+	u8                      *location;
+
+
+	/*
+	 * Parameter validation
+	 */
+	if (!obj_desc) {
+		return (AE_AML_NO_OPERAND);
+	}
+
+	if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
+		status = acpi_ds_get_buffer_field_arguments (obj_desc);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+	}
+
+	if (!obj_desc->buffer_field.buffer_obj) {
+		return (AE_AML_INTERNAL);
+	}
+
+	if (ACPI_TYPE_BUFFER != obj_desc->buffer_field.buffer_obj->common.type) {
+		return (AE_AML_OPERAND_TYPE);
+	}
+
+	if (!result_desc) {
+		return (AE_AML_INTERNAL);
+	}
+
+
+	/* Field location is (base of buffer) + (byte offset) */
+
+	location = obj_desc->buffer_field.buffer_obj->buffer.pointer
+			 + obj_desc->buffer_field.base_byte_offset;
+
+	/*
+	 * Construct Mask with as many 1 bits as the field width
+	 *
+	 * NOTE: Only the bottom 5 bits are valid for a shift operation, so
+	 *  special care must be taken for any shift greater than 31 bits.
+	 *
+	 * TBD: [Unhandled] Fields greater than 32 bits will not work.
+	 */
+	if (obj_desc->buffer_field.bit_length < 32) {
+		mask = ((u32) 1 << obj_desc->buffer_field.bit_length) - (u32) 1;
+	}
+	else {
+		mask = ACPI_UINT32_MAX;
+	}
+
+	result_desc->integer.type = (u8) ACPI_TYPE_INTEGER;
+
+	/* Get the 32 bit value at the location */
+
+	MOVE_UNALIGNED32_TO_32 (&result_desc->integer.value, location);
+
+	/*
+	 * Shift the 32-bit word containing the field, and mask off the
+	 * resulting value
+	 */
+	result_desc->integer.value =
+		(result_desc->integer.value >> obj_desc->buffer_field.start_field_bit_offset) & mask;
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_resolve_to_value
+ *
+ * PARAMETERS:  **Stack_ptr         - Points to entry on Obj_stack, which can
+ *                                    be either an (ACPI_OPERAND_OBJECT *)
+ *                                    or an ACPI_HANDLE.
+ *              Walk_state          - Current method state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert Reference objects to values
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_resolve_to_value (
+	ACPI_OPERAND_OBJECT     **stack_ptr,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_STATUS             status;
+
+
+	if (!stack_ptr || !*stack_ptr) {
+		return (AE_AML_NO_OPERAND);
+	}
+
+
+	/*
+	 * The entity pointed to by the Stack_ptr can be either
+	 * 1) A valid ACPI_OPERAND_OBJECT, or
+	 * 2) A ACPI_NAMESPACE_NODE (Named_obj)
+	 */
+	if (VALID_DESCRIPTOR_TYPE (*stack_ptr, ACPI_DESC_TYPE_INTERNAL)) {
+		status = acpi_ex_resolve_object_to_value (stack_ptr, walk_state);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+	}
+
+	/*
+	 * Object on the stack may have changed if Acpi_ex_resolve_object_to_value()
+	 * was called (i.e., we can't use an _else_ here.)
+	 */
+	if (VALID_DESCRIPTOR_TYPE (*stack_ptr, ACPI_DESC_TYPE_NAMED)) {
+		status = acpi_ex_resolve_node_to_value ((ACPI_NAMESPACE_NODE **) stack_ptr,
+				  walk_state);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+	}
+
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_resolve_object_to_value
+ *
+ * PARAMETERS:  Stack_ptr       - Pointer to a stack location that contains a
+ *                                ptr to an internal object.
+ *              Walk_state      - Current method state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Retrieve the value from an internal object.  The Reference type
+ *              uses the associated AML opcode to determine the value.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_resolve_object_to_value (
+	ACPI_OPERAND_OBJECT     **stack_ptr,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_STATUS             status = AE_OK;
+	ACPI_OPERAND_OBJECT     *stack_desc;
+	void                    *temp_node;
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	u16                     opcode;
+
+
+	stack_desc = *stack_ptr;
+
+	/* This is an ACPI_OPERAND_OBJECT  */
+
+	switch (stack_desc->common.type) {
+
+	case INTERNAL_TYPE_REFERENCE:
+
+		opcode = stack_desc->reference.opcode;
+
+		switch (opcode) {
+
+		case AML_NAME_OP:
+
+			/*
+			 * Convert indirect name ptr to a direct name ptr.
+			 * Then, Acpi_ex_resolve_node_to_value can be used to get the value
+			 */
+			temp_node = stack_desc->reference.object;
+
+			/* Delete the Reference Object */
+
+			acpi_ut_remove_reference (stack_desc);
+
+			/* Put direct name pointer onto stack and exit */
+
+			(*stack_ptr) = temp_node;
+			break;
+
+
+		case AML_LOCAL_OP:
+		case AML_ARG_OP:
+
+			/*
+			 * Get the local from the method's state info
+			 * Note: this increments the local's object reference count
+			 */
+			status = acpi_ds_method_data_get_value (opcode,
+					  stack_desc->reference.offset, walk_state, &obj_desc);
+			if (ACPI_FAILURE (status)) {
+				return (status);
+			}
+
+			/*
+			 * Now we can delete the original Reference Object and
+			 * replace it with the resolve value
+			 */
+			acpi_ut_remove_reference (stack_desc);
+			*stack_ptr = obj_desc;
+
+			break;
+
+
+		/*
+		 * TBD: [Restructure] These next three opcodes change the type of
+		 * the object, which is actually a no-no.
+		 */
+		case AML_ZERO_OP:
+
+			stack_desc->common.type = (u8) ACPI_TYPE_INTEGER;
+			stack_desc->integer.value = 0;
+			break;
+
+
+		case AML_ONE_OP:
+
+			stack_desc->common.type = (u8) ACPI_TYPE_INTEGER;
+			stack_desc->integer.value = 1;
+			break;
+
+
+		case AML_ONES_OP:
+
+			stack_desc->common.type = (u8) ACPI_TYPE_INTEGER;
+			stack_desc->integer.value = ACPI_INTEGER_MAX;
+
+			/* Truncate value if we are executing from a 32-bit ACPI table */
+
+			acpi_ex_truncate_for32bit_table (stack_desc, walk_state);
+			break;
+
+
+		case AML_INDEX_OP:
+
+			switch (stack_desc->reference.target_type) {
+			case ACPI_TYPE_BUFFER_FIELD:
+
+				/* Just return - leave the Reference on the stack */
+				break;
+
+
+			case ACPI_TYPE_PACKAGE:
+				obj_desc = *stack_desc->reference.where;
+				if (obj_desc) {
+					/*
+					 * Valid obj descriptor, copy pointer to return value
+					 * (i.e., dereference the package index)
+					 * Delete the ref object, increment the returned object
+					 */
+					acpi_ut_remove_reference (stack_desc);
+					acpi_ut_add_reference (obj_desc);
+					*stack_ptr = obj_desc;
+				}
+
+				else {
+					/*
+					 * A NULL object descriptor means an unitialized element of
+					 * the package, can't dereference it
+					 */
+					status = AE_AML_UNINITIALIZED_ELEMENT;
+				}
+				break;
+
+			default:
+				/* Invalid reference object */
+
+				status = AE_AML_INTERNAL;
+				break;
+			}
+
+			break;
+
+
+		case AML_DEBUG_OP:
+
+			/* Just leave the object as-is */
+			break;
+
+
+		default:
+
+			status = AE_AML_INTERNAL;
+			break;
+
+		}   /* switch (Opcode) */
+
+		break; /* case INTERNAL_TYPE_REFERENCE */
+
+
+	case ACPI_TYPE_BUFFER_FIELD:
+
+		obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_ANY);
+		if (!obj_desc) {
+			return (AE_NO_MEMORY);
+		}
+
+		status = acpi_ex_get_buffer_field_value (stack_desc, obj_desc);
+		if (ACPI_FAILURE (status)) {
+			acpi_ut_remove_reference (obj_desc);
+			obj_desc = NULL;
+		}
+
+		*stack_ptr = (void *) obj_desc;
+		break;
+
+
+	case INTERNAL_TYPE_BANK_FIELD:
+
+		obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_ANY);
+		if (!obj_desc) {
+			return (AE_NO_MEMORY);
+		}
+
+		/* TBD: WRONG! */
+
+		status = acpi_ex_get_buffer_field_value (stack_desc, obj_desc);
+		if (ACPI_FAILURE (status)) {
+			acpi_ut_remove_reference (obj_desc);
+			obj_desc = NULL;
+		}
+
+		*stack_ptr = (void *) obj_desc;
+		break;
+
+
+	/* TBD: [Future] - may need to handle Index_field, and Def_field someday */
+
+	default:
+
+		break;
+
+	}   /* switch (Stack_desc->Common.Type) */
+
+
+	return (status);
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exresop.c linux/drivers/acpi/executer/exresop.c
--- v2.4.5/linux/drivers/acpi/executer/exresop.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exresop.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,480 @@
+
+/******************************************************************************
+ *
+ * Module Name: exresop - AML Interpreter operand/object resolution
+ *              $Revision: 29 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "amlcode.h"
+#include "acparser.h"
+#include "acdispat.h"
+#include "acinterp.h"
+#include "acnamesp.h"
+#include "actables.h"
+#include "acevents.h"
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exresop")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_check_object_type
+ *
+ * PARAMETERS:  Type_needed         Object type needed
+ *              This_type           Actual object type
+ *              Object              Object pointer
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check required type against actual type
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_check_object_type (
+	ACPI_OBJECT_TYPE        type_needed,
+	ACPI_OBJECT_TYPE        this_type,
+	void                    *object)
+{
+
+
+	if (type_needed == ACPI_TYPE_ANY) {
+		/* All types OK, so we don't perform any typechecks */
+
+		return (AE_OK);
+	}
+
+	if (type_needed != this_type) {
+		return (AE_AML_OPERAND_TYPE);
+	}
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_resolve_operands
+ *
+ * PARAMETERS:  Opcode              Opcode being interpreted
+ *              Stack_ptr           Top of operand stack
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert stack entries to required types
+ *
+ *      Each nibble in Arg_types represents one required operand
+ *      and indicates the required Type:
+ *
+ *      The corresponding stack entry will be converted to the
+ *      required type if possible, else return an exception
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_resolve_operands (
+	u16                     opcode,
+	ACPI_OPERAND_OBJECT     **stack_ptr,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	ACPI_STATUS             status = AE_OK;
+	u8                      object_type;
+	void                    *temp_node;
+	u32                     arg_types;
+	ACPI_OPCODE_INFO        *op_info;
+	u32                     this_arg_type;
+	ACPI_OBJECT_TYPE        type_needed;
+
+
+	op_info = acpi_ps_get_opcode_info (opcode);
+	if (ACPI_GET_OP_TYPE (op_info) != ACPI_OP_TYPE_OPCODE) {
+		return (AE_AML_BAD_OPCODE);
+	}
+
+
+	arg_types = op_info->runtime_args;
+	if (arg_types == ARGI_INVALID_OPCODE) {
+		return (AE_AML_INTERNAL);
+	}
+
+
+	/*
+	 * Normal exit is with (Arg_types == 0) at end of argument list.
+	 * Function will return an exception from within the loop upon
+	 * finding an entry which is not (or cannot be converted
+	 * to) the required type; if stack underflows; or upon
+	 * finding a NULL stack entry (which should not happen).
+	 */
+
+	while (GET_CURRENT_ARG_TYPE (arg_types)) {
+		if (!stack_ptr || !*stack_ptr) {
+			return (AE_AML_INTERNAL);
+		}
+
+		/* Extract useful items */
+
+		obj_desc = *stack_ptr;
+
+		/* Decode the descriptor type */
+
+		if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
+			/* Node */
+
+			object_type = ((ACPI_NAMESPACE_NODE *) obj_desc)->type;
+		}
+
+		else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) {
+			/* ACPI internal object */
+
+			object_type = obj_desc->common.type;
+
+			/* Check for bad ACPI_OBJECT_TYPE */
+
+			if (!acpi_ex_validate_object_type (object_type)) {
+				return (AE_AML_OPERAND_TYPE);
+			}
+
+			if (object_type == (u8) INTERNAL_TYPE_REFERENCE) {
+				/*
+				 * Decode the Reference
+				 */
+
+				op_info = acpi_ps_get_opcode_info (opcode);
+				if (ACPI_GET_OP_TYPE (op_info) != ACPI_OP_TYPE_OPCODE) {
+					return (AE_AML_BAD_OPCODE);
+				}
+
+
+				switch (obj_desc->reference.opcode) {
+				case AML_ZERO_OP:
+				case AML_ONE_OP:
+				case AML_ONES_OP:
+				case AML_DEBUG_OP:
+				case AML_NAME_OP:
+				case AML_INDEX_OP:
+				case AML_ARG_OP:
+				case AML_LOCAL_OP:
+
+					break;
+
+				default:
+					return (AE_AML_OPERAND_TYPE);
+					break;
+				}
+			}
+		}
+
+		else {
+			/* Invalid descriptor */
+
+			return (AE_AML_OPERAND_TYPE);
+		}
+
+
+		/*
+		 * Get one argument type, point to the next
+		 */
+
+		this_arg_type = GET_CURRENT_ARG_TYPE (arg_types);
+		INCREMENT_ARG_LIST (arg_types);
+
+
+		/*
+		 * Handle cases where the object does not need to be
+		 * resolved to a value
+		 */
+
+		switch (this_arg_type) {
+
+		case ARGI_REFERENCE:            /* References */
+		case ARGI_INTEGER_REF:
+		case ARGI_OBJECT_REF:
+		case ARGI_DEVICE_REF:
+		case ARGI_TARGETREF:            /* TBD: must implement implicit conversion rules before store */
+		case ARGI_FIXED_TARGET:         /* No implicit conversion before store to target */
+		case ARGI_SIMPLE_TARGET:        /* Name, Local, or Arg - no implicit conversion */
+
+			/* Need an operand of type INTERNAL_TYPE_REFERENCE */
+
+			if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED))            /* direct name ptr OK as-is */ {
+				goto next_operand;
+			}
+
+			status = acpi_ex_check_object_type (INTERNAL_TYPE_REFERENCE,
+					  object_type, obj_desc);
+			if (ACPI_FAILURE (status)) {
+				return (status);
+			}
+
+
+			if (AML_NAME_OP == obj_desc->reference.opcode) {
+				/*
+				 * Convert an indirect name ptr to direct name ptr and put
+				 * it on the stack
+				 */
+
+				temp_node = obj_desc->reference.object;
+				acpi_ut_remove_reference (obj_desc);
+				(*stack_ptr) = temp_node;
+			}
+
+			goto next_operand;
+			break;
+
+
+		case ARGI_ANYTYPE:
+
+			/*
+			 * We don't want to resolve Index_op reference objects during
+			 * a store because this would be an implicit De_ref_of operation.
+			 * Instead, we just want to store the reference object.
+			 * -- All others must be resolved below.
+			 */
+
+			if ((opcode == AML_STORE_OP) &&
+				((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) &&
+				((*stack_ptr)->reference.opcode == AML_INDEX_OP)) {
+				goto next_operand;
+			}
+			break;
+		}
+
+
+		/*
+		 * Resolve this object to a value
+		 */
+
+		status = acpi_ex_resolve_to_value (stack_ptr, walk_state);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+
+
+		/*
+		 * Check the resulting object (value) type
+		 */
+		switch (this_arg_type) {
+		/*
+		 * For the simple cases, only one type of resolved object
+		 * is allowed
+		 */
+		case ARGI_MUTEX:
+
+			/* Need an operand of type ACPI_TYPE_MUTEX */
+
+			type_needed = ACPI_TYPE_MUTEX;
+			break;
+
+		case ARGI_EVENT:
+
+			/* Need an operand of type ACPI_TYPE_EVENT */
+
+			type_needed = ACPI_TYPE_EVENT;
+			break;
+
+		case ARGI_REGION:
+
+			/* Need an operand of type ACPI_TYPE_REGION */
+
+			type_needed = ACPI_TYPE_REGION;
+			break;
+
+		case ARGI_IF:   /* If */
+
+			/* Need an operand of type INTERNAL_TYPE_IF */
+
+			type_needed = INTERNAL_TYPE_IF;
+			break;
+
+		case ARGI_PACKAGE:   /* Package */
+
+			/* Need an operand of type ACPI_TYPE_PACKAGE */
+
+			type_needed = ACPI_TYPE_PACKAGE;
+			break;
+
+		case ARGI_ANYTYPE:
+
+			/* Any operand type will do */
+
+			type_needed = ACPI_TYPE_ANY;
+			break;
+
+
+		/*
+		 * The more complex cases allow multiple resolved object types
+		 */
+
+		case ARGI_INTEGER:   /* Number */
+
+			/*
+			 * Need an operand of type ACPI_TYPE_INTEGER,
+			 * But we can implicitly convert from a STRING or BUFFER
+			 */
+			status = acpi_ex_convert_to_integer (stack_ptr, walk_state);
+			if (ACPI_FAILURE (status)) {
+				if (status == AE_TYPE) {
+					return (AE_AML_OPERAND_TYPE);
+				}
+
+				return (status);
+			}
+
+			goto next_operand;
+			break;
+
+
+		case ARGI_BUFFER:
+
+			/*
+			 * Need an operand of type ACPI_TYPE_BUFFER,
+			 * But we can implicitly convert from a STRING or INTEGER
+			 */
+			status = acpi_ex_convert_to_buffer (stack_ptr, walk_state);
+			if (ACPI_FAILURE (status)) {
+				if (status == AE_TYPE) {
+					return (AE_AML_OPERAND_TYPE);
+				}
+
+				return (status);
+			}
+
+			goto next_operand;
+			break;
+
+
+		case ARGI_STRING:
+
+			/*
+			 * Need an operand of type ACPI_TYPE_STRING,
+			 * But we can implicitly convert from a BUFFER or INTEGER
+			 */
+			status = acpi_ex_convert_to_string (stack_ptr, walk_state);
+			if (ACPI_FAILURE (status)) {
+				if (status == AE_TYPE) {
+					return (AE_AML_OPERAND_TYPE);
+				}
+
+				return (status);
+			}
+
+			goto next_operand;
+			break;
+
+
+		case ARGI_COMPUTEDATA:
+
+			/* Need an operand of type INTEGER, STRING or BUFFER */
+
+			if ((ACPI_TYPE_INTEGER != (*stack_ptr)->common.type) &&
+				(ACPI_TYPE_STRING != (*stack_ptr)->common.type) &&
+				(ACPI_TYPE_BUFFER != (*stack_ptr)->common.type)) {
+				return (AE_AML_OPERAND_TYPE);
+			}
+			goto next_operand;
+			break;
+
+
+		case ARGI_DATAOBJECT:
+			/*
+			 * ARGI_DATAOBJECT is only used by the Size_of operator.
+			 *
+			 * The ACPI specification allows Size_of to return the size of
+			 *  a Buffer, String or Package.  However, the MS ACPI.SYS AML
+			 *  Interpreter also allows an Node reference to return without
+			 *  error with a size of 4.
+			 */
+
+			/* Need a buffer, string, package or Node reference */
+
+			if (((*stack_ptr)->common.type != ACPI_TYPE_BUFFER) &&
+				((*stack_ptr)->common.type != ACPI_TYPE_STRING) &&
+				((*stack_ptr)->common.type != ACPI_TYPE_PACKAGE) &&
+				((*stack_ptr)->common.type != INTERNAL_TYPE_REFERENCE)) {
+				return (AE_AML_OPERAND_TYPE);
+			}
+
+			/*
+			 * If this is a reference, only allow a reference to an Node.
+			 */
+			if ((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) {
+				if (!(*stack_ptr)->reference.node) {
+					return (AE_AML_OPERAND_TYPE);
+				}
+			}
+			goto next_operand;
+			break;
+
+
+		case ARGI_COMPLEXOBJ:
+
+			/* Need a buffer or package or (ACPI 2.0) String */
+
+			if (((*stack_ptr)->common.type != ACPI_TYPE_BUFFER) &&
+				((*stack_ptr)->common.type != ACPI_TYPE_STRING) &&
+				((*stack_ptr)->common.type != ACPI_TYPE_PACKAGE)) {
+				return (AE_AML_OPERAND_TYPE);
+			}
+			goto next_operand;
+			break;
+
+
+		default:
+
+			/* Unknown type */
+
+			return (AE_BAD_PARAMETER);
+		}
+
+
+		/*
+		 * Make sure that the original object was resolved to the
+		 * required object type (Simple cases only).
+		 */
+		status = acpi_ex_check_object_type (type_needed,
+				  (*stack_ptr)->common.type, *stack_ptr);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+
+
+next_operand:
+		/*
+		 * If more operands needed, decrement Stack_ptr to point
+		 * to next operand on stack
+		 */
+		if (GET_CURRENT_ARG_TYPE (arg_types)) {
+			stack_ptr--;
+		}
+
+	}   /* while (*Types) */
+
+
+	return (status);
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exstore.c linux/drivers/acpi/executer/exstore.c
--- v2.4.5/linux/drivers/acpi/executer/exstore.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exstore.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,600 @@
+
+/******************************************************************************
+ *
+ * Module Name: exstore - AML Interpreter object store support
+ *              $Revision: 139 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "acdispat.h"
+#include "acinterp.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+#include "actables.h"
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exstore")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_store
+ *
+ * PARAMETERS:  *Val_desc           - Value to be stored
+ *              *Dest_desc          - Where to store it.  Must be an NS node
+ *                                    or an ACPI_OPERAND_OBJECT of type
+ *                                    Reference; if the latter the descriptor
+ *                                    will be either reused or deleted.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Store the value described by Val_desc into the location
+ *              described by Dest_desc. Called by various interpreter
+ *              functions to store the result of an operation into
+ *              the destination operand.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_store (
+	ACPI_OPERAND_OBJECT     *val_desc,
+	ACPI_OPERAND_OBJECT     *dest_desc,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_STATUS             status = AE_OK;
+	ACPI_OPERAND_OBJECT     *ref_desc = dest_desc;
+
+
+	/* Validate parameters */
+
+	if (!val_desc || !dest_desc) {
+		return (AE_AML_NO_OPERAND);
+	}
+
+	/* Dest_desc can be either a namespace node or an ACPI object */
+
+	if (VALID_DESCRIPTOR_TYPE (dest_desc, ACPI_DESC_TYPE_NAMED)) {
+		/*
+		 * Dest is a namespace node,
+		 * Storing an object into a Name "container"
+		 */
+		status = acpi_ex_store_object_to_node (val_desc,
+				 (ACPI_NAMESPACE_NODE *) dest_desc, walk_state);
+
+		/* All done, that's it */
+
+		return (status);
+	}
+
+
+	/* Destination object must be an object of type Reference */
+
+	if (dest_desc->common.type != INTERNAL_TYPE_REFERENCE) {
+		/* Destination is not an Reference */
+
+		return (AE_AML_OPERAND_TYPE);
+	}
+
+
+	/*
+	 * Examine the Reference opcode.  These cases are handled:
+	 *
+	 * 1) Store to Name (Change the object associated with a name)
+	 * 2) Store to an indexed area of a Buffer or Package
+	 * 3) Store to a Method Local or Arg
+	 * 4) Store to the debug object
+	 * 5) Store to a constant -- a noop
+	 */
+
+	switch (ref_desc->reference.opcode) {
+
+	case AML_NAME_OP:
+
+		/* Storing an object into a Name "container" */
+
+		status = acpi_ex_store_object_to_node (val_desc, ref_desc->reference.object,
+				  walk_state);
+		break;
+
+
+	case AML_INDEX_OP:
+
+		/* Storing to an Index (pointer into a packager or buffer) */
+
+		status = acpi_ex_store_object_to_index (val_desc, ref_desc, walk_state);
+		break;
+
+
+	case AML_LOCAL_OP:
+	case AML_ARG_OP:
+
+		/* Store to a method local/arg  */
+
+		status = acpi_ds_store_object_to_local (ref_desc->reference.opcode,
+				  ref_desc->reference.offset, val_desc, walk_state);
+		break;
+
+
+	case AML_DEBUG_OP:
+
+		/*
+		 * Storing to the Debug object causes the value stored to be
+		 * displayed and otherwise has no effect -- see ACPI Specification
+		 */
+		switch (val_desc->common.type) {
+		case ACPI_TYPE_INTEGER:
+
+			break;
+
+
+		case ACPI_TYPE_BUFFER:
+
+			break;
+
+
+		case ACPI_TYPE_STRING:
+
+			break;
+
+
+		case ACPI_TYPE_PACKAGE:
+
+			break;
+
+
+		default:
+
+			break;
+		}
+
+		break;
+
+
+	case AML_ZERO_OP:
+	case AML_ONE_OP:
+	case AML_ONES_OP:
+
+		/*
+		 * Storing to a constant is a no-op -- see ACPI Specification
+		 * Delete the reference descriptor, however
+		 */
+		break;
+
+
+	default:
+
+		/* TBD: [Restructure] use object dump routine !! */
+
+		status = AE_AML_INTERNAL;
+		break;
+
+	}   /* switch (Ref_desc->Reference.Opcode) */
+
+
+	/* Always delete the reference descriptor object */
+
+	if (ref_desc) {
+		acpi_ut_remove_reference (ref_desc);
+	}
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_store_object_to_index
+ *
+ * PARAMETERS:  *Val_desc           - Value to be stored
+ *              *Node               - Named object to receive the value
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Store the object to the named object.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_store_object_to_index (
+	ACPI_OPERAND_OBJECT     *val_desc,
+	ACPI_OPERAND_OBJECT     *dest_desc,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_STATUS             status = AE_OK;
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	u32                     length;
+	u32                     i;
+	u8                      value = 0;
+
+
+	/*
+	 * Destination must be a reference pointer, and
+	 * must point to either a buffer or a package
+	 */
+
+	switch (dest_desc->reference.target_type) {
+	case ACPI_TYPE_PACKAGE:
+		/*
+		 * Storing to a package element is not simple.  The source must be
+		 * evaluated and converted to the type of the destination and then the
+		 * source is copied into the destination - we can't just point to the
+		 * source object.
+		 */
+		if (dest_desc->reference.target_type == ACPI_TYPE_PACKAGE) {
+			/*
+			 * The object at *(Dest_desc->Reference.Where) is the
+			 *  element within the package that is to be modified.
+			 */
+			obj_desc = *(dest_desc->reference.where);
+			if (obj_desc) {
+				/*
+				 * If the Destination element is a package, we will delete
+				 *  that object and construct a new one.
+				 *
+				 * TBD: [Investigate] Should both the src and dest be required
+				 *      to be packages?
+				 *       && (Val_desc->Common.Type == ACPI_TYPE_PACKAGE)
+				 */
+				if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
+					/*
+					 * Take away the reference for being part of a package and
+					 * delete
+					 */
+					acpi_ut_remove_reference (obj_desc);
+					acpi_ut_remove_reference (obj_desc);
+
+					obj_desc = NULL;
+				}
+			}
+
+			if (!obj_desc) {
+				/*
+				 * If the Obj_desc is NULL, it means that an uninitialized package
+				 * element has been used as a destination (this is OK), therefore,
+				 * we must create the destination element to match the type of the
+				 * source element NOTE: Val_desc can be of any type.
+				 */
+				obj_desc = acpi_ut_create_internal_object (val_desc->common.type);
+				if (!obj_desc) {
+					return (AE_NO_MEMORY);
+				}
+
+				/*
+				 * If the source is a package, copy the source to the new dest
+				 */
+				if (ACPI_TYPE_PACKAGE == obj_desc->common.type) {
+					status = acpi_ut_copy_ipackage_to_ipackage (val_desc, obj_desc, walk_state);
+					if (ACPI_FAILURE (status)) {
+						acpi_ut_remove_reference (obj_desc);
+						return (status);
+					}
+				}
+
+				/*
+				 * Install the new descriptor into the package and add a
+				 * reference to the newly created descriptor for now being
+				 * part of the parent package
+				 */
+
+				*(dest_desc->reference.where) = obj_desc;
+				acpi_ut_add_reference (obj_desc);
+			}
+
+			if (ACPI_TYPE_PACKAGE != obj_desc->common.type) {
+				/*
+				 * The destination element is not a package, so we need to
+				 * convert the contents of the source (Val_desc) and copy into
+				 * the destination (Obj_desc)
+				 */
+				status = acpi_ex_store_object_to_object (val_desc, obj_desc,
+						  walk_state);
+				if (ACPI_FAILURE (status)) {
+					/*
+					 * An error occurrered when copying the internal object
+					 * so delete the reference.
+					 */
+					return (AE_AML_OPERAND_TYPE);
+				}
+			}
+		}
+		break;
+
+
+	case ACPI_TYPE_BUFFER_FIELD:
+
+
+		/* TBD: can probably call the generic Buffer/Field routines */
+
+		/*
+		 * Storing into a buffer at a location defined by an Index.
+		 *
+		 * Each 8-bit element of the source object is written to the
+		 * 8-bit Buffer Field of the Index destination object.
+		 */
+
+		/*
+		 * Set the Obj_desc to the destination object and type check.
+		 */
+		obj_desc = dest_desc->reference.object;
+		if (obj_desc->common.type != ACPI_TYPE_BUFFER) {
+			return (AE_AML_OPERAND_TYPE);
+		}
+
+		/*
+		 * The assignment of the individual elements will be slightly
+		 * different for each source type.
+		 */
+
+		switch (val_desc->common.type) {
+		case ACPI_TYPE_INTEGER:
+			/*
+			 * Type is Integer, assign bytewise
+			 * This loop to assign each of the elements is somewhat
+			 * backward because of the Big Endian-ness of IA-64
+			 */
+			length = sizeof (ACPI_INTEGER);
+			for (i = length; i != 0; i--) {
+				value = (u8)(val_desc->integer.value >> (MUL_8 (i - 1)));
+				obj_desc->buffer.pointer[dest_desc->reference.offset] = value;
+			}
+			break;
+
+
+		case ACPI_TYPE_BUFFER:
+			/*
+			 * Type is Buffer, the Length is in the structure.
+			 * Just loop through the elements and assign each one in turn.
+			 */
+			length = val_desc->buffer.length;
+			for (i = 0; i < length; i++) {
+				value = *(val_desc->buffer.pointer + i);
+				obj_desc->buffer.pointer[dest_desc->reference.offset] = value;
+			}
+			break;
+
+
+		case ACPI_TYPE_STRING:
+			/*
+			 * Type is String, the Length is in the structure.
+			 * Just loop through the elements and assign each one in turn.
+			 */
+			length = val_desc->string.length;
+			for (i = 0; i < length; i++) {
+				value = *(val_desc->string.pointer + i);
+				obj_desc->buffer.pointer[dest_desc->reference.offset] = value;
+			}
+			break;
+
+
+		default:
+
+			/* Other types are invalid */
+
+			status = AE_AML_OPERAND_TYPE;
+			break;
+		}
+		break;
+
+
+	default:
+		status = AE_AML_OPERAND_TYPE;
+		break;
+	}
+
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_store_object_to_node
+ *
+ * PARAMETERS:  *Source_desc           - Value to be stored
+ *              *Node                  - Named object to receive the value
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Store the object to the named object.
+ *
+ *              The Assignment of an object to a named object is handled here
+ *              The val passed in will replace the current value (if any)
+ *              with the input value.
+ *
+ *              When storing into an object the data is converted to the
+ *              target object type then stored in the object.  This means
+ *              that the target object type (for an initialized target) will
+ *              not be changed by a store operation.
+ *
+ *              NOTE: the global lock is acquired early.  This will result
+ *              in the global lock being held a bit longer.  Also, if the
+ *              function fails during set up we may get the lock when we
+ *              don't really need it.  I don't think we care.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_store_object_to_node (
+	ACPI_OPERAND_OBJECT     *source_desc,
+	ACPI_NAMESPACE_NODE     *node,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_STATUS             status = AE_OK;
+	ACPI_OPERAND_OBJECT     *target_desc;
+	ACPI_OBJECT_TYPE8       target_type = ACPI_TYPE_ANY;
+
+
+	/*
+	 * Assuming the parameters were already validated
+	 */
+	ACPI_ASSERT((node) && (source_desc));
+
+
+	/*
+	 * Get current type of the node, and object attached to Node
+	 */
+	target_type = acpi_ns_get_type (node);
+	target_desc = acpi_ns_get_attached_object (node);
+
+
+	/*
+	 * Resolve the source object to an actual value
+	 * (If it is a reference object)
+	 */
+	status = acpi_ex_resolve_object (&source_desc, target_type, walk_state);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+
+	/*
+	 * Do the actual store operation
+	 */
+	switch (target_type) {
+	case ACPI_TYPE_BUFFER_FIELD:
+	case INTERNAL_TYPE_REGION_FIELD:
+	case INTERNAL_TYPE_BANK_FIELD:
+	case INTERNAL_TYPE_INDEX_FIELD:
+
+		/*
+		 * For fields, copy the source data to the target field.
+		 */
+		status = acpi_ex_write_data_to_field (source_desc, target_desc);
+		break;
+
+
+	case ACPI_TYPE_INTEGER:
+	case ACPI_TYPE_STRING:
+	case ACPI_TYPE_BUFFER:
+
+		/*
+		 * These target types are all of type Integer/String/Buffer, and
+		 * therefore support implicit conversion before the store.
+		 *
+		 * Copy and/or convert the source object to a new target object
+		 */
+		status = acpi_ex_store_object (source_desc, target_type, &target_desc, walk_state);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+
+		/*
+		 * Store the new Target_desc as the new value of the Name, and set
+		 * the Name's type to that of the value being stored in it.
+		 * Source_desc reference count is incremented by Attach_object.
+		 */
+		status = acpi_ns_attach_object (node, target_desc, target_type);
+		break;
+
+
+	default:
+
+		/* No conversions for all other types.  Just attach the source object */
+
+		status = acpi_ns_attach_object (node, source_desc, source_desc->common.type);
+
+		break;
+	}
+
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_store_object_to_object
+ *
+ * PARAMETERS:  *Source_desc           - Value to be stored
+ *              *Dest_desc          - Object to receive the value
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Store an object to another object.
+ *
+ *              The Assignment of an object to another (not named) object
+ *              is handled here.
+ *              The val passed in will replace the current value (if any)
+ *              with the input value.
+ *
+ *              When storing into an object the data is converted to the
+ *              target object type then stored in the object.  This means
+ *              that the target object type (for an initialized target) will
+ *              not be changed by a store operation.
+ *
+ *              This module allows destination types of Number, String,
+ *              and Buffer.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_store_object_to_object (
+	ACPI_OPERAND_OBJECT     *source_desc,
+	ACPI_OPERAND_OBJECT     *dest_desc,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_STATUS             status = AE_OK;
+	ACPI_OBJECT_TYPE8       destination_type = dest_desc->common.type;
+
+
+	/*
+	 *  Assuming the parameters are valid!
+	 */
+	ACPI_ASSERT((dest_desc) && (source_desc));
+
+
+	/*
+	 * From this interface, we only support Integers/Strings/Buffers
+	 */
+	switch (destination_type) {
+	case ACPI_TYPE_INTEGER:
+	case ACPI_TYPE_STRING:
+	case ACPI_TYPE_BUFFER:
+		break;
+
+	default:
+		return (AE_NOT_IMPLEMENTED);
+	}
+
+
+	/*
+	 * Resolve the source object to an actual value
+	 * (If it is a reference object)
+	 */
+	status = acpi_ex_resolve_object (&source_desc, destination_type, walk_state);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+
+	/*
+	 * Copy and/or convert the source object to the destination object
+	 */
+	status = acpi_ex_store_object (source_desc, destination_type, &dest_desc, walk_state);
+
+
+	return (status);
+}
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exstoren.c linux/drivers/acpi/executer/exstoren.c
--- v2.4.5/linux/drivers/acpi/executer/exstoren.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exstoren.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,241 @@
+
+/******************************************************************************
+ *
+ * Module Name: exstoren - AML Interpreter object store support,
+ *                        Store to Node (namespace object)
+ *              $Revision: 38 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "acdispat.h"
+#include "acinterp.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+#include "actables.h"
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exstoren")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_resolve_object
+ *
+ * PARAMETERS:  Source_desc_ptr     - Pointer to the source object
+ *              Target_type         - Current type of the target
+ *              Walk_state          - Current walk state
+ *
+ * RETURN:      Status, resolved object in Source_desc_ptr.
+ *
+ * DESCRIPTION: Resolve an object.  If the object is a reference, dereference
+ *              it and return the actual object in the Source_desc_ptr.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_resolve_object (
+	ACPI_OPERAND_OBJECT     **source_desc_ptr,
+	ACPI_OBJECT_TYPE8       target_type,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_OPERAND_OBJECT     *source_desc = *source_desc_ptr;
+	ACPI_STATUS             status = AE_OK;
+
+
+	/*
+	 * Ensure we have a Source that can be stored in the target
+	 */
+	switch (target_type) {
+
+	/* This case handles the "interchangeable" types Integer, String, and Buffer. */
+
+	/*
+	 * These cases all require only Integers or values that
+	 * can be converted to Integers (Strings or Buffers)
+	 */
+	case ACPI_TYPE_BUFFER_FIELD:
+	case INTERNAL_TYPE_REGION_FIELD:
+	case INTERNAL_TYPE_BANK_FIELD:
+	case INTERNAL_TYPE_INDEX_FIELD:
+
+	/*
+	 * Stores into a Field/Region or into a Buffer/String
+	 * are all essentially the same.
+	 */
+	case ACPI_TYPE_INTEGER:
+	case ACPI_TYPE_STRING:
+	case ACPI_TYPE_BUFFER:
+
+
+		/* TBD: FIX - check for source==REF, resolve, then check type */
+
+		/*
+		 * If Source_desc is not a valid type, try to resolve it to one.
+		 */
+		if ((source_desc->common.type != ACPI_TYPE_INTEGER)    &&
+			(source_desc->common.type != ACPI_TYPE_BUFFER)     &&
+			(source_desc->common.type != ACPI_TYPE_STRING)) {
+			/*
+			 * Initially not a valid type, convert
+			 */
+			status = acpi_ex_resolve_to_value (source_desc_ptr, walk_state);
+			if (ACPI_SUCCESS (status) &&
+				(source_desc->common.type != ACPI_TYPE_INTEGER)    &&
+				(source_desc->common.type != ACPI_TYPE_BUFFER)     &&
+				(source_desc->common.type != ACPI_TYPE_STRING)) {
+				/*
+				 * Conversion successful but still not a valid type
+				 */
+				status = AE_AML_OPERAND_TYPE;
+			}
+		}
+		break;
+
+
+	case INTERNAL_TYPE_ALIAS:
+
+		/*
+		 * Aliases are resolved by Acpi_ex_prep_operands
+		 */
+		status = AE_AML_INTERNAL;
+		break;
+
+
+	case ACPI_TYPE_PACKAGE:
+	default:
+
+		/*
+		 * All other types than Alias and the various Fields come here,
+		 * including the untyped case - ACPI_TYPE_ANY.
+		 */
+		break;
+	}
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_store_object
+ *
+ * PARAMETERS:  Source_desc         - Object to store
+ *              Target_type         - Current type of the target
+ *              Target_desc_ptr     - Pointer to the target
+ *              Walk_state          - Current walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: "Store" an object to another object.  This may include
+ *              converting the source type to the target type (implicit
+ *              conversion), and a copy of the value of the source to
+ *              the target.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_store_object (
+	ACPI_OPERAND_OBJECT     *source_desc,
+	ACPI_OBJECT_TYPE8       target_type,
+	ACPI_OPERAND_OBJECT     **target_desc_ptr,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_OPERAND_OBJECT     *target_desc = *target_desc_ptr;
+	ACPI_STATUS             status = AE_OK;
+
+
+	/*
+	 * Perform the "implicit conversion" of the source to the current type
+	 * of the target - As per the ACPI specification.
+	 *
+	 * If no conversion performed, Source_desc is left alone, otherwise it
+	 * is updated with a new object.
+	 */
+	status = acpi_ex_convert_to_target_type (target_type, &source_desc, walk_state);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/*
+	 * We now have two objects of identical types, and we can perform a
+	 * copy of the *value* of the source object.
+	 */
+	switch (target_type) {
+	case ACPI_TYPE_ANY:
+	case INTERNAL_TYPE_DEF_ANY:
+
+		/*
+		 * The target namespace node is uninitialized (has no target object),
+		 * and will take on the type of the source object
+		 */
+
+		*target_desc_ptr = source_desc;
+		break;
+
+
+	case ACPI_TYPE_INTEGER:
+
+		target_desc->integer.value = source_desc->integer.value;
+
+		/* Truncate value if we are executing from a 32-bit ACPI table */
+
+		acpi_ex_truncate_for32bit_table (target_desc, walk_state);
+		break;
+
+	case ACPI_TYPE_STRING:
+
+		status = acpi_ex_copy_string_to_string (source_desc, target_desc);
+		break;
+
+
+	case ACPI_TYPE_BUFFER:
+
+		status = acpi_ex_copy_buffer_to_buffer (source_desc, target_desc);
+		break;
+
+
+	case ACPI_TYPE_PACKAGE:
+
+		/*
+		 * TBD: [Unhandled] Not real sure what to do here
+		 */
+		status = AE_NOT_IMPLEMENTED;
+		break;
+
+
+	default:
+
+		/*
+		 * All other types come here.
+		 */
+		status = AE_NOT_IMPLEMENTED;
+		break;
+	}
+
+
+	return (status);
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exstorob.c linux/drivers/acpi/executer/exstorob.c
--- v2.4.5/linux/drivers/acpi/executer/exstorob.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exstorob.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,169 @@
+
+/******************************************************************************
+ *
+ * Module Name: exstorob - AML Interpreter object store support, store to object
+ *              $Revision: 32 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "acdispat.h"
+#include "acinterp.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+#include "actables.h"
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exstorob")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_copy_buffer_to_buffer
+ *
+ * PARAMETERS:  Source_desc         - Source object to copy
+ *              Target_desc         - Destination object of the copy
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Copy a buffer object to another buffer object.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_copy_buffer_to_buffer (
+	ACPI_OPERAND_OBJECT     *source_desc,
+	ACPI_OPERAND_OBJECT     *target_desc)
+{
+	u32                     length;
+	u8                      *buffer;
+
+
+	/*
+	 * We know that Source_desc is a buffer by now
+	 */
+	buffer = (u8 *) source_desc->buffer.pointer;
+	length = source_desc->buffer.length;
+
+	/*
+	 * If target is a buffer of length zero, allocate a new
+	 * buffer of the proper length
+	 */
+	if (target_desc->buffer.length == 0) {
+		target_desc->buffer.pointer = acpi_ut_allocate (length);
+		if (!target_desc->buffer.pointer) {
+			return (AE_NO_MEMORY);
+		}
+
+		target_desc->buffer.length = length;
+	}
+
+	/*
+	 * Buffer is a static allocation,
+	 * only place what will fit in the buffer.
+	 */
+	if (length <= target_desc->buffer.length) {
+		/* Clear existing buffer and copy in the new one */
+
+		MEMSET(target_desc->buffer.pointer, 0, target_desc->buffer.length);
+		MEMCPY(target_desc->buffer.pointer, buffer, length);
+	}
+
+	else {
+		/*
+		 * Truncate the source, copy only what will fit
+		 */
+		MEMCPY(target_desc->buffer.pointer, buffer, target_desc->buffer.length);
+
+	}
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_copy_string_to_string
+ *
+ * PARAMETERS:  Source_desc         - Source object to copy
+ *              Target_desc         - Destination object of the copy
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Copy a String object to another String object
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_copy_string_to_string (
+	ACPI_OPERAND_OBJECT     *source_desc,
+	ACPI_OPERAND_OBJECT     *target_desc)
+{
+	u32                     length;
+	u8                      *buffer;
+
+
+	/*
+	 * We know that Source_desc is a string by now.
+	 */
+	buffer = (u8 *) source_desc->string.pointer;
+	length = source_desc->string.length;
+
+	/*
+	 * Setting a string value replaces the old string
+	 */
+	if (length < target_desc->string.length) {
+		/* Clear old string and copy in the new one */
+
+		MEMSET(target_desc->string.pointer, 0, target_desc->string.length);
+		MEMCPY(target_desc->string.pointer, buffer, length);
+	}
+
+	else {
+		/*
+		 * Free the current buffer, then allocate a buffer
+		 * large enough to hold the value
+		 */
+		if (target_desc->string.pointer &&
+			!acpi_tb_system_table_pointer (target_desc->string.pointer)) {
+			/*
+			 * Only free if not a pointer into the DSDT
+			 */
+			acpi_ut_free(target_desc->string.pointer);
+		}
+
+		target_desc->string.pointer = acpi_ut_allocate (length + 1);
+		if (!target_desc->string.pointer) {
+			return (AE_NO_MEMORY);
+		}
+		target_desc->string.length = length;
+
+
+		MEMCPY(target_desc->string.pointer, buffer, length);
+	}
+
+	return (AE_OK);
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exsystem.c linux/drivers/acpi/executer/exsystem.c
--- v2.4.5/linux/drivers/acpi/executer/exsystem.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exsystem.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,326 @@
+
+/******************************************************************************
+ *
+ * Module Name: exsystem - Interface to OS services
+ *              $Revision: 62 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acinterp.h"
+#include "acnamesp.h"
+#include "achware.h"
+#include "acevents.h"
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exsystem")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_system_wait_semaphore
+ *
+ * PARAMETERS:  Semaphore           - OSD semaphore to wait on
+ *              Timeout             - Max time to wait
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Implements a semaphore wait with a check to see if the
+ *              semaphore is available immediately.  If it is not, the
+ *              interpreter is released.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_system_wait_semaphore (
+	ACPI_HANDLE             semaphore,
+	u32                     timeout)
+{
+	ACPI_STATUS             status;
+
+
+	status = acpi_os_wait_semaphore (semaphore, 1, 0);
+	if (ACPI_SUCCESS (status)) {
+		return (status);
+	}
+
+	if (status == AE_TIME) {
+		/* We must wait, so unlock the interpreter */
+
+		acpi_ex_exit_interpreter ();
+
+		status = acpi_os_wait_semaphore (semaphore, 1, timeout);
+
+		/* Reacquire the interpreter */
+
+		status = acpi_ex_enter_interpreter ();
+		if (ACPI_SUCCESS (status)) {
+			/* Restore the timeout exception */
+
+			status = AE_TIME;
+		}
+	}
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_system_do_stall
+ *
+ * PARAMETERS:  How_long            - The amount of time to stall
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Suspend running thread for specified amount of time.
+ *
+ ******************************************************************************/
+
+void
+acpi_ex_system_do_stall (
+	u32                     how_long)
+{
+
+	if (how_long > 1000) /* 1 millisecond */ {
+		/* Since this thread will sleep, we must release the interpreter */
+
+		acpi_ex_exit_interpreter ();
+
+		acpi_os_sleep_usec (how_long);
+
+		/* And now we must get the interpreter again */
+
+		acpi_ex_enter_interpreter ();
+	}
+
+	else {
+		acpi_os_sleep_usec (how_long);
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_system_do_suspend
+ *
+ * PARAMETERS:  How_long            - The amount of time to suspend
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Suspend running thread for specified amount of time.
+ *
+ ******************************************************************************/
+
+void
+acpi_ex_system_do_suspend (
+	u32                     how_long)
+{
+	/* Since this thread will sleep, we must release the interpreter */
+
+	acpi_ex_exit_interpreter ();
+
+	acpi_os_sleep ((u16) (how_long / (u32) 1000),
+			  (u16) (how_long % (u32) 1000));
+
+	/* And now we must get the interpreter again */
+
+	acpi_ex_enter_interpreter ();
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_system_acquire_mutex
+ *
+ * PARAMETERS:  *Time_desc          - The 'time to delay' object descriptor
+ *              *Obj_desc           - The object descriptor for this op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Provides an access point to perform synchronization operations
+ *              within the AML.  This function will cause a lock to be generated
+ *              for the Mutex pointed to by Obj_desc.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_system_acquire_mutex (
+	ACPI_OPERAND_OBJECT     *time_desc,
+	ACPI_OPERAND_OBJECT     *obj_desc)
+{
+	ACPI_STATUS             status = AE_OK;
+
+
+	if (!obj_desc) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Support for the _GL_ Mutex object -- go get the global lock
+	 */
+
+	if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
+		status = acpi_ev_acquire_global_lock ();
+		return (status);
+	}
+
+	status = acpi_ex_system_wait_semaphore (obj_desc->mutex.semaphore,
+			  (u32) time_desc->integer.value);
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_system_release_mutex
+ *
+ * PARAMETERS:  *Obj_desc           - The object descriptor for this op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Provides an access point to perform synchronization operations
+ *              within the AML.  This operation is a request to release a
+ *              previously acquired Mutex.  If the Mutex variable is set then
+ *              it will be decremented.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_system_release_mutex (
+	ACPI_OPERAND_OBJECT     *obj_desc)
+{
+	ACPI_STATUS             status = AE_OK;
+
+
+	if (!obj_desc) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Support for the _GL_ Mutex object -- release the global lock
+	 */
+	if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
+		acpi_ev_release_global_lock ();
+		return (AE_OK);
+	}
+
+	status = acpi_os_signal_semaphore (obj_desc->mutex.semaphore, 1);
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_system_signal_event
+ *
+ * PARAMETERS:  *Obj_desc           - The object descriptor for this op
+ *
+ * RETURN:      AE_OK
+ *
+ * DESCRIPTION: Provides an access point to perform synchronization operations
+ *              within the AML.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_system_signal_event (
+	ACPI_OPERAND_OBJECT     *obj_desc)
+{
+	ACPI_STATUS             status = AE_OK;
+
+
+	if (obj_desc) {
+		status = acpi_os_signal_semaphore (obj_desc->event.semaphore, 1);
+	}
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_system_wait_event
+ *
+ * PARAMETERS:  *Time_desc          - The 'time to delay' object descriptor
+ *              *Obj_desc           - The object descriptor for this op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Provides an access point to perform synchronization operations
+ *              within the AML.  This operation is a request to wait for an
+ *              event.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_system_wait_event (
+	ACPI_OPERAND_OBJECT     *time_desc,
+	ACPI_OPERAND_OBJECT     *obj_desc)
+{
+	ACPI_STATUS             status = AE_OK;
+
+
+	if (obj_desc) {
+		status = acpi_ex_system_wait_semaphore (obj_desc->event.semaphore,
+				  (u32) time_desc->integer.value);
+	}
+
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_system_reset_event
+ *
+ * PARAMETERS:  *Obj_desc           - The object descriptor for this op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Reset an event to a known state.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_system_reset_event (
+	ACPI_OPERAND_OBJECT     *obj_desc)
+{
+	ACPI_STATUS             status = AE_OK;
+	void                    *temp_semaphore;
+
+
+	/*
+	 * We are going to simply delete the existing semaphore and
+	 * create a new one!
+	 */
+
+	status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore);
+	if (ACPI_SUCCESS (status)) {
+		acpi_os_delete_semaphore (obj_desc->event.semaphore);
+		obj_desc->event.semaphore = temp_semaphore;
+	}
+
+	return (status);
+}
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exutils.c linux/drivers/acpi/executer/exutils.c
--- v2.4.5/linux/drivers/acpi/executer/exutils.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exutils.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,366 @@
+
+/******************************************************************************
+ *
+ * Module Name: exutils - interpreter/scanner utilities
+ *              $Revision: 79 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "acinterp.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+#include "acevents.h"
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exutils")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_enter_interpreter
+ *
+ * PARAMETERS:  None
+ *
+ * DESCRIPTION: Enter the interpreter execution region
+ *              TBD: should be a macro
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_enter_interpreter (void)
+{
+	ACPI_STATUS             status;
+
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_EXECUTE);
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_exit_interpreter
+ *
+ * PARAMETERS:  None
+ *
+ * DESCRIPTION: Exit the interpreter execution region
+ *
+ * Cases where the interpreter is unlocked:
+ *      1) Completion of the execution of a control method
+ *      2) Method blocked on a Sleep() AML opcode
+ *      3) Method blocked on an Acquire() AML opcode
+ *      4) Method blocked on a Wait() AML opcode
+ *      5) Method blocked to acquire the global lock
+ *      6) Method blocked to execute a serialized control method that is
+ *          already executing
+ *      7) About to invoke a user-installed opregion handler
+ *
+ *              TBD: should be a macro
+ *
+ ******************************************************************************/
+
+void
+acpi_ex_exit_interpreter (void)
+{
+
+	acpi_ut_release_mutex (ACPI_MTX_EXECUTE);
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_validate_object_type
+ *
+ * PARAMETERS:  Type            Object type to validate
+ *
+ * DESCRIPTION: Determine if a type is a valid ACPI object type
+ *
+ ******************************************************************************/
+
+u8
+acpi_ex_validate_object_type (
+	ACPI_OBJECT_TYPE        type)
+{
+
+	if ((type > ACPI_TYPE_MAX && type < INTERNAL_TYPE_BEGIN) ||
+		(type > INTERNAL_TYPE_MAX)) {
+		return (FALSE);
+	}
+
+	return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_truncate_for32bit_table
+ *
+ * PARAMETERS:  Obj_desc        - Object to be truncated
+ *              Walk_state      - Current walk state
+ *                                (A method must be executing)
+ *
+ * RETURN:      none
+ *
+ * DESCRIPTION: Truncate a number to 32-bits if the currently executing method
+ *              belongs to a 32-bit ACPI table.
+ *
+ ******************************************************************************/
+
+void
+acpi_ex_truncate_for32bit_table (
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	ACPI_WALK_STATE         *walk_state)
+{
+
+	/*
+	 * Object must be a valid number and we must be executing
+	 * a control method
+	 */
+
+	if ((!obj_desc) ||
+		(obj_desc->common.type != ACPI_TYPE_INTEGER) ||
+		(!walk_state->method_node)) {
+		return;
+	}
+
+	if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) {
+		/*
+		 * We are running a method that exists in a 32-bit ACPI table.
+		 * Truncate the value to 32 bits by zeroing out the upper 32-bit field
+		 */
+		obj_desc->integer.value &= (ACPI_INTEGER) ACPI_UINT32_MAX;
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_acquire_global_lock
+ *
+ * PARAMETERS:  Rule            - Lock rule: Always_lock, Never_lock
+ *
+ * RETURN:      TRUE/FALSE indicating whether the lock was actually acquired
+ *
+ * DESCRIPTION: Obtain the global lock and keep track of this fact via two
+ *              methods.  A global variable keeps the state of the lock, and
+ *              the state is returned to the caller.
+ *
+ ******************************************************************************/
+
+u8
+acpi_ex_acquire_global_lock (
+	u32                     rule)
+{
+	u8                      locked = FALSE;
+	ACPI_STATUS             status;
+
+
+	/* Only attempt lock if the Rule says so */
+
+	if (rule == (u32) GLOCK_ALWAYS_LOCK) {
+		/* We should attempt to get the lock */
+
+		status = acpi_ev_acquire_global_lock ();
+		if (ACPI_SUCCESS (status)) {
+			locked = TRUE;
+		}
+
+	}
+
+	return (locked);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_release_global_lock
+ *
+ * PARAMETERS:  Locked_by_me    - Return value from corresponding call to
+ *                                Acquire_global_lock.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Release the global lock if it is locked.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_release_global_lock (
+	u8                      locked_by_me)
+{
+
+
+	/* Only attempt unlock if the caller locked it */
+
+	if (locked_by_me) {
+		/* OK, now release the lock */
+
+		acpi_ev_release_global_lock ();
+	}
+
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_digits_needed
+ *
+ * PARAMETERS:  val             - Value to be represented
+ *              base            - Base of representation
+ *
+ * RETURN:      the number of digits needed to represent val in base
+ *
+ ******************************************************************************/
+
+u32
+acpi_ex_digits_needed (
+	ACPI_INTEGER            val,
+	u32                     base)
+{
+	u32                     num_digits = 0;
+
+
+	if (base < 1) {
+		REPORT_ERROR (("Ex_digits_needed: Internal error - Invalid base\n"));
+	}
+
+	else {
+		/*
+		 * ACPI_INTEGER is unsigned, which is why we don't worry about the '-'
+		 */
+		for (num_digits = 1; (val = ACPI_DIVIDE (val,base)); ++num_digits) { ; }
+	}
+
+	return (num_digits);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    ntohl
+ *
+ * PARAMETERS:  Value           - Value to be converted
+ *
+ * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
+ *
+ ******************************************************************************/
+
+static u32
+_ntohl (
+	u32                     value)
+{
+	union {
+		u32                 value;
+		u8                  bytes[4];
+	} out;
+
+	union {
+		u32                 value;
+		u8                  bytes[4];
+	} in;
+
+
+	in.value = value;
+
+	out.bytes[0] = in.bytes[3];
+	out.bytes[1] = in.bytes[2];
+	out.bytes[2] = in.bytes[1];
+	out.bytes[3] = in.bytes[0];
+
+	return (out.value);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_eisa_id_to_string
+ *
+ * PARAMETERS:  Numeric_id      - EISA ID to be converted
+ *              Out_string      - Where to put the converted string (8 bytes)
+ *
+ * DESCRIPTION: Convert a numeric EISA ID to string representation
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_eisa_id_to_string (
+	u32                     numeric_id,
+	NATIVE_CHAR             *out_string)
+{
+	u32                     id;
+
+	/* swap to big-endian to get contiguous bits */
+
+	id = _ntohl (numeric_id);
+
+	out_string[0] = (char) ('@' + ((id >> 26) & 0x1f));
+	out_string[1] = (char) ('@' + ((id >> 21) & 0x1f));
+	out_string[2] = (char) ('@' + ((id >> 16) & 0x1f));
+	out_string[3] = acpi_gbl_hex_to_ascii[(id >> 12) & 0xf];
+	out_string[4] = acpi_gbl_hex_to_ascii[(id >> 8) & 0xf];
+	out_string[5] = acpi_gbl_hex_to_ascii[(id >> 4) & 0xf];
+	out_string[6] = acpi_gbl_hex_to_ascii[id & 0xf];
+	out_string[7] = 0;
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_unsigned_integer_to_string
+ *
+ * PARAMETERS:  Value           - Value to be converted
+ *              Out_string      - Where to put the converted string (8 bytes)
+ *
+ * RETURN:      Convert a number to string representation
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_unsigned_integer_to_string (
+	ACPI_INTEGER            value,
+	NATIVE_CHAR             *out_string)
+{
+	u32                     count;
+	u32                     digits_needed;
+
+
+	digits_needed = acpi_ex_digits_needed (value, 10);
+
+	out_string[digits_needed] = '\0';
+
+	for (count = digits_needed; count > 0; count--) {
+		out_string[count-1] = (NATIVE_CHAR) ('0' + (ACPI_MODULO (value, 10)));
+		value = ACPI_DIVIDE (value, 10);
+	}
+
+	return (AE_OK);
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/executer/exxface.c linux/drivers/acpi/executer/exxface.c
--- v2.4.5/linux/drivers/acpi/executer/exxface.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/executer/exxface.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,98 @@
+
+/******************************************************************************
+ *
+ * Module Name: exxface - External interpreter interfaces
+ *              $Revision: 27 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acinterp.h"
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 MODULE_NAME         ("exxface")
+
+
+/*
+ * DEFINE_AML_GLOBALS is tested in amlcode.h
+ * to determine whether certain global names should be "defined" or only
+ * "declared" in the current compilation.  This enhances maintainability
+ * by enabling a single header file to embody all knowledge of the names
+ * in question.
+ *
+ * Exactly one module of any executable should #define DEFINE_GLOBALS
+ * before #including the header files which use this convention.  The
+ * names in question will be defined and initialized in that module,
+ * and declared as extern in all other modules which #include those
+ * header files.
+ */
+
+#define DEFINE_AML_GLOBALS
+#include "amlcode.h"
+#include "acparser.h"
+#include "acnamesp.h"
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ex_execute_method
+ *
+ * PARAMETERS:  Pcode               - Pointer to the pcode stream
+ *              Pcode_length        - Length of pcode that comprises the method
+ *              **Params            - List of parameters to pass to method,
+ *                                    terminated by NULL. Params itself may be
+ *                                    NULL if no parameters are being passed.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute a control method
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ex_execute_method (
+	ACPI_NAMESPACE_NODE     *method_node,
+	ACPI_OPERAND_OBJECT     **params,
+	ACPI_OPERAND_OBJECT     **return_obj_desc)
+{
+	ACPI_STATUS             status;
+
+
+	/*
+	 * The point here is to lock the interpreter and call the low
+	 * level execute.
+	 */
+
+	status = acpi_ex_enter_interpreter ();
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	status = acpi_psx_execute (method_node, params, return_obj_desc);
+
+	acpi_ex_exit_interpreter ();
+
+	return (status);
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/hardware/Makefile linux/drivers/acpi/hardware/Makefile
--- v2.4.5/linux/drivers/acpi/hardware/Makefile	Fri Dec 29 14:07:21 2000
+++ linux/drivers/acpi/hardware/Makefile	Wed Jun 20 17:47:40 2001
@@ -1,16 +1,12 @@
 #
 # Makefile for all Linux ACPI interpreter subdirectories
+# EXCEPT for the ospm directory
 #
 
-O_TARGET := ../$(shell basename `pwd`).o
+O_TARGET := $(notdir $(CURDIR)).o
 
 obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c))
 
-EXTRA_CFLAGS += -I../include
-
 EXTRA_CFLAGS += $(ACPI_CFLAGS)
 
 include $(TOPDIR)/Rules.make
-
-clean:
-	$(RM) *.o 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/hardware/hwacpi.c linux/drivers/acpi/hardware/hwacpi.c
--- v2.4.5/linux/drivers/acpi/hardware/hwacpi.c	Mon Jan 29 10:15:58 2001
+++ linux/drivers/acpi/hardware/hwacpi.c	Wed Jun 20 17:47:40 2001
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Module Name: hwacpi - ACPI Hardware Initialization/Mode Interface
- *              $Revision: 36 $
+ *              $Revision: 40 $
  *
  *****************************************************************************/
 
@@ -29,7 +29,7 @@
 #include "achware.h"
 
 
-#define _COMPONENT          HARDWARE
+#define _COMPONENT          ACPI_HARDWARE
 	 MODULE_NAME         ("hwacpi")
 
 
@@ -63,7 +63,8 @@
 
 	/* Must support *some* mode! */
 /*
-	if (!(System_flags & SYS_MODES_MASK)) {
+	if (!(System_flags & SYS_MODES_MASK))
+	{
 		Restore_acpi_chipset = FALSE;
 
 		return (AE_ERROR);
@@ -72,8 +73,7 @@
 */
 
 
-	switch (acpi_gbl_system_flags & SYS_MODES_MASK)
-	{
+	switch (acpi_gbl_system_flags & SYS_MODES_MASK) {
 		/* Identify current ACPI/legacy mode   */
 
 	case (SYS_MODE_ACPI):
@@ -128,12 +128,11 @@
 		 */
 
 		if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) &&
-			acpi_gbl_FADT->gpe0blk_len)
-		{
+			acpi_gbl_FADT->gpe0blk_len) {
 			/* GPE0 specified in FADT  */
 
 			acpi_gbl_gpe0enable_register_save =
-				acpi_cm_allocate (DIV_2 (acpi_gbl_FADT->gpe0blk_len));
+				acpi_ut_allocate (DIV_2 (acpi_gbl_FADT->gpe0blk_len));
 			if (!acpi_gbl_gpe0enable_register_save) {
 				return (AE_NO_MEMORY);
 			}
@@ -151,12 +150,11 @@
 		}
 
 		if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) &&
-			acpi_gbl_FADT->gpe1_blk_len)
-		{
+			acpi_gbl_FADT->gpe1_blk_len) {
 			/* GPE1 defined */
 
 			acpi_gbl_gpe1_enable_register_save =
-				acpi_cm_allocate (DIV_2 (acpi_gbl_FADT->gpe1_blk_len));
+				acpi_ut_allocate (DIV_2 (acpi_gbl_FADT->gpe1_blk_len));
 			if (!acpi_gbl_gpe1_enable_register_save) {
 				return (AE_NO_MEMORY);
 			}
@@ -196,7 +194,7 @@
 	u32                     mode)
 {
 
-	ACPI_STATUS             status = AE_ERROR;
+	ACPI_STATUS             status = AE_NO_HARDWARE_RESPONSE;
 
 
 	if (mode == SYS_MODE_ACPI) {
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/hardware/hwgpe.c linux/drivers/acpi/hardware/hwgpe.c
--- v2.4.5/linux/drivers/acpi/hardware/hwgpe.c	Mon Jan 29 10:15:58 2001
+++ linux/drivers/acpi/hardware/hwgpe.c	Wed Jun 20 17:47:40 2001
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Module Name: hwgpe - Low level GPE enable/disable/clear functions
- *              $Revision: 28 $
+ *              $Revision: 29 $
  *
  *****************************************************************************/
 
@@ -29,7 +29,7 @@
 #include "acnamesp.h"
 #include "acevents.h"
 
-#define _COMPONENT          HARDWARE
+#define _COMPONENT          ACPI_HARDWARE
 	 MODULE_NAME         ("hwgpe")
 
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/hardware/hwregs.c linux/drivers/acpi/hardware/hwregs.c
--- v2.4.5/linux/drivers/acpi/hardware/hwregs.c	Mon Jan 29 10:15:58 2001
+++ linux/drivers/acpi/hardware/hwregs.c	Wed Jun 20 17:47:40 2001
@@ -3,7 +3,7 @@
  *
  * Module Name: hwregs - Read/write access functions for the various ACPI
  *                       control and status registers.
- *              $Revision: 88 $
+ *              $Revision: 97 $
  *
  ******************************************************************************/
 
@@ -30,7 +30,7 @@
 #include "achware.h"
 #include "acnamesp.h"
 
-#define _COMPONENT          HARDWARE
+#define _COMPONENT          ACPI_HARDWARE
 	 MODULE_NAME         ("hwregs")
 
 
@@ -55,8 +55,7 @@
 
 u32
 acpi_hw_get_bit_shift (
-	u32                     mask)
-{
+	u32                     mask) {
 	u32                     shift;
 
 
@@ -85,14 +84,14 @@
 	u16                     index;
 
 
-	acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE);
+	acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE);
 
 	acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, PM1_STS, ALL_FIXED_STS_BITS);
 
 
 	if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm1b_evt_blk.address)) {
 		acpi_os_out16 ((ACPI_IO_ADDRESS) ACPI_GET_ADDRESS (acpi_gbl_FADT->Xpm1b_evt_blk.address),
-				  (u16) ALL_FIXED_STS_BITS);
+			(u16) ALL_FIXED_STS_BITS);
 	}
 
 	/* now clear the GPE Bits */
@@ -101,8 +100,9 @@
 		gpe_length = (u16) DIV_2 (acpi_gbl_FADT->gpe0blk_len);
 
 		for (index = 0; index < gpe_length; index++) {
-			acpi_os_out8 ((ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) + index),
-					  (u8) 0xff);
+			acpi_os_out8 ((ACPI_IO_ADDRESS) (
+				ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) + index),
+				(u8) 0xff);
 		}
 	}
 
@@ -110,12 +110,13 @@
 		gpe_length = (u16) DIV_2 (acpi_gbl_FADT->gpe1_blk_len);
 
 		for (index = 0; index < gpe_length; index++) {
-			acpi_os_out8 ((ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) + index),
-					  (u8) 0xff);
+			acpi_os_out8 ((ACPI_IO_ADDRESS) (
+				ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) + index),
+				(u8) 0xff);
 		}
 	}
 
-	acpi_cm_release_mutex (ACPI_MTX_HARDWARE);
+	acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
 	return;
 }
 
@@ -150,8 +151,7 @@
 	 */
 
 	if ((sleep_state > ACPI_S_STATES_MAX) ||
-		!slp_typ_a || !slp_typ_b)
-	{
+		!slp_typ_a || !slp_typ_b) {
 		return (AE_BAD_PARAMETER);
 	}
 
@@ -175,7 +175,10 @@
 	 *  two elements
 	 */
 
-	status = acpi_cm_resolve_package_references(obj_desc);
+	/* Even though Acpi_evaluate_object resolves package references,
+	 * Ns_evaluate dpesn't. So, we do it here.
+	 */
+	status = acpi_ut_resolve_package_references(obj_desc);
 
 	if (obj_desc->package.count < 2) {
 		/* Must have at least two elements */
@@ -187,8 +190,7 @@
 	else if (((obj_desc->package.elements[0])->common.type !=
 			 ACPI_TYPE_INTEGER) ||
 			 ((obj_desc->package.elements[1])->common.type !=
-				ACPI_TYPE_INTEGER))
-	{
+				ACPI_TYPE_INTEGER)) {
 		/* Must have two  */
 
 		REPORT_ERROR (("Sleep State package elements are not both of type Number\n"));
@@ -206,7 +208,7 @@
 
 
 
-	acpi_cm_remove_reference (obj_desc);
+	acpi_ut_remove_reference (obj_desc);
 
 	return (status);
 }
@@ -239,34 +241,31 @@
 	u32                     register_value = 0;
 	u32                     mask = 0;
 	u32                     value = 0;
+	va_list                 marker;
 
 
 	if (read_write == ACPI_WRITE) {
-		va_list         marker;
-
 		va_start (marker, register_id);
 		value = va_arg (marker, u32);
 		va_end (marker);
 	}
 
 	if (ACPI_MTX_LOCK == use_lock) {
-		acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE);
+		acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE);
 	}
 
 	/*
 	 * Decode the Register ID
-	 *  Register id = Register block id | bit id
+	 * Register id = Register block id | bit id
 	 *
 	 * Check bit id to fine locate Register offset.
-	 *  check Mask to determine Register offset, and then read-write.
+	 * Check Mask to determine Register offset, and then read-write.
 	 */
 
-	switch (REGISTER_BLOCK_ID(register_id))
-	{
+	switch (REGISTER_BLOCK_ID (register_id)) {
 	case PM1_STS:
 
-		switch (register_id)
-		{
+		switch (register_id) {
 		case TMR_STS:
 			mask = TMR_STS_MASK;
 			break;
@@ -315,8 +314,8 @@
 			value &= mask;
 
 			if (value) {
-				acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, PM1_STS, (u16) value);
-
+				acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, PM1_STS,
+					(u16) value);
 				register_value = 0;
 			}
 		}
@@ -326,8 +325,7 @@
 
 	case PM1_EN:
 
-		switch (register_id)
-		{
+		switch (register_id) {
 		case TMR_EN:
 			mask = TMR_EN_MASK;
 			break;
@@ -369,8 +367,7 @@
 
 	case PM1_CONTROL:
 
-		switch (register_id)
-		{
+		switch (register_id) {
 		case SCI_EN:
 			mask = SCI_EN_MASK;
 			break;
@@ -421,16 +418,15 @@
 			 * because we need to do different things. Yuck.
 			 */
 
-			acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
-				register_id, (u16) register_value);
+			acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, register_id,
+					(u16) register_value);
 		}
 		break;
 
 
 	case PM2_CONTROL:
 
-		switch (register_id)
-		{
+		switch (register_id) {
 		case ARB_DIS:
 			mask = ARB_DIS_MASK;
 			break;
@@ -507,16 +503,18 @@
 			/* This write will put the Action state into the General Purpose */
 			/* Enable Register indexed by the value in Mask */
 
-			acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
-					   register_id, (u8) register_value);
-			register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, register_id);
+			acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, register_id,
+				(u8) register_value);
+			register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK,
+					   register_id);
 		}
 		break;
 
 
 	case SMI_CMD_BLOCK:
 	case PROCESSOR_BLOCK:
-		/* not used */
+		/* Not used by any callers at this time - therefore, not implemented */
+
 	default:
 
 		mask = 0;
@@ -524,7 +522,7 @@
 	}
 
 	if (ACPI_MTX_LOCK == use_lock) {
-		acpi_cm_release_mutex (ACPI_MTX_HARDWARE);
+		acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
 	}
 
 
@@ -557,13 +555,13 @@
 	u32                     value       = 0;
 	u32                     bank_offset;
 
+
 	if (ACPI_MTX_LOCK == use_lock) {
-		acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE);
+		acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE);
 	}
 
 
-	switch (REGISTER_BLOCK_ID(register_id))
-	{
+	switch (REGISTER_BLOCK_ID(register_id)) {
 	case PM1_STS: /* 16-bit access */
 
 		value =  acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_evt_blk, 0);
@@ -637,7 +635,7 @@
 
 
 	if (ACPI_MTX_LOCK == use_lock) {
-		acpi_cm_release_mutex (ACPI_MTX_HARDWARE);
+		acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
 	}
 
 	return (value);
@@ -668,12 +666,11 @@
 
 
 	if (ACPI_MTX_LOCK == use_lock) {
-		acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE);
+		acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE);
 	}
 
 
-	switch (REGISTER_BLOCK_ID (register_id))
-	{
+	switch (REGISTER_BLOCK_ID (register_id)) {
 	case PM1_STS: /* 16-bit access */
 
 		acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_evt_blk, 0);
@@ -751,7 +748,7 @@
 		/* For 2.0, SMI_CMD is always in IO space */
 		/* TBD: what about 1.0? 0.71? */
 
-	   acpi_os_out8 (acpi_gbl_FADT->smi_cmd, (u8) value);
+		acpi_os_out8 (acpi_gbl_FADT->smi_cmd, (u8) value);
 		break;
 
 
@@ -762,7 +759,7 @@
 
 
 	if (ACPI_MTX_LOCK == use_lock) {
-		acpi_cm_release_mutex (ACPI_MTX_HARDWARE);
+		acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
 	}
 
 	return;
@@ -786,7 +783,7 @@
 u32
 acpi_hw_low_level_read (
 	u32                     width,
-	ACPI_GAS                *reg,
+	ACPI_GENERIC_ADDRESS    *reg,
 	u32                     offset)
 {
 	u32                     value = 0;
@@ -801,8 +798,7 @@
 	 * a non-zero address within
 	 */
 	if ((!reg) ||
-		(!ACPI_VALID_ADDRESS (reg->address)))
-	{
+		(!ACPI_VALID_ADDRESS (reg->address))) {
 		return 0;
 	}
 
@@ -812,14 +808,12 @@
 	 * Memory, Io, or PCI config.
 	 */
 
-	switch (reg->address_space_id)
-	{
-	case ADDRESS_SPACE_SYSTEM_MEMORY:
+	switch (reg->address_space_id) {
+	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 
 		mem_address = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset);
 
-		switch (width)
-		{
+		switch (width) {
 		case 8:
 			value = acpi_os_mem_in8 (mem_address);
 			break;
@@ -833,12 +827,11 @@
 		break;
 
 
-	case ADDRESS_SPACE_SYSTEM_IO:
+	case ACPI_ADR_SPACE_SYSTEM_IO:
 
 		io_address = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset);
 
-		switch (width)
-		{
+		switch (width) {
 		case 8:
 			value = acpi_os_in8 (io_address);
 			break;
@@ -852,13 +845,12 @@
 		break;
 
 
-	case ADDRESS_SPACE_PCI_CONFIG:
+	case ACPI_ADR_SPACE_PCI_CONFIG:
 
 		pci_dev_func = ACPI_PCI_DEVFUN  (ACPI_GET_ADDRESS (reg->address));
 		pci_register = ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (reg->address)) + offset;
 
-		switch (width)
-		{
+		switch (width) {
 		case 8:
 			acpi_os_read_pci_cfg_byte (0, pci_dev_func, pci_register, (u8 *) &value);
 			break;
@@ -896,7 +888,7 @@
 acpi_hw_low_level_write (
 	u32                     width,
 	u32                     value,
-	ACPI_GAS                *reg,
+	ACPI_GENERIC_ADDRESS    *reg,
 	u32                     offset)
 {
 	ACPI_PHYSICAL_ADDRESS   mem_address;
@@ -910,8 +902,7 @@
 	 * a non-zero address within
 	 */
 	if ((!reg) ||
-		(!ACPI_VALID_ADDRESS (reg->address)))
-	{
+		(!ACPI_VALID_ADDRESS (reg->address))) {
 		return;
 	}
 
@@ -921,14 +912,12 @@
 	 * Memory, Io, or PCI config.
 	 */
 
-	switch (reg->address_space_id)
-	{
-	case ADDRESS_SPACE_SYSTEM_MEMORY:
+	switch (reg->address_space_id) {
+	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 
 		mem_address = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset);
 
-		switch (width)
-		{
+		switch (width) {
 		case 8:
 			acpi_os_mem_out8 (mem_address, (u8) value);
 			break;
@@ -942,12 +931,11 @@
 		break;
 
 
-	case ADDRESS_SPACE_SYSTEM_IO:
+	case ACPI_ADR_SPACE_SYSTEM_IO:
 
 		io_address = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset);
 
-		switch (width)
-		{
+		switch (width) {
 		case 8:
 			acpi_os_out8 (io_address, (u8) value);
 			break;
@@ -961,13 +949,12 @@
 		break;
 
 
-	case ADDRESS_SPACE_PCI_CONFIG:
+	case ACPI_ADR_SPACE_PCI_CONFIG:
 
 		pci_dev_func = ACPI_PCI_DEVFUN  (ACPI_GET_ADDRESS (reg->address));
 		pci_register = ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (reg->address)) + offset;
 
-		switch (width)
-		{
+		switch (width) {
 		case 8:
 			acpi_os_write_pci_cfg_byte (0, pci_dev_func, pci_register, (u8) value);
 			break;
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/hardware/hwsleep.c linux/drivers/acpi/hardware/hwsleep.c
--- v2.4.5/linux/drivers/acpi/hardware/hwsleep.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/hardware/hwsleep.c	Wed Jun 20 17:47:40 2001
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface
- *              $Revision: 7 $
+ *              $Revision: 12 $
  *
  *****************************************************************************/
 
@@ -28,7 +28,7 @@
 #include "acnamesp.h"
 #include "achware.h"
 
-#define _COMPONENT          HARDWARE
+#define _COMPONENT          ACPI_HARDWARE
 	 MODULE_NAME         ("hwsleep")
 
 
@@ -126,27 +126,28 @@
 
 ACPI_STATUS
 acpi_enter_sleep_state (
-	u8 sleep_state)
+	u8                  sleep_state)
 {
-	ACPI_STATUS status;
-	ACPI_OBJECT_LIST arg_list;
-	ACPI_OBJECT arg;
-	u8 type_a;
-	u8 type_b;
-	u16 PM1_acontrol;
-	u16 PM1_bcontrol;
+	ACPI_STATUS         status;
+	ACPI_OBJECT_LIST    arg_list;
+	ACPI_OBJECT         arg;
+	u8                  type_a;
+	u8                  type_b;
+	u16                 PM1_acontrol;
+	u16                 PM1_bcontrol;
+
 
 	/*
 	 * _PSW methods could be run here to enable wake-on keyboard, LAN, etc.
 	 */
 
-	status = acpi_hw_obtain_sleep_type_register_data(sleep_state, &type_a, &type_b);
-
-	if (!ACPI_SUCCESS(status)) {
+	status = acpi_hw_obtain_sleep_type_register_data (sleep_state, &type_a, &type_b);
+	if (!ACPI_SUCCESS (status)) {
 		return status;
 	}
 
 	/* run the _PTS and _GTS methods */
+
 	MEMSET(&arg_list, 0, sizeof(arg_list));
 	arg_list.count = 1;
 	arg_list.pointer = &arg;
@@ -159,28 +160,32 @@
 	acpi_evaluate_object(NULL, "\\_GTS", &arg_list, NULL);
 
 	/* clear wake status */
+
 	acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, WAK_STS, 1);
 
+	disable();
+
 	PM1_acontrol = (u16) acpi_hw_register_read(ACPI_MTX_LOCK, PM1_CONTROL);
 
 	/* mask off SLP_EN and SLP_TYP fields */
 	PM1_acontrol &= 0xC3FF;
-
-	/* mask in SLP_EN */
-	PM1_acontrol |= (1 << acpi_hw_get_bit_shift (SLP_EN_MASK));
-
 	PM1_bcontrol = PM1_acontrol;
 
 	/* mask in SLP_TYP */
 	PM1_acontrol |= (type_a << acpi_hw_get_bit_shift (SLP_TYPE_X_MASK));
 	PM1_bcontrol |= (type_b << acpi_hw_get_bit_shift (SLP_TYPE_X_MASK));
 
-	disable();
+	/* write #1: fill in SLP_TYPE data */
+	acpi_hw_register_write(ACPI_MTX_LOCK, PM1_a_CONTROL, PM1_acontrol);
+	acpi_hw_register_write(ACPI_MTX_LOCK, PM1_b_CONTROL, PM1_bcontrol);
+
+	/* mask in SLP_EN */
+	PM1_acontrol |= (1 << acpi_hw_get_bit_shift (SLP_EN_MASK));
+	PM1_bcontrol |= (1 << acpi_hw_get_bit_shift (SLP_EN_MASK));
 
+	/* write #2: the whole tamale */
 	acpi_hw_register_write(ACPI_MTX_LOCK, PM1_a_CONTROL, PM1_acontrol);
 	acpi_hw_register_write(ACPI_MTX_LOCK, PM1_b_CONTROL, PM1_bcontrol);
-	acpi_hw_register_write(ACPI_MTX_LOCK, PM1_CONTROL,
-		(1 << acpi_hw_get_bit_shift (SLP_EN_MASK)));
 
 	enable();
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/hardware/hwtimer.c linux/drivers/acpi/hardware/hwtimer.c
--- v2.4.5/linux/drivers/acpi/hardware/hwtimer.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/hardware/hwtimer.c	Wed Jun 20 17:47:40 2001
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Name: hwtimer.c - ACPI Power Management Timer Interface
- *              $Revision: 5 $
+ *              $Revision: 10 $
  *
  *****************************************************************************/
 
@@ -27,7 +27,7 @@
 #include "acpi.h"
 #include "achware.h"
 
-#define _COMPONENT          HARDWARE
+#define _COMPONENT          ACPI_HARDWARE
 	 MODULE_NAME         ("hwtimer")
 
 
@@ -47,6 +47,16 @@
 acpi_get_timer_resolution (
 	u32                     *resolution)
 {
+	ACPI_STATUS             status;
+
+
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	if (!resolution) {
 		return (AE_BAD_PARAMETER);
 	}
@@ -78,6 +88,16 @@
 acpi_get_timer (
 	u32                     *ticks)
 {
+	ACPI_STATUS             status;
+
+
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	if (!ticks) {
 		return (AE_BAD_PARAMETER);
 	}
@@ -126,6 +146,7 @@
 	u32                     microseconds = 0;
 	u32                     remainder = 0;
 
+
 	if (!time_elapsed) {
 		return (AE_BAD_PARAMETER);
 	}
@@ -160,7 +181,7 @@
 	 * divides in kernel-space we have to do some trickery to preserve
 	 * accuracy while using 32-bit math.
 	 *
-	 * TODO: Change to use 64-bit math when supported.
+	 * TBD: Change to use 64-bit math when supported.
 	 *
 	 * The process is as follows:
 	 *  1. Compute the number of seconds by dividing Delta Ticks by
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/accommon.h linux/drivers/acpi/include/accommon.h
--- v2.4.5/linux/drivers/acpi/include/accommon.h	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/include/accommon.h	Wed Dec 31 16:00:00 1969
@@ -1,725 +0,0 @@
-/******************************************************************************
- *
- * Name: accommon.h -- prototypes for the common (subsystem-wide) procedures
- *       $Revision: 90 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _ACCOMMON_H
-#define _ACCOMMON_H
-
-
-typedef
-ACPI_STATUS (*ACPI_PKG_CALLBACK) (
-	u8                      object_type,
-	ACPI_OPERAND_OBJECT     *source_object,
-	ACPI_GENERIC_STATE      *state,
-	void                    *context);
-
-
-ACPI_STATUS
-acpi_cm_walk_package_tree (
-	ACPI_OPERAND_OBJECT     *source_object,
-	void                    *target_object,
-	ACPI_PKG_CALLBACK       walk_callback,
-	void                    *context);
-
-
-typedef struct acpi_pkg_info
-{
-	u8                      *free_space;
-	u32                     length;
-	u32                     object_space;
-	u32                     num_packages;
-} ACPI_PKG_INFO;
-
-#define REF_INCREMENT       (u16) 0
-#define REF_DECREMENT       (u16) 1
-#define REF_FORCE_DELETE    (u16) 2
-
-/* Acpi_cm_dump_buffer */
-
-#define DB_BYTE_DISPLAY     1
-#define DB_WORD_DISPLAY     2
-#define DB_DWORD_DISPLAY    4
-#define DB_QWORD_DISPLAY    8
-
-
-/* Global initialization interfaces */
-
-void
-acpi_cm_init_globals (
-	void);
-
-void
-acpi_cm_terminate (
-	void);
-
-
-/*
- * Cm_init - miscellaneous initialization and shutdown
- */
-
-ACPI_STATUS
-acpi_cm_hardware_initialize (
-	void);
-
-ACPI_STATUS
-acpi_cm_subsystem_shutdown (
-	void);
-
-ACPI_STATUS
-acpi_cm_validate_fadt (
-	void);
-
-/*
- * Cm_global - Global data structures and procedures
- */
-
-#ifdef ACPI_DEBUG
-
-NATIVE_CHAR *
-acpi_cm_get_mutex_name (
-	u32                     mutex_id);
-
-NATIVE_CHAR *
-acpi_cm_get_type_name (
-	u32                     type);
-
-NATIVE_CHAR *
-acpi_cm_get_region_name (
-	u8                      space_id);
-
-#endif
-
-
-u8
-acpi_cm_valid_object_type (
-	u32                     type);
-
-ACPI_OWNER_ID
-acpi_cm_allocate_owner_id (
-	u32                     id_type);
-
-
-/*
- * Cm_clib - Local implementations of C library functions
- */
-
-#ifndef ACPI_USE_SYSTEM_CLIBRARY
-
-NATIVE_UINT
-acpi_cm_strlen (
-	const NATIVE_CHAR       *string);
-
-NATIVE_CHAR *
-acpi_cm_strcpy (
-	NATIVE_CHAR             *dst_string,
-	const NATIVE_CHAR       *src_string);
-
-NATIVE_CHAR *
-acpi_cm_strncpy (
-	NATIVE_CHAR             *dst_string,
-	const NATIVE_CHAR       *src_string,
-	NATIVE_UINT             count);
-
-u32
-acpi_cm_strncmp (
-	const NATIVE_CHAR       *string1,
-	const NATIVE_CHAR       *string2,
-	NATIVE_UINT             count);
-
-u32
-acpi_cm_strcmp (
-	const NATIVE_CHAR       *string1,
-	const NATIVE_CHAR       *string2);
-
-NATIVE_CHAR *
-acpi_cm_strcat (
-	NATIVE_CHAR             *dst_string,
-	const NATIVE_CHAR       *src_string);
-
-NATIVE_CHAR *
-acpi_cm_strncat (
-	NATIVE_CHAR             *dst_string,
-	const NATIVE_CHAR       *src_string,
-	NATIVE_UINT             count);
-
-u32
-acpi_cm_strtoul (
-	const NATIVE_CHAR       *string,
-	NATIVE_CHAR             **terminator,
-	NATIVE_UINT             base);
-
-NATIVE_CHAR *
-acpi_cm_strstr (
-	NATIVE_CHAR             *string1,
-	NATIVE_CHAR             *string2);
-
-NATIVE_CHAR *
-acpi_cm_strupr (
-	NATIVE_CHAR             *src_string);
-
-void *
-acpi_cm_memcpy (
-	void                    *dest,
-	const void              *src,
-	NATIVE_UINT             count);
-
-void *
-acpi_cm_memset (
-	void                    *dest,
-	NATIVE_UINT             value,
-	NATIVE_UINT             count);
-
-u32
-acpi_cm_to_upper (
-	u32                     c);
-
-u32
-acpi_cm_to_lower (
-	u32                     c);
-
-#endif /* ACPI_USE_SYSTEM_CLIBRARY */
-
-/*
- * Cm_copy - Object construction and conversion interfaces
- */
-
-ACPI_STATUS
-acpi_cm_build_simple_object(
-	ACPI_OPERAND_OBJECT     *obj,
-	ACPI_OBJECT             *user_obj,
-	u8                      *data_space,
-	u32                     *buffer_space_used);
-
-ACPI_STATUS
-acpi_cm_build_package_object (
-	ACPI_OPERAND_OBJECT     *obj,
-	u8                      *buffer,
-	u32                     *space_used);
-
-ACPI_STATUS
-acpi_cm_copy_iobject_to_eobject (
-	ACPI_OPERAND_OBJECT     *obj,
-	ACPI_BUFFER             *ret_buffer);
-
-ACPI_STATUS
-acpi_cm_copy_esimple_to_isimple(
-	ACPI_OBJECT             *user_obj,
-	ACPI_OPERAND_OBJECT     *obj);
-
-ACPI_STATUS
-acpi_cm_copy_eobject_to_iobject (
-	ACPI_OBJECT             *obj,
-	ACPI_OPERAND_OBJECT     *internal_obj);
-
-ACPI_STATUS
-acpi_cm_copy_isimple_to_isimple (
-	ACPI_OPERAND_OBJECT     *source_obj,
-	ACPI_OPERAND_OBJECT     *dest_obj);
-
-ACPI_STATUS
-acpi_cm_copy_ipackage_to_ipackage (
-	ACPI_OPERAND_OBJECT     *source_obj,
-	ACPI_OPERAND_OBJECT     *dest_obj,
-	ACPI_WALK_STATE         *walk_state);
-
-
-/*
- * Cm_create - Object creation
- */
-
-ACPI_STATUS
-acpi_cm_update_object_reference (
-	ACPI_OPERAND_OBJECT     *object,
-	u16                     action);
-
-ACPI_OPERAND_OBJECT  *
-_cm_create_internal_object (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id,
-	OBJECT_TYPE_INTERNAL    type);
-
-
-/*
- * Cm_debug - Debug interfaces
- */
-
-u32
-get_debug_level (
-	void);
-
-void
-set_debug_level (
-	u32                     level);
-
-void
-function_trace (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id,
-	NATIVE_CHAR             *function_name);
-
-void
-function_trace_ptr (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id,
-	NATIVE_CHAR             *function_name,
-	void                    *pointer);
-
-void
-function_trace_u32 (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id,
-	NATIVE_CHAR             *function_name,
-	u32                     integer);
-
-void
-function_trace_str (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id,
-	NATIVE_CHAR             *function_name,
-	NATIVE_CHAR             *string);
-
-void
-function_exit (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id,
-	NATIVE_CHAR             *function_name);
-
-void
-function_status_exit (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id,
-	NATIVE_CHAR             *function_name,
-	ACPI_STATUS             status);
-
-void
-function_value_exit (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id,
-	NATIVE_CHAR             *function_name,
-	ACPI_INTEGER            value);
-
-void
-function_ptr_exit (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id,
-	NATIVE_CHAR             *function_name,
-	u8                      *ptr);
-
-void
-debug_print_prefix (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number);
-
-void
-debug_print (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id,
-	u32                     print_level,
-	NATIVE_CHAR             *format, ...);
-
-void
-debug_print_raw (
-	NATIVE_CHAR             *format, ...);
-
-void
-_report_info (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id);
-
-void
-_report_error (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id);
-
-void
-_report_warning (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id);
-
-void
-acpi_cm_dump_buffer (
-	u8                      *buffer,
-	u32                     count,
-	u32                     display,
-	u32                     component_id);
-
-
-/*
- * Cm_delete - Object deletion
- */
-
-void
-acpi_cm_delete_internal_obj (
-	ACPI_OPERAND_OBJECT     *object);
-
-void
-acpi_cm_delete_internal_package_object (
-	ACPI_OPERAND_OBJECT     *object);
-
-void
-acpi_cm_delete_internal_simple_object (
-	ACPI_OPERAND_OBJECT     *object);
-
-ACPI_STATUS
-acpi_cm_delete_internal_object_list (
-	ACPI_OPERAND_OBJECT     **obj_list);
-
-
-/*
- * Cm_eval - object evaluation
- */
-
-/* Method name strings */
-
-#define METHOD_NAME__HID        "_HID"
-#define METHOD_NAME__UID        "_UID"
-#define METHOD_NAME__ADR        "_ADR"
-#define METHOD_NAME__STA        "_STA"
-#define METHOD_NAME__REG        "_REG"
-#define METHOD_NAME__SEG        "_SEG"
-#define METHOD_NAME__BBN        "_BBN"
-
-
-ACPI_STATUS
-acpi_cm_evaluate_numeric_object (
-	NATIVE_CHAR             *object_name,
-	ACPI_NAMESPACE_NODE     *device_node,
-	ACPI_INTEGER            *address);
-
-ACPI_STATUS
-acpi_cm_execute_HID (
-	ACPI_NAMESPACE_NODE     *device_node,
-	DEVICE_ID               *hid);
-
-ACPI_STATUS
-acpi_cm_execute_STA (
-	ACPI_NAMESPACE_NODE     *device_node,
-	u32                     *status_flags);
-
-ACPI_STATUS
-acpi_cm_execute_UID (
-	ACPI_NAMESPACE_NODE     *device_node,
-	DEVICE_ID               *uid);
-
-
-/*
- * Cm_error - exception interfaces
- */
-
-NATIVE_CHAR *
-acpi_cm_format_exception (
-	ACPI_STATUS             status);
-
-
-/*
- * Cm_mutex - mutual exclusion interfaces
- */
-
-ACPI_STATUS
-acpi_cm_mutex_initialize (
-	void);
-
-void
-acpi_cm_mutex_terminate (
-	void);
-
-ACPI_STATUS
-acpi_cm_create_mutex (
-	ACPI_MUTEX_HANDLE       mutex_id);
-
-ACPI_STATUS
-acpi_cm_delete_mutex (
-	ACPI_MUTEX_HANDLE       mutex_id);
-
-ACPI_STATUS
-acpi_cm_acquire_mutex (
-	ACPI_MUTEX_HANDLE       mutex_id);
-
-ACPI_STATUS
-acpi_cm_release_mutex (
-	ACPI_MUTEX_HANDLE       mutex_id);
-
-
-/*
- * Cm_object - internal object create/delete/cache routines
- */
-
-void *
-_cm_allocate_object_desc (
-	NATIVE_CHAR             *module_name,
-	u32                     line_number,
-	u32                     component_id);
-
-#define acpi_cm_create_internal_object(t) _cm_create_internal_object(_THIS_MODULE,__LINE__,_COMPONENT,t)
-#define acpi_cm_allocate_object_desc()  _cm_allocate_object_desc(_THIS_MODULE,__LINE__,_COMPONENT)
-
-void
-acpi_cm_delete_object_desc (
-	ACPI_OPERAND_OBJECT     *object);
-
-u8
-acpi_cm_valid_internal_object (
-	void                    *object);
-
-
-/*
- * Cm_ref_cnt - Object reference count management
- */
-
-void
-acpi_cm_add_reference (
-	ACPI_OPERAND_OBJECT     *object);
-
-void
-acpi_cm_remove_reference (
-	ACPI_OPERAND_OBJECT     *object);
-
-/*
- * Cm_size - Object size routines
- */
-
-ACPI_STATUS
-acpi_cm_get_simple_object_size (
-	ACPI_OPERAND_OBJECT     *obj,
-	u32                     *obj_length);
-
-ACPI_STATUS
-acpi_cm_get_package_object_size (
-	ACPI_OPERAND_OBJECT     *obj,
-	u32                     *obj_length);
-
-ACPI_STATUS
-acpi_cm_get_object_size(
-	ACPI_OPERAND_OBJECT     *obj,
-	u32                     *obj_length);
-
-
-/*
- * Cm_state - Generic state creation/cache routines
- */
-
-void
-acpi_cm_push_generic_state (
-	ACPI_GENERIC_STATE      **list_head,
-	ACPI_GENERIC_STATE      *state);
-
-ACPI_GENERIC_STATE *
-acpi_cm_pop_generic_state (
-	ACPI_GENERIC_STATE      **list_head);
-
-
-ACPI_GENERIC_STATE *
-acpi_cm_create_generic_state (
-	void);
-
-ACPI_GENERIC_STATE *
-acpi_cm_create_update_state (
-	ACPI_OPERAND_OBJECT     *object,
-	u16                     action);
-
-ACPI_GENERIC_STATE *
-acpi_cm_create_pkg_state (
-	void                    *internal_object,
-	void                    *external_object,
-	u16                     index);
-
-ACPI_STATUS
-acpi_cm_create_update_state_and_push (
-	ACPI_OPERAND_OBJECT     *object,
-	u16                     action,
-	ACPI_GENERIC_STATE      **state_list);
-
-ACPI_STATUS
-acpi_cm_create_pkg_state_and_push (
-	void                    *internal_object,
-	void                    *external_object,
-	u16                     index,
-	ACPI_GENERIC_STATE      **state_list);
-
-ACPI_GENERIC_STATE *
-acpi_cm_create_control_state (
-	void);
-
-void
-acpi_cm_delete_generic_state (
-	ACPI_GENERIC_STATE      *state);
-
-void
-acpi_cm_delete_generic_state_cache (
-	void);
-
-void
-acpi_cm_delete_object_cache (
-	void);
-
-/*
- * Cmutils
- */
-
-u8
-acpi_cm_valid_acpi_name (
-	u32                     name);
-
-u8
-acpi_cm_valid_acpi_character (
-	NATIVE_CHAR             character);
-
-ACPI_STATUS
-acpi_cm_resolve_package_references (
-	ACPI_OPERAND_OBJECT     *obj_desc);
-
-#ifdef ACPI_DEBUG
-
-void
-acpi_cm_display_init_pathname (
-	ACPI_HANDLE             obj_handle,
-	char                    *path);
-
-#endif
-
-
-/*
- * Memory allocation functions and related macros.
- * Macros that expand to include filename and line number
- */
-
-void *
-_cm_allocate (
-	u32                     size,
-	u32                     component,
-	NATIVE_CHAR             *module,
-	u32                     line);
-
-void *
-_cm_callocate (
-	u32                     size,
-	u32                     component,
-	NATIVE_CHAR             *module,
-	u32                     line);
-
-void
-_cm_free (
-	void                    *address,
-	u32                     component,
-	NATIVE_CHAR             *module,
-	u32                     line);
-
-void
-acpi_cm_init_static_object (
-	ACPI_OPERAND_OBJECT     *obj_desc);
-
-#define acpi_cm_allocate(a)             _cm_allocate(a,_COMPONENT,_THIS_MODULE,__LINE__)
-#define acpi_cm_callocate(a)            _cm_callocate(a, _COMPONENT,_THIS_MODULE,__LINE__)
-#define acpi_cm_free(a)                 _cm_free(a,_COMPONENT,_THIS_MODULE,__LINE__)
-
-#ifndef ACPI_DEBUG_TRACK_ALLOCATIONS
-
-#define acpi_cm_add_element_to_alloc_list(a,b,c,d,e,f)
-#define acpi_cm_delete_element_from_alloc_list(a,b,c,d)
-#define acpi_cm_dump_current_allocations(a,b)
-#define acpi_cm_dump_allocation_info()
-
-#define DECREMENT_OBJECT_METRICS(a)
-#define INCREMENT_OBJECT_METRICS(a)
-#define INITIALIZE_ALLOCATION_METRICS()
-#define DECREMENT_NAME_TABLE_METRICS(a)
-#define INCREMENT_NAME_TABLE_METRICS(a)
-
-#else
-
-#define INITIALIZE_ALLOCATION_METRICS() \
-	acpi_gbl_current_object_count = 0; \
-	acpi_gbl_current_object_size = 0; \
-	acpi_gbl_running_object_count = 0; \
-	acpi_gbl_running_object_size = 0; \
-	acpi_gbl_max_concurrent_object_count = 0; \
-	acpi_gbl_max_concurrent_object_size = 0; \
-	acpi_gbl_current_alloc_size = 0; \
-	acpi_gbl_current_alloc_count = 0; \
-	acpi_gbl_running_alloc_size = 0; \
-	acpi_gbl_running_alloc_count = 0; \
-	acpi_gbl_max_concurrent_alloc_size = 0; \
-	acpi_gbl_max_concurrent_alloc_count = 0; \
-	acpi_gbl_current_node_count = 0; \
-	acpi_gbl_current_node_size = 0; \
-	acpi_gbl_max_concurrent_node_count = 0
-
-
-#define DECREMENT_OBJECT_METRICS(a) \
-	acpi_gbl_current_object_count--; \
-	acpi_gbl_current_object_size -= a
-
-#define INCREMENT_OBJECT_METRICS(a) \
-	acpi_gbl_current_object_count++; \
-	acpi_gbl_running_object_count++; \
-	if (acpi_gbl_max_concurrent_object_count < acpi_gbl_current_object_count) \
-	{ \
-		acpi_gbl_max_concurrent_object_count = acpi_gbl_current_object_count; \
-	} \
-	acpi_gbl_running_object_size += a; \
-	acpi_gbl_current_object_size += a; \
-	if (acpi_gbl_max_concurrent_object_size < acpi_gbl_current_object_size) \
-	{ \
-		acpi_gbl_max_concurrent_object_size = acpi_gbl_current_object_size; \
-	}
-
-#define DECREMENT_NAME_TABLE_METRICS(a) \
-	acpi_gbl_current_node_count--; \
-	acpi_gbl_current_node_size -= (a)
-
-#define INCREMENT_NAME_TABLE_METRICS(a) \
-	acpi_gbl_current_node_count++; \
-	acpi_gbl_current_node_size+= (a); \
-	if (acpi_gbl_max_concurrent_node_count < acpi_gbl_current_node_count) \
-	{ \
-		acpi_gbl_max_concurrent_node_count = acpi_gbl_current_node_count; \
-	} \
-
-
-void
-acpi_cm_dump_allocation_info (
-	void);
-
-void
-acpi_cm_dump_current_allocations (
-	u32                     component,
-	NATIVE_CHAR             *module);
-
-#endif
-
-
-#endif /* _ACCOMMON_H */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/acconfig.h linux/drivers/acpi/include/acconfig.h
--- v2.4.5/linux/drivers/acpi/include/acconfig.h	Tue Mar  6 19:44:36 2001
+++ linux/drivers/acpi/include/acconfig.h	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acconfig.h - Global configuration constants
- *       $Revision: 55 $
+ *       $Revision: 65 $
  *
  *****************************************************************************/
 
@@ -53,7 +53,7 @@
 
 /* Version string */
 
-#define ACPI_CA_VERSION             0x20010208
+#define ACPI_CA_VERSION             0x20010615
 
 
 /* Maximum objects in the various object caches */
@@ -147,6 +147,11 @@
 #define LO_RSDP_WINDOW_SIZE         0x400
 #define HI_RSDP_WINDOW_SIZE         0x20000
 #define RSDP_SCAN_STEP              16
+
+/* Maximum Space_ids for Operation Regions */
+
+#define ACPI_MAX_ADDRESS_SPACE      255
+#define ACPI_NUM_ADDRESS_SPACES     256
 
 
 #endif /* _ACCONFIG_H */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/acdebug.h linux/drivers/acpi/include/acdebug.h
--- v2.4.5/linux/drivers/acpi/include/acdebug.h	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/include/acdebug.h	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acdebug.h - ACPI/AML debugger
- *       $Revision: 41 $
+ *       $Revision: 44 $
  *
  *****************************************************************************/
 
@@ -36,7 +36,7 @@
 extern int                      optind;
 extern NATIVE_CHAR              *optarg;
 extern u8                       *aml_ptr;
-extern u32                      acpi_aml_length;
+extern u32                      aml_length;
 
 extern u8                       opt_tables;
 extern u8                       opt_disasm;
@@ -200,6 +200,10 @@
 	NATIVE_CHAR             *object_arg);
 
 void
+acpi_db_display_locks (void);
+
+
+void
 acpi_db_display_resources (
 	NATIVE_CHAR             *object_arg);
 
@@ -303,7 +307,7 @@
  * dbfileio - Debugger file I/O commands
  */
 
-OBJECT_TYPE_INTERNAL
+ACPI_OBJECT_TYPE8
 acpi_db_match_argument (
 	NATIVE_CHAR             *user_argument,
 	ARGUMENT_INFO           *arguments);
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/acdispat.h linux/drivers/acpi/include/acdispat.h
--- v2.4.5/linux/drivers/acpi/include/acdispat.h	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/include/acdispat.h	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acdispat.h - dispatcher (parser to interpreter interface)
- *       $Revision: 35 $
+ *       $Revision: 40 $
  *
  *****************************************************************************/
 
@@ -32,12 +32,6 @@
 #define NAMEOF_ARG_NTE      "__A0"
 
 
-/* For Acpi_ds_method_data_set_value */
-
-#define MTH_TYPE_LOCAL              0
-#define MTH_TYPE_ARG                1
-
-
 /* Common interfaces */
 
 ACPI_STATUS
@@ -64,7 +58,7 @@
 /* dsopcode - support for late evaluation */
 
 ACPI_STATUS
-acpi_ds_get_field_unit_arguments (
+acpi_ds_get_buffer_field_arguments (
 	ACPI_OPERAND_OBJECT     *obj_desc);
 
 ACPI_STATUS
@@ -126,7 +120,7 @@
 ACPI_STATUS
 acpi_ds_create_index_field (
 	ACPI_PARSE_OBJECT       *op,
-	ACPI_HANDLE             region_node,
+	ACPI_NAMESPACE_NODE     *region_node,
 	ACPI_WALK_STATE         *walk_state);
 
 
@@ -173,8 +167,15 @@
 
 
 ACPI_STATUS
+acpi_ds_store_object_to_local (
+	u16                     opcode,
+	u32                     index,
+	ACPI_OPERAND_OBJECT     *src_desc,
+	ACPI_WALK_STATE         *walk_state);
+
+ACPI_STATUS
 acpi_ds_method_data_get_entry (
-	u32                     type,
+	u16                     opcode,
 	u32                     index,
 	ACPI_WALK_STATE         *walk_state,
 	ACPI_OPERAND_OBJECT     ***node);
@@ -187,29 +188,22 @@
 acpi_ds_is_method_value (
 	ACPI_OPERAND_OBJECT     *obj_desc);
 
-OBJECT_TYPE_INTERNAL
+ACPI_OBJECT_TYPE8
 acpi_ds_method_data_get_type (
-	u32                     type,
+	u16                     opcode,
 	u32                     index,
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_STATUS
 acpi_ds_method_data_get_value (
-	u32                     type,
+	u16                     opcode,
 	u32                     index,
 	ACPI_WALK_STATE         *walk_state,
 	ACPI_OPERAND_OBJECT     **dest_desc);
 
 ACPI_STATUS
-acpi_ds_method_data_set_value (
-	u32                     type,
-	u32                     index,
-	ACPI_OPERAND_OBJECT     *src_desc,
-	ACPI_WALK_STATE         *walk_state);
-
-ACPI_STATUS
 acpi_ds_method_data_delete_value (
-	u32                     type,
+	u16                     opcode,
 	u32                     index,
 	ACPI_WALK_STATE         *walk_state);
 
@@ -220,8 +214,8 @@
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_NAMESPACE_NODE *
-acpi_ds_method_data_get_nte (
-	u32                     type,
+acpi_ds_method_data_get_node (
+	u16                     opcode,
 	u32                     index,
 	ACPI_WALK_STATE         *walk_state);
 
@@ -231,7 +225,7 @@
 
 ACPI_STATUS
 acpi_ds_method_data_set_entry (
-	u32                     type,
+	u16                     opcode,
 	u32                     index,
 	ACPI_OPERAND_OBJECT     *object,
 	ACPI_WALK_STATE         *walk_state);
@@ -261,7 +255,8 @@
 ACPI_STATUS
 acpi_ds_begin_method_execution (
 	ACPI_NAMESPACE_NODE     *method_node,
-	ACPI_OPERAND_OBJECT     *obj_desc);
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	ACPI_NAMESPACE_NODE     *calling_method_node);
 
 
 /* dsobj - Parser/Interpreter interface - object initialization and conversion */
@@ -307,7 +302,7 @@
 /* dsregn - Parser/Interpreter interface - Op Region parsing */
 
 ACPI_STATUS
-acpi_ds_eval_field_unit_operands (
+acpi_ds_eval_buffer_field_operands (
 	ACPI_WALK_STATE         *walk_state,
 	ACPI_PARSE_OBJECT       *op);
 
@@ -349,12 +344,12 @@
 acpi_ds_resolve_operands (
 	ACPI_WALK_STATE         *walk_state);
 
-OBJECT_TYPE_INTERNAL
+ACPI_OBJECT_TYPE8
 acpi_ds_map_opcode_to_data_type (
 	u16                     opcode,
 	u32                     *out_flags);
 
-OBJECT_TYPE_INTERNAL
+ACPI_OBJECT_TYPE8
 acpi_ds_map_named_opcode_to_data_type (
 	u16                     opcode);
 
@@ -366,7 +361,7 @@
 ACPI_STATUS
 acpi_ds_scope_stack_push (
 	ACPI_NAMESPACE_NODE     *node,
-	OBJECT_TYPE_INTERNAL    type,
+	ACPI_OBJECT_TYPE8       type,
 	ACPI_WALK_STATE         *walk_state);
 
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/acenv.h linux/drivers/acpi/include/acenv.h
--- v2.4.5/linux/drivers/acpi/include/acenv.h	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/include/acenv.h	Wed Dec 31 16:00:00 1969
@@ -1,288 +0,0 @@
-/******************************************************************************
- *
- * Name: acenv.h - Generation environment specific items
- *       $Revision: 70 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef __ACENV_H__
-#define __ACENV_H__
-
-
-/*
- * Configuration for ACPI tools and utilities
- */
-
-#ifdef _ACPI_DUMP_APP
-#define ACPI_DEBUG
-#define ACPI_APPLICATION
-#define ENABLE_DEBUGGER
-#define ACPI_USE_SYSTEM_CLIBRARY
-#define PARSER_ONLY
-#endif
-
-#ifdef _ACPI_EXEC_APP
-#undef DEBUGGER_THREADING
-#define DEBUGGER_THREADING      DEBUGGER_SINGLE_THREADED
-#define ACPI_DEBUG
-#define ACPI_APPLICATION
-#define ENABLE_DEBUGGER
-#define ACPI_USE_SYSTEM_CLIBRARY
-#endif
-
-#ifdef _ACPI_ASL_COMPILER
-#define ACPI_DEBUG
-#define ACPI_APPLICATION
-#define ENABLE_DEBUGGER
-#define ACPI_USE_SYSTEM_CLIBRARY
-#endif
-
-/*
- * Memory allocation tracking.  Used only if
- * 1) This is the debug version
- * 2) This is NOT a 16-bit version of the code (not enough real-mode memory)
- */
-#ifdef ACPI_DEBUG
-#ifndef _IA16
-#define ACPI_DEBUG_TRACK_ALLOCATIONS
-#endif
-#endif
-
-/*
- * Environment configuration.  The purpose of this file is to interface to the
- * local generation environment.
- *
- * 1) ACPI_USE_SYSTEM_CLIBRARY - Define this if linking to an actual C library.
- *      Otherwise, local versions of string/memory functions will be used.
- * 2) ACPI_USE_STANDARD_HEADERS - Define this if linking to a C library and
- *      the standard header files may be used.
- *
- * The ACPI subsystem only uses low level C library functions that do not call
- * operating system services and may therefore be inlined in the code.
- *
- * It may be necessary to tailor these include files to the target
- * generation environment.
- *
- *
- * Functions and constants used from each header:
- *
- * string.h:    memcpy
- *              memset
- *              strcat
- *              strcmp
- *              strcpy
- *              strlen
- *              strncmp
- *              strncat
- *              strncpy
- *
- * stdlib.h:    strtoul
- *
- * stdarg.h:    va_list
- *              va_arg
- *              va_start
- *              va_end
- *
- */
-
-/*! [Begin] no source code translation */
-
-#ifdef _LINUX
-#include "aclinux.h"
-
-#elif _AED_EFI
-#include "acefi.h"
-
-#elif WIN32
-#include "acwin.h"
-
-#elif __FreeBSD__
-#include "acfreebsd.h"
-
-#else
-
-/* All other environments */
-
-#define ACPI_USE_STANDARD_HEADERS
-
-/* Name of host operating system (returned by the _OS_ namespace object) */
-
-#define ACPI_OS_NAME         "Intel ACPI/CA Core Subsystem"
-
-#endif
-
-
-/*! [End] no source code translation !*/
-
-/******************************************************************************
- *
- * C library configuration
- *
- *****************************************************************************/
-
-#ifdef ACPI_USE_SYSTEM_CLIBRARY
-/*
- * Use the standard C library headers.
- * We want to keep these to a minimum.
- *
- */
-
-#ifdef ACPI_USE_STANDARD_HEADERS
-/*
- * Use the standard headers from the standard locations
- */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#endif /* ACPI_USE_STANDARD_HEADERS */
-
-/*
- * We will be linking to the standard Clib functions
- */
-
-#define STRSTR(s1,s2)   strstr((s1), (s2))
-#define STRUPR(s)       strupr((s))
-#define STRLEN(s)       strlen((s))
-#define STRCPY(d,s)     strcpy((d), (s))
-#define STRNCPY(d,s,n)  strncpy((d), (s), (NATIVE_INT)(n))
-#define STRNCMP(d,s,n)  strncmp((d), (s), (NATIVE_INT)(n))
-#define STRCMP(d,s)     strcmp((d), (s))
-#define STRCAT(d,s)     strcat((d), (s))
-#define STRNCAT(d,s,n)  strncat((d), (s), (NATIVE_INT)(n))
-#define STRTOUL(d,s,n)  strtoul((d), (s), (NATIVE_INT)(n))
-#define MEMCPY(d,s,n)   memcpy((d), (s), (NATIVE_INT)(n))
-#define MEMSET(d,s,n)   memset((d), (s), (NATIVE_INT)(n))
-#define TOUPPER         toupper
-#define TOLOWER         tolower
-#define IS_XDIGIT       isxdigit
-
-/******************************************************************************
- *
- * Not using native C library, use local implementations
- *
- *****************************************************************************/
-#else
-
-/*
- * Use local definitions of C library macros and functions
- * NOTE: The function implementations may not be as efficient
- * as an inline or assembly code implementation provided by a
- * native C library.
- */
-
-#ifndef va_arg
-
-#ifndef _VALIST
-#define _VALIST
-typedef char *va_list;
-#endif /* _VALIST */
-
-/*
- * Storage alignment properties
- */
-
-#define  _AUPBND         (sizeof(int) - 1)
-#define  _ADNBND         (sizeof(int) - 1)
-
-/*
- * Variable argument list macro definitions
- */
-
-#define _bnd(X, bnd)    (((sizeof(X)) + (bnd)) & (~(bnd)))
-#define va_arg(ap, T)  (*(T *)(((ap)+=((_bnd(T, _AUPBND)))-(_bnd(T,_ADNBND)))))
-#define va_end(ap)      (void)0
-#define va_start(ap, A) (void)((ap)=(((char*)&(A))+(_bnd(A,_AUPBND))))
-
-#endif /* va_arg */
-
-
-#define STRSTR(s1,s2)    acpi_cm_strstr ((s1), (s2))
-#define STRUPR(s)        acpi_cm_strupr ((s))
-#define STRLEN(s)        acpi_cm_strlen ((s))
-#define STRCPY(d,s)      acpi_cm_strcpy ((d), (s))
-#define STRNCPY(d,s,n)   acpi_cm_strncpy ((d), (s), (n))
-#define STRNCMP(d,s,n)   acpi_cm_strncmp ((d), (s), (n))
-#define STRCMP(d,s)      acpi_cm_strcmp ((d), (s))
-#define STRCAT(d,s)      acpi_cm_strcat ((d), (s))
-#define STRNCAT(d,s,n)   acpi_cm_strncat ((d), (s), (n))
-#define STRTOUL(d,s,n)   acpi_cm_strtoul ((d), (s),(n))
-#define MEMCPY(d,s,n)    acpi_cm_memcpy ((d), (s), (n))
-#define MEMSET(d,v,n)    acpi_cm_memset ((d), (v), (n))
-#define TOUPPER          acpi_cm_to_upper
-#define TOLOWER          acpi_cm_to_lower
-
-#endif /* ACPI_USE_SYSTEM_CLIBRARY */
-
-
-/******************************************************************************
- *
- * Assembly code macros
- *
- *****************************************************************************/
-
-/*
- * Handle platform- and compiler-specific assembly language differences.
- * These should already have been defined by the platform includes above.
- *
- * Notes:
- * 1) Interrupt 3 is used to break into a debugger
- * 2) Interrupts are turned off during ACPI register setup
- */
-
-/* Unrecognized compiler, use defaults */
-#ifndef ACPI_ASM_MACROS
-
-#define ACPI_ASM_MACROS
-#define causeinterrupt(level)
-#define BREAKPOINT3
-#define disable()
-#define enable()
-#define halt()
-#define ACPI_ACQUIRE_GLOBAL_LOCK(Glptr, acq)
-#define ACPI_RELEASE_GLOBAL_LOCK(Glptr, acq)
-
-#endif /* ACPI_ASM_MACROS */
-
-
-#ifdef ACPI_APPLICATION
-
-/* Don't want software interrupts within a ring3 application */
-
-#undef causeinterrupt
-#undef BREAKPOINT3
-#define causeinterrupt(level)
-#define BREAKPOINT3
-#endif
-
-
-/******************************************************************************
- *
- * Compiler-specific
- *
- *****************************************************************************/
-
-/* this has been moved to compiler-specific headers, which are included from the
-   platform header. */
-
-
-#endif /* __ACENV_H__ */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/acevents.h linux/drivers/acpi/include/acevents.h
--- v2.4.5/linux/drivers/acpi/include/acevents.h	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/include/acevents.h	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acevents.h - Event subcomponent prototypes and defines
- *       $Revision: 63 $
+ *       $Revision: 65 $
  *
  *****************************************************************************/
 
@@ -91,11 +91,14 @@
  * Acpi_evnotify - Device Notify handling and dispatch
  */
 
-void
-acpi_ev_notify_dispatch (
-	ACPI_HANDLE             device,
+ACPI_STATUS
+acpi_ev_queue_notify_request (
+	ACPI_NAMESPACE_NODE     *node,
 	u32                     notify_value);
 
+void
+acpi_ev_notify_dispatch (
+	void                    *context);
 
 /*
  * Acpi_evregion - Address Space handling
@@ -195,22 +198,6 @@
 void
 acpi_ev_terminate (
 	void);
-
-
-/* Debug support */
-
-#ifdef ACPI_DEBUG
-
-u32
-acpi_ev_sci_count (
-	u32                     acpi_event);
-
-#define DEBUG_INCREMENT_EVENT_COUNT(a)   acpi_gbl_event_count[a]++;
-
-#else
-
-#define DEBUG_INCREMENT_EVENT_COUNT(a)
-#endif
 
 
 #endif  /* __ACEVENTS_H__  */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/acexcep.h linux/drivers/acpi/include/acexcep.h
--- v2.4.5/linux/drivers/acpi/include/acexcep.h	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/include/acexcep.h	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acexcep.h - Exception codes returned by the ACPI subsystem
- *       $Revision: 41 $
+ *       $Revision: 46 $
  *
  *****************************************************************************/
 
@@ -68,8 +68,14 @@
 #define AE_LIMIT                        (ACPI_STATUS) (0x0012 | AE_CODE_ENVIRONMENTAL)
 #define AE_TIME                         (ACPI_STATUS) (0x0013 | AE_CODE_ENVIRONMENTAL)
 #define AE_UNKNOWN_STATUS               (ACPI_STATUS) (0x0014 | AE_CODE_ENVIRONMENTAL)
+#define AE_ACQUIRE_DEADLOCK             (ACPI_STATUS) (0x0015 | AE_CODE_ENVIRONMENTAL)
+#define AE_RELEASE_DEADLOCK             (ACPI_STATUS) (0x0016 | AE_CODE_ENVIRONMENTAL)
+#define AE_NOT_ACQUIRED                 (ACPI_STATUS) (0x0017 | AE_CODE_ENVIRONMENTAL)
+#define AE_ALREADY_ACQUIRED             (ACPI_STATUS) (0x0018 | AE_CODE_ENVIRONMENTAL)
+#define AE_NO_HARDWARE_RESPONSE         (ACPI_STATUS) (0x0019 | AE_CODE_ENVIRONMENTAL)
+#define AE_NO_GLOBAL_LOCK               (ACPI_STATUS) (0x001A | AE_CODE_ENVIRONMENTAL)
 
-#define AE_CODE_ENV_MAX                 0x0014
+#define AE_CODE_ENV_MAX                 0x001A
 
 /*
  * Programmer exceptions
@@ -118,8 +124,13 @@
 #define AE_AML_INVALID_SPACE_ID         (ACPI_STATUS) (0x0012 | AE_CODE_AML)
 #define AE_AML_STRING_LIMIT             (ACPI_STATUS) (0x0013 | AE_CODE_AML)
 #define AE_AML_NO_RETURN_VALUE          (ACPI_STATUS) (0x0014 | AE_CODE_AML)
+#define AE_AML_METHOD_LIMIT             (ACPI_STATUS) (0x0015 | AE_CODE_AML)
+#define AE_AML_NOT_OWNER                (ACPI_STATUS) (0x0016 | AE_CODE_AML)
+#define AE_AML_MUTEX_ORDER              (ACPI_STATUS) (0x0017 | AE_CODE_AML)
+#define AE_AML_MUTEX_NOT_ACQUIRED       (ACPI_STATUS) (0x0018 | AE_CODE_AML)
+#define AE_AML_INVALID_RESOURCE_TYPE    (ACPI_STATUS) (0x0019 | AE_CODE_AML)
 
-#define AE_CODE_AML_MAX                 0x0014
+#define AE_CODE_AML_MAX                 0x0019
 
 /*
  * Internal exceptions used for control
@@ -165,6 +176,12 @@
 	"AE_LIMIT",
 	"AE_TIME",
 	"AE_UNKNOWN_STATUS",
+	"AE_ACQUIRE_DEADLOCK",
+	"AE_RELEASE_DEADLOCK",
+	"AE_NOT_ACQUIRED",
+	"AE_ALREADY_ACQUIRED",
+	"AE_NO_HARDWARE_RESPONSE",
+	"AE_NO_GLOBAL_LOCK",
 };
 
 static NATIVE_CHAR          *acpi_gbl_exception_names_pgm[] =
@@ -206,6 +223,11 @@
 	"AE_AML_INVALID_SPACE_ID",
 	"AE_AML_STRING_LIMIT",
 	"AE_AML_NO_RETURN_VALUE",
+	"AE_AML_METHOD_LIMIT",
+	"AE_AML_NOT_OWNER",
+	"AE_AML_MUTEX_ORDER",
+	"AE_AML_MUTEX_NOT_ACQUIRED",
+	"AE_AML_INVALID_RESOURCE_TYPE",
 };
 
 static NATIVE_CHAR          *acpi_gbl_exception_names_ctrl[] =
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/acgcc.h linux/drivers/acpi/include/acgcc.h
--- v2.4.5/linux/drivers/acpi/include/acgcc.h	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/include/acgcc.h	Wed Dec 31 16:00:00 1969
@@ -1,147 +0,0 @@
-/******************************************************************************
- *
- * Name: acgcc.h - GCC specific defines, etc.
- *       $Revision: 5 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef __ACGCC_H__
-#define __ACGCC_H__
-
-
-#ifdef __ia64__
-#define _IA64
-
-#define COMPILER_DEPENDENT_UINT64   unsigned long
-/* Single threaded */
-#define ACPI_APPLICATION
-
-#define ACPI_ASM_MACROS
-#define causeinterrupt(level)
-#define BREAKPOINT3
-#define disable() __cli()
-#define enable()  __sti()
-#define wbinvd()
-
-/*! [Begin] no source code translation */
-
-#include <asm/pal.h>
-
-#define halt()              ia64_pal_halt_light()           /* PAL_HALT[_LIGHT] */
-#define safe_halt()         ia64_pal_halt(1)                /* PAL_HALT */
-
-
-#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
-	do { \
-	__asm__ volatile ("1:  ld4      r29=%1\n"  \
-		";;\n"                  \
-		"mov    ar.ccv=r29\n"   \
-		"mov    r2=r29\n"       \
-		"shr.u  r30=r29,1\n"    \
-		"and    r29=-4,r29\n"   \
-		";;\n"                  \
-		"add    r29=2,r29\n"    \
-		"and    r30=1,r30\n"    \
-		";;\n"                  \
-		"add    r29=r29,r30\n"  \
-		";;\n"                  \
-		"cmpxchg4.acq   r30=%1,r29,ar.ccv\n" \
-		";;\n"                  \
-		"cmp.eq p6,p7=r2,r30\n" \
-		"(p7) br.dpnt.few 1b\n" \
-		"cmp.gt p8,p9=3,r29\n"  \
-		";;\n"                  \
-		"(p8) mov %0=-1\n"      \
-		"(p9) mov %0=r0\n"      \
-		:"=r"(Acq):"m"(GLptr):"r2","r29","r30","memory"); \
-	} while (0)
-
-#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \
-	do { \
-	__asm__ volatile ("1:  ld4      r29=%1\n" \
-		";;\n"                  \
-		"mov    ar.ccv=r29\n"   \
-		"mov    r2=r29\n"       \
-		"and    r29=-4,r29\n"   \
-		";;\n"                  \
-		"cmpxchg4.acq   r30=%1,r29,ar.ccv\n" \
-		";;\n"                  \
-		"cmp.eq p6,p7=r2,r30\n" \
-		"(p7) br.dpnt.few 1b\n" \
-		"and    %0=1,r2\n"      \
-		";;\n"                  \
-		:"=r"(Acq):"m"(GLptr):"r2","r29","r30","memory"); \
-	} while (0)
-/*! [End] no source code translation !*/
-
-
-#else /* DO IA32 */
-#define COMPILER_DEPENDENT_UINT64   unsigned long long
-#define ACPI_ASM_MACROS
-#define causeinterrupt(level)
-#define BREAKPOINT3
-#define disable() __cli()
-#define enable()  __sti()
-#define halt()    __asm__ __volatile__ ("sti; hlt":::"memory")
-#define wbinvd()
-
-/*! [Begin] no source code translation
- *
- * A brief explanation as GNU inline assembly is a bit hairy
- *  %0 is the output parameter in EAX ("=a")
- *  %1 and %2 are the input parameters in ECX ("c")
- *  and an immediate value ("i") respectively
- *  All actual register references are preceded with "%%" as in "%%edx"
- *  Immediate values in the assembly are preceded by "$" as in "$0x1"
- *  The final asm parameter are the operation altered non-output registers.
- */
-#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
-	do { \
-		int dummy; \
-		asm("1:     movl (%1),%%eax;" \
-			"movl   %%eax,%%edx;" \
-			"andl   %2,%%edx;" \
-			"btsl   $0x1,%%edx;" \
-			"adcl   $0x0,%%edx;" \
-			"lock;  cmpxchgl %%edx,(%1);" \
-			"jnz    1b;" \
-			"cmpb   $0x3,%%dl;" \
-			"sbbl   %%eax,%%eax" \
-			:"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~1L):"dx"); \
-	} while(0)
-
-#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \
-	do { \
-		int dummy; \
-		asm("1:     movl (%1),%%eax;" \
-			"movl   %%eax,%%edx;" \
-			"andl   %2,%%edx;" \
-			"lock;  cmpxchgl %%edx,(%1);" \
-			"jnz    1b;" \
-			"andl   $0x1,%%eax" \
-			:"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~3L):"dx"); \
-	} while(0)
-
-/*! [End] no source code translation !*/
-
-#endif /* IA 32 */
-
-#endif /* __ACGCC_H__ */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/acglobal.h linux/drivers/acpi/include/acglobal.h
--- v2.4.5/linux/drivers/acpi/include/acglobal.h	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/include/acglobal.h	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acglobal.h - Declarations for global variables
- *       $Revision: 96 $
+ *       $Revision: 101 $
  *
  *****************************************************************************/
 
@@ -150,19 +150,19 @@
 
 ACPI_EXTERN u8                          acpi_gbl_debugger_configuration;
 ACPI_EXTERN u8                          acpi_gbl_global_lock_acquired;
-ACPI_EXTERN u8                          acpi_gbl_global_lock_set; /* TBD: [Restructure] OBSOLETE?? */
 ACPI_EXTERN u8                          acpi_gbl_step_to_next_call;
 ACPI_EXTERN u8                          acpi_gbl_acpi_hardware_present;
+ACPI_EXTERN u8                          acpi_gbl_global_lock_present;
 
 ACPI_EXTERN ACPI_OBJECT_NOTIFY_HANDLER  acpi_gbl_drv_notify;
 ACPI_EXTERN ACPI_OBJECT_NOTIFY_HANDLER  acpi_gbl_sys_notify;
 
 
-extern      u8                          acpi_gbl_shutdown;
-extern      u32                         acpi_gbl_system_flags;
-extern      u32                         acpi_gbl_startup_flags;
-extern      u8                          acpi_gbl_decode_to8bit[8];
-extern NATIVE_CHAR                      acpi_gbl_hex_to_ascii[];
+extern u8                               acpi_gbl_shutdown;
+extern u32                              acpi_gbl_system_flags;
+extern u32                              acpi_gbl_startup_flags;
+extern u8                               acpi_gbl_decode_to8bit[8];
+extern NATIVE_CHAR                      acpi_gbl_hex_to_ascii[16];
 
 
 /*****************************************************************************
@@ -178,15 +178,15 @@
 ACPI_EXTERN ACPI_NAMESPACE_NODE         acpi_gbl_root_node_struct;
 ACPI_EXTERN ACPI_NAMESPACE_NODE        *acpi_gbl_root_node;
 
-extern      u8                          acpi_gbl_ns_properties[NUM_NS_TYPES];
-extern      PREDEFINED_NAMES            acpi_gbl_pre_defined_names [NUM_PREDEFINED_NAMES];
+extern u8                               acpi_gbl_ns_properties[NUM_NS_TYPES];
+extern PREDEFINED_NAMES                 acpi_gbl_pre_defined_names [NUM_PREDEFINED_NAMES];
 
 
 /* Used to detect memory leaks (DEBUG ONLY) */
 
 #ifdef ACPI_DEBUG
-ACPI_EXTERN ALLOCATION_INFO            *acpi_gbl_head_alloc_ptr;
-ACPI_EXTERN ALLOCATION_INFO            *acpi_gbl_tail_alloc_ptr;
+ACPI_EXTERN ACPI_ALLOCATION_INFO        *acpi_gbl_head_alloc_ptr;
+ACPI_EXTERN ACPI_ALLOCATION_INFO        *acpi_gbl_tail_alloc_ptr;
 #endif
 
 
@@ -200,15 +200,9 @@
 ACPI_EXTERN ACPI_WALK_LIST             *acpi_gbl_current_walk_list;
 
 /*
- * Handle to the last method found - used during pass1 of load
- */
-ACPI_EXTERN ACPI_HANDLE                 acpi_gbl_last_method;
-
-/*
  * Table of Address Space handlers
  */
-
-ACPI_EXTERN ACPI_ADDRESS_SPACE_INFO     acpi_gbl_address_spaces[ACPI_NUM_ADDRESS_SPACES];
+ACPI_EXTERN ACPI_ADR_SPACE_INFO         acpi_gbl_address_spaces[ACPI_NUM_ADDRESS_SPACES];
 
 
 /* Control method single step flag */
@@ -240,7 +234,7 @@
  *
  ****************************************************************************/
 
-ACPI_EXTERN ACPI_FIXED_EVENT_INFO       acpi_gbl_fixed_event_handlers[NUM_FIXED_EVENTS];
+ACPI_EXTERN ACPI_FIXED_EVENT_INFO       acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS];
 
 ACPI_EXTERN ACPI_HANDLE                 acpi_gbl_gpe_obj_handle;
 ACPI_EXTERN u32                         acpi_gbl_gpe_register_count;
@@ -255,12 +249,12 @@
  * This table is needed because the GPE numbers supported by block 1 do not
  * have to be contiguous with the GPE numbers supported by block 0.
  */
-ACPI_EXTERN u8                          acpi_gbl_gpe_valid [NUM_GPE];
+ACPI_EXTERN u8                          acpi_gbl_gpe_valid [ACPI_NUM_GPE];
 
 /* Acpi_event counter for debug only */
 
 #ifdef ACPI_DEBUG
-ACPI_EXTERN u32                         acpi_gbl_event_count[NUM_FIXED_EVENTS];
+ACPI_EXTERN u32                         acpi_gbl_event_count[ACPI_NUM_FIXED_EVENTS];
 #endif
 
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/achware.h linux/drivers/acpi/include/achware.h
--- v2.4.5/linux/drivers/acpi/include/achware.h	Mon Jan 29 10:15:59 2001
+++ linux/drivers/acpi/include/achware.h	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: achware.h -- hardware specific interfaces
- *       $Revision: 53 $
+ *       $Revision: 55 $
  *
  *****************************************************************************/
 
@@ -82,14 +82,14 @@
 u32
 acpi_hw_low_level_read (
 	u32                     width,
-	ACPI_GAS                *reg,
+	ACPI_GENERIC_ADDRESS    *reg,
 	u32                     offset);
 
 void
 acpi_hw_low_level_write (
 	u32                     width,
 	u32                     value,
-	ACPI_GAS                *reg,
+	ACPI_GENERIC_ADDRESS    *reg,
 	u32                     offset);
 
 void
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/acinterp.h linux/drivers/acpi/include/acinterp.h
--- v2.4.5/linux/drivers/acpi/include/acinterp.h	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/include/acinterp.h	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acinterp.h - Interpreter subcomponent prototypes and defines
- *       $Revision: 92 $
+ *       $Revision: 102 $
  *
  *****************************************************************************/
 
@@ -48,7 +48,7 @@
 
 
 ACPI_STATUS
-acpi_aml_resolve_operands (
+acpi_ex_resolve_operands (
 	u16                     opcode,
 	ACPI_OPERAND_OBJECT     **stack_ptr,
 	ACPI_WALK_STATE         *walk_state);
@@ -59,11 +59,11 @@
  */
 
 ACPI_STATUS
-acpi_aml_load_table (
+acpi_ex_load_table (
 	ACPI_TABLE_TYPE         table_id);
 
 ACPI_STATUS
-acpi_aml_execute_method (
+acpi_ex_execute_method (
 	ACPI_NAMESPACE_NODE     *method_node,
 	ACPI_OPERAND_OBJECT     **params,
 	ACPI_OPERAND_OBJECT     **return_obj_desc);
@@ -74,23 +74,23 @@
  */
 
 ACPI_STATUS
-acpi_aml_convert_to_integer (
+acpi_ex_convert_to_integer (
 	ACPI_OPERAND_OBJECT     **obj_desc,
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_STATUS
-acpi_aml_convert_to_buffer (
+acpi_ex_convert_to_buffer (
 	ACPI_OPERAND_OBJECT     **obj_desc,
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_STATUS
-acpi_aml_convert_to_string (
+acpi_ex_convert_to_string (
 	ACPI_OPERAND_OBJECT     **obj_desc,
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_STATUS
-acpi_aml_convert_to_target_type (
-	OBJECT_TYPE_INTERNAL    destination_type,
+acpi_ex_convert_to_target_type (
+	ACPI_OBJECT_TYPE8       destination_type,
 	ACPI_OPERAND_OBJECT     **obj_desc,
 	ACPI_WALK_STATE         *walk_state);
 
@@ -100,110 +100,164 @@
  */
 
 ACPI_STATUS
-acpi_aml_read_field (
+acpi_ex_extract_from_field (
 	ACPI_OPERAND_OBJECT     *obj_desc,
 	void                    *buffer,
-	u32                     buffer_length,
-	u32                     byte_length,
-	u32                     datum_length,
-	u32                     bit_granularity,
-	u32                     byte_granularity);
+	u32                     buffer_length);
 
 ACPI_STATUS
-acpi_aml_write_field (
+acpi_ex_insert_into_field (
 	ACPI_OPERAND_OBJECT     *obj_desc,
 	void                    *buffer,
-	u32                     buffer_length,
-	u32                     byte_length,
-	u32                     datum_length,
-	u32                     bit_granularity,
-	u32                     byte_granularity);
+	u32                     buffer_length);
 
 ACPI_STATUS
-acpi_aml_setup_field (
+acpi_ex_setup_field (
 	ACPI_OPERAND_OBJECT     *obj_desc,
-	ACPI_OPERAND_OBJECT     *rgn_desc,
-	u32                     field_bit_width);
+	u32                     field_byte_offset);
 
 ACPI_STATUS
-acpi_aml_read_field_data (
+acpi_ex_read_field_datum (
 	ACPI_OPERAND_OBJECT     *obj_desc,
 	u32                     field_byte_offset,
-	u32                     field_bit_width,
 	u32                     *value);
 
 ACPI_STATUS
-acpi_aml_access_named_field (
+acpi_ex_common_access_field (
 	u32                     mode,
-	ACPI_HANDLE             named_field,
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	void                    *buffer,
+	u32                     buffer_length);
+
+
+ACPI_STATUS
+acpi_ex_access_index_field (
+	u32                     mode,
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	void                    *buffer,
+	u32                     buffer_length);
+
+ACPI_STATUS
+acpi_ex_access_bank_field (
+	u32                     mode,
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	void                    *buffer,
+	u32                     buffer_length);
+
+ACPI_STATUS
+acpi_ex_access_region_field (
+	u32                     mode,
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	void                    *buffer,
+	u32                     buffer_length);
+
+
+ACPI_STATUS
+acpi_ex_access_buffer_field (
+	u32                     mode,
+	ACPI_OPERAND_OBJECT     *obj_desc,
 	void                    *buffer,
-	u32                     length);
+	u32                     buffer_length);
+
+ACPI_STATUS
+acpi_ex_read_data_from_field (
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	ACPI_OPERAND_OBJECT     **ret_buffer_desc);
+
+ACPI_STATUS
+acpi_ex_write_data_to_field (
+	ACPI_OPERAND_OBJECT     *source_desc,
+	ACPI_OPERAND_OBJECT     *obj_desc);
 
 /*
  * ammisc - ACPI AML (p-code) execution - specific opcodes
  */
 
 ACPI_STATUS
-acpi_aml_exec_create_field (
+acpi_ex_create_buffer_field (
 	u8                      *aml_ptr,
 	u32                     aml_length,
 	ACPI_NAMESPACE_NODE     *node,
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_STATUS
-acpi_aml_exec_reconfiguration (
+acpi_ex_reconfiguration (
 	u16                     opcode,
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_STATUS
-acpi_aml_exec_fatal (
+acpi_ex_fatal (
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_STATUS
-acpi_aml_exec_index (
+acpi_ex_index (
 	ACPI_WALK_STATE         *walk_state,
 	ACPI_OPERAND_OBJECT     **return_desc);
 
 ACPI_STATUS
-acpi_aml_exec_match (
+acpi_ex_match (
 	ACPI_WALK_STATE         *walk_state,
 	ACPI_OPERAND_OBJECT     **return_desc);
 
 ACPI_STATUS
-acpi_aml_exec_create_mutex (
+acpi_ex_create_mutex (
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_STATUS
-acpi_aml_exec_create_processor (
+acpi_ex_create_processor (
 	ACPI_PARSE_OBJECT       *op,
-	ACPI_HANDLE             processor_nTE);
+	ACPI_NAMESPACE_NODE     *processor_node);
 
 ACPI_STATUS
-acpi_aml_exec_create_power_resource (
+acpi_ex_create_power_resource (
 	ACPI_PARSE_OBJECT       *op,
-	ACPI_HANDLE             processor_nTE);
+	ACPI_NAMESPACE_NODE     *power_node);
 
 ACPI_STATUS
-acpi_aml_exec_create_region (
+acpi_ex_create_region (
 	u8                      *aml_ptr,
-	u32                     acpi_aml_length,
+	u32                     aml_length,
 	u8                      region_space,
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_STATUS
-acpi_aml_exec_create_event (
+acpi_ex_create_event (
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_STATUS
-acpi_aml_exec_create_alias (
+acpi_ex_create_alias (
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_STATUS
-acpi_aml_exec_create_method (
+acpi_ex_create_method (
 	u8                      *aml_ptr,
-	u32                     acpi_aml_length,
+	u32                     aml_length,
 	u32                     method_flags,
-	ACPI_HANDLE             method);
+	ACPI_NAMESPACE_NODE     *method);
+
+
+/*
+ * ammutex - mutex support
+ */
+
+ACPI_STATUS
+acpi_ex_acquire_mutex (
+	ACPI_OPERAND_OBJECT     *time_desc,
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	ACPI_WALK_STATE         *walk_state);
+
+ACPI_STATUS
+acpi_ex_release_mutex (
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	ACPI_WALK_STATE         *walk_state);
+
+ACPI_STATUS
+acpi_ex_release_all_mutexes (
+	ACPI_OPERAND_OBJECT     *mutex_list);
+
+void
+acpi_ex_unlink_mutex (
+	ACPI_OPERAND_OBJECT     *obj_desc);
 
 
 /*
@@ -211,32 +265,36 @@
  */
 
 ACPI_STATUS
-acpi_aml_prep_def_field_value (
+acpi_ex_prep_common_field_object (
+	ACPI_OPERAND_OBJECT     *obj_desc,
+	u8                      field_flags,
+	u32                     field_position,
+	u32                     field_length);
+
+ACPI_STATUS
+acpi_ex_prep_region_field_value (
 	ACPI_NAMESPACE_NODE     *node,
 	ACPI_HANDLE             region,
 	u8                      field_flags,
-	u8                      field_attribute,
 	u32                     field_position,
 	u32                     field_length);
 
 ACPI_STATUS
-acpi_aml_prep_bank_field_value (
+acpi_ex_prep_bank_field_value (
 	ACPI_NAMESPACE_NODE     *node,
-	ACPI_HANDLE             region,
-	ACPI_HANDLE             bank_reg,
+	ACPI_NAMESPACE_NODE     *region_node,
+	ACPI_NAMESPACE_NODE     *bank_register_node,
 	u32                     bank_val,
 	u8                      field_flags,
-	u8                      field_attribute,
 	u32                     field_position,
 	u32                     field_length);
 
 ACPI_STATUS
-acpi_aml_prep_index_field_value (
+acpi_ex_prep_index_field_value (
 	ACPI_NAMESPACE_NODE     *node,
-	ACPI_HANDLE             index_reg,
-	ACPI_HANDLE             data_reg,
+	ACPI_NAMESPACE_NODE     *index_reg,
+	ACPI_NAMESPACE_NODE     *data_reg,
 	u8                      field_flags,
-	u8                      field_attribute,
 	u32                     field_position,
 	u32                     field_length);
 
@@ -245,47 +303,43 @@
  * amsystem - Interface to OS services
  */
 
-u16
-acpi_aml_system_thread_id (
-	void);
-
 ACPI_STATUS
-acpi_aml_system_do_notify_op (
+acpi_ex_system_do_notify_op (
 	ACPI_OPERAND_OBJECT     *value,
 	ACPI_OPERAND_OBJECT     *obj_desc);
 
 void
-acpi_aml_system_do_suspend(
+acpi_ex_system_do_suspend(
 	u32                     time);
 
 void
-acpi_aml_system_do_stall (
+acpi_ex_system_do_stall (
 	u32                     time);
 
 ACPI_STATUS
-acpi_aml_system_acquire_mutex(
+acpi_ex_system_acquire_mutex(
 	ACPI_OPERAND_OBJECT     *time,
 	ACPI_OPERAND_OBJECT     *obj_desc);
 
 ACPI_STATUS
-acpi_aml_system_release_mutex(
+acpi_ex_system_release_mutex(
 	ACPI_OPERAND_OBJECT     *obj_desc);
 
 ACPI_STATUS
-acpi_aml_system_signal_event(
+acpi_ex_system_signal_event(
 	ACPI_OPERAND_OBJECT     *obj_desc);
 
 ACPI_STATUS
-acpi_aml_system_wait_event(
+acpi_ex_system_wait_event(
 	ACPI_OPERAND_OBJECT     *time,
 	ACPI_OPERAND_OBJECT     *obj_desc);
 
 ACPI_STATUS
-acpi_aml_system_reset_event(
+acpi_ex_system_reset_event(
 	ACPI_OPERAND_OBJECT     *obj_desc);
 
 ACPI_STATUS
-acpi_aml_system_wait_semaphore (
+acpi_ex_system_wait_semaphore (
 	ACPI_HANDLE             semaphore,
 	u32                     timeout);
 
@@ -295,18 +349,18 @@
  */
 
 ACPI_STATUS
-acpi_aml_exec_monadic1 (
+acpi_ex_monadic1 (
 	u16                     opcode,
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_STATUS
-acpi_aml_exec_monadic2 (
+acpi_ex_monadic2 (
 	u16                     opcode,
 	ACPI_WALK_STATE         *walk_state,
 	ACPI_OPERAND_OBJECT     **return_desc);
 
 ACPI_STATUS
-acpi_aml_exec_monadic2_r (
+acpi_ex_monadic2_r (
 	u16                     opcode,
 	ACPI_WALK_STATE         *walk_state,
 	ACPI_OPERAND_OBJECT     **return_desc);
@@ -317,24 +371,24 @@
  */
 
 ACPI_STATUS
-acpi_aml_exec_dyadic1 (
+acpi_ex_dyadic1 (
 	u16                     opcode,
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_STATUS
-acpi_aml_exec_dyadic2 (
+acpi_ex_dyadic2 (
 	u16                     opcode,
 	ACPI_WALK_STATE         *walk_state,
 	ACPI_OPERAND_OBJECT     **return_desc);
 
 ACPI_STATUS
-acpi_aml_exec_dyadic2_r (
+acpi_ex_dyadic2_r (
 	u16                     opcode,
 	ACPI_WALK_STATE         *walk_state,
 	ACPI_OPERAND_OBJECT     **return_desc);
 
 ACPI_STATUS
-acpi_aml_exec_dyadic2_s (
+acpi_ex_dyadic2_s (
 	u16                     opcode,
 	ACPI_WALK_STATE         *walk_state,
 	ACPI_OPERAND_OBJECT     **return_desc);
@@ -345,22 +399,22 @@
  */
 
 ACPI_STATUS
-acpi_aml_resolve_to_value (
+acpi_ex_resolve_to_value (
 	ACPI_OPERAND_OBJECT     **stack_ptr,
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_STATUS
-acpi_aml_resolve_node_to_value (
+acpi_ex_resolve_node_to_value (
 	ACPI_NAMESPACE_NODE     **stack_ptr,
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_STATUS
-acpi_aml_resolve_object_to_value (
+acpi_ex_resolve_object_to_value (
 	ACPI_OPERAND_OBJECT     **stack_ptr,
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_STATUS
-acpi_aml_get_field_unit_value (
+acpi_ex_get_buffer_field_value (
 	ACPI_OPERAND_OBJECT     *field_desc,
 	ACPI_OPERAND_OBJECT     *result_desc);
 
@@ -370,18 +424,18 @@
  */
 
 void
-acpi_aml_show_hex_value (
+acpi_ex_show_hex_value (
 	u32                     byte_count,
 	u8                      *aml_ptr,
 	u32                     lead_space);
 
 
 ACPI_STATUS
-acpi_aml_dump_operand (
+acpi_ex_dump_operand (
 	ACPI_OPERAND_OBJECT     *entry_desc);
 
 void
-acpi_aml_dump_operands (
+acpi_ex_dump_operands (
 	ACPI_OPERAND_OBJECT     **operands,
 	OPERATING_MODE          interpreter_mode,
 	NATIVE_CHAR             *ident,
@@ -391,13 +445,13 @@
 	u32                     line_number);
 
 void
-acpi_aml_dump_object_descriptor (
+acpi_ex_dump_object_descriptor (
 	ACPI_OPERAND_OBJECT     *object,
 	u32                     flags);
 
 
 void
-acpi_aml_dump_node (
+acpi_ex_dump_node (
 	ACPI_NAMESPACE_NODE     *node,
 	u32                     flags);
 
@@ -407,28 +461,28 @@
  */
 
 NATIVE_CHAR *
-acpi_aml_allocate_name_string (
+acpi_ex_allocate_name_string (
 	u32                     prefix_count,
 	u32                     num_name_segs);
 
 u32
-acpi_aml_good_char (
+acpi_ex_good_char (
 	u32                     character);
 
 ACPI_STATUS
-acpi_aml_exec_name_segment (
+acpi_ex_name_segment (
 	u8                      **in_aml_address,
 	NATIVE_CHAR             *name_string);
 
 ACPI_STATUS
-acpi_aml_get_name_string (
-	OBJECT_TYPE_INTERNAL    data_type,
+acpi_ex_get_name_string (
+	ACPI_OBJECT_TYPE8       data_type,
 	u8                      *in_aml_address,
 	NATIVE_CHAR             **out_name_string,
 	u32                     *out_name_length);
 
 ACPI_STATUS
-acpi_aml_do_name (
+acpi_ex_do_name (
 	ACPI_OBJECT_TYPE        data_type,
 	OPERATING_MODE          load_exec_mode);
 
@@ -438,25 +492,25 @@
  */
 
 ACPI_STATUS
-acpi_aml_exec_store (
+acpi_ex_store (
 	ACPI_OPERAND_OBJECT     *val_desc,
 	ACPI_OPERAND_OBJECT     *dest_desc,
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_STATUS
-acpi_aml_store_object_to_index (
+acpi_ex_store_object_to_index (
 	ACPI_OPERAND_OBJECT     *val_desc,
 	ACPI_OPERAND_OBJECT     *dest_desc,
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_STATUS
-acpi_aml_store_object_to_node (
+acpi_ex_store_object_to_node (
 	ACPI_OPERAND_OBJECT     *source_desc,
 	ACPI_NAMESPACE_NODE     *node,
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_STATUS
-acpi_aml_store_object_to_object (
+acpi_ex_store_object_to_object (
 	ACPI_OPERAND_OBJECT     *source_desc,
 	ACPI_OPERAND_OBJECT     *dest_desc,
 	ACPI_WALK_STATE         *walk_state);
@@ -467,15 +521,15 @@
  */
 
 ACPI_STATUS
-acpi_aml_resolve_object (
+acpi_ex_resolve_object (
 	ACPI_OPERAND_OBJECT     **source_desc_ptr,
-	OBJECT_TYPE_INTERNAL    target_type,
+	ACPI_OBJECT_TYPE8       target_type,
 	ACPI_WALK_STATE         *walk_state);
 
 ACPI_STATUS
-acpi_aml_store_object (
+acpi_ex_store_object (
 	ACPI_OPERAND_OBJECT     *source_desc,
-	OBJECT_TYPE_INTERNAL    target_type,
+	ACPI_OBJECT_TYPE8       target_type,
 	ACPI_OPERAND_OBJECT     **target_desc_ptr,
 	ACPI_WALK_STATE         *walk_state);
 
@@ -485,32 +539,32 @@
  */
 
 ACPI_STATUS
-acpi_aml_copy_buffer_to_buffer (
+acpi_ex_copy_buffer_to_buffer (
 	ACPI_OPERAND_OBJECT     *source_desc,
 	ACPI_OPERAND_OBJECT     *target_desc);
 
 ACPI_STATUS
-acpi_aml_copy_string_to_string (
+acpi_ex_copy_string_to_string (
 	ACPI_OPERAND_OBJECT     *source_desc,
 	ACPI_OPERAND_OBJECT     *target_desc);
 
 ACPI_STATUS
-acpi_aml_copy_integer_to_index_field (
+acpi_ex_copy_integer_to_index_field (
 	ACPI_OPERAND_OBJECT     *source_desc,
 	ACPI_OPERAND_OBJECT     *target_desc);
 
 ACPI_STATUS
-acpi_aml_copy_integer_to_bank_field (
+acpi_ex_copy_integer_to_bank_field (
 	ACPI_OPERAND_OBJECT     *source_desc,
 	ACPI_OPERAND_OBJECT     *target_desc);
 
 ACPI_STATUS
-acpi_aml_copy_data_to_named_field (
+acpi_ex_copy_data_to_named_field (
 	ACPI_OPERAND_OBJECT     *source_desc,
 	ACPI_NAMESPACE_NODE     *node);
 
 ACPI_STATUS
-acpi_aml_copy_integer_to_field_unit (
+acpi_ex_copy_integer_to_buffer_field (
 	ACPI_OPERAND_OBJECT     *source_desc,
 	ACPI_OPERAND_OBJECT     *target_desc);
 
@@ -518,43 +572,43 @@
  * amutils - interpreter/scanner utilities
  */
 
-void
-acpi_aml_enter_interpreter (
+ACPI_STATUS
+acpi_ex_enter_interpreter (
 	void);
 
 void
-acpi_aml_exit_interpreter (
+acpi_ex_exit_interpreter (
 	void);
 
 void
-acpi_aml_truncate_for32bit_table (
+acpi_ex_truncate_for32bit_table (
 	ACPI_OPERAND_OBJECT     *obj_desc,
 	ACPI_WALK_STATE         *walk_state);
 
 u8
-acpi_aml_validate_object_type (
+acpi_ex_validate_object_type (
 	ACPI_OBJECT_TYPE        type);
 
 u8
-acpi_aml_acquire_global_lock (
+acpi_ex_acquire_global_lock (
 	u32                     rule);
 
 ACPI_STATUS
-acpi_aml_release_global_lock (
+acpi_ex_release_global_lock (
 	u8                      locked);
 
 u32
-acpi_aml_digits_needed (
+acpi_ex_digits_needed (
 	ACPI_INTEGER            value,
 	u32                     base);
 
 ACPI_STATUS
-acpi_aml_eisa_id_to_string (
+acpi_ex_eisa_id_to_string (
 	u32                     numeric_id,
 	NATIVE_CHAR             *out_string);
 
 ACPI_STATUS
-acpi_aml_unsigned_integer_to_string (
+acpi_ex_unsigned_integer_to_string (
 	ACPI_INTEGER            value,
 	NATIVE_CHAR             *out_string);
 
@@ -564,7 +618,7 @@
  */
 
 ACPI_STATUS
-acpi_aml_system_memory_space_handler (
+acpi_ex_system_memory_space_handler (
 	u32                     function,
 	ACPI_PHYSICAL_ADDRESS   address,
 	u32                     bit_width,
@@ -573,7 +627,7 @@
 	void                    *region_context);
 
 ACPI_STATUS
-acpi_aml_system_io_space_handler (
+acpi_ex_system_io_space_handler (
 	u32                     function,
 	ACPI_PHYSICAL_ADDRESS   address,
 	u32                     bit_width,
@@ -582,7 +636,7 @@
 	void                    *region_context);
 
 ACPI_STATUS
-acpi_aml_pci_config_space_handler (
+acpi_ex_pci_config_space_handler (
 	u32                     function,
 	ACPI_PHYSICAL_ADDRESS   address,
 	u32                     bit_width,
@@ -591,7 +645,7 @@
 	void                    *region_context);
 
 ACPI_STATUS
-acpi_aml_embedded_controller_space_handler (
+acpi_ex_embedded_controller_space_handler (
 	u32                     function,
 	ACPI_PHYSICAL_ADDRESS   address,
 	u32                     bit_width,
@@ -600,7 +654,7 @@
 	void                    *region_context);
 
 ACPI_STATUS
-acpi_aml_sm_bus_space_handler (
+acpi_ex_sm_bus_space_handler (
 	u32                     function,
 	ACPI_PHYSICAL_ADDRESS   address,
 	u32                     bit_width,
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/aclinux.h linux/drivers/acpi/include/aclinux.h
--- v2.4.5/linux/drivers/acpi/include/aclinux.h	Fri Feb 16 16:06:17 2001
+++ linux/drivers/acpi/include/aclinux.h	Wed Dec 31 16:00:00 1969
@@ -1,55 +0,0 @@
-/******************************************************************************
- *
- * Name: aclinux.h - OS specific defines, etc.
- *       $Revision: 9 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef __ACLINUX_H__
-#define __ACLINUX_H__
-
-#define ACPI_OS_NAME                "Linux"
-
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/ctype.h>
-#include <asm/system.h>
-#include <asm/atomic.h>
-#include <asm/div64.h>
-
-/* Linux uses GCC */
-
-#include "acgcc.h"
-
-#undef DEBUGGER_THREADING
-#define DEBUGGER_THREADING          DEBUGGER_SINGLE_THREADED
-
-#ifndef _IA64
-/* Linux ia32 can't do int64 well */
-#define ACPI_NO_INTEGER64_SUPPORT
-/* And the ia32 kernel doesn't include 64-bit divide support */
-#define ACPI_DIV64(dividend, divisor) do_div(dividend, divisor)
-#else
-#define ACPI_DIV64(dividend, divisor) ACPI_DIVIDE(dividend, divisor)
-#endif
-
-
-#endif /* __ACLINUX_H__ */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/aclocal.h linux/drivers/acpi/include/aclocal.h
--- v2.4.5/linux/drivers/acpi/include/aclocal.h	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/include/aclocal.h	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: aclocal.h - Internal data types used across the ACPI subsystem
- *       $Revision: 104 $
+ *       $Revision: 123 $
  *
  *****************************************************************************/
 
@@ -27,20 +27,24 @@
 #define __ACLOCAL_H__
 
 
-#define WAIT_FOREVER                ((u32) -1)
+#define WAIT_FOREVER                    ((u32) -1)
 
-typedef void*                       ACPI_MUTEX;
-typedef u32                         ACPI_MUTEX_HANDLE;
+typedef void*                           ACPI_MUTEX;
+typedef u32                             ACPI_MUTEX_HANDLE;
 
 
+#define ACPI_MEMORY_MODE                0x01
+#define ACPI_LOGICAL_ADDRESSING         0x00
+#define ACPI_PHYSICAL_ADDRESSING        0x01
+
 /* Object descriptor types */
 
-#define ACPI_CACHED_OBJECT          0x11    /* ORed in when object is cached */
-#define ACPI_DESC_TYPE_STATE        0x22
-#define ACPI_DESC_TYPE_WALK         0x44
-#define ACPI_DESC_TYPE_PARSER       0x66
-#define ACPI_DESC_TYPE_INTERNAL     0x88
-#define ACPI_DESC_TYPE_NAMED        0xAA
+#define ACPI_CACHED_OBJECT              0x11    /* ORed in when object is cached */
+#define ACPI_DESC_TYPE_STATE            0x22
+#define ACPI_DESC_TYPE_WALK             0x44
+#define ACPI_DESC_TYPE_PARSER           0x66
+#define ACPI_DESC_TYPE_INTERNAL         0x88
+#define ACPI_DESC_TYPE_NAMED            0xAA
 
 
 /*****************************************************************************
@@ -52,26 +56,30 @@
 
 /*
  * Predefined handles for the mutex objects used within the subsystem
- * All mutex objects are automatically created by Acpi_cm_mutex_initialize.
+ * All mutex objects are automatically created by Acpi_ut_mutex_initialize.
+ *
+ * The acquire/release ordering protocol is implied via this list.  Mutexes
+ * with a lower value must be acquired before mutexes with a higher value.
+ *
  * NOTE: any changes here must be reflected in the Acpi_gbl_Mutex_names table also!
  */
 
-#define ACPI_MTX_HARDWARE           0
-#define ACPI_MTX_MEMORY             1
-#define ACPI_MTX_CACHES             2
-#define ACPI_MTX_TABLES             3
-#define ACPI_MTX_PARSER             4
-#define ACPI_MTX_DISPATCHER         5
-#define ACPI_MTX_INTERPRETER        6
-#define ACPI_MTX_EXECUTE            7
-#define ACPI_MTX_NAMESPACE          8
-#define ACPI_MTX_EVENTS             9
-#define ACPI_MTX_OP_REGIONS         10
-#define ACPI_MTX_DEBUG_CMD_READY    11
-#define ACPI_MTX_DEBUG_CMD_COMPLETE 12
+#define ACPI_MTX_EXECUTE                0
+#define ACPI_MTX_INTERPRETER            1
+#define ACPI_MTX_PARSER                 2
+#define ACPI_MTX_DISPATCHER             3
+#define ACPI_MTX_TABLES                 4
+#define ACPI_MTX_OP_REGIONS             5
+#define ACPI_MTX_NAMESPACE              6
+#define ACPI_MTX_EVENTS                 7
+#define ACPI_MTX_HARDWARE               8
+#define ACPI_MTX_CACHES                 9
+#define ACPI_MTX_MEMORY                 10
+#define ACPI_MTX_DEBUG_CMD_COMPLETE     11
+#define ACPI_MTX_DEBUG_CMD_READY        12
 
-#define MAX_MTX                     12
-#define NUM_MTX                     MAX_MTX+1
+#define MAX_MTX                         12
+#define NUM_MTX                         MAX_MTX+1
 
 
 #if defined(ACPI_DEBUG) || defined(ENABLE_DEBUGGER)
@@ -81,19 +89,19 @@
 
 static NATIVE_CHAR          *acpi_gbl_mutex_names[] =
 {
-	"ACPI_MTX_Hardware",
-	"ACPI_MTX_Memory",
-	"ACPI_MTX_Caches",
-	"ACPI_MTX_Tables",
+	"ACPI_MTX_Execute",
+	"ACPI_MTX_Interpreter",
 	"ACPI_MTX_Parser",
 	"ACPI_MTX_Dispatcher",
-	"ACPI_MTX_Interpreter",
-	"ACPI_MTX_Execute",
+	"ACPI_MTX_Tables",
+	"ACPI_MTX_Op_regions",
 	"ACPI_MTX_Namespace",
 	"ACPI_MTX_Events",
-	"ACPI_MTX_Op_regions",
+	"ACPI_MTX_Hardware",
+	"ACPI_MTX_Caches",
+	"ACPI_MTX_Memory",
+	"ACPI_MTX_Debug_cmd_complete",
 	"ACPI_MTX_Debug_cmd_ready",
-	"ACPI_MTX_Debug_cmd_complete"
 };
 
 #endif
@@ -106,26 +114,38 @@
 {
 	ACPI_MUTEX                  mutex;
 	u32                         use_count;
-	u8                          locked;
+	u32                         owner_id;
 
 } ACPI_MUTEX_INFO;
 
+/* This owner ID means that the mutex is not in use (unlocked) */
+
+#define ACPI_MUTEX_NOT_ACQUIRED         (u32) (-1)
+
 
 /* Lock flag parameter for various interfaces */
 
-#define ACPI_MTX_DO_NOT_LOCK        0
-#define ACPI_MTX_LOCK               1
+#define ACPI_MTX_DO_NOT_LOCK            0
+#define ACPI_MTX_LOCK                   1
 
 
-typedef u16                         ACPI_OWNER_ID;
-#define OWNER_TYPE_TABLE            0x0
-#define OWNER_TYPE_METHOD           0x1
-#define FIRST_METHOD_ID             0x0000
-#define FIRST_TABLE_ID              0x8000
+typedef u16                             ACPI_OWNER_ID;
+#define OWNER_TYPE_TABLE                0x0
+#define OWNER_TYPE_METHOD               0x1
+#define FIRST_METHOD_ID                 0x0000
+#define FIRST_TABLE_ID                  0x8000
 
 /* TBD: [Restructure] get rid of the need for this! */
 
-#define TABLE_ID_DSDT               (ACPI_OWNER_ID) 0x8000
+#define TABLE_ID_DSDT                   (ACPI_OWNER_ID) 0x8000
+
+
+/* Field access granularities */
+
+#define ACPI_FIELD_BYTE_GRANULARITY     1
+#define ACPI_FIELD_WORD_GRANULARITY     2
+#define ACPI_FIELD_DWORD_GRANULARITY    4
+#define ACPI_FIELD_QWORD_GRANULARITY    8
 
 /*****************************************************************************
  *
@@ -175,13 +195,15 @@
 
 /* Node flags */
 
-#define ANOBJ_AML_ATTACHMENT        0x01
-#define ANOBJ_END_OF_PEER_LIST      0x02
-#define ANOBJ_DATA_WIDTH_32         0x04     /* Parent table is 64-bits */
-#define ANOBJ_METHOD_ARG            0x08
-#define ANOBJ_METHOD_LOCAL          0x10
-#define ANOBJ_METHOD_NO_RETVAL      0x20
-#define ANOBJ_METHOD_SOME_NO_RETVAL 0x40
+#define ANOBJ_AML_ATTACHMENT            0x01
+#define ANOBJ_END_OF_PEER_LIST          0x02
+#define ANOBJ_DATA_WIDTH_32             0x04     /* Parent table is 64-bits */
+#define ANOBJ_METHOD_ARG                0x08
+#define ANOBJ_METHOD_LOCAL              0x10
+#define ANOBJ_METHOD_NO_RETVAL          0x20
+#define ANOBJ_METHOD_SOME_NO_RETVAL     0x40
+
+#define ANOBJ_IS_BIT_OFFSET             0x80
 
 
 /*
@@ -225,19 +247,36 @@
 /*
  * Predefined Namespace items
  */
-#define ACPI_MAX_ADDRESS_SPACE      255
-#define ACPI_NUM_ADDRESS_SPACES     256
-
-
 typedef struct
 {
 	NATIVE_CHAR             *name;
-	ACPI_OBJECT_TYPE        type;
+	ACPI_OBJECT_TYPE8       type;
 	NATIVE_CHAR             *val;
 
 } PREDEFINED_NAMES;
 
 
+/* Object types used during package copies */
+
+
+#define ACPI_COPY_TYPE_SIMPLE           0
+#define ACPI_COPY_TYPE_PACKAGE          1
+
+/* Info structure used to convert external<->internal namestrings */
+
+typedef struct acpi_namestring_info
+{
+	NATIVE_CHAR             *external_name;
+	NATIVE_CHAR             *next_external_char;
+	NATIVE_CHAR             *internal_name;
+	u32                     length;
+	u32                     num_segments;
+	u32                     num_carats;
+	u8                      fully_qualified;
+
+} ACPI_NAMESTRING_INFO;
+
+
 /*****************************************************************************
  *
  * Event typedefs and structs
@@ -247,19 +286,19 @@
 
 /* Status bits. */
 
-#define ACPI_STATUS_PMTIMER                  0x0001
-#define ACPI_STATUS_GLOBAL                   0x0020
-#define ACPI_STATUS_POWER_BUTTON             0x0100
-#define ACPI_STATUS_SLEEP_BUTTON             0x0200
-#define ACPI_STATUS_RTC_ALARM                0x0400
+#define ACPI_STATUS_PMTIMER             0x0001
+#define ACPI_STATUS_GLOBAL              0x0020
+#define ACPI_STATUS_POWER_BUTTON        0x0100
+#define ACPI_STATUS_SLEEP_BUTTON        0x0200
+#define ACPI_STATUS_RTC_ALARM           0x0400
 
 /* Enable bits. */
 
-#define ACPI_ENABLE_PMTIMER                  0x0001
-#define ACPI_ENABLE_GLOBAL                   0x0020
-#define ACPI_ENABLE_POWER_BUTTON             0x0100
-#define ACPI_ENABLE_SLEEP_BUTTON             0x0200
-#define ACPI_ENABLE_RTC_ALARM                0x0400
+#define ACPI_ENABLE_PMTIMER             0x0001
+#define ACPI_ENABLE_GLOBAL              0x0020
+#define ACPI_ENABLE_POWER_BUTTON        0x0100
+#define ACPI_ENABLE_SLEEP_BUTTON        0x0200
+#define ACPI_ENABLE_RTC_ALARM           0x0400
 
 
 /*
@@ -268,10 +307,10 @@
 
 typedef struct
 {
-	ADDRESS_SPACE_HANDLER   handler;
+	ACPI_ADR_SPACE_HANDLER  handler;
 	void                    *context;
 
-} ACPI_ADDRESS_SPACE_INFO;
+} ACPI_ADR_SPACE_INFO;
 
 
 /* Values and addresses of the GPE registers (both banks) */
@@ -287,8 +326,8 @@
 } ACPI_GPE_REGISTERS;
 
 
-#define ACPI_GPE_LEVEL_TRIGGERED            1
-#define ACPI_GPE_EDGE_TRIGGERED             2
+#define ACPI_GPE_LEVEL_TRIGGERED        1
+#define ACPI_GPE_EDGE_TRIGGERED         2
 
 
 /* Information about each particular GPE level */
@@ -298,7 +337,7 @@
 	u8                      type;           /* Level or Edge */
 
 	ACPI_HANDLE             method_handle;  /* Method handle for direct (fast) execution */
-	GPE_HANDLER             handler;        /* Address of handler, if any */
+	ACPI_GPE_HANDLER        handler;        /* Address of handler, if any */
 	void                    *context;       /* Context to be passed to handler */
 
 } ACPI_GPE_LEVEL_INFO;
@@ -308,7 +347,7 @@
 
 typedef struct
 {
-	FIXED_EVENT_HANDLER     handler;        /* Address of handler. */
+	ACPI_EVENT_HANDLER      handler;        /* Address of handler. */
 	void                    *context;       /* Context to be passed to handler */
 
 } ACPI_FIXED_EVENT_INFO;
@@ -332,16 +371,18 @@
  ****************************************************************************/
 
 
-#define CONTROL_NORMAL                        0xC0
-#define CONTROL_CONDITIONAL_EXECUTING         0xC1
-#define CONTROL_PREDICATE_EXECUTING           0xC2
-#define CONTROL_PREDICATE_FALSE               0xC3
-#define CONTROL_PREDICATE_TRUE                0xC4
+#define CONTROL_NORMAL                  0xC0
+#define CONTROL_CONDITIONAL_EXECUTING   0xC1
+#define CONTROL_PREDICATE_EXECUTING     0xC2
+#define CONTROL_PREDICATE_FALSE         0xC3
+#define CONTROL_PREDICATE_TRUE          0xC4
 
 
-/* Forward declaration */
+/* Forward declarations */
 struct acpi_walk_state;
-struct acpi_parse_obj ;
+struct acpi_walk_list;
+struct acpi_parse_obj;
+struct acpi_obj_mutex;
 
 
 #define ACPI_STATE_COMMON                  /* Two 32-bit fields and a pointer */\
@@ -401,7 +442,6 @@
 /*
  * Scope state - current scope during namespace lookups
  */
-
 typedef struct acpi_scope_state
 {
 	ACPI_STATE_COMMON
@@ -436,6 +476,19 @@
 } ACPI_RESULT_VALUES;
 
 
+/*
+ * Notify info - used to pass info to the deferred notify
+ * handler/dispatcher.
+ */
+typedef struct acpi_notify_info
+{
+	ACPI_STATE_COMMON
+	ACPI_NAMESPACE_NODE     *node;
+	union acpi_operand_obj  *handler_obj;
+
+} ACPI_NOTIFY_INFO;
+
+
 /* Generic state is union of structs above */
 
 typedef union acpi_gen_state
@@ -447,6 +500,7 @@
 	ACPI_PSCOPE_STATE       parse_scope;
 	ACPI_PKG_STATE          pkg;
 	ACPI_RESULT_VALUES      results;
+	ACPI_NOTIFY_INFO        notify;
 
 } ACPI_GENERIC_STATE;
 
@@ -470,19 +524,18 @@
  *
  ****************************************************************************/
 
-
-#define ACPI_OP_CLASS_MASK          0x1F
-#define ACPI_OP_ARGS_MASK           0x20
-#define ACPI_OP_TYPE_MASK           0xC0
-
-#define ACPI_OP_TYPE_OPCODE         0x00
-#define ACPI_OP_TYPE_ASCII          0x40
-#define ACPI_OP_TYPE_PREFIX         0x80
-#define ACPI_OP_TYPE_UNKNOWN        0xC0
-
-#define ACPI_GET_OP_CLASS(a)        ((a)->flags & ACPI_OP_CLASS_MASK)
-#define ACPI_GET_OP_ARGS(a)         ((a)->flags & ACPI_OP_ARGS_MASK)
-#define ACPI_GET_OP_TYPE(a)         ((a)->flags & ACPI_OP_TYPE_MASK)
+#define ACPI_OP_CLASS_MASK              0x1F
+#define ACPI_OP_ARGS_MASK               0x20
+#define ACPI_OP_TYPE_MASK               0xC0
+
+#define ACPI_OP_TYPE_OPCODE             0x00
+#define ACPI_OP_TYPE_ASCII              0x40
+#define ACPI_OP_TYPE_PREFIX             0x80
+#define ACPI_OP_TYPE_UNKNOWN            0xC0
+
+#define ACPI_GET_OP_CLASS(a)            ((a)->flags & ACPI_OP_CLASS_MASK)
+#define ACPI_GET_OP_ARGS(a)             ((a)->flags & ACPI_OP_ARGS_MASK)
+#define ACPI_GET_OP_TYPE(a)             ((a)->flags & ACPI_OP_TYPE_MASK)
 
 
 /*
@@ -572,130 +625,6 @@
 
 /*****************************************************************************
  *
- * Tree walking typedefs and structs
- *
- ****************************************************************************/
-
-
-/*
- * Walk state - current state of a parse tree walk.  Used for both a leisurely stroll through
- * the tree (for whatever reason), and for control method execution.
- */
-
-#define NEXT_OP_DOWNWARD    1
-#define NEXT_OP_UPWARD      2
-
-#define WALK_NON_METHOD     0
-#define WALK_METHOD         1
-#define WALK_METHOD_RESTART 2
-
-typedef struct acpi_walk_state
-{
-	u8                      data_type;                          /* To differentiate various internal objs */\
-	ACPI_OWNER_ID           owner_id;                           /* Owner of objects created during the walk */
-	u8                      last_predicate;                     /* Result of last predicate */
-	u8                      next_op_info;                       /* Info about Next_op */
-	u8                      num_operands;                       /* Stack pointer for Operands[] array */
-	u8                      current_result;                     /* */
-
-	struct acpi_walk_state  *next;                              /* Next Walk_state in list */
-	ACPI_PARSE_OBJECT       *origin;                            /* Start of walk [Obsolete] */
-
-/* TBD: Obsolete with removal of WALK procedure ? */
-	ACPI_PARSE_OBJECT       *prev_op;                           /* Last op that was processed */
-	ACPI_PARSE_OBJECT       *next_op;                           /* next op to be processed */
-
-
-	ACPI_GENERIC_STATE      *results;                           /* Stack of accumulated results */
-	ACPI_GENERIC_STATE      *control_state;                     /* List of control states (nested IFs) */
-	ACPI_GENERIC_STATE      *scope_info;                        /* Stack of nested scopes */
-	ACPI_PARSE_STATE        *parser_state;                      /* Current state of parser */
-	u8                      *aml_last_while;
-	ACPI_OPCODE_INFO        *op_info;                           /* Info on current opcode */
-	ACPI_PARSE_DOWNWARDS    descending_callback;
-	ACPI_PARSE_UPWARDS      ascending_callback;
-
-	union acpi_operand_obj  *return_desc;                       /* Return object, if any */
-	union acpi_operand_obj  *method_desc;                       /* Method descriptor if running a method */
-	struct acpi_node        *method_node;                       /* Method Node if running a method */
-	ACPI_PARSE_OBJECT       *method_call_op;                    /* Method_call Op if running a method */
-	struct acpi_node        *method_call_node;                  /* Called method Node*/
-	union acpi_operand_obj  *operands[OBJ_NUM_OPERANDS];        /* Operands passed to the interpreter */
-	struct acpi_node        arguments[MTH_NUM_ARGS];            /* Control method arguments */
-	struct acpi_node        local_variables[MTH_NUM_LOCALS];    /* Control method locals */
-	u32                     parse_flags;
-	u8                      walk_type;
-	u8                      return_used;
-	u16                     opcode;                             /* Current AML opcode */
-	u32                     prev_arg_types;
-
-	/* Debug support */
-
-	u32                     method_breakpoint;
-
-
-} ACPI_WALK_STATE;
-
-
-/*
- * Walk list - head of a tree of walk states.  Multiple walk states are created when there
- * are nested control methods executing.
- */
-typedef struct acpi_walk_list
-{
-
-	ACPI_WALK_STATE         *walk_state;
-
-} ACPI_WALK_LIST;
-
-
-/* Info used by Acpi_ps_init_objects */
-
-typedef struct acpi_init_walk_info
-{
-	u16                     method_count;
-	u16                     op_region_count;
-	u16                     field_count;
-	u16                     op_region_init;
-	u16                     field_init;
-	u16                     object_count;
-	ACPI_TABLE_DESC         *table_desc;
-
-} ACPI_INIT_WALK_INFO;
-
-
-/* Info used by TBD */
-
-typedef struct acpi_device_walk_info
-{
-	u16                     device_count;
-	u16                     num_STA;
-	u16                     num_INI;
-	ACPI_TABLE_DESC         *table_desc;
-
-} ACPI_DEVICE_WALK_INFO;
-
-
-/* TBD: [Restructure] Merge with struct above */
-
-typedef struct acpi_walk_info
-{
-	u32                     debug_level;
-	u32                     owner_id;
-
-} ACPI_WALK_INFO;
-
-typedef struct acpi_get_devices_info
-{
-	WALK_CALLBACK           user_function;
-	void                    *context;
-	NATIVE_CHAR             *hid;
-
-} ACPI_GET_DEVICES_INFO;
-
-
-/*****************************************************************************
- *
  * Hardware and PNP
  *
  ****************************************************************************/
@@ -703,20 +632,20 @@
 
 /* PCI */
 
-#define PCI_ROOT_HID_STRING         "PNP0A03"
-#define PCI_ROOT_HID_VALUE          0x030AD041       /* EISAID("PNP0A03") */
+#define PCI_ROOT_HID_STRING             "PNP0A03"
+#define PCI_ROOT_HID_VALUE              0x030AD041       /* EISAID("PNP0A03") */
 
 
 /* Sleep states */
 
-#define SLWA_DEBUG_LEVEL            4
-#define GTS_CALL                    0
-#define GTS_WAKE                    1
+#define SLWA_DEBUG_LEVEL                4
+#define GTS_CALL                        0
+#define GTS_WAKE                        1
 
 /* Cx States */
 
-#define MAX_CX_STATE_LATENCY        0xFFFFFFFF
-#define MAX_CX_STATES               4
+#define MAX_CX_STATE_LATENCY            0xFFFFFFFF
+#define MAX_CX_STATES                   4
 
 
 /*
@@ -725,13 +654,13 @@
  * values as they are used in switch statements and offset calculations.
  */
 
-#define REGISTER_BLOCK_MASK         0xFF00  /* Register Block Id    */
-#define BIT_IN_REGISTER_MASK        0x00FF  /* Bit Id in the Register Block Id    */
-#define BYTE_IN_REGISTER_MASK       0x00FF  /* Register Offset in the Register Block    */
-
-#define REGISTER_BLOCK_ID(reg_id)   (reg_id & REGISTER_BLOCK_MASK)
-#define REGISTER_BIT_ID(reg_id)     (reg_id & BIT_IN_REGISTER_MASK)
-#define REGISTER_OFFSET(reg_id)     (reg_id & BYTE_IN_REGISTER_MASK)
+#define REGISTER_BLOCK_MASK             0xFF00  /* Register Block Id    */
+#define BIT_IN_REGISTER_MASK            0x00FF  /* Bit Id in the Register Block Id    */
+#define BYTE_IN_REGISTER_MASK           0x00FF  /* Register Offset in the Register Block    */
+
+#define REGISTER_BLOCK_ID(reg_id)       (reg_id & REGISTER_BLOCK_MASK)
+#define REGISTER_BIT_ID(reg_id)         (reg_id & BIT_IN_REGISTER_MASK)
+#define REGISTER_OFFSET(reg_id)         (reg_id & BYTE_IN_REGISTER_MASK)
 
 /*
  * Access Rule
@@ -746,94 +675,94 @@
 /*
  * Register Block Id
  */
-#define PM1_STS                     0x0100
-#define PM1_EN                      0x0200
-#define PM1_CONTROL                 0x0300
-#define PM1_a_CONTROL               0x0400
-#define PM1_b_CONTROL               0x0500
-#define PM2_CONTROL                 0x0600
-#define PM_TIMER                    0x0700
-#define PROCESSOR_BLOCK             0x0800
-#define GPE0_STS_BLOCK              0x0900
-#define GPE0_EN_BLOCK               0x0A00
-#define GPE1_STS_BLOCK              0x0B00
-#define GPE1_EN_BLOCK               0x0C00
-#define SMI_CMD_BLOCK               0x0D00
+#define PM1_STS                         0x0100
+#define PM1_EN                          0x0200
+#define PM1_CONTROL                     0x0300
+#define PM1_a_CONTROL                   0x0400
+#define PM1_b_CONTROL                   0x0500
+#define PM2_CONTROL                     0x0600
+#define PM_TIMER                        0x0700
+#define PROCESSOR_BLOCK                 0x0800
+#define GPE0_STS_BLOCK                  0x0900
+#define GPE0_EN_BLOCK                   0x0A00
+#define GPE1_STS_BLOCK                  0x0B00
+#define GPE1_EN_BLOCK                   0x0C00
+#define SMI_CMD_BLOCK                   0x0D00
 
 /*
  * Address space bitmasks for mmio or io spaces
  */
 
-#define SMI_CMD_ADDRESS_SPACE       0x01
-#define PM1_BLK_ADDRESS_SPACE       0x02
-#define PM2_CNT_BLK_ADDRESS_SPACE   0x04
-#define PM_TMR_BLK_ADDRESS_SPACE    0x08
-#define GPE0_BLK_ADDRESS_SPACE      0x10
-#define GPE1_BLK_ADDRESS_SPACE      0x20
+#define SMI_CMD_ADDRESS_SPACE           0x01
+#define PM1_BLK_ADDRESS_SPACE           0x02
+#define PM2_CNT_BLK_ADDRESS_SPACE       0x04
+#define PM_TMR_BLK_ADDRESS_SPACE        0x08
+#define GPE0_BLK_ADDRESS_SPACE          0x10
+#define GPE1_BLK_ADDRESS_SPACE          0x20
 
 /*
  * Control bit definitions
  */
-#define TMR_STS                     (PM1_STS | 0x01)
-#define BM_STS                      (PM1_STS | 0x02)
-#define GBL_STS                     (PM1_STS | 0x03)
-#define PWRBTN_STS                  (PM1_STS | 0x04)
-#define SLPBTN_STS                  (PM1_STS | 0x05)
-#define RTC_STS                     (PM1_STS | 0x06)
-#define WAK_STS                     (PM1_STS | 0x07)
-
-#define TMR_EN                      (PM1_EN | 0x01)
-			   /* no BM_EN */
-#define GBL_EN                      (PM1_EN | 0x03)
-#define PWRBTN_EN                   (PM1_EN | 0x04)
-#define SLPBTN_EN                   (PM1_EN | 0x05)
-#define RTC_EN                      (PM1_EN | 0x06)
-#define WAK_EN                      (PM1_EN | 0x07)
-
-#define SCI_EN                      (PM1_CONTROL | 0x01)
-#define BM_RLD                      (PM1_CONTROL | 0x02)
-#define GBL_RLS                     (PM1_CONTROL | 0x03)
-#define SLP_TYPE_A                  (PM1_CONTROL | 0x04)
-#define SLP_TYPE_B                  (PM1_CONTROL | 0x05)
-#define SLP_EN                      (PM1_CONTROL | 0x06)
-
-#define ARB_DIS                     (PM2_CONTROL | 0x01)
-
-#define TMR_VAL                     (PM_TIMER | 0x01)
-
-#define GPE0_STS                    (GPE0_STS_BLOCK | 0x01)
-#define GPE0_EN                     (GPE0_EN_BLOCK  | 0x01)
-
-#define GPE1_STS                    (GPE1_STS_BLOCK | 0x01)
-#define GPE1_EN                     (GPE1_EN_BLOCK  | 0x01)
-
-
-#define TMR_STS_MASK                0x0001
-#define BM_STS_MASK                 0x0010
-#define GBL_STS_MASK                0x0020
-#define PWRBTN_STS_MASK             0x0100
-#define SLPBTN_STS_MASK             0x0200
-#define RTC_STS_MASK                0x0400
-#define WAK_STS_MASK                0x8000
-
-#define ALL_FIXED_STS_BITS          (TMR_STS_MASK   | BM_STS_MASK  | GBL_STS_MASK \
-					 | PWRBTN_STS_MASK | SLPBTN_STS_MASK \
-					 | RTC_STS_MASK | WAK_STS_MASK)
-
-#define TMR_EN_MASK                 0x0001
-#define GBL_EN_MASK                 0x0020
-#define PWRBTN_EN_MASK              0x0100
-#define SLPBTN_EN_MASK              0x0200
-#define RTC_EN_MASK                 0x0400
-
-#define SCI_EN_MASK                 0x0001
-#define BM_RLD_MASK                 0x0002
-#define GBL_RLS_MASK                0x0004
-#define SLP_TYPE_X_MASK             0x1C00
-#define SLP_EN_MASK                 0x2000
+#define TMR_STS                         (PM1_STS | 0x01)
+#define BM_STS                          (PM1_STS | 0x02)
+#define GBL_STS                         (PM1_STS | 0x03)
+#define PWRBTN_STS                      (PM1_STS | 0x04)
+#define SLPBTN_STS                      (PM1_STS | 0x05)
+#define RTC_STS                         (PM1_STS | 0x06)
+#define WAK_STS                         (PM1_STS | 0x07)
+
+#define TMR_EN                          (PM1_EN | 0x01)
+			 /* no BM_EN */
+#define GBL_EN                          (PM1_EN | 0x03)
+#define PWRBTN_EN                       (PM1_EN | 0x04)
+#define SLPBTN_EN                       (PM1_EN | 0x05)
+#define RTC_EN                          (PM1_EN | 0x06)
+#define WAK_EN                          (PM1_EN | 0x07)
+
+#define SCI_EN                          (PM1_CONTROL | 0x01)
+#define BM_RLD                          (PM1_CONTROL | 0x02)
+#define GBL_RLS                         (PM1_CONTROL | 0x03)
+#define SLP_TYPE_A                      (PM1_CONTROL | 0x04)
+#define SLP_TYPE_B                      (PM1_CONTROL | 0x05)
+#define SLP_EN                          (PM1_CONTROL | 0x06)
+
+#define ARB_DIS                         (PM2_CONTROL | 0x01)
+
+#define TMR_VAL                         (PM_TIMER | 0x01)
+
+#define GPE0_STS                        (GPE0_STS_BLOCK | 0x01)
+#define GPE0_EN                         (GPE0_EN_BLOCK  | 0x01)
+
+#define GPE1_STS                        (GPE1_STS_BLOCK | 0x01)
+#define GPE1_EN                         (GPE1_EN_BLOCK  | 0x01)
+
+
+#define TMR_STS_MASK                    0x0001
+#define BM_STS_MASK                     0x0010
+#define GBL_STS_MASK                    0x0020
+#define PWRBTN_STS_MASK                 0x0100
+#define SLPBTN_STS_MASK                 0x0200
+#define RTC_STS_MASK                    0x0400
+#define WAK_STS_MASK                    0x8000
+
+#define ALL_FIXED_STS_BITS              (TMR_STS_MASK   | BM_STS_MASK  | GBL_STS_MASK \
+					  | PWRBTN_STS_MASK | SLPBTN_STS_MASK \
+					  | RTC_STS_MASK | WAK_STS_MASK)
+
+#define TMR_EN_MASK                     0x0001
+#define GBL_EN_MASK                     0x0020
+#define PWRBTN_EN_MASK                  0x0100
+#define SLPBTN_EN_MASK                  0x0200
+#define RTC_EN_MASK                     0x0400
+
+#define SCI_EN_MASK                     0x0001
+#define BM_RLD_MASK                     0x0002
+#define GBL_RLS_MASK                    0x0004
+#define SLP_TYPE_X_MASK                 0x1C00
+#define SLP_EN_MASK                     0x2000
 
-#define ARB_DIS_MASK                0x0001
-#define TMR_VAL_MASK                0xFFFFFFFF
+#define ARB_DIS_MASK                    0x0001
+#define TMR_VAL_MASK                    0xFFFFFFFF
 
 #define GPE0_STS_MASK
 #define GPE0_EN_MASK
@@ -842,55 +771,87 @@
 #define GPE1_EN_MASK
 
 
-#define ACPI_READ                   1
-#define ACPI_WRITE                  2
+#define ACPI_READ                       1
+#define ACPI_WRITE                      2
+
+
+/*****************************************************************************
+ *
+ * Resource descriptors
+ *
+ ****************************************************************************/
+
+
+/* Resource_type values */
+
+#define RESOURCE_TYPE_MEMORY_RANGE              0
+#define RESOURCE_TYPE_IO_RANGE                  1
+#define RESOURCE_TYPE_BUS_NUMBER_RANGE          2
+
+/* Resource descriptor types and masks */
+
+#define RESOURCE_DESC_TYPE_LARGE                0x80
+#define RESOURCE_DESC_TYPE_SMALL                0x00
+
+#define RESOURCE_DESC_TYPE_MASK                 0x80
+#define RESOURCE_DESC_SMALL_MASK                0x78        /* Only bits 6:3 contain the type */
 
 
-/* Plug and play */
+/*
+ * Small resource descriptor types
+ * Note: The 3 length bits (2:0) must be zero
+ */
+#define RESOURCE_DESC_IRQ_FORMAT                0x20
+#define RESOURCE_DESC_DMA_FORMAT                0x28
+#define RESOURCE_DESC_START_DEPENDENT           0x30
+#define RESOURCE_DESC_END_DEPENDENT             0x38
+#define RESOURCE_DESC_IO_PORT                   0x40
+#define RESOURCE_DESC_FIXED_IO_PORT             0x48
+#define RESOURCE_DESC_SMALL_VENDOR              0x70
+#define RESOURCE_DESC_END_TAG                   0x78
+
+/*
+ * Large resource descriptor types
+ */
 
-/* Pnp and ACPI data */
+#define RESOURCE_DESC_MEMORY_24                 0x81
+#define RESOURCE_DESC_GENERAL_REGISTER          0x82
+#define RESOURCE_DESC_LARGE_VENDOR              0x84
+#define RESOURCE_DESC_MEMORY_32                 0x85
+#define RESOURCE_DESC_FIXED_MEMORY_32           0x86
+#define RESOURCE_DESC_DWORD_ADDRESS_SPACE       0x87
+#define RESOURCE_DESC_WORD_ADDRESS_SPACE        0x88
+#define RESOURCE_DESC_EXTENDED_XRUPT            0x89
+#define RESOURCE_DESC_QWORD_ADDRESS_SPACE       0x8A
 
-#define VERSION_NO                      0x01
-#define LOGICAL_DEVICE_ID               0x02
-#define COMPATIBLE_DEVICE_ID            0x03
-#define IRQ_FORMAT                      0x04
-#define DMA_FORMAT                      0x05
-#define START_DEPENDENT_TAG             0x06
-#define END_DEPENDENT_TAG               0x07
-#define IO_PORT_DESCRIPTOR              0x08
-#define FIXED_LOCATION_IO_DESCRIPTOR    0x09
-#define RESERVED_TYPE0                  0x0A
-#define RESERVED_TYPE1                  0x0B
-#define RESERVED_TYPE2                  0x0C
-#define RESERVED_TYPE3                  0x0D
-#define SMALL_VENDOR_DEFINED            0x0E
-#define END_TAG                         0x0F
-
-/* Pnp and ACPI data */
-
-#define MEMORY_RANGE_24                 0x81
-#define ISA_MEMORY_RANGE                0x81
-#define LARGE_VENDOR_DEFINED            0x84
-#define EISA_MEMORY_RANGE               0x85
-#define MEMORY_RANGE_32                 0x85
-#define FIXED_EISA_MEMORY_RANGE         0x86
-#define FIXED_MEMORY_RANGE_32           0x86
-
-/* ACPI only data */
-
-#define DWORD_ADDRESS_SPACE             0x87
-#define WORD_ADDRESS_SPACE              0x88
-#define EXTENDED_IRQ                    0x89
 
-/* MUST HAVES */
+/* String version of device HIDs and UIDs */
 
-#define DEVICE_ID_LENGTH                0x09
+#define ACPI_DEVICE_ID_LENGTH                   0x09
 
 typedef struct
 {
-		NATIVE_CHAR         buffer[DEVICE_ID_LENGTH];
+	NATIVE_CHAR             buffer[ACPI_DEVICE_ID_LENGTH];
+
+} ACPI_DEVICE_ID;
+
+
+/*****************************************************************************
+ *
+ * Debugger
+ *
+ ****************************************************************************/
+
+typedef struct dbmethodinfo
+{
+	ACPI_HANDLE             thread_gate;
+	NATIVE_CHAR             *name;
+	NATIVE_CHAR             **args;
+	u32                     flags;
+	u32                     num_loops;
+	NATIVE_CHAR             pathname[128];
 
-} DEVICE_ID;
+} DB_METHOD_INFO;
 
 
 /*****************************************************************************
@@ -904,22 +865,22 @@
 
 #ifdef ACPI_DEBUG
 
-#define MEM_MALLOC          0
-#define MEM_CALLOC          1
-#define MAX_MODULE_NAME     16
-
-typedef struct allocation_info
-{
-	struct allocation_info  *previous;
-	struct allocation_info  *next;
-	void                    *address;
-	u32                     size;
-	u32                     component;
-	u32                     line;
-	NATIVE_CHAR             module[MAX_MODULE_NAME];
-	u8                      alloc_type;
+#define MEM_MALLOC                      0
+#define MEM_CALLOC                      1
+#define MAX_MODULE_NAME                 16
+
+typedef struct acpi_allocation_info
+{
+	struct acpi_allocation_info *previous;
+	struct acpi_allocation_info *next;
+	void                        *address;
+	u32                         size;
+	u32                         component;
+	u32                         line;
+	NATIVE_CHAR                 module[MAX_MODULE_NAME];
+	u8                          alloc_type;
 
-} ALLOCATION_INFO;
+} ACPI_ALLOCATION_INFO;
 
 #endif
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/acmacros.h linux/drivers/acpi/include/acmacros.h
--- v2.4.5/linux/drivers/acpi/include/acmacros.h	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/include/acmacros.h	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acmacros.h - C macros for the entire subsystem.
- *       $Revision: 62 $
+ *       $Revision: 72 $
  *
  *****************************************************************************/
 
@@ -88,12 +88,18 @@
 #define ACPI_STORE_ADDRESS(a,b)         ((a)=(b))
 #define ACPI_VALID_ADDRESS(a)           (a)
 #endif
+
  /*
   * Extract a byte of data using a pointer.  Any more than a byte and we
   * get into potential aligment issues -- see the STORE macros below
   */
 #define GET8(addr)                      (*(u8*)(addr))
 
+/* Pointer arithmetic */
+
+
+#define POINTER_ADD(t,a,b)              (t *) ((NATIVE_UINT)(a) + (NATIVE_UINT)(b))
+#define POINTER_DIFF(a,b)               ((u32) ((NATIVE_UINT)(a) - (NATIVE_UINT)(b)))
 
 /*
  * Macros for moving data around to/from buffers that are possibly unaligned.
@@ -108,6 +114,7 @@
 #define MOVE_UNALIGNED16_TO_16(d,s)     *(u16*)(d) = *(u16*)(s)
 #define MOVE_UNALIGNED32_TO_32(d,s)     *(u32*)(d) = *(u32*)(s)
 #define MOVE_UNALIGNED16_TO_32(d,s)     *(u32*)(d) = *(u16*)(s)
+#define MOVE_UNALIGNED64_TO_64(d,s)     *(UINT64*)(d) = *(UINT64*)(s)
 
 #else
 /*
@@ -126,6 +133,15 @@
 
 #define MOVE_UNALIGNED16_TO_32(d,s)     {(*(u32*)(d)) = 0; MOVE_UNALIGNED16_TO_16(d,s);}
 
+#define MOVE_UNALIGNED64_TO_64(d,s)     {((u8 *)(d))[0] = ((u8 *)(s))[0];\
+					   ((u8 *)(d))[1] = ((u8 *)(s))[1];\
+					   ((u8 *)(d))[2] = ((u8 *)(s))[2];\
+					   ((u8 *)(d))[3] = ((u8 *)(s))[3];\
+					   ((u8 *)(d))[4] = ((u8 *)(s))[4];\
+					   ((u8 *)(d))[5] = ((u8 *)(s))[5];\
+					   ((u8 *)(d))[6] = ((u8 *)(s))[6];\
+					   ((u8 *)(d))[7] = ((u8 *)(s))[7];}
+
 #endif
 
 
@@ -177,8 +193,26 @@
 #define ROUND_PTR_UP_TO_4(a,b)          ((b *)(((NATIVE_UINT)(a) + 3) & ~3))
 #define ROUND_PTR_UP_TO_8(a,b)          ((b *)(((NATIVE_UINT)(a) + 7) & ~7))
 
+#define ROUND_BITS_UP_TO_BYTES(a)       DIV_8((a) + 7)
+#define ROUND_BITS_DOWN_TO_BYTES(a)     DIV_8((a))
+
 #define ROUND_UP_TO_1_k(a)              (((a) + 1023) >> 10)
 
+/* Generic (non-power-of-two) rounding */
+
+#define ROUND_UP_TO(value,boundary)     (((value) + ((boundary)-1)) / (boundary))
+
+/*
+ * Bitmask creation
+ * Bit positions start at zero.
+ * MASK_BITS_ABOVE creates a mask starting AT the position and above
+ * MASK_BITS_BELOW creates a mask starting one bit BELOW the position
+ */
+
+
+#define MASK_BITS_ABOVE(position)       (~(((u32)(-1)) << ((u32) (position))))
+#define MASK_BITS_BELOW(position)       (((u32)(-1)) << ((u32) (position)))
+
 #ifdef DEBUG_ASSERT
 #undef DEBUG_ASSERT
 #endif
@@ -222,6 +256,10 @@
 
 #define IS_SINGLE_TABLE(x)              (((x) & 0x01) == ACPI_TABLE_SINGLE ? 1 : 0)
 
+/* Check if ACPI has been initialized properly */
+
+#define ACPI_IS_INITIALIZATION_COMPLETE(s)  {if (acpi_gbl_root_node) s = AE_OK; else s=AE_NO_NAMESPACE;}
+
 /*
  * Macro to check if a pointer is within an ACPI table.
  * Parameter (a) is the pointer to check.  Parameter (b) must be defined
@@ -231,12 +269,12 @@
 
 #ifndef _IA16
 #define IS_IN_ACPI_TABLE(a,b)           (((u8 *)(a) >= (u8 *)(b + 1)) &&\
-					  ((u8 *)(a) < ((u8 *)b + b->length)))
+							   ((u8 *)(a) < ((u8 *)b + b->length)))
 
 #else
 #define IS_IN_ACPI_TABLE(a,b)           (_segment)(a) == (_segment)(b) &&\
-							   (((u8 *)(a) >= (u8 *)(b + 1)) &&\
-							   ((u8 *)(a) < ((u8 *)b + b->length)))
+									 (((u8 *)(a) >= (u8 *)(b + 1)) &&\
+									 ((u8 *)(a) < ((u8 *)b + b->length)))
 #endif
 
 /*
@@ -276,6 +314,26 @@
 
 
 /*
+ * Build a GAS structure from earlier ACPI table entries (V1.0 and 0.71 extensions)
+ *
+ * 1) Address space
+ * 2) Length in bytes -- convert to length in bits
+ * 3) Bit offset is zero
+ * 4) Reserved field is zero
+ * 5) Expand address to 64 bits
+ */
+#define ASL_BUILD_GAS_FROM_ENTRY(a,b,c,d)   {a.address_space_id = (u8) d;\
+											 a.register_bit_width = (u8) MUL_8 (b);\
+											 a.register_bit_offset = 0;\
+											 a.reserved = 0;\
+											 ACPI_STORE_ADDRESS (a.address,c);}
+
+/* ACPI V1.0 entries -- address space is always I/O */
+
+#define ASL_BUILD_GAS_FROM_V1_ENTRY(a,b,c)  ASL_BUILD_GAS_FROM_ENTRY(a,b,c,ACPI_ADR_SPACE_SYSTEM_IO)
+
+
+/*
  * Reporting macros that are never compiled out
  */
 
@@ -290,7 +348,7 @@
 #ifdef ACPI_DEBUG
 
 #define REPORT_INFO(fp)                 {_report_info(_THIS_MODULE,__LINE__,_COMPONENT); \
-									  debug_print_raw PARAM_LIST(fp);}
+											debug_print_raw PARAM_LIST(fp);}
 #define REPORT_ERROR(fp)                {_report_error(_THIS_MODULE,__LINE__,_COMPONENT); \
 											debug_print_raw PARAM_LIST(fp);}
 #define REPORT_WARNING(fp)              {_report_warning(_THIS_MODULE,__LINE__,_COMPONENT); \
@@ -318,7 +376,7 @@
 
 /* Buffer dump macros */
 
-#define DUMP_BUFFER(a,b)                acpi_cm_dump_buffer((u8 *)a,b,DB_BYTE_DISPLAY,_COMPONENT)
+#define DUMP_BUFFER(a,b)                acpi_ut_dump_buffer((u8 *)a,b,DB_BYTE_DISPLAY,_COMPONENT)
 
 /*
  * Debug macros that are conditionally compiled
@@ -334,6 +392,7 @@
  * as a local string ("_Proc_name) so that it can be also used by the function exit macros below.
  */
 
+#define PROC_NAME(a)                    char * _proc_name = a;
 #define FUNCTION_TRACE(a)               char * _proc_name = a;\
 										function_trace(_THIS_MODULE,__LINE__,_COMPONENT,a)
 #define FUNCTION_TRACE_PTR(a,b)         char * _proc_name = a;\
@@ -351,7 +410,7 @@
  */
 #define return_VOID                     {function_exit(_THIS_MODULE,__LINE__,_COMPONENT,_proc_name);return;}
 #define return_ACPI_STATUS(s)           {function_status_exit(_THIS_MODULE,__LINE__,_COMPONENT,_proc_name,s);return(s);}
-#define return_VALUE(s)                 {function_value_exit(_THIS_MODULE,__LINE__,_COMPONENT,_proc_name,(ACPI_INTEGER)s);return(s);}
+#define return_VALUE(s)                 {function_value_exit(_THIS_MODULE,__LINE__,_COMPONENT,_proc_name,s);return(s);}
 #define return_PTR(s)                   {function_ptr_exit(_THIS_MODULE,__LINE__,_COMPONENT,_proc_name,(u8 *)s);return(s);}
 
 
@@ -368,8 +427,8 @@
 
 /* Stack and buffer dumping */
 
-#define DUMP_STACK_ENTRY(a)             acpi_aml_dump_operand(a)
-#define DUMP_OPERANDS(a,b,c,d,e)        acpi_aml_dump_operands(a,b,c,d,e,_THIS_MODULE,__LINE__)
+#define DUMP_STACK_ENTRY(a)             acpi_ex_dump_operand(a)
+#define DUMP_OPERANDS(a,b,c,d,e)        acpi_ex_dump_operands(a,b,c,d,e,_THIS_MODULE,__LINE__)
 
 
 #define DUMP_ENTRY(a,b)                 acpi_ns_dump_entry (a,b)
@@ -404,6 +463,12 @@
 											debug_print_raw PARAM_LIST(fp);\
 											BREAK_ON_ERROR(lvl);}
 
+#define DEBUG_PRINTP(lvl,fp)            TEST_DEBUG_SWITCH(lvl) {\
+											debug_print_prefix (_THIS_MODULE,__LINE__);\
+											debug_print_raw ("%s: ",_proc_name);\
+											debug_print_raw PARAM_LIST(fp);\
+											BREAK_ON_ERROR(lvl);}
+
 #define DEBUG_PRINT_RAW(lvl,fp)         TEST_DEBUG_SWITCH(lvl) {\
 											debug_print_raw PARAM_LIST(fp);}
 
@@ -431,6 +496,7 @@
 
 #define DEBUG_DEFINE(a)
 #define DEBUG_ONLY_MEMBERS(a)
+#define PROC_NAME(a)
 #define FUNCTION_TRACE(a)
 #define FUNCTION_TRACE_PTR(a,b)
 #define FUNCTION_TRACE_U32(a,b)
@@ -445,6 +511,7 @@
 #define DUMP_PATHNAME(a,b,c,d)
 #define DUMP_RESOURCE_LIST(a)
 #define DEBUG_PRINT(l,f)
+#define DEBUG_PRINTP(l,f)
 #define DEBUG_PRINT_RAW(l,f)
 #define BREAK_MSG(a)
 
@@ -496,6 +563,75 @@
 #define ADD_OBJECT_NAME(a,b)
 
 #endif
+
+
+/*
+ * Memory allocation tracking (DEBUG ONLY)
+ */
+
+#ifndef ACPI_DEBUG_TRACK_ALLOCATIONS
+
+#define acpi_ut_add_element_to_alloc_list(a,b,c,d,e,f)
+#define acpi_ut_delete_element_from_alloc_list(a,b,c,d)
+#define acpi_ut_dump_current_allocations(a,b)
+#define acpi_ut_dump_allocation_info()
+
+#define DECREMENT_OBJECT_METRICS(a)
+#define INCREMENT_OBJECT_METRICS(a)
+#define INITIALIZE_ALLOCATION_METRICS()
+#define DECREMENT_NAME_TABLE_METRICS(a)
+#define INCREMENT_NAME_TABLE_METRICS(a)
+
+#else
+
+#define INITIALIZE_ALLOCATION_METRICS() \
+	acpi_gbl_current_object_count = 0; \
+	acpi_gbl_current_object_size = 0; \
+	acpi_gbl_running_object_count = 0; \
+	acpi_gbl_running_object_size = 0; \
+	acpi_gbl_max_concurrent_object_count = 0; \
+	acpi_gbl_max_concurrent_object_size = 0; \
+	acpi_gbl_current_alloc_size = 0; \
+	acpi_gbl_current_alloc_count = 0; \
+	acpi_gbl_running_alloc_size = 0; \
+	acpi_gbl_running_alloc_count = 0; \
+	acpi_gbl_max_concurrent_alloc_size = 0; \
+	acpi_gbl_max_concurrent_alloc_count = 0; \
+	acpi_gbl_current_node_count = 0; \
+	acpi_gbl_current_node_size = 0; \
+	acpi_gbl_max_concurrent_node_count = 0
+
+
+#define DECREMENT_OBJECT_METRICS(a) \
+	acpi_gbl_current_object_count--; \
+	acpi_gbl_current_object_size -= a
+
+#define INCREMENT_OBJECT_METRICS(a) \
+	acpi_gbl_current_object_count++; \
+	acpi_gbl_running_object_count++; \
+	if (acpi_gbl_max_concurrent_object_count < acpi_gbl_current_object_count) \
+	{ \
+		acpi_gbl_max_concurrent_object_count = acpi_gbl_current_object_count; \
+	} \
+	acpi_gbl_running_object_size += a; \
+	acpi_gbl_current_object_size += a; \
+	if (acpi_gbl_max_concurrent_object_size < acpi_gbl_current_object_size) \
+	{ \
+		acpi_gbl_max_concurrent_object_size = acpi_gbl_current_object_size; \
+	}
+
+#define DECREMENT_NAME_TABLE_METRICS(a) \
+	acpi_gbl_current_node_count--; \
+	acpi_gbl_current_node_size -= (a)
+
+#define INCREMENT_NAME_TABLE_METRICS(a) \
+	acpi_gbl_current_node_count++; \
+	acpi_gbl_current_node_size+= (a); \
+	if (acpi_gbl_max_concurrent_node_count < acpi_gbl_current_node_count) \
+	{ \
+		acpi_gbl_max_concurrent_node_count = acpi_gbl_current_node_count; \
+	}
+#endif /* ACPI_DEBUG_TRACK_ALLOCATIONS */
 
 
 #endif /* ACMACROS_H */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/acnamesp.h linux/drivers/acpi/include/acnamesp.h
--- v2.4.5/linux/drivers/acpi/include/acnamesp.h	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/include/acnamesp.h	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acnamesp.h - Namespace subcomponent prototypes and defines
- *       $Revision: 103 $
+ *       $Revision: 106 $
  *
  *****************************************************************************/
 
@@ -94,18 +94,18 @@
 
 ACPI_STATUS
 acpi_ns_walk_namespace (
-	OBJECT_TYPE_INTERNAL    type,
+	ACPI_OBJECT_TYPE8       type,
 	ACPI_HANDLE             start_object,
 	u32                     max_depth,
 	u8                      unlock_before_callback,
-	WALK_CALLBACK           user_function,
+	ACPI_WALK_CALLBACK      user_function,
 	void                    *context,
 	void                    **return_value);
 
 
 ACPI_NAMESPACE_NODE *
 acpi_ns_get_next_object (
-	OBJECT_TYPE_INTERNAL    type,
+	ACPI_OBJECT_TYPE8       type,
 	ACPI_NAMESPACE_NODE     *parent,
 	ACPI_NAMESPACE_NODE     *child);
 
@@ -150,7 +150,7 @@
 acpi_ns_lookup (
 	ACPI_GENERIC_STATE      *scope_info,
 	NATIVE_CHAR             *name,
-	OBJECT_TYPE_INTERNAL    type,
+	ACPI_OBJECT_TYPE8       type,
 	OPERATING_MODE          interpreter_mode,
 	u32                     flags,
 	ACPI_WALK_STATE         *walk_state,
@@ -223,7 +223,7 @@
 
 void
 acpi_ns_dump_objects (
-	OBJECT_TYPE_INTERNAL    type,
+	ACPI_OBJECT_TYPE8       type,
 	u32                     max_depth,
 	u32                     ownder_id,
 	ACPI_HANDLE             start_handle);
@@ -283,7 +283,7 @@
 
 u32
 acpi_ns_opens_scope (
-	OBJECT_TYPE_INTERNAL    type);
+	ACPI_OBJECT_TYPE8       type);
 
 NATIVE_CHAR *
 acpi_ns_get_table_pathname (
@@ -304,12 +304,6 @@
 	ACPI_NAMESPACE_NODE     *obj_node,
 	NATIVE_CHAR             *search_for);
 
-ACPI_STATUS
-acpi_ns_name_compare (
-	ACPI_HANDLE             obj_handle,
-	u32                     level,
-	void                    *context,
-	void                    **return_value);
 
 ACPI_STATUS
 acpi_ns_get_node (
@@ -330,14 +324,7 @@
 acpi_ns_attach_object (
 	ACPI_NAMESPACE_NODE     *node,
 	ACPI_OPERAND_OBJECT     *object,
-	OBJECT_TYPE_INTERNAL    type);
-
-
-void *
-acpi_ns_compare_value (
-	ACPI_HANDLE             obj_handle,
-	u32                     level,
-	void                    *obj_desc);
+	ACPI_OBJECT_TYPE8       type);
 
 
 /*
@@ -350,7 +337,7 @@
 	ACPI_WALK_STATE         *walk_state,
 	ACPI_NAMESPACE_NODE     *node,
 	OPERATING_MODE          interpreter_mode,
-	OBJECT_TYPE_INTERNAL    type,
+	ACPI_OBJECT_TYPE8       type,
 	u32                     flags,
 	ACPI_NAMESPACE_NODE     **ret_node);
 
@@ -358,7 +345,7 @@
 acpi_ns_search_node (
 	u32                     entry_name,
 	ACPI_NAMESPACE_NODE     *node,
-	OBJECT_TYPE_INTERNAL    type,
+	ACPI_OBJECT_TYPE8       type,
 	ACPI_NAMESPACE_NODE     **ret_node);
 
 void
@@ -366,7 +353,7 @@
 	ACPI_WALK_STATE         *walk_state,
 	ACPI_NAMESPACE_NODE     *parent_node,   /* Parent */
 	ACPI_NAMESPACE_NODE     *node,      /* New Child*/
-	OBJECT_TYPE_INTERNAL    type);
+	ACPI_OBJECT_TYPE8       type);
 
 
 /*
@@ -381,17 +368,25 @@
 acpi_ns_valid_path_separator (
 	NATIVE_CHAR             sep);
 
-OBJECT_TYPE_INTERNAL
+ACPI_OBJECT_TYPE8
 acpi_ns_get_type (
-	ACPI_HANDLE             obj_handle);
+	ACPI_NAMESPACE_NODE     *node);
 
 void *
 acpi_ns_get_attached_object (
-	ACPI_HANDLE             obj_handle);
+	ACPI_NAMESPACE_NODE     *node);
 
 u32
 acpi_ns_local (
-	OBJECT_TYPE_INTERNAL    type);
+	ACPI_OBJECT_TYPE8       type);
+
+ACPI_STATUS
+acpi_ns_build_internal_name (
+	ACPI_NAMESTRING_INFO    *info);
+
+ACPI_STATUS
+acpi_ns_get_internal_name_length (
+	ACPI_NAMESTRING_INFO    *info);
 
 ACPI_STATUS
 acpi_ns_internalize_name (
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/acobject.h linux/drivers/acpi/include/acobject.h
--- v2.4.5/linux/drivers/acpi/include/acobject.h	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/include/acobject.h	Wed Jun 20 17:47:40 2001
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Name: acobject.h - Definition of ACPI_OPERAND_OBJECT  (Internal object only)
- *       $Revision: 78 $
+ *       $Revision: 89 $
  *
  *****************************************************************************/
 
@@ -58,7 +58,7 @@
  */
 
 
-#define ACPI_OBJECT_COMMON_HEADER           /* 32-bits plus 8-bit flag */\
+#define ACPI_OBJECT_COMMON_HEADER           /* SIZE/ALIGNMENT: 32-bits plus trailing 8-bit flag */\
 	u8                          data_type;          /* To differentiate various internal objs */\
 	u8                          type;               /* ACPI_OBJECT_TYPE */\
 	u16                         reference_count;    /* For object deletion management */\
@@ -73,16 +73,27 @@
 
 /*
  * Common bitfield for the field objects
+ * "Field Datum"    -- a datum from the actual field object
+ * "Buffer Datum"   -- a datum from a user buffer, read from or to be written to the field
  */
-#define ACPI_COMMON_FIELD_INFO              /* Three 32-bit values plus 8*/\
-	u8                          granularity;\
-	u16                         length; \
-	u32                         offset;             /* Byte offset within containing object */\
-	u8                          bit_offset;         /* Bit offset within min read/write data unit */\
-	u8                          access;             /* Access_type */\
-	u8                          lock_rule;\
-	u8                          update_rule;\
-	u8                          access_attribute;
+#define ACPI_COMMON_FIELD_INFO              /* SIZE/ALIGNMENT: 24 bits + three 32-bit values */\
+	u8                          access_flags;\
+	u16                         bit_length;         /* Length of field in bits */\
+	u32                         base_byte_offset;   /* Byte offset within containing object */\
+	u8                          access_bit_width;   /* Read/Write size in bits (from ASL Access_type)*/\
+	u8                          access_byte_width;  /* Read/Write size in bytes */\
+	u8                          update_rule;        /* How neighboring field bits are handled */\
+	u8                          lock_rule;          /* Global Lock: 1 = "Must Lock" */\
+	u8                          start_field_bit_offset;/* Bit offset within first field datum (0-63) */\
+	u8                          datum_valid_bits;   /* Valid bit in first "Field datum" */\
+	u8                          end_field_valid_bits; /* Valid bits in the last "field datum" */\
+	u8                          end_buffer_valid_bits; /* Valid bits in the last "buffer datum" */\
+	u32                         value;              /* Value to store into the Bank or Index register */
+
+
+/* Access flag bits */
+
+#define AFIELD_SINGLE_DATUM         0x1
 
 
 /******************************************************************************
@@ -121,7 +132,7 @@
 	ACPI_OBJECT_COMMON_HEADER
 
 	u32                         length;
-	NATIVE_CHAR                 *pointer;       /* String value in AML stream or in allocated space */
+	NATIVE_CHAR                 *pointer;           /* String value in AML stream or in allocated space */
 
 } ACPI_OBJECT_STRING;
 
@@ -131,7 +142,7 @@
 	ACPI_OBJECT_COMMON_HEADER
 
 	u32                         length;
-	u8                          *pointer;       /* points to the buffer in allocated space */
+	u8                          *pointer;           /* points to the buffer in allocated space */
 
 } ACPI_OBJECT_BUFFER;
 
@@ -140,27 +151,14 @@
 {
 	ACPI_OBJECT_COMMON_HEADER
 
-	u32                         count;          /* # of elements in package */
+	u32                         count;              /* # of elements in package */
 
-	union acpi_operand_obj      **elements;     /* Array of pointers to Acpi_objects */
-	union acpi_operand_obj      **next_element; /* used only while initializing */
+	union acpi_operand_obj      **elements;         /* Array of pointers to Acpi_objects */
+	union acpi_operand_obj      **next_element;     /* used only while initializing */
 
 } ACPI_OBJECT_PACKAGE;
 
 
-typedef struct /* FIELD UNIT */
-{
-	ACPI_OBJECT_COMMON_HEADER
-
-	ACPI_COMMON_FIELD_INFO
-
-	union acpi_operand_obj      *extra;             /* Pointer to executable AML (in field definition) */
-	ACPI_NAMESPACE_NODE         *node;              /* containing object */
-	union acpi_operand_obj      *container;         /* Containing object (Buffer) */
-
-} ACPI_OBJECT_FIELD_UNIT;
-
-
 typedef struct /* DEVICE - has handle and notification handler/context */
 {
 	ACPI_OBJECT_COMMON_HEADER
@@ -175,7 +173,6 @@
 typedef struct /* EVENT */
 {
 	ACPI_OBJECT_COMMON_HEADER
-
 	void                        *semaphore;
 
 } ACPI_OBJECT_EVENT;
@@ -201,12 +198,16 @@
 } ACPI_OBJECT_METHOD;
 
 
-typedef struct /* MUTEX */
+typedef struct acpi_obj_mutex /* MUTEX */
 {
 	ACPI_OBJECT_COMMON_HEADER
 	u16                         sync_level;
+	u16                         acquisition_depth;
 
 	void                        *semaphore;
+	void                        *owner;
+	union acpi_operand_obj      *prev;              /* Link for list of acquired mutexes */
+	union acpi_operand_obj      *next;              /* Link for list of acquired mutexes */
 
 } ACPI_OBJECT_MUTEX;
 
@@ -267,57 +268,78 @@
 
 
 /*
- * Internal types
+ * Fields.  All share a common header/info field.
  */
 
-
-typedef struct /* FIELD */
+typedef struct /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */
 {
 	ACPI_OBJECT_COMMON_HEADER
-
 	ACPI_COMMON_FIELD_INFO
+	union acpi_operand_obj      *region_obj;        /* Containing Operation Region object */
+			 /* (REGION/BANK fields only) */
+} ACPI_OBJECT_FIELD_COMMON;
 
-	union acpi_operand_obj      *container;         /* Containing object */
 
-} ACPI_OBJECT_FIELD;
+typedef struct /* REGION FIELD */
+{
+	ACPI_OBJECT_COMMON_HEADER
+	ACPI_COMMON_FIELD_INFO
+	union acpi_operand_obj      *region_obj;        /* Containing Op_region object */
+
+} ACPI_OBJECT_REGION_FIELD;
 
 
 typedef struct /* BANK FIELD */
 {
 	ACPI_OBJECT_COMMON_HEADER
-
 	ACPI_COMMON_FIELD_INFO
-	u32                         value;              /* Value to store into Bank_select */
 
-	ACPI_HANDLE                 bank_select;        /* Bank select register */
-	union acpi_operand_obj      *container;         /* Containing object */
+	union acpi_operand_obj      *region_obj;        /* Containing Op_region object */
+	union acpi_operand_obj      *bank_register_obj; /* Bank_select Register object */
 
 } ACPI_OBJECT_BANK_FIELD;
 
 
 typedef struct /* INDEX FIELD */
 {
+	ACPI_OBJECT_COMMON_HEADER
+	ACPI_COMMON_FIELD_INFO
+
 	/*
-	 * No container pointer needed since the index and data register definitions
-	 * will define how to access the respective registers
+	 * No "Region_obj" pointer needed since the Index and Data registers
+	 * are each field definitions unto themselves.
 	 */
-	ACPI_OBJECT_COMMON_HEADER
+	union acpi_operand_obj      *index_obj;         /* Index register */
+	union acpi_operand_obj      *data_obj;          /* Data register */
+
+
+} ACPI_OBJECT_INDEX_FIELD;
 
+
+/* The Buffer_field is different in that it is part of a Buffer, not an Op_region */
+
+typedef struct /* BUFFER FIELD */
+{
+	ACPI_OBJECT_COMMON_HEADER
 	ACPI_COMMON_FIELD_INFO
-	u32                         value;              /* Value to store into Index register */
 
-	ACPI_HANDLE                 index;              /* Index register */
-	ACPI_HANDLE                 data;               /* Data register */
+	union acpi_operand_obj      *extra;             /* Pointer to executable AML (in field definition) */
+	ACPI_NAMESPACE_NODE         *node;              /* Parent (containing) object node */
+	union acpi_operand_obj      *buffer_obj;        /* Containing Buffer object */
+
+} ACPI_OBJECT_BUFFER_FIELD;
 
-} ACPI_OBJECT_INDEX_FIELD;
 
+/*
+ * Handlers
+ */
 
 typedef struct /* NOTIFY HANDLER */
 {
 	ACPI_OBJECT_COMMON_HEADER
 
 	ACPI_NAMESPACE_NODE         *node;               /* Parent device */
-	NOTIFY_HANDLER              handler;
+	ACPI_NOTIFY_HANDLER         handler;
 	void                        *context;
 
 } ACPI_OBJECT_NOTIFY_HANDLER;
@@ -334,11 +356,11 @@
 
 	u8                          space_id;
 	u16                         hflags;
-	ADDRESS_SPACE_HANDLER       handler;
+	ACPI_ADR_SPACE_HANDLER      handler;
 
 	ACPI_NAMESPACE_NODE         *node;              /* Parent device */
 	void                        *context;
-	ADDRESS_SPACE_SETUP         setup;
+	ACPI_ADR_SPACE_SETUP        setup;
 	union acpi_operand_obj      *region_list;       /* regions using this handler */
 	union acpi_operand_obj      *next;
 
@@ -355,7 +377,7 @@
 	ACPI_OBJECT_COMMON_HEADER
 
 	u8                          target_type;        /* Used for Index_op */
-	u16                         op_code;
+	u16                         opcode;
 	u32                         offset;             /* Used for Arg_op, Local_op, and Index_op */
 
 	void                        *object;            /* Name_op=>HANDLE to obj, Index_op=>ACPI_OPERAND_OBJECT */
@@ -400,7 +422,7 @@
 	ACPI_OBJECT_STRING          string;
 	ACPI_OBJECT_BUFFER          buffer;
 	ACPI_OBJECT_PACKAGE         package;
-	ACPI_OBJECT_FIELD_UNIT      field_unit;
+	ACPI_OBJECT_BUFFER_FIELD    buffer_field;
 	ACPI_OBJECT_DEVICE          device;
 	ACPI_OBJECT_EVENT           event;
 	ACPI_OBJECT_METHOD          method;
@@ -409,7 +431,8 @@
 	ACPI_OBJECT_POWER_RESOURCE  power_resource;
 	ACPI_OBJECT_PROCESSOR       processor;
 	ACPI_OBJECT_THERMAL_ZONE    thermal_zone;
-	ACPI_OBJECT_FIELD           field;
+	ACPI_OBJECT_FIELD_COMMON    common_field;
+	ACPI_OBJECT_REGION_FIELD    field;
 	ACPI_OBJECT_BANK_FIELD      bank_field;
 	ACPI_OBJECT_INDEX_FIELD     index_field;
 	ACPI_OBJECT_REFERENCE       reference;
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/acoutput.h linux/drivers/acpi/include/acoutput.h
--- v2.4.5/linux/drivers/acpi/include/acoutput.h	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/include/acoutput.h	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acoutput.h -- debug output
- *       $Revision: 70 $
+ *       $Revision: 78 $
  *
  *****************************************************************************/
 
@@ -34,34 +34,35 @@
 
 /* Component IDs -- used in the global "Debug_layer" */
 
-#define GLOBAL                      0x00000001
-#define COMMON                      0x00000002
-#define PARSER                      0x00000004
-#define DISPATCHER                  0x00000008
-#define INTERPRETER                 0x00000010
-#define NAMESPACE                   0x00000020
-#define RESOURCE_MANAGER            0x00000040
-#define TABLE_MANAGER               0x00000080
-#define EVENT_HANDLING              0x00000100
-#define HARDWARE                    0x00000200
-#define MISCELLANEOUS               0x00000400
-#define OS_DEPENDENT                0x00000800
-
-#define BUS_MANAGER                 0x00001000
-
-#define PROCESSOR_CONTROL           0x00002000
-#define SYSTEM_CONTROL              0x00004000
-#define THERMAL_CONTROL             0x00008000
-#define POWER_CONTROL               0x00010000
-
-#define EMBEDDED_CONTROLLER         0x00020000
-#define BATTERY                     0x00040000
-
-#define DEBUGGER                    0x00100000
-#define COMPILER                    0x00200000
-#define ALL_COMPONENTS              0x001FFFFF
+#define ACPI_UTILITIES              0x00000001
+#define ACPI_HARDWARE               0x00000002
+#define ACPI_EVENTS                 0x00000004
+#define ACPI_TABLES                 0x00000008
+#define ACPI_NAMESPACE              0x00000010
+#define ACPI_PARSER                 0x00000020
+#define ACPI_DISPATCHER             0x00000040
+#define ACPI_EXECUTER               0x00000080
+#define ACPI_RESOURCES              0x00000100
+#define ACPI_DEBUGGER               0x00000200
+#define ACPI_OS_SERVICES            0x00000400
+
+#define ACPI_BUS                    0x00001000
+#define ACPI_SYSTEM                 0x00002000
+#define ACPI_POWER                  0x00004000
+#define ACPI_EC                     0x00008000
+#define ACPI_AC_ADAPTER             0x00010000
+#define ACPI_BATTERY                0x00020000
+#define ACPI_BUTTON                 0x00040000
+#define ACPI_PROCESSOR              0x00080000
+#define ACPI_THERMAL                0x00100000
 
-#define COMPONENT_DEFAULT           (ALL_COMPONENTS)
+#define ACPI_ALL_COMPONENTS         0x00FFFFFF
+
+#define ACPI_COMPONENT_DEFAULT      (ACPI_ALL_COMPONENTS)
+
+
+#define ACPI_COMPILER               0x10000000
+#define ACPI_TOOLS                  0x20000000
 
 
 /* Exception level -- used in the global "Debug_level" */
@@ -77,6 +78,7 @@
 
 /* Trace level -- also used in the global "Debug_level" */
 
+#define TRACE_THREADS               0x00000080
 #define TRACE_PARSE                 0x00000100
 #define TRACE_DISPATCH              0x00000200
 #define TRACE_LOAD                  0x00000400
@@ -98,7 +100,7 @@
 #define TRACE_MUTEX                 0x04000000
 #define TRACE_INIT                  0x08000000
 
-#define TRACE_ALL                   0x0FFFFF00
+#define TRACE_ALL                   0x0FFFFF80
 
 
 /* Exceptionally verbose output -- also used in the global "Debug_level" */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/acpi.h linux/drivers/acpi/include/acpi.h
--- v2.4.5/linux/drivers/acpi/include/acpi.h	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/include/acpi.h	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acpi.h - Master include file, Publics and external data.
- *       $Revision: 50 $
+ *       $Revision: 54 $
  *
  *****************************************************************************/
 
@@ -31,20 +31,21 @@
  * We put them here because we don't want to duplicate them
  * in the rest of the source code again and again.
  */
-#include "acconfig.h"       /* Configuration constants */
-#include "acenv.h"          /* Target environment specific items */
-#include "actypes.h"        /* Fundamental data types */
-#include "acexcep.h"        /* Local exception codes */
-#include "acmacros.h"       /* C macros */
-#include "actbl.h"          /* Acpi table definitions */
-#include "aclocal.h"        /* Internal data types */
-#include "acoutput.h"       /* Error output and Debug macros */
-#include "acpiosxf.h"       /* Interfaces to the Acpi-to-OS layer*/
-#include "acpixf.h"         /* Acpi core external interfaces */
-#include "acobject.h"       /* Acpi internal object */
-#include "acglobal.h"       /* All global variables */
-#include "achware.h"        /* Hardware defines and interfaces */
-#include "accommon.h"       /* Common (global) interfaces */
+#include "acconfig.h"           /* Configuration constants */
+#include "platform/acenv.h"     /* Target environment specific items */
+#include "actypes.h"            /* Fundamental common data types */
+#include "acexcep.h"            /* ACPI exception codes */
+#include "acmacros.h"           /* C macros */
+#include "actbl.h"              /* ACPI table definitions */
+#include "aclocal.h"            /* Internal data types */
+#include "acoutput.h"           /* Error output and Debug macros */
+#include "acpiosxf.h"           /* Interfaces to the ACPI-to-OS layer*/
+#include "acpixf.h"             /* ACPI core subsystem external interfaces */
+#include "acobject.h"           /* ACPI internal object */
+#include "acstruct.h"           /* Common structures */
+#include "acglobal.h"           /* All global variables */
+#include "achware.h"            /* Hardware defines and interfaces */
+#include "acutils.h"            /* Utility interfaces */
 
 
 #endif /* __ACPI_H__ */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/acpiosxf.h linux/drivers/acpi/include/acpiosxf.h
--- v2.4.5/linux/drivers/acpi/include/acpiosxf.h	Mon Jan 29 10:15:59 2001
+++ linux/drivers/acpi/include/acpiosxf.h	Wed Jun 20 17:47:40 2001
@@ -1,9 +1,9 @@
 
 /******************************************************************************
  *
- * Name: acpiosxf.h - All interfaces to the OS-dependent layer.  These
- *                    interfaces must be implemented by the OS-dependent
- *                    front-end to the ACPI subsystem.
+ * Name: acpiosxf.h - All interfaces to the OS Services Layer (OSL).  These
+ *                    interfaces must be implemented by OSL to interface the
+ *                    ACPI components to the host operating system.
  *
  *****************************************************************************/
 
@@ -26,26 +26,26 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifndef __ACPIOSD_H__
-#define __ACPIOSD_H__
+#ifndef __ACPIOSXF_H__
+#define __ACPIOSXF_H__
 
-#include "acenv.h"
+#include "platform/acenv.h"
 #include "actypes.h"
 
 
 /* Priorities for Acpi_os_queue_for_execution */
 
-#define OSD_PRIORITY_GPE    1
-#define OSD_PRIORITY_HIGH   2
-#define OSD_PRIORITY_MED    3
-#define OSD_PRIORITY_LO     4
+#define OSD_PRIORITY_GPE            1
+#define OSD_PRIORITY_HIGH           2
+#define OSD_PRIORITY_MED            3
+#define OSD_PRIORITY_LO             4
 
-#define ACPI_NO_UNIT_LIMIT  ((u32) -1)
-#define ACPI_MUTEX_SEM      1
+#define ACPI_NO_UNIT_LIMIT          ((u32) -1)
+#define ACPI_MUTEX_SEM              1
 
 
 /*
- * Types specific to the OS-dependent layer interfaces
+ * Types specific to the OS service interfaces
  */
 
 typedef
@@ -58,7 +58,7 @@
 
 
 /*
- * Initialization and shutdown primitives  (Optional)
+ * OSL Initialization and shutdown primitives
  */
 
 ACPI_STATUS
@@ -69,6 +69,7 @@
 acpi_os_terminate (
 	void);
 
+
 /*
  * Synchronization primitives
  */
@@ -94,6 +95,7 @@
 	ACPI_HANDLE             handle,
 	u32                     units);
 
+
 /*
  * Memory allocation and mapping
  */
@@ -126,6 +128,7 @@
 	void                    *logical_address,
 	ACPI_PHYSICAL_ADDRESS   *physical_address);
 
+
 /*
  * Interrupt handlers
  */
@@ -143,9 +146,13 @@
 
 
 /*
- * Scheduling
+ * Threads and Scheduling
  */
 
+u32
+acpi_os_get_thread_id (
+	void);
+
 ACPI_STATUS
 acpi_os_queue_for_execution (
 	u32                     priority,
@@ -161,6 +168,7 @@
 acpi_os_sleep_usec (
 	u32                     microseconds);
 
+
 /*
  * Platform/Hardware independent I/O interfaces
  */
@@ -193,6 +201,7 @@
 	ACPI_IO_ADDRESS         out_port,
 	u32                     value);
 
+
 /*
  * Platform/Hardware independent physical memory interfaces
  */
@@ -292,6 +301,10 @@
 	void                    *pointer,
 	u32                     length);
 
+u32
+acpi_os_get_timer (
+	void);
+
 
 /*
  * Debug print routines
@@ -307,6 +320,7 @@
 	const NATIVE_CHAR       *format,
 	va_list                 args);
 
+
 /*
  * Debug input
  */
@@ -328,4 +342,4 @@
 	NATIVE_CHAR             *message);
 
 
-#endif /* __ACPIOSD_H__ */
+#endif /* __ACPIOSXF_H__ */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/acpixf.h linux/drivers/acpi/include/acpixf.h
--- v2.4.5/linux/drivers/acpi/include/acpixf.h	Mon Jan 29 10:15:59 2001
+++ linux/drivers/acpi/include/acpixf.h	Wed Jun 20 17:47:40 2001
@@ -30,6 +30,7 @@
 #include "actypes.h"
 #include "actbl.h"
 
+
 /*
  * Global interfaces
  */
@@ -65,6 +66,23 @@
 
 
 /*
+ * ACPI Memory manager
+ */
+
+void *
+acpi_allocate (
+	u32                     size);
+
+void *
+acpi_callocate (
+	u32                     size);
+
+void
+acpi_free (
+	void                    *address);
+
+
+/*
  * ACPI table manipulation interfaces
  */
 
@@ -96,6 +114,13 @@
 	u32                     instance,
 	ACPI_BUFFER             *ret_buffer);
 
+ACPI_STATUS
+acpi_get_firmware_table (
+	ACPI_STRING             signature,
+	u32                     instance,
+	u32                     flags,
+	ACPI_TABLE_HEADER       **table_pointer);
+
 
 /*
  * Namespace and name interfaces
@@ -106,14 +131,14 @@
 	ACPI_OBJECT_TYPE        type,
 	ACPI_HANDLE             start_object,
 	u32                     max_depth,
-	WALK_CALLBACK           user_function,
+	ACPI_WALK_CALLBACK      user_function,
 	void                    *context,
 	void *                  *return_value);
 
 ACPI_STATUS
 acpi_get_devices (
 	NATIVE_CHAR             *HID,
-	WALK_CALLBACK           user_function,
+	ACPI_WALK_CALLBACK      user_function,
 	void                    *context,
 	void                    **return_value);
 
@@ -165,52 +190,52 @@
 
 
 /*
- * Acpi_event handler interfaces
+ * Event handler interfaces
  */
 
 ACPI_STATUS
 acpi_install_fixed_event_handler (
 	u32                     acpi_event,
-	FIXED_EVENT_HANDLER     handler,
+	ACPI_EVENT_HANDLER      handler,
 	void                    *context);
 
 ACPI_STATUS
 acpi_remove_fixed_event_handler (
 	u32                     acpi_event,
-	FIXED_EVENT_HANDLER     handler);
+	ACPI_EVENT_HANDLER      handler);
 
 ACPI_STATUS
 acpi_install_notify_handler (
 	ACPI_HANDLE             device,
 	u32                     handler_type,
-	NOTIFY_HANDLER          handler,
+	ACPI_NOTIFY_HANDLER     handler,
 	void                    *context);
 
 ACPI_STATUS
 acpi_remove_notify_handler (
 	ACPI_HANDLE             device,
 	u32                     handler_type,
-	NOTIFY_HANDLER          handler);
+	ACPI_NOTIFY_HANDLER     handler);
 
 ACPI_STATUS
 acpi_install_address_space_handler (
 	ACPI_HANDLE             device,
-	ACPI_ADDRESS_SPACE_TYPE space_id,
-	ADDRESS_SPACE_HANDLER   handler,
-	ADDRESS_SPACE_SETUP     setup,
+	ACPI_ADR_SPACE_TYPE     space_id,
+	ACPI_ADR_SPACE_HANDLER  handler,
+	ACPI_ADR_SPACE_SETUP    setup,
 	void                    *context);
 
 ACPI_STATUS
 acpi_remove_address_space_handler (
 	ACPI_HANDLE             device,
-	ACPI_ADDRESS_SPACE_TYPE space_id,
-	ADDRESS_SPACE_HANDLER   handler);
+	ACPI_ADR_SPACE_TYPE     space_id,
+	ACPI_ADR_SPACE_HANDLER  handler);
 
 ACPI_STATUS
 acpi_install_gpe_handler (
 	u32                     gpe_number,
 	u32                     type,
-	GPE_HANDLER             handler,
+	ACPI_GPE_HANDLER        handler,
 	void                    *context);
 
 ACPI_STATUS
@@ -224,7 +249,7 @@
 ACPI_STATUS
 acpi_remove_gpe_handler (
 	u32                     gpe_number,
-	GPE_HANDLER             handler);
+	ACPI_GPE_HANDLER        handler);
 
 ACPI_STATUS
 acpi_enable_event (
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/acresrc.h linux/drivers/acpi/include/acresrc.h
--- v2.4.5/linux/drivers/acpi/include/acresrc.h	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/include/acresrc.h	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acresrc.h - Resource Manager function prototypes
- *       $Revision: 22 $
+ *       $Revision: 25 $
  *
  *****************************************************************************/
 
@@ -60,7 +60,7 @@
 
 ACPI_STATUS
 acpi_rs_create_byte_stream (
-	RESOURCE                *linked_list_buffer,
+	ACPI_RESOURCE           *linked_list_buffer,
 	u8                      *output_buffer,
 	u32                     *output_buffer_length);
 
@@ -77,7 +77,7 @@
 
 void
 acpi_rs_dump_resource_list (
-	RESOURCE                *resource);
+	ACPI_RESOURCE           *resource);
 
 void
 acpi_rs_dump_irq_list (
@@ -97,7 +97,7 @@
 
 ACPI_STATUS
 acpi_rs_calculate_byte_stream_length (
-	RESOURCE                *linked_list_buffer,
+	ACPI_RESOURCE           *linked_list_buffer,
 	u32                     *size_needed);
 
 ACPI_STATUS
@@ -113,7 +113,7 @@
 
 ACPI_STATUS
 acpi_rs_list_to_byte_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u32                     byte_stream_size_needed,
 	u8                      **output_buffer);
 
@@ -133,13 +133,13 @@
 
 ACPI_STATUS
 acpi_rs_io_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed);
 
 ACPI_STATUS
 acpi_rs_fixed_io_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed);
 
@@ -152,7 +152,7 @@
 
 ACPI_STATUS
 acpi_rs_irq_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed);
 
@@ -165,7 +165,7 @@
 
 ACPI_STATUS
 acpi_rs_dma_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed);
 
@@ -178,7 +178,7 @@
 
 ACPI_STATUS
 acpi_rs_address16_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed);
 
@@ -191,7 +191,20 @@
 
 ACPI_STATUS
 acpi_rs_address32_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
+	u8                      **output_buffer,
+	u32                     *bytes_consumed);
+
+ACPI_STATUS
+acpi_rs_address64_resource (
+	u8                      *byte_stream_buffer,
+	u32                     *bytes_consumed,
+	u8                      **output_buffer,
+	u32                     *structure_size);
+
+ACPI_STATUS
+acpi_rs_address64_stream (
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed);
 
@@ -211,13 +224,13 @@
 
 ACPI_STATUS
 acpi_rs_start_dependent_functions_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed);
 
 ACPI_STATUS
 acpi_rs_end_dependent_functions_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed);
 
@@ -230,7 +243,7 @@
 
 ACPI_STATUS
 acpi_rs_memory24_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed);
 
@@ -251,13 +264,13 @@
 
 ACPI_STATUS
 acpi_rs_memory32_range_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed);
 
 ACPI_STATUS
 acpi_rs_fixed_memory32_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed);
 
@@ -270,7 +283,7 @@
 
 ACPI_STATUS
 acpi_rs_extended_irq_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed);
 
@@ -283,7 +296,7 @@
 
 ACPI_STATUS
 acpi_rs_end_tag_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed);
 
@@ -296,9 +309,12 @@
 
 ACPI_STATUS
 acpi_rs_vendor_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed);
 
+u8
+acpi_rs_get_resource_type (
+	u8                      resource_start_byte);
 
 #endif  /* __ACRESRC_H__ */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/acstruct.h linux/drivers/acpi/include/acstruct.h
--- v2.4.5/linux/drivers/acpi/include/acstruct.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/include/acstruct.h	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,157 @@
+/******************************************************************************
+ *
+ * Name: acstruct.h - Internal structs
+ *       $Revision: 3 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ACSTRUCT_H__
+#define __ACSTRUCT_H__
+
+
+/*****************************************************************************
+ *
+ * Tree walking typedefs and structs
+ *
+ ****************************************************************************/
+
+
+/*
+ * Walk state - current state of a parse tree walk.  Used for both a leisurely stroll through
+ * the tree (for whatever reason), and for control method execution.
+ */
+
+#define NEXT_OP_DOWNWARD    1
+#define NEXT_OP_UPWARD      2
+
+#define WALK_NON_METHOD     0
+#define WALK_METHOD         1
+#define WALK_METHOD_RESTART 2
+
+typedef struct acpi_walk_state
+{
+	u8                      data_type;                          /* To differentiate various internal objs */\
+	ACPI_OWNER_ID           owner_id;                           /* Owner of objects created during the walk */
+	u8                      last_predicate;                     /* Result of last predicate */
+	u8                      next_op_info;                       /* Info about Next_op */
+	u8                      num_operands;                       /* Stack pointer for Operands[] array */
+	u8                      current_result;                     /* */
+
+	struct acpi_walk_state  *next;                              /* Next Walk_state in list */
+	ACPI_PARSE_OBJECT       *origin;                            /* Start of walk [Obsolete] */
+
+/* TBD: Obsolete with removal of WALK procedure ? */
+	ACPI_PARSE_OBJECT       *prev_op;                           /* Last op that was processed */
+	ACPI_PARSE_OBJECT       *next_op;                           /* next op to be processed */
+
+
+	ACPI_GENERIC_STATE      *results;                           /* Stack of accumulated results */
+	ACPI_GENERIC_STATE      *control_state;                     /* List of control states (nested IFs) */
+	ACPI_GENERIC_STATE      *scope_info;                        /* Stack of nested scopes */
+	ACPI_PARSE_STATE        *parser_state;                      /* Current state of parser */
+	u8                      *aml_last_while;
+	ACPI_OPCODE_INFO        *op_info;                           /* Info on current opcode */
+	ACPI_PARSE_DOWNWARDS    descending_callback;
+	ACPI_PARSE_UPWARDS      ascending_callback;
+
+	union acpi_operand_obj  *return_desc;                       /* Return object, if any */
+	union acpi_operand_obj  *method_desc;                       /* Method descriptor if running a method */
+	struct acpi_node        *method_node;                       /* Method Node if running a method */
+	ACPI_PARSE_OBJECT       *method_call_op;                    /* Method_call Op if running a method */
+	struct acpi_node        *method_call_node;                  /* Called method Node*/
+	union acpi_operand_obj  *operands[OBJ_NUM_OPERANDS];        /* Operands passed to the interpreter */
+	struct acpi_node        arguments[MTH_NUM_ARGS];            /* Control method arguments */
+	struct acpi_node        local_variables[MTH_NUM_LOCALS];    /* Control method locals */
+	struct acpi_walk_list   *walk_list;
+	u32                     parse_flags;
+	u8                      walk_type;
+	u8                      return_used;
+	u16                     opcode;                             /* Current AML opcode */
+	u32                     prev_arg_types;
+	u16                     current_sync_level;                 /* Mutex Sync (nested acquire) level */
+
+	/* Debug support */
+
+	u32                     method_breakpoint;
+
+
+} ACPI_WALK_STATE;
+
+
+/*
+ * Walk list - head of a tree of walk states.  Multiple walk states are created when there
+ * are nested control methods executing.
+ */
+typedef struct acpi_walk_list
+{
+
+	ACPI_WALK_STATE         *walk_state;
+	ACPI_OBJECT_MUTEX       acquired_mutex_list;               /* List of all currently acquired mutexes */
+
+} ACPI_WALK_LIST;
+
+
+/* Info used by Acpi_ps_init_objects */
+
+typedef struct acpi_init_walk_info
+{
+	u16                     method_count;
+	u16                     op_region_count;
+	u16                     field_count;
+	u16                     op_region_init;
+	u16                     field_init;
+	u16                     object_count;
+	ACPI_TABLE_DESC         *table_desc;
+
+} ACPI_INIT_WALK_INFO;
+
+
+/* Info used by TBD */
+
+typedef struct acpi_device_walk_info
+{
+	u16                     device_count;
+	u16                     num_STA;
+	u16                     num_INI;
+	ACPI_TABLE_DESC         *table_desc;
+
+} ACPI_DEVICE_WALK_INFO;
+
+
+/* TBD: [Restructure] Merge with struct above */
+
+typedef struct acpi_walk_info
+{
+	u32                     debug_level;
+	u32                     owner_id;
+
+} ACPI_WALK_INFO;
+
+typedef struct acpi_get_devices_info
+{
+	ACPI_WALK_CALLBACK      user_function;
+	void                    *context;
+	NATIVE_CHAR             *hid;
+
+} ACPI_GET_DEVICES_INFO;
+
+
+#endif
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/actables.h linux/drivers/acpi/include/actables.h
--- v2.4.5/linux/drivers/acpi/include/actables.h	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/include/actables.h	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: actables.h - ACPI table management
- *       $Revision: 29 $
+ *       $Revision: 31 $
  *
  *****************************************************************************/
 
@@ -54,6 +54,10 @@
 acpi_tb_build_common_facs (
 	ACPI_TABLE_DESC         *table_info);
 
+u32
+acpi_tb_get_table_count (
+	RSDP_DESCRIPTOR         *RSDP,
+	ACPI_TABLE_HEADER       *RSDT);
 
 /*
  * tbget - Table "get" routines
@@ -80,6 +84,20 @@
 	ACPI_TABLE_HEADER       *buffer_ptr,
 	ACPI_TABLE_DESC         *table_info);
 
+ACPI_PHYSICAL_ADDRESS
+acpi_tb_get_rsdt_address (
+	void);
+
+ACPI_STATUS
+acpi_tb_validate_rsdt (
+	ACPI_TABLE_HEADER       *table_ptr);
+
+ACPI_STATUS
+acpi_tb_get_table_pointer (
+	ACPI_PHYSICAL_ADDRESS   physical_address,
+	u32                     flags,
+	u32                     *size,
+	ACPI_TABLE_HEADER       **table_ptr);
 
 /*
  * tbgetall - Get all firmware ACPI tables
@@ -151,7 +169,8 @@
 
 ACPI_STATUS
 acpi_tb_find_rsdp (
-	ACPI_TABLE_DESC         *table_info);
+	ACPI_TABLE_DESC         *table_info,
+	u32                     flags);
 
 
 /*
@@ -166,7 +185,7 @@
 acpi_tb_map_acpi_table (
 	ACPI_PHYSICAL_ADDRESS   physical_address,
 	u32                     *size,
-	void                    **logical_address);
+	ACPI_TABLE_HEADER       **logical_address);
 
 ACPI_STATUS
 acpi_tb_verify_table_checksum (
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/actbl.h linux/drivers/acpi/include/actbl.h
--- v2.4.5/linux/drivers/acpi/include/actbl.h	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/include/actbl.h	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: actbl.h - Table data structures defined in ACPI specification
- *       $Revision: 45 $
+ *       $Revision: 46 $
  *
  *****************************************************************************/
 
@@ -140,7 +140,7 @@
 	u8                      processor_apic_id;      /* ACPI processor id */
 	u8                      local_apic_id;          /* processor's local APIC id */
 	u32                     processor_enabled: 1;   /* Processor is usable if set */
-	u32                     reserved1       : 32;
+	u32                     reserved1       : 31;
 
 } PROCESSOR_APIC;
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/actbl2.h linux/drivers/acpi/include/actbl2.h
--- v2.4.5/linux/drivers/acpi/include/actbl2.h	Mon Jan 29 10:15:59 2001
+++ linux/drivers/acpi/include/actbl2.h	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: actbl2.h - ACPI Specification Revision 2.0 Tables
- *       $Revision: 21 $
+ *       $Revision: 24 $
  *
  *****************************************************************************/
 
@@ -26,159 +26,156 @@
 #ifndef __ACTBL2_H__
 #define __ACTBL2_H__
 
-/**************************************/
-/* Prefered Power Management Profiles */
-/**************************************/
-#define PM_UNSPECIFIED        0
-#define PM_DESKTOP            1
-#define PM_MOBILE             2
-#define PM_WORKSTATION        3
-#define PM_ENTERPRISE_SERVER  4
-#define PM_SOHO_SERVER        5
-#define PM_APPLIANCE_PC       6
-
-/*********************************************/
-/* ACPI Boot Arch Flags, See spec Table 5-10 */
-/*********************************************/
-#define BAF_LEGACY_DEVICES             0x0001
-#define BAF_8042_KEYBOARD_CONTROLLER   0x0002
+/*
+ * Prefered Power Management Profiles
+ */
+#define PM_UNSPECIFIED                  0
+#define PM_DESKTOP                      1
+#define PM_MOBILE                       2
+#define PM_WORKSTATION                  3
+#define PM_ENTERPRISE_SERVER            4
+#define PM_SOHO_SERVER                  5
+#define PM_APPLIANCE_PC                 6
+
+/*
+ * ACPI Boot Arch Flags
+ */
+#define BAF_LEGACY_DEVICES              0x0001
+#define BAF_8042_KEYBOARD_CONTROLLER    0x0002
+
+#define FADT2_REVISION_ID               3
 
-#define FADT2_REVISION_ID     3
 
 #pragma pack(1)
 
-/*************************************/
-/* ACPI Specification Rev 2.0 for    */
-/* the Root System Description Table */
-/*************************************/
+/*
+ * ACPI Specification Rev 2.0 for the Root System Description Table
+ */
 typedef struct
 {
-	ACPI_TABLE_HEADER   header;                 /* Table header */
-	u32                 table_offset_entry [1]; /* Array of pointers to  */
-			   /* other tables' headers */
+	ACPI_TABLE_HEADER       header;                 /* Table header */
+	u32                     table_offset_entry [1]; /* Array of pointers to  */
+			 /* other tables' headers */
 } RSDT_DESCRIPTOR_REV2;
 
 
-/********************************************/
-/* ACPI Specification Rev 2.0 for the       */
-/* Extended System Description Table (XSDT) */
-/********************************************/
+/*
+ * ACPI Specification Rev 2.0 for the Extended System Description Table (XSDT)
+ */
 typedef struct
 {
-	ACPI_TABLE_HEADER   header;                 /* Table header */
-	UINT64              table_offset_entry [1]; /* Array of pointers to  */
-			   /* other tables' headers */
+	ACPI_TABLE_HEADER       header;                 /* Table header */
+	UINT64                  table_offset_entry [1]; /* Array of pointers to  */
+			 /* other tables' headers */
 } XSDT_DESCRIPTOR_REV2;
 
-/***************************************/
-/* ACPI Specification Rev 2.0 for      */
-/* the Firmware ACPI Control Structure */
-/***************************************/
+
+/*
+ * ACPI Specification Rev 2.0 for the Firmware ACPI Control Structure
+ */
 typedef struct
 {
-	NATIVE_CHAR         signature[4];           /* signature "FACS" */
-	u32                 length;                 /* length of structure, in bytes */
-	u32                 hardware_signature;     /* hardware configuration signature */
-	u32                 firmware_waking_vector; /* 32bit physical address of the Firmware Waking Vector. */
-	u32                 global_lock;            /* Global Lock used to synchronize access to shared hardware resources */
-	u32                 S4_bios_f       : 1;    /* Indicates if S4_bIOS support is present */
-	u32                 reserved1       : 31;   /* must be 0 */
-	UINT64              Xfirmware_waking_vector; /* 64bit physical address of the Firmware Waking Vector. */
-	u8                  version;                /* Version of this table */
-	u8                  reserved3 [31];         /* reserved - must be zero */
+	NATIVE_CHAR             signature[4];           /* signature "FACS" */
+	u32                     length;                 /* length of structure, in bytes */
+	u32                     hardware_signature;     /* hardware configuration signature */
+	u32                     firmware_waking_vector; /* 32bit physical address of the Firmware Waking Vector. */
+	u32                     global_lock;            /* Global Lock used to synchronize access to shared hardware resources */
+	u32                     S4_bios_f       : 1;    /* Indicates if S4_bIOS support is present */
+	u32                     reserved1       : 31;   /* must be 0 */
+	UINT64                  Xfirmware_waking_vector; /* 64bit physical address of the Firmware Waking Vector. */
+	u8                      version;                /* Version of this table */
+	u8                      reserved3 [31];         /* reserved - must be zero */
 
 } FACS_DESCRIPTOR_REV2;
 
 
-/***************************************/
-/* ACPI Specification Rev 2.0 for      */
-/* the Generic Address Structure (GAS) */
-/***************************************/
+/*
+ * ACPI Specification Rev 2.0 for the Generic Address Structure (GAS)
+ */
 typedef struct
 {
-	u8                  address_space_id;   /* Address space where struct or register exists. */
-	u8                  register_bit_width; /* Size in bits of given register */
-	u8                  register_bit_offset; /* Bit offset within the register */
-	u8                  reserved;           /* Must be 0 */
-	UINT64              address;            /* 64-bit address of struct or register */
-
-} ACPI_GAS;
+	u8                      address_space_id;       /* Address space where struct or register exists. */
+	u8                      register_bit_width;     /* Size in bits of given register */
+	u8                      register_bit_offset;    /* Bit offset within the register */
+	u8                      reserved;               /* Must be 0 */
+	UINT64                  address;                /* 64-bit address of struct or register */
+
+} ACPI_GENERIC_ADDRESS;
 
 
-/************************************/
-/* ACPI Specification Rev 2.0 for   */
-/* the Fixed ACPI Description Table */
-/************************************/
+/*
+ * ACPI Specification Rev 2.0 for the Fixed ACPI Description Table
+ */
 typedef struct
 {
-	ACPI_TABLE_HEADER   header;            /* table header */
-	u32                 V1_firmware_ctrl;  /* 32-bit physical address of FACS */
-	u32                 V1_dsdt;           /* 32-bit physical address of DSDT */
-	u8                  reserved1;         /* System Interrupt Model isn't used in ACPI 2.0*/
-	u8                  prefer_PM_profile; /* Conveys preferred power management profile to OSPM. */
-	u16                 sci_int;           /* System vector of SCI interrupt */
-	u32                 smi_cmd;           /* Port address of SMI command port */
-	u8                  acpi_enable;       /* value to write to smi_cmd to enable ACPI */
-	u8                  acpi_disable;      /* value to write to smi_cmd to disable ACPI */
-	u8                  S4_bios_req;       /* Value to write to SMI CMD to enter S4_bIOS state */
-	u8                  pstate_cnt;        /* processor performance state control*/
-	u32                 V1_pm1a_evt_blk;   /* Port address of Power Mgt 1a Acpi_event Reg Blk */
-	u32                 V1_pm1b_evt_blk;   /* Port address of Power Mgt 1b Acpi_event Reg Blk */
-	u32                 V1_pm1a_cnt_blk;   /* Port address of Power Mgt 1a Control Reg Blk */
-	u32                 V1_pm1b_cnt_blk;   /* Port address of Power Mgt 1b Control Reg Blk */
-	u32                 V1_pm2_cnt_blk;    /* Port address of Power Mgt 2 Control Reg Blk */
-	u32                 V1_pm_tmr_blk;     /* Port address of Power Mgt Timer Ctrl Reg Blk */
-	u32                 V1_gpe0blk;        /* Port addr of General Purpose Acpi_event 0 Reg Blk */
-	u32                 V1_gpe1_blk;       /* Port addr of General Purpose Acpi_event 1 Reg Blk */
-	u8                  pm1_evt_len;       /* Byte Length of ports at pm1_x_evt_blk */
-	u8                  pm1_cnt_len;       /* Byte Length of ports at pm1_x_cnt_blk */
-	u8                  pm2_cnt_len;       /* Byte Length of ports at pm2_cnt_blk */
-	u8                  pm_tm_len;         /* Byte Length of ports at pm_tm_blk */
-	u8                  gpe0blk_len;       /* Byte Length of ports at gpe0_blk */
-	u8                  gpe1_blk_len;      /* Byte Length of ports at gpe1_blk */
-	u8                  gpe1_base;         /* offset in gpe model where gpe1 events start */
-	u8                  cst_cnt;           /* Support for the _CST object and C States change notification.*/
-	u16                 plvl2_lat;         /* worst case HW latency to enter/exit C2 state */
-	u16                 plvl3_lat;         /* worst case HW latency to enter/exit C3 state */
-	u16                 flush_size;        /* number of flush strides that need to be read */
-	u16                 flush_stride;      /* Processor's memory cache line width, in bytes */
-	u8                  duty_offset;       /* Processor_’s duty cycle index in processor's P_CNT reg*/
-	u8                  duty_width;        /* Processor_’s duty cycle value bit width in P_CNT register.*/
-	u8                  day_alrm;          /* index to day-of-month alarm in RTC CMOS RAM */
-	u8                  mon_alrm;          /* index to month-of-year alarm in RTC CMOS RAM */
-	u8                  century;           /* index to century in RTC CMOS RAM */
-	u16                 iapc_boot_arch;    /* IA-PC Boot Architecture Flags. See Table 5-10 for description*/
-	u8                  reserved2;         /* reserved */
-	u32                 wb_invd     : 1;   /* wbinvd instruction works properly */
-	u32                 wb_invd_flush : 1; /* wbinvd flushes but does not invalidate */
-	u32                 proc_c1     : 1;   /* all processors support C1 state */
-	u32                 plvl2_up    : 1;   /* C2 state works on MP system */
-	u32                 pwr_button  : 1;   /* Power button is handled as a generic feature */
-	u32                 sleep_button : 1;  /* Sleep button is handled as a generic feature, or not present */
-	u32                 fixed_rTC   : 1;   /* RTC wakeup stat not in fixed register space */
-	u32                 rtcs4       : 1;   /* RTC wakeup stat not possible from S4 */
-	u32                 tmr_val_ext : 1;   /* tmr_val is 32 bits */
-	u32                 dock_cap    : 1;   /* Supports Docking */
-	u32                 reset_reg_sup : 1; /* Indicates system supports system reset via the FADT RESET_REG*/
-	u32                 sealed_case : 1;   /* Indicates system has no internal expansion capabilities and case is sealed. */
-	u32                 headless    : 1;   /* Indicates system does not have local video capabilities or local input devices.*/
-	u32                 cpu_sw_sleep : 1;  /* Indicates to OSPM that a processor native instruction */
-			 /* must be executed after writing the SLP_TYPx register. */
-	u32                 reserved6   : 18;  /* reserved - must be zero */
-
-	ACPI_GAS            reset_register;    /* Reset register address in GAS format */
-	u8                  reset_value;       /* Value to write to the Reset_register port to reset the system. */
-	u8                  reserved7[3];      /* These three bytes must be zero */
-	UINT64              Xfirmware_ctrl;     /* 64-bit physical address of FACS */
-	UINT64              Xdsdt;              /* 64-bit physical address of DSDT */
-	ACPI_GAS            Xpm1a_evt_blk;      /* Extended Power Mgt 1a Acpi_event Reg Blk address */
-	ACPI_GAS            Xpm1b_evt_blk;      /* Extended Power Mgt 1b Acpi_event Reg Blk address */
-	ACPI_GAS            Xpm1a_cnt_blk;      /* Extended Power Mgt 1a Control Reg Blk address */
-	ACPI_GAS            Xpm1b_cnt_blk;      /* Extended Power Mgt 1b Control Reg Blk address */
-	ACPI_GAS            Xpm2_cnt_blk;       /* Extended Power Mgt 2 Control Reg Blk address */
-	ACPI_GAS            Xpm_tmr_blk;        /* Extended Power Mgt Timer Ctrl Reg Blk address */
-	ACPI_GAS            Xgpe0blk;           /* Extended General Purpose Acpi_event 0 Reg Blk address */
-	ACPI_GAS            Xgpe1_blk;          /* Extended General Purpose Acpi_event 1 Reg Blk address */
+	ACPI_TABLE_HEADER       header;             /* table header */
+	u32                     V1_firmware_ctrl;   /* 32-bit physical address of FACS */
+	u32                     V1_dsdt;            /* 32-bit physical address of DSDT */
+	u8                      reserved1;          /* System Interrupt Model isn't used in ACPI 2.0*/
+	u8                      prefer_PM_profile;  /* Conveys preferred power management profile to OSPM. */
+	u16                     sci_int;            /* System vector of SCI interrupt */
+	u32                     smi_cmd;            /* Port address of SMI command port */
+	u8                      acpi_enable;        /* value to write to smi_cmd to enable ACPI */
+	u8                      acpi_disable;       /* value to write to smi_cmd to disable ACPI */
+	u8                      S4_bios_req;        /* Value to write to SMI CMD to enter S4_bIOS state */
+	u8                      pstate_cnt;         /* processor performance state control*/
+	u32                     V1_pm1a_evt_blk;    /* Port address of Power Mgt 1a Acpi_event Reg Blk */
+	u32                     V1_pm1b_evt_blk;    /* Port address of Power Mgt 1b Acpi_event Reg Blk */
+	u32                     V1_pm1a_cnt_blk;    /* Port address of Power Mgt 1a Control Reg Blk */
+	u32                     V1_pm1b_cnt_blk;    /* Port address of Power Mgt 1b Control Reg Blk */
+	u32                     V1_pm2_cnt_blk;     /* Port address of Power Mgt 2 Control Reg Blk */
+	u32                     V1_pm_tmr_blk;      /* Port address of Power Mgt Timer Ctrl Reg Blk */
+	u32                     V1_gpe0blk;         /* Port addr of General Purpose Acpi_event 0 Reg Blk */
+	u32                     V1_gpe1_blk;        /* Port addr of General Purpose Acpi_event 1 Reg Blk */
+	u8                      pm1_evt_len;        /* Byte Length of ports at pm1_x_evt_blk */
+	u8                      pm1_cnt_len;        /* Byte Length of ports at pm1_x_cnt_blk */
+	u8                      pm2_cnt_len;        /* Byte Length of ports at pm2_cnt_blk */
+	u8                      pm_tm_len;          /* Byte Length of ports at pm_tm_blk */
+	u8                      gpe0blk_len;        /* Byte Length of ports at gpe0_blk */
+	u8                      gpe1_blk_len;       /* Byte Length of ports at gpe1_blk */
+	u8                      gpe1_base;          /* offset in gpe model where gpe1 events start */
+	u8                      cst_cnt;            /* Support for the _CST object and C States change notification.*/
+	u16                     plvl2_lat;          /* worst case HW latency to enter/exit C2 state */
+	u16                     plvl3_lat;          /* worst case HW latency to enter/exit C3 state */
+	u16                     flush_size;         /* number of flush strides that need to be read */
+	u16                     flush_stride;       /* Processor's memory cache line width, in bytes */
+	u8                      duty_offset;        /* Processor’s duty cycle index in processor's P_CNT reg*/
+	u8                      duty_width;         /* Processor’s duty cycle value bit width in P_CNT register.*/
+	u8                      day_alrm;           /* index to day-of-month alarm in RTC CMOS RAM */
+	u8                      mon_alrm;           /* index to month-of-year alarm in RTC CMOS RAM */
+	u8                      century;            /* index to century in RTC CMOS RAM */
+	u16                     iapc_boot_arch;     /* IA-PC Boot Architecture Flags. See Table 5-10 for description*/
+	u8                      reserved2;          /* reserved */
+	u32                     wb_invd     : 1;    /* wbinvd instruction works properly */
+	u32                     wb_invd_flush : 1;  /* wbinvd flushes but does not invalidate */
+	u32                     proc_c1     : 1;    /* all processors support C1 state */
+	u32                     plvl2_up    : 1;    /* C2 state works on MP system */
+	u32                     pwr_button  : 1;    /* Power button is handled as a generic feature */
+	u32                     sleep_button : 1;   /* Sleep button is handled as a generic feature, or not present */
+	u32                     fixed_rTC   : 1;    /* RTC wakeup stat not in fixed register space */
+	u32                     rtcs4       : 1;    /* RTC wakeup stat not possible from S4 */
+	u32                     tmr_val_ext : 1;    /* tmr_val is 32 bits */
+	u32                     dock_cap    : 1;    /* Supports Docking */
+	u32                     reset_reg_sup : 1;  /* Indicates system supports system reset via the FADT RESET_REG*/
+	u32                     sealed_case : 1;    /* Indicates system has no internal expansion capabilities and case is sealed. */
+	u32                     headless    : 1;    /* Indicates system does not have local video capabilities or local input devices.*/
+	u32                     cpu_sw_sleep : 1;   /* Indicates to OSPM that a processor native instruction */
+			   /* must be executed after writing the SLP_TYPx register. */
+	u32                     reserved6   : 18;   /* reserved - must be zero */
+
+	ACPI_GENERIC_ADDRESS    reset_register;     /* Reset register address in GAS format */
+	u8                      reset_value;        /* Value to write to the Reset_register port to reset the system. */
+	u8                      reserved7[3];       /* These three bytes must be zero */
+	UINT64                  Xfirmware_ctrl;     /* 64-bit physical address of FACS */
+	UINT64                  Xdsdt;              /* 64-bit physical address of DSDT */
+	ACPI_GENERIC_ADDRESS    Xpm1a_evt_blk;      /* Extended Power Mgt 1a Acpi_event Reg Blk address */
+	ACPI_GENERIC_ADDRESS    Xpm1b_evt_blk;      /* Extended Power Mgt 1b Acpi_event Reg Blk address */
+	ACPI_GENERIC_ADDRESS    Xpm1a_cnt_blk;      /* Extended Power Mgt 1a Control Reg Blk address */
+	ACPI_GENERIC_ADDRESS    Xpm1b_cnt_blk;      /* Extended Power Mgt 1b Control Reg Blk address */
+	ACPI_GENERIC_ADDRESS    Xpm2_cnt_blk;       /* Extended Power Mgt 2 Control Reg Blk address */
+	ACPI_GENERIC_ADDRESS    Xpm_tmr_blk;        /* Extended Power Mgt Timer Ctrl Reg Blk address */
+	ACPI_GENERIC_ADDRESS    Xgpe0blk;           /* Extended General Purpose Acpi_event 0 Reg Blk address */
+	ACPI_GENERIC_ADDRESS    Xgpe1_blk;          /* Extended General Purpose Acpi_event 1 Reg Blk address */
 
 }  FADT_DESCRIPTOR_REV2;
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/actbl71.h linux/drivers/acpi/include/actbl71.h
--- v2.4.5/linux/drivers/acpi/include/actbl71.h	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/include/actbl71.h	Wed Jun 20 17:47:40 2001
@@ -3,7 +3,7 @@
  * Name: actbl71.h - IA-64 Extensions to the ACPI Spec Rev. 0.71
  *                   This file includes tables specific to this
  *                   specification revision.
- *       $Revision: 9 $
+ *       $Revision: 11 $
  *
  *****************************************************************************/
 
@@ -28,8 +28,10 @@
 #ifndef __ACTBL71_H__
 #define __ACTBL71_H__
 
+
 /* 0.71 FADT Address_space data item bitmasks defines */
 /* If the associated bit is zero then it is in memory space else in io space */
+
 #define SMI_CMD_ADDRESS_SPACE       0x01
 #define PM1_BLK_ADDRESS_SPACE       0x02
 #define PM2_CNT_BLK_ADDRESS_SPACE   0x04
@@ -38,10 +40,11 @@
 #define GPE1_BLK_ADDRESS_SPACE      0x20
 
 /* Only for clarity in declarations */
+
 typedef UINT64              IO_ADDRESS;
 
-#pragma pack(1)
 
+#pragma pack(1)
 typedef struct  /* Root System Descriptor Pointer */
 {
 	NATIVE_CHAR             signature [8];          /* contains "RSD PTR " */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/actypes.h linux/drivers/acpi/include/actypes.h
--- v2.4.5/linux/drivers/acpi/include/actypes.h	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/include/actypes.h	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: actypes.h - Common data types for the entire ACPI subsystem
- *       $Revision: 165 $
+ *       $Revision: 180 $
  *
  *****************************************************************************/
 
@@ -231,6 +231,10 @@
 
 #define ACPI_ROOT_OBJECT                (ACPI_HANDLE)(-1)
 
+
+/*
+ * Initialization sequence
+ */
 #define ACPI_FULL_INITIALIZATION        0x00
 #define ACPI_NO_ADDRESS_SPACE_INIT      0x01
 #define ACPI_NO_HARDWARE_INIT           0x02
@@ -241,8 +245,11 @@
 
 
 /*
- * Sleep state constants
+ * Power state values
  */
+
+#define ACPI_STATE_UNKNOWN              (u8) 0xFF
+
 #define ACPI_STATE_S0                   (u8) 0
 #define ACPI_STATE_S1                   (u8) 1
 #define ACPI_STATE_S2                   (u8) 2
@@ -252,6 +259,26 @@
 /* let's pretend S4_bIOS didn't exist for now. ASG */
 #define ACPI_STATE_S4_bIOS              (u8) 6
 #define ACPI_S_STATES_MAX               ACPI_STATE_S5
+#define ACPI_S_STATE_COUNT              6
+
+#define ACPI_STATE_D0                   (u8) 0
+#define ACPI_STATE_D1                   (u8) 1
+#define ACPI_STATE_D2                   (u8) 2
+#define ACPI_STATE_D3                   (u8) 3
+#define ACPI_D_STATES_MAX               ACPI_STATE_D3
+#define ACPI_D_STATE_COUNT              4
+
+/*
+ * Standard notify values
+ */
+#define ACPI_NOTIFY_BUS_CHECK           (u8) 0
+#define ACPI_NOTIFY_DEVICE_CHECK        (u8) 1
+#define ACPI_NOTIFY_DEVICE_WAKE         (u8) 2
+#define ACPI_NOTIFY_EJECT_REQUEST       (u8) 3
+#define ACPI_NOTIFY_DEVICE_CHECK_LIGHT  (u8) 4
+#define ACPI_NOTIFY_FREQUENCY_MISMATCH  (u8) 5
+#define ACPI_NOTIFY_BUS_MODE_MISMATCH   (u8) 6
+#define ACPI_NOTIFY_POWER_FAULT	        (u8) 7
 
 
 /*
@@ -282,35 +309,7 @@
  */
 
 typedef u32                             ACPI_OBJECT_TYPE;
-typedef u8                              OBJECT_TYPE_INTERNAL;
-
-#define ACPI_BTYPE_ANY                  0x00000000
-#define ACPI_BTYPE_INTEGER               0x00000001
-#define ACPI_BTYPE_STRING               0x00000002
-#define ACPI_BTYPE_BUFFER               0x00000004
-#define ACPI_BTYPE_PACKAGE              0x00000008
-#define ACPI_BTYPE_FIELD_UNIT           0x00000010
-#define ACPI_BTYPE_DEVICE               0x00000020
-#define ACPI_BTYPE_EVENT                0x00000040
-#define ACPI_BTYPE_METHOD               0x00000080
-#define ACPI_BTYPE_MUTEX                0x00000100
-#define ACPI_BTYPE_REGION               0x00000200
-#define ACPI_BTYPE_POWER                0x00000400
-#define ACPI_BTYPE_PROCESSOR            0x00000800
-#define ACPI_BTYPE_THERMAL              0x00001000
-#define ACPI_BTYPE_BUFFER_FIELD         0x00002000
-#define ACPI_BTYPE_DDB_HANDLE           0x00004000
-#define ACPI_BTYPE_DEBUG_OBJECT         0x00008000
-#define ACPI_BTYPE_REFERENCE            0x00010000
-#define ACPI_BTYPE_RESOURCE             0x00020000
-
-#define ACPI_BTYPE_COMPUTE_DATA         (ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER)
-
-#define ACPI_BTYPE_DATA                 (ACPI_BTYPE_COMPUTE_DATA  | ACPI_BTYPE_PACKAGE)
-#define ACPI_BTYPE_DATA_REFERENCE       (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE)
-#define ACPI_BTYPE_DEVICE_OBJECTS       (ACPI_BTYPE_DEVICE | ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR)
-#define ACPI_BTYPE_OBJECTS_AND_REFS     0x00017FFF  /* ARG or LOCAL */
-#define ACPI_BTYPE_ALL_OBJECTS          0x00007FFF
+typedef u8                              ACPI_OBJECT_TYPE8;
 
 
 #define ACPI_TYPE_ANY                   0  /* 0x00  */
@@ -342,7 +341,7 @@
  */
 #define INTERNAL_TYPE_BEGIN             17
 
-#define INTERNAL_TYPE_DEF_FIELD         17 /* 0x11  */
+#define INTERNAL_TYPE_REGION_FIELD      17 /* 0x11  */
 #define INTERNAL_TYPE_BANK_FIELD        18 /* 0x12  */
 #define INTERNAL_TYPE_INDEX_FIELD       19 /* 0x13  */
 #define INTERNAL_TYPE_REFERENCE         20 /* 0x14  Arg#, Local#, Name, Debug; used only in descriptors */
@@ -350,27 +349,62 @@
 #define INTERNAL_TYPE_NOTIFY            22 /* 0x16  */
 #define INTERNAL_TYPE_ADDRESS_HANDLER   23 /* 0x17  */
 #define INTERNAL_TYPE_RESOURCE          24 /* 0x18  */
+#define INTERNAL_TYPE_RESOURCE_FIELD    25 /* 0x19  */
 
 
-#define INTERNAL_TYPE_NODE_MAX          24
+#define INTERNAL_TYPE_NODE_MAX          25
 
 /* These are pseudo-types because there are never any namespace nodes with these types */
 
-#define INTERNAL_TYPE_DEF_FIELD_DEFN    25 /* 0x19  Name, Byte_const, multiple Field_element */
-#define INTERNAL_TYPE_BANK_FIELD_DEFN   26 /* 0x1A  2 Name,DWord_const,Byte_const,multi Field_element */
-#define INTERNAL_TYPE_INDEX_FIELD_DEFN  27 /* 0x1B  2 Name, Byte_const, multiple Field_element */
-#define INTERNAL_TYPE_IF                28 /* 0x1C  Op_code, multiple Code */
-#define INTERNAL_TYPE_ELSE              29 /* 0x1D  multiple Code */
-#define INTERNAL_TYPE_WHILE             30 /* 0x1E  Op_code, multiple Code */
-#define INTERNAL_TYPE_SCOPE             31 /* 0x1F  Name, multiple Node */
-#define INTERNAL_TYPE_DEF_ANY           32 /* 0x20  type is Any, suppress search of enclosing scopes */
-#define INTERNAL_TYPE_EXTRA             33 /* 0x21  */
+#define INTERNAL_TYPE_FIELD_DEFN        26 /* 0x1A  Name, Byte_const, multiple Field_element */
+#define INTERNAL_TYPE_BANK_FIELD_DEFN   27 /* 0x1B  2 Name,DWord_const,Byte_const,multi Field_element */
+#define INTERNAL_TYPE_INDEX_FIELD_DEFN  28 /* 0x1C  2 Name, Byte_const, multiple Field_element */
+#define INTERNAL_TYPE_IF                29 /* 0x1D  */
+#define INTERNAL_TYPE_ELSE              30 /* 0x1E  */
+#define INTERNAL_TYPE_WHILE             31 /* 0x1F  */
+#define INTERNAL_TYPE_SCOPE             32 /* 0x20  Name, multiple Node */
+#define INTERNAL_TYPE_DEF_ANY           33 /* 0x21  type is Any, suppress search of enclosing scopes */
+#define INTERNAL_TYPE_EXTRA             34 /* 0x22  */
 
-#define INTERNAL_TYPE_MAX               33
+#define INTERNAL_TYPE_MAX               34
 
-#define INTERNAL_TYPE_INVALID           34
+#define INTERNAL_TYPE_INVALID           35
 #define ACPI_TYPE_NOT_FOUND             0xFF
 
+
+/*
+ * Bitmapped ACPI types
+ * Used internally only
+ */
+#define ACPI_BTYPE_ANY                  0x00000000
+#define ACPI_BTYPE_INTEGER              0x00000001
+#define ACPI_BTYPE_STRING               0x00000002
+#define ACPI_BTYPE_BUFFER               0x00000004
+#define ACPI_BTYPE_PACKAGE              0x00000008
+#define ACPI_BTYPE_FIELD_UNIT           0x00000010
+#define ACPI_BTYPE_DEVICE               0x00000020
+#define ACPI_BTYPE_EVENT                0x00000040
+#define ACPI_BTYPE_METHOD               0x00000080
+#define ACPI_BTYPE_MUTEX                0x00000100
+#define ACPI_BTYPE_REGION               0x00000200
+#define ACPI_BTYPE_POWER                0x00000400
+#define ACPI_BTYPE_PROCESSOR            0x00000800
+#define ACPI_BTYPE_THERMAL              0x00001000
+#define ACPI_BTYPE_BUFFER_FIELD         0x00002000
+#define ACPI_BTYPE_DDB_HANDLE           0x00004000
+#define ACPI_BTYPE_DEBUG_OBJECT         0x00008000
+#define ACPI_BTYPE_REFERENCE            0x00010000
+#define ACPI_BTYPE_RESOURCE             0x00020000
+
+#define ACPI_BTYPE_COMPUTE_DATA         (ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER)
+
+#define ACPI_BTYPE_DATA                 (ACPI_BTYPE_COMPUTE_DATA  | ACPI_BTYPE_PACKAGE)
+#define ACPI_BTYPE_DATA_REFERENCE       (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE)
+#define ACPI_BTYPE_DEVICE_OBJECTS       (ACPI_BTYPE_DEVICE | ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR)
+#define ACPI_BTYPE_OBJECTS_AND_REFS     0x0001FFFF  /* ARG or LOCAL */
+#define ACPI_BTYPE_ALL_OBJECTS          0x0000FFFF
+
+
 /*
  * Acpi_event Types:
  * ------------
@@ -398,11 +432,11 @@
 #define ACPI_EVENT_RTC                  (ACPI_EVENT_TYPE) 5
 #define ACPI_EVENT_GENERAL              (ACPI_EVENT_TYPE) 6
 #define ACPI_EVENT_MAX                  6
-#define NUM_FIXED_EVENTS                (ACPI_EVENT_TYPE) 7
+#define ACPI_NUM_FIXED_EVENTS           (ACPI_EVENT_TYPE) 7
 
 #define ACPI_GPE_INVALID                0xFF
 #define ACPI_GPE_MAX                    0xFF
-#define NUM_GPE                         256
+#define ACPI_NUM_GPE                    256
 
 #define ACPI_EVENT_LEVEL_TRIGGERED      (ACPI_EVENT_TYPE) 1
 #define ACPI_EVENT_EDGE_TRIGGERED       (ACPI_EVENT_TYPE) 2
@@ -439,15 +473,15 @@
 
 /* Address Space (Operation Region) Types */
 
-typedef u8                              ACPI_ADDRESS_SPACE_TYPE;
+typedef u8                              ACPI_ADR_SPACE_TYPE;
 
-#define ADDRESS_SPACE_SYSTEM_MEMORY     (ACPI_ADDRESS_SPACE_TYPE) 0
-#define ADDRESS_SPACE_SYSTEM_IO         (ACPI_ADDRESS_SPACE_TYPE) 1
-#define ADDRESS_SPACE_PCI_CONFIG        (ACPI_ADDRESS_SPACE_TYPE) 2
-#define ADDRESS_SPACE_EC                (ACPI_ADDRESS_SPACE_TYPE) 3
-#define ADDRESS_SPACE_SMBUS             (ACPI_ADDRESS_SPACE_TYPE) 4
-#define ADDRESS_SPACE_CMOS              (ACPI_ADDRESS_SPACE_TYPE) 5
-#define ADDRESS_SPACE_PCI_BAR_TARGET    (ACPI_ADDRESS_SPACE_TYPE) 6
+#define ACPI_ADR_SPACE_SYSTEM_MEMORY    (ACPI_ADR_SPACE_TYPE) 0
+#define ACPI_ADR_SPACE_SYSTEM_IO        (ACPI_ADR_SPACE_TYPE) 1
+#define ACPI_ADR_SPACE_PCI_CONFIG       (ACPI_ADR_SPACE_TYPE) 2
+#define ACPI_ADR_SPACE_EC               (ACPI_ADR_SPACE_TYPE) 3
+#define ACPI_ADR_SPACE_SMBUS            (ACPI_ADR_SPACE_TYPE) 4
+#define ACPI_ADR_SPACE_CMOS             (ACPI_ADR_SPACE_TYPE) 5
+#define ACPI_ADR_SPACE_PCI_BAR_TARGET   (ACPI_ADR_SPACE_TYPE) 6
 
 
 /*
@@ -495,7 +529,7 @@
 	{
 		ACPI_OBJECT_TYPE            type;
 		u32                         proc_id;
-		u32                         pblk_address;
+		ACPI_IO_ADDRESS             pblk_address;
 		u32                         pblk_length;
 	} processor;
 
@@ -616,29 +650,33 @@
 			  /*  not found in the IA32 manner        */
 } ACPI_INIT_DATA;
 
+
 /*
  * Various handlers and callback procedures
  */
 
 typedef
-u32 (*FIXED_EVENT_HANDLER) (
+u32 (*ACPI_EVENT_HANDLER) (
 	void                        *context);
 
 typedef
-void (*GPE_HANDLER) (
+void (*ACPI_GPE_HANDLER) (
 	void                        *context);
 
 typedef
-void (*NOTIFY_HANDLER) (
+void (*ACPI_NOTIFY_HANDLER) (
 	ACPI_HANDLE                 device,
 	u32                         value,
 	void                        *context);
 
-#define ADDRESS_SPACE_READ              1
-#define ADDRESS_SPACE_WRITE             2
+
+/* Address Spaces (Operation Regions */
+
+#define ACPI_READ_ADR_SPACE     1
+#define ACPI_WRITE_ADR_SPACE    2
 
 typedef
-ACPI_STATUS (*ADDRESS_SPACE_HANDLER) (
+ACPI_STATUS (*ACPI_ADR_SPACE_HANDLER) (
 	u32                         function,
 	ACPI_PHYSICAL_ADDRESS       address,
 	u32                         bit_width,
@@ -646,11 +684,11 @@
 	void                        *handler_context,
 	void                        *region_context);
 
-#define ACPI_DEFAULT_HANDLER            ((ADDRESS_SPACE_HANDLER) NULL)
+#define ACPI_DEFAULT_HANDLER            ((ACPI_ADR_SPACE_HANDLER) NULL)
 
 
 typedef
-ACPI_STATUS (*ADDRESS_SPACE_SETUP) (
+ACPI_STATUS (*ACPI_ADR_SPACE_SETUP) (
 	ACPI_HANDLE                 region_handle,
 	u32                         function,
 	void                        *handler_context,
@@ -660,7 +698,7 @@
 #define ACPI_REGION_DEACTIVATE  1
 
 typedef
-ACPI_STATUS (*WALK_CALLBACK) (
+ACPI_STATUS (*ACPI_WALK_CALLBACK) (
 	ACPI_HANDLE                 obj_handle,
 	u32                         nesting_level,
 	void                        *context,
@@ -697,7 +735,7 @@
 	ACPI_COMMON_OBJ_INFO;
 
 	u32                         valid;              /*  Are the next bits legit? */
-	NATIVE_CHAR                 hardware_id [9];    /*  _HID value if any */
+	NATIVE_CHAR                 hardware_id[9];     /*  _HID value if any */
 	NATIVE_CHAR                 unique_id[9];       /*  _UID value if any */
 	ACPI_INTEGER                address;            /*  _ADR value if any */
 	u32                         current_status;     /*  _STA value */
@@ -711,7 +749,7 @@
 	u32                         seg;
 	u32                         bus;
 	u32                         dev_func;
-} PCI_HANDLER_CONTEXT;
+} ACPI_PCI_SPACE_CONTEXT;
 
 
 typedef struct
@@ -719,7 +757,7 @@
 	ACPI_PHYSICAL_ADDRESS       mapped_physical_address;
 	u8                          *mapped_logical_address;
 	u32                         mapped_length;
-} MEM_HANDLER_CONTEXT;
+} ACPI_MEM_SPACE_CONTEXT;
 
 
 /*
@@ -821,7 +859,7 @@
 	u32                         number_of_interrupts;
 	u32                         interrupts[1];
 
-} IRQ_RESOURCE;
+} ACPI_RESOURCE_IRQ;
 
 typedef struct
 {
@@ -831,14 +869,14 @@
 	u32                         number_of_channels;
 	u32                         channels[1];
 
-} DMA_RESOURCE;
+} ACPI_RESOURCE_DMA;
 
 typedef struct
 {
 	u32                         compatibility_priority;
 	u32                         performance_robustness;
 
-} START_DEPENDENT_FUNCTIONS_RESOURCE;
+} ACPI_RESOURCE_START_DPF;
 
 /*
  * END_DEPENDENT_FUNCTIONS_RESOURCE struct is not
@@ -853,21 +891,21 @@
 	u32                         alignment;
 	u32                         range_length;
 
-} IO_RESOURCE;
+} ACPI_RESOURCE_IO;
 
 typedef struct
 {
 	u32                         base_address;
 	u32                         range_length;
 
-} FIXED_IO_RESOURCE;
+} ACPI_RESOURCE_FIXED_IO;
 
 typedef struct
 {
 	u32                         length;
 	u8                          reserved[1];
 
-} VENDOR_RESOURCE;
+} ACPI_RESOURCE_VENDOR;
 
 typedef struct
 {
@@ -877,7 +915,7 @@
 	u32                         alignment;
 	u32                         range_length;
 
-} MEMORY24_RESOURCE;
+} ACPI_RESOURCE_MEM24;
 
 typedef struct
 {
@@ -887,7 +925,7 @@
 	u32                         alignment;
 	u32                         range_length;
 
-} MEMORY32_RESOURCE;
+} ACPI_RESOURCE_MEM32;
 
 typedef struct
 {
@@ -895,36 +933,44 @@
 	u32                         range_base_address;
 	u32                         range_length;
 
-} FIXED_MEMORY32_RESOURCE;
+} ACPI_RESOURCE_FIXED_MEM32;
 
 typedef struct
 {
 	u16                         cache_attribute;
 	u16                         read_write_attribute;
 
-} MEMORY_ATTRIBUTE;
+} ACPI_MEMORY_ATTRIBUTE;
 
 typedef struct
 {
 	u16                         range_attribute;
 	u16                         reserved;
 
-} IO_ATTRIBUTE;
+} ACPI_IO_ATTRIBUTE;
 
 typedef struct
 {
 	u16                         reserved1;
 	u16                         reserved2;
 
-} BUS_ATTRIBUTE;
+} ACPI_BUS_ATTRIBUTE;
 
 typedef union
 {
-	MEMORY_ATTRIBUTE            memory;
-	IO_ATTRIBUTE                io;
-	BUS_ATTRIBUTE               bus;
+	ACPI_MEMORY_ATTRIBUTE       memory;
+	ACPI_IO_ATTRIBUTE           io;
+	ACPI_BUS_ATTRIBUTE          bus;
+
+} ACPI_RESOURCE_ATTRIBUTE;
+
+typedef struct
+{
+	u32                         index;
+	u32                         string_length;
+	NATIVE_CHAR                 *string_ptr;
 
-} ATTRIBUTE_DATA;
+} ACPI_RESOURCE_SOURCE;
 
 typedef struct
 {
@@ -933,17 +979,15 @@
 	u32                         decode;
 	u32                         min_address_fixed;
 	u32                         max_address_fixed;
-	ATTRIBUTE_DATA              attribute;
+	ACPI_RESOURCE_ATTRIBUTE     attribute;
 	u32                         granularity;
 	u32                         min_address_range;
 	u32                         max_address_range;
 	u32                         address_translation_offset;
 	u32                         address_length;
-	u32                         resource_source_index;
-	u32                         resource_source_string_length;
-	NATIVE_CHAR                 resource_source[1];
+	ACPI_RESOURCE_SOURCE        resource_source;
 
-} ADDRESS16_RESOURCE;
+} ACPI_RESOURCE_ADDRESS16;
 
 typedef struct
 {
@@ -952,17 +996,32 @@
 	u32                         decode;
 	u32                         min_address_fixed;
 	u32                         max_address_fixed;
-	ATTRIBUTE_DATA              attribute;
+	ACPI_RESOURCE_ATTRIBUTE     attribute;
 	u32                         granularity;
 	u32                         min_address_range;
 	u32                         max_address_range;
 	u32                         address_translation_offset;
 	u32                         address_length;
-	u32                         resource_source_index;
-	u32                         resource_source_string_length;
-	NATIVE_CHAR                 resource_source[1];
+	ACPI_RESOURCE_SOURCE        resource_source;
 
-} ADDRESS32_RESOURCE;
+} ACPI_RESOURCE_ADDRESS32;
+
+typedef struct
+{
+	u32                         resource_type;
+	u32                         producer_consumer;
+	u32                         decode;
+	u32                         min_address_fixed;
+	u32                         max_address_fixed;
+	ACPI_RESOURCE_ATTRIBUTE     attribute;
+	UINT64                      granularity;
+	UINT64                      min_address_range;
+	UINT64                      max_address_range;
+	UINT64                      address_translation_offset;
+	UINT64                      address_length;
+	ACPI_RESOURCE_SOURCE        resource_source;
+
+} ACPI_RESOURCE_ADDRESS64;
 
 typedef struct
 {
@@ -971,58 +1030,65 @@
 	u32                         active_high_low;
 	u32                         shared_exclusive;
 	u32                         number_of_interrupts;
+	ACPI_RESOURCE_SOURCE        resource_source;
 	u32                         interrupts[1];
-	u32                         resource_source_index;
-	u32                         resource_source_string_length;
-	NATIVE_CHAR                 resource_source[1];
-
-} EXTENDED_IRQ_RESOURCE;
-
-typedef enum
-{
-	irq,
-	dma,
-	start_dependent_functions,
-	end_dependent_functions,
-	io,
-	fixed_io,
-	vendor_specific,
-	end_tag,
-	memory24,
-	memory32,
-	fixed_memory32,
-	address16,
-	address32,
-	extended_irq
-} RESOURCE_TYPE;
+
+} ACPI_RESOURCE_EXT_IRQ;
+
+
+/* ACPI_RESOURCE_TYPEs */
+
+#define ACPI_RSTYPE_IRQ                 0
+#define ACPI_RSTYPE_DMA                 1
+#define ACPI_RSTYPE_START_DPF           2
+#define ACPI_RSTYPE_END_DPF             3
+#define ACPI_RSTYPE_IO                  4
+#define ACPI_RSTYPE_FIXED_IO            5
+#define ACPI_RSTYPE_VENDOR              6
+#define ACPI_RSTYPE_END_TAG             7
+#define ACPI_RSTYPE_MEM24               8
+#define ACPI_RSTYPE_MEM32               9
+#define ACPI_RSTYPE_FIXED_MEM32         10
+#define ACPI_RSTYPE_ADDRESS16           11
+#define ACPI_RSTYPE_ADDRESS32           12
+#define ACPI_RSTYPE_ADDRESS64           13
+#define ACPI_RSTYPE_EXT_IRQ             14
+
+typedef u32                     ACPI_RESOURCE_TYPE;
 
 typedef union
 {
-	IRQ_RESOURCE                        irq;
-	DMA_RESOURCE                        dma;
-	START_DEPENDENT_FUNCTIONS_RESOURCE  start_dependent_functions;
-	IO_RESOURCE                         io;
-	FIXED_IO_RESOURCE                   fixed_io;
-	VENDOR_RESOURCE                     vendor_specific;
-	MEMORY24_RESOURCE                   memory24;
-	MEMORY32_RESOURCE                   memory32;
-	FIXED_MEMORY32_RESOURCE             fixed_memory32;
-	ADDRESS16_RESOURCE                  address16;
-	ADDRESS32_RESOURCE                  address32;
-	EXTENDED_IRQ_RESOURCE               extended_irq;
-} RESOURCE_DATA;
+	ACPI_RESOURCE_IRQ           irq;
+	ACPI_RESOURCE_DMA           dma;
+	ACPI_RESOURCE_START_DPF     start_dpf;
+	ACPI_RESOURCE_IO            io;
+	ACPI_RESOURCE_FIXED_IO      fixed_io;
+	ACPI_RESOURCE_VENDOR        vendor_specific;
+	ACPI_RESOURCE_MEM24         memory24;
+	ACPI_RESOURCE_MEM32         memory32;
+	ACPI_RESOURCE_FIXED_MEM32   fixed_memory32;
+	ACPI_RESOURCE_ADDRESS16     address16;
+	ACPI_RESOURCE_ADDRESS32     address32;
+	ACPI_RESOURCE_ADDRESS64     address64;
+	ACPI_RESOURCE_EXT_IRQ       extended_irq;
+
+} ACPI_RESOURCE_DATA;
 
-typedef struct _resource_tag
+typedef struct acpi_resource
 {
-	RESOURCE_TYPE               id;
+	ACPI_RESOURCE_TYPE          id;
 	u32                         length;
-	RESOURCE_DATA               data;
-} RESOURCE;
+	ACPI_RESOURCE_DATA          data;
+
+} ACPI_RESOURCE;
+
+#define ACPI_RESOURCE_LENGTH            12
+#define ACPI_RESOURCE_LENGTH_NO_DATA    8       /* Id + Length fields */
+
+#define SIZEOF_RESOURCE(type)   (ACPI_RESOURCE_LENGTH_NO_DATA + sizeof (type))
 
-#define RESOURCE_LENGTH                 12
-#define RESOURCE_LENGTH_NO_DATA         8
+#define NEXT_RESOURCE(res)      (ACPI_RESOURCE *)((u8 *) res + res->length)
 
-#define NEXT_RESOURCE(res)    (RESOURCE*)((u8*) res + res->length)
 
 /*
  * END: Definitions for Resource Attributes
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/acutils.h linux/drivers/acpi/include/acutils.h
--- v2.4.5/linux/drivers/acpi/include/acutils.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/include/acutils.h	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,663 @@
+/******************************************************************************
+ *
+ * Name: acutils.h -- prototypes for the common (subsystem-wide) procedures
+ *       $Revision: 100 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _ACUTILS_H
+#define _ACUTILS_H
+
+
+typedef
+ACPI_STATUS (*ACPI_PKG_CALLBACK) (
+	u8                      object_type,
+	ACPI_OPERAND_OBJECT     *source_object,
+	ACPI_GENERIC_STATE      *state,
+	void                    *context);
+
+
+ACPI_STATUS
+acpi_ut_walk_package_tree (
+	ACPI_OPERAND_OBJECT     *source_object,
+	void                    *target_object,
+	ACPI_PKG_CALLBACK       walk_callback,
+	void                    *context);
+
+
+typedef struct acpi_pkg_info
+{
+	u8                      *free_space;
+	u32                     length;
+	u32                     object_space;
+	u32                     num_packages;
+} ACPI_PKG_INFO;
+
+#define REF_INCREMENT       (u16) 0
+#define REF_DECREMENT       (u16) 1
+#define REF_FORCE_DELETE    (u16) 2
+
+/* Acpi_ut_dump_buffer */
+
+#define DB_BYTE_DISPLAY     1
+#define DB_WORD_DISPLAY     2
+#define DB_DWORD_DISPLAY    4
+#define DB_QWORD_DISPLAY    8
+
+
+/* Global initialization interfaces */
+
+void
+acpi_ut_init_globals (
+	void);
+
+void
+acpi_ut_terminate (
+	void);
+
+
+/*
+ * Ut_init - miscellaneous initialization and shutdown
+ */
+
+ACPI_STATUS
+acpi_ut_hardware_initialize (
+	void);
+
+ACPI_STATUS
+acpi_ut_subsystem_shutdown (
+	void);
+
+ACPI_STATUS
+acpi_ut_validate_fadt (
+	void);
+
+/*
+ * Ut_global - Global data structures and procedures
+ */
+
+#ifdef ACPI_DEBUG
+
+NATIVE_CHAR *
+acpi_ut_get_mutex_name (
+	u32                     mutex_id);
+
+NATIVE_CHAR *
+acpi_ut_get_type_name (
+	u32                     type);
+
+NATIVE_CHAR *
+acpi_ut_get_region_name (
+	u8                      space_id);
+
+#endif
+
+
+u8
+acpi_ut_valid_object_type (
+	u32                     type);
+
+ACPI_OWNER_ID
+acpi_ut_allocate_owner_id (
+	u32                     id_type);
+
+
+/*
+ * Ut_clib - Local implementations of C library functions
+ */
+
+#ifndef ACPI_USE_SYSTEM_CLIBRARY
+
+u32
+acpi_ut_strlen (
+	const NATIVE_CHAR       *string);
+
+NATIVE_CHAR *
+acpi_ut_strcpy (
+	NATIVE_CHAR             *dst_string,
+	const NATIVE_CHAR       *src_string);
+
+NATIVE_CHAR *
+acpi_ut_strncpy (
+	NATIVE_CHAR             *dst_string,
+	const NATIVE_CHAR       *src_string,
+	NATIVE_UINT             count);
+
+u32
+acpi_ut_strncmp (
+	const NATIVE_CHAR       *string1,
+	const NATIVE_CHAR       *string2,
+	NATIVE_UINT             count);
+
+u32
+acpi_ut_strcmp (
+	const NATIVE_CHAR       *string1,
+	const NATIVE_CHAR       *string2);
+
+NATIVE_CHAR *
+acpi_ut_strcat (
+	NATIVE_CHAR             *dst_string,
+	const NATIVE_CHAR       *src_string);
+
+NATIVE_CHAR *
+acpi_ut_strncat (
+	NATIVE_CHAR             *dst_string,
+	const NATIVE_CHAR       *src_string,
+	NATIVE_UINT             count);
+
+u32
+acpi_ut_strtoul (
+	const NATIVE_CHAR       *string,
+	NATIVE_CHAR             **terminator,
+	u32                     base);
+
+NATIVE_CHAR *
+acpi_ut_strstr (
+	NATIVE_CHAR             *string1,
+	NATIVE_CHAR             *string2);
+
+void *
+acpi_ut_memcpy (
+	void                    *dest,
+	const void              *src,
+	NATIVE_UINT             count);
+
+void *
+acpi_ut_memset (
+	void                    *dest,
+	NATIVE_UINT             value,
+	NATIVE_UINT             count);
+
+u32
+acpi_ut_to_upper (
+	u32                     c);
+
+u32
+acpi_ut_to_lower (
+	u32                     c);
+
+#endif /* ACPI_USE_SYSTEM_CLIBRARY */
+
+/*
+ * Ut_copy - Object construction and conversion interfaces
+ */
+
+ACPI_STATUS
+acpi_ut_build_simple_object(
+	ACPI_OPERAND_OBJECT     *obj,
+	ACPI_OBJECT             *user_obj,
+	u8                      *data_space,
+	u32                     *buffer_space_used);
+
+ACPI_STATUS
+acpi_ut_build_package_object (
+	ACPI_OPERAND_OBJECT     *obj,
+	u8                      *buffer,
+	u32                     *space_used);
+
+ACPI_STATUS
+acpi_ut_copy_iobject_to_eobject (
+	ACPI_OPERAND_OBJECT     *obj,
+	ACPI_BUFFER             *ret_buffer);
+
+ACPI_STATUS
+acpi_ut_copy_esimple_to_isimple(
+	ACPI_OBJECT             *user_obj,
+	ACPI_OPERAND_OBJECT     *obj);
+
+ACPI_STATUS
+acpi_ut_copy_eobject_to_iobject (
+	ACPI_OBJECT             *obj,
+	ACPI_OPERAND_OBJECT     *internal_obj);
+
+ACPI_STATUS
+acpi_ut_copy_isimple_to_isimple (
+	ACPI_OPERAND_OBJECT     *source_obj,
+	ACPI_OPERAND_OBJECT     *dest_obj);
+
+ACPI_STATUS
+acpi_ut_copy_ipackage_to_ipackage (
+	ACPI_OPERAND_OBJECT     *source_obj,
+	ACPI_OPERAND_OBJECT     *dest_obj,
+	ACPI_WALK_STATE         *walk_state);
+
+
+/*
+ * Ut_create - Object creation
+ */
+
+ACPI_STATUS
+acpi_ut_update_object_reference (
+	ACPI_OPERAND_OBJECT     *object,
+	u16                     action);
+
+ACPI_OPERAND_OBJECT  *
+_ut_create_internal_object (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	ACPI_OBJECT_TYPE8       type);
+
+
+/*
+ * Ut_debug - Debug interfaces
+ */
+
+u32
+get_debug_level (
+	void);
+
+void
+set_debug_level (
+	u32                     level);
+
+void
+function_trace (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	NATIVE_CHAR             *function_name);
+
+void
+function_trace_ptr (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	NATIVE_CHAR             *function_name,
+	void                    *pointer);
+
+void
+function_trace_u32 (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	NATIVE_CHAR             *function_name,
+	u32                     integer);
+
+void
+function_trace_str (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	NATIVE_CHAR             *function_name,
+	NATIVE_CHAR             *string);
+
+void
+function_exit (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	NATIVE_CHAR             *function_name);
+
+void
+function_status_exit (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	NATIVE_CHAR             *function_name,
+	ACPI_STATUS             status);
+
+void
+function_value_exit (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	NATIVE_CHAR             *function_name,
+	ACPI_INTEGER            value);
+
+void
+function_ptr_exit (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	NATIVE_CHAR             *function_name,
+	u8                      *ptr);
+
+void
+debug_print_prefix (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number);
+
+void
+debug_print (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	u32                     print_level,
+	NATIVE_CHAR             *format, ...);
+
+void
+debug_print_raw (
+	NATIVE_CHAR             *format, ...);
+
+void
+_report_info (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id);
+
+void
+_report_error (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id);
+
+void
+_report_warning (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id);
+
+void
+acpi_ut_dump_buffer (
+	u8                      *buffer,
+	u32                     count,
+	u32                     display,
+	u32                     component_id);
+
+
+/*
+ * Ut_delete - Object deletion
+ */
+
+void
+acpi_ut_delete_internal_obj (
+	ACPI_OPERAND_OBJECT     *object);
+
+void
+acpi_ut_delete_internal_package_object (
+	ACPI_OPERAND_OBJECT     *object);
+
+void
+acpi_ut_delete_internal_simple_object (
+	ACPI_OPERAND_OBJECT     *object);
+
+ACPI_STATUS
+acpi_ut_delete_internal_object_list (
+	ACPI_OPERAND_OBJECT     **obj_list);
+
+
+/*
+ * Ut_eval - object evaluation
+ */
+
+/* Method name strings */
+
+#define METHOD_NAME__HID        "_HID"
+#define METHOD_NAME__UID        "_UID"
+#define METHOD_NAME__ADR        "_ADR"
+#define METHOD_NAME__STA        "_STA"
+#define METHOD_NAME__REG        "_REG"
+#define METHOD_NAME__SEG        "_SEG"
+#define METHOD_NAME__BBN        "_BBN"
+
+
+ACPI_STATUS
+acpi_ut_evaluate_numeric_object (
+	NATIVE_CHAR             *object_name,
+	ACPI_NAMESPACE_NODE     *device_node,
+	ACPI_INTEGER            *address);
+
+ACPI_STATUS
+acpi_ut_execute_HID (
+	ACPI_NAMESPACE_NODE     *device_node,
+	ACPI_DEVICE_ID          *hid);
+
+ACPI_STATUS
+acpi_ut_execute_STA (
+	ACPI_NAMESPACE_NODE     *device_node,
+	u32                     *status_flags);
+
+ACPI_STATUS
+acpi_ut_execute_UID (
+	ACPI_NAMESPACE_NODE     *device_node,
+	ACPI_DEVICE_ID          *uid);
+
+
+/*
+ * Ut_error - exception interfaces
+ */
+
+NATIVE_CHAR *
+acpi_ut_format_exception (
+	ACPI_STATUS             status);
+
+
+/*
+ * Ut_mutex - mutual exclusion interfaces
+ */
+
+ACPI_STATUS
+acpi_ut_mutex_initialize (
+	void);
+
+void
+acpi_ut_mutex_terminate (
+	void);
+
+ACPI_STATUS
+acpi_ut_create_mutex (
+	ACPI_MUTEX_HANDLE       mutex_id);
+
+ACPI_STATUS
+acpi_ut_delete_mutex (
+	ACPI_MUTEX_HANDLE       mutex_id);
+
+ACPI_STATUS
+acpi_ut_acquire_mutex (
+	ACPI_MUTEX_HANDLE       mutex_id);
+
+ACPI_STATUS
+acpi_ut_release_mutex (
+	ACPI_MUTEX_HANDLE       mutex_id);
+
+
+/*
+ * Ut_object - internal object create/delete/cache routines
+ */
+
+void *
+_ut_allocate_object_desc (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id);
+
+#define acpi_ut_create_internal_object(t) _ut_create_internal_object(_THIS_MODULE,__LINE__,_COMPONENT,t)
+#define acpi_ut_allocate_object_desc()  _ut_allocate_object_desc(_THIS_MODULE,__LINE__,_COMPONENT)
+
+void
+acpi_ut_delete_object_desc (
+	ACPI_OPERAND_OBJECT     *object);
+
+u8
+acpi_ut_valid_internal_object (
+	void                    *object);
+
+
+/*
+ * Ut_ref_cnt - Object reference count management
+ */
+
+void
+acpi_ut_add_reference (
+	ACPI_OPERAND_OBJECT     *object);
+
+void
+acpi_ut_remove_reference (
+	ACPI_OPERAND_OBJECT     *object);
+
+/*
+ * Ut_size - Object size routines
+ */
+
+ACPI_STATUS
+acpi_ut_get_simple_object_size (
+	ACPI_OPERAND_OBJECT     *obj,
+	u32                     *obj_length);
+
+ACPI_STATUS
+acpi_ut_get_package_object_size (
+	ACPI_OPERAND_OBJECT     *obj,
+	u32                     *obj_length);
+
+ACPI_STATUS
+acpi_ut_get_object_size(
+	ACPI_OPERAND_OBJECT     *obj,
+	u32                     *obj_length);
+
+
+/*
+ * Ut_state - Generic state creation/cache routines
+ */
+
+void
+acpi_ut_push_generic_state (
+	ACPI_GENERIC_STATE      **list_head,
+	ACPI_GENERIC_STATE      *state);
+
+ACPI_GENERIC_STATE *
+acpi_ut_pop_generic_state (
+	ACPI_GENERIC_STATE      **list_head);
+
+
+ACPI_GENERIC_STATE *
+acpi_ut_create_generic_state (
+	void);
+
+ACPI_GENERIC_STATE *
+acpi_ut_create_update_state (
+	ACPI_OPERAND_OBJECT     *object,
+	u16                     action);
+
+ACPI_GENERIC_STATE *
+acpi_ut_create_pkg_state (
+	void                    *internal_object,
+	void                    *external_object,
+	u16                     index);
+
+ACPI_STATUS
+acpi_ut_create_update_state_and_push (
+	ACPI_OPERAND_OBJECT     *object,
+	u16                     action,
+	ACPI_GENERIC_STATE      **state_list);
+
+ACPI_STATUS
+acpi_ut_create_pkg_state_and_push (
+	void                    *internal_object,
+	void                    *external_object,
+	u16                     index,
+	ACPI_GENERIC_STATE      **state_list);
+
+ACPI_GENERIC_STATE *
+acpi_ut_create_control_state (
+	void);
+
+void
+acpi_ut_delete_generic_state (
+	ACPI_GENERIC_STATE      *state);
+
+void
+acpi_ut_delete_generic_state_cache (
+	void);
+
+void
+acpi_ut_delete_object_cache (
+	void);
+
+/*
+ * Ututils
+ */
+
+u8
+acpi_ut_valid_acpi_name (
+	u32                     name);
+
+u8
+acpi_ut_valid_acpi_character (
+	NATIVE_CHAR             character);
+
+NATIVE_CHAR *
+acpi_ut_strupr (
+	NATIVE_CHAR             *src_string);
+
+ACPI_STATUS
+acpi_ut_resolve_package_references (
+	ACPI_OPERAND_OBJECT     *obj_desc);
+
+
+#ifdef ACPI_DEBUG
+void
+acpi_ut_display_init_pathname (
+	ACPI_HANDLE             obj_handle,
+	char                    *path);
+
+#endif
+
+
+/*
+ * Memory allocation functions and related macros.
+ * Macros that expand to include filename and line number
+ */
+
+void *
+_ut_allocate (
+	u32                     size,
+	u32                     component,
+	NATIVE_CHAR             *module,
+	u32                     line);
+
+void *
+_ut_callocate (
+	u32                     size,
+	u32                     component,
+	NATIVE_CHAR             *module,
+	u32                     line);
+
+void
+_ut_free (
+	void                    *address,
+	u32                     component,
+	NATIVE_CHAR             *module,
+	u32                     line);
+
+void
+acpi_ut_init_static_object (
+	ACPI_OPERAND_OBJECT     *obj_desc);
+
+
+#ifdef ACPI_DEBUG_TRACK_ALLOCATIONS
+void
+acpi_ut_dump_allocation_info (
+	void);
+
+void
+acpi_ut_dump_current_allocations (
+	u32                     component,
+	NATIVE_CHAR             *module);
+#endif
+
+
+#define acpi_ut_allocate(a) _ut_allocate(a,_COMPONENT,_THIS_MODULE,__LINE__)
+#define acpi_ut_callocate(a) _ut_callocate(a, _COMPONENT,_THIS_MODULE,__LINE__)
+#define acpi_ut_free(a)     _ut_free(a,_COMPONENT,_THIS_MODULE,__LINE__)
+
+
+#endif /* _ACUTILS_H */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/amlcode.h linux/drivers/acpi/include/amlcode.h
--- v2.4.5/linux/drivers/acpi/include/amlcode.h	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/include/amlcode.h	Wed Jun 20 17:47:40 2001
@@ -3,7 +3,7 @@
  * Name: amlcode.h - Definitions for AML, as included in "definition blocks"
  *                   Declarations and definitions contained herein are derived
  *                   directly from the ACPI specification.
- *       $Revision: 46 $
+ *       $Revision: 52 $
  *
  *****************************************************************************/
 
@@ -98,12 +98,12 @@
 #define AML_SIZE_OF_OP              (u16) 0x87
 #define AML_INDEX_OP                (u16) 0x88
 #define AML_MATCH_OP                (u16) 0x89
-#define AML_DWORD_FIELD_OP          (u16) 0x8a
-#define AML_WORD_FIELD_OP           (u16) 0x8b
-#define AML_BYTE_FIELD_OP           (u16) 0x8c
-#define AML_BIT_FIELD_OP            (u16) 0x8d
+#define AML_CREATE_DWORD_FIELD_OP   (u16) 0x8a
+#define AML_CREATE_WORD_FIELD_OP    (u16) 0x8b
+#define AML_CREATE_BYTE_FIELD_OP    (u16) 0x8c
+#define AML_CREATE_BIT_FIELD_OP     (u16) 0x8d
 #define AML_TYPE_OP                 (u16) 0x8e
-#define AML_QWORD_FIELD_OP          (u16) 0x8f     /* ACPI 2.0 */
+#define AML_CREATE_QWORD_FIELD_OP   (u16) 0x8f     /* ACPI 2.0 */
 #define AML_LAND_OP                 (u16) 0x90
 #define AML_LOR_OP                  (u16) 0x91
 #define AML_LNOT_OP                 (u16) 0x92
@@ -154,7 +154,7 @@
 #define AML_DEBUG_OP                (u16) 0x5b31
 #define AML_FATAL_OP                (u16) 0x5b32
 #define AML_REGION_OP               (u16) 0x5b80
-#define AML_DEF_FIELD_OP            (u16) 0x5b81
+#define AML_FIELD_OP                (u16) 0x5b81
 #define AML_DEVICE_OP               (u16) 0x5b82
 #define AML_PROCESSOR_OP            (u16) 0x5b83
 #define AML_POWER_RES_OP            (u16) 0x5b84
@@ -177,14 +177,14 @@
  * any valid ACPI ASCII values (A-Z, 0-9, '-')
  */
 
-#define AML_NAMEPATH_OP             (u16) 0x002d
-#define AML_NAMEDFIELD_OP           (u16) 0x0030
-#define AML_RESERVEDFIELD_OP        (u16) 0x0031
-#define AML_ACCESSFIELD_OP          (u16) 0x0032
-#define AML_BYTELIST_OP             (u16) 0x0033
-#define AML_STATICSTRING_OP         (u16) 0x0034
-#define AML_METHODCALL_OP           (u16) 0x0035
-#define AML_RETURN_VALUE_OP         (u16) 0x0036
+#define AML_INT_NAMEPATH_OP         (u16) 0x002d
+#define AML_INT_NAMEDFIELD_OP       (u16) 0x0030
+#define AML_INT_RESERVEDFIELD_OP    (u16) 0x0031
+#define AML_INT_ACCESSFIELD_OP      (u16) 0x0032
+#define AML_INT_BYTELIST_OP         (u16) 0x0033
+#define AML_INT_STATICSTRING_OP     (u16) 0x0034
+#define AML_INT_METHODCALL_OP       (u16) 0x0035
+#define AML_INT_RETURN_VALUE_OP     (u16) 0x0036
 
 
 #define ARG_NONE                    0x0
@@ -222,7 +222,7 @@
 
 /* "Standard" ACPI types are 1-15 (0x0F) */
 
-#define ARGI_INTEGER                 ACPI_TYPE_INTEGER        /* 1 */
+#define ARGI_INTEGER                ACPI_TYPE_INTEGER       /* 1 */
 #define ARGI_STRING                 ACPI_TYPE_STRING        /* 2 */
 #define ARGI_BUFFER                 ACPI_TYPE_BUFFER        /* 3 */
 #define ARGI_PACKAGE                ACPI_TYPE_PACKAGE       /* 4 */
@@ -237,8 +237,8 @@
 #define ARGI_ANYOBJECT              0x11
 #define ARGI_ANYTYPE                0x12
 #define ARGI_COMPUTEDATA            0x13     /* Buffer, String, or Integer */
-#define ARGI_DATAOBJECT             0x14     /* Buffer, string, package or reference to a Node - Used only by Size_of operator*/
-#define ARGI_COMPLEXOBJ             0x15     /* Buffer or package */
+#define ARGI_DATAOBJECT             0x14     /* Buffer, String, package or reference to a Node - Used only by Size_of operator*/
+#define ARGI_COMPLEXOBJ             0x15     /* Buffer, String, or package (Used by INDEX op only) */
 #define ARGI_INTEGER_REF            0x16
 #define ARGI_OBJECT_REF             0x17
 #define ARGI_DEVICE_REF             0x18
@@ -312,13 +312,14 @@
 
 typedef enum
 {
-	REGION_MEMORY               = 0,
+	REGION_MEMORY                   = 0,
 	REGION_IO,
 	REGION_PCI_CONFIG,
 	REGION_EC,
 	REGION_SMBUS,
 	REGION_CMOS,
-	REGION_PCI_BAR
+	REGION_PCI_BAR,
+	REGION_FIXED_HW                 = 0x7F,
 
 } AML_REGION_TYPES;
 
@@ -327,80 +328,82 @@
 
 typedef enum
 {
-	MATCH_MTR                   = 0,
-	MATCH_MEQ                   = 1,
-	MATCH_MLE                   = 2,
-	MATCH_MLT                   = 3,
-	MATCH_MGE                   = 4,
-	MATCH_MGT                   = 5
+	MATCH_MTR                       = 0,
+	MATCH_MEQ                       = 1,
+	MATCH_MLE                       = 2,
+	MATCH_MLT                       = 3,
+	MATCH_MGE                       = 4,
+	MATCH_MGT                       = 5
 
 } AML_MATCH_OPERATOR;
 
-#define MAX_MATCH_OPERATOR      5
+#define MAX_MATCH_OPERATOR          5
 
 
 /* Field Access Types */
 
-#define ACCESS_TYPE_MASK        0x0f
-#define ACCESS_TYPE_SHIFT       0
+#define ACCESS_TYPE_MASK            0x0f
+#define ACCESS_TYPE_SHIFT           0
 
 typedef enum
 {
-	ACCESS_ANY_ACC              = 0,
-	ACCESS_BYTE_ACC             = 1,
-	ACCESS_WORD_ACC             = 2,
-	ACCESS_DWORD_ACC            = 3,
-	ACCESS_BLOCK_ACC            = 4,
-	ACCESS_SMBSEND_RECV_ACC     = 5,
-	ACCESS_SMBQUICK_ACC         = 6
+	ACCESS_ANY_ACC                  = 0,
+	ACCESS_BYTE_ACC                 = 1,
+	ACCESS_WORD_ACC                 = 2,
+	ACCESS_DWORD_ACC                = 3,
+	ACCESS_QWORD_ACC                = 4,    /* ACPI 2.0 */
+	ACCESS_BLOCK_ACC                = 4,
+	ACCESS_SMBSEND_RECV_ACC         = 5,
+	ACCESS_SMBQUICK_ACC             = 6
 
 } AML_ACCESS_TYPE;
 
 
 /* Field Lock Rules */
 
-#define LOCK_RULE_MASK          0x10
-#define LOCK_RULE_SHIFT         4
+#define LOCK_RULE_MASK              0x10
+#define LOCK_RULE_SHIFT             4
 
 typedef enum
 {
-	GLOCK_NEVER_LOCK            = 0,
-	GLOCK_ALWAYS_LOCK           = 1
+	GLOCK_NEVER_LOCK                = 0,
+	GLOCK_ALWAYS_LOCK               = 1
 
 } AML_LOCK_RULE;
 
 
 /* Field Update Rules */
 
-#define UPDATE_RULE_MASK        0x060
-#define UPDATE_RULE_SHIFT       5
+#define UPDATE_RULE_MASK            0x060
+#define UPDATE_RULE_SHIFT           5
 
 typedef enum
 {
-	UPDATE_PRESERVE             = 0,
-	UPDATE_WRITE_AS_ONES        = 1,
-	UPDATE_WRITE_AS_ZEROS       = 2
+	UPDATE_PRESERVE                 = 0,
+	UPDATE_WRITE_AS_ONES            = 1,
+	UPDATE_WRITE_AS_ZEROS           = 2
 
 } AML_UPDATE_RULE;
 
 
 /* bit fields in Method_flags byte */
 
-#define METHOD_FLAGS_ARG_COUNT  0x07
-#define METHOD_FLAGS_SERIALIZED 0x08
+#define METHOD_FLAGS_ARG_COUNT      0x07
+#define METHOD_FLAGS_SERIALIZED     0x08
+#define METHOD_FLAGS_SYNCH_LEVEL    0xF0
 
 
 /* Array sizes.  Used for range checking also */
 
-#define NUM_REGION_TYPES        7
-#define NUM_ACCESS_TYPES        7
-#define NUM_UPDATE_RULES        3
-#define NUM_MATCH_OPS           7
-#define NUM_OPCODES             256
-#define NUM_FIELD_NAMES         2
+#define NUM_REGION_TYPES            7
+#define NUM_ACCESS_TYPES            7
+#define NUM_UPDATE_RULES            3
+#define NUM_MATCH_OPS               7
+#define NUM_OPCODES                 256
+#define NUM_FIELD_NAMES             2
 
 
-#define USER_REGION_BEGIN       0x80
+#define USER_REGION_BEGIN           0x80
 
 /*
  * AML tables
@@ -408,7 +411,7 @@
 
 #ifdef DEFINE_AML_GLOBALS
 
-/* External declarations of the AML tables */
+/* External declarations for the AML tables */
 
 extern u8                       acpi_gbl_aml            [NUM_OPCODES];
 extern u16                      acpi_gbl_pfx            [NUM_OPCODES];
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/platform/acenv.h linux/drivers/acpi/include/platform/acenv.h
--- v2.4.5/linux/drivers/acpi/include/platform/acenv.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/include/platform/acenv.h	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,288 @@
+/******************************************************************************
+ *
+ * Name: acenv.h - Generation environment specific items
+ *       $Revision: 75 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ACENV_H__
+#define __ACENV_H__
+
+
+/*
+ * Configuration for ACPI tools and utilities
+ */
+
+#ifdef _ACPI_DUMP_APP
+#define ACPI_DEBUG
+#define ACPI_APPLICATION
+#define ENABLE_DEBUGGER
+#define ACPI_USE_SYSTEM_CLIBRARY
+#define PARSER_ONLY
+#endif
+
+#ifdef _ACPI_EXEC_APP
+#undef DEBUGGER_THREADING
+#define DEBUGGER_THREADING      DEBUGGER_SINGLE_THREADED
+#define ACPI_DEBUG
+#define ACPI_APPLICATION
+#define ENABLE_DEBUGGER
+#define ACPI_USE_SYSTEM_CLIBRARY
+#endif
+
+#ifdef _ACPI_ASL_COMPILER
+#define ACPI_DEBUG
+#define ACPI_APPLICATION
+#define ENABLE_DEBUGGER
+#define ACPI_USE_SYSTEM_CLIBRARY
+#endif
+
+/*
+ * Memory allocation tracking.  Used only if
+ * 1) This is the debug version
+ * 2) This is NOT a 16-bit version of the code (not enough real-mode memory)
+ */
+#ifdef ACPI_DEBUG
+#ifndef _IA16
+#define ACPI_DEBUG_TRACK_ALLOCATIONS
+#endif
+#endif
+
+/*
+ * Environment configuration.  The purpose of this file is to interface to the
+ * local generation environment.
+ *
+ * 1) ACPI_USE_SYSTEM_CLIBRARY - Define this if linking to an actual C library.
+ *      Otherwise, local versions of string/memory functions will be used.
+ * 2) ACPI_USE_STANDARD_HEADERS - Define this if linking to a C library and
+ *      the standard header files may be used.
+ *
+ * The ACPI subsystem only uses low level C library functions that do not call
+ * operating system services and may therefore be inlined in the code.
+ *
+ * It may be necessary to tailor these include files to the target
+ * generation environment.
+ *
+ *
+ * Functions and constants used from each header:
+ *
+ * string.h:    memcpy
+ *              memset
+ *              strcat
+ *              strcmp
+ *              strcpy
+ *              strlen
+ *              strncmp
+ *              strncat
+ *              strncpy
+ *
+ * stdlib.h:    strtoul
+ *
+ * stdarg.h:    va_list
+ *              va_arg
+ *              va_start
+ *              va_end
+ *
+ */
+
+/*! [Begin] no source code translation */
+
+#ifdef _LINUX
+#include "aclinux.h"
+
+#elif _AED_EFI
+#include "acefi.h"
+
+#elif WIN32
+#include "acwin.h"
+
+#elif __FreeBSD__
+#include "acfreebsd.h"
+
+#else
+
+/* All other environments */
+
+#define ACPI_USE_STANDARD_HEADERS
+
+/* Name of host operating system (returned by the _OS_ namespace object) */
+
+#define ACPI_OS_NAME         "Intel ACPI/CA Core Subsystem"
+
+#endif
+
+
+/*! [End] no source code translation !*/
+
+/******************************************************************************
+ *
+ * C library configuration
+ *
+ *****************************************************************************/
+
+#ifdef ACPI_USE_SYSTEM_CLIBRARY
+/*
+ * Use the standard C library headers.
+ * We want to keep these to a minimum.
+ *
+ */
+
+#ifdef ACPI_USE_STANDARD_HEADERS
+/*
+ * Use the standard headers from the standard locations
+ */
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#endif /* ACPI_USE_STANDARD_HEADERS */
+
+/*
+ * We will be linking to the standard Clib functions
+ */
+
+#define STRSTR(s1,s2)   strstr((s1), (s2))
+#define STRUPR(s)       acpi_ut_strupr ((s))
+#define STRLEN(s)       (u32) strlen((s))
+#define STRCPY(d,s)     strcpy((d), (s))
+#define STRNCPY(d,s,n)  strncpy((d), (s), (NATIVE_INT)(n))
+#define STRNCMP(d,s,n)  strncmp((d), (s), (NATIVE_INT)(n))
+#define STRCMP(d,s)     strcmp((d), (s))
+#define STRCAT(d,s)     strcat((d), (s))
+#define STRNCAT(d,s,n)  strncat((d), (s), (NATIVE_INT)(n))
+#define STRTOUL(d,s,n)  strtoul((d), (s), (NATIVE_INT)(n))
+#define MEMCPY(d,s,n)   memcpy((d), (s), (NATIVE_INT)(n))
+#define MEMSET(d,s,n)   memset((d), (s), (NATIVE_INT)(n))
+#define TOUPPER         toupper
+#define TOLOWER         tolower
+#define IS_XDIGIT       isxdigit
+
+/******************************************************************************
+ *
+ * Not using native C library, use local implementations
+ *
+ *****************************************************************************/
+#else
+
+/*
+ * Use local definitions of C library macros and functions
+ * NOTE: The function implementations may not be as efficient
+ * as an inline or assembly code implementation provided by a
+ * native C library.
+ */
+
+#ifndef va_arg
+
+#ifndef _VALIST
+#define _VALIST
+typedef char *va_list;
+#endif /* _VALIST */
+
+/*
+ * Storage alignment properties
+ */
+
+#define  _AUPBND         (sizeof (NATIVE_INT) - 1)
+#define  _ADNBND         (sizeof (NATIVE_INT) - 1)
+
+/*
+ * Variable argument list macro definitions
+ */
+
+#define _bnd(X, bnd)    (((sizeof (X)) + (bnd)) & (~(bnd)))
+#define va_arg(ap, T)   (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))
+#define va_end(ap)      (void) 0
+#define va_start(ap, A) (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))
+
+#endif /* va_arg */
+
+
+#define STRSTR(s1,s2)    acpi_ut_strstr ((s1), (s2))
+#define STRUPR(s)        acpi_ut_strupr ((s))
+#define STRLEN(s)        acpi_ut_strlen ((s))
+#define STRCPY(d,s)      acpi_ut_strcpy ((d), (s))
+#define STRNCPY(d,s,n)   acpi_ut_strncpy ((d), (s), (n))
+#define STRNCMP(d,s,n)   acpi_ut_strncmp ((d), (s), (n))
+#define STRCMP(d,s)      acpi_ut_strcmp ((d), (s))
+#define STRCAT(d,s)      acpi_ut_strcat ((d), (s))
+#define STRNCAT(d,s,n)   acpi_ut_strncat ((d), (s), (n))
+#define STRTOUL(d,s,n)   acpi_ut_strtoul ((d), (s),(n))
+#define MEMCPY(d,s,n)    acpi_ut_memcpy ((d), (s), (n))
+#define MEMSET(d,v,n)    acpi_ut_memset ((d), (v), (n))
+#define TOUPPER          acpi_ut_to_upper
+#define TOLOWER          acpi_ut_to_lower
+
+#endif /* ACPI_USE_SYSTEM_CLIBRARY */
+
+
+/******************************************************************************
+ *
+ * Assembly code macros
+ *
+ *****************************************************************************/
+
+/*
+ * Handle platform- and compiler-specific assembly language differences.
+ * These should already have been defined by the platform includes above.
+ *
+ * Notes:
+ * 1) Interrupt 3 is used to break into a debugger
+ * 2) Interrupts are turned off during ACPI register setup
+ */
+
+/* Unrecognized compiler, use defaults */
+#ifndef ACPI_ASM_MACROS
+
+#define ACPI_ASM_MACROS
+#define causeinterrupt(level)
+#define BREAKPOINT3
+#define disable()
+#define enable()
+#define halt()
+#define ACPI_ACQUIRE_GLOBAL_LOCK(Glptr, acq)
+#define ACPI_RELEASE_GLOBAL_LOCK(Glptr, acq)
+
+#endif /* ACPI_ASM_MACROS */
+
+
+#ifdef ACPI_APPLICATION
+
+/* Don't want software interrupts within a ring3 application */
+
+#undef causeinterrupt
+#undef BREAKPOINT3
+#define causeinterrupt(level)
+#define BREAKPOINT3
+#endif
+
+
+/******************************************************************************
+ *
+ * Compiler-specific
+ *
+ *****************************************************************************/
+
+/* this has been moved to compiler-specific headers, which are included from the
+   platform header. */
+
+
+#endif /* __ACENV_H__ */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/platform/acgcc.h linux/drivers/acpi/include/platform/acgcc.h
--- v2.4.5/linux/drivers/acpi/include/platform/acgcc.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/include/platform/acgcc.h	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,147 @@
+/******************************************************************************
+ *
+ * Name: acgcc.h - GCC specific defines, etc.
+ *       $Revision: 6 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ACGCC_H__
+#define __ACGCC_H__
+
+
+#ifdef __ia64__
+#define _IA64
+
+#define COMPILER_DEPENDENT_UINT64   unsigned long
+/* Single threaded */
+#define ACPI_APPLICATION
+
+#define ACPI_ASM_MACROS
+#define causeinterrupt(level)
+#define BREAKPOINT3
+#define disable() __cli()
+#define enable()  __sti()
+#define wbinvd()
+
+/*! [Begin] no source code translation */
+
+#include <asm/pal.h>
+
+#define halt()              ia64_pal_halt_light()           /* PAL_HALT[_LIGHT] */
+#define safe_halt()         ia64_pal_halt(1)                /* PAL_HALT */
+
+
+#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
+	do { \
+	__asm__ volatile ("1:  ld4      r29=%1\n"  \
+		";;\n"                  \
+		"mov    ar.ccv=r29\n"   \
+		"mov    r2=r29\n"       \
+		"shr.u  r30=r29,1\n"    \
+		"and    r29=-4,r29\n"   \
+		";;\n"                  \
+		"add    r29=2,r29\n"    \
+		"and    r30=1,r30\n"    \
+		";;\n"                  \
+		"add    r29=r29,r30\n"  \
+		";;\n"                  \
+		"cmpxchg4.acq   r30=%1,r29,ar.ccv\n" \
+		";;\n"                  \
+		"cmp.eq p6,p7=r2,r30\n" \
+		"(p7) br.dpnt.few 1b\n" \
+		"cmp.gt p8,p9=3,r29\n"  \
+		";;\n"                  \
+		"(p8) mov %0=-1\n"      \
+		"(p9) mov %0=r0\n"      \
+		:"=r"(Acq):"m"(GLptr):"r2","r29","r30","memory"); \
+	} while (0)
+
+#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \
+	do { \
+	__asm__ volatile ("1:  ld4      r29=%1\n" \
+		";;\n"                  \
+		"mov    ar.ccv=r29\n"   \
+		"mov    r2=r29\n"       \
+		"and    r29=-4,r29\n"   \
+		";;\n"                  \
+		"cmpxchg4.acq   r30=%1,r29,ar.ccv\n" \
+		";;\n"                  \
+		"cmp.eq p6,p7=r2,r30\n" \
+		"(p7) br.dpnt.few 1b\n" \
+		"and    %0=1,r2\n"      \
+		";;\n"                  \
+		:"=r"(Acq):"m"(GLptr):"r2","r29","r30","memory"); \
+	} while (0)
+/*! [End] no source code translation !*/
+
+
+#else /* DO IA32 */
+#define COMPILER_DEPENDENT_UINT64   unsigned long long
+#define ACPI_ASM_MACROS
+#define causeinterrupt(level)
+#define BREAKPOINT3
+#define disable() __cli()
+#define enable()  __sti()
+#define halt()    __asm__ __volatile__ ("sti; hlt":::"memory")
+#define wbinvd()
+
+/*! [Begin] no source code translation
+ *
+ * A brief explanation as GNU inline assembly is a bit hairy
+ *  %0 is the output parameter in EAX ("=a")
+ *  %1 and %2 are the input parameters in ECX ("c")
+ *  and an immediate value ("i") respectively
+ *  All actual register references are preceded with "%%" as in "%%edx"
+ *  Immediate values in the assembly are preceded by "$" as in "$0x1"
+ *  The final asm parameter are the operation altered non-output registers.
+ */
+#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
+	do { \
+		int dummy; \
+		asm("1:     movl (%1),%%eax;" \
+			"movl   %%eax,%%edx;" \
+			"andl   %2,%%edx;" \
+			"btsl   $0x1,%%edx;" \
+			"adcl   $0x0,%%edx;" \
+			"lock;  cmpxchgl %%edx,(%1);" \
+			"jnz    1b;" \
+			"cmpb   $0x3,%%dl;" \
+			"sbbl   %%eax,%%eax" \
+			:"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~1L):"dx"); \
+	} while(0)
+
+#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \
+	do { \
+		int dummy; \
+		asm("1:     movl (%1),%%eax;" \
+			"movl   %%eax,%%edx;" \
+			"andl   %2,%%edx;" \
+			"lock;  cmpxchgl %%edx,(%1);" \
+			"jnz    1b;" \
+			"andl   $0x1,%%eax" \
+			:"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~3L):"dx"); \
+	} while(0)
+
+/*! [End] no source code translation !*/
+
+#endif /* IA 32 */
+
+#endif /* __ACGCC_H__ */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/include/platform/aclinux.h linux/drivers/acpi/include/platform/aclinux.h
--- v2.4.5/linux/drivers/acpi/include/platform/aclinux.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/include/platform/aclinux.h	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,71 @@
+/******************************************************************************
+ *
+ * Name: aclinux.h - OS specific defines, etc.
+ *       $Revision: 13 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ACLINUX_H__
+#define __ACLINUX_H__
+
+#define ACPI_OS_NAME                "Linux"
+
+#define ACPI_USE_SYSTEM_CLIBRARY
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/ctype.h>
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <asm/div64.h>
+
+#define strtoul simple_strtoul
+
+#else
+
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#endif
+
+/* Linux uses GCC */
+
+#include "acgcc.h"
+
+#undef DEBUGGER_THREADING
+#define DEBUGGER_THREADING          DEBUGGER_SINGLE_THREADED
+
+#ifndef _IA64
+/* Linux ia32 can't do int64 well */
+#define ACPI_NO_INTEGER64_SUPPORT
+/* And the ia32 kernel doesn't include 64-bit divide support */
+#define ACPI_DIV64(dividend, divisor) do_div(dividend, divisor)
+#else
+#define ACPI_DIV64(dividend, divisor) ACPI_DIVIDE(dividend, divisor)
+#endif
+
+
+#endif /* __ACLINUX_H__ */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/Makefile linux/drivers/acpi/interpreter/Makefile
--- v2.4.5/linux/drivers/acpi/interpreter/Makefile	Fri Dec 29 14:07:21 2000
+++ linux/drivers/acpi/interpreter/Makefile	Wed Dec 31 16:00:00 1969
@@ -1,16 +0,0 @@
-#
-# Makefile for all Linux ACPI interpreter subdirectories
-#
-
-O_TARGET := ../$(shell basename `pwd`).o
-
-obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c))
-
-EXTRA_CFLAGS += -I../include
-
-EXTRA_CFLAGS += $(ACPI_CFLAGS)
-
-include $(TOPDIR)/Rules.make
-
-clean:
-	$(RM) *.o 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/amconfig.c linux/drivers/acpi/interpreter/amconfig.c
--- v2.4.5/linux/drivers/acpi/interpreter/amconfig.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/interpreter/amconfig.c	Wed Dec 31 16:00:00 1969
@@ -1,306 +0,0 @@
-/******************************************************************************
- *
- * Module Name: amconfig - Namespace reconfiguration (Load/Unload opcodes)
- *              $Revision: 29 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acparser.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acnamesp.h"
-#include "acevents.h"
-#include "actables.h"
-#include "acdispat.h"
-
-
-#define _COMPONENT          INTERPRETER
-	 MODULE_NAME         ("amconfig")
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_load_table
- *
- * PARAMETERS:  Rgn_desc        - Op region where the table will be obtained
- *              Ddb_handle      - Where a handle to the table will be returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Load an ACPI table
- *
- ****************************************************************************/
-
-static ACPI_STATUS
-acpi_aml_exec_load_table (
-	ACPI_OPERAND_OBJECT     *rgn_desc,
-	ACPI_HANDLE             *ddb_handle)
-{
-	ACPI_STATUS             status;
-	ACPI_OPERAND_OBJECT     *table_desc = NULL;
-	u8                      *table_ptr;
-	u8                      *table_data_ptr;
-	ACPI_TABLE_HEADER       table_header;
-	ACPI_TABLE_DESC         table_info;
-	u32                     i;
-
-
-	/* TBD: [Unhandled] Object can be either a field or an opregion */
-
-
-	/* Get the table header */
-
-	table_header.length = 0;
-	for (i = 0; i < sizeof (ACPI_TABLE_HEADER); i++) {
-		status = acpi_ev_address_space_dispatch (rgn_desc, ADDRESS_SPACE_READ,
-				   (ACPI_PHYSICAL_ADDRESS) i, 8,
-				   (u32 *) ((u8 *) &table_header + i));
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-	}
-
-	/* Allocate a buffer for the entire table */
-
-	table_ptr = acpi_cm_allocate (table_header.length);
-	if (!table_ptr) {
-		return (AE_NO_MEMORY);
-	}
-
-	/* Copy the header to the buffer */
-
-	MEMCPY (table_ptr, &table_header, sizeof (ACPI_TABLE_HEADER));
-	table_data_ptr = table_ptr + sizeof (ACPI_TABLE_HEADER);
-
-
-	/* Get the table from the op region */
-
-	for (i = 0; i < table_header.length; i++) {
-		status = acpi_ev_address_space_dispatch (rgn_desc, ADDRESS_SPACE_READ,
-				   (ACPI_PHYSICAL_ADDRESS)i, 8,
-				   (u32 *) (table_data_ptr + i));
-		if (ACPI_FAILURE (status)) {
-			goto cleanup;
-		}
-	}
-
-
-	/* Table must be either an SSDT or a PSDT */
-
-	if ((!STRNCMP (table_header.signature,
-			  acpi_gbl_acpi_table_data[ACPI_TABLE_PSDT].signature,
-			  acpi_gbl_acpi_table_data[ACPI_TABLE_PSDT].sig_length)) &&
-		(!STRNCMP (table_header.signature,
-				 acpi_gbl_acpi_table_data[ACPI_TABLE_SSDT].signature,
-				 acpi_gbl_acpi_table_data[ACPI_TABLE_SSDT].sig_length)))
-	{
-		status = AE_BAD_SIGNATURE;
-		goto cleanup;
-	}
-
-	/* Create an object to be the table handle */
-
-	table_desc = acpi_cm_create_internal_object (INTERNAL_TYPE_REFERENCE);
-	if (!table_desc) {
-		status = AE_NO_MEMORY;
-		goto cleanup;
-	}
-
-
-	/* Install the new table into the local data structures */
-
-	table_info.pointer     = (ACPI_TABLE_HEADER *) table_ptr;
-	table_info.length      = table_header.length;
-	table_info.allocation  = ACPI_MEM_ALLOCATED;
-	table_info.base_pointer = table_ptr;
-
-	status = acpi_tb_install_table (NULL, &table_info);
-	if (ACPI_FAILURE (status)) {
-		goto cleanup;
-	}
-
-	/* Add the table to the namespace */
-
-	/* TBD: [Restructure] - change to whatever new interface is appropriate */
-/*
-	Status = Acpi_load_namespace ();
-	if (ACPI_FAILURE (Status)) {
-*/
-		/* TBD: [Errors] Unload the table on failure ? */
-/*
-		goto Cleanup;
-	}
-*/
-
-
-	/* TBD: [Investigate] we need a pointer to the table desc */
-
-	/* Init the table handle */
-
-	table_desc->reference.op_code = AML_LOAD_OP;
-	table_desc->reference.object = table_info.installed_desc;
-
-	*ddb_handle = table_desc;
-
-	return (status);
-
-
-cleanup:
-
-	acpi_cm_free (table_desc);
-	acpi_cm_free (table_ptr);
-	return (status);
-
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_unload_table
- *
- * PARAMETERS:  Ddb_handle          - Handle to a previously loaded table
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Unload an ACPI table
- *
- ****************************************************************************/
-
-static ACPI_STATUS
-acpi_aml_exec_unload_table (
-	ACPI_HANDLE             ddb_handle)
-{
-	ACPI_STATUS             status = AE_NOT_IMPLEMENTED;
-	ACPI_OPERAND_OBJECT     *table_desc = (ACPI_OPERAND_OBJECT *) ddb_handle;
-	ACPI_TABLE_DESC         *table_info;
-
-
-	/* Validate the handle */
-	/* Although the handle is partially validated in Acpi_aml_exec_reconfiguration(),
-	 *  when it calls Acpi_aml_resolve_operands(), the handle is more completely
-	 *  validated here.
-	 */
-
-	if ((!ddb_handle) ||
-		(!VALID_DESCRIPTOR_TYPE (ddb_handle, ACPI_DESC_TYPE_INTERNAL)) ||
-		(((ACPI_OPERAND_OBJECT  *)ddb_handle)->common.type !=
-				INTERNAL_TYPE_REFERENCE))
-	{
-		return (AE_BAD_PARAMETER);
-	}
-
-
-	/* Get the actual table descriptor from the Ddb_handle */
-
-	table_info = (ACPI_TABLE_DESC *) table_desc->reference.object;
-
-	/*
-	 * Delete the entire namespace under this table Node
-	 * (Offset contains the Table_id)
-	 */
-
-	status = acpi_ns_delete_namespace_by_owner (table_info->table_id);
-	if (ACPI_FAILURE (status)) {
-		return (status);
-	}
-
-	/* Delete the table itself */
-
-	acpi_tb_uninstall_table (table_info->installed_desc);
-
-	/* Delete the table descriptor (Ddb_handle) */
-
-	acpi_cm_remove_reference (table_desc);
-
-	return (status);
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_reconfiguration
- *
- * PARAMETERS:  Opcode              - The opcode to be executed
- *              Walk_state          - Current state of the parse tree walk
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Reconfiguration opcodes such as LOAD and UNLOAD
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_aml_exec_reconfiguration (
-	u16                     opcode,
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_STATUS             status;
-	ACPI_OPERAND_OBJECT     *region_desc = NULL;
-	ACPI_HANDLE             *ddb_handle;
-
-
-	/* Resolve the operands */
-
-	status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
-	/* Get the table handle, common for both opcodes */
-
-	status |= acpi_ds_obj_stack_pop_object ((ACPI_OPERAND_OBJECT **) &ddb_handle,
-			 walk_state);
-
-	switch (opcode)
-	{
-
-	case AML_LOAD_OP:
-
-		/* Get the region or field descriptor */
-
-		status |= acpi_ds_obj_stack_pop_object (&region_desc, walk_state);
-		if (ACPI_FAILURE (status)) {
-			acpi_cm_remove_reference (region_desc);
-			return (status);
-		}
-
-		status = acpi_aml_exec_load_table (region_desc, ddb_handle);
-		break;
-
-
-	case AML_UNLOAD_OP:
-
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-
-		status = acpi_aml_exec_unload_table (ddb_handle);
-		break;
-
-
-	default:
-
-		status = AE_AML_BAD_OPCODE;
-		break;
-	}
-
-
-	return (status);
-}
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/amconvrt.c linux/drivers/acpi/interpreter/amconvrt.c
--- v2.4.5/linux/drivers/acpi/interpreter/amconvrt.c	Mon Jan 29 10:15:59 2001
+++ linux/drivers/acpi/interpreter/amconvrt.c	Wed Dec 31 16:00:00 1969
@@ -1,525 +0,0 @@
-/******************************************************************************
- *
- * Module Name: amconvrt - Object conversion routines
- *              $Revision: 3 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acparser.h"
-#include "acnamesp.h"
-#include "acinterp.h"
-#include "acevents.h"
-#include "amlcode.h"
-#include "acdispat.h"
-
-
-#define _COMPONENT          INTERPRETER
-	 MODULE_NAME         ("amconvrt")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_convert_to_target_type
- *
- * PARAMETERS:  *Obj_desc       - Object to be converted.
- *              Walk_state      - Current method state
- *
- * RETURN:      Status
- *
- * DESCRIPTION:
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_convert_to_target_type (
-	OBJECT_TYPE_INTERNAL    destination_type,
-	ACPI_OPERAND_OBJECT     **obj_desc,
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_STATUS             status = AE_OK;
-
-
-	/*
-	 * If required by the target,
-	 * perform implicit conversion on the source before we store it.
-	 */
-
-	switch (GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args))
-	{
-	case ARGI_SIMPLE_TARGET:
-	case ARGI_FIXED_TARGET:
-	case ARGI_INTEGER_REF:      /* Handles Increment, Decrement cases */
-
-		switch (destination_type)
-		{
-		case INTERNAL_TYPE_DEF_FIELD:
-			/*
-			 * Named field can always handle conversions
-			 */
-			break;
-
-		default:
-			/* No conversion allowed for these types */
-
-			if (destination_type != (*obj_desc)->common.type) {
-				status = AE_TYPE;
-			}
-		}
-		break;
-
-
-	case ARGI_TARGETREF:
-
-		switch (destination_type)
-		{
-		case ACPI_TYPE_INTEGER:
-		case ACPI_TYPE_FIELD_UNIT:
-		case INTERNAL_TYPE_BANK_FIELD:
-		case INTERNAL_TYPE_INDEX_FIELD:
-			/*
-			 * These types require an Integer operand.  We can convert
-			 * a Buffer or a String to an Integer if necessary.
-			 */
-			status = acpi_aml_convert_to_integer (obj_desc, walk_state);
-			break;
-
-
-		case ACPI_TYPE_STRING:
-
-			/*
-			 * The operand must be a String.  We can convert an
-			 * Integer or Buffer if necessary
-			 */
-			status = acpi_aml_convert_to_string (obj_desc, walk_state);
-			break;
-
-
-		case ACPI_TYPE_BUFFER:
-
-			/*
-			 * The operand must be a String.  We can convert an
-			 * Integer or Buffer if necessary
-			 */
-			status = acpi_aml_convert_to_buffer (obj_desc, walk_state);
-			break;
-		}
-		break;
-
-
-	case ARGI_REFERENCE:
-		/*
-		 * Create_xxxx_field cases - we are storing the field object into the name
-		 */
-		break;
-
-
-	default:
-		status = AE_AML_INTERNAL;
-	}
-
-
-	/*
-	 * Source-to-Target conversion semantics:
-	 *
-	 * If conversion to the target type cannot be performed, then simply
-	 * overwrite the target with the new object and type.
-	 */
-	if (status == AE_TYPE) {
-		status = AE_OK;
-	}
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_convert_to_integer
- *
- * PARAMETERS:  *Obj_desc       - Object to be converted.  Must be an
- *                                Integer, Buffer, or String
- *              Walk_state      - Current method state
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Convert an ACPI Object to an integer.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_convert_to_integer (
-	ACPI_OPERAND_OBJECT     **obj_desc,
-	ACPI_WALK_STATE         *walk_state)
-{
-	u32                     i;
-	ACPI_OPERAND_OBJECT     *ret_desc;
-	u32                     count;
-	char                    *pointer;
-	ACPI_INTEGER            result;
-	u32                     integer_size = sizeof (ACPI_INTEGER);
-
-
-	switch ((*obj_desc)->common.type)
-	{
-	case ACPI_TYPE_INTEGER:
-		return (AE_OK);
-
-	case ACPI_TYPE_STRING:
-		pointer = (*obj_desc)->string.pointer;
-		count = (*obj_desc)->string.length;
-		break;
-
-	case ACPI_TYPE_BUFFER:
-		pointer = (char *) (*obj_desc)->buffer.pointer;
-		count = (*obj_desc)->buffer.length;
-		break;
-
-	default:
-		return (AE_TYPE);
-	}
-
-	/*
-	 * Create a new integer
-	 */
-	ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
-	if (!ret_desc) {
-		return (AE_NO_MEMORY);
-	}
-
-
-	/* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */
-
-	if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) {
-		/*
-		 * We are running a method that exists in a 32-bit ACPI table.
-		 * Truncate the value to 32 bits by zeroing out the upper 32-bit field
-		 */
-		integer_size = sizeof (u32);
-	}
-
-
-	/*
-	 * Convert the buffer/string to an integer.  Note that both buffers and
-	 * strings are treated as raw data - we don't convert ascii to hex for
-	 * strings.
-	 *
-	 * There are two terminating conditions for the loop:
-	 * 1) The size of an integer has been reached, or
-	 * 2) The end of the buffer or string has been reached
-	 */
-	result = 0;
-
-	/* Transfer no more than an integer's worth of data */
-
-	if (count > integer_size) {
-		count = integer_size;
-	}
-
-	/*
-	 * String conversion is different than Buffer conversion
-	 */
-	switch ((*obj_desc)->common.type)
-	{
-	case ACPI_TYPE_STRING:
-
-		/* TBD: Need to use 64-bit STRTOUL */
-
-		/*
-		 * Convert string to an integer
-		 * String must be hexadecimal as per the ACPI specification
-		 */
-
-		result = STRTOUL (pointer, NULL, 16);
-		break;
-
-
-	case ACPI_TYPE_BUFFER:
-
-		/*
-		 * Buffer conversion - we simply grab enough raw data from the
-		 * buffer to fill an integer
-		 */
-		for (i = 0; i < count; i++) {
-			/*
-			 * Get next byte and shift it into the Result.
-			 * Little endian is used, meaning that the first byte of the buffer
-			 * is the LSB of the integer
-			 */
-			result |= (((ACPI_INTEGER) pointer[i]) << (i * 8));
-		}
-
-		break;
-	}
-
-	/* Save the Result, delete original descriptor, store new descriptor */
-
-	ret_desc->integer.value = result;
-
-	if (walk_state->opcode != AML_STORE_OP) {
-		acpi_cm_remove_reference (*obj_desc);
-	}
-
-	*obj_desc = ret_desc;
-
-	return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_convert_to_buffer
- *
- * PARAMETERS:  *Obj_desc       - Object to be converted.  Must be an
- *                                Integer, Buffer, or String
- *              Walk_state      - Current method state
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Convert an ACPI Object to an Buffer
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_convert_to_buffer (
-	ACPI_OPERAND_OBJECT     **obj_desc,
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_OPERAND_OBJECT     *ret_desc;
-	u32                     i;
-	u32                     integer_size = sizeof (ACPI_INTEGER);
-	u8                      *new_buf;
-
-
-	switch ((*obj_desc)->common.type)
-	{
-	case ACPI_TYPE_INTEGER:
-
-		/*
-		 * Create a new Buffer
-		 */
-		ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_BUFFER);
-		if (!ret_desc) {
-			return (AE_NO_MEMORY);
-		}
-
-		/* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */
-
-		if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) {
-			/*
-			 * We are running a method that exists in a 32-bit ACPI table.
-			 * Truncate the value to 32 bits by zeroing out the upper
-			 * 32-bit field
-			 */
-			integer_size = sizeof (u32);
-		}
-
-		/* Need enough space for one integers */
-
-		ret_desc->buffer.length = integer_size;
-		new_buf = acpi_cm_callocate (integer_size);
-		if (!new_buf) {
-			REPORT_ERROR
-				(("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure\n"));
-			acpi_cm_remove_reference (ret_desc);
-			return (AE_NO_MEMORY);
-		}
-
-		/* Copy the integer to the buffer */
-
-		for (i = 0; i < integer_size; i++) {
-			new_buf[i] = (u8) ((*obj_desc)->integer.value >> (i * 8));
-		}
-		ret_desc->buffer.pointer = new_buf;
-
-		/* Return the new buffer descriptor */
-
-		if (walk_state->opcode != AML_STORE_OP) {
-			acpi_cm_remove_reference (*obj_desc);
-		}
-		*obj_desc = ret_desc;
-		break;
-
-
-	case ACPI_TYPE_STRING:
-		break;
-
-
-	case ACPI_TYPE_BUFFER:
-		break;
-
-
-	default:
-		return (AE_TYPE);
-		break;
-   }
-
-	return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_convert_to_string
- *
- * PARAMETERS:  *Obj_desc       - Object to be converted.  Must be an
- *                                Integer, Buffer, or String
- *              Walk_state      - Current method state
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Convert an ACPI Object to a string
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_convert_to_string (
-	ACPI_OPERAND_OBJECT     **obj_desc,
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_OPERAND_OBJECT     *ret_desc;
-	u32                     i;
-	u32                     index;
-	u32                     integer_size = sizeof (ACPI_INTEGER);
-	u8                      *new_buf;
-	u8                      *pointer;
-
-
-	switch ((*obj_desc)->common.type)
-	{
-	case ACPI_TYPE_INTEGER:
-
-		/*
-		 * Create a new String
-		 */
-		ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_STRING);
-		if (!ret_desc) {
-			return (AE_NO_MEMORY);
-		}
-
-		/* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */
-
-		if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) {
-			/*
-			 * We are running a method that exists in a 32-bit ACPI table.
-			 * Truncate the value to 32 bits by zeroing out the upper
-			 * 32-bit field
-			 */
-			integer_size = sizeof (u32);
-		}
-
-		/* Need enough space for one ASCII integer plus null terminator */
-
-		ret_desc->string.length = (integer_size * 2) + 1;
-		new_buf = acpi_cm_callocate (ret_desc->string.length);
-		if (!new_buf) {
-			REPORT_ERROR
-				(("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure\n"));
-			acpi_cm_remove_reference (ret_desc);
-			return (AE_NO_MEMORY);
-		}
-
-		/* Copy the integer to the buffer */
-
-		for (i = 0; i < (integer_size * 2); i++) {
-			new_buf[i] = acpi_gbl_hex_to_ascii [((*obj_desc)->integer.value >> (i * 4)) & 0xF];
-		}
-
-		/* Null terminate */
-
-		new_buf [i] = 0;
-		ret_desc->buffer.pointer = new_buf;
-
-		/* Return the new buffer descriptor */
-
-		if (walk_state->opcode != AML_STORE_OP) {
-			acpi_cm_remove_reference (*obj_desc);
-		}
-		*obj_desc = ret_desc;
-
-		return (AE_OK);
-
-
-	case ACPI_TYPE_BUFFER:
-
-		if (((*obj_desc)->buffer.length * 3) > ACPI_MAX_STRING_CONVERSION) {
-			return (AE_AML_STRING_LIMIT);
-		}
-
-		/*
-		 * Create a new String
-		 */
-		ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_STRING);
-		if (!ret_desc) {
-			return (AE_NO_MEMORY);
-		}
-
-		/* Need enough space for one ASCII integer plus null terminator */
-
-		ret_desc->string.length = (*obj_desc)->buffer.length * 3;
-		new_buf = acpi_cm_callocate (ret_desc->string.length + 1);
-		if (!new_buf) {
-			REPORT_ERROR
-				(("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure\n"));
-			acpi_cm_remove_reference (ret_desc);
-			return (AE_NO_MEMORY);
-		}
-
-		/*
-		 * Convert each byte of the buffer to two ASCII characters plus a space.
-		 */
-		pointer = (*obj_desc)->buffer.pointer;
-		index = 0;
-		for (i = 0; i < (*obj_desc)->buffer.length; i++) {
-			new_buf[index + 0] = acpi_gbl_hex_to_ascii [pointer[i] & 0x0F];
-			new_buf[index + 1] = acpi_gbl_hex_to_ascii [(pointer[i] >> 4) & 0x0F];
-			new_buf[index + 2] = ' ';
-			index += 3;
-		}
-
-		/* Null terminate */
-
-		new_buf [index] = 0;
-		ret_desc->buffer.pointer = new_buf;
-
-		/* Return the new buffer descriptor */
-
-		if (walk_state->opcode != AML_STORE_OP) {
-			acpi_cm_remove_reference (*obj_desc);
-		}
-		*obj_desc = ret_desc;
-		break;
-
-
-	case ACPI_TYPE_STRING:
-		break;
-
-
-	default:
-		return (AE_TYPE);
-		break;
-   }
-
-	return (AE_OK);
-}
-
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/amcreate.c linux/drivers/acpi/interpreter/amcreate.c
--- v2.4.5/linux/drivers/acpi/interpreter/amcreate.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/interpreter/amcreate.c	Wed Dec 31 16:00:00 1969
@@ -1,722 +0,0 @@
-/******************************************************************************
- *
- * Module Name: amcreate - Named object creation
- *              $Revision: 53 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acparser.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acnamesp.h"
-#include "acevents.h"
-#include "acdispat.h"
-
-
-#define _COMPONENT          INTERPRETER
-	 MODULE_NAME         ("amcreate")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_create_field
- *
- * PARAMETERS:  Opcode              - The opcode to be executed
- *              Operands            - List of operands for the opcode
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Execute Create_field operators: Create_bit_field_op,
- *              Create_byte_field_op, Create_word_field_op, Create_dWord_field_op,
- *              Create_field_op (which define fields in buffers)
- *
- * ALLOCATION:  Deletes Create_field_op's count operand descriptor
- *
- *
- *  ACPI SPECIFICATION REFERENCES:
- *  Def_create_bit_field := Create_bit_field_op Src_buf Bit_idx   Name_string
- *  Def_create_byte_field := Create_byte_field_op Src_buf Byte_idx Name_string
- *  Def_create_dWord_field := Create_dWord_field_op Src_buf Byte_idx Name_string
- *  Def_create_field    :=  Create_field_op     Src_buf Bit_idx   Num_bits    Name_string
- *  Def_create_word_field := Create_word_field_op Src_buf Byte_idx Name_string
- *  Bit_index           :=  Term_arg=>Integer
- *  Byte_index          :=  Term_arg=>Integer
- *  Num_bits            :=  Term_arg=>Integer
- *  Source_buff         :=  Term_arg=>Buffer
- *
- ******************************************************************************/
-
-
-ACPI_STATUS
-acpi_aml_exec_create_field (
-	u8                      *aml_ptr,
-	u32                     aml_length,
-	ACPI_NAMESPACE_NODE     *node,
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_STATUS             status;
-	ACPI_OPERAND_OBJECT     *obj_desc;
-	ACPI_OPERAND_OBJECT     *tmp_desc;
-
-
-	/* Create the region descriptor */
-
-	obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_FIELD_UNIT);
-	if (!obj_desc) {
-		status = AE_NO_MEMORY;
-		goto cleanup;
-	}
-
-	/* Construct the field object */
-
-	obj_desc->field_unit.access     = (u8) ACCESS_ANY_ACC;
-	obj_desc->field_unit.lock_rule  = (u8) GLOCK_NEVER_LOCK;
-	obj_desc->field_unit.update_rule = (u8) UPDATE_PRESERVE;
-
-	/*
-	 * Allocate a method object for this field unit
-	 */
-
-	obj_desc->field_unit.extra = acpi_cm_create_internal_object (
-			 INTERNAL_TYPE_EXTRA);
-	if (!obj_desc->field_unit.extra) {
-		status = AE_NO_MEMORY;
-		goto cleanup;
-	}
-
-	/*
-	 * Remember location in AML stream of the field unit
-	 * opcode and operands -- since the buffer and index
-	 * operands must be evaluated.
-	 */
-
-	obj_desc->field_unit.extra->extra.pcode     = aml_ptr;
-	obj_desc->field_unit.extra->extra.pcode_length = aml_length;
-	obj_desc->field_unit.node = node;
-
-
-	/*
-	 * This operation is supposed to cause the destination Name to refer
-	 * to the defined Field_unit -- it must not store the constructed
-	 * Field_unit object (or its current value) in some location that the
-	 * Name may already be pointing to.  So, if the Name currently contains
-	 * a reference which would cause Acpi_aml_exec_store() to perform an indirect
-	 * store rather than setting the value of the Name itself, clobber that
-	 * reference before calling Acpi_aml_exec_store().
-	 */
-
-	/* Type of Name's existing value */
-
-	switch (acpi_ns_get_type (node))
-	{
-
-	case ACPI_TYPE_FIELD_UNIT:
-
-	case INTERNAL_TYPE_ALIAS:
-	case INTERNAL_TYPE_BANK_FIELD:
-	case INTERNAL_TYPE_DEF_FIELD:
-	case INTERNAL_TYPE_INDEX_FIELD:
-
-		tmp_desc = acpi_ns_get_attached_object (node);
-		if (tmp_desc) {
-			/*
-			 * There is an existing object here;  delete it and zero out the
-			 * object field within the Node
-			 */
-
-			acpi_cm_remove_reference (tmp_desc);
-			acpi_ns_attach_object ((ACPI_NAMESPACE_NODE *) node, NULL,
-					 ACPI_TYPE_ANY);
-		}
-
-		/* Set the type to ANY (or the store below will fail) */
-
-		((ACPI_NAMESPACE_NODE *) node)->type = ACPI_TYPE_ANY;
-
-		break;
-
-
-	default:
-
-		break;
-	}
-
-
-	/* Store constructed field descriptor in result location */
-
-	status = acpi_aml_exec_store (obj_desc, (ACPI_OPERAND_OBJECT *) node, walk_state);
-
-	/*
-	 * If the field descriptor was not physically stored (or if a failure
-	 * above), we must delete it
-	 */
-	if (obj_desc->common.reference_count <= 1) {
-		acpi_cm_remove_reference (obj_desc);
-	}
-
-
-	return (AE_OK);
-
-
-cleanup:
-
-	/* Delete region object and method subobject */
-
-	if (obj_desc) {
-		/* Remove deletes both objects! */
-
-		acpi_cm_remove_reference (obj_desc);
-		obj_desc = NULL;
-	}
-
-	return (status);
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_create_alias
- *
- * PARAMETERS:  Operands            - List of operands for the opcode
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Create a new named alias
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_aml_exec_create_alias (
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_NAMESPACE_NODE     *source_node;
-	ACPI_NAMESPACE_NODE     *alias_node;
-	ACPI_STATUS             status;
-
-
-	/* Get the source/alias operands (both NTEs) */
-
-	status = acpi_ds_obj_stack_pop_object ((ACPI_OPERAND_OBJECT **) &source_node,
-			 walk_state);
-	if (ACPI_FAILURE (status)) {
-		return (status);
-	}
-
-	/*
-	 * Don't pop it, it gets removed in the calling routine
-	 */
-
-	alias_node = acpi_ds_obj_stack_get_value (0, walk_state);
-
-	/* Add an additional reference to the object */
-
-	acpi_cm_add_reference (source_node->object);
-
-	/*
-	 * Attach the original source Node to the new Alias Node.
-	 */
-	status = acpi_ns_attach_object (alias_node, source_node->object,
-			   source_node->type);
-
-
-	/*
-	 * The new alias assumes the type of the source, but it points
-	 * to the same object.  The reference count of the object has two
-	 * additional references to prevent deletion out from under either the
-	 * source or the alias Node
-	 */
-
-	/* Since both operands are NTEs, we don't need to delete them */
-
-	return (status);
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_create_event
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Create a new event object
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_aml_exec_create_event (
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_STATUS             status;
-	ACPI_OPERAND_OBJECT     *obj_desc;
-
-
- BREAKPOINT3;
-
-	obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_EVENT);
-	if (!obj_desc) {
-		status = AE_NO_MEMORY;
-		goto cleanup;
-	}
-
-	/* Create the actual OS semaphore */
-
-	/* TBD: [Investigate] should be created with 0 or 1 units? */
-
-	status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 1,
-			   &obj_desc->event.semaphore);
-	if (ACPI_FAILURE (status)) {
-		acpi_cm_remove_reference (obj_desc);
-		goto cleanup;
-	}
-
-	/* Attach object to the Node */
-
-	status = acpi_ns_attach_object (acpi_ds_obj_stack_get_value (0, walk_state),
-			   obj_desc, (u8) ACPI_TYPE_EVENT);
-	if (ACPI_FAILURE (status)) {
-		acpi_os_delete_semaphore (obj_desc->event.semaphore);
-		acpi_cm_remove_reference (obj_desc);
-		goto cleanup;
-	}
-
-
-cleanup:
-
-	return (status);
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_create_mutex
- *
- * PARAMETERS:  Interpreter_mode    - Current running mode (load1/Load2/Exec)
- *              Operands            - List of operands for the opcode
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Create a new mutex object
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_aml_exec_create_mutex (
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_STATUS             status = AE_OK;
-	ACPI_OPERAND_OBJECT     *sync_desc;
-	ACPI_OPERAND_OBJECT     *obj_desc;
-
-
-	/* Get the operand */
-
-	status = acpi_ds_obj_stack_pop_object (&sync_desc, walk_state);
-	if (ACPI_FAILURE (status)) {
-		return (status);
-	}
-
-	/* Attempt to allocate a new object */
-
-	obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_MUTEX);
-	if (!obj_desc) {
-		status = AE_NO_MEMORY;
-		goto cleanup;
-	}
-
-	/* Create the actual OS semaphore */
-
-	status = acpi_os_create_semaphore (1, 1, &obj_desc->mutex.semaphore);
-	if (ACPI_FAILURE (status)) {
-		acpi_cm_remove_reference (obj_desc);
-		goto cleanup;
-	}
-
-	obj_desc->mutex.sync_level = (u8) sync_desc->integer.value;
-
-	/* Obj_desc was on the stack top, and the name is below it */
-
-	status = acpi_ns_attach_object (acpi_ds_obj_stack_get_value (0, walk_state),
-			  obj_desc, (u8) ACPI_TYPE_MUTEX);
-	if (ACPI_FAILURE (status)) {
-		acpi_os_delete_semaphore (obj_desc->mutex.semaphore);
-		acpi_cm_remove_reference (obj_desc);
-		goto cleanup;
-	}
-
-
-cleanup:
-
-	/* Always delete the operand */
-
-	acpi_cm_remove_reference (sync_desc);
-
-	return (status);
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_create_region
- *
- * PARAMETERS:  Aml_ptr             - Pointer to the region declaration AML
- *              Aml_length          - Max length of the declaration AML
- *              Operands            - List of operands for the opcode
- *              Interpreter_mode    - Load1/Load2/Execute
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Create a new operation region object
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_aml_exec_create_region (
-	u8                      *aml_ptr,
-	u32                     aml_length,
-	u8                      region_space,
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_STATUS             status;
-	ACPI_OPERAND_OBJECT     *obj_desc;
-	ACPI_NAMESPACE_NODE     *node;
-
-
-	/*
-	 * Space ID must be one of the predefined IDs, or in the user-defined
-	 * range
-	 */
-	if ((region_space >= NUM_REGION_TYPES) &&
-		(region_space < USER_REGION_BEGIN))
-	{
-		REPORT_ERROR (("Invalid Address_space type %X\n", region_space));
-		return (AE_AML_INVALID_SPACE_ID);
-	}
-
-
-	/* Get the Node from the object stack  */
-
-	node = (ACPI_NAMESPACE_NODE *) acpi_ds_obj_stack_get_value (0, walk_state);
-
-	/* Create the region descriptor */
-
-	obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_REGION);
-	if (!obj_desc) {
-		status = AE_NO_MEMORY;
-		goto cleanup;
-	}
-
-	/*
-	 * Allocate a method object for this region.
-	 */
-
-	obj_desc->region.extra = acpi_cm_create_internal_object (
-			 INTERNAL_TYPE_EXTRA);
-	if (!obj_desc->region.extra) {
-		status = AE_NO_MEMORY;
-		goto cleanup;
-	}
-
-	/*
-	 * Remember location in AML stream of address & length
-	 * operands since they need to be evaluated at run time.
-	 */
-
-	obj_desc->region.extra->extra.pcode      = aml_ptr;
-	obj_desc->region.extra->extra.pcode_length = aml_length;
-
-	/* Init the region from the operands */
-
-	obj_desc->region.space_id     = region_space;
-	obj_desc->region.address      = 0;
-	obj_desc->region.length       = 0;
-
-
-	/* Install the new region object in the parent Node */
-
-	obj_desc->region.node = node;
-
-	status = acpi_ns_attach_object (node, obj_desc,
-			  (u8) ACPI_TYPE_REGION);
-
-	if (ACPI_FAILURE (status)) {
-		goto cleanup;
-	}
-
-	/*
-	 * If we have a valid region, initialize it
-	 * Namespace is NOT locked at this point.
-	 */
-
-	status = acpi_ev_initialize_region (obj_desc, FALSE);
-
-	if (ACPI_FAILURE (status)) {
-		/*
-		 *  If AE_NOT_EXIST is returned, it is not fatal
-		 *  because many regions get created before a handler
-		 *  is installed for said region.
-		 */
-		if (AE_NOT_EXIST == status) {
-			status = AE_OK;
-		}
-	}
-
-cleanup:
-
-	if (ACPI_FAILURE (status)) {
-		/* Delete region object and method subobject */
-
-		if (obj_desc) {
-			/* Remove deletes both objects! */
-
-			acpi_cm_remove_reference (obj_desc);
-			obj_desc = NULL;
-		}
-	}
-
-	return (status);
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_create_processor
- *
- * PARAMETERS:  Op              - Op containing the Processor definition and
- *                                args
- *              Processor_nTE   - Node for the containing Node
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Create a new processor object and populate the fields
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_aml_exec_create_processor (
-	ACPI_PARSE_OBJECT       *op,
-	ACPI_HANDLE             processor_nTE)
-{
-	ACPI_STATUS             status;
-	ACPI_PARSE_OBJECT       *arg;
-	ACPI_OPERAND_OBJECT     *obj_desc;
-
-
-	obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_PROCESSOR);
-	if (!obj_desc) {
-		status = AE_NO_MEMORY;
-		return (status);
-	}
-
-	/* Install the new processor object in the parent Node */
-
-	status = acpi_ns_attach_object (processor_nTE, obj_desc,
-			   (u8) ACPI_TYPE_PROCESSOR);
-	if (ACPI_FAILURE (status)) {
-		return(status);
-	}
-
-	arg = op->value.arg;
-
-	/* check existence */
-
-	if (!arg) {
-		status = AE_AML_NO_OPERAND;
-		return (status);
-	}
-
-	/* First arg is the Processor ID */
-
-	obj_desc->processor.proc_id = (u8) arg->value.integer;
-
-	/* Move to next arg and check existence */
-
-	arg = arg->next;
-	if (!arg) {
-		status = AE_AML_NO_OPERAND;
-		return (status);
-	}
-
-	/* Second arg is the PBlock Address */
-
-	obj_desc->processor.address = (ACPI_IO_ADDRESS) arg->value.integer;
-
-	/* Move to next arg and check existence */
-
-	arg = arg->next;
-	if (!arg) {
-		status = AE_AML_NO_OPERAND;
-		return (status);
-	}
-
-	/* Third arg is the PBlock Length */
-
-	obj_desc->processor.length = (u8) arg->value.integer;
-
-	return (AE_OK);
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_create_power_resource
- *
- * PARAMETERS:  Op              - Op containing the Power_resource definition
- *                                and args
- *              Power_res_nTE   - Node for the containing Node
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Create a new Power_resource object and populate the fields
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_aml_exec_create_power_resource (
-	ACPI_PARSE_OBJECT       *op,
-	ACPI_HANDLE             power_res_nTE)
-{
-	ACPI_STATUS             status;
-	ACPI_PARSE_OBJECT       *arg;
-	ACPI_OPERAND_OBJECT     *obj_desc;
-
-
-	obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_POWER);
-	if (!obj_desc) {
-		status = AE_NO_MEMORY;
-		return (status);
-	}
-
-	/* Install the new power resource object in the parent Node */
-
-	status = acpi_ns_attach_object (power_res_nTE, obj_desc,
-			  (u8) ACPI_TYPE_POWER);
-	if (ACPI_FAILURE (status)) {
-		return(status);
-	}
-
-	arg = op->value.arg;
-
-	/* check existence */
-
-	if (!arg) {
-		status = AE_AML_NO_OPERAND;
-		return (status);
-	}
-
-	/* First arg is the System_level */
-
-	obj_desc->power_resource.system_level = (u8) arg->value.integer;
-
-	/* Move to next arg and check existence */
-
-	arg = arg->next;
-	if (!arg) {
-		status = AE_AML_NO_OPERAND;
-		return (status);
-	}
-
-	/* Second arg is the PBlock Address */
-
-	obj_desc->power_resource.resource_order = (u16) arg->value.integer;
-
-	return (AE_OK);
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_create_method
- *
- * PARAMETERS:  Aml_ptr         - First byte of the method's AML
- *              Aml_length      - AML byte count for this method
- *              Method_flags    - AML method flag byte
- *              Method          - Method Node
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Create a new method object
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_aml_exec_create_method (
-	u8                      *aml_ptr,
-	u32                     aml_length,
-	u32                     method_flags,
-	ACPI_HANDLE             method)
-{
-	ACPI_OPERAND_OBJECT     *obj_desc;
-	ACPI_STATUS             status;
-
-
-	/* Create a new method object */
-
-	obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_METHOD);
-	if (!obj_desc) {
-	   return (AE_NO_MEMORY);
-	}
-
-	/* Get the method's AML pointer/length from the Op */
-
-	obj_desc->method.pcode      = aml_ptr;
-	obj_desc->method.pcode_length = aml_length;
-
-	/*
-	 * First argument is the Method Flags (contains parameter count for the
-	 * method)
-	 */
-
-	obj_desc->method.method_flags = (u8) method_flags;
-	obj_desc->method.param_count = (u8) (method_flags &
-			  METHOD_FLAGS_ARG_COUNT);
-
-	/*
-	 * Get the concurrency count.  If required, a semaphore will be
-	 * created for this method when it is parsed.
-	 *
-	 * TBD: [Future]  for APCI 2.0, there will be a Sync_level value, not
-	 * just a flag
-	 * Concurrency = Sync_level + 1;.
-	 */
-
-	if (method_flags & METHOD_FLAGS_SERIALIZED) {
-		obj_desc->method.concurrency = 1;
-	}
-
-	else {
-		obj_desc->method.concurrency = INFINITE_CONCURRENCY;
-	}
-
-	/* Attach the new object to the method Node */
-
-	status = acpi_ns_attach_object (method, obj_desc, (u8) ACPI_TYPE_METHOD);
-	if (ACPI_FAILURE (status)) {
-		acpi_cm_delete_object_desc (obj_desc);
-	}
-
-	return (status);
-}
-
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/amdyadic.c linux/drivers/acpi/interpreter/amdyadic.c
--- v2.4.5/linux/drivers/acpi/interpreter/amdyadic.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/interpreter/amdyadic.c	Wed Dec 31 16:00:00 1969
@@ -1,882 +0,0 @@
-/******************************************************************************
- *
- * Module Name: amdyadic - ACPI AML (p-code) execution for dyadic operators
- *              $Revision: 71 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acparser.h"
-#include "acnamesp.h"
-#include "acinterp.h"
-#include "acevents.h"
-#include "amlcode.h"
-#include "acdispat.h"
-
-
-#define _COMPONENT          INTERPRETER
-	 MODULE_NAME         ("amdyadic")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_do_concatenate
- *
- * PARAMETERS:  *Obj_desc       - Object to be converted.  Must be an
- *                                Integer, Buffer, or String
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Concatenate two objects OF THE SAME TYPE.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_do_concatenate (
-	ACPI_OPERAND_OBJECT     *obj_desc,
-	ACPI_OPERAND_OBJECT     *obj_desc2,
-	ACPI_OPERAND_OBJECT     **actual_ret_desc,
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_STATUS             status;
-	u32                     i;
-	ACPI_INTEGER            this_integer;
-	ACPI_OPERAND_OBJECT     *ret_desc;
-	NATIVE_CHAR             *new_buf;
-	u32                     integer_size = sizeof (ACPI_INTEGER);
-
-
-	/*
-	 * There are three cases to handle:
-	 * 1) Two Integers concatenated to produce a buffer
-	 * 2) Two Strings concatenated to produce a string
-	 * 3) Two Buffers concatenated to produce a buffer
-	 */
-	switch (obj_desc->common.type)
-	{
-	case ACPI_TYPE_INTEGER:
-
-		/* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */
-
-		if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) {
-			/*
-			 * We are running a method that exists in a 32-bit ACPI table.
-			 * Truncate the value to 32 bits by zeroing out the upper
-			 * 32-bit field
-			 */
-			integer_size = sizeof (u32);
-		}
-
-		/* Result of two integers is a buffer */
-
-		ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_BUFFER);
-		if (!ret_desc) {
-			return (AE_NO_MEMORY);
-		}
-
-		/* Need enough space for two integers */
-
-		ret_desc->buffer.length = integer_size * 2;
-		new_buf = acpi_cm_callocate (ret_desc->buffer.length);
-		if (!new_buf) {
-			REPORT_ERROR
-				(("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure\n"));
-			status = AE_NO_MEMORY;
-			goto cleanup;
-		}
-
-		ret_desc->buffer.pointer = (u8 *) new_buf;
-
-		/* Convert the first integer */
-
-		this_integer = obj_desc->integer.value;
-		for (i = 0; i < integer_size; i++) {
-			new_buf[i] = (u8) this_integer;
-			this_integer >>= 8;
-		}
-
-		/* Convert the second integer */
-
-		this_integer = obj_desc2->integer.value;
-		for (; i < (integer_size * 2); i++) {
-			new_buf[i] = (u8) this_integer;
-			this_integer >>= 8;
-		}
-
-		break;
-
-
-	case ACPI_TYPE_STRING:
-
-		ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_STRING);
-		if (!ret_desc) {
-			return (AE_NO_MEMORY);
-		}
-
-		/* Operand1 is string  */
-
-		new_buf = acpi_cm_allocate (obj_desc->string.length +
-				  obj_desc2->string.length + 1);
-		if (!new_buf) {
-			REPORT_ERROR
-				(("Aml_exec_dyadic2_r/Concat_op: String allocation failure\n"));
-			status = AE_NO_MEMORY;
-			goto cleanup;
-		}
-
-		STRCPY (new_buf, obj_desc->string.pointer);
-		STRCPY (new_buf + obj_desc->string.length,
-				  obj_desc2->string.pointer);
-
-		/* Point the return object to the new string */
-
-		ret_desc->string.pointer = new_buf;
-		ret_desc->string.length = obj_desc->string.length +=
-				  obj_desc2->string.length;
-		break;
-
-
-	case ACPI_TYPE_BUFFER:
-
-		/* Operand1 is a buffer */
-
-		ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_BUFFER);
-		if (!ret_desc) {
-			return (AE_NO_MEMORY);
-		}
-
-		new_buf = acpi_cm_allocate (obj_desc->buffer.length +
-				  obj_desc2->buffer.length);
-		if (!new_buf) {
-			REPORT_ERROR
-				(("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure\n"));
-			status = AE_NO_MEMORY;
-			goto cleanup;
-		}
-
-		MEMCPY (new_buf, obj_desc->buffer.pointer,
-				  obj_desc->buffer.length);
-		MEMCPY (new_buf + obj_desc->buffer.length, obj_desc2->buffer.pointer,
-				  obj_desc2->buffer.length);
-
-		/*
-		 * Point the return object to the new buffer
-		 */
-
-		ret_desc->buffer.pointer    = (u8 *) new_buf;
-		ret_desc->buffer.length     = obj_desc->buffer.length +
-				 obj_desc2->buffer.length;
-		break;
-
-	default:
-		status = AE_AML_INTERNAL;
-		ret_desc = NULL;
-	}
-
-
-	*actual_ret_desc = ret_desc;
-	return (AE_OK);
-
-
-cleanup:
-
-	acpi_cm_remove_reference (ret_desc);
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_dyadic1
- *
- * PARAMETERS:  Opcode              - The opcode to be executed
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Execute Type 1 dyadic operator with numeric operands:
- *              Notify_op
- *
- * ALLOCATION:  Deletes both operands
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_exec_dyadic1 (
-	u16                     opcode,
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_OPERAND_OBJECT     *obj_desc = NULL;
-	ACPI_OPERAND_OBJECT     *val_desc = NULL;
-	ACPI_NAMESPACE_NODE     *node;
-	ACPI_STATUS             status = AE_OK;
-
-
-	/* Resolve all operands */
-
-	status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
-	/* Get the operands */
-
-	status |= acpi_ds_obj_stack_pop_object (&val_desc, walk_state);
-	status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
-	if (ACPI_FAILURE (status)) {
-		/* Invalid parameters on object stack  */
-
-		goto cleanup;
-	}
-
-
-	/* Examine the opcode */
-
-	switch (opcode)
-	{
-
-	/* Def_notify  :=  Notify_op   Notify_object   Notify_value */
-
-	case AML_NOTIFY_OP:
-
-		/* The Obj_desc is actually an Node */
-
-		node = (ACPI_NAMESPACE_NODE *) obj_desc;
-		obj_desc = NULL;
-
-		/* Object must be a device or thermal zone */
-
-		if (node && val_desc) {
-			switch (node->type)
-			{
-			case ACPI_TYPE_DEVICE:
-			case ACPI_TYPE_THERMAL:
-
-				/*
-				 * Requires that Device and Thermal_zone be compatible
-				 * mappings
-				 */
-
-				/* Dispatch the notify to the appropriate handler */
-
-				acpi_ev_notify_dispatch (node, (u32) val_desc->integer.value);
-				break;
-
-			default:
-				status = AE_AML_OPERAND_TYPE;
-			}
-		}
-		break;
-
-	default:
-
-		REPORT_ERROR (("Acpi_aml_exec_dyadic1: Unknown dyadic opcode %X\n",
-			opcode));
-		status = AE_AML_BAD_OPCODE;
-	}
-
-
-cleanup:
-
-	/* Always delete both operands */
-
-	acpi_cm_remove_reference (val_desc);
-	acpi_cm_remove_reference (obj_desc);
-
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_dyadic2_r
- *
- * PARAMETERS:  Opcode              - The opcode to be executed
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Execute Type 2 dyadic operator with numeric operands and
- *              one or two result operands.
- *
- * ALLOCATION:  Deletes one operand descriptor -- other remains on stack
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_exec_dyadic2_r (
-	u16                     opcode,
-	ACPI_WALK_STATE         *walk_state,
-	ACPI_OPERAND_OBJECT     **return_desc)
-{
-	ACPI_OPERAND_OBJECT     *obj_desc   = NULL;
-	ACPI_OPERAND_OBJECT     *obj_desc2  = NULL;
-	ACPI_OPERAND_OBJECT     *res_desc   = NULL;
-	ACPI_OPERAND_OBJECT     *res_desc2  = NULL;
-	ACPI_OPERAND_OBJECT     *ret_desc   = NULL;
-	ACPI_OPERAND_OBJECT     *ret_desc2  = NULL;
-	ACPI_STATUS             status      = AE_OK;
-	u32                     num_operands = 3;
-
-
-	/* Resolve all operands */
-
-	status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
-	/* Get all operands */
-
-	if (AML_DIVIDE_OP == opcode) {
-		num_operands = 4;
-		status |= acpi_ds_obj_stack_pop_object (&res_desc2, walk_state);
-	}
-
-	status |= acpi_ds_obj_stack_pop_object (&res_desc, walk_state);
-	status |= acpi_ds_obj_stack_pop_object (&obj_desc2, walk_state);
-	status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
-	if (ACPI_FAILURE (status)) {
-		goto cleanup;
-	}
-
-
-	/* Create an internal return object if necessary */
-
-	switch (opcode)
-	{
-	case AML_ADD_OP:
-	case AML_BIT_AND_OP:
-	case AML_BIT_NAND_OP:
-	case AML_BIT_OR_OP:
-	case AML_BIT_NOR_OP:
-	case AML_BIT_XOR_OP:
-	case AML_DIVIDE_OP:
-	case AML_MULTIPLY_OP:
-	case AML_SHIFT_LEFT_OP:
-	case AML_SHIFT_RIGHT_OP:
-	case AML_SUBTRACT_OP:
-
-		ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
-		if (!ret_desc) {
-			status = AE_NO_MEMORY;
-			goto cleanup;
-		}
-
-		break;
-	}
-
-
-	/*
-	 * Execute the opcode
-	 */
-
-	switch (opcode)
-	{
-
-	/* Def_add :=  Add_op  Operand1    Operand2    Result  */
-
-	case AML_ADD_OP:
-
-		ret_desc->integer.value = obj_desc->integer.value +
-				 obj_desc2->integer.value;
-		break;
-
-
-	/* Def_and :=  And_op  Operand1    Operand2    Result  */
-
-	case AML_BIT_AND_OP:
-
-		ret_desc->integer.value = obj_desc->integer.value &
-				 obj_desc2->integer.value;
-		break;
-
-
-	/* Def_nAnd := NAnd_op Operand1    Operand2    Result  */
-
-	case AML_BIT_NAND_OP:
-
-		ret_desc->integer.value = ~(obj_desc->integer.value &
-				   obj_desc2->integer.value);
-		break;
-
-
-	/* Def_or  :=  Or_op   Operand1    Operand2    Result  */
-
-	case AML_BIT_OR_OP:
-
-		ret_desc->integer.value = obj_desc->integer.value |
-				 obj_desc2->integer.value;
-		break;
-
-
-	/* Def_nOr :=  NOr_op  Operand1    Operand2    Result  */
-
-	case AML_BIT_NOR_OP:
-
-		ret_desc->integer.value = ~(obj_desc->integer.value |
-				   obj_desc2->integer.value);
-		break;
-
-
-	/* Def_xOr :=  XOr_op  Operand1    Operand2    Result  */
-
-	case AML_BIT_XOR_OP:
-
-		ret_desc->integer.value = obj_desc->integer.value ^
-				 obj_desc2->integer.value;
-		break;
-
-
-	/* Def_divide  :=  Divide_op Dividend Divisor Remainder Quotient */
-
-	case AML_DIVIDE_OP:
-
-		if (!obj_desc2->integer.value) {
-			REPORT_ERROR
-				(("Aml_exec_dyadic2_r/Divide_op: Divide by zero\n"));
-
-			status = AE_AML_DIVIDE_BY_ZERO;
-			goto cleanup;
-		}
-
-		ret_desc2 = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
-		if (!ret_desc2) {
-			status = AE_NO_MEMORY;
-			goto cleanup;
-		}
-
-		/* Remainder (modulo) */
-
-		ret_desc->integer.value  = ACPI_MODULO (obj_desc->integer.value,
-				  obj_desc2->integer.value);
-
-		/* Result (what we used to call the quotient) */
-
-		ret_desc2->integer.value = ACPI_DIVIDE (obj_desc->integer.value,
-				  obj_desc2->integer.value);
-		break;
-
-
-	/* Def_multiply := Multiply_op Operand1    Operand2    Result  */
-
-	case AML_MULTIPLY_OP:
-
-		ret_desc->integer.value = obj_desc->integer.value *
-				 obj_desc2->integer.value;
-		break;
-
-
-	/* Def_shift_left  :=  Shift_left_op Operand Shift_count Result */
-
-	case AML_SHIFT_LEFT_OP:
-
-		ret_desc->integer.value = obj_desc->integer.value <<
-				 obj_desc2->integer.value;
-		break;
-
-
-	/* Def_shift_right :=  Shift_right_op  Operand Shift_count Result  */
-
-	case AML_SHIFT_RIGHT_OP:
-
-		ret_desc->integer.value = obj_desc->integer.value >>
-				 obj_desc2->integer.value;
-		break;
-
-
-	/* Def_subtract := Subtract_op Operand1    Operand2    Result  */
-
-	case AML_SUBTRACT_OP:
-
-		ret_desc->integer.value = obj_desc->integer.value -
-				 obj_desc2->integer.value;
-		break;
-
-
-	/* Def_concat  :=  Concat_op   Data1   Data2   Result  */
-
-	case AML_CONCAT_OP:
-
-
-		/*
-		 * Convert the second operand if necessary.  The first operand
-		 * determines the type of the second operand, (See the Data Types
-		 * section of the ACPI specification.)  Both object types are
-		 * guaranteed to be either Integer/String/Buffer by the operand
-		 * resolution mechanism above.
-		 */
-
-		switch (obj_desc->common.type)
-		{
-		case ACPI_TYPE_INTEGER:
-			status = acpi_aml_convert_to_integer (&obj_desc2, walk_state);
-			break;
-
-		case ACPI_TYPE_STRING:
-			status = acpi_aml_convert_to_string (&obj_desc2, walk_state);
-			break;
-
-		case ACPI_TYPE_BUFFER:
-			status = acpi_aml_convert_to_buffer (&obj_desc2, walk_state);
-			break;
-
-		default:
-			status = AE_AML_INTERNAL;
-		}
-
-		if (ACPI_FAILURE (status)) {
-			goto cleanup;
-		}
-
-
-		/*
-		 * Both operands are now known to be the same object type
-		 * (Both are Integer, String, or Buffer), and we can now perform the
-		 * concatenation.
-		 */
-		status = acpi_aml_do_concatenate (obj_desc, obj_desc2, &ret_desc, walk_state);
-		if (ACPI_FAILURE (status)) {
-			goto cleanup;
-		}
-		break;
-
-
-	default:
-
-		REPORT_ERROR (("Acpi_aml_exec_dyadic2_r: Unknown dyadic opcode %X\n",
-				opcode));
-		status = AE_AML_BAD_OPCODE;
-		goto cleanup;
-	}
-
-
-	/*
-	 * Store the result of the operation (which is now in Obj_desc) into
-	 * the result descriptor, or the location pointed to by the result
-	 * descriptor (Res_desc).
-	 */
-
-	status = acpi_aml_exec_store (ret_desc, res_desc, walk_state);
-	if (ACPI_FAILURE (status)) {
-		goto cleanup;
-	}
-
-	if (AML_DIVIDE_OP == opcode) {
-		status = acpi_aml_exec_store (ret_desc2, res_desc2, walk_state);
-
-		/*
-		 * Since the remainder is not returned, remove a reference to
-		 * the object we created earlier
-		 */
-
-		acpi_cm_remove_reference (ret_desc2);
-	}
-
-
-cleanup:
-
-	/* Always delete the operands */
-
-	acpi_cm_remove_reference (obj_desc);
-	acpi_cm_remove_reference (obj_desc2);
-
-
-	/* Delete return object on error */
-
-	if (ACPI_FAILURE (status)) {
-		/* On failure, delete the result ops */
-
-		acpi_cm_remove_reference (res_desc);
-		acpi_cm_remove_reference (res_desc2);
-
-		if (ret_desc) {
-			/* And delete the internal return object */
-
-			acpi_cm_remove_reference (ret_desc);
-			ret_desc = NULL;
-		}
-	}
-
-	/* Set the return object and exit */
-
-	*return_desc = ret_desc;
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_dyadic2_s
- *
- * PARAMETERS:  Opcode              - The opcode to be executed
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Execute Type 2 dyadic synchronization operator
- *
- * ALLOCATION:  Deletes one operand descriptor -- other remains on stack
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_exec_dyadic2_s (
-	u16                     opcode,
-	ACPI_WALK_STATE         *walk_state,
-	ACPI_OPERAND_OBJECT     **return_desc)
-{
-	ACPI_OPERAND_OBJECT     *obj_desc;
-	ACPI_OPERAND_OBJECT     *time_desc;
-	ACPI_OPERAND_OBJECT     *ret_desc = NULL;
-	ACPI_STATUS             status;
-
-
-	/* Resolve all operands */
-
-	status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
-	/* Get all operands */
-
-	status |= acpi_ds_obj_stack_pop_object (&time_desc, walk_state);
-	status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
-	if (ACPI_FAILURE (status)) {
-		/* Invalid parameters on object stack  */
-
-		goto cleanup;
-	}
-
-
-	/* Create the internal return object */
-
-	ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
-	if (!ret_desc) {
-		status = AE_NO_MEMORY;
-		goto cleanup;
-	}
-
-	/* Default return value is FALSE, operation did not time out */
-
-	ret_desc->integer.value = 0;
-
-
-	/* Examine the opcode */
-
-	switch (opcode)
-	{
-
-	/* Def_acquire :=  Acquire_op  Mutex_object Timeout */
-
-	case AML_ACQUIRE_OP:
-
-		status = acpi_aml_system_acquire_mutex (time_desc, obj_desc);
-		break;
-
-
-	/* Def_wait := Wait_op Acpi_event_object Timeout */
-
-	case AML_WAIT_OP:
-
-		status = acpi_aml_system_wait_event (time_desc, obj_desc);
-		break;
-
-
-	default:
-
-		REPORT_ERROR (("Acpi_aml_exec_dyadic2_s: Unknown dyadic synchronization opcode %X\n", opcode));
-		status = AE_AML_BAD_OPCODE;
-		goto cleanup;
-	}
-
-
-	/*
-	 * Return a boolean indicating if operation timed out
-	 * (TRUE) or not (FALSE)
-	 */
-
-	if (status == AE_TIME) {
-		ret_desc->integer.value = ACPI_INTEGER_MAX;  /* TRUE, op timed out */
-		status = AE_OK;
-	}
-
-
-cleanup:
-
-	/* Delete params */
-
-	acpi_cm_remove_reference (time_desc);
-	acpi_cm_remove_reference (obj_desc);
-
-	/* Delete return object on error */
-
-	if (ACPI_FAILURE (status) &&
-		(ret_desc))
-	{
-		acpi_cm_remove_reference (ret_desc);
-		ret_desc = NULL;
-	}
-
-
-	/* Set the return object and exit */
-
-	*return_desc = ret_desc;
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_dyadic2
- *
- * PARAMETERS:  Opcode              - The opcode to be executed
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Execute Type 2 dyadic operator with numeric operands and
- *              no result operands
- *
- * ALLOCATION:  Deletes one operand descriptor -- other remains on stack
- *              containing result value
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_exec_dyadic2 (
-	u16                     opcode,
-	ACPI_WALK_STATE         *walk_state,
-	ACPI_OPERAND_OBJECT     **return_desc)
-{
-	ACPI_OPERAND_OBJECT     *obj_desc;
-	ACPI_OPERAND_OBJECT     *obj_desc2;
-	ACPI_OPERAND_OBJECT     *ret_desc = NULL;
-	ACPI_STATUS             status;
-	u8                      lboolean;
-
-
-	/* Resolve all operands */
-
-	status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
-	/* Get all operands */
-
-	status |= acpi_ds_obj_stack_pop_object (&obj_desc2, walk_state);
-	status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
-	if (ACPI_FAILURE (status)) {
-		/* Invalid parameters on object stack  */
-
-		goto cleanup;
-	}
-
-
-	/* Create the internal return object */
-
-	ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
-	if (!ret_desc) {
-		status = AE_NO_MEMORY;
-		goto cleanup;
-	}
-
-	/*
-	 * Execute the Opcode
-	 */
-
-	lboolean = FALSE;
-	switch (opcode)
-	{
-
-	/* Def_lAnd := LAnd_op Operand1    Operand2    */
-
-	case AML_LAND_OP:
-
-		lboolean = (u8) (obj_desc->integer.value &&
-				  obj_desc2->integer.value);
-		break;
-
-
-	/* Def_lEqual  :=  LEqual_op   Operand1    Operand2    */
-
-	case AML_LEQUAL_OP:
-
-		lboolean = (u8) (obj_desc->integer.value ==
-				  obj_desc2->integer.value);
-		break;
-
-
-	/* Def_lGreater := LGreater_op Operand1    Operand2    */
-
-	case AML_LGREATER_OP:
-
-		lboolean = (u8) (obj_desc->integer.value >
-				  obj_desc2->integer.value);
-		break;
-
-
-	/* Def_lLess   :=  LLess_op Operand1   Operand2    */
-
-	case AML_LLESS_OP:
-
-		lboolean = (u8) (obj_desc->integer.value <
-				  obj_desc2->integer.value);
-		break;
-
-
-	/* Def_lOr :=  LOr_op  Operand1    Operand2    */
-
-	case AML_LOR_OP:
-
-		lboolean = (u8) (obj_desc->integer.value ||
-				  obj_desc2->integer.value);
-		break;
-
-
-	default:
-
-		REPORT_ERROR (("Acpi_aml_exec_dyadic2: Unknown dyadic opcode %X\n", opcode));
-		status = AE_AML_BAD_OPCODE;
-		goto cleanup;
-		break;
-	}
-
-
-	/* Set return value to logical TRUE (all ones) or FALSE (zero) */
-
-	if (lboolean) {
-		ret_desc->integer.value = ACPI_INTEGER_MAX;
-	}
-	else {
-		ret_desc->integer.value = 0;
-	}
-
-
-cleanup:
-
-	/* Always delete operands */
-
-	acpi_cm_remove_reference (obj_desc);
-	acpi_cm_remove_reference (obj_desc2);
-
-
-	/* Delete return object on error */
-
-	if (ACPI_FAILURE (status) &&
-		(ret_desc))
-	{
-		acpi_cm_remove_reference (ret_desc);
-		ret_desc = NULL;
-	}
-
-
-	/* Set the return object and exit */
-
-	*return_desc = ret_desc;
-	return (status);
-}
-
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/amfield.c linux/drivers/acpi/interpreter/amfield.c
--- v2.4.5/linux/drivers/acpi/interpreter/amfield.c	Mon Jan 29 10:15:59 2001
+++ linux/drivers/acpi/interpreter/amfield.c	Wed Dec 31 16:00:00 1969
@@ -1,283 +0,0 @@
-/******************************************************************************
- *
- * Module Name: amfield - ACPI AML (p-code) execution - field manipulation
- *              $Revision: 77 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acnamesp.h"
-#include "achware.h"
-#include "acevents.h"
-
-
-#define _COMPONENT          INTERPRETER
-	 MODULE_NAME         ("amfield")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_setup_field
- *
- * PARAMETERS:  *Obj_desc           - Field to be read or written
- *              *Rgn_desc           - Region containing field
- *              Field_bit_width     - Field Width in bits (8, 16, or 32)
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Common processing for Acpi_aml_read_field and Acpi_aml_write_field
- *
- *  ACPI SPECIFICATION REFERENCES:
- *  Each of the Type1_opcodes is defined as specified in in-line
- *  comments below. For each one, use the following definitions.
- *
- *  Def_bit_field   :=  Bit_field_op    Src_buf Bit_idx Destination
- *  Def_byte_field  :=  Byte_field_op   Src_buf Byte_idx Destination
- *  Def_create_field := Create_field_op Src_buf Bit_idx Num_bits Name_string
- *  Def_dWord_field :=  DWord_field_op  Src_buf Byte_idx Destination
- *  Def_word_field  :=  Word_field_op   Src_buf Byte_idx Destination
- *  Bit_index       :=  Term_arg=>Integer
- *  Byte_index      :=  Term_arg=>Integer
- *  Destination     :=  Name_string
- *  Num_bits        :=  Term_arg=>Integer
- *  Source_buf      :=  Term_arg=>Buffer
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_setup_field (
-	ACPI_OPERAND_OBJECT     *obj_desc,
-	ACPI_OPERAND_OBJECT     *rgn_desc,
-	u32                     field_bit_width)
-{
-	ACPI_STATUS             status = AE_OK;
-	u32                     field_byte_width;
-
-
-	/* Parameter validation */
-
-	if (!obj_desc || !rgn_desc) {
-		return (AE_AML_NO_OPERAND);
-	}
-
-	if (ACPI_TYPE_REGION != rgn_desc->common.type) {
-		return (AE_AML_OPERAND_TYPE);
-	}
-
-
-	/*
-	 * TBD: [Future] Acpi 2.0 supports Qword fields
-	 *
-	 * Init and validate Field width
-	 * Possible values are 1, 2, 4
-	 */
-
-	field_byte_width = DIV_8 (field_bit_width);
-
-	if ((field_bit_width != 8) &&
-		(field_bit_width != 16) &&
-		(field_bit_width != 32))
-	{
-		return (AE_AML_OPERAND_VALUE);
-	}
-
-
-	/*
-	 * If the Region Address and Length have not been previously evaluated,
-	 * evaluate them and save the results.
-	 */
-	if (!(rgn_desc->region.flags & AOPOBJ_DATA_VALID)) {
-
-		status = acpi_ds_get_region_arguments (rgn_desc);
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-	}
-
-
-	if ((obj_desc->common.type == ACPI_TYPE_FIELD_UNIT) &&
-		(!(obj_desc->common.flags & AOPOBJ_DATA_VALID)))
-	{
-		/*
-		 * Field Buffer and Index have not been previously evaluated,
-		 */
-		return (AE_AML_INTERNAL);
-	}
-
-	if (rgn_desc->region.length <
-	   (obj_desc->field.offset & ~((u32) field_byte_width - 1)) +
-			field_byte_width)
-	{
-		/*
-		 * Offset rounded up to next multiple of field width
-		 * exceeds region length, indicate an error
-		 */
-
-		return (AE_AML_REGION_LIMIT);
-	}
-
-	return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_access_named_field
- *
- * PARAMETERS:  Mode                - ACPI_READ or ACPI_WRITE
- *              Named_field         - Handle for field to be accessed
- *              *Buffer             - Value(s) to be read or written
- *              Buffer_length         - Number of bytes to transfer
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Read or write a named field
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_access_named_field (
-	u32                     mode,
-	ACPI_HANDLE             named_field,
-	void                    *buffer,
-	u32                     buffer_length)
-{
-	ACPI_OPERAND_OBJECT     *obj_desc = NULL;
-	ACPI_STATUS             status = AE_OK;
-	u8                      locked = FALSE;
-	u32                     bit_granularity = 0;
-	u32                     byte_granularity;
-	u32                     datum_length;
-	u32                     actual_byte_length;
-	u32                     byte_field_length;
-
-
-	/* Parameter validation */
-
-	if ((!named_field) || (ACPI_READ == mode && !buffer)) {
-		return (AE_AML_INTERNAL);
-	}
-
-	/* Get the attached field object */
-
-	obj_desc = acpi_ns_get_attached_object (named_field);
-	if (!obj_desc) {
-		return (AE_AML_INTERNAL);
-	}
-
-	/* Check the type */
-
-	if (INTERNAL_TYPE_DEF_FIELD != acpi_ns_get_type (named_field)) {
-		return (AE_AML_OPERAND_TYPE);
-	}
-
-	/* Obj_desc valid and Named_field is a defined field */
-
-
-	/* Double-check that the attached object is also a field */
-
-	if (INTERNAL_TYPE_DEF_FIELD != obj_desc->common.type) {
-		return (AE_AML_OPERAND_TYPE);
-	}
-
-
-	/*
-	 * Granularity was decoded from the field access type
-	 * (Any_acc will be the same as Byte_acc)
-	 */
-
-	bit_granularity = obj_desc->field_unit.granularity;
-	byte_granularity = DIV_8 (bit_granularity);
-
-	/*
-	 * Check if request is too large for the field, and silently truncate
-	 * if necessary
-	 */
-
-	/* TBD: [Errors] should an error be returned in this case? */
-
-	byte_field_length = (u32) DIV_8 (obj_desc->field_unit.length + 7);
-
-
-	actual_byte_length = buffer_length;
-	if (buffer_length > byte_field_length) {
-		actual_byte_length = byte_field_length;
-	}
-
-	/* TBD: should these round down to a power of 2? */
-
-	if (DIV_8 (bit_granularity) > byte_field_length) {
-		bit_granularity = MUL_8(byte_field_length);
-	}
-
-	if (byte_granularity > byte_field_length) {
-		byte_granularity = byte_field_length;
-	}
-
-
-	/* Convert byte count to datum count, round up if necessary */
-
-	datum_length = (actual_byte_length + (byte_granularity-1)) / byte_granularity;
-
-
-	/* Get the global lock if needed */
-
-	locked = acpi_aml_acquire_global_lock (obj_desc->field_unit.lock_rule);
-
-
-	/* Perform the actual read or write of the buffer */
-
-	switch (mode)
-	{
-	case ACPI_READ:
-
-		status = acpi_aml_read_field (obj_desc, buffer, buffer_length,
-				  actual_byte_length, datum_length,
-				  bit_granularity, byte_granularity);
-		break;
-
-
-	case ACPI_WRITE:
-
-		status = acpi_aml_write_field (obj_desc, buffer, buffer_length,
-				  actual_byte_length, datum_length,
-				  bit_granularity, byte_granularity);
-		break;
-
-
-	default:
-
-		status = AE_BAD_PARAMETER;
-		break;
-	}
-
-
-	/* Release global lock if we acquired it earlier */
-
-	acpi_aml_release_global_lock (locked);
-
-	return (status);
-}
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/amfldio.c linux/drivers/acpi/interpreter/amfldio.c
--- v2.4.5/linux/drivers/acpi/interpreter/amfldio.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/interpreter/amfldio.c	Wed Dec 31 16:00:00 1969
@@ -1,685 +0,0 @@
-/******************************************************************************
- *
- * Module Name: amfldio - Aml Field I/O
- *              $Revision: 39 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acnamesp.h"
-#include "achware.h"
-#include "acevents.h"
-
-
-#define _COMPONENT          INTERPRETER
-	 MODULE_NAME         ("amfldio")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_read_field_data
- *
- * PARAMETERS:  *Obj_desc           - Field to be read
- *              *Value              - Where to store value
- *              Field_bit_width     - Field Width in bits (8, 16, or 32)
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Retrieve the value of the given field
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_read_field_data (
-	ACPI_OPERAND_OBJECT     *obj_desc,
-	u32                     field_byte_offset,
-	u32                     field_bit_width,
-	u32                     *value)
-{
-	ACPI_STATUS             status;
-	ACPI_OPERAND_OBJECT     *rgn_desc = NULL;
-	ACPI_PHYSICAL_ADDRESS   address;
-	u32                     local_value = 0;
-	u32                     field_byte_width;
-
-
-	/* Obj_desc is validated by callers */
-
-	if (obj_desc) {
-		rgn_desc = obj_desc->field.container;
-	}
-
-
-	field_byte_width = DIV_8 (field_bit_width);
-	status = acpi_aml_setup_field (obj_desc, rgn_desc, field_bit_width);
-	if (ACPI_FAILURE (status)) {
-		return (status);
-	}
-
-	/* Setup_field validated Rgn_desc and Field_bit_width */
-
-	if (!value) {
-		value = &local_value;   /*  support reads without saving value  */
-	}
-
-
-	/*
-	 * Set offset to next multiple of field width,
-	 *  add region base address and offset within the field
-	 */
-	address = rgn_desc->region.address +
-			  (obj_desc->field.offset * field_byte_width) +
-			  field_byte_offset;
-
-
-	/* Invoke the appropriate Address_space/Op_region handler */
-
-	status = acpi_ev_address_space_dispatch (rgn_desc, ADDRESS_SPACE_READ,
-			 address, field_bit_width, value);
-
-
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_read_field
- *
- * PARAMETERS:  *Obj_desc           - Field to be read
- *              *Value              - Where to store value
- *              Field_bit_width     - Field Width in bits (8, 16, or 32)
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Retrieve the value of the given field
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_read_field (
-	ACPI_OPERAND_OBJECT     *obj_desc,
-	void                    *buffer,
-	u32                     buffer_length,
-	u32                     byte_length,
-	u32                     datum_length,
-	u32                     bit_granularity,
-	u32                     byte_granularity)
-{
-	ACPI_STATUS             status;
-	u32                     this_field_byte_offset;
-	u32                     this_field_datum_offset;
-	u32                     previous_raw_datum;
-	u32                     this_raw_datum = 0;
-	u32                     valid_field_bits;
-	u32                     mask;
-	u32                     merged_datum = 0;
-
-
-	/*
-	 * Clear the caller's buffer (the whole buffer length as given)
-	 * This is very important, especially in the cases where a byte is read,
-	 * but the buffer is really a u32 (4 bytes).
-	 */
-
-	MEMSET (buffer, 0, buffer_length);
-
-	/* Read the first raw datum to prime the loop */
-
-	this_field_byte_offset = 0;
-	this_field_datum_offset= 0;
-
-	status = acpi_aml_read_field_data (obj_desc, this_field_byte_offset, bit_granularity,
-			   &previous_raw_datum);
-	if (ACPI_FAILURE (status)) {
-		goto cleanup;
-	}
-
-	/* We might actually be done if the request fits in one datum */
-
-	if ((datum_length == 1) &&
-		((obj_desc->field.bit_offset + obj_desc->field_unit.length) <=
-			(u16) bit_granularity))
-	{
-		merged_datum = previous_raw_datum;
-
-		merged_datum = (merged_datum >> obj_desc->field.bit_offset);
-
-		valid_field_bits = obj_desc->field_unit.length % bit_granularity;
-		if (valid_field_bits) {
-			mask = (((u32) 1 << valid_field_bits) - (u32) 1);
-			merged_datum &= mask;
-		}
-
-
-		/*
-		 * Place the Merged_datum into the proper format and return buffer
-		 * field
-		 */
-
-		switch (byte_granularity)
-		{
-		case 1:
-			((u8 *) buffer) [this_field_datum_offset] = (u8) merged_datum;
-			break;
-
-		case 2:
-			MOVE_UNALIGNED16_TO_16 (&(((u16 *) buffer)[this_field_datum_offset]), &merged_datum);
-			break;
-
-		case 4:
-			MOVE_UNALIGNED32_TO_32 (&(((u32 *) buffer)[this_field_datum_offset]), &merged_datum);
-			break;
-		}
-
-		this_field_byte_offset = 1;
-		this_field_datum_offset = 1;
-	}
-
-	else {
-		/* We need to get more raw data to complete one or more field data */
-
-		while (this_field_datum_offset < datum_length) {
-			/*
-			 * If the field is aligned on a byte boundary, we don't want
-			 * to perform a final read, since this would potentially read
-			 * past the end of the region.
-			 *
-			 * TBD: [Investigate] It may make more sense to just split the aligned
-			 * and non-aligned cases since the aligned case is so very simple,
-			 */
-			if ((obj_desc->field.bit_offset != 0) ||
-				((obj_desc->field.bit_offset == 0) &&
-				(this_field_datum_offset < (datum_length -1))))
-			{
-				/*
-				 * Get the next raw datum, it contains some or all bits
-				 * of the current field datum
-				 */
-
-				status = acpi_aml_read_field_data (obj_desc,
-						  this_field_byte_offset + byte_granularity,
-						  bit_granularity, &this_raw_datum);
-				if (ACPI_FAILURE (status)) {
-					goto cleanup;
-				}
-
-				/* Before merging the data, make sure the unused bits are clear */
-
-				switch (byte_granularity)
-				{
-				case 1:
-					this_raw_datum &= 0x000000FF;
-					previous_raw_datum &= 0x000000FF;
-					break;
-
-				case 2:
-					this_raw_datum &= 0x0000FFFF;
-					previous_raw_datum &= 0x0000FFFF;
-					break;
-				}
-			}
-
-
-			/*
-			 * Put together bits of the two raw data to make a complete
-			 * field datum
-			 */
-
-
-			if (obj_desc->field.bit_offset != 0) {
-				merged_datum =
-					(previous_raw_datum >> obj_desc->field.bit_offset) |
-					(this_raw_datum << (bit_granularity - obj_desc->field.bit_offset));
-			}
-
-			else {
-				merged_datum = previous_raw_datum;
-			}
-
-			/*
-			 * Prepare the merged datum for storing into the caller's
-			 *  buffer.  It is possible to have a 32-bit buffer
-			 *  (Byte_granularity == 4), but a Obj_desc->Field.Length
-			 *  of 8 or 16, meaning that the upper bytes of merged data
-			 *  are undesired.  This section fixes that.
-			 */
-			switch (obj_desc->field.length)
-			{
-			case 8:
-				merged_datum &= 0x000000FF;
-				break;
-
-			case 16:
-				merged_datum &= 0x0000FFFF;
-				break;
-			}
-
-			/*
-			 * Now store the datum in the caller's buffer, according to
-			 * the data type
-			 */
-			switch (byte_granularity)
-			{
-			case 1:
-				((u8 *) buffer) [this_field_datum_offset] = (u8) merged_datum;
-				break;
-
-			case 2:
-				MOVE_UNALIGNED16_TO_16 (&(((u16 *) buffer) [this_field_datum_offset]), &merged_datum);
-				break;
-
-			case 4:
-				MOVE_UNALIGNED32_TO_32 (&(((u32 *) buffer) [this_field_datum_offset]), &merged_datum);
-				break;
-			}
-
-			/*
-			 * Save the most recent datum since it contains bits of
-			 * the *next* field datum
-			 */
-
-			previous_raw_datum = this_raw_datum;
-
-			this_field_byte_offset += byte_granularity;
-			this_field_datum_offset++;
-
-		}  /* while */
-	}
-
-cleanup:
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_write_field_data
- *
- * PARAMETERS:  *Obj_desc           - Field to be set
- *              Value               - Value to store
- *              Field_bit_width     - Field Width in bits (8, 16, or 32)
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Store the value into the given field
- *
- ******************************************************************************/
-
-static ACPI_STATUS
-acpi_aml_write_field_data (
-	ACPI_OPERAND_OBJECT     *obj_desc,
-	u32                     field_byte_offset,
-	u32                     field_bit_width,
-	u32                     value)
-{
-	ACPI_STATUS             status = AE_OK;
-	ACPI_OPERAND_OBJECT     *rgn_desc = NULL;
-	ACPI_PHYSICAL_ADDRESS   address;
-	u32                     field_byte_width;
-
-
-	/* Obj_desc is validated by callers */
-
-	if (obj_desc) {
-		rgn_desc = obj_desc->field.container;
-	}
-
-	field_byte_width = DIV_8 (field_bit_width);
-	status = acpi_aml_setup_field (obj_desc, rgn_desc, field_bit_width);
-	if (ACPI_FAILURE (status)) {
-		return (status);
-	}
-
-
-	/*
-	 * Set offset to next multiple of field width,
-	 *  add region base address and offset within the field
-	 */
-	address = rgn_desc->region.address +
-			  (obj_desc->field.offset * field_byte_width) +
-			  field_byte_offset;
-
-	/* Invoke the appropriate Address_space/Op_region handler */
-
-	status = acpi_ev_address_space_dispatch (rgn_desc, ADDRESS_SPACE_WRITE,
-			 address, field_bit_width, &value);
-
-
-
-	return (status);
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Acpi_aml_write_field_data_with_update_rule
- *
- * PARAMETERS:  *Obj_desc           - Field to be set
- *              Value               - Value to store
- *              Field_bit_width     - Field Width in bits (8, 16, or 32)
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Apply the field update rule to a field write
- *
- ****************************************************************************/
-
-static ACPI_STATUS
-acpi_aml_write_field_data_with_update_rule (
-	ACPI_OPERAND_OBJECT     *obj_desc,
-	u32                     mask,
-	u32                     field_value,
-	u32                     this_field_byte_offset,
-	u32                     bit_granularity)
-{
-	ACPI_STATUS             status = AE_OK;
-	u32                     merged_value;
-	u32                     current_value;
-
-
-	/* Start with the new bits  */
-
-	merged_value = field_value;
-
-
-	/* Decode the update rule */
-
-	switch (obj_desc->field.update_rule)
-	{
-
-	case UPDATE_PRESERVE:
-
-		/* Check if update rule needs to be applied (not if mask is all ones) */
-
-		/* The left shift drops the bits we want to ignore. */
-		if ((~mask << (sizeof(mask)*8 - bit_granularity)) != 0) {
-			/*
-			 * Read the current contents of the byte/word/dword containing
-			 * the field, and merge with the new field value.
-			 */
-			status = acpi_aml_read_field_data (obj_desc, this_field_byte_offset,
-					   bit_granularity, &current_value);
-			merged_value |= (current_value & ~mask);
-		}
-		break;
-
-
-	case UPDATE_WRITE_AS_ONES:
-
-		/* Set positions outside the field to all ones */
-
-		merged_value |= ~mask;
-		break;
-
-
-	case UPDATE_WRITE_AS_ZEROS:
-
-		/* Set positions outside the field to all zeros */
-
-		merged_value &= mask;
-		break;
-
-
-	default:
-		status = AE_AML_OPERAND_VALUE;
-	}
-
-
-	/* Write the merged value */
-
-	if (ACPI_SUCCESS (status)) {
-		status = acpi_aml_write_field_data (obj_desc, this_field_byte_offset,
-				   bit_granularity, merged_value);
-	}
-
-	return (status);
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    Acpi_aml_write_field
- *
- * PARAMETERS:  *Obj_desc           - Field to be set
- *              Value               - Value to store
- *              Field_bit_width     - Field Width in bits (8, 16, or 32)
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Store the value into the given field
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_aml_write_field (
-	ACPI_OPERAND_OBJECT     *obj_desc,
-	void                    *buffer,
-	u32                     buffer_length,
-	u32                     byte_length,
-	u32                     datum_length,
-	u32                     bit_granularity,
-	u32                     byte_granularity)
-{
-	ACPI_STATUS             status;
-	u32                     this_field_byte_offset;
-	u32                     this_field_datum_offset;
-	u32                     mask;
-	u32                     merged_datum;
-	u32                     previous_raw_datum;
-	u32                     this_raw_datum;
-	u32                     field_value;
-	u32                     valid_field_bits;
-
-
-	/*
-	 * Break the request into up to three parts:
-	 * non-aligned part at start, aligned part in middle, non-aligned part
-	 * at end --- Just like an I/O request ---
-	 */
-
-	this_field_byte_offset = 0;
-	this_field_datum_offset= 0;
-
-	/* Get a datum */
-
-	switch (byte_granularity)
-	{
-	case 1:
-		previous_raw_datum = ((u8 *) buffer) [this_field_datum_offset];
-		break;
-
-	case 2:
-		MOVE_UNALIGNED16_TO_32 (&previous_raw_datum, &(((u16 *) buffer) [this_field_datum_offset]));
-		break;
-
-	case 4:
-		MOVE_UNALIGNED32_TO_32 (&previous_raw_datum, &(((u32 *) buffer) [this_field_datum_offset]));
-		break;
-
-	default:
-		status = AE_AML_OPERAND_VALUE;
-		goto cleanup;
-	}
-
-
-	/*
-	 * Write a partial field datum if field does not begin on a datum boundary
-	 *
-	 * Construct Mask with 1 bits where the field is, 0 bits elsewhere
-	 *
-	 * 1) Bits above the field
-	 */
-
-	mask = (((u32)(-1)) << (u32)obj_desc->field.bit_offset);
-
-	/* 2) Only the bottom 5 bits are valid for a shift operation. */
-
-	if ((obj_desc->field.bit_offset + obj_desc->field_unit.length) < 32) {
-		/* Bits above the field */
-
-		mask &= (~(((u32)(-1)) << ((u32)obj_desc->field.bit_offset +
-				   (u32)obj_desc->field_unit.length)));
-	}
-
-	/* 3) Shift and mask the value into the field position */
-
-	field_value = (previous_raw_datum << obj_desc->field.bit_offset) & mask;
-
-	status = acpi_aml_write_field_data_with_update_rule (obj_desc, mask, field_value,
-			 this_field_byte_offset,
-			 bit_granularity);
-	if (ACPI_FAILURE (status)) {
-		goto cleanup;
-	}
-
-
-	/* If the field fits within one datum, we are done. */
-
-	if ((datum_length == 1) &&
-	   ((obj_desc->field.bit_offset + obj_desc->field_unit.length) <=
-			(u16) bit_granularity))
-	{
-		goto cleanup;
-	}
-
-	/*
-	 * We don't need to worry about the update rule for these data, because
-	 * all of the bits are part of the field.
-	 *
-	 * Can't write the last datum, however, because it might contain bits that
-	 * are not part of the field -- the update rule must be applied.
-	 */
-
-	while (this_field_datum_offset < (datum_length - 1)) {
-		this_field_datum_offset++;
-
-		/* Get the next raw datum, it contains bits of the current field datum... */
-
-		switch (byte_granularity)
-		{
-		case 1:
-			this_raw_datum = ((u8 *) buffer) [this_field_datum_offset];
-			break;
-
-		case 2:
-			MOVE_UNALIGNED16_TO_32 (&this_raw_datum, &(((u16 *) buffer) [this_field_datum_offset]));
-			break;
-
-		case 4:
-			MOVE_UNALIGNED32_TO_32 (&this_raw_datum, &(((u32 *) buffer) [this_field_datum_offset]));
-			break;
-
-		default:
-			status = AE_AML_OPERAND_VALUE;
-			goto cleanup;
-		}
-
-		/*
-		 * Put together bits of the two raw data to make a complete field
-		 * datum
-		 */
-
-		if (obj_desc->field.bit_offset != 0) {
-			merged_datum =
-				(previous_raw_datum >> (bit_granularity - obj_desc->field.bit_offset)) |
-				(this_raw_datum << obj_desc->field.bit_offset);
-		}
-
-		else {
-			merged_datum = this_raw_datum;
-		}
-
-		/* Now write the completed datum  */
-
-
-		status = acpi_aml_write_field_data (obj_desc,
-				   this_field_byte_offset + byte_granularity,
-				   bit_granularity, merged_datum);
-		if (ACPI_FAILURE (status)) {
-			goto cleanup;
-		}
-
-
-		/*
-		 * Save the most recent datum since it contains bits of
-		 * the *next* field datum
-		 */
-
-		previous_raw_datum = this_raw_datum;
-
-		this_field_byte_offset += byte_granularity;
-
-	}  /* while */
-
-
-	/* Write a partial field datum if field does not end on a datum boundary */
-
-	if ((obj_desc->field_unit.length + obj_desc->field_unit.bit_offset) %
-		bit_granularity)
-	{
-		switch (byte_granularity)
-		{
-		case 1:
-			this_raw_datum = ((u8 *) buffer) [this_field_datum_offset];
-			break;
-
-		case 2:
-			MOVE_UNALIGNED16_TO_32 (&this_raw_datum, &(((u16 *) buffer) [this_field_datum_offset]));
-			break;
-
-		case 4:
-			MOVE_UNALIGNED32_TO_32 (&this_raw_datum, &(((u32 *) buffer) [this_field_datum_offset]));
-			break;
-		}
-
-		/* Construct Mask with 1 bits where the field is, 0 bits elsewhere */
-
-		valid_field_bits = ((obj_desc->field_unit.length % bit_granularity) +
-				   obj_desc->field.bit_offset);
-
-		mask = (((u32) 1 << valid_field_bits) - (u32) 1);
-
-		/* Shift and mask the value into the field position */
-
-		field_value = (previous_raw_datum >>
-				  (bit_granularity - obj_desc->field.bit_offset)) & mask;
-
-		status = acpi_aml_write_field_data_with_update_rule (obj_desc, mask, field_value,
-				 this_field_byte_offset + byte_granularity,
-				 bit_granularity);
-		if (ACPI_FAILURE (status)) {
-			goto cleanup;
-		}
-	}
-
-
-cleanup:
-
-	return (status);
-}
-
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/ammisc.c linux/drivers/acpi/interpreter/ammisc.c
--- v2.4.5/linux/drivers/acpi/interpreter/ammisc.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/interpreter/ammisc.c	Wed Dec 31 16:00:00 1969
@@ -1,529 +0,0 @@
-
-/******************************************************************************
- *
- * Module Name: ammisc - ACPI AML (p-code) execution - specific opcodes
- *              $Revision: 73 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acparser.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acdispat.h"
-
-
-#define _COMPONENT          INTERPRETER
-	 MODULE_NAME         ("ammisc")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_fatal
- *
- * PARAMETERS:  none
- *
- * RETURN:      Status.  If the OS returns from the OSD call, we just keep
- *              on going.
- *
- * DESCRIPTION: Execute Fatal operator
- *
- * ACPI SPECIFICATION REFERENCES:
- *  Def_fatal   :=  Fatal_op Fatal_type Fatal_code  Fatal_arg
- *  Fatal_type  :=  Byte_data
- *  Fatal_code  :=  DWord_data
- *  Fatal_arg   :=  Term_arg=>Integer
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_exec_fatal (
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_OPERAND_OBJECT     *type_desc;
-	ACPI_OPERAND_OBJECT     *code_desc;
-	ACPI_OPERAND_OBJECT     *arg_desc;
-	ACPI_STATUS             status;
-
-
-	/* Resolve operands */
-
-	status = acpi_aml_resolve_operands (AML_FATAL_OP, WALK_OPERANDS, walk_state);
-	/* Get operands */
-
-	status |= acpi_ds_obj_stack_pop_object (&arg_desc, walk_state);
-	status |= acpi_ds_obj_stack_pop_object (&code_desc, walk_state);
-	status |= acpi_ds_obj_stack_pop_object (&type_desc, walk_state);
-	if (ACPI_FAILURE (status)) {
-		/* Invalid parameters on object stack  */
-
-		goto cleanup;
-	}
-
-
-	/* Def_fatal   :=  Fatal_op Fatal_type Fatal_code  Fatal_arg   */
-
-
-	/*
-	 * TBD: [Unhandled] call OSD interface to notify OS of fatal error
-	 * requiring shutdown!
-	 */
-
-
-cleanup:
-
-	/* Free the operands */
-
-	acpi_cm_remove_reference (arg_desc);
-	acpi_cm_remove_reference (code_desc);
-	acpi_cm_remove_reference (type_desc);
-
-
-	/* If we get back from the OS call, we might as well keep going. */
-
-	REPORT_WARNING (("An AML \"fatal\" Opcode (Fatal_op) was executed\n"));
-	return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_index
- *
- * PARAMETERS:  none
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Execute Index operator
- *
- * ALLOCATION:  Deletes one operand descriptor -- other remains on stack
- *
- *  ACPI SPECIFICATION REFERENCES:
- *  Def_index   :=  Index_op Buff_pkg_obj Index_value Result
- *  Index_value :=  Term_arg=>Integer
- *  Name_string :=  <Root_char Name_path> | <Prefix_path Name_path>
- *  Result      :=  Super_name
- *  Super_name  :=  Name_string | Arg_obj | Local_obj | Debug_obj | Def_index
- *                             Local4_op | Local5_op | Local6_op | Local7_op
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_exec_index (
-	ACPI_WALK_STATE         *walk_state,
-	ACPI_OPERAND_OBJECT     **return_desc)
-{
-	ACPI_OPERAND_OBJECT     *obj_desc;
-	ACPI_OPERAND_OBJECT     *idx_desc;
-	ACPI_OPERAND_OBJECT     *res_desc;
-	ACPI_OPERAND_OBJECT     *ret_desc = NULL;
-	ACPI_OPERAND_OBJECT     *tmp_desc;
-	ACPI_STATUS             status;
-
-
-	/* Resolve operands */
-	/* First operand can be either a package or a buffer */
-
-	status = acpi_aml_resolve_operands (AML_INDEX_OP, WALK_OPERANDS, walk_state);
-	/* Get all operands */
-
-	status |= acpi_ds_obj_stack_pop_object (&res_desc, walk_state);
-	status |= acpi_ds_obj_stack_pop_object (&idx_desc, walk_state);
-	status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
-	if (ACPI_FAILURE (status)) {
-		/* Invalid parameters on object stack  */
-
-		goto cleanup;
-	}
-
-
-	/* Create the internal return object */
-
-	ret_desc = acpi_cm_create_internal_object (INTERNAL_TYPE_REFERENCE);
-	if (!ret_desc) {
-		status = AE_NO_MEMORY;
-		goto cleanup;
-	}
-
-
-	/*
-	 * At this point, the Obj_desc operand is either a Package or a Buffer
-	 */
-
-	if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
-		/* Object to be indexed is a Package */
-
-		if (idx_desc->integer.value >= obj_desc->package.count) {
-			status = AE_AML_PACKAGE_LIMIT;
-			goto cleanup;
-		}
-
-		if ((res_desc->common.type == INTERNAL_TYPE_REFERENCE) &&
-			(res_desc->reference.op_code == AML_ZERO_OP))
-		{
-			/*
-			 * There is no actual result descriptor (the Zero_op Result
-			 * descriptor is a placeholder), so just delete the placeholder and
-			 * return a reference to the package element
-			 */
-
-			acpi_cm_remove_reference (res_desc);
-		}
-
-		else {
-			/*
-			 * Each element of the package is an internal object.  Get the one
-			 * we are after.
-			 */
-
-			tmp_desc                      = obj_desc->package.elements[idx_desc->integer.value];
-			ret_desc->reference.op_code   = AML_INDEX_OP;
-			ret_desc->reference.target_type = tmp_desc->common.type;
-			ret_desc->reference.object    = tmp_desc;
-
-			status = acpi_aml_exec_store (ret_desc, res_desc, walk_state);
-			ret_desc->reference.object    = NULL;
-		}
-
-		/*
-		 * The local return object must always be a reference to the package element,
-		 * not the element itself.
-		 */
-		ret_desc->reference.op_code   = AML_INDEX_OP;
-		ret_desc->reference.target_type = ACPI_TYPE_PACKAGE;
-		ret_desc->reference.where     = &obj_desc->package.elements[idx_desc->integer.value];
-	}
-
-	else {
-		/* Object to be indexed is a Buffer */
-
-		if (idx_desc->integer.value >= obj_desc->buffer.length) {
-			status = AE_AML_BUFFER_LIMIT;
-			goto cleanup;
-		}
-
-		ret_desc->reference.op_code     = AML_INDEX_OP;
-		ret_desc->reference.target_type = ACPI_TYPE_BUFFER_FIELD;
-		ret_desc->reference.object      = obj_desc;
-		ret_desc->reference.offset      = (u32) idx_desc->integer.value;
-
-		status = acpi_aml_exec_store (ret_desc, res_desc, walk_state);
-	}
-
-
-cleanup:
-
-	/* Always delete operands */
-
-	acpi_cm_remove_reference (obj_desc);
-	acpi_cm_remove_reference (idx_desc);
-
-	/* Delete return object on error */
-
-	if (ACPI_FAILURE (status)) {
-		acpi_cm_remove_reference (res_desc);
-
-		if (ret_desc) {
-			acpi_cm_remove_reference (ret_desc);
-			ret_desc = NULL;
-		}
-	}
-
-	/* Set the return object and exit */
-
-	*return_desc = ret_desc;
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_match
- *
- * PARAMETERS:  none
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Execute Match operator
- *
- * ACPI SPECIFICATION REFERENCES:
- *  Def_match   :=  Match_op Search_pkg Opcode1     Operand1
- *                              Opcode2 Operand2    Start_index
- *  Opcode1     :=  Byte_data: MTR, MEQ, MLE, MLT, MGE, or MGT
- *  Opcode2     :=  Byte_data: MTR, MEQ, MLE, MLT, MGE, or MGT
- *  Operand1    :=  Term_arg=>Integer
- *  Operand2    :=  Term_arg=>Integer
- *  Search_pkg  :=  Term_arg=>Package_object
- *  Start_index :=  Term_arg=>Integer
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_exec_match (
-	ACPI_WALK_STATE         *walk_state,
-	ACPI_OPERAND_OBJECT     **return_desc)
-{
-	ACPI_OPERAND_OBJECT     *pkg_desc;
-	ACPI_OPERAND_OBJECT     *op1_desc;
-	ACPI_OPERAND_OBJECT     *V1_desc;
-	ACPI_OPERAND_OBJECT     *op2_desc;
-	ACPI_OPERAND_OBJECT     *V2_desc;
-	ACPI_OPERAND_OBJECT     *start_desc;
-	ACPI_OPERAND_OBJECT     *ret_desc = NULL;
-	ACPI_STATUS             status;
-	u32                     index;
-	u32                     match_value = (u32) -1;
-
-
-	/* Resolve all operands */
-
-	status = acpi_aml_resolve_operands (AML_MATCH_OP, WALK_OPERANDS, walk_state);
-	/* Get all operands */
-
-	status |= acpi_ds_obj_stack_pop_object (&start_desc, walk_state);
-	status |= acpi_ds_obj_stack_pop_object (&V2_desc, walk_state);
-	status |= acpi_ds_obj_stack_pop_object (&op2_desc, walk_state);
-	status |= acpi_ds_obj_stack_pop_object (&V1_desc, walk_state);
-	status |= acpi_ds_obj_stack_pop_object (&op1_desc, walk_state);
-	status |= acpi_ds_obj_stack_pop_object (&pkg_desc, walk_state);
-
-	if (ACPI_FAILURE (status)) {
-		/* Invalid parameters on object stack  */
-
-		goto cleanup;
-	}
-
-	/* Validate match comparison sub-opcodes */
-
-	if ((op1_desc->integer.value > MAX_MATCH_OPERATOR) ||
-		(op2_desc->integer.value > MAX_MATCH_OPERATOR))
-	{
-		status = AE_AML_OPERAND_VALUE;
-		goto cleanup;
-	}
-
-	index = (u32) start_desc->integer.value;
-	if (index >= (u32) pkg_desc->package.count) {
-		status = AE_AML_PACKAGE_LIMIT;
-		goto cleanup;
-	}
-
-	ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
-	if (!ret_desc) {
-		status = AE_NO_MEMORY;
-		goto cleanup;
-
-	}
-
-	/*
-	 * Examine each element until a match is found.  Within the loop,
-	 * "continue" signifies that the current element does not match
-	 * and the next should be examined.
-	 * Upon finding a match, the loop will terminate via "break" at
-	 * the bottom.  If it terminates "normally", Match_value will be -1
-	 * (its initial value) indicating that no match was found.  When
-	 * returned as a Number, this will produce the Ones value as specified.
-	 */
-
-	for ( ; index < pkg_desc->package.count; ++index) {
-		/*
-		 * Treat any NULL or non-numeric elements as non-matching.
-		 * TBD [Unhandled] - if an element is a Name,
-		 *      should we examine its value?
-		 */
-		if (!pkg_desc->package.elements[index] ||
-			ACPI_TYPE_INTEGER != pkg_desc->package.elements[index]->common.type)
-		{
-			continue;
-		}
-
-		/*
-		 * Within these switch statements:
-		 *      "break" (exit from the switch) signifies a match;
-		 *      "continue" (proceed to next iteration of enclosing
-		 *          "for" loop) signifies a non-match.
-		 */
-		switch (op1_desc->integer.value)
-		{
-
-		case MATCH_MTR:   /* always true */
-
-			break;
-
-
-		case MATCH_MEQ:   /* true if equal   */
-
-			if (pkg_desc->package.elements[index]->integer.value
-				 != V1_desc->integer.value)
-			{
-				continue;
-			}
-			break;
-
-
-		case MATCH_MLE:   /* true if less than or equal  */
-
-			if (pkg_desc->package.elements[index]->integer.value
-				 > V1_desc->integer.value)
-			{
-				continue;
-			}
-			break;
-
-
-		case MATCH_MLT:   /* true if less than   */
-
-			if (pkg_desc->package.elements[index]->integer.value
-				 >= V1_desc->integer.value)
-			{
-				continue;
-			}
-			break;
-
-
-		case MATCH_MGE:   /* true if greater than or equal   */
-
-			if (pkg_desc->package.elements[index]->integer.value
-				 < V1_desc->integer.value)
-			{
-				continue;
-			}
-			break;
-
-
-		case MATCH_MGT:   /* true if greater than    */
-
-			if (pkg_desc->package.elements[index]->integer.value
-				 <= V1_desc->integer.value)
-			{
-				continue;
-			}
-			break;
-
-
-		default:    /* undefined   */
-
-			continue;
-		}
-
-
-		switch(op2_desc->integer.value)
-		{
-
-		case MATCH_MTR:
-
-			break;
-
-
-		case MATCH_MEQ:
-
-			if (pkg_desc->package.elements[index]->integer.value
-				 != V2_desc->integer.value)
-			{
-				continue;
-			}
-			break;
-
-
-		case MATCH_MLE:
-
-			if (pkg_desc->package.elements[index]->integer.value
-				 > V2_desc->integer.value)
-			{
-				continue;
-			}
-			break;
-
-
-		case MATCH_MLT:
-
-			if (pkg_desc->package.elements[index]->integer.value
-				 >= V2_desc->integer.value)
-			{
-				continue;
-			}
-			break;
-
-
-		case MATCH_MGE:
-
-			if (pkg_desc->package.elements[index]->integer.value
-				 < V2_desc->integer.value)
-			{
-				continue;
-			}
-			break;
-
-
-		case MATCH_MGT:
-
-			if (pkg_desc->package.elements[index]->integer.value
-				 <= V2_desc->integer.value)
-			{
-				continue;
-			}
-			break;
-
-
-		default:
-
-			continue;
-		}
-
-		/* Match found: exit from loop */
-
-		match_value = index;
-		break;
-	}
-
-	/* Match_value is the return value */
-
-	ret_desc->integer.value = match_value;
-
-
-cleanup:
-
-	/* Free the operands */
-
-	acpi_cm_remove_reference (start_desc);
-	acpi_cm_remove_reference (V2_desc);
-	acpi_cm_remove_reference (op2_desc);
-	acpi_cm_remove_reference (V1_desc);
-	acpi_cm_remove_reference (op1_desc);
-	acpi_cm_remove_reference (pkg_desc);
-
-
-	/* Delete return object on error */
-
-	if (ACPI_FAILURE (status) &&
-		(ret_desc))
-	{
-		acpi_cm_remove_reference (ret_desc);
-		ret_desc = NULL;
-	}
-
-
-	/* Set the return object and exit */
-
-	*return_desc = ret_desc;
-	return (status);
-}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/ammonad.c linux/drivers/acpi/interpreter/ammonad.c
--- v2.4.5/linux/drivers/acpi/interpreter/ammonad.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/interpreter/ammonad.c	Wed Dec 31 16:00:00 1969
@@ -1,999 +0,0 @@
-
-/******************************************************************************
- *
- * Module Name: ammonad - ACPI AML (p-code) execution for monadic operators
- *              $Revision: 89 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acparser.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acnamesp.h"
-
-
-#define _COMPONENT          INTERPRETER
-	 MODULE_NAME         ("ammonad")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_get_object_reference
- *
- * PARAMETERS:  Obj_desc        - Create a reference to this object
- *              Ret_desc        - Where to store the reference
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Obtain and return a "reference" to the target object
- *              Common code for the Ref_of_op and the Cond_ref_of_op.
- *
- ******************************************************************************/
-
-static ACPI_STATUS
-acpi_aml_get_object_reference (
-	ACPI_OPERAND_OBJECT     *obj_desc,
-	ACPI_OPERAND_OBJECT     **ret_desc,
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_STATUS             status = AE_OK;
-
-
-	if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) {
-		if (obj_desc->common.type != INTERNAL_TYPE_REFERENCE) {
-			*ret_desc = NULL;
-			status = AE_TYPE;
-			goto cleanup;
-		}
-
-		/*
-		 * Not a Name -- an indirect name pointer would have
-		 * been converted to a direct name pointer in Acpi_aml_resolve_operands
-		 */
-		switch (obj_desc->reference.op_code)
-		{
-		case AML_LOCAL_OP:
-
-			*ret_desc = (void *) acpi_ds_method_data_get_nte (MTH_TYPE_LOCAL,
-					  (obj_desc->reference.offset), walk_state);
-			break;
-
-
-		case AML_ARG_OP:
-
-			*ret_desc = (void *) acpi_ds_method_data_get_nte (MTH_TYPE_ARG,
-					  (obj_desc->reference.offset), walk_state);
-			break;
-
-
-		default:
-
-			*ret_desc = NULL;
-			status = AE_AML_INTERNAL;
-			goto cleanup;
-		}
-
-	}
-
-	else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
-		/* Must be a named object;  Just return the Node */
-
-		*ret_desc = obj_desc;
-	}
-
-	else {
-		*ret_desc = NULL;
-		status = AE_TYPE;
-	}
-
-
-cleanup:
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_monadic1
- *
- * PARAMETERS:  Opcode              - The opcode to be executed
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on
- *              object stack
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_exec_monadic1 (
-	u16                     opcode,
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_OPERAND_OBJECT     *obj_desc;
-	ACPI_STATUS             status;
-
-
-	/* Resolve all operands */
-
-	status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
-	/* Get all operands */
-
-	status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
-	if (ACPI_FAILURE (status)) {
-		goto cleanup;
-	}
-
-
-	/* Examine the opcode */
-
-	switch (opcode)
-	{
-
-	/*  Def_release :=  Release_op  Mutex_object */
-
-	case AML_RELEASE_OP:
-
-		status = acpi_aml_system_release_mutex (obj_desc);
-		break;
-
-
-	/*  Def_reset   :=  Reset_op    Acpi_event_object */
-
-	case AML_RESET_OP:
-
-		status = acpi_aml_system_reset_event (obj_desc);
-		break;
-
-
-	/*  Def_signal  :=  Signal_op   Acpi_event_object */
-
-	case AML_SIGNAL_OP:
-
-		status = acpi_aml_system_signal_event (obj_desc);
-		break;
-
-
-	/*  Def_sleep   :=  Sleep_op    Msec_time   */
-
-	case AML_SLEEP_OP:
-
-		acpi_aml_system_do_suspend ((u32) obj_desc->integer.value);
-		break;
-
-
-	/*  Def_stall   :=  Stall_op    Usec_time   */
-
-	case AML_STALL_OP:
-
-		acpi_aml_system_do_stall ((u32) obj_desc->integer.value);
-		break;
-
-
-	/*  Unknown opcode  */
-
-	default:
-
-		REPORT_ERROR (("Acpi_aml_exec_monadic1: Unknown monadic opcode %X\n",
-			opcode));
-		status = AE_AML_BAD_OPCODE;
-		break;
-
-	} /* switch */
-
-
-cleanup:
-
-	/* Always delete the operand */
-
-	acpi_cm_remove_reference (obj_desc);
-
-	return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_monadic2_r
- *
- * PARAMETERS:  Opcode              - The opcode to be executed
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Execute Type 2 monadic operator with numeric operand and
- *              result operand on operand stack
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_exec_monadic2_r (
-	u16                     opcode,
-	ACPI_WALK_STATE         *walk_state,
-	ACPI_OPERAND_OBJECT     **return_desc)
-{
-	ACPI_OPERAND_OBJECT     *obj_desc;
-	ACPI_OPERAND_OBJECT     *res_desc;
-	ACPI_OPERAND_OBJECT     *ret_desc = NULL;
-	ACPI_OPERAND_OBJECT     *ret_desc2 = NULL;
-	u32                     res_val;
-	ACPI_STATUS             status;
-	u32                     i;
-	u32                     j;
-	ACPI_INTEGER            digit;
-
-
-	/* Resolve all operands */
-
-	status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
-	/* Get all operands */
-
-	status |= acpi_ds_obj_stack_pop_object (&res_desc, walk_state);
-	status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
-	if (ACPI_FAILURE (status)) {
-		goto cleanup;
-	}
-
-
-	/* Create a return object of type NUMBER for most opcodes */
-
-	switch (opcode)
-	{
-	case AML_BIT_NOT_OP:
-	case AML_FIND_SET_LEFT_BIT_OP:
-	case AML_FIND_SET_RIGHT_BIT_OP:
-	case AML_FROM_BCD_OP:
-	case AML_TO_BCD_OP:
-	case AML_COND_REF_OF_OP:
-
-		ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
-		if (!ret_desc) {
-			status = AE_NO_MEMORY;
-			goto cleanup;
-		}
-
-		break;
-	}
-
-
-	switch (opcode)
-	{
-	/*  Def_not :=  Not_op  Operand Result  */
-
-	case AML_BIT_NOT_OP:
-
-		ret_desc->integer.value = ~obj_desc->integer.value;
-		break;
-
-
-	/*  Def_find_set_left_bit := Find_set_left_bit_op Operand Result */
-
-	case AML_FIND_SET_LEFT_BIT_OP:
-
-		ret_desc->integer.value = obj_desc->integer.value;
-
-		/*
-		 * Acpi specification describes Integer type as a little
-		 * endian unsigned value, so this boundry condition is valid.
-		 */
-		for (res_val = 0; ret_desc->integer.value && res_val < ACPI_INTEGER_BIT_SIZE; ++res_val) {
-			ret_desc->integer.value >>= 1;
-		}
-
-		ret_desc->integer.value = res_val;
-		break;
-
-
-	/*  Def_find_set_right_bit := Find_set_right_bit_op Operand Result */
-
-	case AML_FIND_SET_RIGHT_BIT_OP:
-
-		ret_desc->integer.value = obj_desc->integer.value;
-
-		/*
-		 * Acpi specification describes Integer type as a little
-		 * endian unsigned value, so this boundry condition is valid.
-		 */
-		for (res_val = 0; ret_desc->integer.value && res_val < ACPI_INTEGER_BIT_SIZE; ++res_val) {
-			ret_desc->integer.value <<= 1;
-		}
-
-		/* Since returns must be 1-based, subtract from 33 (65) */
-
-		ret_desc->integer.value = res_val == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - res_val;
-		break;
-
-
-	/*  Def_from_bDC := From_bCDOp  BCDValue    Result  */
-
-	case AML_FROM_BCD_OP:
-
-		/*
-		 * The 64-bit ACPI integer can hold 16 4-bit BCD integers
-		 */
-		ret_desc->integer.value = 0;
-		for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) {
-			/* Get one BCD digit */
-
-			digit = (ACPI_INTEGER) ((obj_desc->integer.value >> (i * 4)) & 0xF);
-
-			/* Check the range of the digit */
-
-			if (digit > 9) {
-				status = AE_AML_NUMERIC_OVERFLOW;
-				goto cleanup;
-			}
-
-			if (digit > 0) {
-				/* Sum into the result with the appropriate power of 10 */
-
-				for (j = 0; j < i; j++) {
-					digit *= 10;
-				}
-
-				ret_desc->integer.value += digit;
-			}
-		}
-		break;
-
-
-	/*  Def_to_bDC  :=  To_bCDOp Operand Result */
-
-	case AML_TO_BCD_OP:
-
-
-		if (obj_desc->integer.value > ACPI_MAX_BCD_VALUE) {
-			status = AE_AML_NUMERIC_OVERFLOW;
-			goto cleanup;
-		}
-
-		ret_desc->integer.value = 0;
-		for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) {
-			/* Divide by nth factor of 10 */
-
-			digit = obj_desc->integer.value;
-			for (j = 0; j < i; j++) {
-				digit /= 10;
-			}
-
-			/* Create the BCD digit */
-
-			if (digit > 0) {
-				ret_desc->integer.value += (ACPI_MODULO (digit, 10) << (i * 4));
-			}
-		}
-		break;
-
-
-	/*  Def_cond_ref_of     :=  Cond_ref_of_op  Source_object   Result  */
-
-	case AML_COND_REF_OF_OP:
-
-		/*
-		 * This op is a little strange because the internal return value is
-		 * different than the return value stored in the result descriptor
-		 * (There are really two return values)
-		 */
-
-		if ((ACPI_NAMESPACE_NODE *) obj_desc == acpi_gbl_root_node) {
-			/*
-			 * This means that the object does not exist in the namespace,
-			 * return FALSE
-			 */
-
-			ret_desc->integer.value = 0;
-
-			/*
-			 * Must delete the result descriptor since there is no reference
-			 * being returned
-			 */
-
-			acpi_cm_remove_reference (res_desc);
-			goto cleanup;
-		}
-
-		/* Get the object reference and store it */
-
-		status = acpi_aml_get_object_reference (obj_desc, &ret_desc2, walk_state);
-		if (ACPI_FAILURE (status)) {
-			goto cleanup;
-		}
-
-		status = acpi_aml_exec_store (ret_desc2, res_desc, walk_state);
-
-		/* The object exists in the namespace, return TRUE */
-
-		ret_desc->integer.value = ACPI_INTEGER_MAX;
-		goto cleanup;
-		break;
-
-
-	case AML_STORE_OP:
-
-		/*
-		 * A store operand is typically a number, string, buffer or lvalue
-		 * TBD: [Unhandled] What about a store to a package?
-		 */
-
-		/*
-		 * Do the store, and be careful about deleting the source object,
-		 * since the object itself may have been stored.
-		 */
-
-		status = acpi_aml_exec_store (obj_desc, res_desc, walk_state);
-		if (ACPI_FAILURE (status)) {
-			/* On failure, just delete the Obj_desc */
-
-			acpi_cm_remove_reference (obj_desc);
-		}
-
-		else {
-			/*
-			 * Normally, we would remove a reference on the Obj_desc parameter;
-			 * But since it is being used as the internal return object
-			 * (meaning we would normally increment it), the two cancel out,
-			 * and we simply don't do anything.
-			 */
-			*return_desc = obj_desc;
-		}
-
-		obj_desc = NULL;
-		return (status);
-
-		break;
-
-
-	case AML_DEBUG_OP:
-
-		/* Reference, returning an Reference */
-
-		return (AE_OK);
-		break;
-
-
-	/*
-	 * These are obsolete opcodes
-	 */
-
-	/*  Def_shift_left_bit  :=  Shift_left_bit_op   Source          Bit_num */
-	/*  Def_shift_right_bit :=  Shift_right_bit_op  Source          Bit_num */
-
-	case AML_SHIFT_LEFT_BIT_OP:
-	case AML_SHIFT_RIGHT_BIT_OP:
-
-		status = AE_SUPPORT;
-		goto cleanup;
-		break;
-
-
-	default:
-
-		REPORT_ERROR (("Acpi_aml_exec_monadic2_r: Unknown monadic opcode %X\n",
-			opcode));
-		status = AE_AML_BAD_OPCODE;
-		goto cleanup;
-	}
-
-
-	status = acpi_aml_exec_store (ret_desc, res_desc, walk_state);
-
-
-cleanup:
-	/* Always delete the operand object */
-
-	acpi_cm_remove_reference (obj_desc);
-
-	/* Delete return object(s) on error */
-
-	if (ACPI_FAILURE (status)) {
-		acpi_cm_remove_reference (res_desc); /* Result descriptor */
-		if (ret_desc) {
-			acpi_cm_remove_reference (ret_desc);
-			ret_desc = NULL;
-		}
-	}
-
-	/* Set the return object and exit */
-
-	*return_desc = ret_desc;
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_monadic2
- *
- * PARAMETERS:  Opcode              - The opcode to be executed
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Execute Type 2 monadic operator with numeric operand:
- *              Deref_of_op, Ref_of_op, Size_of_op, Type_op, Increment_op,
- *              Decrement_op, LNot_op,
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_exec_monadic2 (
-	u16                     opcode,
-	ACPI_WALK_STATE         *walk_state,
-	ACPI_OPERAND_OBJECT     **return_desc)
-{
-	ACPI_OPERAND_OBJECT     *obj_desc;
-	ACPI_OPERAND_OBJECT     *tmp_desc;
-	ACPI_OPERAND_OBJECT     *ret_desc = NULL;
-	ACPI_STATUS             resolve_status;
-	ACPI_STATUS             status;
-	u32                     type;
-	ACPI_INTEGER            value;
-
-
-	/* Attempt to resolve the operands */
-
-	resolve_status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
-	/* Always get all operands */
-
-	status = acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
-
-
-	/* Now we can check the status codes */
-
-	if (ACPI_FAILURE (resolve_status)) {
-		goto cleanup;
-	}
-
-	if (ACPI_FAILURE (status)) {
-		goto cleanup;
-	}
-
-
-	/* Get the operand and decode the opcode */
-
-
-	switch (opcode)
-	{
-
-	/*  Def_lNot := LNot_op Operand */
-
-	case AML_LNOT_OP:
-
-		ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
-		if (!ret_desc) {
-			status = AE_NO_MEMORY;
-			goto cleanup;
-		}
-
-		ret_desc->integer.value = !obj_desc->integer.value;
-		break;
-
-
-	/*  Def_decrement   :=  Decrement_op Target */
-	/*  Def_increment   :=  Increment_op Target */
-
-	case AML_DECREMENT_OP:
-	case AML_INCREMENT_OP:
-
-		/*
-		 * Since we are expecting an Reference on the top of the stack, it
-		 * can be either an Node or an internal object.
-		 *
-		 * TBD: [Future] This may be the prototype code for all cases where
-		 * an Reference is expected!! 10/99
-		 */
-
-	   if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
-		   ret_desc = obj_desc;
-	   }
-
-	   else {
-			/*
-			 * Duplicate the Reference in a new object so that we can resolve it
-			 * without destroying the original Reference object
-			 */
-
-			ret_desc = acpi_cm_create_internal_object (INTERNAL_TYPE_REFERENCE);
-			if (!ret_desc) {
-			  status = AE_NO_MEMORY;
-			   goto cleanup;
-			}
-
-			ret_desc->reference.op_code = obj_desc->reference.op_code;
-			ret_desc->reference.offset = obj_desc->reference.offset;
-			ret_desc->reference.object = obj_desc->reference.object;
-		}
-
-
-		/*
-		 * Convert the Ret_desc Reference to a Number
-		 * (This deletes the original Ret_desc)
-		 */
-
-		status = acpi_aml_resolve_operands (AML_LNOT_OP, &ret_desc, walk_state);
-		if (ACPI_FAILURE (status)) {
-			goto cleanup;
-		}
-
-		/* Do the actual increment or decrement */
-
-		if (AML_INCREMENT_OP == opcode) {
-			ret_desc->integer.value++;
-		}
-		else {
-			ret_desc->integer.value--;
-		}
-
-		/* Store the result back in the original descriptor */
-
-		status = acpi_aml_exec_store (ret_desc, obj_desc, walk_state);
-
-		/* Objdesc was just deleted (because it is an Reference) */
-
-		obj_desc = NULL;
-
-		break;
-
-
-	/*  Def_object_type :=  Object_type_op  Source_object   */
-
-	case AML_TYPE_OP:
-
-		if (INTERNAL_TYPE_REFERENCE == obj_desc->common.type) {
-			/*
-			 * Not a Name -- an indirect name pointer would have
-			 * been converted to a direct name pointer in Resolve_operands
-			 */
-			switch (obj_desc->reference.op_code)
-			{
-			case AML_ZERO_OP:
-			case AML_ONE_OP:
-			case AML_ONES_OP:
-
-				/* Constants are of type Number */
-
-				type = ACPI_TYPE_INTEGER;
-				break;
-
-
-			case AML_DEBUG_OP:
-
-				/* Per 1.0b spec, Debug object is of type Debug_object */
-
-				type = ACPI_TYPE_DEBUG_OBJECT;
-				break;
-
-
-			case AML_INDEX_OP:
-
-				/* Get the type of this reference (index into another object) */
-
-				type = obj_desc->reference.target_type;
-				if (type == ACPI_TYPE_PACKAGE) {
-					/*
-					 * The main object is a package, we want to get the type
-					 * of the individual package element that is referenced by
-					 * the index.
-					 */
-					type = (*(obj_desc->reference.where))->common.type;
-				}
-
-				break;
-
-
-			case AML_LOCAL_OP:
-
-				type = acpi_ds_method_data_get_type (MTH_TYPE_LOCAL,
-						  (obj_desc->reference.offset), walk_state);
-				break;
-
-
-			case AML_ARG_OP:
-
-				type = acpi_ds_method_data_get_type (MTH_TYPE_ARG,
-						  (obj_desc->reference.offset), walk_state);
-				break;
-
-
-			default:
-
-				REPORT_ERROR (("Acpi_aml_exec_monadic2/Type_op: Internal error - Unknown Reference subtype %X\n",
-					obj_desc->reference.op_code));
-				status = AE_AML_INTERNAL;
-				goto cleanup;
-			}
-		}
-
-		else {
-			/*
-			 * It's not a Reference, so it must be a direct name pointer.
-			 */
-			type = acpi_ns_get_type ((ACPI_HANDLE) obj_desc);
-		}
-
-		/* Allocate a descriptor to hold the type. */
-
-		ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
-		if (!ret_desc) {
-			status = AE_NO_MEMORY;
-			goto cleanup;
-		}
-
-		ret_desc->integer.value = type;
-		break;
-
-
-	/*  Def_size_of :=  Size_of_op  Source_object   */
-
-	case AML_SIZE_OF_OP:
-
-		if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
-			obj_desc = acpi_ns_get_attached_object (obj_desc);
-		}
-
-		if (!obj_desc) {
-			value = 0;
-		}
-
-		else {
-			switch (obj_desc->common.type)
-			{
-
-			case ACPI_TYPE_BUFFER:
-
-				value = obj_desc->buffer.length;
-				break;
-
-
-			case ACPI_TYPE_STRING:
-
-				value = obj_desc->string.length;
-				break;
-
-
-			case ACPI_TYPE_PACKAGE:
-
-				value = obj_desc->package.count;
-				break;
-
-			case INTERNAL_TYPE_REFERENCE:
-
-				value = 4;
-				break;
-
-			default:
-
-				status = AE_AML_OPERAND_TYPE;
-				goto cleanup;
-			}
-		}
-
-		/*
-		 * Now that we have the size of the object, create a result
-		 * object to hold the value
-		 */
-
-		ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
-		if (!ret_desc) {
-			status = AE_NO_MEMORY;
-			goto cleanup;
-		}
-
-		ret_desc->integer.value = value;
-		break;
-
-
-	/*  Def_ref_of  :=  Ref_of_op   Source_object   */
-
-	case AML_REF_OF_OP:
-
-		status = acpi_aml_get_object_reference (obj_desc, &ret_desc, walk_state);
-		if (ACPI_FAILURE (status)) {
-			goto cleanup;
-		}
-		break;
-
-
-	/*  Def_deref_of := Deref_of_op Obj_reference   */
-
-	case AML_DEREF_OF_OP:
-
-
-		/* Check for a method local or argument */
-
-		if (!VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
-			/*
-			 * Must resolve/dereference the local/arg reference first
-			 */
-			switch (obj_desc->reference.op_code)
-			{
-			/* Set Obj_desc to the value of the local/arg */
-
-			case AML_LOCAL_OP:
-
-				acpi_ds_method_data_get_value (MTH_TYPE_LOCAL,
-						(obj_desc->reference.offset), walk_state, &tmp_desc);
-
-				/*
-				 * Delete our reference to the input object and
-				 * point to the object just retrieved
-				 */
-				acpi_cm_remove_reference (obj_desc);
-				obj_desc = tmp_desc;
-				break;
-
-
-			case AML_ARG_OP:
-
-				acpi_ds_method_data_get_value (MTH_TYPE_ARG,
-						(obj_desc->reference.offset), walk_state, &tmp_desc);
-
-				/*
-				 * Delete our reference to the input object and
-				 * point to the object just retrieved
-				 */
-				acpi_cm_remove_reference (obj_desc);
-				obj_desc = tmp_desc;
-				break;
-
-			default:
-
-				/* Index op - handled below */
-				break;
-			}
-		}
-
-
-		/* Obj_desc may have changed from the code above */
-
-		if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
-			/* Get the actual object from the Node (This is the dereference) */
-
-			ret_desc = ((ACPI_NAMESPACE_NODE *) obj_desc)->object;
-
-			/* Returning a pointer to the object, add another reference! */
-
-			acpi_cm_add_reference (ret_desc);
-		}
-
-		else {
-			/*
-			 * This must be a reference object produced by the Index
-			 * ASL operation -- check internal opcode
-			 */
-
-			if ((obj_desc->reference.op_code != AML_INDEX_OP) &&
-				(obj_desc->reference.op_code != AML_REF_OF_OP))
-			{
-				status = AE_TYPE;
-				goto cleanup;
-			}
-
-
-			switch (obj_desc->reference.op_code)
-			{
-			case AML_INDEX_OP:
-
-				/*
-				 * Supported target types for the Index operator are
-				 * 1) A Buffer
-				 * 2) A Package
-				 */
-
-				if (obj_desc->reference.target_type == ACPI_TYPE_BUFFER_FIELD) {
-					/*
-					 * The target is a buffer, we must create a new object that
-					 * contains one element of the buffer, the element pointed
-					 * to by the index.
-					 *
-					 * NOTE: index into a buffer is NOT a pointer to a
-					 * sub-buffer of the main buffer, it is only a pointer to a
-					 * single element (byte) of the buffer!
-					 */
-					ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
-					if (!ret_desc) {
-						status = AE_NO_MEMORY;
-						goto cleanup;
-					}
-
-					tmp_desc = obj_desc->reference.object;
-					ret_desc->integer.value =
-						tmp_desc->buffer.pointer[obj_desc->reference.offset];
-
-					/* TBD: [Investigate] (see below) Don't add an additional
-					 * ref!
-					 */
-				}
-
-				else if (obj_desc->reference.target_type == ACPI_TYPE_PACKAGE) {
-					/*
-					 * The target is a package, we want to return the referenced
-					 * element of the package.  We must add another reference to
-					 * this object, however.
-					 */
-
-					ret_desc = *(obj_desc->reference.where);
-					if (!ret_desc) {
-						/*
-						 * We can't return a NULL dereferenced value.  This is
-						 * an uninitialized package element and is thus a
-						 * severe error.
-						 */
-
-						status = AE_AML_UNINITIALIZED_ELEMENT;
-						goto cleanup;
-					}
-
-					acpi_cm_add_reference (ret_desc);
-				}
-
-				else {
-					status = AE_AML_OPERAND_TYPE;
-					goto cleanup;
-				}
-
-				break;
-
-
-			case AML_REF_OF_OP:
-
-				ret_desc = obj_desc->reference.object;
-
-				/* Add another reference to the object! */
-
-				acpi_cm_add_reference (ret_desc);
-				break;
-			}
-		}
-
-		break;
-
-
-	default:
-
-		REPORT_ERROR (("Acpi_aml_exec_monadic2: Unknown monadic opcode %X\n",
-			opcode));
-		status = AE_AML_BAD_OPCODE;
-		goto cleanup;
-	}
-
-
-cleanup:
-
-	if (obj_desc) {
-		acpi_cm_remove_reference (obj_desc);
-	}
-
-	/* Delete return object on error */
-
-	if (ACPI_FAILURE (status) &&
-		(ret_desc))
-	{
-		acpi_cm_remove_reference (ret_desc);
-		ret_desc = NULL;
-	}
-
-	*return_desc = ret_desc;
-	return (status);
-}
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/amnames.c linux/drivers/acpi/interpreter/amnames.c
--- v2.4.5/linux/drivers/acpi/interpreter/amnames.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/interpreter/amnames.c	Wed Dec 31 16:00:00 1969
@@ -1,395 +0,0 @@
-
-/******************************************************************************
- *
- * Module Name: amnames - interpreter/scanner name load/execute
- *              $Revision: 73 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acnamesp.h"
-
-#define _COMPONENT          INTERPRETER
-	 MODULE_NAME         ("amnames")
-
-
-/* AML Package Length encodings */
-
-#define ACPI_AML_PACKAGE_TYPE1   0x40
-#define ACPI_AML_PACKAGE_TYPE2   0x4000
-#define ACPI_AML_PACKAGE_TYPE3   0x400000
-#define ACPI_AML_PACKAGE_TYPE4   0x40000000
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_allocate_name_string
- *
- * PARAMETERS:  Prefix_count        - Count of parent levels. Special cases:
- *                                    (-1) = root,  0 = none
- *              Num_name_segs       - count of 4-character name segments
- *
- * RETURN:      A pointer to the allocated string segment.  This segment must
- *              be deleted by the caller.
- *
- * DESCRIPTION: Allocate a buffer for a name string. Ensure allocated name
- *              string is long enough, and set up prefix if any.
- *
- ******************************************************************************/
-
-NATIVE_CHAR *
-acpi_aml_allocate_name_string (
-	u32                     prefix_count,
-	u32                     num_name_segs)
-{
-	NATIVE_CHAR             *temp_ptr;
-	NATIVE_CHAR             *name_string;
-	u32                      size_needed;
-
-
-	/*
-	 * Allow room for all \ and ^ prefixes, all segments, and a Multi_name_prefix.
-	 * Also, one byte for the null terminator.
-	 * This may actually be somewhat longer than needed.
-	 */
-
-	if (prefix_count == (u32) -1) {
-		/* Special case for root */
-
-		size_needed = 1 + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
-	}
-	else {
-		size_needed = prefix_count + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
-	}
-
-	/*
-	 * Allocate a buffer for the name.
-	 * This buffer must be deleted by the caller!
-	 */
-
-	name_string = acpi_cm_allocate (size_needed);
-	if (!name_string) {
-		REPORT_ERROR (("Aml_allocate_name_string: name allocation failure\n"));
-		return (NULL);
-	}
-
-	temp_ptr = name_string;
-
-	/* Set up Root or Parent prefixes if needed */
-
-	if (prefix_count == (u32) -1) {
-		*temp_ptr++ = AML_ROOT_PREFIX;
-	}
-
-	else {
-		while (prefix_count--) {
-			*temp_ptr++ = AML_PARENT_PREFIX;
-		}
-	}
-
-
-	/* Set up Dual or Multi prefixes if needed */
-
-	if (num_name_segs > 2) {
-		/* Set up multi prefixes   */
-
-		*temp_ptr++ = AML_MULTI_NAME_PREFIX_OP;
-		*temp_ptr++ = (char) num_name_segs;
-	}
-
-	else if (2 == num_name_segs) {
-		/* Set up dual prefixes */
-
-		*temp_ptr++ = AML_DUAL_NAME_PREFIX;
-	}
-
-	/*
-	 * Terminate string following prefixes. Acpi_aml_exec_name_segment() will
-	 * append the segment(s)
-	 */
-
-	*temp_ptr = 0;
-
-	return (name_string);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_name_segment
- *
- * PARAMETERS:  Interpreter_mode    - Current running mode (load1/Load2/Exec)
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Execute a name segment (4 bytes)
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_exec_name_segment (
-	u8                      **in_aml_address,
-	NATIVE_CHAR             *name_string)
-{
-	u8                      *aml_address = *in_aml_address;
-	ACPI_STATUS             status = AE_OK;
-	u32                     index;
-	NATIVE_CHAR             char_buf[5];
-
-
-	/*
-	 * If first character is a digit, then we know that we aren't looking at a
-	 * valid name segment
-	 */
-
-	char_buf[0] = *aml_address;
-
-	if ('0' <= char_buf[0] && char_buf[0] <= '9') {
-		return (AE_CTRL_PENDING);
-	}
-
-	for (index = 4;
-		(index > 0) && (acpi_cm_valid_acpi_character (*aml_address));
-		--index)
-	{
-		char_buf[4 - index] = *aml_address++;
-	}
-
-
-	/* Valid name segment  */
-
-	if (0 == index) {
-		/* Found 4 valid characters */
-
-		char_buf[4] = '\0';
-
-		if (name_string) {
-			STRCAT (name_string, char_buf);
-		}
-
-	}
-
-	else if (4 == index) {
-		/*
-		 * First character was not a valid name character,
-		 * so we are looking at something other than a name.
-		 */
-		status = AE_CTRL_PENDING;
-	}
-
-	else {
-		/* Segment started with one or more valid characters, but fewer than 4 */
-
-		status = AE_AML_BAD_NAME;
-	}
-
-	*in_aml_address = aml_address;
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_get_name_string
- *
- * PARAMETERS:  Data_type           - Data type to be associated with this name
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Get a name, including any prefixes.
- *
- ******************************************************************************/
-
-
-ACPI_STATUS
-acpi_aml_get_name_string (
-	OBJECT_TYPE_INTERNAL    data_type,
-	u8                      *in_aml_address,
-	NATIVE_CHAR             **out_name_string,
-	u32                     *out_name_length)
-{
-	ACPI_STATUS             status = AE_OK;
-	u8                      *aml_address = in_aml_address;
-	NATIVE_CHAR             *name_string = NULL;
-	u32                     num_segments;
-	u32                     prefix_count = 0;
-	u8                      prefix = 0;
-	u8                      has_prefix = FALSE;
-
-
-	if (INTERNAL_TYPE_DEF_FIELD == data_type  ||
-		INTERNAL_TYPE_BANK_FIELD == data_type ||
-		INTERNAL_TYPE_INDEX_FIELD == data_type)
-	{
-		/* Disallow prefixes for types associated with field names */
-
-		name_string = acpi_aml_allocate_name_string (0, 1);
-		if (!name_string) {
-			status = AE_NO_MEMORY;
-		}
-		else {
-			status = acpi_aml_exec_name_segment (&aml_address, name_string);
-		}
-	}
-
-	else {
-		/*
-		 * Data_type is not a field name.
-		 * Examine first character of name for root or parent prefix operators
-		 */
-
-		switch (*aml_address)
-		{
-
-		case AML_ROOT_PREFIX:
-
-			prefix = *aml_address++;
-			/*
-			 * Remember that we have a Root_prefix --
-			 * see comment in Acpi_aml_allocate_name_string()
-			 */
-			prefix_count = (u32) -1;
-			has_prefix = TRUE;
-			break;
-
-
-		case AML_PARENT_PREFIX:
-
-			/* Increment past possibly multiple parent prefixes */
-
-			do
-			{
-				prefix = *aml_address++;
-				++prefix_count;
-
-			} while (*aml_address == AML_PARENT_PREFIX);
-			has_prefix = TRUE;
-			break;
-
-
-		default:
-
-			break;
-		}
-
-
-		/* Examine first character of name for name segment prefix operator */
-
-		switch (*aml_address)
-		{
-
-		case AML_DUAL_NAME_PREFIX:
-
-			prefix = *aml_address++;
-			name_string = acpi_aml_allocate_name_string (prefix_count, 2);
-			if (!name_string) {
-				status = AE_NO_MEMORY;
-				break;
-			}
-
-			/* Indicate that we processed a prefix */
-			has_prefix = TRUE;
-
-			status = acpi_aml_exec_name_segment (&aml_address, name_string);
-			if (ACPI_SUCCESS (status)) {
-				status = acpi_aml_exec_name_segment (&aml_address, name_string);
-			}
-			break;
-
-
-		case AML_MULTI_NAME_PREFIX_OP:
-
-			prefix = *aml_address++;
-			/* Fetch count of segments remaining in name path */
-
-			num_segments = *aml_address++;
-
-			name_string = acpi_aml_allocate_name_string (prefix_count, num_segments);
-			if (!name_string) {
-				status = AE_NO_MEMORY;
-				break;
-			}
-
-			/* Indicate that we processed a prefix */
-			has_prefix = TRUE;
-
-			while (num_segments &&
-					(status = acpi_aml_exec_name_segment (&aml_address, name_string)) == AE_OK)
-			{
-				--num_segments;
-			}
-
-			break;
-
-
-		case 0:
-
-			/* Null_name valid as of 8-12-98 ASL/AML Grammar Update */
-
-
-			/* Consume the NULL byte */
-
-			aml_address++;
-			name_string = acpi_aml_allocate_name_string (prefix_count, 0);
-			if (!name_string) {
-				status = AE_NO_MEMORY;
-				break;
-			}
-
-			break;
-
-
-		default:
-
-			/* Name segment string */
-
-			name_string = acpi_aml_allocate_name_string (prefix_count, 1);
-			if (!name_string) {
-				status = AE_NO_MEMORY;
-				break;
-			}
-
-			status = acpi_aml_exec_name_segment (&aml_address, name_string);
-			break;
-
-		}   /* Switch (Peek_op ())   */
-	}
-
-
-	if (AE_CTRL_PENDING == status && has_prefix) {
-		/* Ran out of segments after processing a prefix */
-
-		REPORT_ERROR (
-			("Aml_do_name: Malformed Name at %p\n", name_string));
-		status = AE_AML_BAD_NAME;
-	}
-
-
-	*out_name_string = name_string;
-	*out_name_length = (u32) (aml_address - in_aml_address);
-
-	return (status);
-}
-
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/amprep.c linux/drivers/acpi/interpreter/amprep.c
--- v2.4.5/linux/drivers/acpi/interpreter/amprep.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/interpreter/amprep.c	Wed Dec 31 16:00:00 1969
@@ -1,405 +0,0 @@
-
-/******************************************************************************
- *
- * Module Name: amprep - ACPI AML (p-code) execution - field prep utilities
- *              $Revision: 73 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acnamesp.h"
-#include "acparser.h"
-
-
-#define _COMPONENT          INTERPRETER
-	 MODULE_NAME         ("amprep")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_decode_field_access_type
- *
- * PARAMETERS:  Access          - Encoded field access bits
- *
- * RETURN:      Field granularity (8, 16, or 32)
- *
- * DESCRIPTION: Decode the Access_type bits of a field definition.
- *
- ******************************************************************************/
-
-static u32
-acpi_aml_decode_field_access_type (
-	u32                     access,
-	u16                     length)
-{
-
-	switch (access)
-	{
-	case ACCESS_ANY_ACC:
-		if (length <= 8) {
-			return (8);
-		}
-		else if (length <= 16) {
-			return (16);
-		}
-		else if (length <= 32) {
-			return (32);
-		}
-		else {
-			return (8);
-		}
-		break;
-
-	case ACCESS_BYTE_ACC:
-		return (8);
-		break;
-
-	case ACCESS_WORD_ACC:
-		return (16);
-		break;
-
-	case ACCESS_DWORD_ACC:
-		return (32);
-		break;
-
-	default:
-		/* Invalid field access type */
-
-		return (0);
-	}
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_prep_common_field_objec
- *
- * PARAMETERS:  Obj_desc            - The field object
- *              Field_flags         - Access, Lock_rule, or Update_rule.
- *                                    The format of a Field_flag is described
- *                                    in the ACPI specification
- *              Field_position      - Field position
- *              Field_length        - Field length
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Initialize the areas of the field object that are common
- *              to the various types of fields.
- *
- ******************************************************************************/
-
-static ACPI_STATUS
-acpi_aml_prep_common_field_object (
-	ACPI_OPERAND_OBJECT     *obj_desc,
-	u8                      field_flags,
-	u8                      field_attribute,
-	u32                     field_position,
-	u32                     field_length)
-{
-	u32                     granularity;
-
-
-	/*
-	 * Note: the structure being initialized is the
-	 * ACPI_COMMON_FIELD_INFO;  Therefore, we can just use the Field union to
-	 * access this common area.  No structure fields outside of the common area
-	 * are initialized by this procedure.
-	 */
-
-	/* Decode the Field_flags */
-
-	obj_desc->field.access          = (u8) ((field_flags & ACCESS_TYPE_MASK)
-			 >> ACCESS_TYPE_SHIFT);
-	obj_desc->field.lock_rule       = (u8) ((field_flags & LOCK_RULE_MASK)
-			 >> LOCK_RULE_SHIFT);
-	obj_desc->field.update_rule     = (u8) ((field_flags & UPDATE_RULE_MASK)
-			 >> UPDATE_RULE_SHIFT);
-
-	/* Other misc fields */
-
-	obj_desc->field.length          = (u16) field_length;
-	obj_desc->field.access_attribute = field_attribute;
-
-	/* Decode the access type so we can compute offsets */
-
-	granularity = acpi_aml_decode_field_access_type (obj_desc->field.access, obj_desc->field.length);
-	if (!granularity) {
-		return (AE_AML_OPERAND_VALUE);
-	}
-
-	/* Access granularity based fields */
-
-	obj_desc->field.granularity     = (u8) granularity;
-	obj_desc->field.bit_offset      = (u8) (field_position % granularity);
-	obj_desc->field.offset          = (u32) field_position / granularity;
-
-
-	return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_prep_def_field_value
- *
- * PARAMETERS:  Node            - Owning Node
- *              Region              - Region in which field is being defined
- *              Field_flags         - Access, Lock_rule, or Update_rule.
- *                                    The format of a Field_flag is described
- *                                    in the ACPI specification
- *              Field_position      - Field position
- *              Field_length        - Field length
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Construct an ACPI_OPERAND_OBJECT  of type Def_field and
- *              connect it to the parent Node.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_prep_def_field_value (
-	ACPI_NAMESPACE_NODE     *node,
-	ACPI_HANDLE             region,
-	u8                      field_flags,
-	u8                      field_attribute,
-	u32                     field_position,
-	u32                     field_length)
-{
-	ACPI_OPERAND_OBJECT     *obj_desc;
-	u32                     type;
-	ACPI_STATUS             status;
-
-
-	/* Parameter validation */
-
-	if (!region) {
-		return (AE_AML_NO_OPERAND);
-	}
-
-	type = acpi_ns_get_type (region);
-	if (type != ACPI_TYPE_REGION) {
-		return (AE_AML_OPERAND_TYPE);
-	}
-
-	/* Allocate a new object */
-
-	obj_desc = acpi_cm_create_internal_object (INTERNAL_TYPE_DEF_FIELD);
-	if (!obj_desc) {
-		return (AE_NO_MEMORY);
-	}
-
-
-	/* Obj_desc and Region valid */
-
-	/* Initialize areas of the object that are common to all fields */
-
-	status = acpi_aml_prep_common_field_object (obj_desc, field_flags, field_attribute,
-			  field_position, field_length);
-	if (ACPI_FAILURE (status)) {
-		return (status);
-	}
-
-	/* Initialize areas of the object that are specific to this field type */
-
-	obj_desc->field.container = acpi_ns_get_attached_object (region);
-
-	/* An additional reference for the container */
-
-	acpi_cm_add_reference (obj_desc->field.container);
-
-
-	/* Debug info */
-
-	/*
-	 * Store the constructed descriptor (Obj_desc) into the Named_obj whose
-	 * handle is on TOS, preserving the current type of that Named_obj.
-	 */
-	status = acpi_ns_attach_object ((ACPI_HANDLE) node, obj_desc,
-			  (u8) acpi_ns_get_type ((ACPI_HANDLE) node));
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_prep_bank_field_value
- *
- * PARAMETERS:  Node            - Owning Node
- *              Region              - Region in which field is being defined
- *              Bank_reg            - Bank selection register
- *              Bank_val            - Value to store in selection register
- *              Field_flags         - Access, Lock_rule, or Update_rule
- *              Field_position      - Field position
- *              Field_length        - Field length
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Construct an ACPI_OPERAND_OBJECT  of type Bank_field and
- *              connect it to the parent Node.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_prep_bank_field_value (
-	ACPI_NAMESPACE_NODE     *node,
-	ACPI_HANDLE             region,
-	ACPI_HANDLE             bank_reg,
-	u32                     bank_val,
-	u8                      field_flags,
-	u8                      field_attribute,
-	u32                     field_position,
-	u32                     field_length)
-{
-	ACPI_OPERAND_OBJECT     *obj_desc;
-	u32                     type;
-	ACPI_STATUS             status;
-
-
-	/* Parameter validation */
-
-	if (!region) {
-		return (AE_AML_NO_OPERAND);
-	}
-
-	type = acpi_ns_get_type (region);
-	if (type != ACPI_TYPE_REGION) {
-		return (AE_AML_OPERAND_TYPE);
-	}
-
-	/* Allocate a new object */
-
-	obj_desc = acpi_cm_create_internal_object (INTERNAL_TYPE_BANK_FIELD);
-	if (!obj_desc) {
-		return (AE_NO_MEMORY);
-	}
-
-	/*  Obj_desc and Region valid   */
-
-	/* Initialize areas of the object that are common to all fields */
-
-	status = acpi_aml_prep_common_field_object (obj_desc, field_flags, field_attribute,
-			  field_position, field_length);
-	if (ACPI_FAILURE (status)) {
-		return (status);
-	}
-
-	/* Initialize areas of the object that are specific to this field type */
-
-	obj_desc->bank_field.value      = bank_val;
-	obj_desc->bank_field.container  = acpi_ns_get_attached_object (region);
-	obj_desc->bank_field.bank_select = acpi_ns_get_attached_object (bank_reg);
-
-	/* An additional reference for the container and bank select */
-	/* TBD: [Restructure] is "Bank_select" ever a real internal object?? */
-
-	acpi_cm_add_reference (obj_desc->bank_field.container);
-	acpi_cm_add_reference (obj_desc->bank_field.bank_select);
-
-	/* Debug info */
-
-	/*
-	 * Store the constructed descriptor (Obj_desc) into the Named_obj whose
-	 * handle is on TOS, preserving the current type of that Named_obj.
-	 */
-	status = acpi_ns_attach_object ((ACPI_HANDLE) node, obj_desc,
-			 (u8) acpi_ns_get_type ((ACPI_HANDLE) node));
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_prep_index_field_value
- *
- * PARAMETERS:  Node            - Owning Node
- *              Index_reg           - Index register
- *              Data_reg            - Data register
- *              Field_flags         - Access, Lock_rule, or Update_rule
- *              Field_position      - Field position
- *              Field_length        - Field length
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Construct an ACPI_OPERAND_OBJECT  of type Index_field and
- *              connect it to the parent Node.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_prep_index_field_value (
-	ACPI_NAMESPACE_NODE     *node,
-	ACPI_HANDLE             index_reg,
-	ACPI_HANDLE             data_reg,
-	u8                      field_flags,
-	u8                      field_attribute,
-	u32                     field_position,
-	u32                     field_length)
-{
-	ACPI_OPERAND_OBJECT     *obj_desc;
-	ACPI_STATUS             status;
-
-
-	/* Parameter validation */
-
-	if (!index_reg || !data_reg) {
-		return (AE_AML_NO_OPERAND);
-	}
-
-	/* Allocate a new object descriptor */
-
-	obj_desc = acpi_cm_create_internal_object (INTERNAL_TYPE_INDEX_FIELD);
-	if (!obj_desc) {
-		return (AE_NO_MEMORY);
-	}
-
-	/* Initialize areas of the object that are common to all fields */
-
-	status = acpi_aml_prep_common_field_object (obj_desc, field_flags, field_attribute,
-			  field_position, field_length);
-	if (ACPI_FAILURE (status)) {
-		return (status);
-	}
-
-	/* Initialize areas of the object that are specific to this field type */
-
-	obj_desc->index_field.value     = (u32) (field_position /
-			   obj_desc->field.granularity);
-	obj_desc->index_field.index     = index_reg;
-	obj_desc->index_field.data      = data_reg;
-
-	/* Debug info */
-
-	/*
-	 * Store the constructed descriptor (Obj_desc) into the Named_obj whose
-	 * handle is on TOS, preserving the current type of that Named_obj.
-	 */
-	status = acpi_ns_attach_object ((ACPI_HANDLE) node, obj_desc,
-			 (u8) acpi_ns_get_type ((ACPI_HANDLE) node));
-
-	return (status);
-}
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/amregion.c linux/drivers/acpi/interpreter/amregion.c
--- v2.4.5/linux/drivers/acpi/interpreter/amregion.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/interpreter/amregion.c	Wed Dec 31 16:00:00 1969
@@ -1,420 +0,0 @@
-
-/******************************************************************************
- *
- * Module Name: amregion - ACPI default Op_region (address space) handlers
- *              $Revision: 44 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acnamesp.h"
-#include "achware.h"
-#include "acevents.h"
-
-
-#define _COMPONENT          INTERPRETER
-	 MODULE_NAME         ("amregion")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_system_memory_space_handler
- *
- * PARAMETERS:  Function            - Read or Write operation
- *              Address             - Where in the space to read or write
- *              Bit_width           - Field width in bits (8, 16, or 32)
- *              Value               - Pointer to in or out value
- *              Handler_context     - Pointer to Handler's context
- *              Region_context      - Pointer to context specific to the
- *                                      accessed region
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Handler for the System Memory address space (Op Region)
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_system_memory_space_handler (
-	u32                     function,
-	ACPI_PHYSICAL_ADDRESS   address,
-	u32                     bit_width,
-	u32                     *value,
-	void                    *handler_context,
-	void                    *region_context)
-{
-	ACPI_STATUS             status = AE_OK;
-	void                    *logical_addr_ptr = NULL;
-	MEM_HANDLER_CONTEXT     *mem_info = region_context;
-	u32                     length;
-
-
-	/* Validate and translate the bit width */
-
-	switch (bit_width)
-	{
-	case 8:
-		length = 1;
-		break;
-
-	case 16:
-		length = 2;
-		break;
-
-	case 32:
-		length = 4;
-		break;
-
-	default:
-		return (AE_AML_OPERAND_VALUE);
-		break;
-	}
-
-
-	/*
-	 * Does the request fit into the cached memory mapping?
-	 * Is 1) Address below the current mapping? OR
-	 *    2) Address beyond the current mapping?
-	 */
-
-	if ((address < mem_info->mapped_physical_address) ||
-		(((ACPI_INTEGER) address + length) >
-			((ACPI_INTEGER) mem_info->mapped_physical_address + mem_info->mapped_length)))
-	{
-		/*
-		 * The request cannot be resolved by the current memory mapping;
-		 * Delete the existing mapping and create a new one.
-		 */
-
-		if (mem_info->mapped_length) {
-			/* Valid mapping, delete it */
-
-			acpi_os_unmap_memory (mem_info->mapped_logical_address,
-					   mem_info->mapped_length);
-		}
-
-		mem_info->mapped_length = 0; /* In case of failure below */
-
-		/* Create a new mapping starting at the address given */
-
-		status = acpi_os_map_memory (address, SYSMEM_REGION_WINDOW_SIZE,
-				  (void **) &mem_info->mapped_logical_address);
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-
-		/* TBD: should these pointers go to 64-bit in all cases ? */
-
-		mem_info->mapped_physical_address = address;
-		mem_info->mapped_length = SYSMEM_REGION_WINDOW_SIZE;
-	}
-
-
-	/*
-	 * Generate a logical pointer corresponding to the address we want to
-	 * access
-	 */
-
-	/* TBD: should these pointers go to 64-bit in all cases ? */
-
-	logical_addr_ptr = mem_info->mapped_logical_address +
-			  ((ACPI_INTEGER) address - (ACPI_INTEGER) mem_info->mapped_physical_address);
-
-	/* Perform the memory read or write */
-
-	switch (function)
-	{
-
-	case ADDRESS_SPACE_READ:
-
-		switch (bit_width)
-		{
-		case 8:
-			*value = (u32)* (u8 *) logical_addr_ptr;
-			break;
-
-		case 16:
-			MOVE_UNALIGNED16_TO_32 (value, logical_addr_ptr);
-			break;
-
-		case 32:
-			MOVE_UNALIGNED32_TO_32 (value, logical_addr_ptr);
-			break;
-		}
-
-		break;
-
-
-	case ADDRESS_SPACE_WRITE:
-
-		switch (bit_width)
-		{
-		case 8:
-			*(u8 *) logical_addr_ptr = (u8) *value;
-			break;
-
-		case 16:
-			MOVE_UNALIGNED16_TO_16 (logical_addr_ptr, value);
-			break;
-
-		case 32:
-			MOVE_UNALIGNED32_TO_32 (logical_addr_ptr, value);
-			break;
-		}
-
-		break;
-
-
-	default:
-		status = AE_BAD_PARAMETER;
-		break;
-	}
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_system_io_space_handler
- *
- * PARAMETERS:  Function            - Read or Write operation
- *              Address             - Where in the space to read or write
- *              Bit_width           - Field width in bits (8, 16, or 32)
- *              Value               - Pointer to in or out value
- *              Handler_context     - Pointer to Handler's context
- *              Region_context      - Pointer to context specific to the
- *                                      accessed region
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Handler for the System IO address space (Op Region)
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_system_io_space_handler (
-	u32                     function,
-	ACPI_PHYSICAL_ADDRESS   address,
-	u32                     bit_width,
-	u32                     *value,
-	void                    *handler_context,
-	void                    *region_context)
-{
-	ACPI_STATUS             status = AE_OK;
-
-
-	/* Decode the function parameter */
-
-	switch (function)
-	{
-
-	case ADDRESS_SPACE_READ:
-
-		switch (bit_width)
-		{
-		/* I/O Port width */
-
-		case 8:
-			*value = (u32) acpi_os_in8 ((ACPI_IO_ADDRESS) address);
-			break;
-
-		case 16:
-			*value = (u32) acpi_os_in16 ((ACPI_IO_ADDRESS) address);
-			break;
-
-		case 32:
-			*value = acpi_os_in32 ((ACPI_IO_ADDRESS) address);
-			break;
-
-		default:
-			status = AE_AML_OPERAND_VALUE;
-		}
-
-		break;
-
-
-	case ADDRESS_SPACE_WRITE:
-
-		switch (bit_width)
-		{
-		/* I/O Port width */
-		case 8:
-			acpi_os_out8 ((ACPI_IO_ADDRESS) address, (u8) *value);
-			break;
-
-		case 16:
-			acpi_os_out16 ((ACPI_IO_ADDRESS) address, (u16) *value);
-			break;
-
-		case 32:
-			acpi_os_out32 ((ACPI_IO_ADDRESS) address, *value);
-			break;
-
-		default:
-			status = AE_AML_OPERAND_VALUE;
-		}
-
-		break;
-
-
-	default:
-		status = AE_BAD_PARAMETER;
-		break;
-	}
-
-	return (status);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_pci_config_space_handler
- *
- * PARAMETERS:  Function            - Read or Write operation
- *              Address             - Where in the space to read or write
- *              Bit_width           - Field width in bits (8, 16, or 32)
- *              Value               - Pointer to in or out value
- *              Handler_context     - Pointer to Handler's context
- *              Region_context      - Pointer to context specific to the
- *                                      accessed region
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Handler for the PCI Config address space (Op Region)
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_pci_config_space_handler (
-	u32                     function,
-	ACPI_PHYSICAL_ADDRESS   address,
-	u32                     bit_width,
-	u32                     *value,
-	void                    *handler_context,
-	void                    *region_context)
-{
-	ACPI_STATUS             status = AE_OK;
-	u32                     pci_bus;
-	u32                     dev_func;
-	u8                      pci_reg;
-	PCI_HANDLER_CONTEXT    *PCIcontext;
-
-
-	/*
-	 *  The arguments to Acpi_os(Read|Write)Pci_cfg(Byte|Word|Dword) are:
-	 *
-	 *  Seg_bus - 0xSSSSBBBB    - SSSS is the PCI bus segment
-	 *                            BBBB is the PCI bus number
-	 *
-	 *  Dev_func - 0xDDDDFFFF   - DDDD is the PCI device number
-	 *                            FFFF is the PCI device function number
-	 *
-	 *  Reg_num - Config space register must be < 40h
-	 *
-	 *  Value - input value for write, output for read
-	 *
-	 */
-
-	PCIcontext = (PCI_HANDLER_CONTEXT *) region_context;
-
-	pci_bus = LOWORD(PCIcontext->seg) << 16;
-	pci_bus |= LOWORD(PCIcontext->bus);
-
-	dev_func = PCIcontext->dev_func;
-
-	pci_reg = (u8) address;
-
-	switch (function)
-	{
-
-	case ADDRESS_SPACE_READ:
-
-		*value  = 0;
-
-		switch (bit_width)
-		{
-		/* PCI Register width */
-
-		case 8:
-			status = acpi_os_read_pci_cfg_byte (pci_bus, dev_func, pci_reg,
-					   (u8 *) value);
-			break;
-
-		case 16:
-			status = acpi_os_read_pci_cfg_word (pci_bus, dev_func, pci_reg,
-					   (u16 *) value);
-			break;
-
-		case 32:
-			status = acpi_os_read_pci_cfg_dword (pci_bus, dev_func, pci_reg,
-					   value);
-			break;
-
-		default:
-			status = AE_AML_OPERAND_VALUE;
-
-		} /* Switch bit_width */
-
-		break;
-
-
-	case ADDRESS_SPACE_WRITE:
-
-		switch (bit_width)
-		{
-		/* PCI Register width */
-
-		case 8:
-			status = acpi_os_write_pci_cfg_byte (pci_bus, dev_func, pci_reg,
-					 *(u8 *) value);
-			break;
-
-		case 16:
-			status = acpi_os_write_pci_cfg_word (pci_bus, dev_func, pci_reg,
-					 *(u16 *) value);
-			break;
-
-		case 32:
-			status = acpi_os_write_pci_cfg_dword (pci_bus, dev_func, pci_reg,
-					 *value);
-			break;
-
-		default:
-			status = AE_AML_OPERAND_VALUE;
-
-		} /* Switch bit_width */
-
-		break;
-
-
-	default:
-
-		status = AE_BAD_PARAMETER;
-		break;
-
-	}
-
-	return (status);
-}
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/amresnte.c linux/drivers/acpi/interpreter/amresnte.c
--- v2.4.5/linux/drivers/acpi/interpreter/amresnte.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/interpreter/amresnte.c	Wed Dec 31 16:00:00 1969
@@ -1,509 +0,0 @@
-
-/******************************************************************************
- *
- * Module Name: amresnte - AML Interpreter object resolution
- *              $Revision: 27 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "amlcode.h"
-#include "acparser.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "acnamesp.h"
-#include "actables.h"
-#include "acevents.h"
-
-
-#define _COMPONENT          INTERPRETER
-	 MODULE_NAME         ("amresnte")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_resolve_node_to_value
- *
- * PARAMETERS:  Stack_ptr       - Pointer to a location on a stack that contains
- *                                a pointer to an Node
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Resolve a ACPI_NAMESPACE_NODE (Node,
- *              A.K.A. a "direct name pointer")
- *
- * Note: for some of the data types, the pointer attached to the Node
- * can be either a pointer to an actual internal object or a pointer into the
- * AML stream itself.  These types are currently:
- *
- *      ACPI_TYPE_INTEGER
- *      ACPI_TYPE_STRING
- *      ACPI_TYPE_BUFFER
- *      ACPI_TYPE_MUTEX
- *      ACPI_TYPE_PACKAGE
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_resolve_node_to_value (
-	ACPI_NAMESPACE_NODE     **stack_ptr,
-	ACPI_WALK_STATE         *walk_state)
-
-{
-	ACPI_STATUS             status = AE_OK;
-	ACPI_OPERAND_OBJECT     *val_desc = NULL;
-	ACPI_OPERAND_OBJECT     *obj_desc = NULL;
-	ACPI_NAMESPACE_NODE     *node;
-	u8                      *aml_pointer = NULL;
-	OBJECT_TYPE_INTERNAL    entry_type;
-	u8                      locked;
-	u8                      attached_aml_pointer = FALSE;
-	u8                      aml_opcode = 0;
-	ACPI_INTEGER            temp_val;
-	OBJECT_TYPE_INTERNAL    object_type;
-
-
-	node = *stack_ptr;
-
-
-	/*
-	 * The stack pointer is a "Direct name ptr", and points to a
-	 * a ACPI_NAMESPACE_NODE (Node).  Get the pointer that is attached to
-	 * the Node.
-	 */
-
-	val_desc    = acpi_ns_get_attached_object ((ACPI_HANDLE) node);
-	entry_type  = acpi_ns_get_type ((ACPI_HANDLE) node);
-
-	/*
-	 * The Val_desc attached to the Node can be either:
-	 * 1) An internal ACPI object
-	 * 2) A pointer into the AML stream (into one of the ACPI system tables)
-	 */
-
-	if (acpi_tb_system_table_pointer (val_desc)) {
-		attached_aml_pointer = TRUE;
-		aml_opcode = *((u8 *) val_desc);
-		aml_pointer = ((u8 *) val_desc) + 1;
-
-	}
-
-
-	/*
-	 * Several Entry_types do not require further processing, so
-	 *  we will return immediately
-	 */
-	/* Devices rarely have an attached object, return the Node
-	 *  and Method locals and arguments have a pseudo-Node
-	 */
-	if (entry_type == ACPI_TYPE_DEVICE ||
-		(node->flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL)))
-	{
-		return (AE_OK);
-	}
-
-	if (!val_desc) {
-		return (AE_AML_NO_OPERAND);
-	}
-
-	/*
-	 * Action is based on the type of the Node, which indicates the type
-	 * of the attached object or pointer
-	 */
-	switch (entry_type)
-	{
-
-	case ACPI_TYPE_PACKAGE:
-
-		if (attached_aml_pointer) {
-			/*
-			 * This means that the package initialization is not parsed
-			 * -- should not happen
-			 */
-			return (AE_NOT_IMPLEMENTED);
-		}
-
-		/* Val_desc is an internal object in all cases by the time we get here */
-
-		if (ACPI_TYPE_PACKAGE != val_desc->common.type) {
-			return (AE_AML_OPERAND_TYPE);
-		}
-
-		/* Return an additional reference to the object */
-
-		obj_desc = val_desc;
-		acpi_cm_add_reference (obj_desc);
-		break;
-
-
-	case ACPI_TYPE_BUFFER:
-
-		if (attached_aml_pointer) {
-			/*
-			 * This means that the buffer initialization is not parsed
-			 * -- should not happen
-			 */
-			return (AE_NOT_IMPLEMENTED);
-		}
-
-		/* Val_desc is an internal object in all cases by the time we get here */
-
-		if (ACPI_TYPE_BUFFER != val_desc->common.type) {
-			return (AE_AML_OPERAND_TYPE);
-		}
-
-		/* Return an additional reference to the object */
-
-		obj_desc = val_desc;
-		acpi_cm_add_reference (obj_desc);
-		break;
-
-
-	case ACPI_TYPE_STRING:
-
-		if (attached_aml_pointer) {
-			/* Allocate a new string object */
-
-			obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_STRING);
-			if (!obj_desc) {
-				return (AE_NO_MEMORY);
-			}
-
-			/* Init the internal object */
-
-			obj_desc->string.pointer = (NATIVE_CHAR *) aml_pointer;
-			obj_desc->string.length = STRLEN (obj_desc->string.pointer);
-		}
-
-		else {
-			if (ACPI_TYPE_STRING != val_desc->common.type) {
-				return (AE_AML_OPERAND_TYPE);
-			}
-
-			/* Return an additional reference to the object */
-
-			obj_desc = val_desc;
-			acpi_cm_add_reference (obj_desc);
-		}
-
-		break;
-
-
-	case ACPI_TYPE_INTEGER:
-
-		/*
-		 * The Node has an attached internal object, make sure that it's a
-		 * number
-		 */
-
-		if (ACPI_TYPE_INTEGER != val_desc->common.type) {
-			return (AE_AML_OPERAND_TYPE);
-		}
-
-		/* Return an additional reference to the object */
-
-		obj_desc = val_desc;
-		acpi_cm_add_reference (obj_desc);
-		break;
-
-
-	case INTERNAL_TYPE_DEF_FIELD:
-
-		/*
-		 * TBD: [Investigate] Is this the correct solution?
-		 *
-		 * This section was extended to convert to generic buffer if
-		 *  the return length is greater than 32 bits, but still allows
-		 *  for returning a type Number for smaller values because the
-		 *  caller can then apply arithmetic operators on those fields.
-		 *
-		 * XXX - Implementation limitation: Fields are implemented as type
-		 * XXX - Number, but they really are supposed to be type Buffer.
-		 * XXX - The two are interchangeable only for lengths <= 32 bits.
-		 */
-		if(val_desc->field.length > 32) {
-			object_type = ACPI_TYPE_BUFFER;
-		}
-		else {
-			object_type = ACPI_TYPE_INTEGER;
-		}
-
-		/*
-		 * Create the destination buffer object and the buffer space.
-		 */
-		obj_desc = acpi_cm_create_internal_object (object_type);
-		if (!obj_desc) {
-			return (AE_NO_MEMORY);
-		}
-
-		/*
-		 * Fill in the object specific details
-		 */
-		if (ACPI_TYPE_BUFFER == object_type) {
-			obj_desc->buffer.pointer = acpi_cm_callocate (val_desc->field.length);
-			if (!obj_desc->buffer.pointer) {
-				acpi_cm_remove_reference(obj_desc);
-				return (AE_NO_MEMORY);
-			}
-
-			obj_desc->buffer.length = val_desc->field.length;
-
-			status = acpi_aml_access_named_field (ACPI_READ, (ACPI_HANDLE) node,
-					  obj_desc->buffer.pointer, obj_desc->buffer.length);
-
-			if (ACPI_FAILURE (status)) {
-				return (status);
-			}
-		}
-		else {
-			status = acpi_aml_access_named_field (ACPI_READ, (ACPI_HANDLE) node,
-					  &temp_val, sizeof (temp_val));
-
-			if (ACPI_FAILURE (status)) {
-				return (status);
-			}
-
-			obj_desc->integer.value = temp_val;
-		}
-
-
-		break;
-
-
-	case INTERNAL_TYPE_BANK_FIELD:
-
-		if (attached_aml_pointer) {
-			return (AE_AML_OPERAND_TYPE);
-		}
-
-		if (INTERNAL_TYPE_BANK_FIELD != val_desc->common.type) {
-			return (AE_AML_OPERAND_TYPE);
-		}
-
-
-		/* Get the global lock if needed */
-
-		obj_desc = (ACPI_OPERAND_OBJECT *) *stack_ptr;
-		locked = acpi_aml_acquire_global_lock (obj_desc->field_unit.lock_rule);
-
-		/* Set Index value to select proper Data register */
-		/* perform the update */
-
-		status = acpi_aml_access_named_field (ACPI_WRITE,
-				 val_desc->bank_field.bank_select, &val_desc->bank_field.value,
-				 sizeof (val_desc->bank_field.value));
-
-		acpi_aml_release_global_lock (locked);
-
-
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-
-		/* Read Data value */
-
-		status = acpi_aml_access_named_field (ACPI_READ,
-				 (ACPI_HANDLE) val_desc->bank_field.container,
-				 &temp_val, sizeof (temp_val));
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-
-		/* Create an object for the result */
-
-		obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
-		if (!obj_desc) {
-			return (AE_NO_MEMORY);
-		}
-
-		obj_desc->integer.value = temp_val;
-		break;
-
-
-	case INTERNAL_TYPE_INDEX_FIELD:
-
-		if (attached_aml_pointer) {
-			return (AE_AML_OPERAND_TYPE);
-		}
-
-		if (INTERNAL_TYPE_INDEX_FIELD != val_desc->common.type) {
-			return (AE_AML_OPERAND_TYPE);
-		}
-
-
-		/* Set Index value to select proper Data register */
-		/* Get the global lock if needed */
-
-		obj_desc = (ACPI_OPERAND_OBJECT *) *stack_ptr;
-		locked = acpi_aml_acquire_global_lock (obj_desc->field_unit.lock_rule);
-
-		/* Perform the update */
-
-		status = acpi_aml_access_named_field (ACPI_WRITE,
-				  val_desc->index_field.index, &val_desc->index_field.value,
-				  sizeof (val_desc->index_field.value));
-
-		acpi_aml_release_global_lock (locked);
-
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-
-		/* Read Data value */
-
-		status = acpi_aml_access_named_field (ACPI_READ, val_desc->index_field.data,
-				  &temp_val, sizeof (temp_val));
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-
-		/* Create an object for the result */
-
-		obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
-		if (!obj_desc) {
-			return (AE_NO_MEMORY);
-		}
-
-		obj_desc->integer.value = temp_val;
-		break;
-
-
-	case ACPI_TYPE_FIELD_UNIT:
-
-		if (attached_aml_pointer) {
-			return (AE_AML_OPERAND_TYPE);
-		}
-
-		if (val_desc->common.type != (u8) entry_type) {
-			return (AE_AML_OPERAND_TYPE);
-			break;
-		}
-
-		/* Create object for result */
-
-		obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_ANY);
-		if (!obj_desc) {
-			return (AE_NO_MEMORY);
-		}
-
-		status = acpi_aml_get_field_unit_value (val_desc, obj_desc);
-		if (ACPI_FAILURE (status)) {
-			acpi_cm_remove_reference (obj_desc);
-			return (status);
-		}
-
-		break;
-
-
-	/*
-	 * For these objects, just return the object attached to the Node
-	 */
-
-	case ACPI_TYPE_MUTEX:
-	case ACPI_TYPE_METHOD:
-	case ACPI_TYPE_POWER:
-	case ACPI_TYPE_PROCESSOR:
-	case ACPI_TYPE_THERMAL:
-	case ACPI_TYPE_EVENT:
-	case ACPI_TYPE_REGION:
-
-
-		/* Return an additional reference to the object */
-
-		obj_desc = val_desc;
-		acpi_cm_add_reference (obj_desc);
-		break;
-
-
-	/* TYPE_Any is untyped, and thus there is no object associated with it */
-
-	case ACPI_TYPE_ANY:
-
-		return (AE_AML_OPERAND_TYPE);  /* Cannot be AE_TYPE */
-		break;
-
-
-	/*
-	 * The only named references allowed are named constants
-	 *
-	 * e.g.     Name (\OSFL, Ones)
-	 */
-	case INTERNAL_TYPE_REFERENCE:
-
-		switch (val_desc->reference.op_code)
-		{
-
-		case AML_ZERO_OP:
-
-			temp_val = 0;
-			break;
-
-
-		case AML_ONE_OP:
-
-			temp_val = 1;
-			break;
-
-
-		case AML_ONES_OP:
-
-			temp_val = ACPI_INTEGER_MAX;
-			break;
-
-
-		default:
-
-			return (AE_AML_BAD_OPCODE);
-		}
-
-		/* Create object for result */
-
-		obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
-		if (!obj_desc) {
-			return (AE_NO_MEMORY);
-		}
-
-		obj_desc->integer.value = temp_val;
-
-		/* Truncate value if we are executing from a 32-bit ACPI table */
-
-		acpi_aml_truncate_for32bit_table (obj_desc, walk_state);
-		break;
-
-
-	/* Default case is for unknown types */
-
-	default:
-
-		return (AE_AML_OPERAND_TYPE);
-
-	} /* switch (Entry_type) */
-
-
-	/* Put the object descriptor on the stack */
-
-	*stack_ptr = (void *) obj_desc;
-
-	return (status);
-}
-
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/amresolv.c linux/drivers/acpi/interpreter/amresolv.c
--- v2.4.5/linux/drivers/acpi/interpreter/amresolv.c	Mon Jan 29 10:15:59 2001
+++ linux/drivers/acpi/interpreter/amresolv.c	Wed Dec 31 16:00:00 1969
@@ -1,465 +0,0 @@
-
-/******************************************************************************
- *
- * Module Name: amresolv - AML Interpreter object resolution
- *              $Revision: 81 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "amlcode.h"
-#include "acparser.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "acnamesp.h"
-#include "actables.h"
-#include "acevents.h"
-
-
-#define _COMPONENT          INTERPRETER
-	 MODULE_NAME         ("amresolv")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_get_field_unit_value
- *
- * PARAMETERS:  *Field_desc         - Pointer to a Field_unit
- *              *Result_desc        - Pointer to an empty descriptor
- *                                    which will become a Number
- *                                    containing the field's value.
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Retrieve the value from a Field_unit
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_get_field_unit_value (
-	ACPI_OPERAND_OBJECT     *field_desc,
-	ACPI_OPERAND_OBJECT     *result_desc)
-{
-	ACPI_STATUS             status = AE_OK;
-	u32                     mask;
-	u8                      *location = NULL;
-	u8                      locked = FALSE;
-
-
-	if (!field_desc) {
-		status = AE_AML_NO_OPERAND;
-	}
-
-	if (!(field_desc->common.flags & AOPOBJ_DATA_VALID)) {
-		status = acpi_ds_get_field_unit_arguments (field_desc);
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-	}
-
-	if (!field_desc->field_unit.container) {
-		status = AE_AML_INTERNAL;
-	}
-
-	else if (ACPI_TYPE_BUFFER != field_desc->field_unit.container->common.type) {
-		status = AE_AML_OPERAND_TYPE;
-	}
-
-	else if (!result_desc) {
-		status = AE_AML_INTERNAL;
-	}
-
-	if (ACPI_FAILURE (status)) {
-		return (status);
-	}
-
-
-		/* Get the global lock if needed */
-
-	locked = acpi_aml_acquire_global_lock (field_desc->field_unit.lock_rule);
-
-	/* Field location is (base of buffer) + (byte offset) */
-
-	location = field_desc->field_unit.container->buffer.pointer
-			 + field_desc->field_unit.offset;
-
-	/*
-	 * Construct Mask with as many 1 bits as the field width
-	 *
-	 * NOTE: Only the bottom 5 bits are valid for a shift operation, so
-	 *  special care must be taken for any shift greater than 31 bits.
-	 *
-	 * TBD: [Unhandled] Fields greater than 32-bits will not work.
-	 */
-
-	if (field_desc->field_unit.length < 32) {
-		mask = ((u32) 1 << field_desc->field_unit.length) - (u32) 1;
-	}
-	else {
-		mask = ACPI_UINT32_MAX;
-	}
-
-	result_desc->integer.type = (u8) ACPI_TYPE_INTEGER;
-
-	/* Get the 32 bit value at the location */
-
-	MOVE_UNALIGNED32_TO_32 (&result_desc->integer.value, location);
-
-	/*
-	 * Shift the 32-bit word containing the field, and mask off the
-	 * resulting value
-	 */
-
-	result_desc->integer.value =
-		(result_desc->integer.value >> field_desc->field_unit.bit_offset) & mask;
-
-	/* Release global lock if we acquired it earlier */
-
-	acpi_aml_release_global_lock (locked);
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_resolve_to_value
- *
- * PARAMETERS:  **Stack_ptr         - Points to entry on Obj_stack, which can
- *                                    be either an (ACPI_OPERAND_OBJECT  *)
- *                                    or an ACPI_HANDLE.
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Convert Reference objects to values
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_resolve_to_value (
-	ACPI_OPERAND_OBJECT     **stack_ptr,
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_STATUS             status = AE_OK;
-
-
-	if (!stack_ptr || !*stack_ptr) {
-		return (AE_AML_NO_OPERAND);
-	}
-
-
-	/*
-	 * The entity pointed to by the Stack_ptr can be either
-	 * 1) A valid ACPI_OPERAND_OBJECT, or
-	 * 2) A ACPI_NAMESPACE_NODE (Named_obj)
-	 */
-
-	if (VALID_DESCRIPTOR_TYPE (*stack_ptr, ACPI_DESC_TYPE_INTERNAL)) {
-
-		status = acpi_aml_resolve_object_to_value (stack_ptr, walk_state);
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-	}
-
-	/*
-	 * Object on the stack may have changed if Acpi_aml_resolve_object_to_value()
-	 * was called (i.e., we can't use an _else_ here.)
-	 */
-
-	if (VALID_DESCRIPTOR_TYPE (*stack_ptr, ACPI_DESC_TYPE_NAMED)) {
-		status = acpi_aml_resolve_node_to_value ((ACPI_NAMESPACE_NODE **) stack_ptr, walk_state);
-	}
-
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_resolve_object_to_value
- *
- * PARAMETERS:  Stack_ptr       - Pointer to a stack location that contains a
- *                                ptr to an internal object.
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Retrieve the value from an internal object.  The Reference type
- *              uses the associated AML opcode to determine the value.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_resolve_object_to_value (
-	ACPI_OPERAND_OBJECT     **stack_ptr,
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_OPERAND_OBJECT     *stack_desc;
-	ACPI_STATUS             status = AE_OK;
-	ACPI_HANDLE             temp_handle = NULL;
-	ACPI_OPERAND_OBJECT     *obj_desc = NULL;
-	u32                     index = 0;
-	u16                     opcode;
-
-
-	stack_desc = *stack_ptr;
-
-	/* This is an ACPI_OPERAND_OBJECT  */
-
-	switch (stack_desc->common.type)
-	{
-
-	case INTERNAL_TYPE_REFERENCE:
-
-		opcode = stack_desc->reference.op_code;
-
-		switch (opcode)
-		{
-
-		case AML_NAME_OP:
-
-			/*
-			 * Convert indirect name ptr to a direct name ptr.
-			 * Then, Acpi_aml_resolve_node_to_value can be used to get the value
-			 */
-
-			temp_handle = stack_desc->reference.object;
-
-			/* Delete the Reference Object */
-
-			acpi_cm_remove_reference (stack_desc);
-
-			/* Put direct name pointer onto stack and exit */
-
-			(*stack_ptr) = temp_handle;
-			status = AE_OK;
-			break;
-
-
-		case AML_LOCAL_OP:
-
-			index = stack_desc->reference.offset;
-
-			/*
-			 * Get the local from the method's state info
-			 * Note: this increments the local's object reference count
-			 */
-
-			status = acpi_ds_method_data_get_value (MTH_TYPE_LOCAL, index,
-					 walk_state, &obj_desc);
-			if (ACPI_FAILURE (status)) {
-				return (status);
-			}
-
-			/*
-			 * Now we can delete the original Reference Object and
-			 * replace it with the resolve value
-			 */
-
-			acpi_cm_remove_reference (stack_desc);
-			*stack_ptr = obj_desc;
-
-			if (ACPI_TYPE_INTEGER == obj_desc->common.type) {
-				/* Value is a Number */
-
-			}
-
-			break;
-
-
-		case AML_ARG_OP:
-
-			index = stack_desc->reference.offset;
-
-
-			/*
-			 * Get the argument from the method's state info
-			 * Note: this increments the object reference count
-			 */
-
-			status = acpi_ds_method_data_get_value (MTH_TYPE_ARG, index,
-					 walk_state, &obj_desc);
-			if (ACPI_FAILURE (status)) {
-				return (status);
-			}
-
-			/*
-			 * Now we can delete the original Reference Object and
-			 * replace it with the resolve value
-			 */
-
-			acpi_cm_remove_reference (stack_desc);
-			*stack_ptr = obj_desc;
-
-			if (ACPI_TYPE_INTEGER == obj_desc->common.type) {
-				/* Value is a Number */
-
-			}
-
-			break;
-
-
-		/*
-		 * TBD: [Restructure] These next three opcodes change the type of
-		 * the object, which is actually a no-no.
-		 */
-
-		case AML_ZERO_OP:
-
-			stack_desc->common.type = (u8) ACPI_TYPE_INTEGER;
-			stack_desc->integer.value = 0;
-			break;
-
-
-		case AML_ONE_OP:
-
-			stack_desc->common.type = (u8) ACPI_TYPE_INTEGER;
-			stack_desc->integer.value = 1;
-			break;
-
-
-		case AML_ONES_OP:
-
-			stack_desc->common.type = (u8) ACPI_TYPE_INTEGER;
-			stack_desc->integer.value = ACPI_INTEGER_MAX;
-
-			/* Truncate value if we are executing from a 32-bit ACPI table */
-
-			acpi_aml_truncate_for32bit_table (stack_desc, walk_state);
-			break;
-
-
-		case AML_INDEX_OP:
-
-			switch (stack_desc->reference.target_type)
-			{
-			case ACPI_TYPE_BUFFER_FIELD:
-
-				/* Just return - leave the Reference on the stack */
-				break;
-
-
-			case ACPI_TYPE_PACKAGE:
-				obj_desc = *stack_desc->reference.where;
-				if (obj_desc) {
-					/*
-					 * Valid obj descriptor, copy pointer to return value
-					 * (i.e., dereference the package index)
-					 * Delete the ref object, increment the returned object
-					 */
-					acpi_cm_remove_reference (stack_desc);
-					acpi_cm_add_reference (obj_desc);
-					*stack_ptr = obj_desc;
-				}
-
-				else {
-					/*
-					 * A NULL object descriptor means an unitialized element of
-					 * the package, can't deref it
-					 */
-
-					status = AE_AML_UNINITIALIZED_ELEMENT;
-				}
-				break;
-
-			default:
-				/* Invalid reference OBJ*/
-
-				status = AE_AML_INTERNAL;
-				break;
-			}
-
-			break;
-
-
-		case AML_DEBUG_OP:
-
-			/* Just leave the object as-is */
-			break;
-
-
-		default:
-
-			status = AE_AML_INTERNAL;
-
-		}   /* switch (Opcode) */
-
-
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-
-		break; /* case INTERNAL_TYPE_REFERENCE */
-
-
-	case ACPI_TYPE_FIELD_UNIT:
-
-		obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_ANY);
-		if (!obj_desc) {
-			/* Descriptor allocation failure  */
-
-			return (AE_NO_MEMORY);
-		}
-
-		status = acpi_aml_get_field_unit_value (stack_desc, obj_desc);
-		if (ACPI_FAILURE (status)) {
-			acpi_cm_remove_reference (obj_desc);
-			obj_desc = NULL;
-		}
-
-		*stack_ptr = (void *) obj_desc;
-		break;
-
-
-	case INTERNAL_TYPE_BANK_FIELD:
-
-		obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_ANY);
-		if (!obj_desc) {
-			/* Descriptor allocation failure */
-
-			return (AE_NO_MEMORY);
-		}
-
-		status = acpi_aml_get_field_unit_value (stack_desc, obj_desc);
-		if (ACPI_FAILURE (status)) {
-			acpi_cm_remove_reference (obj_desc);
-			obj_desc = NULL;
-		}
-
-		*stack_ptr = (void *) obj_desc;
-		break;
-
-
-	/* TBD: [Future] - may need to handle Index_field, and Def_field someday */
-
-	default:
-
-		break;
-
-	}   /* switch (Stack_desc->Common.Type) */
-
-
-	return (status);
-}
-
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/amresop.c linux/drivers/acpi/interpreter/amresop.c
--- v2.4.5/linux/drivers/acpi/interpreter/amresop.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/interpreter/amresop.c	Wed Dec 31 16:00:00 1969
@@ -1,488 +0,0 @@
-
-/******************************************************************************
- *
- * Module Name: amresop - AML Interpreter operand/object resolution
- *              $Revision: 22 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "amlcode.h"
-#include "acparser.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "acnamesp.h"
-#include "actables.h"
-#include "acevents.h"
-
-
-#define _COMPONENT          INTERPRETER
-	 MODULE_NAME         ("amresop")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_check_object_type
- *
- * PARAMETERS:  Type_needed         Object type needed
- *              This_type           Actual object type
- *              Object              Object pointer
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Check required type against actual type
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_check_object_type (
-	ACPI_OBJECT_TYPE        type_needed,
-	ACPI_OBJECT_TYPE        this_type,
-	void                    *object)
-{
-
-
-	if (type_needed == ACPI_TYPE_ANY) {
-		/* All types OK, so we don't perform any typechecks */
-
-		return (AE_OK);
-	}
-
-
-	if (type_needed != this_type) {
-		return (AE_AML_OPERAND_TYPE);
-	}
-
-
-	return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_resolve_operands
- *
- * PARAMETERS:  Opcode              Opcode being interpreted
- *              Stack_ptr           Top of operand stack
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Convert stack entries to required types
- *
- *      Each nibble in Arg_types represents one required operand
- *      and indicates the required Type:
- *
- *      The corresponding stack entry will be converted to the
- *      required type if possible, else return an exception
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_resolve_operands (
-	u16                     opcode,
-	ACPI_OPERAND_OBJECT     **stack_ptr,
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_OPERAND_OBJECT     *obj_desc;
-	ACPI_STATUS             status = AE_OK;
-	u8                      object_type;
-	ACPI_HANDLE             temp_handle;
-	u32                     arg_types;
-	ACPI_OPCODE_INFO        *op_info;
-	u32                     this_arg_type;
-	ACPI_OBJECT_TYPE        type_needed;
-
-
-	op_info = acpi_ps_get_opcode_info (opcode);
-	if (ACPI_GET_OP_TYPE (op_info) != ACPI_OP_TYPE_OPCODE) {
-		return (AE_AML_BAD_OPCODE);
-	}
-
-
-	arg_types = op_info->runtime_args;
-	if (arg_types == ARGI_INVALID_OPCODE) {
-		return (AE_AML_INTERNAL);
-	}
-
-
-   /*
-	 * Normal exit is with *Types == '\0' at end of string.
-	 * Function will return an exception from within the loop upon
-	 * finding an entry which is not, and cannot be converted
-	 * to, the required type; if stack underflows; or upon
-	 * finding a NULL stack entry (which "should never happen").
-	 */
-
-	while (GET_CURRENT_ARG_TYPE (arg_types)) {
-		if (!stack_ptr || !*stack_ptr) {
-			return (AE_AML_INTERNAL);
-		}
-
-		/* Extract useful items */
-
-		obj_desc = *stack_ptr;
-
-		/* Decode the descriptor type */
-
-		if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
-			/* Node */
-
-			object_type = ((ACPI_NAMESPACE_NODE *) obj_desc)->type;
-		}
-
-		else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) {
-			/* ACPI internal object */
-
-			object_type = obj_desc->common.type;
-
-			/* Check for bad ACPI_OBJECT_TYPE */
-
-			if (!acpi_aml_validate_object_type (object_type)) {
-				return (AE_AML_OPERAND_TYPE);
-			}
-
-			if (object_type == (u8) INTERNAL_TYPE_REFERENCE) {
-				/*
-				 * Decode the Reference
-				 */
-
-				op_info = acpi_ps_get_opcode_info (opcode);
-				if (ACPI_GET_OP_TYPE (op_info) != ACPI_OP_TYPE_OPCODE) {
-					return (AE_AML_BAD_OPCODE);
-				}
-
-
-				switch (obj_desc->reference.op_code)
-				{
-				case AML_ZERO_OP:
-				case AML_ONE_OP:
-				case AML_ONES_OP:
-				case AML_DEBUG_OP:
-				case AML_NAME_OP:
-				case AML_INDEX_OP:
-				case AML_ARG_OP:
-				case AML_LOCAL_OP:
-
-					break;
-
-				default:
-					return (AE_AML_OPERAND_TYPE);
-					break;
-				}
-			}
-		}
-
-		else {
-			/* Invalid descriptor */
-
-			return (AE_AML_OPERAND_TYPE);
-		}
-
-
-		/*
-		 * Get one argument type, point to the next
-		 */
-
-		this_arg_type = GET_CURRENT_ARG_TYPE (arg_types);
-		INCREMENT_ARG_LIST (arg_types);
-
-
-		/*
-		 * Handle cases where the object does not need to be
-		 * resolved to a value
-		 */
-
-		switch (this_arg_type)
-		{
-
-		case ARGI_REFERENCE:            /* References */
-		case ARGI_INTEGER_REF:
-		case ARGI_OBJECT_REF:
-		case ARGI_DEVICE_REF:
-		case ARGI_TARGETREF:            /* TBD: must implement implicit conversion rules before store */
-		case ARGI_FIXED_TARGET:         /* No implicit conversion before store to target */
-		case ARGI_SIMPLE_TARGET:        /* Name, Local, or Arg - no implicit conversion */
-
-			/* Need an operand of type INTERNAL_TYPE_REFERENCE */
-
-			if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED))            /* direct name ptr OK as-is */ {
-				goto next_operand;
-			}
-
-			status = acpi_aml_check_object_type (INTERNAL_TYPE_REFERENCE,
-					  object_type, obj_desc);
-			if (ACPI_FAILURE (status)) {
-				return (status);
-			}
-
-
-			if (AML_NAME_OP == obj_desc->reference.op_code) {
-				/*
-				 * Convert an indirect name ptr to direct name ptr and put
-				 * it on the stack
-				 */
-
-				temp_handle = obj_desc->reference.object;
-				acpi_cm_remove_reference (obj_desc);
-				(*stack_ptr) = temp_handle;
-			}
-
-			goto next_operand;
-			break;
-
-
-		case ARGI_ANYTYPE:
-
-			/*
-			 * We don't want to resolve Index_op reference objects during
-			 * a store because this would be an implicit De_ref_of operation.
-			 * Instead, we just want to store the reference object.
-			 * -- All others must be resolved below.
-			 */
-
-			if ((opcode == AML_STORE_OP) &&
-				((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) &&
-				((*stack_ptr)->reference.op_code == AML_INDEX_OP))
-			{
-				goto next_operand;
-			}
-			break;
-		}
-
-
-		/*
-		 * Resolve this object to a value
-		 */
-
-		status = acpi_aml_resolve_to_value (stack_ptr, walk_state);
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-
-
-		/*
-		 * Check the resulting object (value) type
-		 */
-		switch (this_arg_type)
-		{
-		/*
-		 * For the simple cases, only one type of resolved object
-		 * is allowed
-		 */
-		case ARGI_MUTEX:
-
-			/* Need an operand of type ACPI_TYPE_MUTEX */
-
-			type_needed = ACPI_TYPE_MUTEX;
-			break;
-
-		case ARGI_EVENT:
-
-			/* Need an operand of type ACPI_TYPE_EVENT */
-
-			type_needed = ACPI_TYPE_EVENT;
-			break;
-
-		case ARGI_REGION:
-
-			/* Need an operand of type ACPI_TYPE_REGION */
-
-			type_needed = ACPI_TYPE_REGION;
-			break;
-
-		case ARGI_IF:   /* If */
-
-			/* Need an operand of type INTERNAL_TYPE_IF */
-
-			type_needed = INTERNAL_TYPE_IF;
-			break;
-
-		case ARGI_PACKAGE:   /* Package */
-
-			/* Need an operand of type ACPI_TYPE_PACKAGE */
-
-			type_needed = ACPI_TYPE_PACKAGE;
-			break;
-
-		case ARGI_ANYTYPE:
-
-			/* Any operand type will do */
-
-			type_needed = ACPI_TYPE_ANY;
-			break;
-
-
-		/*
-		 * The more complex cases allow multiple resolved object types
-		 */
-
-		case ARGI_INTEGER:   /* Number */
-
-			/*
-			 * Need an operand of type ACPI_TYPE_INTEGER,
-			 * But we can implicitly convert from a STRING or BUFFER
-			 */
-			status = acpi_aml_convert_to_integer (stack_ptr, walk_state);
-			if (ACPI_FAILURE (status)) {
-				if (status == AE_TYPE) {
-					return (AE_AML_OPERAND_TYPE);
-				}
-
-				return (status);
-			}
-
-			goto next_operand;
-			break;
-
-
-		case ARGI_BUFFER:
-
-			/*
-			 * Need an operand of type ACPI_TYPE_BUFFER,
-			 * But we can implicitly convert from a STRING or INTEGER
-			 */
-			status = acpi_aml_convert_to_buffer (stack_ptr, walk_state);
-			if (ACPI_FAILURE (status)) {
-				if (status == AE_TYPE) {
-					return (AE_AML_OPERAND_TYPE);
-				}
-
-				return (status);
-			}
-
-			goto next_operand;
-			break;
-
-
-		case ARGI_STRING:
-
-			/*
-			 * Need an operand of type ACPI_TYPE_STRING,
-			 * But we can implicitly convert from a BUFFER or INTEGER
-			 */
-			status = acpi_aml_convert_to_string (stack_ptr, walk_state);
-			if (ACPI_FAILURE (status)) {
-				if (status == AE_TYPE) {
-					return (AE_AML_OPERAND_TYPE);
-				}
-
-				return (status);
-			}
-
-			goto next_operand;
-			break;
-
-
-		case ARGI_COMPUTEDATA:
-
-			/* Need an operand of type INTEGER, STRING or BUFFER */
-
-			if ((ACPI_TYPE_INTEGER != (*stack_ptr)->common.type) &&
-				(ACPI_TYPE_STRING != (*stack_ptr)->common.type) &&
-				(ACPI_TYPE_BUFFER != (*stack_ptr)->common.type))
-			{
-				return (AE_AML_OPERAND_TYPE);
-			}
-			goto next_operand;
-			break;
-
-
-		case ARGI_DATAOBJECT:
-			/*
-			 * ARGI_DATAOBJECT is only used by the Size_of operator.
-			 *
-			 * The ACPI specification allows Size_of to return the size of
-			 *  a Buffer, String or Package.  However, the MS ACPI.SYS AML
-			 *  Interpreter also allows an Node reference to return without
-			 *  error with a size of 4.
-			 */
-
-			/* Need a buffer, string, package or Node reference */
-
-			if (((*stack_ptr)->common.type != ACPI_TYPE_BUFFER) &&
-				((*stack_ptr)->common.type != ACPI_TYPE_STRING) &&
-				((*stack_ptr)->common.type != ACPI_TYPE_PACKAGE) &&
-				((*stack_ptr)->common.type != INTERNAL_TYPE_REFERENCE))
-			{
-				return (AE_AML_OPERAND_TYPE);
-			}
-
-			/*
-			 * If this is a reference, only allow a reference to an Node.
-			 */
-			if ((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) {
-				if (!(*stack_ptr)->reference.node) {
-					return (AE_AML_OPERAND_TYPE);
-				}
-			}
-			goto next_operand;
-			break;
-
-
-		case ARGI_COMPLEXOBJ:
-
-			/* Need a buffer or package */
-
-			if (((*stack_ptr)->common.type != ACPI_TYPE_BUFFER) &&
-				((*stack_ptr)->common.type != ACPI_TYPE_PACKAGE))
-			{
-				return (AE_AML_OPERAND_TYPE);
-			}
-			goto next_operand;
-			break;
-
-
-		default:
-
-			/* Unknown type */
-
-			return (AE_BAD_PARAMETER);
-		}
-
-
-		/*
-		 * Make sure that the original object was resolved to the
-		 * required object type (Simple cases only).
-		 */
-		status = acpi_aml_check_object_type (type_needed,
-				  (*stack_ptr)->common.type, *stack_ptr);
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-
-
-next_operand:
-		/*
-		 * If more operands needed, decrement Stack_ptr to point
-		 * to next operand on stack
-		 */
-		if (GET_CURRENT_ARG_TYPE (arg_types)) {
-			stack_ptr--;
-		}
-
-	}   /* while (*Types) */
-
-
-	return (status);
-}
-
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/amstore.c linux/drivers/acpi/interpreter/amstore.c
--- v2.4.5/linux/drivers/acpi/interpreter/amstore.c	Tue Mar  6 19:44:36 2001
+++ linux/drivers/acpi/interpreter/amstore.c	Wed Dec 31 16:00:00 1969
@@ -1,578 +0,0 @@
-
-/******************************************************************************
- *
- * Module Name: amstore - AML Interpreter object store support
- *              $Revision: 123 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acparser.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acnamesp.h"
-#include "actables.h"
-
-
-#define _COMPONENT          INTERPRETER
-	 MODULE_NAME         ("amstore")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_exec_store
- *
- * PARAMETERS:  *Val_desc           - Value to be stored
- *              *Dest_desc          - Where to store it 0 Must be (ACPI_HANDLE)
- *                                    or an ACPI_OPERAND_OBJECT  of type
- *                                    Reference; if the latter the descriptor
- *                                    will be either reused or deleted.
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Store the value described by Val_desc into the location
- *              described by Dest_desc. Called by various interpreter
- *              functions to store the result of an operation into
- *              the destination operand.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_exec_store (
-	ACPI_OPERAND_OBJECT     *val_desc,
-	ACPI_OPERAND_OBJECT     *dest_desc,
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_STATUS             status = AE_OK;
-	ACPI_OPERAND_OBJECT     *ref_desc = dest_desc;
-
-
-	/* Validate parameters */
-
-	if (!val_desc || !dest_desc) {
-		return (AE_AML_NO_OPERAND);
-	}
-
-	/* Dest_desc can be either a namespace node or an ACPI object */
-
-	if (VALID_DESCRIPTOR_TYPE (dest_desc, ACPI_DESC_TYPE_NAMED)) {
-		/*
-		 * Dest is a namespace node,
-		 * Storing an object into a Name "container"
-		 */
-		status = acpi_aml_store_object_to_node (val_desc,
-				 (ACPI_NAMESPACE_NODE *) dest_desc, walk_state);
-
-		/* All done, that's it */
-
-		return (status);
-	}
-
-
-	/* Destination object must be an object of type Reference */
-
-	if (dest_desc->common.type != INTERNAL_TYPE_REFERENCE) {
-		/* Destination is not an Reference */
-
-		return (AE_AML_OPERAND_TYPE);
-	}
-
-
-	/*
-	 * Examine the Reference opcode.  These cases are handled:
-	 *
-	 * 1) Store to Name (Change the object associated with a name)
-	 * 2) Store to an indexed area of a Buffer or Package
-	 * 3) Store to a Method Local or Arg
-	 * 4) Store to the debug object
-	 * 5) Store to a constant -- a noop
-	 */
-
-	switch (ref_desc->reference.op_code)
-	{
-
-	case AML_NAME_OP:
-
-		/* Storing an object into a Name "container" */
-
-		status = acpi_aml_store_object_to_node (val_desc, ref_desc->reference.object,
-				  walk_state);
-		break;
-
-
-	case AML_INDEX_OP:
-
-		/* Storing to an Index (pointer into a packager or buffer) */
-
-		status = acpi_aml_store_object_to_index (val_desc, ref_desc, walk_state);
-		break;
-
-
-	case AML_LOCAL_OP:
-
-		status = acpi_ds_method_data_set_value (MTH_TYPE_LOCAL,
-				  (ref_desc->reference.offset), val_desc, walk_state);
-		break;
-
-
-	case AML_ARG_OP:
-
-		status = acpi_ds_method_data_set_value (MTH_TYPE_ARG,
-				  (ref_desc->reference.offset), val_desc, walk_state);
-		break;
-
-
-	case AML_DEBUG_OP:
-
-		/*
-		 * Storing to the Debug object causes the value stored to be
-		 * displayed and otherwise has no effect -- see ACPI Specification
-		 *
-		 * TBD: print known object types "prettier".
-		 */
-
-		break;
-
-
-	case AML_ZERO_OP:
-	case AML_ONE_OP:
-	case AML_ONES_OP:
-
-		/*
-		 * Storing to a constant is a no-op -- see ACPI Specification
-		 * Delete the reference descriptor, however
-		 */
-		break;
-
-
-	default:
-
-		/* TBD: [Restructure] use object dump routine !! */
-
-		status = AE_AML_INTERNAL;
-		break;
-
-	}   /* switch (Ref_desc->Reference.Op_code) */
-
-
-	/* Always delete the reference descriptor object */
-
-	if (ref_desc) {
-		acpi_cm_remove_reference (ref_desc);
-	}
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_store_object_to_index
- *
- * PARAMETERS:  *Val_desc           - Value to be stored
- *              *Node           - Named object to receive the value
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Store the object to the named object.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_store_object_to_index (
-	ACPI_OPERAND_OBJECT     *val_desc,
-	ACPI_OPERAND_OBJECT     *dest_desc,
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_STATUS             status = AE_OK;
-	ACPI_OPERAND_OBJECT     *obj_desc;
-	u32                     length;
-	u32                     i;
-	u8                      value = 0;
-
-
-	/*
-	 * Destination must be a reference pointer, and
-	 * must point to either a buffer or a package
-	 */
-
-	switch (dest_desc->reference.target_type)
-	{
-	case ACPI_TYPE_PACKAGE:
-		/*
-		 * Storing to a package element is not simple.  The source must be
-		 * evaluated and converted to the type of the destination and then the
-		 * source is copied into the destination - we can't just point to the
-		 * source object.
-		 */
-		if (dest_desc->reference.target_type == ACPI_TYPE_PACKAGE) {
-			/*
-			 * The object at *(Dest_desc->Reference.Where) is the
-			 *  element within the package that is to be modified.
-			 */
-			obj_desc = *(dest_desc->reference.where);
-			if (obj_desc) {
-				/*
-				 * If the Destination element is a package, we will delete
-				 *  that object and construct a new one.
-				 *
-				 * TBD: [Investigate] Should both the src and dest be required
-				 *      to be packages?
-				 *       && (Val_desc->Common.Type == ACPI_TYPE_PACKAGE)
-				 */
-				if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
-					/*
-					 * Take away the reference for being part of a package and
-					 * delete
-					 */
-					acpi_cm_remove_reference (obj_desc);
-					acpi_cm_remove_reference (obj_desc);
-
-					obj_desc = NULL;
-				}
-			}
-
-			if (!obj_desc) {
-				/*
-				 * If the Obj_desc is NULL, it means that an uninitialized package
-				 * element has been used as a destination (this is OK), therefore,
-				 * we must create the destination element to match the type of the
-				 * source element NOTE: Val_desc can be of any type.
-				 */
-				obj_desc = acpi_cm_create_internal_object (val_desc->common.type);
-				if (!obj_desc) {
-					return (AE_NO_MEMORY);
-				}
-
-				/*
-				 * If the source is a package, copy the source to the new dest
-				 */
-				if (ACPI_TYPE_PACKAGE == obj_desc->common.type) {
-					status = acpi_cm_copy_ipackage_to_ipackage (val_desc, obj_desc, walk_state);
-					if (ACPI_FAILURE (status)) {
-						acpi_cm_remove_reference (obj_desc);
-						return (status);
-					}
-				}
-
-				/*
-				 * Install the new descriptor into the package and add a
-				 * reference to the newly created descriptor for now being
-				 * part of the parent package
-				 */
-
-				*(dest_desc->reference.where) = obj_desc;
-				acpi_cm_add_reference (obj_desc);
-			}
-
-			if (ACPI_TYPE_PACKAGE != obj_desc->common.type) {
-				/*
-				 * The destination element is not a package, so we need to
-				 * convert the contents of the source (Val_desc) and copy into
-				 * the destination (Obj_desc)
-				 */
-				status = acpi_aml_store_object_to_object (val_desc, obj_desc,
-						  walk_state);
-				if (ACPI_FAILURE (status)) {
-					/*
-					 * An error occurrered when copying the internal object
-					 * so delete the reference.
-					 */
-					return (AE_AML_OPERAND_TYPE);
-				}
-			}
-		}
-		break;
-
-
-	case ACPI_TYPE_BUFFER_FIELD:
-		/*
-		 * Storing into a buffer at a location defined by an Index.
-		 *
-		 * Each 8-bit element of the source object is written to the
-		 * 8-bit Buffer Field of the Index destination object.
-		 */
-
-		/*
-		 * Set the Obj_desc to the destination object and type check.
-		 */
-		obj_desc = dest_desc->reference.object;
-		if (obj_desc->common.type != ACPI_TYPE_BUFFER) {
-			return (AE_AML_OPERAND_TYPE);
-		}
-
-		/*
-		 * The assignment of the individual elements will be slightly
-		 * different for each source type.
-		 */
-
-		switch (val_desc->common.type)
-		{
-		/*
-		 * If the type is Integer, assign bytewise
-		 * This loop to assign each of the elements is somewhat
-		 * backward because of the Big Endian-ness of IA-64
-		 */
-		case ACPI_TYPE_INTEGER:
-			length = sizeof (ACPI_INTEGER);
-			for (i = length; i != 0; i--) {
-				value = (u8)(val_desc->integer.value >> (MUL_8 (i - 1)));
-				obj_desc->buffer.pointer[dest_desc->reference.offset] = value;
-			}
-			break;
-
-		/*
-		 * If the type is Buffer, the Length is in the structure.
-		 * Just loop through the elements and assign each one in turn.
-		 */
-		case ACPI_TYPE_BUFFER:
-			length = val_desc->buffer.length;
-			for (i = 0; i < length; i++) {
-				value = *(val_desc->buffer.pointer + i);
-				obj_desc->buffer.pointer[dest_desc->reference.offset] = value;
-			}
-			break;
-
-		/*
-		 * If the type is String, the Length is in the structure.
-		 * Just loop through the elements and assign each one in turn.
-		 */
-		case ACPI_TYPE_STRING:
-			length = val_desc->string.length;
-			for (i = 0; i < length; i++) {
-				value = *(val_desc->string.pointer + i);
-				obj_desc->buffer.pointer[dest_desc->reference.offset] = value;
-			}
-			break;
-
-		/*
-		 * If source is not a valid type so return an error.
-		 */
-		default:
-			status = AE_AML_OPERAND_TYPE;
-			break;
-		}
-		break;
-
-
-	default:
-		status = AE_AML_OPERAND_TYPE;
-		break;
-	}
-
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_store_object_to_node
- *
- * PARAMETERS:  *Source_desc           - Value to be stored
- *              *Node               - Named object to receive the value
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Store the object to the named object.
- *
- *              The Assignment of an object to a named object is handled here
- *              The val passed in will replace the current value (if any)
- *              with the input value.
- *
- *              When storing into an object the data is converted to the
- *              target object type then stored in the object.  This means
- *              that the target object type (for an initialized target) will
- *              not be changed by a store operation.
- *
- *              NOTE: the global lock is acquired early.  This will result
- *              in the global lock being held a bit longer.  Also, if the
- *              function fails during set up we may get the lock when we
- *              don't really need it.  I don't think we care.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_store_object_to_node (
-	ACPI_OPERAND_OBJECT     *source_desc,
-	ACPI_NAMESPACE_NODE     *node,
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_STATUS             status = AE_OK;
-	ACPI_OPERAND_OBJECT     *target_desc;
-	OBJECT_TYPE_INTERNAL    target_type = ACPI_TYPE_ANY;
-
-
-	/*
-	 * Assuming the parameters were already validated
-	 */
-	ACPI_ASSERT((node) && (source_desc));
-
-
-	/*
-	 * Get current type of the node, and object attached to Node
-	 */
-	target_type = acpi_ns_get_type (node);
-	target_desc = acpi_ns_get_attached_object (node);
-
-
-	/*
-	 * Resolve the source object to an actual value
-	 * (If it is a reference object)
-	 */
-	status = acpi_aml_resolve_object (&source_desc, target_type, walk_state);
-	if (ACPI_FAILURE (status)) {
-		return (status);
-	}
-
-
-	/*
-	 * Do the actual store operation
-	 */
-	switch (target_type)
-	{
-	case INTERNAL_TYPE_DEF_FIELD:
-
-		/* Raw data copy for target types Integer/String/Buffer */
-
-		status = acpi_aml_copy_data_to_named_field (source_desc, node);
-		break;
-
-
-	case ACPI_TYPE_INTEGER:
-	case ACPI_TYPE_STRING:
-	case ACPI_TYPE_BUFFER:
-	case INTERNAL_TYPE_BANK_FIELD:
-	case INTERNAL_TYPE_INDEX_FIELD:
-	case ACPI_TYPE_FIELD_UNIT:
-
-		/*
-		 * These target types are all of type Integer/String/Buffer, and
-		 * therefore support implicit conversion before the store.
-		 *
-		 * Copy and/or convert the source object to a new target object
-		 */
-		status = acpi_aml_store_object (source_desc, target_type, &target_desc, walk_state);
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-
-		/*
-		 * Store the new Target_desc as the new value of the Name, and set
-		 * the Name's type to that of the value being stored in it.
-		 * Source_desc reference count is incremented by Attach_object.
-		 */
-		status = acpi_ns_attach_object (node, target_desc, target_type);
-		break;
-
-
-	default:
-
-		/* No conversions for all other types.  Just attach the source object */
-
-		status = acpi_ns_attach_object (node, source_desc, source_desc->common.type);
-
-		break;
-	}
-
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_store_object_to_object
- *
- * PARAMETERS:  *Source_desc           - Value to be stored
- *              *Dest_desc          - Object to receive the value
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Store an object to another object.
- *
- *              The Assignment of an object to another (not named) object
- *              is handled here.
- *              The val passed in will replace the current value (if any)
- *              with the input value.
- *
- *              When storing into an object the data is converted to the
- *              target object type then stored in the object.  This means
- *              that the target object type (for an initialized target) will
- *              not be changed by a store operation.
- *
- *              This module allows destination types of Number, String,
- *              and Buffer.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_store_object_to_object (
-	ACPI_OPERAND_OBJECT     *source_desc,
-	ACPI_OPERAND_OBJECT     *dest_desc,
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_STATUS             status = AE_OK;
-	OBJECT_TYPE_INTERNAL    destination_type = dest_desc->common.type;
-
-
-	/*
-	 *  Assuming the parameters are valid!
-	 */
-	ACPI_ASSERT((dest_desc) && (source_desc));
-
-
-	/*
-	 * From this interface, we only support Integers/Strings/Buffers
-	 */
-	switch (destination_type)
-	{
-	case ACPI_TYPE_INTEGER:
-	case ACPI_TYPE_STRING:
-	case ACPI_TYPE_BUFFER:
-		break;
-
-	default:
-		return (AE_NOT_IMPLEMENTED);
-	}
-
-
-	/*
-	 * Resolve the source object to an actual value
-	 * (If it is a reference object)
-	 */
-	status = acpi_aml_resolve_object (&source_desc, destination_type, walk_state);
-	if (ACPI_FAILURE (status)) {
-		return (status);
-	}
-
-
-	/*
-	 * Copy and/or convert the source object to the destination object
-	 */
-	status = acpi_aml_store_object (source_desc, destination_type, &dest_desc, walk_state);
-
-
-	return (status);
-}
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/amstoren.c linux/drivers/acpi/interpreter/amstoren.c
--- v2.4.5/linux/drivers/acpi/interpreter/amstoren.c	Mon Jan 29 10:15:59 2001
+++ linux/drivers/acpi/interpreter/amstoren.c	Wed Dec 31 16:00:00 1969
@@ -1,262 +0,0 @@
-
-/******************************************************************************
- *
- * Module Name: amstoren - AML Interpreter object store support,
- *                        Store to Node (namespace object)
- *              $Revision: 28 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acparser.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acnamesp.h"
-#include "actables.h"
-
-
-#define _COMPONENT          INTERPRETER
-	 MODULE_NAME         ("amstoren")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_resolve_object
- *
- * PARAMETERS:  Source_desc_ptr     - Pointer to the source object
- *              Target_type         - Current type of the target
- *              Walk_state          - Current walk state
- *
- * RETURN:      Status, resolved object in Source_desc_ptr.
- *
- * DESCRIPTION: Resolve an object.  If the object is a reference, dereference
- *              it and return the actual object in the Source_desc_ptr.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_resolve_object (
-	ACPI_OPERAND_OBJECT     **source_desc_ptr,
-	OBJECT_TYPE_INTERNAL    target_type,
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_OPERAND_OBJECT     *source_desc = *source_desc_ptr;
-	ACPI_STATUS             status = AE_OK;
-
-
-	/*
-	 * Ensure we have a Source that can be stored in the target
-	 */
-	switch (target_type)
-	{
-
-	/* This case handles the "interchangeable" types Integer, String, and Buffer. */
-
-	/*
-	 * These cases all require only Integers or values that
-	 * can be converted to Integers (Strings or Buffers)
-	 */
-	case ACPI_TYPE_INTEGER:
-	case ACPI_TYPE_FIELD_UNIT:
-	case INTERNAL_TYPE_BANK_FIELD:
-	case INTERNAL_TYPE_INDEX_FIELD:
-
-	/*
-	 * Stores into a Field/Region or into a Buffer/String
-	 * are all essentially the same.
-	 */
-	case ACPI_TYPE_STRING:
-	case ACPI_TYPE_BUFFER:
-	case INTERNAL_TYPE_DEF_FIELD:
-
-		/*
-		 * If Source_desc is not a valid type, try to resolve it to one.
-		 */
-		if ((source_desc->common.type != ACPI_TYPE_INTEGER)    &&
-			(source_desc->common.type != ACPI_TYPE_BUFFER)     &&
-			(source_desc->common.type != ACPI_TYPE_STRING))
-		{
-			/*
-			 * Initially not a valid type, convert
-			 */
-			status = acpi_aml_resolve_to_value (source_desc_ptr, walk_state);
-			if (ACPI_SUCCESS (status) &&
-				(source_desc->common.type != ACPI_TYPE_INTEGER)    &&
-				(source_desc->common.type != ACPI_TYPE_BUFFER)     &&
-				(source_desc->common.type != ACPI_TYPE_STRING))
-			{
-				/*
-				 * Conversion successful but still not a valid type
-				 */
-				status = AE_AML_OPERAND_TYPE;
-			}
-		}
-		break;
-
-
-	case INTERNAL_TYPE_ALIAS:
-
-		/*
-		 * Aliases are resolved by Acpi_aml_prep_operands
-		 */
-		status = AE_AML_INTERNAL;
-		break;
-
-
-	case ACPI_TYPE_PACKAGE:
-	default:
-
-		/*
-		 * All other types than Alias and the various Fields come here,
-		 * including the untyped case - ACPI_TYPE_ANY.
-		 */
-		break;
-	}
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_store_object
- *
- * PARAMETERS:  Source_desc         - Object to store
- *              Target_type         - Current type of the target
- *              Target_desc_ptr     - Pointer to the target
- *              Walk_state          - Current walk state
- *
- * RETURN:      Status
- *
- * DESCRIPTION: "Store" an object to another object.  This may include
- *              converting the source type to the target type (implicit
- *              conversion), and a copy of the value of the source to
- *              the target.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_store_object (
-	ACPI_OPERAND_OBJECT     *source_desc,
-	OBJECT_TYPE_INTERNAL    target_type,
-	ACPI_OPERAND_OBJECT     **target_desc_ptr,
-	ACPI_WALK_STATE         *walk_state)
-{
-	ACPI_OPERAND_OBJECT     *target_desc = *target_desc_ptr;
-	ACPI_STATUS             status;
-
-
-	/*
-	 * Perform the "implicit conversion" of the source to the current type
-	 * of the target - As per the ACPI specification.
-	 *
-	 * If no conversion performed, Source_desc is left alone, otherwise it
-	 * is updated with a new object.
-	 */
-	status = acpi_aml_convert_to_target_type (target_type, &source_desc, walk_state);
-	if (ACPI_FAILURE (status)) {
-		return (status);
-	}
-
-
-	/*
-	 * We now have two objects of identical types, and we can perform a
-	 * copy of the *value* of the source object.
-	 */
-	switch (target_type)
-	{
-	case ACPI_TYPE_ANY:
-	case INTERNAL_TYPE_DEF_ANY:
-
-		/*
-		 * The target namespace node is uninitialized (has no target object),
-		 * and will take on the type of the source object
-		 */
-
-		*target_desc_ptr = source_desc;
-		break;
-
-
-	case ACPI_TYPE_INTEGER:
-
-		target_desc->integer.value = source_desc->integer.value;
-
-		/* Truncate value if we are executing from a 32-bit ACPI table */
-
-		acpi_aml_truncate_for32bit_table (target_desc, walk_state);
-		break;
-
-
-	case ACPI_TYPE_FIELD_UNIT:
-
-		status = acpi_aml_copy_integer_to_field_unit (source_desc, target_desc);
-		break;
-
-
-	case INTERNAL_TYPE_BANK_FIELD:
-
-		status = acpi_aml_copy_integer_to_bank_field (source_desc, target_desc);
-		break;
-
-
-	case INTERNAL_TYPE_INDEX_FIELD:
-
-		status = acpi_aml_copy_integer_to_index_field (source_desc, target_desc);
-		break;
-
-
-	case ACPI_TYPE_STRING:
-
-		status = acpi_aml_copy_string_to_string (source_desc, target_desc);
-		break;
-
-
-	case ACPI_TYPE_BUFFER:
-
-		status = acpi_aml_copy_buffer_to_buffer (source_desc, target_desc);
-		break;
-
-
-	case ACPI_TYPE_PACKAGE:
-
-		/*
-		 * TBD: [Unhandled] Not real sure what to do here
-		 */
-		status = AE_NOT_IMPLEMENTED;
-		break;
-
-
-	default:
-
-		/*
-		 * All other types come here.
-		 */
-		status = AE_NOT_IMPLEMENTED;
-		break;
-	}
-
-
-	return (status);
-}
-
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/amstorob.c linux/drivers/acpi/interpreter/amstorob.c
--- v2.4.5/linux/drivers/acpi/interpreter/amstorob.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/interpreter/amstorob.c	Wed Dec 31 16:00:00 1969
@@ -1,435 +0,0 @@
-
-/******************************************************************************
- *
- * Module Name: amstorob - AML Interpreter object store support, store to object
- *              $Revision: 23 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acparser.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acnamesp.h"
-#include "actables.h"
-
-
-#define _COMPONENT          INTERPRETER
-	 MODULE_NAME         ("amstorob")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_copy_buffer_to_buffer
- *
- * PARAMETERS:  Source_desc         - Source object to copy
- *              Target_desc         - Destination object of the copy
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Copy a buffer object to another buffer object.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_copy_buffer_to_buffer (
-	ACPI_OPERAND_OBJECT     *source_desc,
-	ACPI_OPERAND_OBJECT     *target_desc)
-{
-	u32                     length;
-	u8                      *buffer;
-
- 	   /*
-	 * We know that Source_desc is a buffer by now
-	 */
-	buffer = (u8 *) source_desc->buffer.pointer;
-	length = source_desc->buffer.length;
-
-	/*
-	 * If target is a buffer of length zero, allocate a new
-	 * buffer of the proper length
-	 */
-	if (target_desc->buffer.length == 0) {
-		target_desc->buffer.pointer = acpi_cm_allocate (length);
-		if (!target_desc->buffer.pointer) {
-			return (AE_NO_MEMORY);
-		}
-
-		target_desc->buffer.length = length;
-	}
-
-	/*
-	 * Buffer is a static allocation,
-	 * only place what will fit in the buffer.
-	 */
-	if (length <= target_desc->buffer.length) {
-		/* Clear existing buffer and copy in the new one */
-
-		MEMSET(target_desc->buffer.pointer, 0, target_desc->buffer.length);
-		MEMCPY(target_desc->buffer.pointer, buffer, length);
-	}
-
-	else {
-		/*
-		 * Truncate the source, copy only what will fit
-		 */
-		MEMCPY(target_desc->buffer.pointer, buffer, target_desc->buffer.length);
-
-	}
-
-	return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_copy_string_to_string
- *
- * PARAMETERS:  Source_desc         - Source object to copy
- *              Target_desc         - Destination object of the copy
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Copy a String object to another String object
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_copy_string_to_string (
-	ACPI_OPERAND_OBJECT     *source_desc,
-	ACPI_OPERAND_OBJECT     *target_desc)
-{
-	u32                     length;
-	u8                      *buffer;
-
-
-	/*
-	 * We know that Source_desc is a string by now.
-	 */
-	buffer = (u8 *) source_desc->string.pointer;
-	length = source_desc->string.length;
-
-	/*
-	 * Setting a string value replaces the old string
-	 */
-	if (length < target_desc->string.length) {
-		/* Clear old string and copy in the new one */
-
-		MEMSET(target_desc->string.pointer, 0, target_desc->string.length);
-		MEMCPY(target_desc->string.pointer, buffer, length);
-	}
-
-	else {
-		/*
-		 * Free the current buffer, then allocate a buffer
-		 * large enough to hold the value
-		 */
-		if (target_desc->string.pointer &&
-			!acpi_tb_system_table_pointer (target_desc->string.pointer))
-		{
-			/*
-			 * Only free if not a pointer into the DSDT
-			 */
-			acpi_cm_free(target_desc->string.pointer);
-		}
-
-		target_desc->string.pointer = acpi_cm_allocate (length + 1);
-		if (!target_desc->string.pointer) {
-			return (AE_NO_MEMORY);
-		}
-		target_desc->string.length = length;
-
-
-		MEMCPY(target_desc->string.pointer, buffer, length);
-	}
-
-	return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_copy_integer_to_index_field
- *
- * PARAMETERS:  Source_desc         - Source object to copy
- *              Target_desc         - Destination object of the copy
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Write an Integer to an Index Field
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_copy_integer_to_index_field (
-	ACPI_OPERAND_OBJECT     *source_desc,
-	ACPI_OPERAND_OBJECT     *target_desc)
-{
-	ACPI_STATUS             status;
-	u8                      locked;
-
-
-	/*
-	 * Get the global lock if needed
-	 */
-	locked = acpi_aml_acquire_global_lock (target_desc->index_field.lock_rule);
-
-	/*
-	 * Set Index value to select proper Data register
-	 * perform the update (Set index)
-	 */
-	status = acpi_aml_access_named_field (ACPI_WRITE,
-			 target_desc->index_field.index,
-			 &target_desc->index_field.value,
-			 sizeof (target_desc->index_field.value));
-	if (ACPI_SUCCESS (status)) {
-		/* Set_index was successful, next set Data value */
-
-		status = acpi_aml_access_named_field (ACPI_WRITE,
-				   target_desc->index_field.data,
-				   &source_desc->integer.value,
-				   sizeof (source_desc->integer.value));
-
-	}
-
-
-
-	/*
-	 * Release global lock if we acquired it earlier
-	 */
-	acpi_aml_release_global_lock (locked);
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_copy_integer_to_bank_field
- *
- * PARAMETERS:  Source_desc         - Source object to copy
- *              Target_desc         - Destination object of the copy
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Write an Integer to a Bank Field
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_copy_integer_to_bank_field (
-	ACPI_OPERAND_OBJECT     *source_desc,
-	ACPI_OPERAND_OBJECT     *target_desc)
-{
-	ACPI_STATUS             status;
-	u8                      locked;
-
-
-	/*
-	 * Get the global lock if needed
-	 */
-	locked = acpi_aml_acquire_global_lock (target_desc->index_field.lock_rule);
-
-
-	/*
-	 * Set Bank value to select proper Bank
-	 * Perform the update (Set Bank Select)
-	 */
-
-	status = acpi_aml_access_named_field (ACPI_WRITE,
-			 target_desc->bank_field.bank_select,
-			 &target_desc->bank_field.value,
-			 sizeof (target_desc->bank_field.value));
-	if (ACPI_SUCCESS (status)) {
-		/* Set bank select successful, set data value  */
-
-		status = acpi_aml_access_named_field (ACPI_WRITE,
-				   target_desc->bank_field.bank_select,
-				   &source_desc->bank_field.value,
-				   sizeof (source_desc->bank_field.value));
-	}
-
-
-
-	/*
-	 * Release global lock if we acquired it earlier
-	 */
-	acpi_aml_release_global_lock (locked);
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_copy_data_to_named_field
- *
- * PARAMETERS:  Source_desc         - Source object to copy
- *              Node                - Destination Namespace node
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Copy raw data to a Named Field.  No implicit conversion
- *              is performed on the source object
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_copy_data_to_named_field (
-	ACPI_OPERAND_OBJECT     *source_desc,
-	ACPI_NAMESPACE_NODE     *node)
-{
-	ACPI_STATUS             status;
-	u8                      locked;
-	u32                     length;
-	u8                      *buffer;
-
-
-	/*
-	 * Named fields (Create_xxx_field) - We don't perform any conversions on the
-	 * source operand, just use the raw data
-	 */
-	switch (source_desc->common.type)
-	{
-	case ACPI_TYPE_INTEGER:
-		buffer = (u8 *) &source_desc->integer.value;
-		length = sizeof (source_desc->integer.value);
-		break;
-
-	case ACPI_TYPE_BUFFER:
-		buffer = (u8 *) source_desc->buffer.pointer;
-		length = source_desc->buffer.length;
-		break;
-
-	case ACPI_TYPE_STRING:
-		buffer = (u8 *) source_desc->string.pointer;
-		length = source_desc->string.length;
-		break;
-
-	default:
-		return (AE_TYPE);
-	}
-
-	/*
-	 * Get the global lock if needed before the update
-	 * TBD: not needed!
-	 */
-	locked = acpi_aml_acquire_global_lock (source_desc->field.lock_rule);
-
-	status = acpi_aml_access_named_field (ACPI_WRITE,
-			  node, buffer, length);
-
-	acpi_aml_release_global_lock (locked);
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_copy_integer_to_field_unit
- *
- * PARAMETERS:  Source_desc         - Source object to copy
- *              Target_desc         - Destination object of the copy
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Write an Integer to a Field Unit.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_copy_integer_to_field_unit (
-	ACPI_OPERAND_OBJECT     *source_desc,
-	ACPI_OPERAND_OBJECT     *target_desc)
-{
-	ACPI_STATUS             status = AE_OK;
-	u8                      *location = NULL;
-	u32                     mask;
-	u32                     new_value;
-	u8                      locked = FALSE;
-
-
-	/*
-	 * If the Field Buffer and Index have not been previously evaluated,
-	 * evaluate them and save the results.
-	 */
-	if (!(target_desc->common.flags & AOPOBJ_DATA_VALID)) {
-		status = acpi_ds_get_field_unit_arguments (target_desc);
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-	}
-
-	if ((!target_desc->field_unit.container ||
-		ACPI_TYPE_BUFFER != target_desc->field_unit.container->common.type))
-	{
-		return (AE_AML_INTERNAL);
-	}
-
-	/*
-	 * Get the global lock if needed
-	 */
-	locked = acpi_aml_acquire_global_lock (target_desc->field_unit.lock_rule);
-
-	/*
-	 * TBD: [Unhandled] REMOVE this limitation
-	 * Make sure the operation is within the limits of our implementation
-	 * this is not a Spec limitation!!
-	 */
-	if (target_desc->field_unit.length + target_desc->field_unit.bit_offset > 32) {
-		return (AE_NOT_IMPLEMENTED);
-	}
-
-	/* Field location is (base of buffer) + (byte offset) */
-
-	location = target_desc->field_unit.container->buffer.pointer
-			  + target_desc->field_unit.offset;
-
-	/*
-	 * Construct Mask with 1 bits where the field is,
-	 * 0 bits elsewhere
-	 */
-	mask = ((u32) 1 << target_desc->field_unit.length) - ((u32)1
-			   << target_desc->field_unit.bit_offset);
-
-	/* Zero out the field in the buffer */
-
-	MOVE_UNALIGNED32_TO_32 (&new_value, location);
-	new_value &= ~mask;
-
-	/*
-	 * Shift and mask the new value into position,
-	 * and or it into the buffer.
-	 */
-	new_value |= (source_desc->integer.value << target_desc->field_unit.bit_offset) &
-			 mask;
-
-	/* Store back the value */
-
-	MOVE_UNALIGNED32_TO_32 (location, &new_value);
-
-	return (AE_OK);
-}
-
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/amsystem.c linux/drivers/acpi/interpreter/amsystem.c
--- v2.4.5/linux/drivers/acpi/interpreter/amsystem.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/interpreter/amsystem.c	Wed Dec 31 16:00:00 1969
@@ -1,344 +0,0 @@
-
-/******************************************************************************
- *
- * Module Name: amsystem - Interface to OS services
- *              $Revision: 54 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acinterp.h"
-#include "acnamesp.h"
-#include "achware.h"
-#include "acevents.h"
-
-#define _COMPONENT          INTERPRETER
-	 MODULE_NAME         ("amsystem")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_system_thread_id
- *
- * PARAMETERS:  None
- *
- * RETURN:      Current Thread ID (for this implementation a 1 is returned)
- *
- * DESCRIPTION: An invocation is identified by its Thread ID.  In a single
- *              threaded OS the Thread ID is undefined so a 1 will be
- *              returned.
- *
- ******************************************************************************/
-
-u16
-acpi_aml_system_thread_id (void)
-{
-	return (1);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_system_wait_semaphore
- *
- * PARAMETERS:  Semaphore           - OSD semaphore to wait on
- *              Timeout             - Max time to wait
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Implements a semaphore wait with a check to see if the
- *              semaphore is available immediately.  If it is not, the
- *              interpreter is released.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_system_wait_semaphore (
-	ACPI_HANDLE             semaphore,
-	u32                     timeout)
-{
-	ACPI_STATUS             status;
-
-
-	status = acpi_os_wait_semaphore (semaphore, 1, 0);
-	if (ACPI_SUCCESS (status)) {
-		return (status);
-	}
-
-	if (status == AE_TIME) {
-		/* We must wait, so unlock the interpreter */
-
-		acpi_aml_exit_interpreter ();
-
-		status = acpi_os_wait_semaphore (semaphore, 1, timeout);
-
-		/* Reacquire the interpreter */
-
-		acpi_aml_enter_interpreter ();
-
-	}
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_system_do_stall
- *
- * PARAMETERS:  How_long            - The amount of time to stall
- *
- * RETURN:      None
- *
- * DESCRIPTION: Suspend running thread for specified amount of time.
- *
- ******************************************************************************/
-
-void
-acpi_aml_system_do_stall (
-	u32                     how_long)
-{
-
-	if (how_long > 1000) /* 1 millisecond */ {
-		/* Since this thread will sleep, we must release the interpreter */
-
-		acpi_aml_exit_interpreter ();
-
-		acpi_os_sleep_usec (how_long);
-
-		/* And now we must get the interpreter again */
-
-		acpi_aml_enter_interpreter ();
-	}
-
-	else {
-		acpi_os_sleep_usec (how_long);
-	}
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_system_do_suspend
- *
- * PARAMETERS:  How_long            - The amount of time to suspend
- *
- * RETURN:      None
- *
- * DESCRIPTION: Suspend running thread for specified amount of time.
- *
- ******************************************************************************/
-
-void
-acpi_aml_system_do_suspend (
-	u32                     how_long)
-{
-	/* Since this thread will sleep, we must release the interpreter */
-
-	acpi_aml_exit_interpreter ();
-
-	acpi_os_sleep ((u16) (how_long / (u32) 1000),
-			  (u16) (how_long % (u32) 1000));
-
-	/* And now we must get the interpreter again */
-
-	acpi_aml_enter_interpreter ();
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_system_acquire_mutex
- *
- * PARAMETERS:  *Time_desc          - The 'time to delay' object descriptor
- *              *Obj_desc           - The object descriptor for this op
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Provides an access point to perform synchronization operations
- *              within the AML.  This function will cause a lock to be generated
- *              for the Mutex pointed to by Obj_desc.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_system_acquire_mutex (
-	ACPI_OPERAND_OBJECT     *time_desc,
-	ACPI_OPERAND_OBJECT     *obj_desc)
-{
-	ACPI_STATUS             status = AE_OK;
-
-
-	if (!obj_desc) {
-		return (AE_BAD_PARAMETER);
-	}
-
-	/*
-	 * Support for the _GL_ Mutex object -- go get the global lock
-	 */
-
-	if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
-		status = acpi_ev_acquire_global_lock ();
-		return (status);
-	}
-
-	status = acpi_aml_system_wait_semaphore (obj_desc->mutex.semaphore,
-			  (u32) time_desc->integer.value);
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_system_release_mutex
- *
- * PARAMETERS:  *Obj_desc           - The object descriptor for this op
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Provides an access point to perform synchronization operations
- *              within the AML.  This operation is a request to release a
- *              previously acquired Mutex.  If the Mutex variable is set then
- *              it will be decremented.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_system_release_mutex (
-	ACPI_OPERAND_OBJECT     *obj_desc)
-{
-	ACPI_STATUS             status = AE_OK;
-
-
-	if (!obj_desc) {
-		return (AE_BAD_PARAMETER);
-	}
-
-	/*
-	 * Support for the _GL_ Mutex object -- release the global lock
-	 */
-	if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
-		acpi_ev_release_global_lock ();
-		return (AE_OK);
-	}
-
-	status = acpi_os_signal_semaphore (obj_desc->mutex.semaphore, 1);
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_system_signal_event
- *
- * PARAMETERS:  *Obj_desc           - The object descriptor for this op
- *
- * RETURN:      AE_OK
- *
- * DESCRIPTION: Provides an access point to perform synchronization operations
- *              within the AML.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_system_signal_event (
-	ACPI_OPERAND_OBJECT     *obj_desc)
-{
-	ACPI_STATUS             status = AE_OK;
-
-
-	if (obj_desc) {
-		status = acpi_os_signal_semaphore (obj_desc->event.semaphore, 1);
-	}
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_system_wait_event
- *
- * PARAMETERS:  *Time_desc          - The 'time to delay' object descriptor
- *              *Obj_desc           - The object descriptor for this op
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Provides an access point to perform synchronization operations
- *              within the AML.  This operation is a request to wait for an
- *              event.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_system_wait_event (
-	ACPI_OPERAND_OBJECT     *time_desc,
-	ACPI_OPERAND_OBJECT     *obj_desc)
-{
-	ACPI_STATUS             status = AE_OK;
-
-
-	if (obj_desc) {
-		status = acpi_aml_system_wait_semaphore (obj_desc->event.semaphore,
-				  (u32) time_desc->integer.value);
-	}
-
-
-	return (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_system_reset_event
- *
- * PARAMETERS:  *Obj_desc           - The object descriptor for this op
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Provides an access point to perform synchronization operations
- *              within the AML.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_system_reset_event (
-	ACPI_OPERAND_OBJECT     *obj_desc)
-{
-	ACPI_STATUS             status = AE_OK;
-	void                    *temp_semaphore;
-
-
-	/*
-	 * We are going to simply delete the existing semaphore and
-	 * create a new one!
-	 */
-
-	status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore);
-	if (ACPI_SUCCESS (status)) {
-		acpi_os_delete_semaphore (obj_desc->mutex.semaphore);
-		obj_desc->mutex.semaphore = temp_semaphore;
-	}
-
-	return (status);
-}
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/amutils.c linux/drivers/acpi/interpreter/amutils.c
--- v2.4.5/linux/drivers/acpi/interpreter/amutils.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/interpreter/amutils.c	Wed Dec 31 16:00:00 1969
@@ -1,370 +0,0 @@
-
-/******************************************************************************
- *
- * Module Name: amutils - interpreter/scanner utilities
- *              $Revision: 69 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acparser.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acnamesp.h"
-#include "acevents.h"
-
-#define _COMPONENT          INTERPRETER
-	 MODULE_NAME         ("amutils")
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_enter_interpreter
- *
- * PARAMETERS:  None
- *
- * DESCRIPTION: Enter the interpreter execution region
- *
- ******************************************************************************/
-
-void
-acpi_aml_enter_interpreter (void)
-{
-
-	acpi_cm_acquire_mutex (ACPI_MTX_EXECUTE);
-
-	return;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_exit_interpreter
- *
- * PARAMETERS:  None
- *
- * DESCRIPTION: Exit the interpreter execution region
- *
- * Cases where the interpreter is unlocked:
- *      1) Completion of the execution of a control method
- *      2) Method blocked on a Sleep() AML opcode
- *      3) Method blocked on an Acquire() AML opcode
- *      4) Method blocked on a Wait() AML opcode
- *      5) Method blocked to acquire the global lock
- *      6) Method blocked to execute a serialized control method that is
- *          already executing
- *      7) About to invoke a user-installed opregion handler
- *
- ******************************************************************************/
-
-void
-acpi_aml_exit_interpreter (void)
-{
-
-	acpi_cm_release_mutex (ACPI_MTX_EXECUTE);
-
-	return;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_validate_object_type
- *
- * PARAMETERS:  Type            Object type to validate
- *
- * DESCRIPTION: Determine if a type is a valid ACPI object type
- *
- ******************************************************************************/
-
-u8
-acpi_aml_validate_object_type (
-	ACPI_OBJECT_TYPE        type)
-{
-
-	if ((type > ACPI_TYPE_MAX && type < INTERNAL_TYPE_BEGIN) ||
-		(type > INTERNAL_TYPE_MAX))
-	{
-		return (FALSE);
-	}
-
-	return (TRUE);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_truncate_for32bit_table
- *
- * PARAMETERS:  Obj_desc        - Object to be truncated
- *              Walk_state      - Current walk state
- *                                (A method must be executing)
- *
- * RETURN:      none
- *
- * DESCRIPTION: Truncate a number to 32-bits if the currently executing method
- *              belongs to a 32-bit ACPI table.
- *
- ******************************************************************************/
-
-void
-acpi_aml_truncate_for32bit_table (
-	ACPI_OPERAND_OBJECT     *obj_desc,
-	ACPI_WALK_STATE         *walk_state)
-{
-
-	/*
-	 * Object must be a valid number and we must be executing
-	 * a control method
-	 */
-
-	if ((!obj_desc) ||
-		(obj_desc->common.type != ACPI_TYPE_INTEGER) ||
-		(!walk_state->method_node))
-	{
-		return;
-	}
-
-	if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) {
-		/*
-		 * We are running a method that exists in a 32-bit ACPI table.
-		 * Truncate the value to 32 bits by zeroing out the upper 32-bit field
-		 */
-		obj_desc->integer.value &= (ACPI_INTEGER) ACPI_UINT32_MAX;
-	}
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_acquire_global_lock
- *
- * PARAMETERS:  Rule            - Lock rule: Always_lock, Never_lock
- *
- * RETURN:      TRUE/FALSE indicating whether the lock was actually acquired
- *
- * DESCRIPTION: Obtain the global lock and keep track of this fact via two
- *              methods.  A global variable keeps the state of the lock, and
- *              the state is returned to the caller.
- *
- ******************************************************************************/
-
-u8
-acpi_aml_acquire_global_lock (
-	u32                     rule)
-{
-	u8                      locked = FALSE;
-	ACPI_STATUS             status;
-
-
-	/*  Only attempt lock if the Rule says so */
-
-	if (rule == (u32) GLOCK_ALWAYS_LOCK) {
-		/*  OK to get the lock   */
-
-		status = acpi_ev_acquire_global_lock ();
-
-		if (ACPI_SUCCESS (status)) {
-			acpi_gbl_global_lock_set = TRUE;
-			locked = TRUE;
-		}
-	}
-
-	return (locked);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_release_global_lock
- *
- * PARAMETERS:  Locked_by_me    - Return value from corresponding call to
- *                                Acquire_global_lock.
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Release the global lock if it is locked.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_release_global_lock (
-	u8                      locked_by_me)
-{
-
-
-	/* Only attempt unlock if the caller locked it */
-
-	if (locked_by_me) {
-		/* Double check against the global flag */
-
-		if (acpi_gbl_global_lock_set) {
-			/* OK, now release the lock */
-
-			acpi_ev_release_global_lock ();
-			acpi_gbl_global_lock_set = FALSE;
-		}
-
-	}
-
-
-	return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_digits_needed
- *
- * PARAMETERS:  val             - Value to be represented
- *              base            - Base of representation
- *
- * RETURN:      the number of digits needed to represent val in base
- *
- ******************************************************************************/
-
-u32
-acpi_aml_digits_needed (
-	ACPI_INTEGER            val,
-	u32                     base)
-{
-	u32                     num_digits = 0;
-
-
-	if (base < 1) {
-		REPORT_ERROR (("Aml_digits_needed: Internal error - Invalid base\n"));
-	}
-
-	else {
-		for (num_digits = 1 + (val < 0); (val = ACPI_DIVIDE (val,base)); ++num_digits) { ; }
-	}
-
-	return (num_digits);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    ntohl
- *
- * PARAMETERS:  Value           - Value to be converted
- *
- * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
- *
- ******************************************************************************/
-
-static u32
-_ntohl (
-	u32                     value)
-{
-	union
-	{
-		u32                 value;
-		u8                  bytes[4];
-	} out;
-
-	union
-	{
-		u32                 value;
-		u8                  bytes[4];
-	} in;
-
-
-	in.value = value;
-
-	out.bytes[0] = in.bytes[3];
-	out.bytes[1] = in.bytes[2];
-	out.bytes[2] = in.bytes[1];
-	out.bytes[3] = in.bytes[0];
-
-	return (out.value);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_eisa_id_to_string
- *
- * PARAMETERS:  Numeric_id      - EISA ID to be converted
- *              Out_string      - Where to put the converted string (8 bytes)
- *
- * DESCRIPTION: Convert a numeric EISA ID to string representation
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_eisa_id_to_string (
-	u32                     numeric_id,
-	NATIVE_CHAR             *out_string)
-{
-	u32                     id;
-
-	/* swap to big-endian to get contiguous bits */
-
-	id = _ntohl (numeric_id);
-
-	out_string[0] = (char) ('@' + ((id >> 26) & 0x1f));
-	out_string[1] = (char) ('@' + ((id >> 21) & 0x1f));
-	out_string[2] = (char) ('@' + ((id >> 16) & 0x1f));
-	out_string[3] = acpi_gbl_hex_to_ascii[(id >> 12) & 0xf];
-	out_string[4] = acpi_gbl_hex_to_ascii[(id >> 8) & 0xf];
-	out_string[5] = acpi_gbl_hex_to_ascii[(id >> 4) & 0xf];
-	out_string[6] = acpi_gbl_hex_to_ascii[id & 0xf];
-	out_string[7] = 0;
-
-	return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_unsigned_integer_to_string
- *
- * PARAMETERS:  Value           - Value to be converted
- *              Out_string      - Where to put the converted string (8 bytes)
- *
- * RETURN:      Convert a number to string representation
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_unsigned_integer_to_string (
-	ACPI_INTEGER            value,
-	NATIVE_CHAR             *out_string)
-{
-	u32                     count;
-	u32                     digits_needed;
-
-
-	digits_needed = acpi_aml_digits_needed (value, 10);
-
-	out_string[digits_needed] = '\0';
-
-	for (count = digits_needed; count > 0; count--) {
-		out_string[count-1] = (NATIVE_CHAR) ('0' + (ACPI_MODULO (value, 10)));
-		value = ACPI_DIVIDE (value, 10);
-	}
-
-	return (AE_OK);
-}
-
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/interpreter/amxface.c linux/drivers/acpi/interpreter/amxface.c
--- v2.4.5/linux/drivers/acpi/interpreter/amxface.c	Mon Jan 22 13:23:42 2001
+++ linux/drivers/acpi/interpreter/amxface.c	Wed Dec 31 16:00:00 1969
@@ -1,95 +0,0 @@
-
-/******************************************************************************
- *
- * Module Name: amxface - External interpreter interfaces
- *              $Revision: 24 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000, 2001 R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "acpi.h"
-#include "acinterp.h"
-
-
-#define _COMPONENT          INTERPRETER
-	 MODULE_NAME         ("amxface")
-
-
-/*
- * DEFINE_AML_GLOBALS is tested in amlcode.h
- * to determine whether certain global names should be "defined" or only
- * "declared" in the current compilation.  This enhances maintainability
- * by enabling a single header file to embody all knowledge of the names
- * in question.
- *
- * Exactly one module of any executable should #define DEFINE_GLOBALS
- * before #including the header files which use this convention.  The
- * names in question will be defined and initialized in that module,
- * and declared as extern in all other modules which #include those
- * header files.
- */
-
-#define DEFINE_AML_GLOBALS
-#include "amlcode.h"
-#include "acparser.h"
-#include "acnamesp.h"
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_aml_execute_method
- *
- * PARAMETERS:  Pcode               - Pointer to the pcode stream
- *              Pcode_length        - Length of pcode that comprises the method
- *              **Params            - List of parameters to pass to method,
- *                                    terminated by NULL. Params itself may be
- *                                    NULL if no parameters are being passed.
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Execute a control method
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_aml_execute_method (
-	ACPI_NAMESPACE_NODE     *method_node,
-	ACPI_OPERAND_OBJECT     **params,
-	ACPI_OPERAND_OBJECT     **return_obj_desc)
-{
-	ACPI_STATUS             status;
-
-
-	/*
-	 * The point here is to lock the interpreter and call the low
-	 * level execute.
-	 */
-
-	acpi_aml_enter_interpreter ();
-
-	status = acpi_psx_execute (method_node, params, return_obj_desc);
-
-	acpi_aml_exit_interpreter ();
-
-	return (status);
-}
-
-
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/namespace/Makefile linux/drivers/acpi/namespace/Makefile
--- v2.4.5/linux/drivers/acpi/namespace/Makefile	Fri Dec 29 14:07:21 2000
+++ linux/drivers/acpi/namespace/Makefile	Wed Jun 20 17:47:40 2001
@@ -1,16 +1,12 @@
 #
 # Makefile for all Linux ACPI interpreter subdirectories
+# EXCEPT for the ospm directory
 #
 
-O_TARGET := ../$(shell basename `pwd`).o
+O_TARGET := $(notdir $(CURDIR)).o
 
 obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c))
 
-EXTRA_CFLAGS += -I../include
-
 EXTRA_CFLAGS += $(ACPI_CFLAGS)
 
 include $(TOPDIR)/Rules.make
-
-clean:
-	$(RM) *.o 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/namespace/nsaccess.c linux/drivers/acpi/namespace/nsaccess.c
--- v2.4.5/linux/drivers/acpi/namespace/nsaccess.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/namespace/nsaccess.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: nsaccess - Top-level functions for accessing ACPI namespace
- *              $Revision: 119 $
+ *              $Revision: 126 $
  *
  ******************************************************************************/
 
@@ -31,7 +31,7 @@
 #include "acdispat.h"
 
 
-#define _COMPONENT          NAMESPACE
+#define _COMPONENT          ACPI_NAMESPACE
 	 MODULE_NAME         ("nsaccess")
 
 
@@ -58,7 +58,7 @@
 	ACPI_OPERAND_OBJECT     *obj_desc;
 
 
-	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 
 	/*
 	 * The global root ptr is initially NULL, so a non-NULL value indicates
@@ -82,8 +82,7 @@
 	/* Enter the pre-defined names in the name table */
 
 	for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) {
-		status = acpi_ns_lookup (NULL, init_val->name,
-				 (OBJECT_TYPE_INTERNAL) init_val->type,
+		status = acpi_ns_lookup (NULL, init_val->name, init_val->type,
 				 IMODE_LOAD_PASS2, NS_NO_UPSEARCH,
 				 NULL, &new_node);
 
@@ -100,9 +99,7 @@
 			 * descriptor for it.
 			 */
 
-			obj_desc = acpi_cm_create_internal_object (
-					  (OBJECT_TYPE_INTERNAL) init_val->type);
-
+			obj_desc = acpi_ut_create_internal_object (init_val->type);
 			if (!obj_desc) {
 				status = AE_NO_MEMORY;
 				goto unlock_and_exit;
@@ -114,8 +111,7 @@
 			 * used for initial values are implemented here.
 			 */
 
-			switch (init_val->type)
-			{
+			switch (init_val->type) {
 
 			case ACPI_TYPE_INTEGER:
 
@@ -126,18 +122,17 @@
 
 			case ACPI_TYPE_STRING:
 
-				obj_desc->string.length =
-						(u16) STRLEN (init_val->val);
+				obj_desc->string.length = STRLEN (init_val->val);
 
 				/*
 				 * Allocate a buffer for the string.  All
 				 * String.Pointers must be allocated buffers!
 				 * (makes deletion simpler)
 				 */
-				obj_desc->string.pointer = acpi_cm_allocate (
+				obj_desc->string.pointer = acpi_ut_allocate (
 						   (obj_desc->string.length + 1));
 				if (!obj_desc->string.pointer) {
-					acpi_cm_remove_reference (obj_desc);
+					acpi_ut_remove_reference (obj_desc);
 					status = AE_NO_MEMORY;
 					goto unlock_and_exit;
 				}
@@ -149,7 +144,7 @@
 			case ACPI_TYPE_MUTEX:
 
 				obj_desc->mutex.sync_level =
-						(u16) STRTOUL (init_val->val, NULL, 10);
+						 (u16) STRTOUL (init_val->val, NULL, 10);
 
 				if (STRCMP (init_val->name, "_GL_") == 0) {
 					/*
@@ -186,21 +181,20 @@
 			default:
 				REPORT_ERROR (("Unsupported initial type value %X\n",
 					init_val->type));
-				acpi_cm_remove_reference (obj_desc);
+				acpi_ut_remove_reference (obj_desc);
 				obj_desc = NULL;
 				continue;
 			}
 
 			/* Store pointer to value descriptor in the Node */
 
-			acpi_ns_attach_object (new_node, obj_desc,
-					   obj_desc->common.type);
+			acpi_ns_attach_object (new_node, obj_desc, obj_desc->common.type);
 		}
 	}
 
 
 unlock_and_exit:
-	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 	return (status);
 }
 
@@ -232,7 +226,7 @@
 acpi_ns_lookup (
 	ACPI_GENERIC_STATE      *scope_info,
 	NATIVE_CHAR             *pathname,
-	OBJECT_TYPE_INTERNAL    type,
+	ACPI_OBJECT_TYPE8       type,
 	OPERATING_MODE          interpreter_mode,
 	u32                     flags,
 	ACPI_WALK_STATE         *walk_state,
@@ -246,8 +240,8 @@
 	u32                     num_segments;
 	ACPI_NAME               simple_name;
 	u8                      null_name_path = FALSE;
-	OBJECT_TYPE_INTERNAL    type_to_check_for;
-	OBJECT_TYPE_INTERNAL    this_search_type;
+	ACPI_OBJECT_TYPE8       type_to_check_for;
+	ACPI_OBJECT_TYPE8       this_search_type;
 	u32                     local_flags = flags & ~NS_ERROR_IF_FOUND;
 
 
@@ -271,8 +265,7 @@
 	 */
 
 	if ((!scope_info) ||
-		(!scope_info->scope.node))
-	{
+		(!scope_info->scope.node)) {
 		prefix_node = acpi_gbl_root_node;
 	}
 	else {
@@ -281,14 +274,14 @@
 
 
 	/*
-	 * This check is explicitly split provide relax the Type_to_check_for
+	 * This check is explicitly split to relax the Type_to_check_for
 	 * conditions for Bank_field_defn. Originally, both Bank_field_defn and
 	 * Def_field_defn caused Type_to_check_for to be set to ACPI_TYPE_REGION,
 	 * but the Bank_field_defn may also check for a Field definition as well
 	 * as an Operation_region.
 	 */
 
-	if (INTERNAL_TYPE_DEF_FIELD_DEFN == type) {
+	if (INTERNAL_TYPE_FIELD_DEFN == type) {
 		/* Def_field_defn defines fields in a Region */
 
 		type_to_check_for = ACPI_TYPE_REGION;
@@ -376,7 +369,8 @@
 				if (!this_node) {
 					/* Current scope has no parent scope */
 
-					REPORT_ERROR (("Too many parent prefixes (^) - reached root\n"));
+					REPORT_ERROR (
+						("Too many parent prefixes (^) - reached root\n"));
 					return (AE_NOT_FOUND);
 				}
 
@@ -480,8 +474,7 @@
 			(type_to_check_for  != INTERNAL_TYPE_SCOPE)             &&
 			(type_to_check_for  != INTERNAL_TYPE_INDEX_FIELD_DEFN)  &&
 			(this_node->type    != ACPI_TYPE_ANY)                   &&
-			(this_node->type    != type_to_check_for))
-		{
+			(this_node->type    != type_to_check_for)) {
 			/* Complain about a type mismatch */
 
 			REPORT_WARNING (
@@ -500,8 +493,7 @@
 		}
 
 		if ((num_segments || acpi_ns_opens_scope (type)) &&
-			(this_node->child == NULL))
-		{
+			(this_node->child == NULL)) {
 			/*
 			 * More segments or the type implies enclosed scope,
 			 * and the next scope has not been allocated.
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/namespace/nsalloc.c linux/drivers/acpi/namespace/nsalloc.c
--- v2.4.5/linux/drivers/acpi/namespace/nsalloc.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/namespace/nsalloc.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: nsalloc - Namespace allocation and deletion utilities
- *              $Revision: 45 $
+ *              $Revision: 50 $
  *
  ******************************************************************************/
 
@@ -29,7 +29,7 @@
 #include "acinterp.h"
 
 
-#define _COMPONENT          NAMESPACE
+#define _COMPONENT          ACPI_NAMESPACE
 	 MODULE_NAME         ("nsalloc")
 
 
@@ -52,7 +52,7 @@
 	ACPI_NAMESPACE_NODE     *node;
 
 
-	node = acpi_cm_callocate (sizeof (ACPI_NAMESPACE_NODE));
+	node = acpi_ut_callocate (sizeof (ACPI_NAMESPACE_NODE));
 	if (!node) {
 		return (NULL);
 	}
@@ -119,7 +119,7 @@
 		acpi_ns_detach_object (node);
 	}
 
-	acpi_cm_free (node);
+	acpi_ut_free (node);
 
 
 	return;
@@ -146,7 +146,7 @@
 	ACPI_WALK_STATE         *walk_state,
 	ACPI_NAMESPACE_NODE     *parent_node,   /* Parent */
 	ACPI_NAMESPACE_NODE     *node,      /* New Child*/
-	OBJECT_TYPE_INTERNAL    type)
+	ACPI_OBJECT_TYPE8       type)
 {
 	u16                     owner_id = TABLE_ID_DSDT;
 	ACPI_NAMESPACE_NODE     *child_node;
@@ -195,27 +195,22 @@
 	 * add the region in order to define fields in it, we
 	 * have a forward reference.
 	 */
-
 	if ((ACPI_TYPE_ANY == type) ||
-		(INTERNAL_TYPE_DEF_FIELD_DEFN == type) ||
-		(INTERNAL_TYPE_BANK_FIELD_DEFN == type))
-	{
+		(INTERNAL_TYPE_FIELD_DEFN == type) ||
+		(INTERNAL_TYPE_BANK_FIELD_DEFN == type)) {
 		/*
 		 * We don't want to abort here, however!
 		 * We will fill in the actual type when the
 		 * real definition is found later.
 		 */
-
 	}
 
 	/*
 	 * The Def_field_defn and Bank_field_defn cases are actually
 	 * looking up the Region in which the field will be defined
 	 */
-
-	if ((INTERNAL_TYPE_DEF_FIELD_DEFN == type) ||
-		(INTERNAL_TYPE_BANK_FIELD_DEFN == type))
-	{
+	if ((INTERNAL_TYPE_FIELD_DEFN == type) ||
+		(INTERNAL_TYPE_BANK_FIELD_DEFN == type)) {
 		type = ACPI_TYPE_REGION;
 	}
 
@@ -225,11 +220,9 @@
 	 * being looked up.  Save any other value of Type as the type of
 	 * the entry.
 	 */
-
 	if ((type != INTERNAL_TYPE_SCOPE) &&
 		(type != INTERNAL_TYPE_DEF_ANY) &&
-		(type != INTERNAL_TYPE_INDEX_FIELD_DEFN))
-	{
+		(type != INTERNAL_TYPE_INDEX_FIELD_DEFN)) {
 		node->type = (u8) type;
 	}
 
@@ -237,7 +230,6 @@
 	 * Increment the reference count(s) of all parents up to
 	 * the root!
 	 */
-
 	while ((node = acpi_ns_get_parent_object (node)) != NULL) {
 		node->reference_count++;
 	}
@@ -282,8 +274,7 @@
 	/*
 	 * Deallocate all children at this level
 	 */
-	do
-	{
+	do {
 		/* Get the things we need */
 
 		next_node   = child_node->peer;
@@ -304,7 +295,7 @@
 			acpi_ns_detach_object (child_node);
 		}
 
-		acpi_cm_free (child_node);
+		acpi_ut_free (child_node);
 
 		/* And move on to the next child in the list */
 
@@ -373,7 +364,7 @@
 			obj_desc = acpi_ns_get_attached_object (child_node);
 			if (obj_desc) {
 				acpi_ns_detach_object (child_node);
-				acpi_cm_remove_reference (obj_desc);
+				acpi_ut_remove_reference (obj_desc);
 			}
 
 
@@ -519,7 +510,7 @@
 				obj_desc = acpi_ns_get_attached_object (child_node);
 				if (obj_desc) {
 					acpi_ns_detach_object (child_node);
-					acpi_cm_remove_reference (obj_desc);
+					acpi_ut_remove_reference (obj_desc);
 				}
 			}
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/namespace/nseval.c linux/drivers/acpi/namespace/nseval.c
--- v2.4.5/linux/drivers/acpi/namespace/nseval.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/namespace/nseval.c	Wed Jun 20 17:47:40 2001
@@ -2,7 +2,7 @@
  *
  * Module Name: nseval - Object evaluation interfaces -- includes control
  *                       method lookup and execution.
- *              $Revision: 83 $
+ *              $Revision: 91 $
  *
  ******************************************************************************/
 
@@ -32,7 +32,7 @@
 #include "acnamesp.h"
 
 
-#define _COMPONENT          NAMESPACE
+#define _COMPONENT          ACPI_NAMESPACE
 	 MODULE_NAME         ("nseval")
 
 
@@ -88,11 +88,11 @@
 
 	/* Get the prefix handle and Node */
 
-	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 
 	prefix_node = acpi_ns_convert_handle_to_entry (handle);
 	if (!prefix_node) {
-		acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+		acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 		status = AE_BAD_PARAMETER;
 		goto cleanup;
 	}
@@ -104,7 +104,7 @@
 			 IMODE_EXECUTE, NS_NO_UPSEARCH, NULL,
 			 &node);
 
-	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 
 	if (ACPI_FAILURE (status)) {
 		goto cleanup;
@@ -119,10 +119,7 @@
 
 cleanup:
 
-	/* Cleanup */
-
-	acpi_cm_free (internal_path);
-
+	acpi_ut_free (internal_path);
 	return (status);
 }
 
@@ -165,7 +162,7 @@
 		return (status);
 	}
 
-	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 
 	/* Lookup the name in the namespace */
 
@@ -173,7 +170,7 @@
 			 IMODE_EXECUTE, NS_NO_UPSEARCH, NULL,
 			 &node);
 
-	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 
 	if (ACPI_FAILURE (status)) {
 		goto cleanup;
@@ -192,7 +189,7 @@
 	/* Cleanup */
 
 	if (internal_path) {
-		acpi_cm_free (internal_path);
+		acpi_ut_free (internal_path);
 	}
 
 	return (status);
@@ -249,11 +246,11 @@
 
 	/* Get the prefix handle and Node */
 
-	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 
 	node = acpi_ns_convert_handle_to_entry (handle);
 	if (!node) {
-		acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+		acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 		return (AE_BAD_PARAMETER);
 	}
 
@@ -348,6 +345,15 @@
 	ACPI_OPERAND_OBJECT     *obj_desc;
 
 
+	/* Verify that there is a method associated with this object */
+
+	obj_desc = acpi_ns_get_attached_object (method_node);
+	if (!obj_desc) {
+		acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+		return (AE_ERROR);
+	}
+
+
 	/*
 	 * Unlock the namespace before execution.  This allows namespace access
 	 * via the external Acpi* interfaces while a method is being executed.
@@ -355,21 +361,12 @@
 	 * interpreter locks to ensure that no thread is using the portion of the
 	 * namespace that is being deleted.
 	 */
-
-	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
-
-	/* Verify that there is a method associated with this object */
-
-	obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) method_node);
-	if (!obj_desc) {
-		return (AE_ERROR);
-	}
-
+	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 
 	/*
 	 * Execute the method via the interpreter
 	 */
-	status = acpi_aml_execute_method (method_node, params, return_obj_desc);
+	status = acpi_ex_execute_method (method_node, params, return_obj_desc);
 
 	return (status);
 }
@@ -404,12 +401,11 @@
 	 */
 
 	if ((node->type == ACPI_TYPE_PROCESSOR) ||
-		(node->type == ACPI_TYPE_POWER))
-	{
+		(node->type == ACPI_TYPE_POWER)) {
 		/*
 		 *  Create a Reference object to contain the object
 		 */
-		obj_desc = acpi_cm_create_internal_object (node->type);
+		obj_desc = acpi_ut_create_internal_object (node->type);
 		if (!obj_desc) {
 		   status = AE_NO_MEMORY;
 		   goto unlock_and_exit;
@@ -434,6 +430,7 @@
 
 		MEMCPY (obj_desc, val_desc, sizeof (ACPI_OPERAND_OBJECT));
 		obj_desc->common.reference_count = 1;
+		acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 	}
 
 
@@ -444,7 +441,7 @@
 	else {
 		/* Create an Reference object to contain the object */
 
-		obj_desc = acpi_cm_create_internal_object (INTERNAL_TYPE_REFERENCE);
+		obj_desc = acpi_ut_create_internal_object (INTERNAL_TYPE_REFERENCE);
 		if (!obj_desc) {
 		   status = AE_NO_MEMORY;
 		   goto unlock_and_exit;
@@ -452,32 +449,37 @@
 
 		/* Construct a descriptor pointing to the name */
 
-		obj_desc->reference.op_code = (u8) AML_NAME_OP;
+		obj_desc->reference.opcode = (u8) AML_NAME_OP;
 		obj_desc->reference.object = (void *) node;
 
 		/*
-		 * Use Acpi_aml_resolve_to_value() to get the associated value.
-		 * The call to Acpi_aml_resolve_to_value causes
-		 * Obj_desc (allocated above) to always be deleted.
+		 * Use Resolve_to_value() to get the associated value. This call
+		 * always deletes Obj_desc (allocated above).
 		 *
 		 * NOTE: we can get away with passing in NULL for a walk state
 		 * because Obj_desc is guaranteed to not be a reference to either
 		 * a method local or a method argument
 		 *
-		 * Even though we do not technically need to use the interpreter
-		 * for this, we must enter it because we could hit an opregion.
-		 * The opregion access code assumes it is in the interpreter.
+		 * Even though we do not directly invoke the interpreter
+		 * for this, we must enter it because we could access an opregion.
+		 * The opregion access code assumes that the interpreter
+		 * is locked.
+		 *
+		 * We must release the namespace lock before entering the
+		 * intepreter.
 		 */
 
-		acpi_aml_enter_interpreter();
-
-		status = acpi_aml_resolve_to_value (&obj_desc, NULL);
+		acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+		status = acpi_ex_enter_interpreter ();
+		if (ACPI_SUCCESS (status)) {
+			status = acpi_ex_resolve_to_value (&obj_desc, NULL);
 
-		acpi_aml_exit_interpreter();
+			acpi_ex_exit_interpreter ();
+		}
 	}
 
 	/*
-	 * If Acpi_aml_resolve_to_value() succeeded, the return value was
+	 * If Acpi_ex_resolve_to_value() succeeded, the return value was
 	 * placed in Obj_desc.
 	 */
 
@@ -487,11 +489,15 @@
 		*return_obj_desc = obj_desc;
 	}
 
+	/* Namespace is unlocked */
+
+	return (status);
+
 
 unlock_and_exit:
 
 	/* Unlock the namespace */
 
-	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 	return (status);
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/namespace/nsinit.c linux/drivers/acpi/namespace/nsinit.c
--- v2.4.5/linux/drivers/acpi/namespace/nsinit.c	Tue Mar  6 19:44:36 2001
+++ linux/drivers/acpi/namespace/nsinit.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: nsinit - namespace initialization
- *              $Revision: 15 $
+ *              $Revision: 25 $
  *
  *****************************************************************************/
 
@@ -28,7 +28,7 @@
 #include "acnamesp.h"
 #include "acdispat.h"
 
-#define _COMPONENT          NAMESPACE
+#define _COMPONENT          ACPI_NAMESPACE
 	 MODULE_NAME         ("nsinit")
 
 
@@ -70,7 +70,7 @@
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ns_initialize_devices
  *
@@ -81,11 +81,10 @@
  * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices.
  *              This means running _INI on all present devices.
  *
- *              Also: Install PCI config space handler for all PCI root bridges.
- *              A PCI root bridge is found by searching for devices containing
- *              a HID with the value EISAID("PNP0A03")
+ *              Note: We install PCI config space handler on region access,
+ *              not here.
  *
- *****************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_ns_initialize_devices (
@@ -100,8 +99,8 @@
 	info.num_INI = 0;
 
 
-	status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
-			   FALSE, acpi_ns_init_one_device, &info, NULL);
+	status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+			  ACPI_UINT32_MAX, FALSE, acpi_ns_init_one_device, &info, NULL);
 
 
 
@@ -136,7 +135,7 @@
 	void                    *context,
 	void                    **return_value)
 {
-	OBJECT_TYPE_INTERNAL    type;
+	ACPI_OBJECT_TYPE8       type;
 	ACPI_STATUS             status;
 	ACPI_INIT_WALK_INFO     *info = (ACPI_INIT_WALK_INFO *) context;
 	ACPI_NAMESPACE_NODE     *node = (ACPI_NAMESPACE_NODE *) obj_handle;
@@ -154,8 +153,7 @@
 		return (AE_OK);
 	}
 
-	switch (type)
-	{
+	switch (type) {
 
 	case ACPI_TYPE_REGION:
 
@@ -171,7 +169,7 @@
 		break;
 
 
-	case ACPI_TYPE_FIELD_UNIT:
+	case ACPI_TYPE_BUFFER_FIELD:
 
 		info->field_count++;
 		if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
@@ -179,7 +177,7 @@
 		}
 
 		info->field_init++;
-		status = acpi_ds_get_field_unit_arguments (obj_desc);
+		status = acpi_ds_get_buffer_field_arguments (obj_desc);
 
 
 		break;
@@ -196,11 +194,11 @@
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ns_init_one_device
  *
- * PARAMETERS:  WALK_CALLBACK
+ * PARAMETERS:  ACPI_WALK_CALLBACK
  *
  * RETURN:      ACPI_STATUS
  *
@@ -208,7 +206,7 @@
  *              to initialize each device. It determines if the device is
  *              present, and if so, calls _INI.
  *
- *****************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_ns_init_one_device (
@@ -226,21 +224,21 @@
 
 	info->device_count++;
 
-	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 
 	node = acpi_ns_convert_handle_to_entry (obj_handle);
 	if (!node) {
-		acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+		acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 		return (AE_BAD_PARAMETER);
 	}
 
-	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 
 	/*
 	 * Run _STA to determine if we can run _INI on the device.
 	 */
 
-	status = acpi_cm_execute_STA (node, &flags);
+	status = acpi_ut_execute_STA (node, &flags);
 	if (ACPI_FAILURE (status)) {
 		/* Ignore error and move on to next device */
 
@@ -251,6 +249,7 @@
 
 	if (!(flags & 0x01)) {
 		/* don't look at children of a not present device */
+
 		return(AE_CTRL_DEPTH);
 	}
 
@@ -258,10 +257,10 @@
 	/*
 	 * The device is present. Run _INI.
 	 */
-
 	status = acpi_ns_evaluate_relative (obj_handle, "_INI", NULL, NULL);
 	if (AE_NOT_FOUND == status) {
 		/* No _INI means device requires no initialization */
+
 		status = AE_OK;
 	}
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/namespace/nsload.c linux/drivers/acpi/namespace/nsload.c
--- v2.4.5/linux/drivers/acpi/namespace/nsload.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/namespace/nsload.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: nsload - namespace loading/expanding/contracting procedures
- *              $Revision: 35 $
+ *              $Revision: 41 $
  *
  *****************************************************************************/
 
@@ -33,11 +33,11 @@
 #include "acdebug.h"
 
 
-#define _COMPONENT          NAMESPACE
+#define _COMPONENT          ACPI_NAMESPACE
 	 MODULE_NAME         ("nsload")
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_load_namespace
  *
@@ -107,8 +107,7 @@
 	ACPI_STATUS             status;
 
 
-	switch (pass_number)
-	{
+	switch (pass_number) {
 	case 1:
 		descending_callback = acpi_ds_load1_begin_op;
 		ascending_callback = acpi_ds_load1_end_op;
@@ -140,16 +139,13 @@
 
 	/* Pass 1:  Parse everything except control method bodies */
 
-	status = acpi_ps_parse_aml (parse_root,
-			 table_desc->aml_pointer,
+	status = acpi_ps_parse_aml (parse_root, table_desc->aml_pointer,
 			 table_desc->aml_length,
 			 ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE,
-			 NULL, NULL, NULL,
-			 descending_callback,
+			 NULL, NULL, NULL, descending_callback,
 			 ascending_callback);
 
 	acpi_ps_delete_parse_tree (parse_root);
-
 	return (status);
 }
 
@@ -211,7 +207,7 @@
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ns_load_table
  *
@@ -222,7 +218,7 @@
  *
  * DESCRIPTION: Load one ACPI table into the namespace
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_ns_load_table (
@@ -252,9 +248,9 @@
 	 * because we don't know how many arguments to parse next!
 	 */
 
-	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 	status = acpi_ns_parse_table (table_desc, node->child);
-	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 
 	if (ACPI_FAILURE (status)) {
 		return (status);
@@ -273,7 +269,7 @@
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ns_load_table_by_type
  *
@@ -285,7 +281,7 @@
  *              of the given type are loaded.  The mechanism allows this
  *              routine to be called repeatedly.
  *
- *****************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_ns_load_table_by_type (
@@ -293,11 +289,10 @@
 {
 	u32                     i;
 	ACPI_STATUS             status = AE_OK;
-	ACPI_TABLE_HEADER       *table_ptr;
 	ACPI_TABLE_DESC         *table_desc;
 
 
-	acpi_cm_acquire_mutex (ACPI_MTX_TABLES);
+	acpi_ut_acquire_mutex (ACPI_MTX_TABLES);
 
 
 	/*
@@ -305,8 +300,7 @@
 	 * DSDT (one), SSDT/PSDT (multiple)
 	 */
 
-	switch (table_type)
-	{
+	switch (table_type) {
 
 	case ACPI_TABLE_DSDT:
 
@@ -338,16 +332,13 @@
 
 		table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_SSDT];
 		for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_SSDT].count; i++) {
-			table_ptr = table_desc->pointer;
-
 			/*
 			 * Only attempt to load table if it is not
 			 * already loaded!
 			 */
 
 			if (!table_desc->loaded_into_namespace) {
-				status = acpi_ns_load_table (table_desc,
-						  acpi_gbl_root_node);
+				status = acpi_ns_load_table (table_desc, acpi_gbl_root_node);
 				if (ACPI_FAILURE (status)) {
 					break;
 				}
@@ -357,7 +348,6 @@
 
 			table_desc = table_desc->next;
 		}
-
 		break;
 
 
@@ -370,13 +360,10 @@
 		table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_PSDT];
 
 		for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_PSDT].count; i++) {
-			table_ptr = table_desc->pointer;
-
 			/* Only attempt to load table if it is not already loaded! */
 
 			if (!table_desc->loaded_into_namespace) {
-				status = acpi_ns_load_table (table_desc,
-						  acpi_gbl_root_node);
+				status = acpi_ns_load_table (table_desc, acpi_gbl_root_node);
 				if (ACPI_FAILURE (status)) {
 					break;
 				}
@@ -392,19 +379,20 @@
 
 	default:
 		status = AE_SUPPORT;
+		break;
 	}
 
 
 unlock_and_exit:
 
-	acpi_cm_release_mutex (ACPI_MTX_TABLES);
+	acpi_ut_release_mutex (ACPI_MTX_TABLES);
 
 	return (status);
 
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ns_delete_subtree
  *
@@ -432,9 +420,9 @@
 	u32                     level;
 
 
-	parent_handle   = start_handle;
-	child_handle    = 0;
-	level           = 1;
+	parent_handle = start_handle;
+	child_handle = 0;
+	level        = 1;
 
 	/*
 	 * Traverse the tree of objects until we bubble back up
@@ -445,8 +433,7 @@
 		/* Attempt to get the next object in this scope */
 
 		status = acpi_get_next_object (ACPI_TYPE_ANY, parent_handle,
-				  child_handle,
-				  &next_child_handle);
+				  child_handle, &next_child_handle);
 
 		child_handle = next_child_handle;
 
@@ -456,18 +443,16 @@
 		if (ACPI_SUCCESS (status)) {
 			/* Check if this object has any children */
 
-			if (ACPI_SUCCESS (acpi_get_next_object (ACPI_TYPE_ANY,
-					 child_handle, 0,
-					 &dummy)))
-			{
+			if (ACPI_SUCCESS (acpi_get_next_object (ACPI_TYPE_ANY, child_handle,
+					 0, &dummy))) {
 				/*
 				 * There is at least one child of this object,
 				 * visit the object
 				 */
 
 				level++;
-				parent_handle   = child_handle;
-				child_handle    = 0;
+				parent_handle = child_handle;
+				child_handle = 0;
 			}
 		}
 
@@ -491,12 +476,11 @@
 
 	acpi_ns_delete_node (child_handle);
 
-
 	return (AE_OK);
 }
 
 
-/****************************************************************************
+/*******************************************************************************
  *
  *  FUNCTION:       Acpi_ns_unload_name_space
  *
@@ -508,7 +492,7 @@
  *                  event.  Deletes an entire subtree starting from (and
  *                  including) the given handle.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_ns_unload_namespace (
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/namespace/nsnames.c linux/drivers/acpi/namespace/nsnames.c
--- v2.4.5/linux/drivers/acpi/namespace/nsnames.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/namespace/nsnames.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: nsnames - Name manipulation and search
- *              $Revision: 54 $
+ *              $Revision: 59 $
  *
  ******************************************************************************/
 
@@ -30,7 +30,7 @@
 #include "acnamesp.h"
 
 
-#define _COMPONENT          NAMESPACE
+#define _COMPONENT          ACPI_NAMESPACE
 	 MODULE_NAME         ("nsnames")
 
 
@@ -84,7 +84,7 @@
 
 	/* Allocate a buffer to be returned to caller */
 
-	name_buffer = acpi_cm_callocate (size + 1);
+	name_buffer = acpi_ut_callocate (size + 1);
 	if (!name_buffer) {
 		REPORT_ERROR (("Ns_get_table_pathname: allocation failure\n"));
 		return (NULL);
@@ -95,8 +95,7 @@
 
 	name_buffer[size] = '\0';
 	while ((size > ACPI_NAME_SIZE) &&
-		acpi_ns_get_parent_object (child_node))
-	{
+		acpi_ns_get_parent_object (child_node)) {
 		size -= ACPI_NAME_SIZE;
 		name = acpi_ns_find_parent_name (child_node);
 
@@ -138,8 +137,7 @@
 	 */
 	for (size = 0, next_node = node;
 		  acpi_ns_get_parent_object (next_node);
-		  next_node = acpi_ns_get_parent_object (next_node))
-	{
+		  next_node = acpi_ns_get_parent_object (next_node)) {
 		size += PATH_SEGMENT_LENGTH;
 	}
 
@@ -184,7 +182,7 @@
 	u32                     size;
 
 
-	if (!acpi_gbl_root_node || !target_handle) {
+	if (!acpi_gbl_root_node) {
 		/*
 		 * If the name space has not been initialized,
 		 * this function should not have been called.
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/namespace/nsobject.c linux/drivers/acpi/namespace/nsobject.c
--- v2.4.5/linux/drivers/acpi/namespace/nsobject.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/namespace/nsobject.c	Wed Jun 20 17:47:40 2001
@@ -2,7 +2,7 @@
  *
  * Module Name: nsobject - Utilities for objects attached to namespace
  *                         table entries
- *              $Revision: 49 $
+ *              $Revision: 55 $
  *
  ******************************************************************************/
 
@@ -32,7 +32,7 @@
 #include "actables.h"
 
 
-#define _COMPONENT          NAMESPACE
+#define _COMPONENT          ACPI_NAMESPACE
 	 MODULE_NAME         ("nsobject")
 
 
@@ -57,11 +57,11 @@
 acpi_ns_attach_object (
 	ACPI_NAMESPACE_NODE     *node,
 	ACPI_OPERAND_OBJECT     *object,
-	OBJECT_TYPE_INTERNAL    type)
+	ACPI_OBJECT_TYPE8       type)
 {
 	ACPI_OPERAND_OBJECT     *obj_desc;
 	ACPI_OPERAND_OBJECT     *previous_obj_desc;
-	OBJECT_TYPE_INTERNAL    obj_type = ACPI_TYPE_ANY;
+	ACPI_OBJECT_TYPE8      obj_type = ACPI_TYPE_ANY;
 	u8                      flags;
 	u16                     opcode;
 
@@ -124,8 +124,7 @@
 	 */
 
 	else if (VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_NAMED) &&
-			((ACPI_NAMESPACE_NODE *) object)->object)
-	{
+			((ACPI_NAMESPACE_NODE *) object)->object) {
 		/*
 		 * Value passed is a name handle and that name has a
 		 * non-null value.  Use that name's value and type.
@@ -183,10 +182,9 @@
 
 			MOVE_UNALIGNED16_TO_16 (&opcode, object);
 
-			/* Check for a recognized Op_code */
+			/* Check for a recognized Opcode */
 
-			switch ((u8) opcode)
-			{
+			switch ((u8) opcode) {
 
 			case AML_OP_PREFIX:
 
@@ -257,7 +255,7 @@
 	 * (if it is an internal object)
 	 */
 
-	acpi_cm_add_reference (obj_desc);
+	acpi_ut_add_reference (obj_desc);
 
 	/* Save the existing object (if any) for deletion later */
 
@@ -277,11 +275,11 @@
 	if (previous_obj_desc) {
 		/* One for the attach to the Node */
 
-		acpi_cm_remove_reference (previous_obj_desc);
+		acpi_ut_remove_reference (previous_obj_desc);
 
 		/* Now delete */
 
-		acpi_cm_remove_reference (previous_obj_desc);
+		acpi_ut_remove_reference (previous_obj_desc);
 	}
 
 	return (AE_OK);
@@ -321,14 +319,14 @@
 	/* Found a valid value */
 
 	/*
-	 * Not every value is an object allocated via Acpi_cm_callocate,
+	 * Not every value is an object allocated via Acpi_ut_callocate,
 	 * - must check
 	 */
 
 	if (!acpi_tb_system_table_pointer (obj_desc)) {
 		/* Attempt to delete the object (and all subobjects) */
 
-		acpi_cm_remove_reference (obj_desc);
+		acpi_ut_remove_reference (obj_desc);
 	}
 
 	return;
@@ -339,7 +337,7 @@
  *
  * FUNCTION:    Acpi_ns_get_attached_object
  *
- * PARAMETERS:  Handle              - Parent Node to be examined
+ * PARAMETERS:  Node             - Parent Node to be examined
  *
  * RETURN:      Current value of the object field from the Node whose
  *              handle is passed
@@ -348,16 +346,16 @@
 
 void *
 acpi_ns_get_attached_object (
-	ACPI_HANDLE             handle)
+	ACPI_NAMESPACE_NODE     *node)
 {
 
-	if (!handle) {
+	if (!node) {
 		/* handle invalid */
 
 		return (NULL);
 	}
 
-	return (((ACPI_NAMESPACE_NODE *) handle)->object);
+	return (node->object);
 }
 
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/namespace/nssearch.c linux/drivers/acpi/namespace/nssearch.c
--- v2.4.5/linux/drivers/acpi/namespace/nssearch.c	Mon Jan 29 10:15:59 2001
+++ linux/drivers/acpi/namespace/nssearch.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: nssearch - Namespace search
- *              $Revision: 64 $
+ *              $Revision: 70 $
  *
  ******************************************************************************/
 
@@ -30,7 +30,7 @@
 #include "acnamesp.h"
 
 
-#define _COMPONENT          NAMESPACE
+#define _COMPONENT          ACPI_NAMESPACE
 	 MODULE_NAME         ("nssearch")
 
 
@@ -39,9 +39,9 @@
  * FUNCTION:    Acpi_ns_search_node
  *
  * PARAMETERS:  *Target_name        - Ascii ACPI name to search for
- *              *Node           - Starting table where search will begin
+ *              *Node               - Starting table where search will begin
  *              Type                - Object type to match
- *              **Return_node   - Where the matched Named obj is returned
+ *              **Return_node       - Where the matched Named obj is returned
  *
  * RETURN:      Status
  *
@@ -64,7 +64,7 @@
 acpi_ns_search_node (
 	u32                     target_name,
 	ACPI_NAMESPACE_NODE     *node,
-	OBJECT_TYPE_INTERNAL    type,
+	ACPI_OBJECT_TYPE8       type,
 	ACPI_NAMESPACE_NODE     **return_node)
 {
 	ACPI_NAMESPACE_NODE     *next_node;
@@ -81,36 +81,29 @@
 
 		if (next_node->name == target_name) {
 			/*
-			 * Found matching entry.  Capture type if
-			 * appropriate before returning the entry.
+			 * Found matching entry.  Capture the type if appropriate, before
+			 * returning the entry.
+			 *
+			 * The Def_field_defn and Bank_field_defn cases are actually looking up
+			 * the Region in which the field will be defined
 			 */
 
-			/*
-			 * The Def_field_defn and Bank_field_defn cases
-			 * are actually looking up the Region in which
-			 * the field will be defined
-			 */
-
-			if ((INTERNAL_TYPE_DEF_FIELD_DEFN == type) ||
-				(INTERNAL_TYPE_BANK_FIELD_DEFN == type))
-			{
+			if ((INTERNAL_TYPE_FIELD_DEFN == type) ||
+				(INTERNAL_TYPE_BANK_FIELD_DEFN == type)) {
 				type = ACPI_TYPE_REGION;
 			}
 
 			/*
-			 * Scope, Def_any, and Index_field_defn are bogus
-			 * "types" which do not actually have anything
-			 * to do with the type of the name being looked
-			 * up.  For any other value of Type, if the type
-			 * stored in the entry is Any (i.e. unknown),
-			 * save the actual type.
+			 * Scope, Def_any, and Index_field_defn are bogus "types" which do not
+			 * actually have anything to do with the type of the name being
+			 * looked up.  For any other value of Type, if the type stored in
+			 * the entry is Any (i.e. unknown), save the actual type.
 			 */
 
 			if (type != INTERNAL_TYPE_SCOPE &&
 				type != INTERNAL_TYPE_DEF_ANY &&
 				type != INTERNAL_TYPE_INDEX_FIELD_DEFN &&
-				next_node->type == ACPI_TYPE_ANY)
-			{
+				next_node->type == ACPI_TYPE_ANY) {
 				next_node->type = (u8) type;
 			}
 
@@ -137,7 +130,6 @@
 
 	/* Searched entire table, not found */
 
-
 	return (AE_NOT_FOUND);
 }
 
@@ -147,9 +139,9 @@
  * FUNCTION:    Acpi_ns_search_parent_tree
  *
  * PARAMETERS:  *Target_name        - Ascii ACPI name to search for
- *              *Node           - Starting table where search will begin
+ *              *Node               - Starting table where search will begin
  *              Type                - Object type to match
- *              **Return_node   - Where the matched Named Obj is returned
+ *              **Return_node       - Where the matched Named Obj is returned
  *
  * RETURN:      Status
  *
@@ -171,7 +163,7 @@
 acpi_ns_search_parent_tree (
 	u32                     target_name,
 	ACPI_NAMESPACE_NODE     *node,
-	OBJECT_TYPE_INTERNAL    type,
+	ACPI_OBJECT_TYPE8       type,
 	ACPI_NAMESPACE_NODE     **return_node)
 {
 	ACPI_STATUS             status;
@@ -184,9 +176,8 @@
 	 * If there is no parent (at the root) or type is "local", we won't be
 	 * searching the parent tree.
 	 */
-	if ((acpi_ns_local (type))  ||
-		(!parent_node))
-	{
+	if ((acpi_ns_local (type)) ||
+		(!parent_node)) {
 
 
 		return (AE_NOT_FOUND);
@@ -199,7 +190,6 @@
 	 * Search parents until found the target or we have backed up to
 	 * the root
 	 */
-
 	while (parent_node) {
 		/* Search parent scope */
 		/* TBD: [Investigate] Why ACPI_TYPE_ANY? */
@@ -232,12 +222,12 @@
  *
  * PARAMETERS:  Target_name         - Ascii ACPI name to search for (4 chars)
  *              Walk_state          - Current state of the walk
- *              *Node           - Starting table where search will begin
+ *              *Node               - Starting table where search will begin
  *              Interpreter_mode    - Add names only in MODE_Load_pass_x.
  *                                    Otherwise,search only.
  *              Type                - Object type to match
  *              Flags               - Flags describing the search restrictions
- *              **Return_node   - Where the Node is returned
+ *              **Return_node       - Where the Node is returned
  *
  * RETURN:      Status
  *
@@ -257,7 +247,7 @@
 	ACPI_WALK_STATE         *walk_state,
 	ACPI_NAMESPACE_NODE     *node,
 	OPERATING_MODE          interpreter_mode,
-	OBJECT_TYPE_INTERNAL    type,
+	ACPI_OBJECT_TYPE8       type,
 	u32                     flags,
 	ACPI_NAMESPACE_NODE     **return_node)
 {
@@ -275,7 +265,7 @@
 
 	/* Name must consist of printable characters */
 
-	if (!acpi_cm_valid_acpi_name (target_name)) {
+	if (!acpi_ut_valid_acpi_name (target_name)) {
 		REPORT_ERROR (("Ns_search_and_enter: Bad character in ACPI Name\n"));
 		return (AE_BAD_CHARACTER);
 	}
@@ -284,16 +274,14 @@
 	/* Try to find the name in the table specified by the caller */
 
 	*return_node = ENTRY_NOT_FOUND;
-	status = acpi_ns_search_node (target_name, node,
-			   type, return_node);
+	status = acpi_ns_search_node (target_name, node, type, return_node);
 	if (status != AE_NOT_FOUND) {
 		/*
-		 * If we found it AND the request specifies that a
-		 * find is an error, return the error
+		 * If we found it AND the request specifies that a find is an error,
+		 * return the error
 		 */
 		if ((status == AE_OK) &&
-			(flags & NS_ERROR_IF_FOUND))
-		{
+			(flags & NS_ERROR_IF_FOUND)) {
 			status = AE_EXIST;
 		}
 
@@ -316,8 +304,7 @@
 	 */
 
 	if ((interpreter_mode != IMODE_LOAD_PASS1) &&
-		(flags & NS_SEARCH_PARENT))
-	{
+		(flags & NS_SEARCH_PARENT)) {
 		/*
 		 * Not found in table - search parent tree according
 		 * to ACPI specification
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/namespace/nsutils.c linux/drivers/acpi/namespace/nsutils.c
--- v2.4.5/linux/drivers/acpi/namespace/nsutils.c	Mon Jan 29 10:15:59 2001
+++ linux/drivers/acpi/namespace/nsutils.c	Wed Jun 20 17:47:40 2001
@@ -2,7 +2,7 @@
  *
  * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
  *                        parents and siblings and Scope manipulation
- *              $Revision: 77 $
+ *              $Revision: 83 $
  *
  *****************************************************************************/
 
@@ -31,11 +31,11 @@
 #include "amlcode.h"
 #include "actables.h"
 
-#define _COMPONENT          NAMESPACE
+#define _COMPONENT          ACPI_NAMESPACE
 	 MODULE_NAME         ("nsutils")
 
 
-/****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ns_valid_root_prefix
  *
@@ -45,7 +45,7 @@
  *
  * DESCRIPTION: Check if a character is a valid ACPI Root prefix
  *
- ***************************************************************************/
+ ******************************************************************************/
 
 u8
 acpi_ns_valid_root_prefix (
@@ -56,7 +56,7 @@
 }
 
 
-/****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ns_valid_path_separator
  *
@@ -66,7 +66,7 @@
  *
  * DESCRIPTION: Check if a character is a valid ACPI path separator
  *
- ***************************************************************************/
+ ******************************************************************************/
 
 u8
 acpi_ns_valid_path_separator (
@@ -77,7 +77,7 @@
 }
 
 
-/****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ns_get_type
  *
@@ -85,23 +85,23 @@
  *
  * RETURN:      Type field from Node whose handle is passed
  *
- ***************************************************************************/
+ ******************************************************************************/
 
-OBJECT_TYPE_INTERNAL
+ACPI_OBJECT_TYPE8
 acpi_ns_get_type (
-	ACPI_HANDLE             handle)
+	ACPI_NAMESPACE_NODE     *node)
 {
 
-	if (!handle) {
-		REPORT_WARNING (("Ns_get_type: Null handle\n"));
+	if (!node) {
+		REPORT_WARNING (("Ns_get_type: Null Node ptr"));
 		return (ACPI_TYPE_ANY);
 	}
 
-	return (((ACPI_NAMESPACE_NODE *) handle)->type);
+	return (node->type);
 }
 
 
-/****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ns_local
  *
@@ -110,14 +110,14 @@
  * RETURN:      LOCAL if names must be found locally in objects of the
  *              passed type, 0 if enclosing scopes should be searched
  *
- ***************************************************************************/
+ ******************************************************************************/
 
 u32
 acpi_ns_local (
-	OBJECT_TYPE_INTERNAL    type)
+	ACPI_OBJECT_TYPE8       type)
 {
 
-	if (!acpi_cm_valid_object_type (type)) {
+	if (!acpi_ut_valid_object_type (type)) {
 		/* Type code out of range  */
 
 		REPORT_WARNING (("Ns_local: Invalid Object Type\n"));
@@ -128,41 +128,32 @@
 }
 
 
-/****************************************************************************
+/*******************************************************************************
  *
- * FUNCTION:    Acpi_ns_internalize_name
+ * FUNCTION:    Acpi_ns_get_internal_name_length
  *
- * PARAMETERS:  *External_name            - External representation of name
- *              **Converted Name        - Where to return the resulting
- *                                        internal represention of the name
+ * PARAMETERS:  Info            - Info struct initialized with the
+ *                                external name pointer.
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0")
- *              to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
+ * DESCRIPTION: Calculate the length of the internal (AML) namestring
+ *              corresponding to the external (ASL) namestring.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
-acpi_ns_internalize_name (
-	NATIVE_CHAR             *external_name,
-	NATIVE_CHAR             **converted_name)
+acpi_ns_get_internal_name_length (
+	ACPI_NAMESTRING_INFO    *info)
 {
-	NATIVE_CHAR             *result = NULL;
-	NATIVE_CHAR             *internal_name;
-	u32                     num_segments = 0;
-	u8                      fully_qualified = FALSE;
+	NATIVE_CHAR             *next_external_char;
 	u32                     i;
-	u32                     num_carats = 0;
 
 
-	if ((!external_name)     ||
-		(*external_name == 0) ||
-		(!converted_name))
-	{
-		return (AE_BAD_PARAMETER);
-	}
-
+	next_external_char = info->external_name;
+	info->num_carats = 0;
+	info->num_segments = 0;
+	info->fully_qualified = FALSE;
 
 	/*
 	 * For the internal name, the required length is 4 bytes
@@ -173,10 +164,9 @@
 	 * strlen() + 1 covers the first Name_seg, which has no
 	 * path separator
 	 */
-
-	if (acpi_ns_valid_root_prefix (external_name[0])) {
-		fully_qualified = TRUE;
-		external_name++;
+	if (acpi_ns_valid_root_prefix (next_external_char[0])) {
+		info->fully_qualified = TRUE;
+		next_external_char++;
 	}
 
 	else {
@@ -184,9 +174,9 @@
 		 * Handle Carat prefixes
 		 */
 
-		while (*external_name == '^') {
-			num_carats++;
-			external_name++;
+		while (*next_external_char == '^') {
+			info->num_carats++;
+			next_external_char++;
 		}
 	}
 
@@ -196,28 +186,51 @@
 	 * with one segment since the segment count is (# separators)
 	 * + 1, and zero separators is ok.
 	 */
-
-	if (*external_name) {
-		num_segments = 1;
-		for (i = 0; external_name[i]; i++) {
-			if (acpi_ns_valid_path_separator (external_name[i])) {
-				num_segments++;
+	if (*next_external_char) {
+		info->num_segments = 1;
+		for (i = 0; next_external_char[i]; i++) {
+			if (acpi_ns_valid_path_separator (next_external_char[i])) {
+				info->num_segments++;
 			}
 		}
 	}
 
+	info->length = (ACPI_NAME_SIZE * info->num_segments) +
+			  4 + info->num_carats;
 
-	/* We need a segment to store the internal version of the name */
+	info->next_external_char = next_external_char;
 
-	internal_name = acpi_cm_callocate ((ACPI_NAME_SIZE * num_segments) + 4 + num_carats);
-	if (!internal_name) {
-		return (AE_NO_MEMORY);
-	}
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ns_build_internal_name
+ *
+ * PARAMETERS:  Info            - Info struct fully initialized
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Construct the internal (AML) namestring
+ *              corresponding to the external (ASL) namestring.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ns_build_internal_name (
+	ACPI_NAMESTRING_INFO    *info)
+{
+	u32                     num_segments = info->num_segments;
+	NATIVE_CHAR             *internal_name = info->internal_name;
+	NATIVE_CHAR             *external_name = info->next_external_char;
+	NATIVE_CHAR             *result = NULL;
+	u32                     i;
 
 
 	/* Setup the correct prefixes, counts, and pointers */
 
-	if (fully_qualified) {
+	if (info->fully_qualified) {
 		internal_name[0] = '\\';
 
 		if (num_segments <= 1) {
@@ -232,7 +245,6 @@
 			internal_name[2] = (char) num_segments;
 			result = &internal_name[3];
 		}
-
 	}
 
 	else {
@@ -240,10 +252,9 @@
 		 * Not fully qualified.
 		 * Handle Carats first, then append the name segments
 		 */
-
 		i = 0;
-		if (num_carats) {
-			for (i = 0; i < num_carats; i++) {
+		if (info->num_carats) {
+			for (i = 0; i < info->num_carats; i++) {
 				internal_name[i] = '^';
 			}
 		}
@@ -270,31 +281,24 @@
 	for (; num_segments; num_segments--) {
 		for (i = 0; i < ACPI_NAME_SIZE; i++) {
 			if (acpi_ns_valid_path_separator (*external_name) ||
-			   (*external_name == 0))
-			{
-				/*
-				 * Pad the segment with underscore(s) if
-				 * segment is short
-				 */
+			   (*external_name == 0)) {
+				/* Pad the segment with underscore(s) if segment is short */
 
 				result[i] = '_';
 			}
 
 			else {
-				/* Convert s8 to uppercase and save it */
+				/* Convert the character to uppercase and save it */
 
 				result[i] = (char) TOUPPER (*external_name);
 				external_name++;
 			}
-
 		}
 
 		/* Now we must have a path separator, or the pathname is bad */
 
 		if (!acpi_ns_valid_path_separator (*external_name) &&
-			(*external_name != 0))
-		{
-			acpi_cm_free (internal_name);
+			(*external_name != 0)) {
 			return (AE_BAD_PARAMETER);
 		}
 
@@ -305,32 +309,87 @@
 	}
 
 
-	/* Return the completed name */
+	/* Terminate the string */
 
-	/* Terminate the string! */
 	*result = 0;
-	*converted_name = internal_name;
 
 
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ns_internalize_name
+ *
+ * PARAMETERS:  *External_name          - External representation of name
+ *              **Converted Name        - Where to return the resulting
+ *                                        internal represention of the name
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0")
+ *              to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
+ *
+ *******************************************************************************/
+
+ACPI_STATUS
+acpi_ns_internalize_name (
+	NATIVE_CHAR             *external_name,
+	NATIVE_CHAR             **converted_name)
+{
+	NATIVE_CHAR             *internal_name;
+	ACPI_NAMESTRING_INFO    info;
+	ACPI_STATUS             status;
+
+
+	if ((!external_name)     ||
+		(*external_name == 0) ||
+		(!converted_name)) {
+		return (AE_BAD_PARAMETER);
+	}
+
+
+	/* Get the length of the new internal name */
+
+	info.external_name = external_name;
+	acpi_ns_get_internal_name_length (&info);
+
+	/* We need a segment to store the internal  name */
+
+	internal_name = acpi_ut_callocate (info.length);
+	if (!internal_name) {
+		return (AE_NO_MEMORY);
+	}
+
+	/* Build the name */
 
+	info.internal_name = internal_name;
+	status = acpi_ns_build_internal_name (&info);
+	if (ACPI_FAILURE (status)) {
+		acpi_ut_free (internal_name);
+		return (status);
+	}
+
+	*converted_name = internal_name;
 	return (AE_OK);
 }
 
 
-/****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ns_externalize_name
  *
  * PARAMETERS:  *Internal_name         - Internal representation of name
  *              **Converted_name       - Where to return the resulting
- *                                        external representation of name
+ *                                       external representation of name
  *
  * RETURN:      Status
  *
  * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
  *              to its external form (e.g. "\_PR_.CPU0")
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_ns_externalize_name (
@@ -349,8 +408,7 @@
 	if (!internal_name_length   ||
 		!internal_name          ||
 		!converted_name_length  ||
-		!converted_name)
-	{
+		!converted_name) {
 		return (AE_BAD_PARAMETER);
 	}
 
@@ -358,8 +416,7 @@
 	/*
 	 * Check for a prefix (one '\' | one or more '^').
 	 */
-	switch (internal_name[0])
-	{
+	switch (internal_name[0]) {
 	case '\\':
 		prefix_length = 1;
 		break;
@@ -383,8 +440,7 @@
 	 * 4-byte elements.
 	 */
 	if (prefix_length < internal_name_length) {
-		switch (internal_name[prefix_length])
-		{
+		switch (internal_name[prefix_length]) {
 
 		/* <count> 4-byte names */
 
@@ -440,7 +496,7 @@
 	 * Build Converted_name...
 	 */
 
-	(*converted_name) = acpi_cm_callocate (*converted_name_length);
+	(*converted_name) = acpi_ut_callocate (*converted_name_length);
 	if (!(*converted_name)) {
 		return (AE_NO_MEMORY);
 	}
@@ -468,7 +524,7 @@
 }
 
 
-/****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ns_convert_handle_to_entry
  *
@@ -478,7 +534,7 @@
  *
  * DESCRIPTION: Convert a namespace handle to a real Node
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 ACPI_NAMESPACE_NODE *
 acpi_ns_convert_handle_to_entry (
@@ -490,7 +546,6 @@
 	 * TBD: [Future] Real integer handles allow for more verification
 	 * and keep all pointers within this subsystem!
 	 */
-
 	if (!handle) {
 		return (NULL);
 	}
@@ -510,7 +565,7 @@
 }
 
 
-/****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ns_convert_entry_to_handle
  *
@@ -520,7 +575,7 @@
  *
  * DESCRIPTION: Convert a real Node to a namespace handle
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 ACPI_HANDLE
 acpi_ns_convert_entry_to_handle (
@@ -533,17 +588,18 @@
 	 * TBD: [Future] Real integer handles allow for more verification
 	 * and keep all pointers within this subsystem!
 	 */
-
 	return ((ACPI_HANDLE) node);
 
 
 /* ---------------------------------------------------
 
-	if (!Node) {
+	if (!Node)
+	{
 		return (NULL);
 	}
 
-	if (Node == Acpi_gbl_Root_node) {
+	if (Node == Acpi_gbl_Root_node)
+	{
 		return (ACPI_ROOT_OBJECT);
 	}
 
@@ -553,7 +609,7 @@
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ns_terminate
  *
@@ -576,12 +632,10 @@
 
 	/*
 	 * 1) Free the entire namespace -- all objects, tables, and stacks
-	 */
-	/*
+	 *
 	 * Delete all objects linked to the root
 	 * (additional table descriptors)
 	 */
-
 	acpi_ns_delete_namespace_subtree (this_node);
 
 	/* Detach any object(s) attached to the root */
@@ -589,23 +643,20 @@
 	obj_desc = acpi_ns_get_attached_object (this_node);
 	if (obj_desc) {
 		acpi_ns_detach_object (this_node);
-		acpi_cm_remove_reference (obj_desc);
+		acpi_ut_remove_reference (obj_desc);
 	}
 
 	acpi_ns_delete_children (this_node);
 
-
 	/*
 	 * 2) Now we can delete the ACPI tables
 	 */
-
 	acpi_tb_delete_acpi_tables ();
-
 	return;
 }
 
 
-/****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ns_opens_scope
  *
@@ -614,14 +665,14 @@
  * RETURN:      NEWSCOPE if the passed type "opens a name scope" according
  *              to the ACPI specification, else 0
  *
- ***************************************************************************/
+ ******************************************************************************/
 
 u32
 acpi_ns_opens_scope (
-	OBJECT_TYPE_INTERNAL    type)
+	ACPI_OBJECT_TYPE8       type)
 {
 
-	if (!acpi_cm_valid_object_type (type)) {
+	if (!acpi_ut_valid_object_type (type)) {
 		/* type code out of range  */
 
 		REPORT_WARNING (("Ns_opens_scope: Invalid Object Type\n"));
@@ -632,7 +683,7 @@
 }
 
 
-/****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ns_get_node
  *
@@ -650,7 +701,7 @@
  *
  * MUTEX:       Locks namespace
  *
- ***************************************************************************/
+ ******************************************************************************/
 
 ACPI_STATUS
 acpi_ns_get_node (
@@ -682,7 +733,7 @@
 	}
 
 
-	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 
 	/* Setup lookup scope (search starting point) */
 
@@ -697,17 +748,16 @@
 
 
 
-	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 
 	/* Cleanup */
 
-	acpi_cm_free (internal_path);
-
+	acpi_ut_free (internal_path);
 	return (status);
 }
 
 
-/****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ns_find_parent_name
  *
@@ -719,7 +769,7 @@
  *              name segment, or "????" if the parent name can't be found
  *              (which "should not happen").
  *
- ***************************************************************************/
+ ******************************************************************************/
 
 ACPI_NAME
 acpi_ns_find_parent_name (
@@ -740,12 +790,11 @@
 
 	}
 
-
 	return (ACPI_UNKNOWN_NAME);
 }
 
 
-/****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ns_get_parent_object
  *
@@ -755,7 +804,7 @@
  *
  * DESCRIPTION: Obtain the parent entry for a given entry in the namespace.
  *
- ***************************************************************************/
+ ******************************************************************************/
 
 
 ACPI_NAMESPACE_NODE *
@@ -775,7 +824,6 @@
 	 * This saves putting a parent back pointer in each and
 	 * every named object!
 	 */
-
 	while (!(node->flags & ANOBJ_END_OF_PEER_LIST)) {
 		node = node->peer;
 	}
@@ -785,7 +833,7 @@
 }
 
 
-/****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    Acpi_ns_get_next_valid_object
  *
@@ -797,7 +845,7 @@
  * DESCRIPTION: Find the next valid object within a name table.
  *              Useful for implementing NULL-end-of-list loops.
  *
- ***************************************************************************/
+ ******************************************************************************/
 
 
 ACPI_NAMESPACE_NODE *
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/namespace/nswalk.c linux/drivers/acpi/namespace/nswalk.c
--- v2.4.5/linux/drivers/acpi/namespace/nswalk.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/namespace/nswalk.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: nswalk - Functions for walking the APCI namespace
- *              $Revision: 19 $
+ *              $Revision: 22 $
  *
  *****************************************************************************/
 
@@ -29,7 +29,7 @@
 #include "acnamesp.h"
 
 
-#define _COMPONENT          NAMESPACE
+#define _COMPONENT          ACPI_NAMESPACE
 	 MODULE_NAME         ("nswalk")
 
 
@@ -54,7 +54,7 @@
 
 ACPI_NAMESPACE_NODE *
 acpi_ns_get_next_object (
-	OBJECT_TYPE_INTERNAL    type,
+	ACPI_OBJECT_TYPE8       type,
 	ACPI_NAMESPACE_NODE     *parent_node,
 	ACPI_NAMESPACE_NODE     *child_node)
 {
@@ -139,18 +139,18 @@
 
 ACPI_STATUS
 acpi_ns_walk_namespace (
-	OBJECT_TYPE_INTERNAL    type,
+	ACPI_OBJECT_TYPE8       type,
 	ACPI_HANDLE             start_node,
 	u32                     max_depth,
 	u8                      unlock_before_callback,
-	WALK_CALLBACK           user_function,
+	ACPI_WALK_CALLBACK      user_function,
 	void                    *context,
 	void                    **return_value)
 {
 	ACPI_STATUS             status;
 	ACPI_NAMESPACE_NODE     *child_node;
 	ACPI_NAMESPACE_NODE     *parent_node;
-	OBJECT_TYPE_INTERNAL    child_type;
+	ACPI_OBJECT_TYPE8        child_type;
 	u32                     level;
 
 
@@ -202,18 +202,17 @@
 				 */
 
 				if (unlock_before_callback) {
-					acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+					acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 				}
 
 				status = user_function (child_node, level,
 						 context, return_value);
 
 				if (unlock_before_callback) {
-					acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+					acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 				}
 
-				switch (status)
-				{
+				switch (status) {
 				case AE_OK:
 				case AE_CTRL_DEPTH:
 					/* Just keep going */
@@ -242,8 +241,7 @@
 
 			if ((level < max_depth) && (status != AE_CTRL_DEPTH)) {
 				if (acpi_ns_get_next_object (ACPI_TYPE_ANY,
-						 child_node, 0))
-				{
+						 child_node, 0)) {
 					/*
 					 * There is at least one child of this
 					 * object, visit the object
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/namespace/nsxfname.c linux/drivers/acpi/namespace/nsxfname.c
--- v2.4.5/linux/drivers/acpi/namespace/nsxfname.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/namespace/nsxfname.c	Wed Jun 20 17:47:40 2001
@@ -2,7 +2,7 @@
  *
  * Module Name: nsxfname - Public interfaces to the ACPI subsystem
  *                         ACPI Namespace oriented interfaces
- *              $Revision: 75 $
+ *              $Revision: 79 $
  *
  *****************************************************************************/
 
@@ -34,7 +34,7 @@
 #include "acevents.h"
 
 
-#define _COMPONENT          NAMESPACE
+#define _COMPONENT          ACPI_NAMESPACE
 	 MODULE_NAME         ("nsxfname")
 
 
@@ -67,6 +67,15 @@
 	ACPI_NAMESPACE_NODE     *prefix_node = NULL;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/* Parameter Validation */
+
 	if (!ret_handle || !pathname) {
 		return (AE_BAD_PARAMETER);
 	}
@@ -74,15 +83,15 @@
 	/* Convert a parent handle to a prefix node */
 
 	if (parent) {
-		acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+		acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 
 		prefix_node = acpi_ns_convert_handle_to_entry (parent);
 		if (!prefix_node) {
-			acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+			acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 			return (AE_BAD_PARAMETER);
 		}
 
-		acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+		acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 	}
 
 	/* Special case for root, since we can't search for it */
@@ -132,6 +141,13 @@
 	ACPI_NAMESPACE_NODE     *node;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/* Buffer pointer must be valid always */
 
 	if (!ret_path_ptr || (name_type > ACPI_NAME_TYPE_MAX)) {
@@ -141,8 +157,7 @@
 	/* Allow length to be zero and ignore the pointer */
 
 	if ((ret_path_ptr->length) &&
-	   (!ret_path_ptr->pointer))
-	{
+	   (!ret_path_ptr->pointer)) {
 		return (AE_BAD_PARAMETER);
 	}
 
@@ -159,7 +174,7 @@
 	 * Validate handle and convert to an Node
 	 */
 
-	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 	node = acpi_ns_convert_handle_to_entry (handle);
 	if (!node) {
 		status = AE_BAD_PARAMETER;
@@ -184,7 +199,7 @@
 
 unlock_and_exit:
 
-	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 	return (status);
 }
 
@@ -209,32 +224,39 @@
 	ACPI_HANDLE             handle,
 	ACPI_DEVICE_INFO        *info)
 {
-	DEVICE_ID               hid;
-	DEVICE_ID               uid;
+	ACPI_DEVICE_ID          hid;
+	ACPI_DEVICE_ID          uid;
 	ACPI_STATUS             status;
 	u32                     device_status = 0;
 	ACPI_INTEGER            address = 0;
 	ACPI_NAMESPACE_NODE     *node;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/* Parameter validation */
 
 	if (!handle || !info) {
 		return (AE_BAD_PARAMETER);
 	}
 
-	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 
 	node = acpi_ns_convert_handle_to_entry (handle);
 	if (!node) {
-		acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+		acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 		return (AE_BAD_PARAMETER);
 	}
 
 	info->type      = node->type;
 	info->name      = node->name;
 
-	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 
 	/*
 	 * If not a device, we are all done.
@@ -256,7 +278,7 @@
 
 	/* Execute the _HID method and save the result */
 
-	status = acpi_cm_execute_HID (node, &hid);
+	status = acpi_ut_execute_HID (node, &hid);
 	if (ACPI_SUCCESS (status)) {
 		STRNCPY (info->hardware_id, hid.buffer, sizeof(info->hardware_id));
 
@@ -265,7 +287,7 @@
 
 	/* Execute the _UID method and save the result */
 
-	status = acpi_cm_execute_UID (node, &uid);
+	status = acpi_ut_execute_UID (node, &uid);
 	if (ACPI_SUCCESS (status)) {
 		STRCPY (info->unique_id, uid.buffer);
 
@@ -277,7 +299,7 @@
 	 * _STA is not always present
 	 */
 
-	status = acpi_cm_execute_STA (node, &device_status);
+	status = acpi_ut_execute_STA (node, &device_status);
 	if (ACPI_SUCCESS (status)) {
 		info->current_status = device_status;
 		info->valid |= ACPI_VALID_STA;
@@ -288,7 +310,7 @@
 	 * _ADR is not always present
 	 */
 
-	status = acpi_cm_evaluate_numeric_object (METHOD_NAME__ADR,
+	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR,
 			  node, &address);
 
 	if (ACPI_SUCCESS (status)) {
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/namespace/nsxfobj.c linux/drivers/acpi/namespace/nsxfobj.c
--- v2.4.5/linux/drivers/acpi/namespace/nsxfobj.c	Sun Apr  8 10:02:56 2001
+++ linux/drivers/acpi/namespace/nsxfobj.c	Wed Jun 20 17:47:40 2001
@@ -2,7 +2,7 @@
  *
  * Module Name: nsxfobj - Public interfaces to the ACPI subsystem
  *                         ACPI Object oriented interfaces
- *              $Revision: 80 $
+ *              $Revision: 86 $
  *
  ******************************************************************************/
 
@@ -31,7 +31,7 @@
 #include "acdispat.h"
 
 
-#define _COMPONENT          NAMESPACE
+#define _COMPONENT          ACPI_NAMESPACE
 	 MODULE_NAME         ("nsxfobj")
 
 
@@ -76,6 +76,13 @@
 	u32                     object_length;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/*
 	 * If there are parameters to be passed to the object
 	 * (which must be a control method), the external objects
@@ -92,7 +99,7 @@
 		param_length    = (count + 1) * sizeof (void *);
 		object_length   = count * sizeof (ACPI_OPERAND_OBJECT);
 
-		param_ptr = acpi_cm_callocate (param_length + /* Parameter List part */
+		param_ptr = acpi_ut_callocate (param_length + /* Parameter List part */
 				  object_length); /* Actual objects */
 		if (!param_ptr) {
 			return (AE_NO_MEMORY);
@@ -108,7 +115,7 @@
 
 		for (i = 0; i < count; i++) {
 			param_ptr[i] = &object_ptr[i];
-			acpi_cm_init_static_object (&object_ptr[i]);
+			acpi_ut_init_static_object (&object_ptr[i]);
 		}
 		param_ptr[count] = NULL;
 
@@ -117,11 +124,11 @@
 		 * internal object
 		 */
 		for (i = 0; i < count; i++) {
-			status = acpi_cm_copy_eobject_to_iobject (&param_objects->pointer[i],
+			status = acpi_ut_copy_eobject_to_iobject (&param_objects->pointer[i],
 					 param_ptr[i]);
 
 			if (ACPI_FAILURE (status)) {
-				acpi_cm_delete_internal_object_list (param_ptr);
+				acpi_ut_delete_internal_object_list (param_ptr);
 				return (status);
 			}
 		}
@@ -136,8 +143,7 @@
 	 */
 
 	if ((pathname) &&
-		(acpi_ns_valid_root_prefix (pathname[0])))
-	{
+		(acpi_ns_valid_root_prefix (pathname[0]))) {
 		/*
 		 *  The path is fully qualified, just evaluate by name
 		 */
@@ -212,7 +218,7 @@
 				 * Find out how large a buffer is needed
 				 * to contain the returned object
 				 */
-				status = acpi_cm_get_object_size (return_obj,
+				status = acpi_ut_get_object_size (return_obj,
 						   &buffer_space_needed);
 				if (ACPI_SUCCESS (status)) {
 					/*
@@ -235,7 +241,7 @@
 						/*
 						 *  We have enough space for the object, build it
 						 */
-						status = acpi_cm_copy_iobject_to_eobject (return_obj,
+						status = acpi_ut_copy_iobject_to_eobject (return_obj,
 								  return_buffer);
 						return_buffer->length = buffer_space_needed;
 					}
@@ -252,7 +258,7 @@
 		 * Delete the internal return object. (Or at least
 		 * decrement the reference count by one)
 		 */
-		acpi_cm_remove_reference (return_obj);
+		acpi_ut_remove_reference (return_obj);
 	}
 
 	/*
@@ -262,7 +268,7 @@
 	if (param_ptr) {
 		/* Free the allocated parameter block */
 
-		acpi_cm_delete_internal_object_list (param_ptr);
+		acpi_ut_delete_internal_object_list (param_ptr);
 	}
 
 	return (status);
@@ -300,13 +306,20 @@
 	ACPI_NAMESPACE_NODE     *child_node = NULL;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/* Parameter validation */
 
 	if (type > ACPI_TYPE_MAX) {
 		return (AE_BAD_PARAMETER);
 	}
 
-	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 
 	/* If null handle, use the parent */
 
@@ -335,7 +348,7 @@
 
 	/* Internal function does the real work */
 
-	node = acpi_ns_get_next_object ((OBJECT_TYPE_INTERNAL) type,
+	node = acpi_ns_get_next_object ((ACPI_OBJECT_TYPE8) type,
 			   parent_node, child_node);
 	if (!node) {
 		status = AE_NOT_FOUND;
@@ -349,7 +362,7 @@
 
 unlock_and_exit:
 
-	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 	return (status);
 }
 
@@ -373,7 +386,15 @@
 	ACPI_OBJECT_TYPE        *ret_type)
 {
 	ACPI_NAMESPACE_NODE     *node;
+	ACPI_STATUS             status;
+
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
 
 	/* Parameter Validation */
 
@@ -390,20 +411,20 @@
 		return (AE_OK);
 	}
 
-	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 
 	/* Convert and validate the handle */
 
 	node = acpi_ns_convert_handle_to_entry (handle);
 	if (!node) {
-		acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+		acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 		return (AE_BAD_PARAMETER);
 	}
 
 	*ret_type = node->type;
 
 
-	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 	return (AE_OK);
 }
 
@@ -431,8 +452,12 @@
 	ACPI_STATUS             status = AE_OK;
 
 
-	/* No trace macro, too verbose */
+	/* Ensure that ACPI has been initialized */
 
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
 
 	if (!ret_handle) {
 		return (AE_BAD_PARAMETER);
@@ -445,7 +470,7 @@
 	}
 
 
-	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 
 	/* Convert and validate the handle */
 
@@ -470,7 +495,7 @@
 
 unlock_and_exit:
 
-	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 	return (status);
 }
 
@@ -510,19 +535,25 @@
 	ACPI_OBJECT_TYPE        type,
 	ACPI_HANDLE             start_object,
 	u32                     max_depth,
-	WALK_CALLBACK           user_function,
+	ACPI_WALK_CALLBACK      user_function,
 	void                    *context,
 	void                    **return_value)
 {
 	ACPI_STATUS             status;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/* Parameter validation */
 
 	if ((type > ACPI_TYPE_MAX)  ||
 		(!max_depth)            ||
-		(!user_function))
-	{
+		(!user_function)) {
 		return (AE_BAD_PARAMETER);
 	}
 
@@ -533,14 +564,14 @@
 	 * must be allowed to make Acpi calls itself.
 	 */
 
-	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
-	status = acpi_ns_walk_namespace ((OBJECT_TYPE_INTERNAL) type,
+	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	status = acpi_ns_walk_namespace ((ACPI_OBJECT_TYPE8) type,
 			   start_object, max_depth,
 			   NS_WALK_UNLOCK,
 			   user_function, context,
 			   return_value);
 
-	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 
 	return (status);
 }
@@ -570,17 +601,15 @@
 	ACPI_STATUS             status;
 	ACPI_NAMESPACE_NODE     *node;
 	u32                     flags;
-	DEVICE_ID               device_id;
+	ACPI_DEVICE_ID          device_id;
 	ACPI_GET_DEVICES_INFO   *info;
 
 
 	info = context;
 
-	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
-
+	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 	node = acpi_ns_convert_handle_to_entry (obj_handle);
-
-	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 
 	if (!node) {
 		return (AE_BAD_PARAMETER);
@@ -589,15 +618,13 @@
 	/*
 	 * Run _STA to determine if device is present
 	 */
-
-	status = acpi_cm_execute_STA (node, &flags);
+	status = acpi_ut_execute_STA (node, &flags);
 	if (ACPI_FAILURE (status)) {
-		return AE_OK;
+		return (AE_CTRL_DEPTH);
 	}
 
 	if (!(flags & 0x01)) {
 		/* don't return at the device or children of the device if not there */
-
 		return (AE_CTRL_DEPTH);
 	}
 
@@ -605,14 +632,13 @@
 	 * Filter based on device HID
 	 */
 	if (info->hid != NULL) {
-		status = acpi_cm_execute_HID (node, &device_id);
-
+		status = acpi_ut_execute_HID (node, &device_id);
 		if (status == AE_NOT_FOUND) {
 			return (AE_OK);
 		}
 
 		else if (ACPI_FAILURE (status)) {
-			return (status);
+			return (AE_CTRL_DEPTH);
 		}
 
 		if (STRNCMP (device_id.buffer, info->hid, sizeof (device_id.buffer)) != 0) {
@@ -621,7 +647,6 @@
 	}
 
 	info->user_function (obj_handle, nesting_level, info->context, return_value);
-
 	return (AE_OK);
 }
 
@@ -654,7 +679,7 @@
 ACPI_STATUS
 acpi_get_devices (
 	NATIVE_CHAR             *HID,
-	WALK_CALLBACK           user_function,
+	ACPI_WALK_CALLBACK      user_function,
 	void                    *context,
 	void                    **return_value)
 {
@@ -662,6 +687,13 @@
 	ACPI_GET_DEVICES_INFO   info;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/* Parameter validation */
 
 	if (!user_function) {
@@ -683,14 +715,14 @@
 	 * must be allowed to make Acpi calls itself.
 	 */
 
-	acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 	status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE,
 			   ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
 			   NS_WALK_UNLOCK,
 			   acpi_ns_get_device_callback, &info,
 			   return_value);
 
-	acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+	acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 
 	return (status);
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/os.c linux/drivers/acpi/os.c
--- v2.4.5/linux/drivers/acpi/os.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/os.c	Sun Jun 24 20:53:07 2001
@@ -1,7 +1,15 @@
+/******************************************************************************
+ * 
+ * Module Name: os.c - Linux OSL functions
+ *		$Revision: 28 $
+ *
+ *****************************************************************************/
+
 /*
  *  os.c - OS-dependent functions
  *
  *  Copyright (C) 2000 Andrew Henroid
+ *  Copyright (C) 2001 Andrew Grover
  *
  *  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
@@ -17,24 +25,36 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+/* Changes
+ *
+ * Christopher Liebman <liebman@sponsera.com> 2001-5-15
+ * - Fixed improper kernel_thread parameters 
+ */
 
 #include <linux/kernel.h>
-#include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/pci.h>
-#include <linux/acpi.h>
+#include <linux/interrupt.h>
+#include <linux/kmod.h>
 #include <linux/delay.h>
 #include <asm/io.h>
-#include "acpi.h"
+#include <acpi.h>
 #include "driver.h"
 
-#define _COMPONENT	OS_DEPENDENT
+#define _COMPONENT	ACPI_OS_SERVICES
 	MODULE_NAME	("os")
 
-static int acpi_irq_irq = 0;
-static OSD_HANDLER acpi_irq_handler = NULL;
-static void *acpi_irq_context = NULL;
+typedef struct 
+{
+    OSD_EXECUTION_CALLBACK  function;
+    void		    *context;
+} ACPI_OS_DPC;
+
+
+/*****************************************************************************
+ *			       Debugger Stuff
+ *****************************************************************************/
 
 #ifdef ENABLE_DEBUGGER
 
@@ -47,6 +67,19 @@
 #endif
 
 
+/*****************************************************************************
+ *				    Globals
+ *****************************************************************************/
+
+static int acpi_irq_irq = 0;
+static OSD_HANDLER acpi_irq_handler = NULL;
+static void *acpi_irq_context = NULL;
+
+
+/******************************************************************************
+ *				   Functions
+ *****************************************************************************/
+
 ACPI_STATUS
 acpi_os_initialize(void)
 {
@@ -141,6 +174,17 @@
 		iounmap(virt);
 }
 
+ACPI_STATUS
+acpi_os_get_physical_address(void *virt, ACPI_PHYSICAL_ADDRESS *phys)
+{
+	if(!phys || !virt)
+		return AE_BAD_PARAMETER;
+
+	*phys = virt_to_phys(virt);
+
+	return AE_OK;
+}
+
 static void
 acpi_irq(int irq, void *dev_id, struct pt_regs *regs)
 {
@@ -171,6 +215,7 @@
 		free_irq(irq, acpi_irq);
 		acpi_irq_handler = NULL;
 	}
+
 	return AE_OK;
 }
 
@@ -248,27 +293,27 @@
 void
 acpi_os_mem_out8 (ACPI_PHYSICAL_ADDRESS phys_addr, UINT8 value)
 {
-	*(u8*) (u32) phys_addr = value;
+	*(u8*) phys_to_virt(phys_addr) = value;
 }
 
 void
 acpi_os_mem_out16 (ACPI_PHYSICAL_ADDRESS phys_addr, UINT16 value)
 {
-	*(u16*) (u32) phys_addr = value;
+	*(u16*) phys_to_virt(phys_addr) = value;
 }
 
 void
 acpi_os_mem_out32 (ACPI_PHYSICAL_ADDRESS phys_addr, UINT32 value)
 {
-	*(u32*) (u32) phys_addr = value;
+	*(u32*) phys_to_virt(phys_addr) = value;
 }
 
 ACPI_STATUS
 acpi_os_read_pci_cfg_byte(
-			  u32 bus,
-			  u32 func,
-			  u32 addr,
-			  u8 * val)
+	u32 bus,
+	u32 func,
+	u32 addr,
+	u8 * val)
 {
 	int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
 	struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
@@ -279,10 +324,10 @@
 
 ACPI_STATUS
 acpi_os_read_pci_cfg_word(
-			  u32 bus,
-			  u32 func,
-			  u32 addr,
-			  u16 * val)
+	u32 bus,
+	u32 func,
+	u32 addr,
+	u16 * val)
 {
 	int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
 	struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
@@ -293,10 +338,10 @@
 
 ACPI_STATUS
 acpi_os_read_pci_cfg_dword(
-			   u32 bus,
-			   u32 func,
-			   u32 addr,
-			   u32 * val)
+	u32 bus,
+	u32 func,
+	u32 addr,
+	u32 * val)
 {
 	int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
 	struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
@@ -307,10 +352,10 @@
 
 ACPI_STATUS
 acpi_os_write_pci_cfg_byte(
-			   u32 bus,
-			   u32 func,
-			   u32 addr,
-			   u8 val)
+	u32 bus,
+	u32 func,
+	u32 addr,
+	u8 val)
 {
 	int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
 	struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
@@ -321,10 +366,10 @@
 
 ACPI_STATUS
 acpi_os_write_pci_cfg_word(
-			   u32 bus,
-			   u32 func,
-			   u32 addr,
-			   u16 val)
+	u32 bus,
+	u32 func,
+	u32 addr,
+	u16 val)
 {
 	int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
 	struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
@@ -335,10 +380,10 @@
 
 ACPI_STATUS
 acpi_os_write_pci_cfg_dword(
-			    u32 bus,
-			    u32 func,
-			    u32 addr,
-			    u32 val)
+	u32 bus,
+	u32 func,
+	u32 addr,
+	u32 val)
 {
 	int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
 	struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
@@ -347,49 +392,317 @@
 	return AE_OK;
 }
 
-/*
- * Queue for interpreter thread
- */
+ACPI_STATUS
+acpi_os_load_module (
+	char *module_name)
+{
+	FUNCTION_TRACE("acpi_os_load_module");
+
+	if (!module_name)
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+
+	if (0 > request_module(module_name)) {
+		DEBUG_PRINT(ACPI_WARN, ("Unable to load module [%s].\n", module_name));
+		return_ACPI_STATUS(AE_ERROR);
+	}
+
+	return_ACPI_STATUS(AE_OK);
+}
 
 ACPI_STATUS
-acpi_os_queue_for_execution(
-			    u32 priority,
-			    OSD_EXECUTION_CALLBACK callback,
-			    void *context)
+acpi_os_unload_module (
+	char *module_name)
 {
-	if (acpi_run(callback, context))
-		return AE_ERROR;
-	return AE_OK;
+	FUNCTION_TRACE("acpi_os_unload_module");
+
+	if (!module_name)
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+
+	/* TODO: How on Linux? */
+	/* this is done automatically for all modules with
+	use_count = 0, I think. see: MOD_INC_USE_COUNT -ASG */
+
+	return_ACPI_STATUS(AE_OK);
 }
 
+
 /*
- * Semaphores are unused, interpreter access is single threaded
+ * See acpi_os_queue_for_execution(), too
  */
+static int
+acpi_os_queue_exec (
+	void *context)
+{
+	ACPI_OS_DPC		*dpc = (ACPI_OS_DPC*)context;
 
-ACPI_STATUS
-acpi_os_create_semaphore(u32 max_units, u32 init, ACPI_HANDLE * handle)
+	FUNCTION_TRACE("acpi_os_queue_exec");
+
+	daemonize();
+	strcpy(current->comm, "kacpidpc");
+    
+	if (!dpc || !dpc->function)
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+
+	DEBUG_PRINT(ACPI_INFO, ("Executing function [%p(%p)].\n", dpc->function, dpc->context));
+
+	dpc->function(dpc->context);
+
+	acpi_os_free(dpc);
+
+	return_VALUE(1);
+}
+
+static void
+acpi_os_schedule_exec (
+	void *context)
 {
-	/* a hack to fake out sems until we implement them */
-	*handle = (ACPI_HANDLE) handle;
-	return AE_OK;
+	ACPI_OS_DPC		*dpc = NULL;
+	int			thread_pid = -1;
+
+	FUNCTION_TRACE("acpi_os_schedule_exec");
+
+	dpc = (ACPI_OS_DPC*)context;
+	if (!dpc) {
+		DEBUG_PRINT(ACPI_ERROR, ("Invalid (NULL) context.\n"));
+		return;
+	}
+
+	DEBUG_PRINT(ACPI_INFO, ("Creating new thread to run function [%p(%p)].\n", dpc->function, dpc->context));
+
+	thread_pid = kernel_thread(acpi_os_queue_exec, dpc, 
+		(CLONE_FS | CLONE_FILES | SIGCHLD));
+	if (thread_pid < 0) {
+		DEBUG_PRINT(ACPI_ERROR, ("Call to kernel_thread() failed.\n"));
+		acpi_os_free(dpc);
+	}
+
+	return_VOID;
 }
 
 ACPI_STATUS
-acpi_os_delete_semaphore(ACPI_HANDLE handle)
+acpi_os_queue_for_execution(
+	u32			priority,
+	OSD_EXECUTION_CALLBACK	function,
+	void			*context)
+{
+	ACPI_STATUS 		status = AE_OK;
+	ACPI_OS_DPC 		*dpc = NULL;
+
+	FUNCTION_TRACE("acpi_os_queue_for_execution");
+
+	DEBUG_PRINT(ACPI_INFO, ("Scheduling function [%p(%p)] for deferred execution.\n", function, context));
+
+	if (!function)
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+
+	/*
+	 * Allocate/initialize DPC structure.  Note that this memory will be
+	 * freed by the callee.
+	 */
+	dpc = acpi_os_callocate(sizeof(ACPI_OS_DPC));
+	if (!dpc) 
+		return AE_NO_MEMORY;
+
+	dpc->function = function;
+	dpc->context = context;
+
+	/*
+	 * Queue via DPC:
+	 * --------------
+	 * Note that we have to use two different processes for queuing DPCs:
+	 *	 Interrupt-Level: Use schedule_task; can't spawn a new thread.
+	 *	    Kernel-Level: Spawn a new kernel thread, as schedule_task has
+	 *			  its limitations (e.g. single-threaded model), and
+	 *			  all other task queues run at interrupt-level.
+	 */
+	switch (priority) {
+
+	case OSD_PRIORITY_GPE:
+	{
+		static struct tq_struct task;
+
+		memset(&task, 0, sizeof(struct tq_struct));
+
+		task.routine = acpi_os_schedule_exec;
+		task.data = (void*)dpc;
+
+		if (schedule_task(&task) < 0) {
+			DEBUG_PRINT(ACPI_ERROR, ("Call to schedule_task() failed.\n"));
+			status = AE_ERROR;
+		}
+	}
+	break;
+
+	default:
+		acpi_os_schedule_exec(dpc);
+		break;
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+
+ACPI_STATUS
+acpi_os_create_semaphore(
+	u32		max_units,
+	u32		initial_units,
+	ACPI_HANDLE	*handle)
 {
-	return AE_OK;
+    struct semaphore	    *sem = NULL;
+
+    FUNCTION_TRACE("acpi_os_create_semaphore");
+
+    sem = acpi_os_callocate(sizeof(struct semaphore));
+    if (!sem)
+	return_ACPI_STATUS(AE_NO_MEMORY);
+
+    sema_init(sem, initial_units);
+
+    *handle = (ACPI_HANDLE*)sem;
+
+    DEBUG_PRINT(ACPI_INFO, ("Creating semaphore[%p|%d].\n", *handle, initial_units));
+
+    return_ACPI_STATUS(AE_OK);
 }
 
+
+/* 
+ * TODO: A better way to delete semaphores?  Linux doesn't have a
+ * 'delete_semaphore()' function -- may result in an invalid
+ * pointer dereference for non-synchronized consumers.	Should
+ * we at least check for blocked threads and signal/cancel them?
+ */
+
 ACPI_STATUS
-acpi_os_wait_semaphore(ACPI_HANDLE handle, u32 units, u32 timeout)
+acpi_os_delete_semaphore(
+	ACPI_HANDLE handle)
 {
-	return AE_OK;
+    struct semaphore	    *sem = (struct semaphore*)handle;
+
+    FUNCTION_TRACE("acpi_os_delete_semaphore");
+
+    if (!sem) 
+	return AE_BAD_PARAMETER;
+
+    DEBUG_PRINT(ACPI_INFO, ("Deleting semaphore[%p].\n", handle));
+
+    acpi_os_free(sem); sem =  NULL;
+
+    return_ACPI_STATUS(AE_OK);
 }
 
+
+/*
+ * TODO: The kernel doesn't have a 'down_timeout' function -- had to
+ * improvise.  The process is to sleep for one scheduler quantum
+ * until the semaphore becomes available.  Downside is that this
+ * may result in starvation for timeout-based waits when there's
+ * lots of semaphore activity.
+ *
+ * TODO: Support for units > 1?
+ */
+ACPI_STATUS
+acpi_os_wait_semaphore(
+	ACPI_HANDLE	handle,
+	u32			units,
+	u32			timeout)
+{
+	ACPI_STATUS		status = AE_OK;
+	struct semaphore	*sem = (struct semaphore*)handle;
+	int			ret = 0;
+
+	FUNCTION_TRACE("acpi_os_wait_semaphore");
+
+	if (!sem || (units < 1)) 
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+
+	if (units > 1)
+		return_ACPI_STATUS(AE_SUPPORT);
+
+	DEBUG_PRINT(ACPI_INFO, ("Waiting for semaphore[%p|%d|%d]\n", handle, units, timeout));
+
+	switch (timeout)
+	{
+		/*
+		 * No Wait:
+		 * --------
+		 * A zero timeout value indicates that we shouldn't wait - just
+		 * acquire the semaphore if available otherwise return AE_TIME
+		 * (a.k.a. 'would block').
+		 */
+		case 0:
+		ret = down_trylock(sem);
+		if (ret < 0)
+			status = AE_TIME;
+		break;
+
+		/*
+		 * Wait Indefinitely:
+		 * ------------------
+		 */
+		case WAIT_FOREVER:
+		ret = down_interruptible(sem);
+		if (ret < 0)
+			status = AE_ERROR;
+		break;
+
+		/*
+		 * Wait w/ Timeout:
+		 * ----------------
+		 */
+		default:
+		// TODO: A better timeout algorithm?
+		{
+			int i = 0;
+			static const int quantum_ms = 1000/HZ;
+
+			ret = down_trylock(sem);
+			for (i = timeout; (i > 0 && ret < 0); i -= quantum_ms) {
+				current->state = TASK_INTERRUPTIBLE;
+				schedule_timeout(1);
+				ret = down_trylock(sem);
+			}
+	
+			if (ret < 0)
+			 status = AE_TIME;
+			}
+		break;
+	}
+
+	if (ACPI_FAILURE(status)) {
+		DEBUG_PRINT(ACPI_INFO, ("Failed to acquire semaphore[%p|%d|%d]\n", handle, units, timeout));
+	}
+	else {
+		DEBUG_PRINT(ACPI_INFO, ("Acquired semaphore[%p|%d|%d]\n", handle, units, timeout));
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+
+/*
+ * TODO: Support for units > 1?
+ */
 ACPI_STATUS
-acpi_os_signal_semaphore(ACPI_HANDLE handle, u32 units)
+acpi_os_signal_semaphore(
+    ACPI_HANDLE 	    handle, 
+    u32 		    units)
 {
-	return AE_OK;
+	struct semaphore *sem = (struct semaphore *) handle;
+
+	FUNCTION_TRACE("acpi_os_signal_semaphore");
+
+	if (!sem || (units < 1)) 
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+
+	if (units > 1)
+		return_ACPI_STATUS(AE_SUPPORT);
+
+	DEBUG_PRINT(ACPI_INFO, ("Signaling semaphore[%p|%d]\n", handle, units));
+
+	up(sem);
+
+	return_ACPI_STATUS(AE_OK);
 }
 
 ACPI_STATUS
@@ -399,8 +712,10 @@
 	return AE_OK;
 }
 
+
 void
 acpi_os_dbg_trap(char *msg)
+
 {
 	acpi_os_printf("trap: %s", msg);
 }
@@ -421,7 +736,7 @@
 
 		kdb_read(buffer, sizeof(line_buf));
 
-		/* remove the CR kdb includes */
+		/* remove the CR kdb includes */ 
 		chars = strlen(buffer) - 1;
 		buffer[chars] = '\0';
 	}
@@ -444,4 +759,15 @@
 acpi_os_writable(void *ptr, u32 len)
 {
 	return 1;
+}
+
+u32
+acpi_os_get_thread_id (void)
+{
+	if (!in_interrupt())
+		return current->pid;
+
+	/*acpi_os_printf("acpi_os_get_thread_id called from interrupt level!\n");*/
+
+	return 0;
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/Makefile linux/drivers/acpi/ospm/Makefile
--- v2.4.5/linux/drivers/acpi/ospm/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/Makefile	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,22 @@
+#
+# Makefile for the Linux OSPM code.
+#
+
+O_TARGET := $(notdir $(CURDIR)).o
+
+ACPI_CFLAGS += -I$(CURDIR)/include
+
+EXTRA_CFLAGS += $(ACPI_CFLAGS)
+
+subdir-$(CONFIG_ACPI_BUSMGR)	+= busmgr
+subdir-$(CONFIG_ACPI_EC)	+= ec
+subdir-$(CONFIG_ACPI_SYS)	+= system
+subdir-$(CONFIG_ACPI_CPU)	+= processor
+subdir-$(CONFIG_ACPI_CMBATT)	+= battery
+subdir-$(CONFIG_ACPI_AC)	+= ac_adapter
+subdir-$(CONFIG_ACPI_BUTTON)	+= button
+subdir-$(CONFIG_ACPI_THERMAL)	+= thermal
+
+obj-y				+= $(foreach dir,$(subdir-y),$(dir)/ospm_$(dir).o)
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/ac_adapter/Makefile linux/drivers/acpi/ospm/ac_adapter/Makefile
--- v2.4.5/linux/drivers/acpi/ospm/ac_adapter/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/ac_adapter/Makefile	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,6 @@
+O_TARGET	:= ospm_$(notdir $(CURDIR)).o
+obj-m		:= $(O_TARGET)
+EXTRA_CFLAGS	+= $(ACPI_CFLAGS)
+obj-y		:= $(patsubst %.c,%.o,$(wildcard *.c))
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/ac_adapter/ac.c linux/drivers/acpi/ospm/ac_adapter/ac.c
--- v2.4.5/linux/drivers/acpi/ospm/ac_adapter/ac.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/ac_adapter/ac.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,348 @@
+/*****************************************************************************
+ *
+ * Module Name: ac.c
+ *   $Revision: 19 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <acpi.h>
+#include "ac.h"
+
+
+#define _COMPONENT		ACPI_AC_ADAPTER
+	MODULE_NAME 		("ac")
+
+
+/****************************************************************************
+ *                            Internal Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:	ac_print
+ *
+ * PARAMETERS:	
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION: Prints out information on a specific ac_adapter.
+ *
+ ****************************************************************************/
+
+void
+ac_print (
+	AC_CONTEXT		*ac_adapter)
+{
+
+	return;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	ac_add_device
+ *
+ * PARAMETERS:	
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ac_add_device(
+	BM_HANDLE		device_handle,
+	void			**context)
+{
+	ACPI_STATUS 		status = AE_OK;
+	BM_DEVICE		*device = NULL;
+	AC_CONTEXT		*ac_adapter = NULL;
+	ACPI_DEVICE_INFO	info;
+
+	if (!context || *context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Get information on this device.
+	 */
+	status = bm_get_device_info(device_handle, &device);
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	/*
+	 * Allocate a new AC_CONTEXT structure.
+	 */
+	ac_adapter = acpi_os_callocate(sizeof(AC_CONTEXT));
+	if (!ac_adapter) {
+		return(AE_NO_MEMORY);
+	}
+
+	ac_adapter->device_handle = device->handle;
+	ac_adapter->acpi_handle = device->acpi_handle;
+
+	/*
+	 * Get information on this object.
+	 */
+	status = acpi_get_object_info(ac_adapter->acpi_handle, &info);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	/*
+	 * _UID?
+	 * -----
+	 */
+	if (info.valid & ACPI_VALID_UID) {
+		strncpy(ac_adapter->uid, info.unique_id, sizeof(info.unique_id));
+	}
+	else {
+		strncpy(ac_adapter->uid, "0", sizeof("0"));
+	}
+
+	/*
+	 * _STA?
+	 * -----
+	 */
+	if (!(info.valid & ACPI_VALID_STA)) {
+		status = AE_ERROR;
+		goto end;
+	}
+
+	status = ac_osl_add_device(ac_adapter);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	*context = ac_adapter;
+
+	ac_print(ac_adapter);
+
+end:
+	if (ACPI_FAILURE(status)) {
+		acpi_os_free(ac_adapter);
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	ac_remove_device
+ *
+ * PARAMETERS:	
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ac_remove_device (
+	void			**context)
+{
+	ACPI_STATUS 		status = AE_OK;
+	AC_CONTEXT		*ac_adapter = NULL;
+
+	if (!context || !*context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	ac_adapter = (AC_CONTEXT*)*context;
+
+	ac_osl_remove_device(ac_adapter);
+
+	acpi_os_free(ac_adapter);
+
+	*context = NULL;
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *                             External Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:	ac_initialize
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ac_initialize (void)
+{
+	ACPI_STATUS		status = AE_OK;
+	BM_DEVICE_ID		criteria;
+	BM_DRIVER		driver;
+
+	MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
+	MEMSET(&driver, 0, sizeof(BM_DRIVER));
+
+	driver.notify = &ac_notify;
+	driver.request = &ac_request;
+
+	/*
+	 * Register driver for AC Adapter devices.
+	 */
+	MEMCPY(criteria.hid, AC_HID_AC_ADAPTER, sizeof(AC_HID_AC_ADAPTER));
+
+	status = bm_register_driver(&criteria, &driver);
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	ac_terminate
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ac_terminate (void)
+{
+	ACPI_STATUS 		status = AE_OK;
+	BM_DEVICE_ID		criteria;
+	BM_DRIVER		driver;
+
+	MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
+	MEMSET(&driver, 0, sizeof(BM_DRIVER));
+
+	/*
+	 * Unregister driver for AC Adapter devices.
+	 */
+	MEMCPY(criteria.hid, AC_HID_AC_ADAPTER, sizeof(AC_HID_AC_ADAPTER));
+
+	driver.notify = &ac_notify;
+	driver.request = &ac_request;
+
+	status = bm_unregister_driver(&criteria, &driver);
+
+	return(status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:	ac_notify
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+ACPI_STATUS
+ac_notify (
+	BM_NOTIFY		notify_type,
+	BM_HANDLE		device_handle,
+	void			**context)
+{
+	ACPI_STATUS 		status = AE_OK;
+
+	if (!context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	switch (notify_type) {
+
+	case BM_NOTIFY_DEVICE_ADDED:
+		status = ac_add_device(device_handle, context);
+		break;
+
+	case BM_NOTIFY_DEVICE_REMOVED:
+		status = ac_remove_device(context);
+		break;
+
+	case AC_NOTIFY_STATUS_CHANGE:
+		status = ac_osl_generate_event(notify_type,
+			((AC_CONTEXT*)*context));
+		break;
+
+	default:
+		status = AE_SUPPORT;
+		break;
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	ac_request
+ *
+ * PARAMETERS:	
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ac_request (
+	BM_REQUEST		*request,
+	void			*context)
+{
+	ACPI_STATUS 		status = AE_OK;
+
+	/*
+	 * Must have a valid request structure and context.
+	 */
+	if (!request || !context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Handle Request:
+	 * ---------------
+	 */
+	switch (request->command) {
+
+	default:
+		status = AE_SUPPORT;
+		break;
+	}
+
+	request->status = status;
+
+	return(status);
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/ac_adapter/ac_osl.c linux/drivers/acpi/ospm/ac_adapter/ac_osl.c
--- v2.4.5/linux/drivers/acpi/ospm/ac_adapter/ac_osl.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/ac_adapter/ac_osl.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,256 @@
+/*****************************************************************************
+ *
+ * Module Name: ac_osl.c
+ *   $Revision: 7 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <acpi.h>
+#include "ac.h"
+
+
+MODULE_AUTHOR("Andrew Grover");
+MODULE_DESCRIPTION("ACPI Component Architecture (CA) - AC Adapter Driver");
+
+
+#define AC_PROC_ROOT		"ac_adapter"
+#define AC_PROC_STATUS		"status"
+#define AC_ON_LINE		"on-line"
+#define AC_OFF_LINE		"off-line"
+
+extern struct proc_dir_entry	*bm_proc_root;
+static struct proc_dir_entry	*ac_proc_root = NULL;
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	ac_osl_proc_read_status
+ *
+ ****************************************************************************/
+
+static int
+ac_osl_proc_read_status (
+	char			*page,
+	char			**start,
+	off_t			off,
+	int 			count,
+	int 			*eof,
+	void			*context)
+{
+	ACPI_STATUS 		status = AE_OK;
+	AC_CONTEXT		*ac_adapter = NULL;
+	char			*p = page;
+	int			len;
+
+	if (!context) {
+		goto end;
+	}
+
+	ac_adapter = (AC_CONTEXT*)context;
+
+	/* don't get status more than once for a single proc read */
+	if (off != 0) {
+		goto end;
+	}
+
+	status = bm_evaluate_simple_integer(ac_adapter->acpi_handle,
+		"_PSR", &(ac_adapter->is_online));
+	if (ACPI_FAILURE(status)) {
+		p += sprintf(p, "Error reading AC Adapter status\n");
+		goto end;
+	}
+
+	if (ac_adapter->is_online) {
+		p += sprintf(p, "Status:                  %s\n", 
+			AC_ON_LINE);
+	}
+	else {
+		p += sprintf(p, "Status:                  %s\n", 
+			AC_OFF_LINE);
+	}
+
+end:
+	len = (p - page);
+	if (len <= off+count) *eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len>count) len = count;
+	if (len<0) len = 0;
+
+	return(len);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	ac_osl_add_device
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ac_osl_add_device(
+	AC_CONTEXT		*ac_adapter)
+{
+	struct proc_dir_entry	*proc_entry = NULL;
+
+	if (!ac_adapter) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	printk(KERN_INFO "AC Adapter: found\n");
+
+	proc_entry = proc_mkdir(ac_adapter->uid, ac_proc_root);
+	if (!proc_entry) {
+		return(AE_ERROR);
+	}
+
+	create_proc_read_entry(AC_PROC_STATUS, S_IFREG | S_IRUGO, 
+		proc_entry, ac_osl_proc_read_status, (void*)ac_adapter);
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	ac_osl_remove_device
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ac_osl_remove_device (
+	AC_CONTEXT		*ac_adapter)
+{
+	char			proc_entry[64];
+
+	if (!ac_adapter) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	sprintf(proc_entry, "%s/%s", ac_adapter->uid, AC_PROC_STATUS);
+	remove_proc_entry(proc_entry, ac_proc_root);
+
+	sprintf(proc_entry, "%s", ac_adapter->uid);
+	remove_proc_entry(proc_entry, ac_proc_root);
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	ac_osl_generate_event
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ac_osl_generate_event (
+	u32			event,
+	AC_CONTEXT		*ac_adapter)
+{
+	ACPI_STATUS		status = AE_OK;
+
+	if (!ac_adapter) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	switch (event) {
+
+	case AC_NOTIFY_STATUS_CHANGE:
+		status = bm_osl_generate_event(ac_adapter->device_handle, 
+			AC_PROC_ROOT, ac_adapter->uid, event, 0);
+		break;
+
+	default:
+		return(AE_BAD_PARAMETER);
+		break;
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	ac_osl_init
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	0: Success
+ *
+ * DESCRIPTION: Module initialization.
+ *
+ ****************************************************************************/
+
+static int __init 
+ac_osl_init (void)
+{
+	ACPI_STATUS		status = AE_OK;
+
+	ac_proc_root = proc_mkdir(AC_PROC_ROOT, bm_proc_root);
+	if (!ac_proc_root) {
+		status = AE_ERROR;
+	}
+	else {
+		status = ac_initialize();
+		if (ACPI_FAILURE(status)) {
+			remove_proc_entry(AC_PROC_ROOT, bm_proc_root);
+		}
+
+	}
+
+	return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	ac_osl_cleanup
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	<none>
+ *
+ * DESCRIPTION: Module cleanup.
+ *
+ ****************************************************************************/
+
+static void __exit 
+ac_osl_cleanup (void)
+{
+	ac_terminate();
+
+	if (ac_proc_root) {
+		remove_proc_entry(AC_PROC_ROOT, bm_proc_root);
+	}
+
+	return;
+}
+
+
+module_init(ac_osl_init);
+module_exit(ac_osl_cleanup);
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/battery/Makefile linux/drivers/acpi/ospm/battery/Makefile
--- v2.4.5/linux/drivers/acpi/ospm/battery/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/battery/Makefile	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,6 @@
+O_TARGET	:= ospm_$(notdir $(CURDIR)).o
+obj-m		:= $(O_TARGET)
+EXTRA_CFLAGS	+= $(ACPI_CFLAGS)
+obj-y		:= $(patsubst %.c,%.o,$(wildcard *.c))
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/battery/bt.c linux/drivers/acpi/ospm/battery/bt.c
--- v2.4.5/linux/drivers/acpi/ospm/battery/bt.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/battery/bt.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,593 @@
+/*****************************************************************************
+ *
+ * Module Name: bt.c
+ *   $Revision: 24 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <acpi.h>
+#include "bt.h"
+
+
+#define _COMPONENT		ACPI_BATTERY
+	MODULE_NAME 		("bt")
+
+
+/****************************************************************************
+ *                            Internal Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:	bt_print
+ *
+ * PARAMETERS:	
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION: Prints out information on a specific battery.
+ *
+ ****************************************************************************/
+
+void
+bt_print (
+	BT_CONTEXT		*battery)
+{
+
+	return;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	bt_get_info
+ *
+ * PARAMETERS:	
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ * NOTES:	Allocates battery_info - which must be freed by the caller.
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bt_get_info (
+	BT_CONTEXT		*battery,
+	BT_BATTERY_INFO 	**battery_info)
+{
+	ACPI_STATUS 		status = AE_OK;
+	ACPI_BUFFER 		bif_buffer, package_format, package_data;
+	ACPI_OBJECT 		*package = NULL;
+
+	if (!battery || !battery_info || *battery_info) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	MEMSET(&bif_buffer, 0, sizeof(ACPI_BUFFER));
+
+	/*
+	 * Evalute _BIF:
+	 * -------------
+	 * And be sure to deallocate bif_buffer.pointer!
+	 */
+	status = bm_evaluate_object(battery->acpi_handle, "_BIF", NULL,
+		&bif_buffer);
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	/*
+	 * Extract Package Data:
+	 * ---------------------
+	 * Type-cast this bif_buffer to a package and use helper
+	 * functions to convert results into BT_BATTERY_INFO structure.
+	 * The first attempt is just to get the size of the package
+	 * data; the second gets the data (once we know the required
+	 * bif_buffer size).
+	 */
+	status = bm_cast_buffer(&bif_buffer, (void**)&package,
+		sizeof(ACPI_OBJECT));
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	package_format.length = sizeof("NNNNNNNNNSSSS");
+	package_format.pointer = "NNNNNNNNNSSSS";
+
+	MEMSET(&package_data, 0, sizeof(ACPI_BUFFER));
+
+	status = bm_extract_package_data(package, &package_format,
+		&package_data);
+	if (status != AE_BUFFER_OVERFLOW) {
+		if (status == AE_OK) {
+			status = AE_ERROR;
+		}
+		goto end;
+	}
+
+	package_data.pointer = acpi_os_callocate(package_data.length);
+	if (!package_data.pointer) {
+		return(AE_NO_MEMORY);
+	}
+
+	status = bm_extract_package_data(package, &package_format,
+		&package_data);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_free(package_data.pointer);
+		goto end;
+	}
+
+	*battery_info = package_data.pointer;
+
+end:
+	acpi_os_free(bif_buffer.pointer);
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	bt_get_status
+ *
+ * PARAMETERS:	
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bt_get_status (
+	BT_CONTEXT		*battery,
+	BT_BATTERY_STATUS	**battery_status)
+{
+	ACPI_STATUS 		status = AE_OK;
+	ACPI_BUFFER 		bst_buffer, package_format, package_data;
+	ACPI_OBJECT 		*package = NULL;
+
+	if (!battery || !battery_status || *battery_status) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	MEMSET(&bst_buffer, 0, sizeof(ACPI_BUFFER));
+
+	/*
+	 * Evalute _BST:
+	 * -------------
+	 * And be sure to deallocate bst_buffer.pointer!
+	 */
+	status = bm_evaluate_object(battery->acpi_handle, "_BST",
+		NULL, &bst_buffer);
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	/*
+	 * Extract Package Data:
+	 * ---------------------
+	 * Type-cast this bst_buffer to a package and use helper
+	 * functions to convert results into BT_BATTERY_STATUS structure.
+	 * The first attempt is just to get the size of the package data;
+	 * the second gets the data (once we know the required bst_buffer
+	 * size).
+	 */
+	status = bm_cast_buffer(&bst_buffer, (void**)&package,
+		sizeof(ACPI_OBJECT));
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	package_format.length = sizeof("NNNN");
+	package_format.pointer = "NNNN";
+
+	MEMSET(&package_data, 0, sizeof(ACPI_BUFFER));
+
+	status = bm_extract_package_data(package, &package_format,
+		&package_data);
+	if (status != AE_BUFFER_OVERFLOW) {
+		if (status == AE_OK) {
+			status = AE_ERROR;
+		}
+		goto end;
+	}
+
+	package_data.pointer = acpi_os_callocate(package_data.length);
+	if (!package_data.pointer) {
+		return(AE_NO_MEMORY);
+	}
+
+	status = bm_extract_package_data(package, &package_format,
+		&package_data);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_free(package_data.pointer);
+		goto end;
+	}
+
+	*battery_status = package_data.pointer;
+
+end:
+	acpi_os_free(bst_buffer.pointer);
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	bt_check_device
+ *
+ * PARAMETERS:	
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bt_check_device (
+	BT_CONTEXT		*battery)
+{
+	ACPI_STATUS 		status = AE_OK;
+	BM_DEVICE_STATUS	battery_status = BM_STATUS_UNKNOWN;
+	u32 			was_present = FALSE;
+	BT_BATTERY_INFO 	*battery_info = NULL;
+
+	if (!battery) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	was_present = battery->is_present;
+
+	/*
+	 * Battery Present?
+	 * ----------------
+	 * Get the device status and check if battery slot is occupied.
+	 */
+	status = bm_get_device_status(battery->device_handle, &battery_status);
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	if (battery_status & BM_STATUS_BATTERY_PRESENT) {
+		battery->is_present = TRUE;
+	}
+	else {
+		battery->is_present = FALSE;
+	}
+
+	/*
+	 * Battery Appeared?
+	 * -----------------
+	 */
+	if (!was_present && battery->is_present) {
+
+		/*
+		 * Units of Power?
+		 * ---------------
+		 * Get the 'units of power', as we'll need this to report
+		 * status information.
+		 */
+		status = bt_get_info(battery, &battery_info);
+		if (ACPI_SUCCESS(status)) {
+			battery->power_units = (battery_info->power_unit)
+				? BT_POWER_UNITS_AMPS : BT_POWER_UNITS_WATTS;
+			acpi_os_free(battery_info);
+		}
+	}
+
+	/*
+	 * Battery Disappeared?
+	 * --------------------
+	 */
+	else if (was_present && !battery->is_present) {
+		battery->power_units = BT_POWER_UNITS_DEFAULT;
+	}
+
+	return(status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:	bt_add_device
+ *
+ * PARAMETERS:	
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bt_add_device (
+	BM_HANDLE		device_handle,
+	void			**context)
+{
+	ACPI_STATUS 		status = AE_OK;
+	BM_DEVICE		*device = NULL;
+	BT_CONTEXT		*battery = NULL;
+
+	if (!context || *context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Get information on this device.
+	 */
+	status = bm_get_device_info(device_handle, &device);
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	/*
+	 * Allocate a new BT_CONTEXT structure.
+	 */
+	battery = acpi_os_callocate(sizeof(BT_CONTEXT));
+	if (!battery) {
+		return(AE_NO_MEMORY);
+	}
+
+	battery->device_handle = device->handle;
+	battery->acpi_handle = device->acpi_handle;
+	strncpy(battery->uid, device->id.uid, sizeof(battery->uid));
+
+	battery->power_units = BT_POWER_UNITS_DEFAULT;
+	battery->is_present = FALSE;
+
+	/*
+	 * See if battery is really present.
+	 */
+	status = bt_check_device(battery);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	status = bt_osl_add_device(battery);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	*context = battery;
+
+	bt_print(battery);
+
+end:
+	if (ACPI_FAILURE(status)) {
+		acpi_os_free(battery);
+	}
+
+	return(status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:	bt_remove_device
+ *
+ * PARAMETERS:	
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bt_remove_device (
+	void			**context)
+{
+	ACPI_STATUS 		status = AE_OK;
+	BT_CONTEXT		*battery = NULL;
+
+	if (!context || !*context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	battery = (BT_CONTEXT*)*context;
+
+	bt_osl_remove_device(battery);
+
+	acpi_os_free(battery);
+
+	*context = NULL;
+
+	return(status);
+}
+
+
+/*****************************************************************************
+ *                               External Functions
+ *****************************************************************************/
+
+/*****************************************************************************
+ *
+ * FUNCTION:	bt_initialize
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bt_initialize (void)
+{
+	ACPI_STATUS		status = AE_OK;
+	BM_DEVICE_ID		criteria;
+	BM_DRIVER		driver;
+
+	MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
+	MEMSET(&driver, 0, sizeof(BM_DRIVER));
+
+	/*
+	 * Register driver for driver method battery devices.
+	 */
+	MEMCPY(criteria.hid, BT_HID_CM_BATTERY, sizeof(BT_HID_CM_BATTERY));
+
+	driver.notify = &bt_notify;
+	driver.request = &bt_request;
+
+	status = bm_register_driver(&criteria, &driver);
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	bt_terminate
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bt_terminate (void)
+{
+	ACPI_STATUS		status = AE_OK;
+	BM_DEVICE_ID		criteria;
+	BM_DRIVER		driver;
+
+	MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
+	MEMSET(&driver, 0, sizeof(BM_DRIVER));
+
+	/*
+	 * Unregister driver for driver method battery devices.
+	 */
+	MEMCPY(criteria.hid, BT_HID_CM_BATTERY, sizeof(BT_HID_CM_BATTERY));
+
+	driver.notify = &bt_notify;
+	driver.request = &bt_request;
+
+	status = bm_unregister_driver(&criteria, &driver);
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	bt_notify
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bt_notify (
+	BM_NOTIFY		notify_type,
+	BM_HANDLE		device_handle,
+	void			**context)
+{
+	ACPI_STATUS 		status = AE_OK;
+
+	if (!context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	switch (notify_type) {
+
+	case BM_NOTIFY_DEVICE_ADDED:
+		status = bt_add_device(device_handle, context);
+		break;
+
+	case BM_NOTIFY_DEVICE_REMOVED:
+		status = bt_remove_device(context);
+		break;
+
+	case BT_NOTIFY_STATUS_CHANGE:
+		status = bt_osl_generate_event(notify_type,
+			((BT_CONTEXT*)*context));
+		break;
+
+	case BT_NOTIFY_INFORMATION_CHANGE:
+		status = bt_check_device((BT_CONTEXT*)*context);
+		if (ACPI_SUCCESS(status)) {
+			status = bt_osl_generate_event(notify_type,
+				((BT_CONTEXT*)*context));
+		}
+		break;
+
+	default:
+		status = AE_SUPPORT;
+		break;
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	bt_request
+ *
+ * PARAMETERS:	
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bt_request (
+	BM_REQUEST		*request,
+	void			*context)
+{
+	ACPI_STATUS 		status = AE_OK;
+
+	/*
+	 * Must have a valid request structure and context.
+	 */
+	if (!request || !context)
+		return(AE_BAD_PARAMETER);
+
+	/*
+	 * Handle request:
+	 * ---------------
+	 */
+	switch (request->command) {
+
+	default:
+		status = AE_SUPPORT;
+		break;
+	}
+
+	request->status = status;
+
+	return(status);
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/battery/bt_osl.c linux/drivers/acpi/ospm/battery/bt_osl.c
--- v2.4.5/linux/drivers/acpi/ospm/battery/bt_osl.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/battery/bt_osl.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,438 @@
+/******************************************************************************
+ *
+ * Module Name: bt_osl.c
+ *   $Revision: 18 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * Changes:
+ * Brendan Burns <bburns@wso.williams.edu> 2000-11-15
+ * - added proc battery interface
+ * - parse returned data from _BST and _BIF
+ * Andy Grover <andrew.grover@intel.com> 2000-12-8
+ * - improved proc interface
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <acpi.h>
+#include "bt.h"
+
+
+MODULE_AUTHOR("Andrew Grover");
+MODULE_DESCRIPTION("ACPI Component Architecture (CA) - Control Method Battery Driver");
+
+
+#define BT_PROC_ROOT		"battery"
+#define BT_PROC_STATUS		"status"
+#define BT_PROC_INFO		"info"
+
+extern struct proc_dir_entry	*bm_proc_root;
+static struct proc_dir_entry	*bt_proc_root = NULL;
+
+
+/****************************************************************************
+ * 
+ * FUNCTION:	bt_osl_proc_read_info
+ *
+ ****************************************************************************/
+
+static int
+bt_osl_proc_read_info (
+	char			*page, 
+	char			**start, 
+	off_t			off, 
+	int 			count, 
+	int 			*eof, 
+	void			*context)
+{
+	BT_CONTEXT		*battery = NULL;
+	BT_BATTERY_INFO 	*battery_info = NULL;
+	char			*p = page;
+	int 			len = 0;
+
+	if (!context || (off != 0)) {
+		goto end;
+	}
+
+	battery = (BT_CONTEXT*)context;
+
+	/*
+	 * Battery Present?
+	 * ----------------
+	 */
+	if (!battery->is_present) {
+		p += sprintf(p, "Present:                 no\n");
+		goto end;
+	}
+	else {
+		p += sprintf(p, "Present:                 yes\n");
+	}
+
+	/*
+	 * Get Battery Information:
+	 * ------------------------
+	 */
+	if (ACPI_FAILURE(bt_get_info(battery, &battery_info))) {
+		p += sprintf(p, "Error reading battery information (_BIF)\n");
+		goto end;
+	}
+
+	if (battery_info->design_capacity == BT_UNKNOWN) {
+		p += sprintf(p, "Design Capacity:         unknown\n");
+	}
+	else {
+		p += sprintf(p, "Design Capacity:         %d %sh\n", 
+			 battery_info->design_capacity, 
+			 battery->power_units);
+	}
+	
+	if (battery_info->last_full_capacity == BT_UNKNOWN) {
+		p += sprintf(p, "Last Full Capacity:      unknown\n");
+	} 
+	else {
+		p += sprintf(p, "Last Full Capacity:      %d %sh\n", 
+			 battery_info->last_full_capacity, 
+			 battery->power_units);
+	}
+
+	if (battery_info->battery_technology == 0) {
+		p += sprintf(p, "Battery Technology:      primary (non-rechargeable)\n");
+	}
+	else if (battery_info->battery_technology == 1) {
+		p += sprintf(p, "Battery Technology:      secondary (rechargeable)\n");
+	}
+	else {
+		p += sprintf(p, "Battery Technology:      unknown\n");
+	}
+
+	if (battery_info->design_voltage == BT_UNKNOWN) {
+		p += sprintf(p, "Design Voltage:          unknown\n");
+	}
+	else {
+		p += sprintf(p, "Design Voltage:          %d mV\n", 
+			 battery_info->design_voltage);
+	}
+	
+	p += sprintf(p, "Design Capacity Warning: %d %sh\n",
+		battery_info->design_capacity_warning, 
+		battery->power_units);
+	p += sprintf(p, "Design Capacity Low:     %d %sh\n",
+		battery_info->design_capacity_low, 
+		battery->power_units);
+	p += sprintf(p, "Capacity Granularity 1:  %d %sh\n",
+		battery_info->battery_capacity_granularity_1, 
+		battery->power_units);
+	p += sprintf(p, "Capacity Granularity 2:  %d %sh\n",
+		battery_info->battery_capacity_granularity_2, 
+		battery->power_units);
+	p += sprintf(p, "Model Number:            %s\n", 
+		battery_info->model_number);
+	p += sprintf(p, "Serial Number:           %s\n", 
+		battery_info->serial_number);
+	p += sprintf(p, "Battery Type:            %s\n", 
+		battery_info->battery_type);
+	p += sprintf(p, "OEM Info:                %s\n", 
+		battery_info->oem_info);
+	
+end:
+	len = (p - page);
+	if (len <= off+count) *eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len>count) len = count;
+	if (len<0) len = 0;
+
+	acpi_os_free(battery_info);
+
+	return(len);
+}
+
+
+/****************************************************************************
+ * 
+ * FUNCTION:	bt_osl_proc_read_status
+ *
+ ****************************************************************************/
+
+static int
+bt_osl_proc_read_status (
+	char			*page, 
+	char			**start, 
+	off_t			off, 
+	int 			count, 
+	int 			*eof, 
+	void			*context)
+{
+	BT_CONTEXT		*battery = NULL;
+	BT_BATTERY_STATUS	*battery_status = NULL;
+	char			*p = page;
+	int 			len = 0;
+
+	if (!context || (off != 0)) {
+		goto end;
+	}
+
+	battery = (BT_CONTEXT*)context;
+
+	/*
+	 * Battery Present?
+	 * ----------------
+	 */
+	if (!battery->is_present) {
+		p += sprintf(p, "Present:                 no\n");
+		goto end;
+	}
+	else {
+		p += sprintf(p, "Present:                 yes\n");
+	}
+
+	/*
+	 * Get Battery Status:
+	 * -------------------
+	 */
+	if (ACPI_FAILURE(bt_get_status(battery, &battery_status))) {
+		p += sprintf(p, "Error reading battery status (_BST)\n");
+		goto end;
+	}
+
+	/*
+	 * Store Data:
+	 * -----------
+	 */
+
+	if (!battery_status->state) {
+		p += sprintf(p, "State:                   ok\n"); 
+	}
+	else {
+		if (battery_status->state & 0x1)
+			p += sprintf(p, "State:                   discharging\n");
+		if (battery_status->state & 0x2)
+			p += sprintf(p, "State:                   charging\n");
+		if (battery_status->state & 0x4)
+			p += sprintf(p, "State:                   critically low\n");
+	}
+
+	if (battery_status->present_rate == BT_UNKNOWN) {
+		p += sprintf(p, "Present Rate:            unknown\n");
+	}
+	else {
+		p += sprintf(p, "Present Rate:            %d %s\n",
+			battery_status->present_rate, 
+			battery->power_units);
+	}
+
+	if (battery_status->remaining_capacity == BT_UNKNOWN) {
+		p += sprintf(p, "Remaining Capacity:      unknown\n");
+	}
+	else {
+		p += sprintf(p, "Remaining Capacity:      %d %sh\n",
+			battery_status->remaining_capacity, 
+			battery->power_units);
+	}
+
+	if (battery_status->present_voltage == BT_UNKNOWN) {
+		p += sprintf(p, "Battery Voltage:         unknown\n");
+	}
+	else {
+		p += sprintf(p, "Battery Voltage:         %d mV\n",
+			battery_status->present_voltage);
+	}
+
+end:
+	len = (p - page);
+	if (len <= off+count) *eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len>count) len = count;
+	if (len<0) len = 0;
+
+	acpi_os_free(battery_status);
+
+	return(len);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	bt_osl_add_device
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bt_osl_add_device(
+	BT_CONTEXT		*battery)
+{
+	struct proc_dir_entry	*proc_entry = NULL;
+
+	if (!battery) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	if (battery->is_present) {
+		printk("Battery: socket found, battery present\n");
+	}
+	else {
+		printk("Battery: socket found, battery absent\n");
+	}
+
+	proc_entry = proc_mkdir(battery->uid, bt_proc_root);
+	if (!proc_entry) {
+		return(AE_ERROR);
+	}
+
+	create_proc_read_entry(BT_PROC_STATUS, S_IFREG | S_IRUGO, 
+		proc_entry, bt_osl_proc_read_status, (void*)battery);
+
+	create_proc_read_entry(BT_PROC_INFO, S_IFREG | S_IRUGO, 
+		proc_entry, bt_osl_proc_read_info, (void*)battery);
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	bt_osl_remove_device
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bt_osl_remove_device (
+	BT_CONTEXT		*battery)
+{
+	char			proc_entry[64];
+
+	if (!battery) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	sprintf(proc_entry, "%s/%s", battery->uid, BT_PROC_INFO);
+	remove_proc_entry(proc_entry, bt_proc_root);
+
+	sprintf(proc_entry, "%s/%s", battery->uid, BT_PROC_STATUS);
+	remove_proc_entry(proc_entry, bt_proc_root);
+
+	sprintf(proc_entry, "%s", battery->uid);
+	remove_proc_entry(proc_entry, bt_proc_root);
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	bt_osl_generate_event
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bt_osl_generate_event (
+	u32			event,
+	BT_CONTEXT		*battery)
+{
+	ACPI_STATUS		status = AE_OK;
+
+	if (!battery) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	switch (event) {
+
+	case BT_NOTIFY_STATUS_CHANGE:
+	case BT_NOTIFY_INFORMATION_CHANGE:
+		status = bm_osl_generate_event(battery->device_handle, 
+			BT_PROC_ROOT, battery->uid, event, 0);
+		break;
+
+	default:
+		return(AE_BAD_PARAMETER);
+		break;
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	bt_osl_init
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	0: Success
+ *
+ * DESCRIPTION: Module initialization.
+ *
+ ****************************************************************************/
+
+static int __init 
+bt_osl_init (void)
+{
+	ACPI_STATUS		status = AE_OK;
+
+	bt_proc_root = proc_mkdir(BT_PROC_ROOT, bm_proc_root);
+	if (!bt_proc_root) {
+		status = AE_ERROR;
+	}
+	else {
+		status = bt_initialize();
+		if (ACPI_FAILURE(status)) {
+			remove_proc_entry(BT_PROC_ROOT, bm_proc_root);
+		}
+	}
+
+	return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	bt_osl_cleanup
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	<none>
+ *
+ * DESCRIPTION: Module cleanup.
+ *
+ ****************************************************************************/
+
+static void __exit 
+bt_osl_cleanup (void)
+{
+	bt_terminate();
+
+	if (bt_proc_root) {
+		remove_proc_entry(BT_PROC_ROOT, bm_proc_root);
+	}
+
+	return;
+}
+
+
+module_init(bt_osl_init);
+module_exit(bt_osl_cleanup);
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/busmgr/Makefile linux/drivers/acpi/ospm/busmgr/Makefile
--- v2.4.5/linux/drivers/acpi/ospm/busmgr/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/busmgr/Makefile	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,6 @@
+O_TARGET	:= ospm_$(notdir $(CURDIR)).o
+obj-m		:= $(O_TARGET)
+EXTRA_CFLAGS	+= $(ACPI_CFLAGS)
+obj-y		:= $(patsubst %.c,%.o,$(wildcard *.c))
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/busmgr/bm.c linux/drivers/acpi/ospm/busmgr/bm.c
--- v2.4.5/linux/drivers/acpi/ospm/busmgr/bm.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/busmgr/bm.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,1144 @@
+/******************************************************************************
+ *
+ * Module Name: bm.c
+ *   $Revision: 42 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <acpi.h>
+#include "bm.h"
+
+
+#define _COMPONENT		ACPI_BUS
+	MODULE_NAME		("bm")
+
+
+/****************************************************************************
+ *                                  Globals
+ ****************************************************************************/
+
+extern FADT_DESCRIPTOR_REV2	acpi_fadt;
+/* TBD: Make dynamically sizeable. */
+BM_NODE_LIST			node_list;
+
+
+/****************************************************************************
+ *                            Internal Functions
+ ****************************************************************************/
+
+/*****************************************************************************
+ * 
+ * FUNCTION:    bm_print_object
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+void
+bm_print_object (
+	ACPI_HANDLE		acpi_handle)
+{
+	ACPI_BUFFER		buffer;
+	ACPI_HANDLE		parent;
+	ACPI_OBJECT_TYPE	type;
+
+	buffer.length = 256;
+	buffer.pointer = acpi_os_callocate(buffer.length);
+	if (!buffer.pointer) {
+		return;
+	}
+
+	acpi_get_name(acpi_handle, ACPI_FULL_PATHNAME, &buffer);
+	acpi_get_parent(acpi_handle, &parent);
+	acpi_get_type(acpi_handle, &type);
+
+	/*
+	 * TBD: Hack to get around scope identification problem.
+	 */
+	if (type == ACPI_TYPE_ANY) {
+		if (ACPI_SUCCESS(acpi_get_next_object(ACPI_TYPE_ANY, 
+			acpi_handle, 0, NULL))) {
+			type = INTERNAL_TYPE_SCOPE;
+		}
+	}
+    
+	switch (type)
+	{
+	case INTERNAL_TYPE_SCOPE:
+		acpi_os_printf("SCOPE: ");
+		break;
+	case ACPI_TYPE_INTEGER:
+		acpi_os_printf("SIMPLE (number): ");
+		break;
+	case ACPI_TYPE_STRING:
+		acpi_os_printf("SIMPLE (string): ");
+		break;
+	case ACPI_TYPE_BUFFER:
+		acpi_os_printf("SIMPLE (buffer): ");
+		break;
+	case ACPI_TYPE_PACKAGE:
+		acpi_os_printf("SIMPLE (package): ");
+		break;
+	case ACPI_TYPE_FIELD_UNIT:
+		acpi_os_printf("FIELD UNIT: ");
+		break;
+	case ACPI_TYPE_DEVICE:
+		acpi_os_printf("DEVICE: ");
+		break;
+	case ACPI_TYPE_EVENT:
+		acpi_os_printf("EVENT: ");
+		break;
+	case ACPI_TYPE_METHOD:
+		acpi_os_printf("CONTROL METHOD: ");
+		break;
+	case ACPI_TYPE_MUTEX:
+		acpi_os_printf("MUTEX: ");
+		break;
+	case ACPI_TYPE_REGION:
+		acpi_os_printf("OPERATION REGION: ");
+		break;
+	case ACPI_TYPE_POWER:
+		acpi_os_printf("POWER RESOURCE: ");
+		break;
+	case ACPI_TYPE_PROCESSOR:
+		acpi_os_printf("PROCESSOR: ");
+		break;
+	case ACPI_TYPE_THERMAL:
+		acpi_os_printf("THERMAL ZONE: ");
+		break;
+	case ACPI_TYPE_BUFFER_FIELD:
+		acpi_os_printf("BUFFER FIELD: ");
+		break;
+	case ACPI_TYPE_DDB_HANDLE:
+		acpi_os_printf("DDB HANDLE: ");
+		break;
+	default:
+		acpi_os_printf("OTHER (%d): ", type);
+		break;
+	}
+
+	acpi_os_printf("Object[%p][%s] parent[%p].\n", acpi_handle, (char*)buffer.pointer, parent);
+
+	acpi_os_free(buffer.pointer);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_print_node
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+void
+bm_print_node (
+	BM_NODE			*node,
+	u32                     flags)
+{
+#ifdef ACPI_DEBUG
+	ACPI_BUFFER             buffer;
+	BM_DEVICE		*device = NULL;
+	char                    *type_string = NULL;
+
+	if (!node) {
+		return;
+	}
+
+	device = &(node->device);
+
+	if (flags & BM_PRINT_PRESENT) {
+		if (!BM_DEVICE_PRESENT(device)) {
+			return;
+		}
+	}
+
+	buffer.length = 256;
+	buffer.pointer = acpi_os_callocate(buffer.length);
+	if (!buffer.pointer) {
+		return;
+	}
+
+	acpi_get_name(device->acpi_handle, ACPI_FULL_PATHNAME, &buffer);
+
+	switch(device->id.type) {
+	case BM_TYPE_SYSTEM:
+		type_string = " System";
+		break;
+	case BM_TYPE_SCOPE: 
+		type_string = "  Scope";
+		break;
+	case BM_TYPE_PROCESSOR:
+		type_string = "   Proc";
+		break;
+	case BM_TYPE_THERMAL_ZONE:
+		type_string = "Thermal";
+		break;
+	case BM_TYPE_POWER_RESOURCE:
+		type_string = "  Power";
+		break;
+	case BM_TYPE_FIXED_BUTTON:
+		type_string = " Button";
+		break;
+	case BM_TYPE_DEVICE:
+		type_string = " Device";
+		break;
+	default:
+		type_string = "Unknown";
+		break;
+	}
+
+	if (!(flags & BM_PRINT_GROUP)) {
+		DEBUG_PRINT_RAW(ACPI_INFO, ("+-------------------------------------------------------------------------------\n"));
+	}
+
+	DEBUG_PRINT_RAW(ACPI_INFO, ("| %s[%02x]:[%p] flags[%02x] hid[%s] %s\n", type_string, device->handle, device->acpi_handle, device->flags, (device->id.hid[0] ? device->id.hid : "       "), buffer.pointer));
+
+	if (flags & BM_PRINT_IDENTIFICATION) {
+		DEBUG_PRINT_RAW(ACPI_INFO, ("|   identification: uid[%s] adr[%08x]\n", device->id.uid, device->id.adr));
+	}
+
+	if (flags & BM_PRINT_LINKAGE) {
+		DEBUG_PRINT_RAW(ACPI_INFO, ("|   linkage: this[%p] parent[%p] next[%p]\n", node, node->parent, node->next));
+		DEBUG_PRINT_RAW(ACPI_INFO, ("|     scope.head[%p] scope.tail[%p]\n", node->scope.head, node->scope.tail));
+	}
+
+	if (flags & BM_PRINT_POWER) {
+		DEBUG_PRINT_RAW(ACPI_INFO, ("|   power: state[D%d] flags[%08x]\n", device->power.state, device->power.flags));
+		DEBUG_PRINT_RAW(ACPI_INFO, ("|     S0[%02x] S1[%02x] S2[%02x] S3[%02x] S4[%02x] S5[%02x]\n", device->power.dx_supported[0], device->power.dx_supported[1], device->power.dx_supported[2], device->power.dx_supported[3], device->power.dx_supported[4], device->power.dx_supported[5]));
+	}
+
+	if (!(flags & BM_PRINT_GROUP)) {
+		DEBUG_PRINT_RAW(ACPI_INFO, ("+-------------------------------------------------------------------------------\n"));
+	}
+
+	acpi_os_free(buffer.pointer);
+#endif /*ACPI_DEBUG*/
+
+	return;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_print_hierarchy
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+void
+bm_print_hierarchy (void)
+{
+#ifdef ACPI_DEBUG
+	u32			i = 0;
+
+	FUNCTION_TRACE("bm_print_hierarchy");
+
+	DEBUG_PRINT_RAW(ACPI_INFO, ("+------------------------------------------------------------\n"));
+
+	for (i = 0; i < node_list.count; i++) {
+		bm_print_node(node_list.nodes[i], BM_PRINT_GROUP | BM_PRINT_PRESENT);
+	}
+
+	DEBUG_PRINT_RAW(ACPI_INFO, ("+------------------------------------------------------------\n"));
+#endif /*ACPI_DEBUG*/
+
+	return_VOID;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_get_status
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_get_status (
+	BM_DEVICE		*device)
+{
+	ACPI_STATUS             status = AE_OK;
+
+	if (!device) {
+		return AE_BAD_PARAMETER;
+	}
+
+	device->status = BM_STATUS_UNKNOWN;
+
+	/*
+	 * Dynamic Status?
+	 * ---------------
+	 * If _STA isn't present we just return the default status.
+	 */
+	if (!(device->flags & BM_FLAGS_DYNAMIC_STATUS)) {
+		device->status = BM_STATUS_DEFAULT;
+		return AE_OK;
+	}
+
+	/*
+	 * Evaluate _STA:
+	 * --------------
+	 */
+	status = bm_evaluate_simple_integer(device->acpi_handle, "_STA", 
+		&(device->status));
+
+	return status;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_get_identification
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_get_identification (
+	BM_DEVICE		*device)
+{
+	ACPI_STATUS             status = AE_OK;
+	ACPI_DEVICE_INFO        info;
+
+	if (!device) {
+		return AE_BAD_PARAMETER;
+	}
+
+	if (!(device->flags & BM_FLAGS_IDENTIFIABLE)) {
+		return AE_OK;
+	}
+
+	device->id.uid[0] = BM_UID_UNKNOWN;
+	device->id.hid[0] = BM_HID_UNKNOWN;
+	device->id.adr = BM_ADDRESS_UNKNOWN;
+
+	/*
+	 * Get Object Info:
+	 * ----------------
+	 * Evalute _UID, _HID, and _ADR...
+	 */
+	status = acpi_get_object_info(device->acpi_handle, &info);
+	if (ACPI_FAILURE(status)) {
+		return status;
+	}
+
+	if (info.valid & ACPI_VALID_UID) {
+		MEMCPY((void*)device->id.uid, (void*)info.unique_id, 
+			sizeof(BM_DEVICE_UID));
+	}
+
+	if (info.valid & ACPI_VALID_HID) {
+		MEMCPY((void*)device->id.hid, (void*)info.hardware_id, 
+			sizeof(BM_DEVICE_HID));
+	}
+
+	if (info.valid & ACPI_VALID_ADR) {
+		device->id.adr = info.address;
+	}
+
+	return status;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_get_flags
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_get_flags (
+	BM_DEVICE		*device)
+{
+	ACPI_HANDLE             acpi_handle = NULL;
+
+	if (!device) {
+		return AE_BAD_PARAMETER;
+	}
+
+	device->flags = BM_FLAGS_UNKNOWN;
+
+	switch (device->id.type) {
+
+	case BM_TYPE_DEVICE:
+
+		/*
+		 * Presence of _DCK indicates a docking station.
+		 */
+		if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, 
+			"_DCK", &acpi_handle))) {
+			device->flags |= BM_FLAGS_DOCKING_STATION;
+		}
+
+		/*
+		 * Presence of _EJD and/or _EJx indicates 'ejectable'.
+		 * TBD: _EJx...
+		 */
+		if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, 
+			"_EJD", &acpi_handle))) {
+			device->flags |= BM_FLAGS_EJECTABLE;
+		}
+
+		/*
+		 * Presence of _PR0 or _PS0 indicates 'power manageable'.
+		 */
+		if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, 
+			"_PR0", &acpi_handle)) ||
+			ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, 
+			"_PS0", &acpi_handle))) {
+			device->flags |= BM_FLAGS_POWER_CONTROL;
+		}
+
+		/*
+		 * Presence of _CRS indicates 'configurable'.
+		 */
+		if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, 
+			"_CRS", &acpi_handle))) {
+			device->flags |= BM_FLAGS_CONFIGURABLE;
+		}
+
+		/* Fall through to next case statement. */
+
+	case BM_TYPE_PROCESSOR:
+	case BM_TYPE_THERMAL_ZONE:
+	case BM_TYPE_POWER_RESOURCE:
+		/*
+		 * Presence of _HID or _ADR indicates 'identifiable'.
+		 */
+		if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, 
+			"_HID", &acpi_handle)) ||
+		   ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, 
+		   "_ADR", &acpi_handle))) {
+			device->flags |= BM_FLAGS_IDENTIFIABLE;
+		}
+
+		/*
+		 * Presence of _STA indicates 'dynamic status'.
+		 */
+		if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, 
+			"_STA", &acpi_handle))) {
+			device->flags |= BM_FLAGS_DYNAMIC_STATUS;
+		}
+
+		break;
+	}
+
+	return AE_OK;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_add_namespace_device
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_add_namespace_device (
+	ACPI_HANDLE             acpi_handle,
+	ACPI_OBJECT_TYPE        acpi_type,
+	BM_NODE			*parent,
+	BM_NODE			**child)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_NODE			*node = NULL;
+	BM_DEVICE		*device = NULL;
+
+	FUNCTION_TRACE("bm_add_namespace_device");
+
+	if (!parent || !child) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	if (node_list.count > BM_HANDLES_MAX) {
+		return_ACPI_STATUS(AE_NO_MEMORY);
+	}
+
+	(*child) = NULL;
+
+	/*
+	 * Create Node:
+	 * ------------
+	 */
+	node = acpi_os_callocate(sizeof(BM_NODE));
+	if (!node) {
+		return_ACPI_STATUS(AE_NO_MEMORY);
+	}
+
+	node->parent = parent;
+	node->next = NULL;
+
+	device = &(node->device);
+
+	device->handle = node_list.count;
+	device->acpi_handle = acpi_handle;
+
+	/*
+	 * Device Type:
+	 * ------------
+	 */ 
+	switch (acpi_type) {
+	case INTERNAL_TYPE_SCOPE:
+		device->id.type = BM_TYPE_SCOPE;
+		break;
+	case ACPI_TYPE_PROCESSOR:
+		device->id.type = BM_TYPE_PROCESSOR;
+		break;
+	case ACPI_TYPE_THERMAL:
+		device->id.type = BM_TYPE_THERMAL_ZONE;
+		break;
+	case ACPI_TYPE_POWER:
+		device->id.type = BM_TYPE_POWER_RESOURCE;
+		break;
+	case ACPI_TYPE_DEVICE:
+		device->id.type = BM_TYPE_DEVICE;
+		break;
+	}
+
+	/*
+	 * Get Other Device Info:
+	 * ----------------------
+	 * But only if this device's parent is present (which implies
+	 * this device MAY be present).
+	 */
+	if (BM_NODE_PRESENT(node->parent)) {
+		/*
+		 * Device Flags
+		 */
+		status = bm_get_flags(device);
+		if (ACPI_FAILURE(status)) {
+			goto end;
+		}
+
+		/*
+		 * Device Identification
+		 */
+		status = bm_get_identification(device);
+		if (ACPI_FAILURE(status)) {
+			goto end;
+		}
+
+		/*
+		 * Device Status
+		 */
+		status = bm_get_status(device);
+		if (ACPI_FAILURE(status)) {
+			goto end;
+		}
+
+		/*
+		 * Power Management:
+		 * -----------------
+		 * If this node doesn't provide direct power control  
+		 * then we inherit PM capabilities from its parent.
+		 *
+		 * TBD: Inherit!
+		 */
+		if (BM_IS_POWER_CONTROL(device)) {
+			status = bm_get_pm_capabilities(node);
+			if (ACPI_FAILURE(status)) {
+				goto end;
+			}
+		}
+	}
+
+end:
+	if (ACPI_FAILURE(status)) {
+		acpi_os_free(node);
+	}
+	else {
+		/*
+		 * Add to the node_list.
+		 */
+		node_list.nodes[node_list.count++] = node;
+
+		/*
+		 * Formulate Hierarchy:
+		 * --------------------
+		 * Arrange within the namespace by assigning the parent and
+		 * adding to the parent device's list of children (scope).
+		 */
+		if (!parent->scope.head) {
+			parent->scope.head = node;
+		}
+		else {
+			if (!parent->scope.tail) {
+				(parent->scope.head)->next = node;
+			}
+			else {
+				(parent->scope.tail)->next = node;
+			}
+		}
+		parent->scope.tail = node;
+
+		(*child) = node;
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_enumerate_namespace
+ *
+ * PARAMETERS:  <none>
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_enumerate_namespace (void)
+{
+	ACPI_STATUS		status = AE_OK;
+	ACPI_HANDLE             parent_handle = ACPI_ROOT_OBJECT;
+	ACPI_HANDLE             child_handle = NULL;
+	BM_NODE			*parent = NULL;
+	BM_NODE			*child = NULL;
+	ACPI_OBJECT_TYPE        acpi_type = 0;
+	u32                     level = 1;
+
+	FUNCTION_TRACE("bm_enumerate_namespace");
+
+	parent = node_list.nodes[0];
+
+	/*
+	 * Enumerate ACPI Namespace:
+	 * -------------------------
+	 * Parse through the ACPI namespace, identify all 'devices',
+	 * and create a new entry for each in our collection.
+	 */
+	while (level > 0) {
+
+		/*
+		 * Get the next object at this level.
+		 */
+		status = acpi_get_next_object(ACPI_TYPE_ANY, parent_handle, child_handle, &child_handle);
+		if (ACPI_SUCCESS(status)) {
+			/*
+			 * TBD: This is a hack to get around the problem 
+			 *       identifying scope objects.  Scopes 
+			 *       somehow need to be uniquely identified.
+			 */
+			status = acpi_get_type(child_handle, &acpi_type);
+			if (ACPI_SUCCESS(status) && (acpi_type == ACPI_TYPE_ANY)) {
+				status = acpi_get_next_object(ACPI_TYPE_ANY, child_handle, 0, NULL);
+				if (ACPI_SUCCESS(status)) {
+					acpi_type = INTERNAL_TYPE_SCOPE;
+				}
+			}
+
+			/*
+			 * Device?
+			 * -------
+			 * If this object is a 'device', insert into the
+			 * ACPI Bus Manager's local hierarchy and search
+			 * the object's scope for any child devices (a
+			 * depth-first search).
+			 */
+			switch (acpi_type) {
+			case INTERNAL_TYPE_SCOPE:
+			case ACPI_TYPE_DEVICE:
+			case ACPI_TYPE_PROCESSOR:
+			case ACPI_TYPE_THERMAL:
+			case ACPI_TYPE_POWER:
+				status = bm_add_namespace_device(child_handle, acpi_type, parent, &child);
+				if (ACPI_SUCCESS(status)) {
+					status = acpi_get_next_object(ACPI_TYPE_ANY, child_handle, 0, NULL);
+					if (ACPI_SUCCESS(status)) {
+						level++;
+						parent_handle = child_handle;
+						child_handle = 0;
+						parent = child;
+					}
+				}
+				break;
+			}
+		}
+
+		/*
+		 * Scope Exhausted:
+		 * ----------------
+		 * No more children in this object's scope, Go back up
+		 * in the namespace tree to the object's parent.
+		 */
+		else {
+			level--;
+			child_handle = parent_handle;
+			acpi_get_parent(parent_handle, 
+				&parent_handle);
+
+			if (parent) {
+				parent = parent->parent;
+			}
+			else {
+				return_ACPI_STATUS(AE_NULL_ENTRY);
+			}
+		}
+	}
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_add_fixed_feature_device
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_add_fixed_feature_device (
+	BM_NODE			*parent,
+	BM_DEVICE_TYPE		device_type,
+	char			*device_hid)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_NODE			*node = NULL;
+
+	FUNCTION_TRACE("bm_add_fixed_feature_device");
+
+	if (!parent) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	if (node_list.count > BM_HANDLES_MAX) {
+		return_ACPI_STATUS(AE_NO_MEMORY);
+	}
+
+	/*
+	 * Allocate the new device and add to the device array.
+	 */
+	node = acpi_os_callocate(sizeof(BM_NODE));
+	if (!node) {
+		return_ACPI_STATUS(AE_NO_MEMORY);
+	}
+
+	/*
+	 * Get device info.
+	 */
+	node->device.handle = node_list.count;
+	node->device.acpi_handle = ACPI_ROOT_OBJECT;
+	node->device.id.type = BM_TYPE_FIXED_BUTTON;
+	if (device_hid) {
+		MEMCPY((void*)node->device.id.hid, device_hid, 
+			sizeof(node->device.id.hid));
+	}
+	node->device.flags = BM_FLAGS_FIXED_FEATURE;
+	node->device.status = BM_STATUS_DEFAULT;
+	/* TBD: Device PM capabilities */
+
+	/*
+	 * Add to the node_list.
+	 */
+	node_list.nodes[node_list.count++] = node;
+
+	/*
+	 * Formulate Hierarchy:
+	 * --------------------
+	 * Arrange within the namespace by assigning the parent and
+	 * adding to the parent device's list of children (scope).
+	 */
+	node->parent = parent;
+	node->next = NULL;
+
+	if (parent) {
+		if (!parent->scope.head) {
+			parent->scope.head = node;
+		}
+		else {
+			if (!parent->scope.tail) {
+				(parent->scope.head)->next = node;
+			}
+			else {
+				(parent->scope.tail)->next = node;
+			}
+		}
+		parent->scope.tail = node;
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_enumerate_fixed_features
+ *
+ * PARAMETERS:  <none>
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_enumerate_fixed_features (void)
+{
+	FUNCTION_TRACE("bm_enumerate_fixed_features");
+
+	/*
+	 * Root Object:
+	 * ------------
+	 * Fabricate the root object, which happens to always get a
+	 * device_handle of zero.
+	 */
+	node_list.nodes[0] = acpi_os_callocate(sizeof(BM_NODE));
+	if (NULL == (node_list.nodes[0])) {
+		return_ACPI_STATUS(AE_NO_MEMORY);
+	}
+
+	node_list.nodes[0]->device.handle = BM_HANDLE_ROOT;
+	node_list.nodes[0]->device.acpi_handle = ACPI_ROOT_OBJECT;
+	node_list.nodes[0]->device.flags = BM_FLAGS_UNKNOWN;
+	node_list.nodes[0]->device.status = BM_STATUS_DEFAULT;
+	node_list.nodes[0]->device.id.type = BM_TYPE_SYSTEM;
+	/* TBD: Get system PM capabilities (Sx states?) */
+
+	node_list.count++;
+
+	/*
+	 * Fixed Features:
+	 * ---------------
+	 * Enumerate fixed-feature devices (e.g. power and sleep buttons).
+	 */
+	if (acpi_fadt.pwr_button == 0) {
+		bm_add_fixed_feature_device(node_list.nodes[0],
+			BM_TYPE_FIXED_BUTTON, BM_HID_POWER_BUTTON);
+	}
+
+	if (acpi_fadt.sleep_button == 0) {
+		bm_add_fixed_feature_device(node_list.nodes[0],
+			BM_TYPE_FIXED_BUTTON, BM_HID_SLEEP_BUTTON);
+	}
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_get_handle
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_get_handle (
+	ACPI_HANDLE             acpi_handle,
+	BM_HANDLE               *device_handle)
+{
+	ACPI_STATUS             status = AE_NOT_FOUND;
+	u32			i = 0;
+
+	FUNCTION_TRACE("bm_get_handle");
+
+	if (!device_handle) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	*device_handle = BM_HANDLE_UNKNOWN;
+
+	/*
+	 * Search all devices for a match on the ACPI handle.
+	 */
+	for (i=0; i<node_list.count; i++) {
+
+		if (!node_list.nodes[i]) {
+			DEBUG_PRINT(ACPI_ERROR, ("Invalid (NULL) node entry [%02x] detected.\n", device_handle));
+			status = AE_NULL_ENTRY;
+			break;
+		}
+
+		if (node_list.nodes[i]->device.acpi_handle == acpi_handle) {
+			*device_handle = node_list.nodes[i]->device.handle;
+			status = AE_OK;
+			break;
+		}
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_get_node
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_get_node (
+	BM_HANDLE               device_handle,
+	ACPI_HANDLE             acpi_handle,
+	BM_NODE			**node)
+{
+	ACPI_STATUS             status = AE_OK;
+
+	FUNCTION_TRACE("bm_get_node");
+
+	if (!node) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	/* busmgr failed to init, but we're being called by subordinate drivers */
+	if (node_list.count < 1) {
+		return_ACPI_STATUS(AE_NOT_FOUND);
+	}
+
+	/*
+	 * If no device handle, resolve acpi handle to device handle.
+	 */
+	if (!device_handle && acpi_handle) {
+		status = bm_get_handle(acpi_handle, &device_handle);
+		if (ACPI_FAILURE(status))
+			return_ACPI_STATUS(status);
+	}
+
+	/*
+	 * Valid device handle?
+	 */
+	if (device_handle > BM_HANDLES_MAX) {
+		DEBUG_PRINT(ACPI_ERROR, ("Invalid node handle [%02x] detected.\n", device_handle));
+		return_ACPI_STATUS(AE_ERROR);
+	}
+
+	*node = node_list.nodes[device_handle];
+
+	/*
+	 * Valid node?
+	 */
+	if (!(*node)) {
+		DEBUG_PRINT(ACPI_ERROR, ("Invalid (NULL) node entry [%02x] detected.\n", device_handle));
+		return_ACPI_STATUS(AE_NULL_ENTRY);
+	}
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+
+/****************************************************************************
+ *                            External Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_initialize
+ *
+ * PARAMETERS:  <none>
+ *
+ * RETURN:      Exception code.
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_initialize (void)
+{
+	ACPI_STATUS             status = AE_OK;
+	u32                     start = 0;
+	u32                     stop = 0;
+	u32                     elapsed = 0;
+
+	FUNCTION_TRACE("bm_initialize");
+
+	MEMSET(&node_list, 0, sizeof(BM_NODE_LIST));
+
+	status = acpi_get_timer(&start);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	DEBUG_PRINT(ACPI_INFO, ("Building device hierarchy.\n"));
+
+	/*
+	 * Enumerate ACPI fixed-feature devices.
+	 */
+	status = bm_enumerate_fixed_features();
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	/*
+	 * Enumerate the ACPI namespace.
+	 */
+	status = bm_enumerate_namespace();
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	acpi_get_timer(&stop);
+	acpi_get_timer_duration(start, stop, &elapsed);
+
+	DEBUG_PRINT(ACPI_INFO, ("Building device hierarchy took [%d] microseconds.\n", elapsed));
+
+	/*
+	 * Display hierarchy.
+	 */
+	bm_print_hierarchy();
+
+	/*
+	 * Register for all standard and device-specific notifications.
+	 */
+	DEBUG_PRINT(ACPI_INFO, ("Registering for all device notifications.\n"));
+
+	status = acpi_install_notify_handler(ACPI_ROOT_OBJECT, 
+		ACPI_SYSTEM_NOTIFY, &bm_notify, NULL);
+	if (ACPI_FAILURE(status)) {
+		DEBUG_PRINT(ACPI_ERROR, ("Unable to register for standard notifications.\n"));
+		return_ACPI_STATUS(status);
+	}
+
+	status = acpi_install_notify_handler(ACPI_ROOT_OBJECT, 
+		ACPI_DEVICE_NOTIFY, &bm_notify, NULL);
+	if (ACPI_FAILURE(status)) {
+		DEBUG_PRINT(ACPI_ERROR, ("Unable to register for device-specific notifications.\n"));
+		return_ACPI_STATUS(status);
+	}
+
+	DEBUG_PRINT(ACPI_INFO, ("ACPI Bus Manager enabled.\n"));
+
+	/*
+	 * Initialize built-in power resource driver.
+	 */
+	bm_pr_initialize();
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_terminate
+ *
+ * PARAMETERS:  <none>
+ *
+ * RETURN:      Exception code.
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_terminate (void)
+{
+	ACPI_STATUS             status = AE_OK;
+	u32                     i = 0;
+
+	FUNCTION_TRACE("bm_terminate");
+
+	/*
+	 * Terminate built-in power resource driver.
+	 */
+	bm_pr_terminate();
+
+	/*
+	 * Unregister for all notifications.
+	 */
+	DEBUG_PRINT(ACPI_INFO, ("Unregistering for device notifications.\n"));
+
+	status = acpi_remove_notify_handler(ACPI_ROOT_OBJECT, 
+		ACPI_SYSTEM_NOTIFY, &bm_notify);
+	if (ACPI_FAILURE(status)) {
+		DEBUG_PRINT(ACPI_ERROR, ("Unable to un-register for standard notifications.\n"));
+	}
+
+	status = acpi_remove_notify_handler(ACPI_ROOT_OBJECT, 
+		ACPI_DEVICE_NOTIFY, &bm_notify);
+	if (ACPI_FAILURE(status)) {
+		DEBUG_PRINT(ACPI_ERROR, ("Unable to un-register for device-specific notifications.\n"));
+	}
+
+	/*
+	 * Parse through the device array, freeing all entries.
+	 */
+	DEBUG_PRINT(ACPI_INFO, ("Removing device hierarchy.\n"));
+	for (i = 0; i < node_list.count; i++) {
+		if (node_list.nodes[i]) {
+			acpi_os_free(node_list.nodes[i]);
+		}
+	}
+
+	DEBUG_PRINT(ACPI_INFO, ("ACPI Bus Manager disabled.\n"));
+
+	return_ACPI_STATUS(AE_OK);
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/busmgr/bm_osl.c linux/drivers/acpi/ospm/busmgr/bm_osl.c
--- v2.4.5/linux/drivers/acpi/ospm/busmgr/bm_osl.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/busmgr/bm_osl.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,383 @@
+/*****************************************************************************
+ *
+ * Module Name: bm_osl.c
+ *   $Revision: 11 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <asm/uaccess.h>
+#include <acpi.h>
+#include "bm.h"
+
+
+MODULE_AUTHOR("Andrew Grover");
+MODULE_DESCRIPTION("ACPI Component Architecture (CA) - ACPI Bus Manager");
+
+
+#ifdef ACPI_DEBUG
+
+static int dbg_layer = ACPI_COMPONENT_DEFAULT;
+MODULE_PARM(dbg_layer, "i");
+MODULE_PARM_DESC(dbg_layer, "Controls debug output (see acpi_dbg_layer).\n");
+
+static int dbg_level = DEBUG_DEFAULT;
+MODULE_PARM(dbg_level, "i");
+MODULE_PARM_DESC(dbg_level, "Controls debug output (see acpi_dbg_level).\n");
+
+#endif /*ACPI_DEBUG*/
+
+
+/*****************************************************************************
+ *                               Types & Defines
+ *****************************************************************************/
+
+typedef struct
+{
+	BM_HANDLE		device_handle;
+	char			*device_type;
+	char			*device_instance;
+	u32			event_type;
+	u32			event_data;
+	struct list_head	list;
+} BM_OSL_EVENT;
+
+
+#define BM_PROC_ROOT		"acpi"
+#define BM_PROC_EVENT		"event"
+#define BM_PROC_DEVICES		"devices"
+
+#define BM_MAX_STRING_LENGTH	80
+
+
+/****************************************************************************
+ *                                  Globals
+ ****************************************************************************/
+
+struct proc_dir_entry		*bm_proc_root = NULL;
+static struct proc_dir_entry	*bm_proc_event = NULL;
+
+#ifdef ACPI_DEBUG
+static u32			save_dbg_layer;
+static u32			save_dbg_level;
+#endif /*ACPI_DEBUG*/
+
+extern BM_NODE_LIST		node_list;
+
+static spinlock_t		bm_osl_event_lock = SPIN_LOCK_UNLOCKED;
+
+static LIST_HEAD(bm_event_list);
+
+static DECLARE_WAIT_QUEUE_HEAD(bm_event_wait_queue);
+
+static int event_is_open = 0;
+
+
+/****************************************************************************
+ *                                 Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:	bm_osl_generate_event
+ *
+ * DESCRIPTION: Generates an event for user-space consumption by writing
+ *              the event data to the 'event' file.
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_osl_generate_event (
+	BM_HANDLE		device_handle,
+	char			*device_type,
+	char			*device_instance,
+	u32			event_type,
+	u32			event_data)
+{
+	BM_OSL_EVENT		*event = NULL;
+	u32			flags = 0;
+
+	/* drop event on the floor if no one's listening */
+	if (!event_is_open)
+		return (AE_OK);
+
+	/*
+	 * Allocate a new event structure.
+	 */
+	event = acpi_os_callocate(sizeof(BM_OSL_EVENT));
+	if (!event)
+		goto alloc_error;
+
+	event->device_type = acpi_os_callocate(strlen(device_type) 
+		+ sizeof(char));
+	if (!event->device_type)
+		goto alloc_error;
+
+	event->device_instance = acpi_os_callocate(strlen(device_instance) 
+		+ sizeof(char));
+	if (!event->device_instance)
+		goto alloc_error;
+
+	/*
+	 * Set event data.
+	 */
+	event->device_handle = device_handle;
+	strcpy(event->device_type, device_type);
+	strcpy(event->device_instance, device_instance);
+	event->event_type = event_type;
+	event->event_data = event_data;
+
+	/*
+	 * Add to the end of our event list.
+	 */
+	spin_lock_irqsave(&bm_osl_event_lock, flags);
+	list_add_tail(&event->list, &bm_event_list);
+	spin_unlock_irqrestore(&bm_osl_event_lock, flags);
+
+	/*
+	 * Signal waiting threads (if any).
+	 */
+	wake_up_interruptible(&bm_event_wait_queue);
+
+	return(AE_OK);
+
+alloc_error:
+	if (event->device_instance)
+		acpi_os_free(event->device_instance);
+
+	if (event->device_type)
+		acpi_os_free(event->device_type);
+
+	if (event)
+		acpi_os_free(event);		
+
+	return (AE_NO_MEMORY);
+}
+
+static int bm_osl_open_event(struct inode *inode, struct file *file)
+{
+	spin_lock_irq (&bm_osl_event_lock);
+
+	if(event_is_open)
+		goto out_busy;
+
+	event_is_open = 1;
+
+	spin_unlock_irq (&bm_osl_event_lock);
+	return 0;
+
+out_busy:
+	spin_unlock_irq (&bm_osl_event_lock);
+	return -EBUSY;
+}
+
+
+static int bm_osl_close_event(struct inode *inode, struct file *file)
+{
+	event_is_open = 0;
+	return 0;
+}
+
+/****************************************************************************
+ *
+ * FUNCTION:	bm_osl_read_event
+ *
+ * DESCRIPTION: Handles reads to the 'event' file by blocking user-mode 
+ *              threads until data (an event) is generated.
+ *
+ ****************************************************************************/
+static ssize_t
+bm_osl_read_event(
+	struct file		*file, 
+	char			*buf, 
+	size_t			count, 
+	loff_t			*ppos)
+{
+	char			str[BM_MAX_STRING_LENGTH];
+	int			size;
+	BM_OSL_EVENT		*event = NULL;
+	unsigned long		flags = 0;
+
+	DECLARE_WAITQUEUE(wait, current);
+
+	if (count < BM_MAX_STRING_LENGTH) {
+		return 0;
+	}
+
+	if (list_empty(&bm_event_list)) {
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		add_wait_queue(&bm_event_wait_queue, &wait);
+
+		if (list_empty(&bm_event_list)) {
+			schedule();
+		}
+
+		remove_wait_queue(&bm_event_wait_queue, &wait);
+		set_current_state(TASK_RUNNING);
+
+		if (signal_pending(current)) {
+			return -ERESTARTSYS;
+		}
+	}
+
+	spin_lock_irqsave(&bm_osl_event_lock, flags);
+	event = list_entry(bm_event_list.next, BM_OSL_EVENT, list);
+	list_del(&event->list);
+	spin_unlock_irqrestore(&bm_osl_event_lock, flags);
+
+	/* BUG: buffer overrun? */
+	size = sprintf(str, "%s %s %08x %08x\n",
+		event->device_type, event->device_instance,
+		event->event_type, event->event_data);
+	
+	acpi_os_free(event->device_type);
+	acpi_os_free(event->device_instance);
+	acpi_os_free(event);
+
+	if (copy_to_user(buf, str, size))
+		return -EFAULT;
+
+	*ppos += size;
+
+	return size;
+}
+
+struct file_operations proc_event_operations = {
+	open:		bm_osl_open_event,
+	read:		bm_osl_read_event,
+	release:	bm_osl_close_event,
+};
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_osl_init
+ *
+ ****************************************************************************/
+
+int
+bm_osl_init(void)
+{
+	ACPI_STATUS		status = AE_OK;
+
+#ifdef ACPI_DEBUG
+	save_dbg_layer = acpi_dbg_layer;
+	acpi_dbg_layer = dbg_layer;
+
+	save_dbg_level = acpi_dbg_level;
+	acpi_dbg_level = dbg_level;
+#endif /*ACPI_DEBUG*/
+
+	bm_proc_root = proc_mkdir(BM_PROC_ROOT, NULL);
+	if (!bm_proc_root) {
+		return(AE_ERROR);
+	}
+
+	bm_proc_event = create_proc_entry(BM_PROC_EVENT, S_IRUSR, bm_proc_root);
+	if (bm_proc_event) {
+		bm_proc_event->proc_fops = &proc_event_operations;
+	}
+
+	status = bm_initialize();
+
+	return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_osl_cleanup
+ *
+ ****************************************************************************/
+
+void
+bm_osl_cleanup(void)
+{
+	bm_terminate();
+
+	if (bm_proc_event) {
+		remove_proc_entry(BM_PROC_EVENT, bm_proc_root);
+		bm_proc_event = NULL;
+	}
+
+	if (bm_proc_root) {
+		remove_proc_entry(BM_PROC_ROOT, NULL);
+		bm_proc_root = NULL;
+	}
+
+#ifdef ACPI_DEBUG
+	acpi_dbg_layer = save_dbg_layer;
+	acpi_dbg_level = save_dbg_level;
+#endif /*ACPI_DEBUG*/
+
+	return;
+}
+
+
+module_init(bm_osl_init);
+module_exit(bm_osl_cleanup);
+
+
+/****************************************************************************
+ *                                  Symbols
+ ****************************************************************************/
+
+/* bm.c */
+
+EXPORT_SYMBOL(bm_get_node);
+
+/* bmdriver.c */
+
+EXPORT_SYMBOL(bm_get_device_power_state);
+EXPORT_SYMBOL(bm_set_device_power_state);
+EXPORT_SYMBOL(bm_get_device_info);
+EXPORT_SYMBOL(bm_get_device_status);
+EXPORT_SYMBOL(bm_get_device_context);
+EXPORT_SYMBOL(bm_register_driver);
+EXPORT_SYMBOL(bm_unregister_driver);
+
+/* bmsearch.c */
+
+EXPORT_SYMBOL(bm_search);
+
+/* bmrequest.c */
+
+EXPORT_SYMBOL(bm_request);
+
+/* bmutils.c */
+
+EXPORT_SYMBOL(bm_extract_package_data);
+EXPORT_SYMBOL(bm_evaluate_object);
+EXPORT_SYMBOL(bm_evaluate_simple_integer);
+EXPORT_SYMBOL(bm_evaluate_reference_list);
+EXPORT_SYMBOL(bm_copy_to_buffer);
+EXPORT_SYMBOL(bm_cast_buffer);
+
+/* bm_proc.c */
+
+EXPORT_SYMBOL(bm_osl_generate_event);
+EXPORT_SYMBOL(bm_proc_root);
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/busmgr/bmdriver.c linux/drivers/acpi/ospm/busmgr/bmdriver.c
--- v2.4.5/linux/drivers/acpi/ospm/busmgr/bmdriver.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/busmgr/bmdriver.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,469 @@
+/*****************************************************************************
+ *
+ * Module Name: bmdriver.c
+ *   $Revision: 17 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <acpi.h>
+#include "bm.h"
+
+#define _COMPONENT		ACPI_BUS
+	MODULE_NAME		("bmdriver")
+
+
+/****************************************************************************
+ *                            External Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_get_device_power_state
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_get_device_power_state (
+	BM_HANDLE               device_handle,
+	BM_POWER_STATE		*state)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_NODE			*node = NULL;
+
+	FUNCTION_TRACE("bm_get_device_power_state");
+
+	if (!state) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	*state = ACPI_STATE_UNKNOWN;
+
+	/*
+	 * Resolve device handle to node.
+	 */
+	status = bm_get_node(device_handle, 0, &node);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	/*
+	 * Get the current power state.
+	 */
+	status = bm_get_power_state(node);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	*state = node->device.power.state;
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_set_device_power_state
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_set_device_power_state (
+	BM_HANDLE               device_handle,
+	BM_POWER_STATE		state)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_NODE			*node = NULL;
+
+	FUNCTION_TRACE("bm_set_device_power_state");
+
+	/*
+	 * Resolve device handle to node.
+	 */
+	status = bm_get_node(device_handle, 0, &node);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	/*
+	 * Set the current power state.
+	 */
+	status = bm_set_power_state(node, state);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_get_device_status
+ *
+ * PARAMETERS:  
+ *    device_handle is really an index number into the array of BM_DEVICE
+ *                  structures in info_list.  This data item is passed to
+ *                  the registered program's "notify" callback.  It is used
+ *                  to retrieve the specific BM_DEVICE structure instance
+ *                  associated with the callback.  
+ *    device_status is a pointer that receives the result of processing
+ *                  the device's associated ACPI _STA.
+ *
+ * RETURN:
+ *    The ACPI_STATUS value indicates success AE_OK or failure of the function
+ *
+ * DESCRIPTION: Evaluates the device's ACPI _STA, if it is present.
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_get_device_status (
+	BM_HANDLE               device_handle,
+	BM_DEVICE_STATUS        *device_status)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_NODE			*node = NULL;
+
+	FUNCTION_TRACE("bm_get_device_status");
+
+	if (!device_status) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	*device_status = BM_STATUS_UNKNOWN;
+
+	/*
+	 * Resolve device handle to node.
+	 */
+	status = bm_get_node(device_handle, 0, &node);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	/*
+	 * Parent Present?
+	 * ---------------
+	 * If the parent isn't present we can't evalute _STA on the child.
+	 * Return an unknown status.
+	 */
+	if (!BM_NODE_PRESENT(node->parent)) {
+		return_ACPI_STATUS(AE_OK);
+	}
+	
+	/*
+	 * Dynamic Status?
+	 * ---------------
+	 * If _STA isn't present we just return the default status.
+	 */
+	if (!(node->device.flags & BM_FLAGS_DYNAMIC_STATUS)) {
+		*device_status = BM_STATUS_DEFAULT;
+		return_ACPI_STATUS(AE_OK);
+	}
+
+	/*
+	 * Evaluate _STA:
+	 * --------------
+	 */
+	status = bm_evaluate_simple_integer(node->device.acpi_handle, "_STA", 
+		&(node->device.status));
+	if (ACPI_SUCCESS(status)) {
+		*device_status = node->device.status;
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_get_device_info
+ *
+ * PARAMETERS:
+ *    device_handle An index used to retrieve the associated BM_DEVICE info.
+ *    device        A pointer to a BM_DEVICE structure instance pointer.
+ *                  This pointed to BM_DEVICE structure will contain the
+ *                  this device's information.
+ *
+ * RETURN:
+ *    The ACPI_STATUS value indicates success AE_OK or failure of the function
+ *
+ * DESCRIPTION:
+ *    Using the device_handle this function retrieves this device's
+ *    BM_DEVICE structure instance and save's it in device.
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_get_device_info (
+	BM_HANDLE               device_handle,
+	BM_DEVICE               **device)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_NODE			*node = NULL;
+
+	FUNCTION_TRACE("bm_get_device_info");
+
+	if (!device) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Resolve device handle to internal device.
+	 */
+	status = bm_get_node(device_handle, 0, &node);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	*device = &(node->device);
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_get_device_context
+ *
+ *    device_handle An index used to retrieve the associated BM_DEVICE info.
+ *    context       A pointer to a BM_DRIVER_CONTEXT structure instance.
+ *
+ * RETURN:
+ *    The ACPI_STATUS value indicates success AE_OK or failure of the function
+ *
+ * DESCRIPTION:
+ *    Using the device_handle this function retrieves this device's
+ *    BM_DRIVER_CONTEXT structure instance and save's it in context.
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_get_device_context (
+	BM_HANDLE               device_handle,
+	BM_DRIVER_CONTEXT	*context)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_NODE			*node = NULL;
+
+	FUNCTION_TRACE("bm_get_device_context");
+
+	if (!context) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	*context = NULL;
+
+	/*
+	 * Resolve device handle to internal device.
+	 */
+	status = bm_get_node(device_handle, 0, &node);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	if (!node->driver.context) {
+		return_ACPI_STATUS(AE_NULL_ENTRY);
+	}
+
+	*context = node->driver.context;
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_register_driver
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_register_driver (
+	BM_DEVICE_ID		*criteria,
+	BM_DRIVER		*driver)
+{
+	ACPI_STATUS             status = AE_NOT_FOUND;
+	BM_HANDLE_LIST          device_list;
+	BM_NODE			*node = NULL;
+	BM_DEVICE		*device = NULL;
+	u32                     i = 0;
+
+	FUNCTION_TRACE("bm_register_driver");
+
+	if (!criteria || !driver || !driver->notify || !driver->request) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	MEMSET(&device_list, 0, sizeof(BM_HANDLE_LIST));
+
+	/*
+	 * Find Matches:
+	 * -------------
+	 * Search through the entire device hierarchy for matches against
+	 * the given device criteria.
+	 */
+	status = bm_search(BM_HANDLE_ROOT, criteria, &device_list);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	/*
+	 * Install driver:
+	 * ----------------
+	 * For each match, record the driver information and execute the 
+	 * driver's Notify() funciton (if present) to notify the driver
+	 * of the device's presence.
+	 */
+	for (i = 0; i < device_list.count; i++) {
+
+		/* Resolve the device handle. */
+		status = bm_get_node(device_list.handles[i], 0, &node);
+		if (ACPI_FAILURE(status)) {
+			continue;
+		}
+
+		device = &(node->device);
+
+		/* 
+		 * Make sure another driver hasn't already registered for 
+		 * this device. 
+		 */
+		if (BM_IS_DRIVER_CONTROL(device)) {
+			DEBUG_PRINT(ACPI_INFO, ("Another driver has already registered for device [%02x].\n", device->handle));
+			continue;
+		}
+
+		DEBUG_PRINT(ACPI_INFO, ("Registering driver for device [%02x].\n", device->handle));
+
+		/* Notify driver of new device. */
+		status = driver->notify(BM_NOTIFY_DEVICE_ADDED, 
+			node->device.handle, &(node->driver.context));
+		if (ACPI_SUCCESS(status)) {
+			node->driver.notify = driver->notify;
+			node->driver.request = driver->request;
+			node->device.flags |= BM_FLAGS_DRIVER_CONTROL;
+		}
+	}
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_unregister_driver
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_unregister_driver (
+	BM_DEVICE_ID		*criteria,
+	BM_DRIVER		*driver)
+{
+	ACPI_STATUS             status = AE_NOT_FOUND;
+	BM_HANDLE_LIST          device_list;
+	BM_NODE			*node = NULL;
+	BM_DEVICE		*device = NULL;
+	u32                     i = 0;
+
+	FUNCTION_TRACE("bm_unregister_driver");
+
+	if (!criteria || !driver || !driver->notify || !driver->request) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	MEMSET(&device_list, 0, sizeof(BM_HANDLE_LIST));
+
+	/*
+	 * Find Matches:
+	 * -------------
+	 * Search through the entire device hierarchy for matches against
+	 * the given device criteria.
+	 */
+	status = bm_search(BM_HANDLE_ROOT, criteria, &device_list);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	/*
+	 * Remove driver:
+	 * ---------------
+	 * For each match, execute the driver's Notify() function to allow
+	 * the driver to cleanup each device instance.
+	 */
+	for (i = 0; i < device_list.count; i++) {
+
+		/* Resolve the device handle. */
+		status = bm_get_node(device_list.handles[i], 0, &node);
+		if (ACPI_FAILURE(status)) {
+			continue;
+		}
+
+		device = &(node->device);
+
+		/* 
+		 * Make sure driver has really registered for this device. 
+		 */
+		if (!BM_IS_DRIVER_CONTROL(device)) {
+			DEBUG_PRINT(ACPI_INFO, ("Driver hasn't registered for device [%02x].\n", device->handle));
+			continue;
+		}
+
+		DEBUG_PRINT(ACPI_INFO, ("Unregistering driver for device [%02x].\n", device->handle));
+
+		/* Notify driver of device removal. */
+		status = node->driver.notify(BM_NOTIFY_DEVICE_REMOVED, 
+			node->device.handle, &(node->driver.context));
+		if (ACPI_SUCCESS(status)) {
+			node->driver.notify = NULL;
+			node->driver.request = NULL;
+			node->driver.context = NULL;
+			node->device.flags &= ~BM_FLAGS_DRIVER_CONTROL;
+		}
+	}
+
+	return_ACPI_STATUS(AE_OK);
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/busmgr/bmnotify.c linux/drivers/acpi/ospm/busmgr/bmnotify.c
--- v2.4.5/linux/drivers/acpi/ospm/busmgr/bmnotify.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/busmgr/bmnotify.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,312 @@
+/*****************************************************************************
+ *
+ * Module Name: bmnotify.c
+ *   $Revision: 17 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <acpi.h>
+#include "bm.h"
+
+
+#define _COMPONENT		ACPI_BUS
+	 MODULE_NAME		("bmnotify")
+
+
+/****************************************************************************
+ *                            Internal Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_generate_notify
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_generate_notify (
+	BM_NODE			*node,
+	u32			notify_type)
+{
+	ACPI_STATUS		status = AE_OK;
+	BM_DEVICE		*device = NULL;
+
+	FUNCTION_TRACE("bm_generate_notify");
+
+	if (!node) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	device = &(node->device);
+
+	DEBUG_PRINT(ACPI_INFO, ("Sending notify [%02x] to device [%02x].\n", notify_type, node->device.handle));
+
+	if (!BM_IS_DRIVER_CONTROL(device)) {
+		DEBUG_PRINT(ACPI_INFO, ("No driver installed for device [%02x].\n", device->handle));
+		return_ACPI_STATUS(AE_NOT_EXIST);
+	}
+
+	status = node->driver.notify(notify_type, node->device.handle, 
+		&(node->driver.context));
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_device_check
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_device_check (
+	BM_NODE			*node,
+	u32			*status_change)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_DEVICE		*device = NULL;
+	BM_DEVICE_STATUS	old_status = BM_STATUS_UNKNOWN;
+
+	FUNCTION_TRACE("bm_device_check");
+
+	if (!node) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	device = &(node->device);
+
+	if (status_change) {
+		*status_change = FALSE;
+	}
+
+	old_status = device->status;
+
+	/*
+	 * Parent Present?
+	 * ---------------
+	 * Only check this device if its parent is present (which implies
+	 * this device MAY be present).
+	 */
+	if (!BM_NODE_PRESENT(node->parent)) {
+		return_ACPI_STATUS(AE_OK);
+	}
+
+	/*
+	 * Get Status:
+	 * -----------
+	 * And see if the status has changed.
+	 */
+	status = bm_get_status(device);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+	
+	if (old_status == node->device.status) {
+		return_ACPI_STATUS(AE_OK);
+	}
+
+	if (status_change) {
+		*status_change = TRUE;
+	}
+	
+	/*
+	 * Device Insertion?
+	 * -----------------
+	 */
+	if ((device->status & BM_STATUS_PRESENT) && 
+		!(old_status & BM_STATUS_PRESENT)) {
+		/* TBD: Make sure driver is loaded, and if not, load. */
+		status = bm_generate_notify(node, BM_NOTIFY_DEVICE_ADDED);
+	}
+
+	/*
+	 * Device Removal?
+	 * ---------------
+	 */
+	else if (!(device->status & BM_STATUS_PRESENT) && 
+		(old_status & BM_STATUS_PRESENT)) {
+		/* TBD: Unload driver if last device instance. */
+		status = bm_generate_notify(node, BM_NOTIFY_DEVICE_REMOVED);
+	}
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_bus_check
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_bus_check (
+	BM_NODE			*parent_node)
+{
+	ACPI_STATUS             status = AE_OK;
+	u32			status_change = FALSE;
+
+	FUNCTION_TRACE("bm_bus_check");
+
+	if (!parent_node) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Status Change?
+	 * --------------
+	 */
+	status = bm_device_check(parent_node, &status_change);
+	if (ACPI_FAILURE(status) || !status_change) {
+		return_ACPI_STATUS(status);
+	}
+
+	/*
+	 * Enumerate Scope:
+	 * ----------------
+	 * TBD: Enumerate child devices within this device's scope and
+	 *       run bm_device_check()'s on them...
+	 */
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+
+/****************************************************************************
+ *                            External Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_notify
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+void
+bm_notify (
+	ACPI_HANDLE             acpi_handle,
+	u32                     notify_value,
+	void                    *context)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_NODE			*node = NULL;
+
+	FUNCTION_TRACE("bm_notify");
+
+	/*
+	 * Resolve the ACPI handle.
+	 */
+	status = bm_get_node(0, acpi_handle, &node);
+	if (ACPI_FAILURE(status)) {
+		DEBUG_PRINT(ACPI_INFO, ("Recieved notify [%02x] for unknown device [%p].\n", notify_value, acpi_handle));
+		return_VOID;
+	}
+
+	/*
+	 * Device-Specific or Standard?
+	 * ----------------------------
+	 * Device-specific notifies are forwarded to the control module's 
+	 * notify() function for processing.  Standard notifies are handled
+	 * internally.
+	 */
+	if (notify_value > 0x7F) {
+		status = bm_generate_notify(node, notify_value);
+	}
+	else {
+		switch (notify_value) {
+
+		case BM_NOTIFY_BUS_CHECK:
+			DEBUG_PRINT(ACPI_INFO, ("Received BUS CHECK notification for device [%02x].\n", node->device.handle));
+			status = bm_bus_check(node);
+			break;
+
+		case BM_NOTIFY_DEVICE_CHECK:
+			DEBUG_PRINT(ACPI_INFO, ("Received DEVICE CHECK notification for device [%02x].\n", node->device.handle));
+			status = bm_device_check(node, NULL);
+			break;
+
+		case BM_NOTIFY_DEVICE_WAKE:
+			DEBUG_PRINT(ACPI_INFO, ("Received DEVICE WAKE notification for device [%02x].\n", node->device.handle));
+			/* TBD */
+			break;
+
+		case BM_NOTIFY_EJECT_REQUEST:
+			DEBUG_PRINT(ACPI_INFO, ("Received EJECT REQUEST notification for device [%02x].\n", node->device.handle));
+			/* TBD */
+			break;
+
+		case BM_NOTIFY_DEVICE_CHECK_LIGHT:
+			DEBUG_PRINT(ACPI_INFO, ("Received DEVICE CHECK LIGHT notification for device [%02x].\n", node->device.handle));
+			/* TBD: Exactly what does the 'light' mean? */
+			status = bm_device_check(node, NULL);
+			break;
+
+		case BM_NOTIFY_FREQUENCY_MISMATCH:
+			DEBUG_PRINT(ACPI_INFO, ("Received FREQUENCY MISMATCH notification for device [%02x].\n", node->device.handle));
+			/* TBD */
+			break;
+
+		case BM_NOTIFY_BUS_MODE_MISMATCH:
+			DEBUG_PRINT(ACPI_INFO, ("Received BUS MODE MISMATCH notification for device [%02x].\n", node->device.handle));
+			/* TBD */
+			break;
+
+		case BM_NOTIFY_POWER_FAULT:
+			DEBUG_PRINT(ACPI_INFO, ("Received POWER FAULT notification.\n"));
+			/* TBD */
+			break;
+
+		default:
+			DEBUG_PRINT(ACPI_INFO, ("Received unknown/unsupported notification.\n"));
+			break;
+		}
+	}
+
+	return_VOID;
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/busmgr/bmpm.c linux/drivers/acpi/ospm/busmgr/bmpm.c
--- v2.4.5/linux/drivers/acpi/ospm/busmgr/bmpm.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/busmgr/bmpm.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,442 @@
+/*****************************************************************************
+ *
+ * Module Name: bmpm.c
+ *   $Revision: 10 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <acpi.h>
+#include "bm.h"
+#include "bmpower.h"
+
+
+#define _COMPONENT		ACPI_BUS
+	MODULE_NAME		("bmpm")
+
+
+/****************************************************************************
+ *                             Internal Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_get_inferred_power_state
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_get_inferred_power_state (
+	BM_DEVICE               *device)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_HANDLE_LIST          pr_list;
+	BM_POWER_STATE          list_state = ACPI_STATE_UNKNOWN;
+	char                    object_name[5] = {'_','P','R','0','\0'};
+	u32                     i = 0;
+
+	FUNCTION_TRACE("bm_get_inferred_power_state");
+
+	if (!device) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	MEMSET(&pr_list, 0, sizeof(BM_HANDLE_LIST));
+
+	device->power.state = ACPI_STATE_D3;
+
+	/*
+	 * Calculate Power State:
+	 * ----------------------
+	 * Try to infer the devices's power state by checking the state of 
+	 * the devices's power resources.  We start by evaluating _PR0
+	 * (resource requirements at D0) and work through _PR1 and _PR2.
+	 * We know the current devices power state when all resources (for 
+	 * a give Dx state) are ON.  If no power resources are on then the 
+	 * device is assumed to be off (D3).
+	 */
+	for (i=ACPI_STATE_D0; i<ACPI_STATE_D3; i++) {
+
+		object_name[3] = '0' + i;
+
+		status = bm_evaluate_reference_list(device->acpi_handle, 
+			object_name, &pr_list);
+
+		if (ACPI_SUCCESS(status)) {
+
+			status = bm_pr_list_get_state(&pr_list, &list_state);
+
+			if (ACPI_SUCCESS(status)) {
+
+				if (list_state == ACPI_STATE_D0) {
+					device->power.state = i;
+					break;
+				}
+			}
+		}
+	}
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+
+/****************************************************************************
+ *                             External Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_get_power_state
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_get_power_state (
+	BM_NODE			*node)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_DEVICE               *device = NULL;
+
+	FUNCTION_TRACE("bm_get_power_state");
+
+	if (!node || !node->parent) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	device = &(node->device);
+
+	device->power.state = ACPI_STATE_UNKNOWN;
+
+	/*
+	 * Power Control?
+	 * --------------
+	 * If this device isn't directly power manageable (e.g. doesn't 
+	 * include _PR0/_PS0) then there's nothing to do (state is static).
+	 */
+	if (!BM_IS_POWER_CONTROL(device)) {
+		return_ACPI_STATUS(AE_OK);
+	}
+
+	/*
+	 * Parent Present?
+	 * ---------------
+	 * Make sure the parent is present before mucking with the child.
+	 */
+	if (!BM_NODE_PRESENT(node->parent)) {
+		return_ACPI_STATUS(AE_NOT_EXIST);
+	}
+	
+	/*
+	 * Get Power State:
+	 * ----------------
+	 * Either directly (via _PSC) or inferred (via power resource
+	 * dependencies).
+	 */
+	if (BM_IS_POWER_STATE(device)) {
+		status = bm_evaluate_simple_integer(device->acpi_handle, 
+			"_PSC", &(device->power.state));
+	}
+	else {
+		status = bm_get_inferred_power_state(device);
+	}
+
+	if (ACPI_SUCCESS(status)) {
+		DEBUG_PRINT(ACPI_INFO, ("Device [%02x] is at power state [D%d].\n", device->handle, device->power.state));
+	}
+	else {
+		DEBUG_PRINT(ACPI_INFO, ("Error getting power state for device [%02x]\n", device->handle));
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_set_power_state
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_set_power_state (
+	BM_NODE			*node,
+	BM_POWER_STATE          state)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_DEVICE		*device = NULL;
+	BM_DEVICE		*parent_device = NULL;
+	BM_HANDLE_LIST          current_list;
+	BM_HANDLE_LIST          target_list;
+	char                    object_name[5] = {'_','P','R','0','\0'};
+
+	FUNCTION_TRACE("bm_set_power_state");
+
+	if (!node || !node->parent || (state > ACPI_STATE_D3)) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	MEMSET(&current_list, 0, sizeof(BM_HANDLE_LIST));
+	MEMSET(&target_list, 0, sizeof(BM_HANDLE_LIST));
+
+	device = &(node->device);
+	parent_device = &(node->parent->device);
+
+	/*
+	 * Power Control?
+	 * --------------
+	 * If this device isn't directly power manageable (e.g. doesn't 
+	 * include _PR0/_PS0) then return an error (can't set state).
+	 */
+	if (!BM_IS_POWER_CONTROL(device)) {
+		return_ACPI_STATUS(AE_ERROR);
+	}
+
+	/*
+	 * Parent Present?
+	 * ---------------
+	 * Make sure the parent is present before mucking with the child.
+	 */
+	if (!BM_NODE_PRESENT(node->parent)) {
+		return_ACPI_STATUS(AE_NOT_EXIST);
+	}
+	
+	/*
+	 * Check Parent's Power State:
+	 * ---------------------------
+	 * Can't be in a higher power state (lower Dx value) than parent.
+	 */
+	if (state < parent_device->power.state) {
+		DEBUG_PRINT(ACPI_WARN, ("Cannot set device [%02x] to a higher-powered state than parent_device.\n", device->handle));
+		return_ACPI_STATUS(AE_ERROR);
+	}
+
+	/*
+	 * Get Resources:
+	 * --------------
+	 * Get the power resources associated with the device's current 
+	 * and target power states.
+	 */
+	if (device->power.state != ACPI_STATE_UNKNOWN) {
+		object_name[3] = '0' + device->power.state;
+		bm_evaluate_reference_list(device->acpi_handle, 
+			object_name, &current_list);
+	}
+
+	object_name[3] = '0' + state;
+	bm_evaluate_reference_list(device->acpi_handle, object_name, 
+		&target_list);
+
+	/*
+	 * Transition Resources:
+	 * ---------------------
+	 * Transition all power resources referenced by this device to 
+	 * the correct power state (taking into consideration sequencing 
+	 * and dependencies to other devices).
+	 */
+	if (current_list.count || target_list.count) {
+		status = bm_pr_list_transition(&current_list, &target_list);
+	}
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	/*
+	 * Execute _PSx:
+	 * -------------
+	 * Execute the _PSx method corresponding to the target Dx state, 
+	 * if it exists.
+	 */
+	object_name[2] = 'S';
+	object_name[3] = '0' + state;
+	bm_evaluate_object(device->acpi_handle, object_name, NULL, NULL);
+
+	if (ACPI_SUCCESS(status)) {
+		DEBUG_PRINT(ACPI_INFO, ("Device [%02x] is now at [D%d].\n", device->handle, state));
+		device->power.state = state;
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_get_pm_capabilities
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_get_pm_capabilities (
+	BM_NODE			*node)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_DEVICE		*device = NULL;
+	BM_DEVICE		*parent_device = NULL;
+	ACPI_HANDLE             acpi_handle = NULL;
+	BM_POWER_STATE          dx_supported = ACPI_STATE_UNKNOWN;
+	char                    object_name[5] = {'_','S','0','D','\0'};
+	u32                     i = 0;
+
+	FUNCTION_TRACE("bm_get_pm_capabilities");
+
+	if (!node || !node->parent) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	device = &(node->device);
+	parent_device = &(node->parent->device);
+
+	/*
+	 * Power Management Flags:
+	 * -----------------------
+	 */
+	if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_PSC", 
+		&acpi_handle))) {
+		device->power.flags |= BM_FLAGS_POWER_STATE;
+	}
+
+	if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_IRC", 
+		&acpi_handle))) {
+		device->power.flags |= BM_FLAGS_INRUSH_CURRENT;
+	}
+
+	if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_PRW", 
+		&acpi_handle))) {
+		device->power.flags |= BM_FLAGS_WAKE_CAPABLE;
+	}
+
+	/*
+	 * Device Power State:
+	 * -------------------
+	 * Note that we can't get the device's power state until we've
+	 * initialized all power resources, so for now we just set to
+	 * unknown.
+	 */
+	device->power.state = ACPI_STATE_UNKNOWN;
+
+	/*
+	 * Dx Supported in S0:
+	 * -------------------
+	 * Figure out which Dx states are supported by this device for the
+	 * S0 (working) state.  Note that D0 and D3 are required (assumed).
+	 */
+	device->power.dx_supported[ACPI_STATE_S0] = BM_FLAGS_D0_SUPPORT | 
+		BM_FLAGS_D3_SUPPORT;
+
+	if ((ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_PR1", 
+		&acpi_handle))) || 
+		(ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_PS1", 
+		&acpi_handle)))) {
+		device->power.dx_supported[ACPI_STATE_S0] |= 
+			BM_FLAGS_D1_SUPPORT;
+	}
+
+	if ((ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_PR2", 
+		&acpi_handle))) || 
+		(ACPI_SUCCESS(acpi_get_handle(device->acpi_handle, "_PS2", 
+		&acpi_handle)))) {
+		device->power.dx_supported[ACPI_STATE_S0] |= 
+			BM_FLAGS_D2_SUPPORT;
+	}
+
+	/*
+	 * Dx Supported in S1-S5:
+	 * ----------------------
+	 * Figure out which Dx states are supported by this device for
+	 * all other Sx states.
+	 */
+	for (i = ACPI_STATE_S1; i <= ACPI_STATE_S5; i++) {
+
+		/*
+		 * D3 support is assumed (off is always possible!).
+		 */
+		device->power.dx_supported[i] = BM_FLAGS_D3_SUPPORT;
+
+		/*
+		 * Evalute _SxD:
+		 * -------------
+		 * Which returns the highest (power) Dx state supported in 
+		 * this system (Sx) state.  We convert this value to a bit 
+		 * mask of supported states (conceptually simpler).
+		 */
+		status = bm_evaluate_simple_integer(device->acpi_handle, 
+			object_name, &dx_supported);
+		if (ACPI_SUCCESS(status)) {
+			switch (dx_supported) {
+			case 0:
+				device->power.dx_supported[i] |= 
+					BM_FLAGS_D0_SUPPORT;
+				/* fall through */
+			case 1:
+				device->power.dx_supported[i] |= 
+					BM_FLAGS_D1_SUPPORT;
+				/* fall through */
+			case 2:
+				device->power.dx_supported[i] |= 
+					BM_FLAGS_D2_SUPPORT;
+				/* fall through */
+			case 3:
+				device->power.dx_supported[i] |= 
+					BM_FLAGS_D3_SUPPORT;
+				break;
+			}
+
+			/*
+			 * Validate:
+			 * ---------
+			 * Mask of any states that _Sx_d falsely advertises 
+			 * (e.g.claims D1 support but neither _PR2 or _PS2 
+			 * exist).  In other words, S1-S5 can't offer a Dx 
+			 * state that isn't supported by S0.
+			 */
+			device->power.dx_supported[i] &= 
+				device->power.dx_supported[ACPI_STATE_S0];
+		}
+
+		object_name[2]++;
+	}
+
+	return_ACPI_STATUS(AE_OK);
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/busmgr/bmpower.c linux/drivers/acpi/ospm/busmgr/bmpower.c
--- v2.4.5/linux/drivers/acpi/ospm/busmgr/bmpower.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/busmgr/bmpower.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,663 @@
+/****************************************************************************
+ *
+ * Module Name: bmpower.c - Driver for ACPI Power Resource 'devices'
+ *   $Revision: 14 $
+ *
+ ****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * TBD: 1. Sequencing of power resource list transitions.
+ *	2. Global serialization of power resource transtions (see ACPI 
+ *         spec section 7.1.2/7.1.3).
+ *      3. Better error handling.
+ */
+
+
+#include <acpi.h>
+#include "bm.h"
+#include "bmpower.h"
+
+
+#define _COMPONENT		ACPI_BUS
+	MODULE_NAME		("bmpower")
+
+
+/****************************************************************************
+ *                             Function Prototypes
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_pr_notify (
+	BM_NOTIFY               notify_type,
+	BM_HANDLE               device_handle,
+	void                    **context);
+	
+ACPI_STATUS
+bm_pr_request (
+	BM_REQUEST		*request,
+	void                    *context);
+
+	
+/****************************************************************************
+ *                             Internal Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_pr_print
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_pr_print (
+	BM_POWER_RESOURCE	*pr)
+{
+	ACPI_BUFFER             buffer;
+
+	if (!pr) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	buffer.length = 256;
+	buffer.pointer = acpi_os_callocate(buffer.length);
+	if (!buffer.pointer) {
+		return(AE_NO_MEMORY);
+	}
+
+	acpi_get_name(pr->acpi_handle, ACPI_FULL_PATHNAME, &buffer);
+
+	acpi_os_printf("Power Resource: found\n");
+
+	DEBUG_PRINT_RAW(ACPI_INFO, ("+------------------------------------------------------------\n"));
+	DEBUG_PRINT_RAW(ACPI_INFO, ("| PowerResource[%02x]:[%p] %s\n", pr->device_handle, pr->acpi_handle, buffer.pointer));
+	DEBUG_PRINT_RAW(ACPI_INFO, ("|   system_level[S%d] resource_order[%d]\n", pr->system_level, pr->resource_order));
+	DEBUG_PRINT_RAW(ACPI_INFO, ("|   state[D%d] reference_count[%d]\n", pr->state, pr->reference_count));
+	DEBUG_PRINT_RAW(ACPI_INFO, ("+------------------------------------------------------------\n"));
+
+	acpi_os_free(buffer.pointer);
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_pr_get_state
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_pr_get_state (
+	BM_POWER_RESOURCE	*pr)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_DEVICE_STATUS        device_status = BM_STATUS_UNKNOWN;
+
+	FUNCTION_TRACE("bm_pr_get_state");
+
+	if (!pr) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	pr->state = ACPI_STATE_UNKNOWN;
+
+	/* 
+	 * Evaluate _STA:
+	 * --------------
+	 * Evalute _STA to determine whether the power resource is ON or OFF.
+	 * Note that if the power resource isn't present we'll get AE_OK but
+	 * an unknown status.
+	 */
+	status = bm_get_device_status(pr->device_handle, &device_status);
+	if (ACPI_FAILURE(status)) {
+		DEBUG_PRINT(ACPI_ERROR, ("Error reading status for power resource [%02x].\n", pr->device_handle));
+		return_ACPI_STATUS(status);
+	}
+
+	/*
+	 * Mask off all bits but the first as some systems return non-standard 
+	 * values (e.g. 0x51).
+	 */
+	switch (device_status & 0x01) {
+	case 0:
+		DEBUG_PRINT(ACPI_INFO, ("Power resource [%02x] is OFF.\n", pr->device_handle));
+		pr->state = ACPI_STATE_D3;
+		break;
+	case 1:
+		DEBUG_PRINT(ACPI_INFO, ("Power resource [%02x] is ON.\n", pr->device_handle));
+		pr->state = ACPI_STATE_D0;
+		break;
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_pr_set_state
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_pr_set_state (
+	BM_POWER_RESOURCE	*pr,
+	BM_POWER_STATE          target_state)
+{
+	ACPI_STATUS             status = AE_OK;
+
+	FUNCTION_TRACE("bm_pr_set_state");
+
+	if (!pr) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	status = bm_pr_get_state(pr);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	if (target_state == pr->state) {
+		DEBUG_PRINT(ACPI_INFO, ("Power resource [%02x] already at target power state [D%d].\n", pr->device_handle, pr->state));
+		return_ACPI_STATUS(AE_OK);
+	}
+
+	switch (target_state) {
+
+	case ACPI_STATE_D0:
+		DEBUG_PRINT(ACPI_INFO, ("Turning power resource [%02x] ON.\n", pr->device_handle));
+		status = bm_evaluate_object(pr->acpi_handle, "_ON", NULL, NULL);
+		break;
+
+	case ACPI_STATE_D3:
+		DEBUG_PRINT(ACPI_INFO, ("Turning power resource [%02x] OFF.\n", pr->device_handle));
+		status = bm_evaluate_object(pr->acpi_handle, "_OFF", NULL, NULL);
+		break;
+
+	default:
+		status = AE_BAD_PARAMETER;
+		break;
+	}
+
+	status = bm_pr_get_state(pr);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_pr_list_get_state
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_pr_list_get_state (
+	BM_HANDLE_LIST          *pr_list,
+	BM_POWER_STATE          *power_state)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_POWER_RESOURCE	*pr = NULL;
+	u32                     i = 0;
+
+	FUNCTION_TRACE("bm_pr_list_get_state");
+
+	if (!pr_list || !power_state) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	if (pr_list->count < 1) {
+		pr->state = ACPI_STATE_UNKNOWN;
+		return_ACPI_STATUS(AE_ERROR);
+	}
+
+	(*power_state) = ACPI_STATE_D0;
+
+	/*
+	 * Calculate Current power_state:
+	 * -----------------------------
+	 * The current state of a list of power resources is ON if all
+	 * power resources are currently in the ON state.  In other words,
+	 * if any power resource in the list is OFF then the collection 
+	 * isn't fully ON.
+	 */
+	for (i = 0; i < pr_list->count; i++) {
+
+		status = bm_get_device_context(pr_list->handles[i],
+			(BM_DRIVER_CONTEXT*)(&pr));
+		if (ACPI_FAILURE(status)) {
+			DEBUG_PRINT(ACPI_WARN, ("Invalid reference to power resource [%02x].\n", pr_list->handles[i]));
+			(*power_state) = ACPI_STATE_UNKNOWN;
+			break;
+		}
+
+		status = bm_pr_get_state(pr);
+		if (ACPI_FAILURE(status)) {
+			(*power_state) = ACPI_STATE_UNKNOWN;
+			break;
+		}
+
+		if (pr->state != ACPI_STATE_D0) {
+			(*power_state) = pr->state;
+			break;
+		}
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_pr_list_transition
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_pr_list_transition (
+	BM_HANDLE_LIST          *current_list,
+	BM_HANDLE_LIST          *target_list)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_POWER_RESOURCE	*pr = NULL;
+	u32                     i = 0;
+
+	FUNCTION_TRACE("bm_pr_list_transition");
+
+	if (!current_list || !target_list) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Reference Target:
+	 * -----------------
+	 * Reference all resources for the target power state first (so 
+	 * the device doesn't get turned off while transitioning).  Power 
+	 * resources that aren't on (new reference count of 1) are turned on.
+	 */
+	for (i = 0; i < target_list->count; i++) {
+
+		status = bm_get_device_context(target_list->handles[i], 
+			(BM_DRIVER_CONTEXT*)(&pr));
+		if (ACPI_FAILURE(status)) {
+			DEBUG_PRINT(ACPI_WARN, ("Invalid reference to power resource [%02x].\n", target_list->handles[i]));
+			continue;
+		}
+
+		if (++pr->reference_count == 1) {
+			/* TBD: Need ordering based upon resource_order */
+			status = bm_pr_set_state(pr, ACPI_STATE_D0);
+			if (ACPI_FAILURE(status)) {
+				/* TBD: How do we handle this? */
+				DEBUG_PRINT(ACPI_WARN, ("Unable to change power state for power resource [%02x].\n", target_list->handles[i]));
+			}
+		}
+	}
+
+	/*
+	 * Dereference Current:
+	 * --------------------
+	 * Dereference all resources for the current power state.  Power
+	 * resources no longer referenced (new reference count of 0) are 
+	 * turned off.
+	 */
+	for (i = 0; i < current_list->count; i++) {
+
+		status = bm_get_device_context(current_list->handles[i], 
+			(BM_DRIVER_CONTEXT*)(&pr));
+		if (ACPI_FAILURE(status)) {
+			DEBUG_PRINT(ACPI_WARN, ("Invalid reference to power resource [%02x].\n", target_list->handles[i]));
+			continue;
+		}
+
+		if (--pr->reference_count == 0) {
+			/* TBD: Need ordering based upon resource_order */
+			status = bm_pr_set_state(pr, ACPI_STATE_D3);
+			if (ACPI_FAILURE(status)) {
+				/* TBD: How do we handle this? */
+				DEBUG_PRINT(ACPI_ERROR, ("Unable to change power state for power resource [%02x].\n", current_list->handles[i]));
+			}
+		}
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_pr_add_device
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_pr_add_device (
+	BM_HANDLE               device_handle,
+	void                    **context)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_POWER_RESOURCE	*pr = NULL;
+	BM_DEVICE		*device = NULL;
+	ACPI_BUFFER		buffer;
+	ACPI_OBJECT		acpi_object;
+
+	FUNCTION_TRACE("bm_pr_add_device");
+
+	DEBUG_PRINT(ACPI_INFO, ("Adding power resource [%02x].\n", device_handle));
+
+	if (!context || *context) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	buffer.length = sizeof(ACPI_OBJECT);
+	buffer.pointer = &acpi_object;
+
+	/*
+	 * Get information on this device.
+	 */
+	status = bm_get_device_info(device_handle, &device);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	/*
+	 * Allocate a new BM_POWER_RESOURCE structure.
+	 */
+	pr = acpi_os_callocate(sizeof(BM_POWER_RESOURCE));
+	if (!pr) {
+		return_ACPI_STATUS(AE_NO_MEMORY);
+	}
+
+	pr->device_handle = device->handle;
+	pr->acpi_handle = device->acpi_handle;
+
+	/* 
+	 * Get information on this power resource.
+	 */
+	status = acpi_evaluate_object(pr->acpi_handle, NULL, NULL, &buffer);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	pr->system_level = acpi_object.power_resource.system_level;
+	pr->resource_order = acpi_object.power_resource.resource_order;
+	pr->state = ACPI_STATE_UNKNOWN;
+	pr->reference_count = 0;
+
+	/*
+	 * Get the power resource's current state (ON|OFF).
+	 */
+	status = bm_pr_get_state(pr);
+
+end:
+	if (ACPI_FAILURE(status)) {
+		acpi_os_free(pr);
+	}
+	else {
+		*context = pr;
+		bm_pr_print(pr);
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_pr_remove_device
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_pr_remove_device (
+	void                    **context)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_POWER_RESOURCE	*pr = NULL;
+
+	FUNCTION_TRACE("bm_pr_remove_device");
+
+	if (!context || !*context) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	pr = (BM_POWER_RESOURCE*)*context;
+
+	DEBUG_PRINT(ACPI_INFO, ("Removing power resource [%02x].\n", pr->device_handle));
+
+	acpi_os_free(pr);
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *                             External Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_pr_initialize
+ *
+ * PARAMETERS:  <none>
+ *
+ * RETURN:
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_pr_initialize (void)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_DEVICE_ID		criteria;
+	BM_DRIVER		driver;
+
+	FUNCTION_TRACE("bm_pr_initialize");
+
+	MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
+	MEMSET(&driver, 0, sizeof(BM_DRIVER));
+
+	criteria.type = BM_TYPE_POWER_RESOURCE;
+
+	driver.notify = &bm_pr_notify;
+	driver.request = &bm_pr_request;
+
+	status = bm_register_driver(&criteria, &driver);
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_pr_terminate
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_pr_terminate (void)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_DEVICE_ID		criteria;
+	BM_DRIVER		driver;
+
+	FUNCTION_TRACE("bm_pr_terminate");
+
+	MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
+	MEMSET(&driver, 0, sizeof(BM_DRIVER));
+
+	criteria.type = BM_TYPE_POWER_RESOURCE;
+
+	driver.notify = &bm_pr_notify;
+	driver.request = &bm_pr_request;
+
+	status = bm_unregister_driver(&criteria, &driver);
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_pr_notify
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_pr_notify (
+	BM_NOTIFY               notify_type,
+	BM_HANDLE               device_handle,
+	void                    **context)
+{
+	ACPI_STATUS             status = AE_OK;
+
+	FUNCTION_TRACE("bm_pr_notify");
+
+	switch (notify_type) {
+
+	case BM_NOTIFY_DEVICE_ADDED:
+		status = bm_pr_add_device(device_handle, context);
+		break;
+
+	case BM_NOTIFY_DEVICE_REMOVED:
+		status = bm_pr_remove_device(context);
+		break;
+
+	default:
+		status = AE_SUPPORT;
+		break;
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_pr_request
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_pr_request (
+	BM_REQUEST		*request,
+	void                    *context)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_POWER_RESOURCE	*pr = NULL;
+
+	FUNCTION_TRACE("bm_pr_request");
+
+	/*
+	 * Must have a valid request structure and context.
+	 */
+	if (!request || !context) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * context contains information specific to this power resource.
+	 */
+	pr = (BM_POWER_RESOURCE*)context;
+
+	/*
+	 * Handle request:
+	 * ---------------
+	 */
+	switch (request->command) {
+
+	default:
+		status = AE_SUPPORT;
+		break;
+	}
+
+	request->status = status;
+
+	return_ACPI_STATUS(status);
+}
+
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/busmgr/bmrequest.c linux/drivers/acpi/ospm/busmgr/bmrequest.c
--- v2.4.5/linux/drivers/acpi/ospm/busmgr/bmrequest.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/busmgr/bmrequest.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,164 @@
+/******************************************************************************
+ *
+ * Module Name: bmrequest.c
+ *   $Revision: 12 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <acpi.h>
+#include "bm.h"
+
+#define _COMPONENT		ACPI_BUS
+	MODULE_NAME		("bmrequest")
+
+
+/****************************************************************************
+ *                            External Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_generate_request
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_generate_request (
+	BM_NODE			*node,
+	BM_REQUEST		*request)
+{
+	ACPI_STATUS		status = AE_OK;
+	BM_DEVICE		*device = NULL;
+
+	FUNCTION_TRACE("bm_generate_request");
+
+	if (!node || !request) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	device = &(node->device);
+
+	if (!BM_IS_DRIVER_CONTROL(device)) {
+		DEBUG_PRINT(ACPI_WARN, ("No driver installed for device [%02x].\n", device->handle));
+		return_ACPI_STATUS(AE_NOT_EXIST);
+	}
+
+	status = node->driver.request(request, node->driver.context);
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_request
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_request (
+	BM_REQUEST              *request)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_NODE			*node = NULL;
+	BM_DEVICE		*device = NULL;
+
+	FUNCTION_TRACE("bm_request");
+
+	/*
+	 * Must have a valid request structure.
+	 */
+	if (!request) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	DEBUG_PRINT(ACPI_INFO, ("Received request for device [%02x] command [%02x].\n", request->handle, request->command));
+
+	/*
+	 * Resolve the node.
+	 */
+	status = bm_get_node(request->handle, 0, &node);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	device = &(node->device);
+
+	/*
+	 * Device-Specific Request?
+	 * ------------------------
+	 * If a device-specific command (>=0x80) forward this request to
+	 * the appropriate driver.
+	 */
+	if (request->command & BM_COMMAND_DEVICE_SPECIFIC) {
+		status = bm_generate_request(node, request);
+		return_ACPI_STATUS(status);
+	}
+
+	/*
+	 * Bus-Specific Requests:
+	 * ----------------------
+	 */
+	switch (request->command) {
+
+	case BM_COMMAND_GET_POWER_STATE:
+		status = bm_get_power_state(node);
+		if (ACPI_FAILURE(status)) {
+			break;
+		}
+		status = bm_copy_to_buffer(&(request->buffer), 
+			&(device->power.state), sizeof(BM_POWER_STATE));
+		break;
+
+	case BM_COMMAND_SET_POWER_STATE:
+	{
+		BM_POWER_STATE *power_state = NULL;
+
+		status = bm_cast_buffer(&(request->buffer), 
+			(void**)&power_state, sizeof(BM_POWER_STATE));
+		if (ACPI_FAILURE(status)) {
+			break;
+		}
+		status = bm_set_power_state(node, *power_state);
+	}
+		break;
+
+	default:
+		status = AE_SUPPORT;
+		request->status = AE_SUPPORT;
+		break;
+	}
+
+	return_ACPI_STATUS(status);
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/busmgr/bmsearch.c linux/drivers/acpi/ospm/busmgr/bmsearch.c
--- v2.4.5/linux/drivers/acpi/ospm/busmgr/bmsearch.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/busmgr/bmsearch.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,192 @@
+/******************************************************************************
+ *
+ * Module Name: bmsearch.c
+ *   $Revision: 13 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <acpi.h>
+#include "bm.h"
+
+
+#define _COMPONENT		ACPI_BUS
+	MODULE_NAME		("bmsearch")
+
+
+/****************************************************************************
+ *                            External Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_compare
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_compare (
+	BM_DEVICE               *device,
+	BM_DEVICE_ID            *criteria)
+{
+	if (!device || !criteria) {
+		return AE_BAD_PARAMETER;
+	}
+
+	/* 
+	 * Present?
+	 * --------
+	 * We're only going to match on devices that are present.
+	 * TBD: Optimize in bm_search (don't have to call here).
+	 */
+	if (!BM_DEVICE_PRESENT(device)) {
+		return AE_NOT_FOUND;
+	}
+
+	/* 
+	 * Type?
+	 */
+	if (criteria->type && (criteria->type != device->id.type)) {
+		return AE_NOT_FOUND;
+	}
+
+	/* 
+	 * HID?
+	 */
+	if ((criteria->hid[0]) && (0 != STRNCMP(criteria->hid, 
+		device->id.hid, sizeof(BM_DEVICE_HID)))) {
+		return AE_NOT_FOUND;
+	}
+
+	/* 
+	 * ADR?
+	 */
+	if ((criteria->adr) && (criteria->adr != device->id.adr)) {
+		return AE_NOT_FOUND;
+	}
+
+	return AE_OK;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_search
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      AE_BAD_PARAMETER- invalid input parameter
+ *              AE_NOT_EXIST    - start_device_handle doesn't exist
+ *              AE_NOT_FOUND    - no matches to Search_info.criteria found
+ *              AE_OK           - success
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_search(
+	BM_HANDLE               device_handle,
+	BM_DEVICE_ID            *criteria,
+	BM_HANDLE_LIST          *results)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_NODE			*node = NULL;
+
+	FUNCTION_TRACE("bm_search");
+
+	if (!criteria || !results) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	results->count = 0;
+
+	/*
+	 * Locate Starting Point:
+	 * ----------------------
+	 * Locate the node in the hierarchy where we'll begin our search.
+	 */
+	status = bm_get_node(device_handle, 0, &node);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	/*
+	 * Parse Hierarchy:
+	 * ----------------
+	 * Parse through the node hierarchy looking for matches.
+	 */
+	while (node && (results->count<=BM_HANDLES_MAX)) {
+		/*
+		 * Depth-first:
+		 * ------------
+		 * Searches are always performed depth-first.
+		 */
+		if (node->scope.head) {
+			status = bm_compare(&(node->device), criteria);
+			if (ACPI_SUCCESS(status)) {
+				results->handles[results->count++] = 
+					node->device.handle;
+			}
+			node = node->scope.head;
+		}
+
+		/*
+		 * Now Breadth:
+		 * ------------
+		 * Search all peers until scope is exhausted.
+		 */
+		else {
+			status = bm_compare(&(node->device), criteria);
+			if (ACPI_SUCCESS(status)) {
+				results->handles[results->count++] = 
+					node->device.handle;
+			}
+
+			/*
+			 * Locate Next Device:
+			 * -------------------
+			 * The next node is either a peer at this level 
+			 * (node->next is valid), or we work are way back 
+			 * up the tree until we either find a non-parsed 
+			 * peer or hit the top (node->parent is NULL).
+			 */
+			while (!node->next && node->parent) {
+				node = node->parent;
+			}
+			node = node->next;
+		}
+	}
+
+	if (results->count == 0) {
+		return_ACPI_STATUS(AE_NOT_FOUND);
+	}
+	else {
+		return_ACPI_STATUS(AE_OK);
+	}
+}
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/busmgr/bmutils.c linux/drivers/acpi/ospm/busmgr/bmutils.c
--- v2.4.5/linux/drivers/acpi/ospm/busmgr/bmutils.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/busmgr/bmutils.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,608 @@
+/*****************************************************************************
+ *
+ * Module Name: bmutils.c
+ *   $Revision: 28 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <acpi.h>
+#include "bm.h"
+
+
+#define _COMPONENT		ACPI_BUS
+	MODULE_NAME		("bmutils")
+
+
+#ifdef ACPI_DEBUG
+#define DEBUG_EVAL_ERROR(l,h,p,s)    bm_print_eval_error(l,h,p,s)
+#else
+#define DEBUG_EVAL_ERROR(l,h,p,s)
+#endif
+
+
+/****************************************************************************
+ *                            External Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_print_eval_error
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+void
+bm_print_eval_error (
+	u32                     debug_level,
+	ACPI_HANDLE             acpi_handle,
+	ACPI_STRING             pathname,
+	ACPI_STATUS             status)
+{
+	ACPI_BUFFER             buffer;
+	ACPI_STRING             status_string = NULL;
+
+	buffer.length = 256;
+	buffer.pointer = acpi_os_callocate(buffer.length);
+	if (!buffer.pointer) {
+		return;
+	}
+
+	status_string = acpi_ut_format_exception(status);
+
+	status = acpi_get_name(acpi_handle, ACPI_FULL_PATHNAME, &buffer);
+	if (ACPI_FAILURE(status)) {
+		DEBUG_PRINT(debug_level, ("Evaluate object [%p], %s\n", acpi_handle, status_string));
+		return;
+	}
+
+	if (pathname) {
+		DEBUG_PRINT(ACPI_INFO, ("Evaluate object [%s.%s], %s\n", buffer.pointer, pathname, status_string));
+	}
+	else {
+		DEBUG_PRINT(ACPI_INFO, ("Evaluate object [%s], %s\n", buffer.pointer, status_string));
+	}
+
+	acpi_os_free(buffer.pointer);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_copy_to_buffer
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_copy_to_buffer (
+	ACPI_BUFFER             *buffer,
+	void                    *data,
+	u32                     length)
+{
+	FUNCTION_TRACE("bm_copy_to_buffer");
+
+	if (!buffer || (!buffer->pointer) || !data || (length == 0)) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	if (length > buffer->length) {
+		buffer->length = length;
+		return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
+	}
+
+	buffer->length = length;
+	MEMCPY(buffer->pointer, data, length);
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_cast_buffer
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_cast_buffer (
+	ACPI_BUFFER             *buffer,
+	void                    **pointer,
+	u32                     length)
+{
+	FUNCTION_TRACE("bm_cast_buffer");
+
+	if (!buffer || !buffer->pointer || !pointer || length == 0) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	if (length > buffer->length) {
+		return_ACPI_STATUS(AE_BAD_DATA);
+	}
+
+	*pointer = buffer->pointer;
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_extract_package_data
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+/*
+ * TBD: Don't assume numbers (in ASL) are 32-bit values!!!!  (IA64)
+ * TBD: Issue with 'assumed' types coming out of interpreter...
+ *       (e.g. toshiba _BIF)
+ */
+
+ACPI_STATUS
+bm_extract_package_data (
+	ACPI_OBJECT             *package,
+	ACPI_BUFFER             *package_format,
+	ACPI_BUFFER             *buffer)
+{
+	ACPI_STATUS             status = AE_OK;
+	u8                      *head = NULL;
+	u8                      *tail = NULL;
+	u8                      **pointer = NULL;
+	u32                     tail_offset = 0;
+	ACPI_OBJECT             *element = NULL;
+	u32                     size_required = 0;
+	char*                   format = NULL;
+	u32                     format_count = 0;
+	u32                     i = 0;
+
+	FUNCTION_TRACE("bm_extract_package_data");
+
+	if (!package || (package->type != ACPI_TYPE_PACKAGE) ||
+		(package->package.count == 0) || !package_format ||
+		(package_format->length < 1) || 
+		(!package_format->pointer) || !buffer) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	format_count = package_format->length - 1;
+
+	if (format_count > package->package.count) {
+		DEBUG_PRINT(ACPI_WARN, ("Format specifies more objects [%d] than exist in package [%d].", format_count, package->package.count));
+		return_ACPI_STATUS(AE_BAD_DATA);
+	}
+
+	format = (char*)package_format->pointer;
+
+	/*
+	 * Calculate size_required.
+	 */
+	for (i=0; i<format_count; i++) {
+		element = &(package->package.elements[i]);
+
+		switch (element->type) {
+
+		case ACPI_TYPE_INTEGER:
+			switch (format[i]) {
+			case 'N':
+				size_required += sizeof(ACPI_INTEGER);
+				tail_offset += sizeof(ACPI_INTEGER);
+				break;
+			case 'S':
+				size_required += sizeof(u8*) + 
+					sizeof(ACPI_INTEGER) + 1;
+				tail_offset += sizeof(ACPI_INTEGER);
+				break;
+			default:
+				DEBUG_PRINT(ACPI_WARN, ("Invalid package element [%d]: got number, expecing [%c].\n", i, format[i]));
+				return_ACPI_STATUS(AE_BAD_DATA);
+				break;
+			}
+			break;
+
+		case ACPI_TYPE_STRING:
+		case ACPI_TYPE_BUFFER:
+			switch (format[i]) {
+			case 'S':
+				size_required += sizeof(u8*) + 
+					element->string.length + 1;
+				tail_offset += sizeof(u8*);
+				break;
+			case 'B':
+				size_required += sizeof(u8*) + 
+					element->buffer.length;
+				tail_offset += sizeof(u8*);
+				break;
+			default:
+				DEBUG_PRINT(ACPI_WARN, ("Invalid package element [%d] got string/buffer, expecing [%c].\n", i, format[i]));
+				return_ACPI_STATUS(AE_BAD_DATA);
+				break;
+			}
+			break;
+
+		case ACPI_TYPE_PACKAGE:
+		default:
+			/* TBD: handle nested packages... */
+			return_ACPI_STATUS(AE_SUPPORT);
+			break;
+		}
+	}
+
+	if (size_required > buffer->length) {
+		buffer->length = size_required;
+		return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
+	}
+
+	buffer->length = size_required;
+
+	if (!buffer->pointer) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	head = buffer->pointer;
+	tail = buffer->pointer + tail_offset;
+
+	/*
+	 * Extract package data:
+	 */
+	for (i=0; i<format_count; i++) {
+
+		element = &(package->package.elements[i]);
+
+		switch (element->type) {
+
+		case ACPI_TYPE_INTEGER:
+			switch (format[i]) {
+			case 'N':
+				*((ACPI_INTEGER*)head) = 
+					element->integer.value;
+				head += sizeof(ACPI_INTEGER);
+				break;
+			case 'S':
+				pointer = (u8**)head;
+				*pointer = tail;
+				*((ACPI_INTEGER*)tail) = 
+					element->integer.value;
+				head += sizeof(ACPI_INTEGER*);
+				tail += sizeof(ACPI_INTEGER);
+				/* NULL terminate string */
+				*tail = 0;
+				tail++;
+				break;
+			default:
+				/* Should never get here */
+				break;
+			}
+			break;
+
+		case ACPI_TYPE_STRING:
+		case ACPI_TYPE_BUFFER:
+			switch (format[i]) {
+			case 'S':
+				pointer = (u8**)head;
+				*pointer = tail;
+				memcpy(tail, element->string.pointer, 
+					element->string.length);
+				head += sizeof(u8*);
+				tail += element->string.length;
+				/* NULL terminate string */
+				*tail = 0;
+				tail++;
+				break;
+			case 'B':
+				pointer = (u8**)head;
+				*pointer = tail;
+				memcpy(tail, element->buffer.pointer, 
+					element->buffer.length);
+				head += sizeof(u8*);
+				tail += element->buffer.length;
+				break;
+			default:
+				/* Should never get here */
+				break;
+			}
+			break;
+
+		case ACPI_TYPE_PACKAGE:
+			/* TBD: handle nested packages... */
+		default:
+			/* Should never get here */
+			break;
+		}
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_evaluate_object
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      AE_OK
+ *              AE_BUFFER_OVERFLOW  Evaluated object returned data, but 
+ *                                  caller did not provide buffer.
+ *
+ * DESCRIPTION: Helper for acpi_evaluate_object that handles buffer
+ *              allocation.  Note that the caller is responsible for 
+ *              freeing buffer->pointer!
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_evaluate_object (
+	ACPI_HANDLE             acpi_handle,
+	ACPI_STRING             pathname,
+	ACPI_OBJECT_LIST        *arguments,
+	ACPI_BUFFER             *buffer)
+{
+	ACPI_STATUS             status = AE_OK;
+
+	FUNCTION_TRACE("bm_evaluate_object");
+
+	/* If caller provided a buffer it must be unallocated/zero'd. */
+	if ((buffer) && (buffer->length != 0 || buffer->pointer)) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Evalute Object:
+	 * ---------------
+	 * The first attempt is just to get the size of the object data 
+	 * (that is unless there's no return data, e.g. _INI); the second 
+	 * gets the data.
+	 */
+	status = acpi_evaluate_object(acpi_handle, pathname, arguments, buffer);
+	if (ACPI_SUCCESS(status)) {
+		return_ACPI_STATUS(status);
+	}
+	else if ((buffer) && (status == AE_BUFFER_OVERFLOW)) {
+
+		/* Gotta allocate -- CALLER MUST FREE! */
+		buffer->pointer = acpi_os_callocate(buffer->length);
+		if (!buffer->pointer) {
+			return_ACPI_STATUS(AE_NO_MEMORY);
+		}
+
+		/* Re-evaluate -- this time it should work */
+		status = acpi_evaluate_object(acpi_handle, pathname, 
+			arguments, buffer);
+	}
+
+	if (ACPI_FAILURE(status)) {
+		if (status != AE_NOT_FOUND) {
+			DEBUG_EVAL_ERROR(ACPI_WARN, acpi_handle, pathname, 
+				status);
+		}
+		if (buffer && buffer->pointer) {
+			acpi_os_free(buffer->pointer); 
+			buffer->pointer = NULL;
+			buffer->length = 0;
+		}
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_evaluate_simple_integer
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_evaluate_simple_integer (
+	ACPI_HANDLE             acpi_handle,
+	ACPI_STRING             pathname,
+	u32                     *data)
+{
+	ACPI_STATUS             status = AE_OK;
+	ACPI_OBJECT             *element = NULL;
+	ACPI_BUFFER             buffer;
+
+	FUNCTION_TRACE("bm_evaluate_simple_integer");
+
+	if (!data) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	MEMSET(&buffer, 0, sizeof(ACPI_BUFFER));
+
+	/*
+	 * Evaluate Object:
+	 * ----------------
+	 */
+	status = bm_evaluate_object(acpi_handle, pathname, NULL, &buffer);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	/*
+	 * Validate Data:
+	 * --------------
+	 */
+	status = bm_cast_buffer(&buffer, (void**)&element, 
+		sizeof(ACPI_OBJECT));
+	if (ACPI_FAILURE(status)) {
+		DEBUG_EVAL_ERROR(ACPI_WARN, acpi_handle, pathname, status);
+		goto end;
+	}
+
+	if (element->type != ACPI_TYPE_INTEGER) {
+		status = AE_BAD_DATA;
+		DEBUG_EVAL_ERROR(ACPI_WARN, acpi_handle, pathname, status);
+		goto end;
+	}
+
+	*data = element->integer.value;
+
+end:
+	acpi_os_free(buffer.pointer);
+
+	return_ACPI_STATUS(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bm_evaluate_reference_list
+ *
+ * PARAMETERS:  
+ *
+ * RETURN:      
+ *
+ * DESCRIPTION: 
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bm_evaluate_reference_list (
+	ACPI_HANDLE             acpi_handle,
+	ACPI_STRING             pathname,
+	BM_HANDLE_LIST          *reference_list)
+{
+	ACPI_STATUS             status = AE_OK;
+	ACPI_OBJECT             *package = NULL;
+	ACPI_OBJECT             *element = NULL;
+	ACPI_HANDLE		reference_handle = NULL;
+	ACPI_BUFFER             buffer;
+	u32                     i = 0;
+
+	FUNCTION_TRACE("bm_evaluate_reference_list");
+
+	if (!reference_list) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	MEMSET(&buffer, 0, sizeof(ACPI_BUFFER));
+
+	/*
+	 * Evaluate Object:
+	 * ----------------
+	 */
+	status = bm_evaluate_object(acpi_handle, pathname, NULL, &buffer);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	/*
+	 * Validate Package:
+	 * -----------------
+	 */
+	status = bm_cast_buffer(&buffer, (void**)&package, 
+		sizeof(ACPI_OBJECT));
+	if (ACPI_FAILURE(status)) {
+		DEBUG_EVAL_ERROR(ACPI_WARN, acpi_handle, pathname, status);
+		goto end;
+	}
+
+	if (package->type != ACPI_TYPE_PACKAGE) {
+		status = AE_BAD_DATA;
+		DEBUG_EVAL_ERROR(ACPI_WARN, acpi_handle, pathname, status);
+		goto end;
+	}
+
+	if (package->package.count > BM_HANDLES_MAX) {
+		package->package.count = BM_HANDLES_MAX;
+	}
+
+	/*
+	 * Parse Package Data:
+	 * -------------------
+	 */
+	for (i = 0; i < package->package.count; i++) {
+
+		element = &(package->package.elements[i]);
+
+		if (!element || (element->type != ACPI_TYPE_STRING)) {
+			status = AE_BAD_DATA;
+			DEBUG_PRINT(ACPI_WARN, ("Invalid element in package (not a device reference).\n"));
+			DEBUG_EVAL_ERROR(ACPI_WARN, acpi_handle, pathname, status);
+			break;
+		}
+
+		/*
+		 * Resolve reference string (e.g. "\_PR_.CPU_") to an
+		 * ACPI_HANDLE.
+		 */
+		status = acpi_get_handle(acpi_handle, 
+			element->string.pointer, &reference_handle);
+		if (ACPI_FAILURE(status)) {
+			status = AE_BAD_DATA;
+			DEBUG_PRINT(ACPI_WARN, ("Unable to resolve device reference [%s].\n", element->string.pointer));
+			DEBUG_EVAL_ERROR(ACPI_WARN, acpi_handle, pathname, status);
+			break;
+		}
+
+		/*
+		 * Resolve ACPI_HANDLE to BM_HANDLE.
+		 */
+		status = bm_get_handle(reference_handle, 
+			&(reference_list->handles[i]));
+		if (ACPI_FAILURE(status)) {
+			status = AE_BAD_DATA;
+			DEBUG_PRINT(ACPI_WARN, ("Unable to resolve device reference for [%p].\n", reference_handle));
+			DEBUG_EVAL_ERROR(ACPI_WARN, acpi_handle, pathname, status);
+			break;
+		}
+
+		DEBUG_PRINT(ACPI_INFO, ("Resolved reference [%s]->[%p]->[%02x]\n", element->string.pointer, reference_handle, reference_list->handles[i]));
+
+		(reference_list->count)++;
+	}
+
+end:
+	acpi_os_free(buffer.pointer);
+
+	return_ACPI_STATUS(status);
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/button/Makefile linux/drivers/acpi/ospm/button/Makefile
--- v2.4.5/linux/drivers/acpi/ospm/button/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/button/Makefile	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,6 @@
+O_TARGET	:= ospm_$(notdir $(CURDIR)).o
+obj-m		:= $(O_TARGET)
+EXTRA_CFLAGS	+= $(ACPI_CFLAGS)
+obj-y		:= $(patsubst %.c,%.o,$(wildcard *.c))
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/button/bn.c linux/drivers/acpi/ospm/button/bn.c
--- v2.4.5/linux/drivers/acpi/ospm/button/bn.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/button/bn.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,439 @@
+/*****************************************************************************
+ *
+ * Module Name: bn.c
+ *   $Revision: 22 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Plxxe, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <acpi.h>
+#include "bn.h"
+
+
+#define _COMPONENT		ACPI_BUTTON
+	MODULE_NAME		("bn")
+
+
+/*****************************************************************************
+ *                            Internal Functions
+ *****************************************************************************/
+
+/*****************************************************************************
+ *
+ * FUNCTION:	bn_print
+ *
+ * PARAMETERS:	
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION: Prints out information on a specific button.
+ *
+ ****************************************************************************/
+
+void
+bn_print (
+	BN_CONTEXT		*button)
+{
+
+	return;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	bn_add_device
+ *
+ * PARAMETERS:	
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bn_add_device(
+	BM_HANDLE		device_handle,
+	void			**context)
+{
+	ACPI_STATUS		status = AE_OK;
+	BM_DEVICE		*device = NULL;
+	BN_CONTEXT		*button = NULL;
+
+	if (!context || *context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Get information on this device.
+	 */
+	status = bm_get_device_info( device_handle, &device );
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	/*
+	 * Allocate a new BN_CONTEXT structure.
+	 */
+	button = acpi_os_callocate(sizeof(BN_CONTEXT));
+	if (!button) {
+		return(AE_NO_MEMORY);
+	}
+
+	button->device_handle = device->handle;
+	button->acpi_handle = device->acpi_handle;
+
+	/*
+	 * Power Button?
+	 * -------------
+	 * Either fixed-feature or generic (namespace) types.
+	 */
+	if (strncmp(device->id.hid, BN_HID_POWER_BUTTON,
+		sizeof(BM_DEVICE_HID)) == 0) {
+
+		if (device->id.type == BM_TYPE_FIXED_BUTTON) {
+
+			button->type = BN_TYPE_POWER_BUTTON_FIXED;
+
+			/* Register for fixed-feature events. */
+			status = acpi_install_fixed_event_handler(
+				ACPI_EVENT_POWER_BUTTON, bn_notify_fixed,
+				(void*)button);
+		}
+		else {
+			button->type = BN_TYPE_POWER_BUTTON;
+		}
+
+	}
+
+	/*
+	 * Sleep Button?
+	 * -------------
+	 * Either fixed-feature or generic (namespace) types.
+	 */
+	else if (strncmp( device->id.hid, BN_HID_SLEEP_BUTTON,
+		sizeof(BM_DEVICE_HID)) == 0) {
+
+		if (device->id.type == BM_TYPE_FIXED_BUTTON) {
+
+			button->type = BN_TYPE_SLEEP_BUTTON_FIXED;
+
+			/* Register for fixed-feature events. */
+			status = acpi_install_fixed_event_handler(
+				ACPI_EVENT_SLEEP_BUTTON, bn_notify_fixed,
+				(void*)button);
+		}
+		else {
+			button->type = BN_TYPE_SLEEP_BUTTON;
+		}
+	}
+
+	/*
+	 * LID Switch?
+	 * -----------
+	 */
+	else if (strncmp( device->id.hid, BN_HID_LID_SWITCH,
+		sizeof(BM_DEVICE_HID)) == 0) {
+		button->type = BN_TYPE_LID_SWITCH;
+	}
+
+	status = bn_osl_add_device(button);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	*context = button;
+
+	bn_print(button);
+
+end:
+	if (ACPI_FAILURE(status)) {
+		acpi_os_free(button);
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	bn_remove_device
+ *
+ * PARAMETERS:	
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bn_remove_device(
+	void			**context)
+{
+	ACPI_STATUS		status = AE_OK;
+	BN_CONTEXT		*button = NULL;
+
+	if (!context || !*context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	button = (BN_CONTEXT*)*context;
+
+	/*
+	 * Unregister for fixed-feature events.
+	 */
+	switch (button->type) {
+	case BN_TYPE_POWER_BUTTON_FIXED:
+		status = acpi_remove_fixed_event_handler(
+			ACPI_EVENT_POWER_BUTTON, bn_notify_fixed);
+		break;
+	case BN_TYPE_SLEEP_BUTTON_FIXED:
+		status = acpi_remove_fixed_event_handler(
+			ACPI_EVENT_SLEEP_BUTTON, bn_notify_fixed);
+		break;
+	}
+
+	bn_osl_remove_device(button);
+
+	acpi_os_free(button);
+
+	*context = NULL;
+
+	return(status);
+}
+
+
+/*****************************************************************************
+ *			      External Functions
+ *****************************************************************************/
+
+/*****************************************************************************
+ *
+ * FUNCTION:	bn_initialize
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+
+ ****************************************************************************/
+
+ACPI_STATUS
+bn_initialize (void)
+{
+	BM_DEVICE_ID		criteria;
+	BM_DRIVER		driver;
+
+	MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
+	MEMSET(&driver, 0, sizeof(BM_DRIVER));
+
+	driver.notify = &bn_notify;
+	driver.request = &bn_request;
+
+	/*
+	 * Register for power buttons.
+	 */
+	MEMCPY(criteria.hid, BN_HID_POWER_BUTTON, sizeof(BN_HID_POWER_BUTTON));
+	bm_register_driver(&criteria, &driver);
+
+	/*
+	 * Register for sleep buttons.
+	 */
+	MEMCPY(criteria.hid, BN_HID_SLEEP_BUTTON, sizeof(BN_HID_SLEEP_BUTTON));
+	bm_register_driver(&criteria, &driver);
+
+	/*
+	 * Register for LID switches.
+	 */
+	MEMCPY(criteria.hid, BN_HID_LID_SWITCH, sizeof(BN_HID_LID_SWITCH));
+	bm_register_driver(&criteria, &driver);
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	bn_terminate
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bn_terminate (void)
+{
+	ACPI_STATUS		status = AE_OK;
+	BM_DEVICE_ID		criteria;
+	BM_DRIVER		driver;
+
+	MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
+	MEMSET(&driver, 0, sizeof(BM_DRIVER));
+
+	driver.notify = &bn_notify;
+	driver.request = &bn_request;
+
+	/*
+	 * Unregister for power buttons.
+	 */
+	MEMCPY(criteria.hid, BN_HID_POWER_BUTTON, sizeof(BN_HID_POWER_BUTTON));
+	status = bm_unregister_driver(&criteria, &driver);
+
+	/*
+	 * Unregister for sleep buttons.
+	 */
+	MEMCPY(criteria.hid, BN_HID_SLEEP_BUTTON, sizeof(BN_HID_SLEEP_BUTTON));
+	status = bm_unregister_driver(&criteria, &driver);
+
+	/*
+	 * Unregister for LID switches.
+	 */
+	MEMCPY(criteria.hid, BN_HID_LID_SWITCH, sizeof(BN_HID_LID_SWITCH));
+	status = bm_unregister_driver(&criteria, &driver);
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	bn_notify_fixed
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bn_notify_fixed (
+	void			*context)
+{
+	ACPI_STATUS		status = AE_OK;
+
+	if (!context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	status = bn_osl_generate_event(BN_NOTIFY_STATUS_CHANGE,
+		((BN_CONTEXT*)context));
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	bn_notify
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bn_notify (
+	BM_NOTIFY		notify_type,
+	BM_HANDLE		device_handle,
+	void			**context)
+{
+	ACPI_STATUS		status = AE_OK;
+
+	if (!context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	switch (notify_type) {
+	case BM_NOTIFY_DEVICE_ADDED:
+		status = bn_add_device(device_handle, context);
+		break;
+		
+	case BM_NOTIFY_DEVICE_REMOVED:
+		status = bn_remove_device(context);
+		break;
+		
+	case BN_NOTIFY_STATUS_CHANGE:
+		status = bn_osl_generate_event(BN_NOTIFY_STATUS_CHANGE,
+			((BN_CONTEXT*)*context));
+		break;
+
+	default:
+		status = AE_SUPPORT;
+		break;
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	bn_request
+ *
+ * PARAMETERS:	
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bn_request (
+	BM_REQUEST		*request,
+	void			*context)
+{
+	ACPI_STATUS		status = AE_OK;
+
+	/*
+	 * Must have a valid request structure and context.
+	 */
+	if (!request || !context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Handle Request:
+	 * ---------------
+	 */
+	switch (request->command) {
+
+	default:
+		status = AE_SUPPORT;
+		break;
+	}
+
+	request->status = status;
+
+	return(status);
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/button/bn_osl.c linux/drivers/acpi/ospm/button/bn_osl.c
--- v2.4.5/linux/drivers/acpi/ospm/button/bn_osl.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/button/bn_osl.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,244 @@
+/******************************************************************************
+ *
+ * Module Name: bn_osl.c
+ *   $Revision: 10 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <acpi.h>
+#include "bn.h"
+
+
+MODULE_AUTHOR("Andrew Grover");
+MODULE_DESCRIPTION("ACPI Component Architecture (CA) - Button Driver");
+
+
+#define BN_PROC_ROOT		"button"
+#define BN_PROC_POWER_BUTTON	"power"
+#define BN_PROC_SLEEP_BUTTON	"sleep"
+#define BN_PROC_LID_SWITCH	"lid"
+
+extern struct proc_dir_entry	*bm_proc_root;
+static struct proc_dir_entry	*bn_proc_root = NULL;
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	bn_osl_add_device
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bn_osl_add_device(
+	BN_CONTEXT		*button)
+{
+	ACPI_STATUS		status = AE_OK;
+
+	if (!button) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	switch (button->type) {
+
+	case BN_TYPE_POWER_BUTTON:
+	case BN_TYPE_POWER_BUTTON_FIXED:
+		printk(KERN_INFO "Power Button: found\n");
+		if (!proc_mkdir(BN_PROC_POWER_BUTTON, bn_proc_root)) {
+			status = AE_ERROR;
+		}
+		break;
+
+	case BN_TYPE_SLEEP_BUTTON:
+	case BN_TYPE_SLEEP_BUTTON_FIXED:
+		printk(KERN_INFO "Sleep Button: found\n");
+		if (!proc_mkdir(BN_PROC_SLEEP_BUTTON, bn_proc_root)) {
+			status = AE_ERROR;
+		}
+		break;
+
+	case BN_TYPE_LID_SWITCH:
+		printk(KERN_INFO "Lid Switch: found\n");
+		if (!proc_mkdir(BN_PROC_LID_SWITCH, bn_proc_root)) {
+			status = AE_ERROR;
+		}
+		break;
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	bn_osl_remove_device
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bn_osl_remove_device (
+	BN_CONTEXT		*button)
+{
+	if (!button) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	switch (button->type) {
+
+	case BN_TYPE_POWER_BUTTON:
+	case BN_TYPE_POWER_BUTTON_FIXED:
+		remove_proc_entry(BN_PROC_POWER_BUTTON, bn_proc_root);
+		break;
+
+	case BN_TYPE_SLEEP_BUTTON:
+	case BN_TYPE_SLEEP_BUTTON_FIXED:
+		remove_proc_entry(BN_PROC_SLEEP_BUTTON, bn_proc_root);
+		break;
+
+	case BN_TYPE_LID_SWITCH:
+		remove_proc_entry(BN_PROC_LID_SWITCH, bn_proc_root);
+		break;
+	}
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	bn_osl_generate_event
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+bn_osl_generate_event (
+	u32			event,
+	BN_CONTEXT		*button)
+{
+	ACPI_STATUS		status = AE_OK;
+
+	if (!button) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	switch (event) {
+
+	case BN_NOTIFY_STATUS_CHANGE:
+
+		switch(button->type) {
+
+		case BN_TYPE_POWER_BUTTON:
+		case BN_TYPE_POWER_BUTTON_FIXED:
+			status = bm_osl_generate_event(button->device_handle,
+				BN_PROC_ROOT, BN_PROC_POWER_BUTTON, event, 0);
+			break;
+
+		case BN_TYPE_SLEEP_BUTTON:
+		case BN_TYPE_SLEEP_BUTTON_FIXED:
+			status = bm_osl_generate_event(button->device_handle,
+				BN_PROC_ROOT, BN_PROC_SLEEP_BUTTON, event, 0);
+			break;
+
+		case BN_TYPE_LID_SWITCH:
+			status = bm_osl_generate_event(button->device_handle,
+				BN_PROC_ROOT, BN_PROC_LID_SWITCH, event, 0);
+			break;
+
+		default:
+			status = AE_SUPPORT;
+			break;
+		}
+
+		break;
+
+	default:
+		return(AE_BAD_PARAMETER);
+		break;
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bn_osl_init
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	0: Success
+ *
+ * DESCRIPTION: Module initialization.
+ *
+ ****************************************************************************/
+
+static int __init 
+bn_osl_init (void)
+{
+	ACPI_STATUS		status = AE_OK;
+
+	bn_proc_root = proc_mkdir(BN_PROC_ROOT, bm_proc_root);
+	if (!bn_proc_root) {
+		status = AE_ERROR;
+	}
+	else {
+		status = bn_initialize();
+		if (ACPI_FAILURE(status)) {
+			remove_proc_entry(BN_PROC_ROOT, bm_proc_root);
+		}
+	}
+
+	return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    bn_osl_cleanup
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	<none>
+ *
+ * DESCRIPTION: Module cleanup.
+ *
+ ****************************************************************************/
+
+static void __exit 
+bn_osl_cleanup (void)
+{
+	bn_terminate();
+
+	if (bn_proc_root) {
+		remove_proc_entry(BN_PROC_ROOT, bm_proc_root);
+	}
+
+	return;
+}
+
+
+module_init(bn_osl_init);
+module_exit(bn_osl_cleanup);
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/ec/Makefile linux/drivers/acpi/ospm/ec/Makefile
--- v2.4.5/linux/drivers/acpi/ospm/ec/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/ec/Makefile	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,6 @@
+O_TARGET	:= ospm_$(notdir $(CURDIR)).o
+obj-m		:= $(O_TARGET)
+EXTRA_CFLAGS	+= $(ACPI_CFLAGS)
+obj-y		:= $(patsubst %.c,%.o,$(wildcard *.c))
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/ec/ec_osl.c linux/drivers/acpi/ospm/ec/ec_osl.c
--- v2.4.5/linux/drivers/acpi/ospm/ec/ec_osl.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/ec/ec_osl.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,115 @@
+/*****************************************************************************
+ *
+ * Module Name: ec_osl.c
+ *   $Revision: 6 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <acpi.h>
+#include <bm.h>
+#include "ec.h"
+
+
+MODULE_AUTHOR("Andrew Grover");
+MODULE_DESCRIPTION("ACPI Component Architecture (CA) - Embedded Controller Driver");
+
+#ifdef ACPI_DEBUG
+
+static int dbg_layer = ACPI_COMPONENT_DEFAULT;
+MODULE_PARM(dbg_layer, "i");
+MODULE_PARM_DESC(dbg_layer, "Controls debug output (see acpi_dbg_layer).\n");
+
+static int dbg_level = DEBUG_DEFAULT;
+MODULE_PARM(dbg_level, "i");
+MODULE_PARM_DESC(dbg_level, "Controls debug output (see acpi_dbg_level).\n");
+
+#endif /*ACPI_DEBUG*/
+
+
+#ifdef ACPI_DEBUG
+static u32			save_dbg_layer;
+static u32			save_dbg_level;
+#endif /*ACPI_DEBUG*/
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_osl_init
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	0: Success
+ *
+ * DESCRIPTION: Module initialization.
+ *
+ ****************************************************************************/
+
+static int __init 
+ec_osl_init (void)
+{
+	ACPI_STATUS		status = AE_OK;
+
+#ifdef ACPI_DEBUG
+	save_dbg_layer = acpi_dbg_layer;
+	acpi_dbg_layer = dbg_layer;
+
+	save_dbg_level = acpi_dbg_level;
+	acpi_dbg_level = dbg_level;
+#endif /*ACPI_DEBUG*/
+
+	status = ec_initialize();
+
+	return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
+}
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_osl_cleanup
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	<none>
+ *
+ * DESCRIPTION: Module cleanup.
+ *
+ ****************************************************************************/
+
+static void __exit 
+ec_osl_cleanup(void)
+{
+	ec_terminate();
+
+#ifdef ACPI_DEBUG
+	acpi_dbg_layer = save_dbg_layer;
+	acpi_dbg_level = save_dbg_level;
+#endif /*ACPI_DEBUG*/
+
+	return;
+}
+
+module_init(ec_osl_init);
+module_exit(ec_osl_cleanup);
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/ec/ecgpe.c linux/drivers/acpi/ospm/ec/ecgpe.c
--- v2.4.5/linux/drivers/acpi/ospm/ec/ecgpe.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/ec/ecgpe.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,230 @@
+/*****************************************************************************
+ *
+ * Module Name: ecgpe.c
+ *   $Revision: 26 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <acpi.h>
+#include "ec.h"
+
+#define _COMPONENT		ACPI_EC
+	MODULE_NAME		("ecgpe")
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_query_handler
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+void
+ec_query_handler (
+	void                    *context)
+{
+	EC_CONTEXT		*ec = (EC_CONTEXT*)context;
+	static char		object_name[5] = {'_','Q','0','0','\0'};
+	const char		hex[] = {'0','1','2','3','4','5','6','7','8',
+					'9','A','B','C','D','E','F'};
+
+	if (!ec) {
+		return;
+	}
+
+	/*
+	 * Evaluate _Qxx:
+	 * --------------
+	 * Evaluate corresponding _Qxx method.  Note that a zero query value
+	 * indicates a spurious EC_SCI (no such thing as _Q00).
+	 */
+	object_name[2] = hex[((ec->query_data >> 4) & 0x0F)];
+	object_name[3] = hex[(ec->query_data & 0x0F)];
+
+	bm_evaluate_object(ec->acpi_handle, object_name, NULL, NULL);
+
+	return;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_gpe_handler
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+void
+ec_gpe_handler (
+	void                    *context)
+{
+	ACPI_STATUS             status = AE_OK;
+	EC_CONTEXT              *ec = (EC_CONTEXT*)context;
+	EC_STATUS               ec_status = 0;
+
+	if (!ec) {
+		return;
+	}
+
+	/* TBD: synchronize w/ transaction (ectransx). */
+
+	/*
+	 * EC_SCI?
+	 * -------
+	 * Check the EC_SCI bit to see if this is an EC_SCI event.  If not (e.g.
+	 * OBF/IBE) just return, as we already poll to detect these events.
+	 */
+	ec_status = acpi_os_in8(ec->status_port);
+	if (!(ec_status & EC_FLAG_SCI)) {
+		return;
+	}
+
+	/*
+	 * Run Query:
+	 * ----------
+	 * Query the EC to find out which _Qxx method we need to evaluate.
+	 * Note that successful completion of the query causes the EC_SCI
+	 * bit to be cleared (and thus clearing the interrupt source).
+	 */
+	status = ec_io_write(ec, ec->command_port, EC_COMMAND_QUERY,
+		EC_EVENT_OUTPUT_BUFFER_FULL);
+	if (ACPI_FAILURE(status)) {
+		return;
+	}
+
+	status = ec_io_read(ec, ec->data_port, &(ec->query_data),
+		EC_EVENT_NONE);
+	if (ACPI_FAILURE(status)) {
+		return;
+	}
+
+	/* TBD: un-synchronize w/ transaction (ectransx). */
+
+	/*
+	 * Spurious EC_SCI?
+	 * ----------------
+	 */
+	if (!ec->query_data) {
+		return;
+	}
+
+	/*
+	 * Defer _Qxx Execution:
+	 * ---------------------
+	 * Can't evaluate this method now 'cause we're at interrupt-level.
+	 */
+	status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
+		ec_query_handler, ec);
+	if (ACPI_FAILURE(status)) {
+		return;
+	}
+
+	return;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_install_gpe_handler
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ec_install_gpe_handler (
+	EC_CONTEXT              *ec)
+{
+	ACPI_STATUS             status = AE_OK;
+
+	if (!ec) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Evaluate _GPE:
+	 * --------------
+	 * Evaluate the "_GPE" object (required) to find out which GPE bit
+	 * is used by this EC to signal events (SCIs).
+	 */
+	status = bm_evaluate_simple_integer(ec->acpi_handle,
+		"_GPE", &(ec->gpe_bit));
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	/*
+	 * Install GPE Handler:
+	 * --------------------
+	 * Install a handler for this EC's GPE bit.
+	 */
+	status = acpi_install_gpe_handler(ec->gpe_bit, ACPI_EVENT_EDGE_TRIGGERED,
+		&ec_gpe_handler, ec);
+	if (ACPI_FAILURE(status)) {
+		ec->gpe_bit = EC_GPE_UNKNOWN;
+		return(status);
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_remove_gpe_handler
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ec_remove_gpe_handler (
+	EC_CONTEXT              *ec)
+{
+	ACPI_STATUS             status = AE_OK;
+
+	if (!ec) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	status = acpi_remove_gpe_handler(ec->gpe_bit, &ec_gpe_handler);
+
+	return(status);
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/ec/ecmain.c linux/drivers/acpi/ospm/ec/ecmain.c
--- v2.4.5/linux/drivers/acpi/ospm/ec/ecmain.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/ec/ecmain.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,452 @@
+/*****************************************************************************
+ *
+ * Module Name: ecmain.c
+ *   $Revision: 26 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <acpi.h>
+#include "ec.h"
+
+#define _COMPONENT		ACPI_EC
+	MODULE_NAME		("ecmain")
+
+
+/****************************************************************************
+ *                            Internal Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_print
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION: Prints out information on a specific ec.
+ *
+ ****************************************************************************/
+
+void
+ec_print (
+	EC_CONTEXT              *ec)
+{
+
+	if (!ec) {
+		return;
+	}
+
+	acpi_os_printf("EC: found, GPE %d\n", ec->gpe_bit);
+
+
+	return;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_get_port_values
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION: Evaluate _CRS to get the current resources (I/O port
+ *              addresses) for this EC.
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ec_get_port_values(
+	EC_CONTEXT              *ec)
+{
+	ACPI_STATUS             status = AE_OK;
+	ACPI_BUFFER             buffer;
+	ACPI_RESOURCE           *resource = NULL;
+
+	if (!ec) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	buffer.length = 0;
+	buffer.pointer = NULL;
+
+	status = acpi_get_current_resources(ec->acpi_handle, &buffer);
+	if (status != AE_BUFFER_OVERFLOW) {
+		return(status);
+	}
+
+	buffer.pointer = acpi_os_callocate(buffer.length);
+	if (!buffer.pointer) {
+		return(AE_NO_MEMORY);
+	}
+
+	status = acpi_get_current_resources(ec->acpi_handle, &buffer);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	resource = (ACPI_RESOURCE *) buffer.pointer;
+	ec->data_port = resource->data.io.min_base_address;
+
+	resource = NEXT_RESOURCE(resource);
+
+	ec->status_port = ec->command_port =
+		resource->data.io.min_base_address;
+end:
+	acpi_os_free(buffer.pointer);
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_add_device
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ec_add_device(
+	BM_HANDLE               device_handle,
+	void                    **context)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_DEVICE		*device = NULL;
+	EC_CONTEXT              *ec = NULL;
+	u8                      gpe_handler = FALSE;
+	u8                      space_handler = FALSE;
+
+	if (!context || *context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Get information on this device.
+	 */
+	status = bm_get_device_info(device_handle, &device);
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	/*
+	 * Allocate a new EC_CONTEXT structure.
+	 */
+	ec = acpi_os_callocate(sizeof(EC_CONTEXT));
+	if (!ec) {
+		return(AE_NO_MEMORY);
+	}
+
+	ec->device_handle = device->handle;
+	ec->acpi_handle = device->acpi_handle;
+
+	/*
+	 * Get the I/O port addresses for the command/status and data ports.
+	 */
+	status = ec_get_port_values(ec);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	/*
+	 * See if we need to obtain the global lock for EC transactions.
+	 */
+	status = bm_evaluate_simple_integer(ec->acpi_handle, "_GLK",
+		&ec->use_global_lock);
+	if (status == AE_NOT_FOUND) {
+		ec->use_global_lock = 0;
+	}
+	else if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	/*
+	 * Install a handler for servicing this EC's GPE.
+	 */
+	status = ec_install_gpe_handler(ec);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+	else {
+		gpe_handler = TRUE;
+	}
+
+	/*
+	 * Install a handler for servicing this EC's address space.
+	 */
+	status = ec_install_space_handler(ec);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+	else {
+		space_handler = TRUE;
+	}
+
+	/*
+	 * Create a semaphore to serialize EC transactions.
+	 */
+	status = acpi_os_create_semaphore(1,1, &(ec->mutex));
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	/*
+	 * Context now contains information specific to this EC.  Note
+	 * that we'll get this pointer back on every ec_request() and
+	 * ec_notify().
+	 */
+	*context = ec;
+
+	ec_print(ec);
+
+end:
+	if (ACPI_FAILURE(status)) {
+
+		if (gpe_handler) {
+			ec_remove_gpe_handler(ec);
+		}
+
+		if (space_handler) {
+			ec_remove_space_handler(ec);
+		}
+
+		if (ec->mutex) {
+			acpi_os_delete_semaphore(ec->mutex);
+		}
+
+		acpi_os_free(ec);
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_remove_device
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ec_remove_device(
+	void                    **context)
+{
+	ACPI_STATUS             status = AE_OK;
+	EC_CONTEXT              *ec = NULL;
+
+	if (!context || !*context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	ec = (EC_CONTEXT*)*context;
+
+	ec_remove_space_handler(ec);
+
+	ec_remove_gpe_handler(ec);
+
+	if (ec->mutex) {
+		acpi_os_delete_semaphore(ec->mutex);
+	}
+
+	acpi_os_free(ec);
+
+	*context = NULL;
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *                             External Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_initialize
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ec_initialize (void)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_DEVICE_ID		criteria;
+	BM_DRIVER		driver;
+
+	MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
+	MEMSET(&driver, 0, sizeof(BM_DRIVER));
+
+	/*
+	 * Register driver for AC Adapter devices.
+	 */
+	MEMCPY(criteria.hid, EC_HID_EC, sizeof(EC_HID_EC));
+
+	driver.notify = &ec_notify;
+	driver.request = &ec_request;
+
+	status = bm_register_driver(&criteria, &driver);
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_terminate
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ec_terminate(void)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_DEVICE_ID		criteria;
+	BM_DRIVER		driver;
+
+	MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
+	MEMSET(&driver, 0, sizeof(BM_DRIVER));
+
+	/*
+	 * Unregister driver for AC Adapter devices.
+	 */
+	MEMCPY(criteria.hid, EC_HID_EC, sizeof(EC_HID_EC));
+
+	driver.notify = &ec_notify;
+	driver.request = &ec_request;
+
+	status = bm_unregister_driver(&criteria, &driver);
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_notify
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ec_notify (
+	BM_NOTIFY               notify,
+	BM_HANDLE               device_handle,
+	void                    **context)
+{
+	ACPI_STATUS             status = AE_OK;
+
+	switch (notify) {
+
+	case BM_NOTIFY_DEVICE_ADDED:
+		status = ec_add_device(device_handle, context);
+		break;
+
+	case BM_NOTIFY_DEVICE_REMOVED:
+		status = ec_remove_device(context);
+		break;
+
+	default:
+		status = AE_SUPPORT;
+		break;
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_request
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ec_request (
+	BM_REQUEST              *request,
+	void                    *context)
+{
+	ACPI_STATUS             status = AE_OK;
+	EC_REQUEST              *ec_request = NULL;
+	EC_CONTEXT              *ec = NULL;
+
+	/*
+	 * Must have a valid request structure and context.
+	 */
+	if (!request || !context)
+		return(AE_BAD_PARAMETER);
+
+	/*
+	 * buffer must contain a valid EC_REQUEST structure.
+	 */
+	status = bm_cast_buffer(&(request->buffer), (void**)&ec_request,
+		sizeof(EC_REQUEST));
+	if (ACPI_FAILURE(status))
+		return(status);
+
+	/*
+	 * context contains information specific to this EC.
+	 */
+	ec = (EC_CONTEXT*)context;
+
+	/*
+	 * Perform the Transaction.
+	 */
+	status = ec_transaction(ec, ec_request);
+
+	return(status);
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/ec/ecspace.c linux/drivers/acpi/ospm/ec/ecspace.c
--- v2.4.5/linux/drivers/acpi/ospm/ec/ecspace.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/ec/ecspace.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,185 @@
+/*****************************************************************************
+ *
+ * Module Name: ecspace.c
+ *   $Revision: 20 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <acpi.h>
+#include "ec.h"
+
+#define _COMPONENT		ACPI_EC
+	MODULE_NAME		("ecspace")
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_space_setup
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ec_space_setup (
+	ACPI_HANDLE		region_handle,
+	u32			function,
+	void			*handler_context,
+	void			**return_context)
+{
+	/*
+	 * The EC object is in the handler context and is needed
+	 * when calling the ec_space_handler.
+	 */
+	*return_context = handler_context;
+
+	return AE_OK;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_space_handler
+ *
+ * PARAMETERS:  function            - Read or Write operation
+ *              address             - Where in the space to read or write
+ *              bit_width           - Field width in bits (8, 16, or 32)
+ *              value               - Pointer to in or out value
+ *              context             - context pointer
+ *
+ * RETURN:
+ *
+ * DESCRIPTION: Handler for the Embedded Controller (EC) address space
+ *              (Op Region)
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ec_space_handler (
+	u32                     function,
+	ACPI_PHYSICAL_ADDRESS   address,
+	u32                     bit_width,
+	u32                     *value,
+	void                    *handler_context,
+	void                    *region_context)
+{
+	ACPI_STATUS             status = AE_OK;
+	EC_CONTEXT              *ec = NULL;
+	EC_REQUEST              ec_request;
+
+	if (address > 0xFF || bit_width != 8 || !value || !handler_context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	ec = (EC_CONTEXT*)handler_context;
+
+	switch (function) {
+
+	case ACPI_READ_ADR_SPACE:
+		ec_request.command = EC_COMMAND_READ;
+		ec_request.address = address;
+		ec_request.data = 0;
+		break;
+
+	case ACPI_WRITE_ADR_SPACE:
+		ec_request.command = EC_COMMAND_WRITE;
+		ec_request.address = address;
+		ec_request.data = (u8)(*value);
+		break;
+
+	default:
+		return(AE_BAD_PARAMETER);
+		break;
+	}
+
+	/*
+	 * Perform the Transaction.
+	 */
+	status = ec_transaction(ec, &ec_request);
+	if (ACPI_SUCCESS(status)) {
+		(*value) = (u32)ec_request.data;
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_install_space_handler
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ec_install_space_handler (
+	EC_CONTEXT              *ec)
+{
+	ACPI_STATUS             status = AE_OK;
+
+	if (!ec) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	status = acpi_install_address_space_handler (ec->acpi_handle,
+		ACPI_ADR_SPACE_EC, &ec_space_handler, &ec_space_setup, ec);
+	
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_remove_space_handler
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ec_remove_space_handler (
+	EC_CONTEXT              *ec)
+{
+	ACPI_STATUS             status = AE_OK;
+
+	if (!ec) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	status = acpi_remove_address_space_handler(ec->acpi_handle,
+		ACPI_ADR_SPACE_EC, &ec_space_handler);
+
+	return(status);
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/ec/ectransx.c linux/drivers/acpi/ospm/ec/ectransx.c
--- v2.4.5/linux/drivers/acpi/ospm/ec/ectransx.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/ec/ectransx.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,326 @@
+/*****************************************************************************
+ *
+ * Module Name: ectransx.c
+ *   $Revision: 21 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <acpi.h>
+#include "ec.h"
+
+#define _COMPONENT		ACPI_EC
+	MODULE_NAME             ("ectransx")
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_io_wait
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ec_io_wait (
+	EC_CONTEXT              *ec,
+	EC_EVENT                wait_event)
+{
+	EC_STATUS               ec_status = 0;
+	u32                     i = 100;
+
+	if (!ec || ((wait_event != EC_EVENT_OUTPUT_BUFFER_FULL)
+		&& (wait_event != EC_EVENT_INPUT_BUFFER_EMPTY))) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Wait for Event:
+	 * ---------------
+	 * Poll the EC status register waiting for the event to occur.
+	 * Note that we'll wait a maximum of 1ms in 10us chunks.
+	 */
+	switch (wait_event) {
+
+	case EC_EVENT_OUTPUT_BUFFER_FULL:
+		do {
+			ec_status = acpi_os_in8(ec->status_port);
+			if (ec_status & EC_FLAG_OUTPUT_BUFFER) {
+				return(AE_OK);
+			}
+			acpi_os_sleep_usec(10);
+		} while (--i>0);
+		break;
+
+	case EC_EVENT_INPUT_BUFFER_EMPTY:
+		do {
+			ec_status = acpi_os_in8(ec->status_port);
+			if (!(ec_status & EC_FLAG_INPUT_BUFFER)) {
+				return(AE_OK);
+			}
+			acpi_os_sleep_usec(10);
+		} while (--i>0);
+		break;
+	}
+
+	return(AE_TIME);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_io_read
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ec_io_read (
+	EC_CONTEXT              *ec,
+	ACPI_IO_ADDRESS         io_port,
+	u8                      *data,
+	EC_EVENT                wait_event)
+{
+	ACPI_STATUS             status = AE_OK;
+
+	if (!ec || !data) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	*data = acpi_os_in8(io_port);
+
+	if (wait_event) {
+		status = ec_io_wait(ec, wait_event);
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_io_write
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ec_io_write (
+	EC_CONTEXT              *ec,
+	ACPI_IO_ADDRESS         io_port,
+	u8                      data,
+	EC_EVENT                wait_event)
+{
+	ACPI_STATUS             status = AE_OK;
+
+	if (!ec) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	acpi_os_out8(io_port, data);
+
+	if (wait_event) {
+		status = ec_io_wait(ec, wait_event);
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_read
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ec_read (
+	EC_CONTEXT              *ec,
+	u8                      address,
+	u8                      *data)
+{
+	ACPI_STATUS             status = AE_OK;
+
+	if (!ec || !data) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	if (ec->use_global_lock) {
+		status = acpi_acquire_global_lock();
+		if (ACPI_FAILURE(status)) {
+			return(status);
+		}
+	}
+
+	status = ec_io_write(ec, ec->command_port, EC_COMMAND_READ,
+		EC_EVENT_INPUT_BUFFER_EMPTY);
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	status = ec_io_write(ec, ec->data_port, address,
+		EC_EVENT_OUTPUT_BUFFER_FULL);
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	status = ec_io_read(ec, ec->data_port, data, EC_EVENT_NONE);
+
+	if (ec->use_global_lock) {
+		acpi_release_global_lock();
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_write
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ec_write (
+	EC_CONTEXT              *ec,
+	u8                      address,
+	u8                      data)
+{
+	ACPI_STATUS             status = AE_OK;
+
+	if (!ec)
+		return(AE_BAD_PARAMETER);
+
+	if (ec->use_global_lock) {
+		status = acpi_acquire_global_lock();
+		if (ACPI_FAILURE(status)) {
+			return(status);
+		}
+	}
+
+	status = ec_io_write(ec, ec->command_port, EC_COMMAND_WRITE,
+		EC_EVENT_INPUT_BUFFER_EMPTY);
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	status = ec_io_write(ec, ec->data_port, address,
+		EC_EVENT_INPUT_BUFFER_EMPTY);
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	status = ec_io_write(ec, ec->data_port, data,
+		EC_EVENT_INPUT_BUFFER_EMPTY);
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	if (ec->use_global_lock) {
+		acpi_release_global_lock();
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    ec_transaction
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+ec_transaction (
+	EC_CONTEXT              *ec,
+	EC_REQUEST              *request)
+{
+	ACPI_STATUS             status = AE_OK;
+
+	if (!ec || !request) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Obtain mutex to serialize all EC transactions.
+	 */
+	status = acpi_os_wait_semaphore(ec->mutex, 1, EC_DEFAULT_TIMEOUT);
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	/*
+	 * Perform the transaction.
+	 */
+	switch (request->command) {
+
+	case EC_COMMAND_READ:
+		status = ec_read(ec, request->address, &(request->data));
+		break;
+
+	case EC_COMMAND_WRITE:
+		status = ec_write(ec, request->address, request->data);
+		break;
+
+	default:
+		status = AE_SUPPORT;
+		break;
+	}
+
+	/*
+	 * Signal the mutex to indicate transaction completion.
+	 */
+	acpi_os_signal_semaphore(ec->mutex, 1);
+
+	return(status);
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/include/ac.h linux/drivers/acpi/ospm/include/ac.h
--- v2.4.5/linux/drivers/acpi/ospm/include/ac.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/include/ac.h	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,102 @@
+/*****************************************************************************
+ *
+ * Module Name: ac.h
+ *   $Revision: 6 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef __AC_H__
+#define __AC_H__
+
+#include <actypes.h>
+#include <acexcep.h>
+#include <bm.h>
+
+
+/*****************************************************************************
+ *                            Types & Other Defines
+ *****************************************************************************/
+
+/*
+ * Notifications:
+ * --------------
+ */
+#define AC_NOTIFY_STATUS_CHANGE	((BM_NOTIFY) 0x80)
+
+/*
+ * Hardware IDs:
+ * -------------
+ */
+#define AC_HID_AC_ADAPTER	"ACPI0003"
+
+
+/*
+ * Device Context:
+ * ---------------
+ */
+typedef struct
+{
+	BM_HANDLE		device_handle;
+	ACPI_HANDLE		acpi_handle;
+	char			uid[9];
+	u32 			is_online;
+} AC_CONTEXT;
+
+
+/*****************************************************************************
+ *                              Function Prototypes
+ *****************************************************************************/
+
+ACPI_STATUS
+ac_initialize (void);
+
+ACPI_STATUS
+ac_terminate (void);
+
+ACPI_STATUS
+ac_notify (
+	u32			notify_type,
+	u32 			device,
+	void			**context);
+
+ACPI_STATUS
+ac_request(
+	BM_REQUEST		*request_info,
+	void			*context);
+
+/* AC Adapter Driver OSL */
+
+ACPI_STATUS
+ac_osl_add_device (
+	AC_CONTEXT		*ac_adapter);
+
+ACPI_STATUS
+ac_osl_remove_device (
+	AC_CONTEXT		*ac_adapter);
+
+ACPI_STATUS
+ac_osl_generate_event (
+	u32			event,
+	AC_CONTEXT		*ac_adapter);
+
+
+#endif	/* __AC_H__ */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/include/bm.h linux/drivers/acpi/ospm/include/bm.h
--- v2.4.5/linux/drivers/acpi/ospm/include/bm.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/include/bm.h	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,584 @@
+/*****************************************************************************
+ *
+ * Module name: bm.h
+ *   $Revision: 39 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __BM_H__
+#define __BM_H__
+
+#include <actypes.h>
+#include <acexcep.h>
+
+
+/*****************************************************************************
+ *                               Types & Defines
+ *****************************************************************************/
+
+/*
+ * Output Flags (Debug):
+ * ---------------------
+ */
+#define BM_PRINT_ALL		(0x00000000)
+#define BM_PRINT_GROUP		(0x00000001)
+#define BM_PRINT_LINKAGE	(0x00000002)
+#define BM_PRINT_IDENTIFICATION	(0x00000004)
+#define BM_PRINT_POWER		(0x00000008)
+#define BM_PRINT_PRESENT	(0x00000010)
+
+
+/*
+ * BM_COMMAND:
+ * -----------
+ */
+typedef u32			BM_COMMAND;
+
+#define BM_COMMAND_UNKNOWN	((BM_COMMAND) 0x00)
+
+#define BM_COMMAND_GET_POWER_STATE ((BM_COMMAND) 0x01)
+#define BM_COMMAND_SET_POWER_STATE ((BM_COMMAND) 0x02)
+
+#define BM_COMMAND_DEVICE_SPECIFIC ((BM_COMMAND) 0x80)
+
+/*
+ * BM_NOTIFY:
+ * ----------
+ * Standard ACPI notification values, from section 5.6.3 of the ACPI 2.0
+ * specification.  Note that the Bus Manager internally handles all
+ * standard ACPI notifications -- driver modules are never sent these
+ * values (see "Bus Manager Notifications", below).
+ */
+typedef u32			BM_NOTIFY;
+
+#define BM_NOTIFY_BUS_CHECK	((BM_NOTIFY) 0x00)
+#define BM_NOTIFY_DEVICE_CHECK	((BM_NOTIFY) 0x01)
+#define BM_NOTIFY_DEVICE_WAKE	((BM_NOTIFY) 0x02)
+#define BM_NOTIFY_EJECT_REQUEST	((BM_NOTIFY) 0x03)
+#define BM_NOTIFY_DEVICE_CHECK_LIGHT ((BM_NOTIFY) 0x04)
+#define BM_NOTIFY_FREQUENCY_MISMATCH ((BM_NOTIFY) 0x05)
+#define BM_NOTIFY_BUS_MODE_MISMATCH ((BM_NOTIFY) 0x06)
+#define BM_NOTIFY_POWER_FAULT	((BM_NOTIFY) 0x07)
+
+/*
+ * These are a higher-level abstraction of ACPI notifications, intended
+ * for consumption by driver modules to facilitate PnP.
+ */
+#define BM_NOTIFY_UNKNOWN	((BM_NOTIFY) 0x00)
+#define BM_NOTIFY_DEVICE_ADDED	((BM_NOTIFY) 0x01)
+#define BM_NOTIFY_DEVICE_REMOVED ((BM_NOTIFY) 0x02)
+
+
+/*
+ * BM_HANDLE:
+ * ----------
+ */
+typedef u32			BM_HANDLE;
+
+#define BM_HANDLE_ROOT		((BM_HANDLE) 0x00000000)
+#define BM_HANDLE_UNKNOWN	((BM_HANDLE) 0xFFFFFFFF)
+#define BM_HANDLES_MAX		100
+
+
+
+/*
+ * BM_HANDLE_LIST:
+ * ---------------
+ */
+typedef struct
+{
+	u32			count;
+	BM_HANDLE		handles[BM_HANDLES_MAX];
+} BM_HANDLE_LIST;
+
+
+/*
+ * BM_DEVICE_TYPE:
+ * ---------------
+ */
+typedef u32			BM_DEVICE_TYPE;
+
+#define BM_TYPE_UNKNOWN		((BM_DEVICE_TYPE) 0x00000000)
+
+#define BM_TYPE_SYSTEM		((BM_DEVICE_TYPE) 0x00000001)
+#define BM_TYPE_SCOPE		((BM_DEVICE_TYPE) 0x00000002)
+#define BM_TYPE_PROCESSOR	((BM_DEVICE_TYPE) 0x00000003)
+#define BM_TYPE_THERMAL_ZONE	((BM_DEVICE_TYPE) 0x00000004)
+#define BM_TYPE_POWER_RESOURCE	((BM_DEVICE_TYPE) 0x00000005)
+#define BM_TYPE_DEVICE		((BM_DEVICE_TYPE) 0x00000006)
+#define BM_TYPE_FIXED_BUTTON	((BM_DEVICE_TYPE) 0x00000007)
+
+
+/*
+ * BM_DEVICE_UID:
+ * --------------
+ */
+typedef char			BM_DEVICE_UID[9];
+
+#define BM_UID_UNKNOWN		'0'
+
+
+/*
+ * BM_DEVICE_HID:
+ * --------------
+ */
+typedef char			BM_DEVICE_HID[9];
+
+#define BM_HID_UNKNOWN		'\0'
+#define BM_HID_POWER_BUTTON	"PNP0C0C"
+#define BM_HID_SLEEP_BUTTON	"PNP0C0E"
+
+/*
+ * BM_DEVICE_ADR:
+ * --------------
+ */
+typedef u32			BM_DEVICE_ADR;
+
+#define BM_ADDRESS_UNKNOWN	0
+
+
+/*
+ * BM_DEVICE_FLAGS:
+ * ----------------
+ * The encoding of BM_DEVICE_FLAGS is illustrated below.
+ * Note that a set bit (1) indicates the property is TRUE
+ * (e.g. if bit 0 is set then the device has dynamic status).
+ * +--+------------+-+-+-+-+-+-+-+
+ * |31| Bits 30:7  |6|5|4|3|2|1|0|
+ * +--+------------+-+-+-+-+-+-+-+
+ *   |       |      | | | | | | |
+ *   |       |      | | | | | | +- Dynamic status?
+ *   |       |      | | | | | +--- Identifiable?
+ *   |       |      | | | | +----- Configurable?
+ *   |       |      | | | +------- Power Control?
+ *   |       |      | | +--------- Ejectable?
+ *   |       |      | +----------- Docking Station?
+ *   |       |      +------------- Fixed-Feature?
+ *   |       +-------------------- <Reserved>
+ *   +---------------------------- Driver Control?
+ *
+ * Dynamic status:  Device has a _STA object.
+ * Identifiable:    Device has a _HID and/or _ADR and possibly other
+ *                  identification objects defined.
+ * Configurable:    Device has a _CRS and possibly other configuration
+ *                  objects defined.
+ * Power Control:   Device has a _PR0 and/or _PS0 and possibly other
+ *                  power management objects defined.
+ * Ejectable:       Device has an _EJD and/or _EJx and possibly other
+ *                  dynamic insertion/removal objects defined.
+ * Docking Station: Device has a _DCK object defined.
+ * Fixed-Feature:   Device does not exist in the namespace; was
+ *                  enumerated as a fixed-feature (e.g. power button).
+ * Driver Control:  A driver has been installed for this device.
+ */
+typedef u32			BM_DEVICE_FLAGS;
+
+#define BM_FLAGS_UNKNOWN	((BM_DEVICE_FLAGS) 0x00000000)
+
+#define BM_FLAGS_DYNAMIC_STATUS	((BM_DEVICE_FLAGS) 0x00000001)
+#define BM_FLAGS_IDENTIFIABLE	((BM_DEVICE_FLAGS) 0x00000002)
+#define BM_FLAGS_CONFIGURABLE	((BM_DEVICE_FLAGS) 0x00000004)
+#define BM_FLAGS_POWER_CONTROL	((BM_DEVICE_FLAGS) 0x00000008)
+#define BM_FLAGS_EJECTABLE	((BM_DEVICE_FLAGS) 0x00000010)
+#define BM_FLAGS_DOCKING_STATION ((BM_DEVICE_FLAGS) 0x00000020)
+#define BM_FLAGS_FIXED_FEATURE	((BM_DEVICE_FLAGS) 0x00000040)
+#define BM_FLAGS_DRIVER_CONTROL	((BM_DEVICE_FLAGS) 0x80000000)
+
+
+/*
+ * Device PM Flags:
+ * ----------------
+ * +-----------+-+-+-+-+-+-+-+
+ * | Bits 31:7 |6|5|4|3|2|1|0|
+ * +-----------+-+-+-+-+-+-+-+
+ *       |      | | | | | | |
+ *       |      | | | | | | +- D0 Support?
+ *       |      | | | | | +--- D1 Support?
+ *       |      | | | | +----- D2 Support?
+ *       |      | | | +------- D3 Support?
+ *       |      | | +--------- Power State Queriable?
+ *       |      | +----------- Inrush Current?
+ *       |      +------------- Wake Capable?
+ *       +-------------------- <Reserved>
+ *
+ * D0-D3 Support:   Device supports corresponding Dx state.
+ * Power State:     Device has a _PSC (current power state) object defined.
+ * Inrush Current:  Device has an _IRC (inrush current) object defined.
+ * Wake Capable:    Device has a _PRW (wake-capable) object defined.
+ */
+#define BM_FLAGS_D0_SUPPORT	((BM_DEVICE_FLAGS) 0x00000001)
+#define BM_FLAGS_D1_SUPPORT	((BM_DEVICE_FLAGS) 0x00000002)
+#define BM_FLAGS_D2_SUPPORT	((BM_DEVICE_FLAGS) 0x00000004)
+#define BM_FLAGS_D3_SUPPORT	((BM_DEVICE_FLAGS) 0x00000008)
+#define BM_FLAGS_POWER_STATE	((BM_DEVICE_FLAGS) 0x00000010)
+#define BM_FLAGS_INRUSH_CURRENT	((BM_DEVICE_FLAGS) 0x00000020)
+#define BM_FLAGS_WAKE_CAPABLE	((BM_DEVICE_FLAGS) 0x00000040)
+
+
+/*
+ * BM_DEVICE_STATUS:
+ * -----------------
+ * The encoding of BM_DEVICE_STATUS is illustrated below.
+ * Note that a set bit (1) indicates the property is TRUE
+ * (e.g. if bit 0 is set then the device is present).
+ * +-----------+-+-+-+-+-+
+ * | Bits 31:4 |4|3|2|1|0|
+ * +-----------+-+-+-+-+-+
+ *       |      | | | | |
+ *       |      | | | | +- Present?
+ *       |      | | | +--- Enabled?
+ *       |      | | +----- Show in UI?
+ *       |      | +------- Functioning?
+ *       |      +--------- Battery Present?
+ *       +---------------- <Reserved>
+ */
+typedef u32			BM_DEVICE_STATUS;
+
+#define BM_STATUS_UNKNOWN	((BM_DEVICE_STATUS) 0x00000000)
+#define BM_STATUS_PRESENT	((BM_DEVICE_STATUS) 0x00000001)
+#define BM_STATUS_ENABLED	((BM_DEVICE_STATUS) 0x00000002)
+#define BM_STATUS_SHOW_UI	((BM_DEVICE_STATUS) 0x00000004)
+#define BM_STATUS_FUNCTIONING	((BM_DEVICE_STATUS) 0x00000008)
+#define BM_STATUS_BATTERY_PRESENT ((BM_DEVICE_STATUS) 0x00000010)
+#define BM_STATUS_DEFAULT	((BM_DEVICE_STATUS) 0x0000000F)
+
+
+/*
+ * BM_POWER_STATE:
+ * ---------------
+ */
+typedef u32			BM_POWER_STATE;
+
+
+/*
+ * BM_DEVICE_ID:
+ * -------------
+ */
+typedef struct
+{
+	BM_DEVICE_TYPE		type;
+	BM_DEVICE_UID		uid;
+	BM_DEVICE_HID		hid;
+	BM_DEVICE_ADR		adr;
+} BM_DEVICE_ID;
+
+
+/*
+ * BM_DEVICE_POWER:
+ * ----------------
+ * Structure containing basic device power management information.
+ */
+typedef struct
+{
+	BM_DEVICE_FLAGS		flags;
+	BM_POWER_STATE		state;
+	BM_DEVICE_FLAGS		dx_supported[ACPI_S_STATE_COUNT];
+} BM_DEVICE_POWER;
+
+
+/*
+ * BM_DEVICE:
+ * ----------
+ */
+typedef struct
+{
+	BM_HANDLE		handle;
+	ACPI_HANDLE		acpi_handle;
+	BM_DEVICE_FLAGS		flags;
+	BM_DEVICE_STATUS	status;
+	BM_DEVICE_ID		id;
+	BM_DEVICE_POWER		power;
+} BM_DEVICE;
+
+
+/*
+ * BM_SEARCH:
+ * ----------
+ * Structure used for searching the ACPI Bus Manager's device hierarchy.
+ */
+typedef struct
+{
+	BM_DEVICE_ID		criteria;
+	BM_HANDLE_LIST		results;
+} BM_SEARCH;
+
+
+/*
+ * BM_REQUEST:
+ * -----------
+ * Structure used for sending requests to/through the ACPI Bus Manager.
+ */
+typedef struct
+{
+	ACPI_STATUS		status;
+	BM_COMMAND		command;
+	BM_HANDLE		handle;
+	ACPI_BUFFER		buffer;
+} BM_REQUEST;
+
+
+/*
+ * Driver Registration:
+ * --------------------
+ */
+
+/* Driver Context */
+typedef void *			BM_DRIVER_CONTEXT;
+
+/* Notification Callback Function */
+typedef
+ACPI_STATUS (*BM_DRIVER_NOTIFY) (
+	BM_NOTIFY		notify_type,
+	BM_HANDLE		device_handle,
+	BM_DRIVER_CONTEXT	*context);
+
+/* Request Callback Function */
+typedef
+ACPI_STATUS (*BM_DRIVER_REQUEST) (
+	BM_REQUEST		*request,
+	BM_DRIVER_CONTEXT	context);
+
+/* Driver Registration */
+typedef struct
+{
+	BM_DRIVER_NOTIFY	notify;
+	BM_DRIVER_REQUEST	request;
+	BM_DRIVER_CONTEXT	context;
+} BM_DRIVER;
+
+
+/*
+ * BM_NODE:
+ * --------
+ * Structure used to maintain the device hierarchy.
+ */
+typedef struct _BM_NODE
+{
+	BM_DEVICE		device;
+	BM_DRIVER		driver;
+	struct _BM_NODE		*parent;
+	struct _BM_NODE		*next;
+	struct
+	{
+		struct _BM_NODE		*head;
+		struct _BM_NODE		*tail;
+	}			scope;
+} BM_NODE;
+
+
+/*
+ * BM_NODE_LIST:
+ * -------------
+ * Structure used to maintain an array of node pointers.
+ */
+typedef struct
+{
+	u32			count;
+	BM_NODE			*nodes[BM_HANDLES_MAX];
+} BM_NODE_LIST;
+
+
+/*****************************************************************************
+ *                                  Macros
+ *****************************************************************************/
+
+/*
+ * Device Presence:
+ * ----------------
+ * Note that status (_STA) means something different for power resources
+ * (they're assumed to always be present).
+ */
+#define BM_DEVICE_PRESENT(d)	((d->id.type!=BM_TYPE_POWER_RESOURCE)?(d->status & BM_STATUS_PRESENT):TRUE)
+#define BM_NODE_PRESENT(n)	((n->device.id.type!=BM_TYPE_POWER_RESOURCE)?(n->device.status & BM_STATUS_PRESENT):TRUE)
+
+/*
+ * Device Flags:
+ * -------------
+ */
+#define BM_IS_DRIVER_CONTROL(d)	(d->flags & BM_FLAGS_DRIVER_CONTROL)
+#define BM_IS_POWER_CONTROL(d)	(d->flags & BM_FLAGS_POWER_CONTROL)
+
+ /*
+ * Device Power Flags:
+ * -------------------
+ */
+#define BM_IS_POWER_STATE(d)	(d->power.flags & BM_FLAGS_POWER_STATE)
+
+/*****************************************************************************
+ *                             Function Prototypes
+ *****************************************************************************/
+
+/* bm.c */
+
+ACPI_STATUS
+bm_initialize (void);
+
+ACPI_STATUS
+bm_terminate (void);
+
+ACPI_STATUS
+bm_get_status (
+	BM_DEVICE		*device);
+
+ACPI_STATUS
+bm_get_handle (
+	ACPI_HANDLE             acpi_handle,
+	BM_HANDLE               *device_handle);
+
+ACPI_STATUS
+bm_get_node (
+	BM_HANDLE               device_handle,
+	ACPI_HANDLE             acpi_handle,
+	BM_NODE			**node);
+
+/* bmsearch.c */
+
+ACPI_STATUS
+bm_search(
+	BM_HANDLE               device_handle,
+	BM_DEVICE_ID            *criteria,
+	BM_HANDLE_LIST          *results);
+
+/* bmnotify.c */
+
+void
+bm_notify (
+	ACPI_HANDLE             acpi_handle,
+	u32                     notify_value,
+	void                    *context);
+
+/* bm_request.c */
+
+ACPI_STATUS
+bm_request (
+	BM_REQUEST		*request_info);
+
+/* bmdriver.c */
+
+ACPI_STATUS
+bm_get_device_power_state (
+	BM_HANDLE               device_handle,
+	BM_POWER_STATE		*state);
+
+ACPI_STATUS
+bm_set_device_power_state (
+	BM_HANDLE               device_handle,
+	BM_POWER_STATE		state);
+
+ACPI_STATUS
+bm_get_device_status (
+	BM_HANDLE               device_handle,
+	BM_DEVICE_STATUS        *device_status);
+
+ACPI_STATUS
+bm_get_device_info (
+	BM_HANDLE               device_handle,
+	BM_DEVICE		**device_info);
+
+ACPI_STATUS
+bm_get_device_context (
+	BM_HANDLE               device_handle,
+	BM_DRIVER_CONTEXT	*context);
+
+ACPI_STATUS
+bm_register_driver (
+	BM_DEVICE_ID		*criteria,
+	BM_DRIVER		*driver);
+
+ACPI_STATUS
+bm_unregister_driver (
+	BM_DEVICE_ID		*criteria,
+	BM_DRIVER		*driver);
+
+/* bmpm.c */
+
+ACPI_STATUS
+bm_get_pm_capabilities (
+	BM_NODE			*node);
+
+ACPI_STATUS
+bm_get_power_state (
+	BM_NODE			*node);
+
+ACPI_STATUS
+bm_set_power_state (
+	BM_NODE			*node,
+	BM_POWER_STATE          target_state);
+
+/* bmpower.c */
+
+ACPI_STATUS
+bm_pr_initialize (void);
+
+ACPI_STATUS
+bm_pr_terminate (void);
+	
+/* bmutils.c */
+
+ACPI_STATUS
+bm_cast_buffer (
+	ACPI_BUFFER             *buffer,
+	void                    **pointer,
+	u32                     length);
+
+ACPI_STATUS
+bm_copy_to_buffer (
+	ACPI_BUFFER             *buffer,
+	void                    *data,
+	u32                     length);
+
+ACPI_STATUS
+bm_extract_package_data (
+	ACPI_OBJECT             *package,
+	ACPI_BUFFER             *format,
+	ACPI_BUFFER             *buffer);
+
+ACPI_STATUS
+bm_evaluate_object (
+	ACPI_HANDLE             acpi_handle,
+	ACPI_STRING             pathname,
+	ACPI_OBJECT_LIST        *arguments,
+	ACPI_BUFFER             *buffer);
+
+ACPI_STATUS
+bm_evaluate_simple_integer (
+	ACPI_HANDLE             acpi_handle,
+	ACPI_STRING             pathname,
+	u32                     *data);
+
+ACPI_STATUS
+bm_evaluate_reference_list (
+	ACPI_HANDLE             acpi_handle,
+	ACPI_STRING             pathname,
+	BM_HANDLE_LIST          *reference_list);
+
+/* ACPI Bus Driver OSL */
+
+ACPI_STATUS
+bm_osl_generate_event (
+	BM_HANDLE		device_handle,
+	char			*device_type,
+	char			*device_instance,
+	u32			event_type,
+	u32			event_data);
+
+
+#endif  /* __BM_H__ */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/include/bmpower.h linux/drivers/acpi/ospm/include/bmpower.h
--- v2.4.5/linux/drivers/acpi/ospm/include/bmpower.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/include/bmpower.h	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,75 @@
+/*****************************************************************************
+ *
+ * Module name: bmpower.h
+ *   $Revision: 1 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __BMPOWER_H__
+#define __BMPOWER_H__
+
+#include "bm.h"
+
+
+/*****************************************************************************
+ *                               Types & Defines
+ *****************************************************************************/
+
+
+/*
+ * BM_POWER_RESOURCE:
+ * ------------------
+ */
+typedef struct
+{
+	BM_HANDLE           device_handle;
+	ACPI_HANDLE         acpi_handle;
+	BM_POWER_STATE      system_level;
+	u32                 resource_order;
+	BM_POWER_STATE      state;
+	u32                 reference_count;
+} BM_POWER_RESOURCE;
+
+
+/*****************************************************************************
+ *                             Function Prototypes
+ *****************************************************************************/
+
+/* bmpower.c */
+
+ACPI_STATUS
+bm_pr_initialize (void);
+
+ACPI_STATUS
+bm_pr_terminate (void);
+
+ACPI_STATUS
+bm_pr_list_get_state (
+	BM_HANDLE_LIST          *resource_list,
+	BM_POWER_STATE          *power_state);
+
+ACPI_STATUS
+bm_pr_list_transition (
+	BM_HANDLE_LIST          *current_list,
+	BM_HANDLE_LIST          *target_list);
+
+
+#endif  /* __BMPOWER_H__ */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/include/bn.h linux/drivers/acpi/ospm/include/bn.h
--- v2.4.5/linux/drivers/acpi/ospm/include/bn.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/include/bn.h	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,122 @@
+/******************************************************************************
+ *
+ * Module Name: bn.h
+ *   $Revision: 10 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef __BN_H__
+#define __BN_H__
+
+#include <actypes.h>
+#include <acexcep.h>
+#include <bm.h>
+
+
+/*****************************************************************************
+ *                            Types & Other Defines
+ *****************************************************************************/
+
+/*
+ * Notifications:
+ * ---------------------
+ */
+#define BN_NOTIFY_STATUS_CHANGE	((BM_NOTIFY) 0x80)
+
+
+/*
+ * Types:
+ * ------
+ */
+#define BN_TYPE_POWER_BUTTON	0x01
+#define BN_TYPE_POWER_BUTTON_FIXED 0x02
+#define BN_TYPE_SLEEP_BUTTON	0x03
+#define BN_TYPE_SLEEP_BUTTON_FIXED 0x04
+#define BN_TYPE_LID_SWITCH	0x05
+
+
+/*
+ * Hardware IDs:
+ * -------------
+ * TBD: Power and Sleep button HIDs also exist in <bm.h>.  Should all
+ *      HIDs (ACPI well-known devices) exist in one place (e.g.
+ *      acpi_hid.h)?
+ */
+#define BN_HID_POWER_BUTTON	"PNP0C0C"
+#define BN_HID_SLEEP_BUTTON	"PNP0C0E"
+#define BN_HID_LID_SWITCH	"PNP0C0D"
+
+
+/*
+ * Device Context:
+ * ---------------
+ */
+typedef struct
+{
+	BM_HANDLE		device_handle;
+	ACPI_HANDLE		acpi_handle;
+	u32			type;
+} BN_CONTEXT;
+
+
+/******************************************************************************
+ *                              Function Prototypes
+ *****************************************************************************/
+
+ACPI_STATUS
+bn_initialize (void);
+
+ACPI_STATUS
+bn_terminate (void);
+
+ACPI_STATUS
+bn_notify_fixed (
+	void			*context);
+
+ACPI_STATUS
+bn_notify (
+	u32			notify_type,
+	u32			device,
+	void			**context);
+
+ACPI_STATUS
+bn_request(
+	BM_REQUEST		*request_info,
+	void			*context);
+
+/* Button OSL */
+
+ACPI_STATUS
+bn_osl_add_device (
+	BN_CONTEXT		*button);
+
+ACPI_STATUS
+bn_osl_remove_device (
+	BN_CONTEXT		*button);
+
+ACPI_STATUS
+bn_osl_generate_event (
+	u32			event,
+	BN_CONTEXT		*button);
+
+
+#endif	/* __BN_H__ */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/include/bt.h linux/drivers/acpi/ospm/include/bt.h
--- v2.4.5/linux/drivers/acpi/ospm/include/bt.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/include/bt.h	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,161 @@
+/******************************************************************************
+ *
+ * Module Name: bt.h
+ *   $Revision: 13 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef __BT_H__
+#define __BT_H__
+
+#include <actypes.h>
+#include <acexcep.h>
+#include <bm.h>
+
+
+/*****************************************************************************
+ *                            Types & Other Defines
+ *****************************************************************************/
+
+/*! [Begin] no source code translation */
+
+#define BT_UNKNOWN		0xFFFFFFFF
+#define BT_POWER_UNITS_DEFAULT	"?"
+#define BT_POWER_UNITS_WATTS	"mW"
+#define BT_POWER_UNITS_AMPS	"mA"
+
+/*! [End] no source code translation */
+
+/*
+ * Battery Notifications:
+ * ----------------------
+ */
+#define BT_NOTIFY_STATUS_CHANGE ((BM_NOTIFY) 0x80)
+#define BT_NOTIFY_INFORMATION_CHANGE ((BM_NOTIFY) 0x81)
+
+
+/*
+ * Hardware IDs:
+ * -------------
+ */
+#define BT_HID_CM_BATTERY	"PNP0C0A"
+
+
+/*
+ * BT_CM_BATTERY_INFO:
+ * -------------------
+ */
+typedef struct
+{
+	u32			power_unit;
+	u32			design_capacity;
+	u32			last_full_capacity;
+	u32			battery_technology;
+	u32			design_voltage;
+	u32			design_capacity_warning;
+	u32			design_capacity_low;
+	u32			battery_capacity_granularity_1;
+	u32			battery_capacity_granularity_2;
+	ACPI_STRING 		model_number;
+	ACPI_STRING 		serial_number;
+	ACPI_STRING 		battery_type;
+	ACPI_STRING 		oem_info;
+} BT_BATTERY_INFO;
+
+
+/*
+ * BT_CM_BATTERY_STATUS:
+ * ---------------------
+ */
+typedef struct
+{
+	u32			state;
+	u32			present_rate;
+	u32			remaining_capacity;
+	u32			present_voltage;
+} BT_BATTERY_STATUS;
+
+
+/*
+ * BT_CONTEXT:
+ * -----------
+ */
+typedef struct
+{
+	BM_HANDLE		device_handle;
+	ACPI_HANDLE 		acpi_handle;
+	char			uid[9];
+	ACPI_STRING 		power_units;
+	BOOLEAN 		is_present;
+} BT_CONTEXT;
+
+
+/*****************************************************************************
+ *                              Function Prototypes
+ *****************************************************************************/
+
+/* bt.c */
+
+ACPI_STATUS
+bt_initialize (void);
+
+ACPI_STATUS
+bt_terminate (void);
+
+ACPI_STATUS
+bt_notify (
+	u32			notify_type,
+	u32			device,
+	void			**context);
+
+ACPI_STATUS
+bt_request(
+	BM_REQUEST		*request_info,
+	void			*context);
+
+ACPI_STATUS
+bt_get_status (
+	BT_CONTEXT		*battery,
+	BT_BATTERY_STATUS	**battery_status);
+
+ACPI_STATUS
+bt_get_info (
+	BT_CONTEXT		*battery,
+	BT_BATTERY_INFO 	**battery_info);
+
+/* Battery OSL */
+
+ACPI_STATUS
+bt_osl_add_device (
+	BT_CONTEXT		*battery);
+
+ACPI_STATUS
+bt_osl_remove_device (
+	BT_CONTEXT		*battery);
+
+ACPI_STATUS
+bt_osl_generate_event (
+	u32			event,
+	BT_CONTEXT		*battery);
+
+
+#endif	/* __BT_H__ */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/include/ec.h linux/drivers/acpi/ospm/include/ec.h
--- v2.4.5/linux/drivers/acpi/ospm/include/ec.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/include/ec.h	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,202 @@
+/*****************************************************************************
+ *
+ * Module Name: ec.h
+ *   $Revision: 15 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef __EC_H__
+#define __EC_H__
+
+#include <linux/spinlock.h>
+#include <asm/semaphore.h>
+#include <actypes.h>
+#include <acexcep.h>
+#include <bm.h>
+
+
+/*****************************************************************************
+ *                            Types & Other Defines
+ *****************************************************************************/
+
+#define EC_DEFAULT_TIMEOUT	1000		/* 1 second */
+#define EC_GPE_UNKNOWN		0xFFFFFFFF
+#define EC_PORT_UNKNOWN		0x00000000
+#define EC_BURST_ENABLE_ACKNOWLEDGE 0x90
+
+
+/*
+ * Commands:
+ * ---------
+ */
+typedef u8			EC_COMMAND;
+
+#define EC_COMMAND_UNKNOWN	((EC_COMMAND) 0x00)
+#define EC_COMMAND_READ		((EC_COMMAND) 0x80)
+#define EC_COMMAND_WRITE	((EC_COMMAND) 0x81)
+#define EC_COMMAND_QUERY	((EC_COMMAND) 0x84)
+
+
+/*
+ * EC_STATUS:
+ * ----------
+ * The encoding of the EC status register is illustrated below.
+ * Note that a set bit (1) indicates the property is TRUE
+ * (e.g. if bit 0 is set then the output buffer is full).
+ * +-+-+-+-+-+-+-+-+
+ * |7|6|5|4|3|2|1|0|
+ * +-+-+-+-+-+-+-+-+
+ *  | | | | | | | |
+ *  | | | | | | | +- Output Buffer Full (OBF)?
+ *  | | | | | | +--- Input Buffer Full (IBF)?
+ *  | | | | | +----- <reserved>
+ *  | | | | +------- data Register is command Byte?
+ *  | | | +--------- Burst Mode Enabled?
+ *  | | +----------- SCI event?
+ *  | +------------- SMI event?
+ *  +--------------- <Reserved>
+ *
+ */
+typedef u8			EC_STATUS;
+
+#define EC_FLAG_OUTPUT_BUFFER	((EC_STATUS) 0x01)
+#define EC_FLAG_INPUT_BUFFER	((EC_STATUS) 0x02)
+#define EC_FLAG_BURST_MODE	((EC_STATUS) 0x10)
+#define EC_FLAG_SCI		((EC_STATUS) 0x20)
+
+
+/*
+ * EC_EVENT:
+ * ---------
+ */
+typedef u8			EC_EVENT;
+
+#define EC_EVENT_UNKNOWN	((EC_EVENT) 0x00)
+#define EC_EVENT_NONE		((EC_EVENT) 0x00)
+#define EC_EVENT_OUTPUT_BUFFER_FULL ((EC_EVENT) 0x01)
+#define EC_EVENT_INPUT_BUFFER_EMPTY ((EC_EVENT) 0x02)
+#define EC_EVENT_SCI		((EC_EVENT) 0x03)
+
+
+/*
+ * Hardware IDs:
+ * -------------
+ */
+#define EC_HID_EC		"PNP0C09"
+
+
+/*
+ * EC_REQUEST:
+ * -----------
+ */
+typedef struct
+{
+	EC_COMMAND              command;
+	u8                      address;
+	u8                      data;
+} EC_REQUEST;
+
+
+/*
+ * Device Context:
+ * ---------------
+ */
+typedef struct
+{
+	BM_HANDLE               device_handle;
+	ACPI_HANDLE             acpi_handle;
+	u32                     gpe_bit;
+	u32			status_port;
+	u32			command_port;
+	u32			data_port;
+	u32			use_global_lock;
+	u8                      query_data;
+	ACPI_HANDLE             mutex;
+} EC_CONTEXT;
+
+
+/*****************************************************************************
+ *                             Function Prototypes
+ *****************************************************************************/
+
+/* ec.c */
+
+ACPI_STATUS
+ec_initialize(void);
+
+ACPI_STATUS
+ec_terminate(void);
+
+ACPI_STATUS
+ec_notify (
+	u32                     notify_type,
+	u32                     device,
+	void                    **context);
+
+ACPI_STATUS
+ec_request(
+	BM_REQUEST              *request_info,
+	void                    *context);
+
+/* ectransx.c */
+
+ACPI_STATUS
+ec_transaction (
+	EC_CONTEXT              *ec,
+	EC_REQUEST              *ec_request);
+
+ACPI_STATUS
+ec_io_read (
+	EC_CONTEXT              *ec,
+	u32         		io_port,
+	u8                      *data,
+	EC_EVENT                wait_event);
+
+ACPI_STATUS
+ec_io_write (
+	EC_CONTEXT              *ec,
+	u32         		io_port,
+	u8                      data,
+	EC_EVENT                wait_event);
+
+/* ecgpe.c */
+
+ACPI_STATUS
+ec_install_gpe_handler (
+	EC_CONTEXT              *ec);
+
+ACPI_STATUS
+ec_remove_gpe_handler (
+	EC_CONTEXT              *ec);
+
+/* ecspace.c */
+
+ACPI_STATUS
+ec_install_space_handler (
+	EC_CONTEXT              *ec);
+
+ACPI_STATUS
+ec_remove_space_handler (
+	EC_CONTEXT              *ec);
+
+
+#endif  /* __EC_H__ */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/include/pr.h linux/drivers/acpi/ospm/include/pr.h
--- v2.4.5/linux/drivers/acpi/ospm/include/pr.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/include/pr.h	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,265 @@
+/******************************************************************************
+ *
+ * Module Name: processor.h
+ *              $Revision: 9 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __PR_H__
+#define __PR_H__
+
+#include <bm.h>
+
+
+/*****************************************************************************
+ *                             Types & Other Defines
+ *****************************************************************************/
+
+
+#define PR_MAX_POWER_STATES	4
+#define PR_MAX_THROTTLE_STATES  8
+#define PR_MAX_PERF_STATES	32
+#define PR_MAX_C2_LATENCY	100
+#define PR_MAX_C3_LATENCY	1000
+
+
+/*
+ * Commands:
+ * ---------
+ */
+#define PR_COMMAND_GET_POWER_INFO ((BM_COMMAND) 0x80)
+#define PR_COMMAND_SET_POWER_INFO ((BM_COMMAND) 0x81)
+#define PR_COMMAND_GET_PERF_INFO ((BM_COMMAND) 0x82)
+#define PR_COMMAND_GET_PERF_STATE ((BM_COMMAND) 0x83)
+#define PR_COMMAND_SET_PERF_LIMIT ((BM_COMMAND) 0x84)
+
+
+/*
+ * Notifications:
+ * --------------
+ */
+#define PR_NOTIFY_PERF_STATES	((BM_NOTIFY) 0x80)
+#define PR_NOTIFY_POWER_STATES	((BM_NOTIFY) 0x81)
+
+
+/*
+ * Performance Control:
+ * --------------------
+ */
+#define PR_PERF_DEC		0x00
+#define PR_PERF_INC		0x01
+#define PR_PERF_MAX		0xFF
+
+
+/*
+ * Power States:
+ * -------------
+ */
+#define PR_C0			0x00
+#define PR_C1			0x01
+#define PR_C2			0x02
+#define PR_C3			0x03
+
+#define PR_C1_FLAG		0x01;
+#define PR_C2_FLAG		0x02;
+#define PR_C3_FLAG		0x04;
+
+
+/*
+ * PR_CX_POLICY_VALUES:
+ * --------------------
+ */
+typedef struct
+{
+	u32			time_threshold;
+	u32			count_threshold;
+	u32                     bm_threshold;
+	u32         		target_state;
+	u32			count;
+} PR_CX_POLICY_VALUES;
+
+
+/*
+ * PR_CX:
+ * ------
+ */
+typedef struct
+{
+	u32                     latency;
+	u32                     utilization;
+	u8                      is_valid;
+	PR_CX_POLICY_VALUES     promotion;
+	PR_CX_POLICY_VALUES     demotion;
+} PR_CX;
+
+
+/*
+ * PR_POWER:
+ * ---------
+ */
+typedef struct
+{
+	ACPI_PHYSICAL_ADDRESS   p_lvl2;
+	ACPI_PHYSICAL_ADDRESS   p_lvl3;
+	u32                     bm_activity;
+	u32                     active_state;
+	u32			default_state;
+	u32			busy_metric;
+	u32                     state_count;
+	PR_CX                   state[PR_MAX_POWER_STATES];
+} PR_POWER;
+
+
+/*
+ * PR_PERFORMANCE_STATE:
+ * ---------------------
+ */
+typedef struct
+{
+	u32                     performance;
+	u32                     power;
+} PR_PERFORMANCE_STATE;
+
+
+/*
+ * PR_PERFORMANCE:
+ * ---------------
+ */
+typedef struct
+{
+	u32                     active_state;
+	u32			thermal_limit;
+	u32			power_limit;
+	u32                     state_count;
+	PR_PERFORMANCE_STATE    state[PR_MAX_PERF_STATES];
+} PR_PERFORMANCE;
+
+
+/*
+ * PR_PBLOCK:
+ * ----------
+ */
+typedef struct
+{
+	u32                     length;
+	ACPI_PHYSICAL_ADDRESS   address;
+} PR_PBLOCK;
+
+
+/*
+ * PR_CONTEXT:
+ * -----------
+ */
+typedef struct
+{
+	BM_HANDLE               device_handle;
+	ACPI_HANDLE             acpi_handle;
+	u32                     uid;
+	PR_PBLOCK               pblk;
+	PR_POWER		power;
+	PR_PERFORMANCE		performance;
+} PR_CONTEXT;
+
+
+/******************************************************************************
+ *                             Function Prototypes
+ *****************************************************************************/
+
+/* processor.c */
+
+ACPI_STATUS
+pr_initialize(void);
+
+ACPI_STATUS
+pr_terminate(void);
+
+ACPI_STATUS
+pr_notify (
+	BM_NOTIFY               notify_type,
+	BM_HANDLE               device_handle,
+	void                    **context);
+
+ACPI_STATUS
+pr_request(
+	BM_REQUEST		*request,
+	void                    *context);
+
+/* prpower.c */
+
+void
+pr_power_idle (void);
+
+ACPI_STATUS
+pr_power_add_device (
+	PR_CONTEXT              *processor);
+
+ACPI_STATUS
+pr_power_remove_device (
+	PR_CONTEXT              *processor);
+
+ACPI_STATUS
+pr_power_initialize (void);
+
+ACPI_STATUS
+pr_power_terminate (void);
+
+/* prperf.c */
+
+ACPI_STATUS
+pr_perf_get_state (
+	PR_CONTEXT              *processor,
+	u32                     *state);
+
+ACPI_STATUS
+pr_perf_set_state (
+	PR_CONTEXT              *processor,
+	u32                     state);
+
+ACPI_STATUS
+pr_perf_set_limit (
+	PR_CONTEXT              *processor,
+	u32                     limit);
+
+ACPI_STATUS
+pr_perf_add_device (
+	PR_CONTEXT              *processor);
+
+ACPI_STATUS
+pr_perf_remove_device (
+	PR_CONTEXT              *processor);
+
+/* Processor Driver OSL */
+
+ACPI_STATUS
+pr_osl_add_device (
+	PR_CONTEXT		*processor);
+
+ACPI_STATUS
+pr_osl_remove_device (
+	PR_CONTEXT		*processor);
+
+ACPI_STATUS
+pr_osl_generate_event (
+	u32			event,
+	PR_CONTEXT		*processor);
+
+
+#endif  /* __PR_H__ */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/include/sm.h linux/drivers/acpi/ospm/include/sm.h
--- v2.4.5/linux/drivers/acpi/ospm/include/sm.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/include/sm.h	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,91 @@
+/*****************************************************************************
+ *
+ * Module Name: sm.h
+ *   $Revision: 3 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef __SM_H__
+#define __SM_H__
+
+#include <actypes.h>
+#include <acexcep.h>
+#include <bm.h>
+
+
+/*****************************************************************************
+ *                            Types & Other Defines
+ *****************************************************************************/
+
+#define SM_MAX_SYSTEM_STATES	6	/* S0-S5 */
+
+
+ /*
+ * Device Context:
+ * ---------------
+ */
+typedef struct
+{
+	BM_HANDLE		device_handle;
+	ACPI_HANDLE 		acpi_handle;
+	u8			states[SM_MAX_SYSTEM_STATES];
+} SM_CONTEXT;
+
+
+/*****************************************************************************
+ *                              Function Prototypes
+ *****************************************************************************/
+
+ACPI_STATUS
+sm_initialize (void);
+
+ACPI_STATUS
+sm_terminate (void);
+
+ACPI_STATUS
+sm_notify (
+	u32			notify_type,
+	u32 			device,
+	void			**context);
+
+ACPI_STATUS
+sm_request(
+	BM_REQUEST		*request_info,
+	void			*context);
+
+/* System Driver OSL */
+
+ACPI_STATUS
+sm_osl_add_device (
+	SM_CONTEXT		*system);
+
+ACPI_STATUS
+sm_osl_remove_device (
+	SM_CONTEXT		*system);
+
+ACPI_STATUS
+sm_osl_generate_event (
+	u32			event,
+	SM_CONTEXT		*system);
+
+
+#endif	/* __SM_H__ */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/include/tz.h linux/drivers/acpi/ospm/include/tz.h
--- v2.4.5/linux/drivers/acpi/ospm/include/tz.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/include/tz.h	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,279 @@
+/*****************************************************************************
+ *
+ * Module Name: tz.h
+ *   $Revision: 21 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __TZ_H__
+#define __TZ_H__
+
+/* TBD: Linux-specific */
+#include <linux/module.h>
+#include <linux/timer.h>
+
+#include <bm.h>
+#include <pr.h>
+
+
+/*****************************************************************************
+ *                             Types & Other Defines
+ *****************************************************************************/
+
+#define TZ_MAX_THRESHOLDS	12	/* _AC0 through _AC9 + _CRT + _PSV */
+#define TZ_MAX_ACTIVE_THRESHOLDS 10	/* _AC0 through _AC9 */
+#define TZ_MAX_COOLING_DEVICES	10	/* TBD: Make size dynamic */
+
+
+/*
+ * Notifications:
+ * --------------
+ */
+#define TZ_NOTIFY_TEMPERATURE_CHANGE ((BM_NOTIFY) 0x80)
+#define TZ_NOTIFY_THRESHOLD_CHANGE ((BM_NOTIFY) 0x81)
+#define TZ_NOTIFY_DEVICE_LISTS_CHANGE ((BM_NOTIFY) 0x82)
+
+
+/*
+ * TZ_THRESHOLD_TYPE:
+ * ------------------
+ */
+typedef u32			TZ_THRESHOLD_TYPE;
+
+#define TZ_THRESHOLD_UNKNOWN	((TZ_THRESHOLD_TYPE) 0x00)
+#define TZ_THRESHOLD_CRITICAL	((TZ_THRESHOLD_TYPE) 0x01)
+
+#define TZ_THRESHOLD_PASSIVE	((TZ_THRESHOLD_TYPE) 0x02)
+#define TZ_THRESHOLD_ACTIVE	((TZ_THRESHOLD_TYPE) 0x03)
+
+
+/*
+ * TZ_COOLING_STATE:
+ * -----------------
+ */
+typedef u32			TZ_COOLING_STATE;
+
+#define TZ_COOLING_UNKNOWN	((TZ_COOLING_STATE) 0x00)
+#define TZ_COOLING_ENABLED	((TZ_COOLING_STATE) 0x01)
+#define TZ_COOLING_DISABLED	((TZ_COOLING_STATE) 0x02)
+
+
+/*
+ * TZ_COOLING_MODE:
+ * ----------------
+ */
+typedef u32			TZ_COOLING_MODE;
+
+#define TZ_COOLING_MODE_ACTIVE	((TZ_COOLING_MODE) 0x00)
+#define TZ_COOLING_MODE_PASSIVE	((TZ_COOLING_MODE) 0x01)
+
+
+/*
+ * Thermal State:
+ * --------------
+ * The encoding of TZ_STATE is illustrated below.
+ * Note that a set bit (1) indicates the property is TRUE
+ * (e.g. if bit 0 is set then the device has dynamic status).
+ * No bits set indicates an OK cooling state.
+ * +--+--+--+-----------+----------+
+ * |31|30|29| Bits 27:4 | Bits 3:0 |
+ * +--+--+--+-----------+----------+
+ *  |  |  |       |          |
+ *  |  |  |       |          +------ Active Index
+ *  |  |  |       +----------------- <reserved>
+ *  |  |  +------------------------- Active
+ *  |  +---------------------------- Passive
+ *  +------------------------------- Critical
+ *
+ * Active Index:    Value representing the level of active cooling
+ *                  presently applied (e.g. 0=_AL0, 9=_AL9).  Only
+ *                  valid when 'Active' is set.
+ * Active:          If set, indicates that the system temperature
+ *                  has crossed at least one active threshold (_ALx).
+ * Passive:         If set, indicates that the system temperature
+ *                  has crossed the passive threshold (_PSL).
+ * Passive:         If set, indicates that the system temperature
+ *                  has crossed the critical threshold (_CRT).
+ */
+typedef u32			TZ_STATE;
+
+#define TZ_STATE_OK		((TZ_STATE) 0x00000000)
+#define TZ_STATE_ACTIVE		((TZ_STATE) 0x20000000)
+#define TZ_STATE_PASSIVE	((TZ_STATE) 0x40000000)
+#define TZ_STATE_CRITICAL	((TZ_STATE) 0x80000000)
+
+
+/*
+ * TZ_THRESHOLD:
+ * -------------
+ * Information on an individual threshold.
+ */
+typedef struct {
+	TZ_THRESHOLD_TYPE	type;
+	u32			index;
+	u32			temperature;
+	TZ_COOLING_STATE	cooling_state;
+	BM_HANDLE_LIST		cooling_devices;
+} TZ_THRESHOLD;
+
+
+/*
+ * TZ_THRESHOLD_LIST:
+ * ------------------
+ * Container for the thresholds of a given thermal zone.
+ * Note that thresholds are always ordered by increasing
+ * temperature value to simplify use by thermal policy.
+ */
+typedef struct {
+	u32			count;
+	TZ_THRESHOLD		thresholds[TZ_MAX_THRESHOLDS];
+} TZ_THRESHOLD_LIST;
+
+
+/*
+ * TZ_CRITICAL_POLICY:
+ * -------------------
+ */
+typedef struct {
+	TZ_THRESHOLD		*threshold;
+} TZ_CRITICAL_POLICY;
+
+
+/*
+ * TZ_PASSIVE_POLICY:
+ * ------------------
+ */
+typedef struct {
+	u32			tc1;
+	u32			tc2;
+	u32			tsp;
+	TZ_THRESHOLD		*threshold;
+} TZ_PASSIVE_POLICY;
+
+
+/*
+ * TZ_ACTIVE_POLICY:
+ * -----------------
+ */
+typedef struct {
+	u32			threshold_count;
+	TZ_THRESHOLD		*threshold[TZ_MAX_ACTIVE_THRESHOLDS];
+} TZ_ACTIVE_POLICY;
+
+
+/*
+ * TZ_POLICY:
+ * ---------
+ */
+typedef struct {
+	u32			temperature;
+	TZ_STATE		state;
+	TZ_COOLING_MODE		cooling_mode;
+	u32			polling_freq;
+	TZ_THRESHOLD_LIST	threshold_list;
+	TZ_CRITICAL_POLICY	critical;
+	TZ_PASSIVE_POLICY	passive;
+	TZ_ACTIVE_POLICY	active;
+	/* TBD: Linux-specific */
+	struct timer_list	timer;
+} TZ_POLICY;
+
+
+/*
+ * TZ_CONTEXT:
+ * -----------
+ */
+typedef struct {
+	BM_HANDLE		device_handle;
+	ACPI_HANDLE		acpi_handle;
+	char			uid[9];
+	TZ_POLICY		policy;
+} TZ_CONTEXT;
+
+
+/*****************************************************************************
+ *                             Function Prototypes
+ *****************************************************************************/
+
+/* thermal_zone.c */
+
+ACPI_STATUS
+tz_initialize (void);
+
+ACPI_STATUS
+tz_terminate (void);
+
+ACPI_STATUS
+tz_notify (
+	BM_NOTIFY               notify_type,
+	BM_HANDLE               device_handle,
+	BM_DRIVER_CONTEXT	*context);
+
+ACPI_STATUS
+tz_request (
+	BM_REQUEST              *request,
+	BM_DRIVER_CONTEXT	context);
+
+ACPI_STATUS
+tz_get_temperature (
+	TZ_CONTEXT              *thermal_zone,
+	u32                     *temperature);
+
+ACPI_STATUS
+tz_get_thresholds (
+	TZ_CONTEXT              *thermal_zone,
+	TZ_THRESHOLD_LIST       *threshold_list);
+
+void
+tz_print (
+	TZ_CONTEXT              *thermal_zone);
+
+/* tzpolicy.c */
+
+ACPI_STATUS
+tz_policy_add_device (
+	TZ_CONTEXT              *thermal_zone);
+
+ACPI_STATUS
+tz_policy_remove_device (
+	TZ_CONTEXT              *thermal_zone);
+
+void
+tz_policy_check (
+	void                    *context);
+
+/* Thermal Zone Driver OSL */
+
+ACPI_STATUS
+tz_osl_add_device (
+	TZ_CONTEXT		*thermal_zone);
+
+ACPI_STATUS
+tz_osl_remove_device (
+	TZ_CONTEXT		*thermal_zone);
+
+ACPI_STATUS
+tz_osl_generate_event (
+	u32			event,
+	TZ_CONTEXT		*thermal_zone);
+
+
+#endif  /* __TZ_H__ */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/processor/Makefile linux/drivers/acpi/ospm/processor/Makefile
--- v2.4.5/linux/drivers/acpi/ospm/processor/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/processor/Makefile	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,6 @@
+O_TARGET	:= ospm_$(notdir $(CURDIR)).o
+obj-m		:= $(O_TARGET)
+EXTRA_CFLAGS	+= $(ACPI_CFLAGS)
+obj-y		:= $(patsubst %.c,%.o,$(wildcard *.c))
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/processor/pr.c linux/drivers/acpi/ospm/processor/pr.c
--- v2.4.5/linux/drivers/acpi/ospm/processor/pr.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/processor/pr.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,454 @@
+/*****************************************************************************
+ *
+ * Module Name: pr.c
+ *   $Revision: 30 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <acpi.h>
+#include <bm.h>
+#include "pr.h"
+
+
+#define _COMPONENT		ACPI_PROCESSOR
+	MODULE_NAME		("pr")
+
+
+/****************************************************************************
+ *                                  Globals
+ ****************************************************************************/
+
+extern FADT_DESCRIPTOR_REV2	acpi_fadt;
+
+
+/****************************************************************************
+ *                             Internal Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:    pr_print
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION: Prints out information on a specific thermal zone.
+ *
+ ****************************************************************************/
+
+void
+pr_print (
+	PR_CONTEXT              *processor)
+{
+
+	return;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    pr_add_device
+ *
+ * PARAMETERS:  <none>
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+pr_add_device(
+	BM_HANDLE		device_handle,
+	void			**context)
+{
+	ACPI_STATUS		status = AE_OK;
+	PR_CONTEXT		*processor = NULL;
+	BM_DEVICE		*device = NULL;
+	ACPI_BUFFER		buffer;
+	ACPI_OBJECT		acpi_object;
+	static u32		processor_count = 0;
+
+
+	if (!context || *context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	status = bm_get_device_info(device_handle, &device);
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	processor = acpi_os_callocate(sizeof(PR_CONTEXT));
+	if (!processor) {
+		return AE_NO_MEMORY;
+	}
+
+	processor->device_handle = device->handle;
+	processor->acpi_handle = device->acpi_handle;
+
+	/*
+	 * Processor Block:
+	 * ----------------
+	 */
+	MEMSET(&acpi_object, 0, sizeof(ACPI_OBJECT));
+
+	buffer.length = sizeof(ACPI_OBJECT);
+	buffer.pointer = &acpi_object;
+
+	status = acpi_evaluate_object(processor->acpi_handle, NULL, NULL, &buffer);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	/*
+	 * Processor ID:
+	 * -------------
+	 * TBD:  We need to synchronize the processor ID values in ACPI
+	 *       with those of the APIC.  For example, an IBM T20 has a
+	 *       proc_id value of '1', where the Linux value for the
+	 *       first CPU on this system is '0'.  Since x86 CPUs are
+	 *       mapped 1:1 we can simply use a zero-based counter.  Note
+	 *       that this assumes that processor objects are enumerated
+	 *       in the proper order.
+	 */
+	/* processor->uid = acpi_object.processor.proc_id; */
+	processor->uid = processor_count++;
+
+	processor->pblk.length = acpi_object.processor.pblk_length;
+	processor->pblk.address = acpi_object.processor.pblk_address;
+
+	status = pr_power_add_device(processor);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	status = pr_perf_add_device(processor);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	status = pr_osl_add_device(processor);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	*context = processor;
+
+	pr_print(processor);
+
+end:
+	if (ACPI_FAILURE(status)) {
+		acpi_os_free(processor);
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    pr_remove_device
+ *
+ * PARAMETERS:  <none>
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+pr_remove_device (
+	void			**context)
+{
+	ACPI_STATUS		status = AE_OK;
+	PR_CONTEXT		*processor= NULL;
+
+	if (!context || !*context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	processor = (PR_CONTEXT*)(*context);
+
+	pr_osl_remove_device(processor);
+
+	pr_perf_remove_device(processor);
+
+	pr_power_remove_device(processor);
+
+	acpi_os_free(processor);
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *                            External Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:    pr_initialize
+ *
+ * PARAMETERS:  <none>
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+pr_initialize (void)
+{
+	ACPI_STATUS		status = AE_OK;
+	BM_DEVICE_ID		criteria;
+	BM_DRIVER		driver;
+
+	MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
+	MEMSET(&driver, 0, sizeof(BM_DRIVER));
+
+	/*
+	 * Initialize power (Cx state) policy.
+	 */
+	status = pr_power_initialize();
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	/*
+	 * Register driver for processor devices.
+	 */
+	criteria.type = BM_TYPE_PROCESSOR;
+
+	driver.notify = &pr_notify;
+	driver.request = &pr_request;
+
+	status = bm_register_driver(&criteria, &driver);
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    pr_terminate
+ *
+ * PARAMETERS:  <none>
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+pr_terminate (void)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_DEVICE_ID		criteria;
+	BM_DRIVER		driver;
+
+	MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
+	MEMSET(&driver, 0, sizeof(BM_DRIVER));
+
+	/*
+	 * Terminate power (Cx state) policy.
+	 */
+	status = pr_power_terminate();
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	/*
+	 * Unegister driver for processor devices.
+	 */
+	criteria.type = BM_TYPE_PROCESSOR;
+
+	driver.notify = &pr_notify;
+	driver.request = &pr_request;
+
+	status = bm_unregister_driver(&criteria, &driver);
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    pr_notify
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+pr_notify (
+	BM_NOTIFY		notify_type,
+	BM_HANDLE		device_handle,
+	void			**context)
+{
+	ACPI_STATUS		status = AE_OK;
+	PR_CONTEXT		*processor = NULL;
+
+	processor = (PR_CONTEXT*)*context;
+
+	switch (notify_type) {
+
+	case BM_NOTIFY_DEVICE_ADDED:
+		status = pr_add_device(device_handle, context);
+		break;
+
+	case BM_NOTIFY_DEVICE_REMOVED:
+		status = pr_remove_device(context);
+		break;
+
+	case PR_NOTIFY_PERF_STATES:
+		/* TBD: Streamline (this is simple but overkill). */
+		status = pr_perf_remove_device(processor);
+		if (ACPI_SUCCESS(status)) {
+			status = pr_perf_add_device(processor);
+		}
+		if (ACPI_SUCCESS(status)) {
+			status = pr_osl_generate_event(notify_type,
+				(processor));
+		}
+		break;
+
+	case PR_NOTIFY_POWER_STATES:
+		/* TBD: Streamline (this is simple but overkill). */
+		status = pr_power_remove_device(processor);
+		if (ACPI_SUCCESS(status)) {
+			status = pr_power_add_device(processor);
+		}
+		if (ACPI_SUCCESS(status)) {
+			status = pr_osl_generate_event(notify_type,
+				(processor));
+		}
+		break;
+
+	default:
+		status = AE_SUPPORT;
+		break;
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    pr_request
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+pr_request (
+	BM_REQUEST		*request,
+	void			*context)
+{
+	ACPI_STATUS		status = AE_OK;
+	PR_CONTEXT		*processor = NULL;
+
+	/*
+	 * Must have a valid request structure and context.
+	 */
+	if (!request || !context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	processor = (PR_CONTEXT*)context;
+
+	/*
+	 * Handle request:
+	 * ---------------
+	 */
+	switch (request->command) {
+
+	case PR_COMMAND_GET_POWER_INFO:
+		status = bm_copy_to_buffer(&(request->buffer),
+			&(processor->power), sizeof(PR_POWER));
+		break;
+
+	case PR_COMMAND_SET_POWER_INFO:
+	 {
+		PR_POWER *power_info = NULL;
+		u32 i = 0;
+
+		status = bm_cast_buffer(&(request->buffer),
+			(void**)&power_info, sizeof(PR_POWER));
+		if (ACPI_SUCCESS(status)) {
+			for (i=0; i<processor->power.state_count; i++) {
+				MEMCPY(&(processor->power.state[i].promotion),
+					&(power_info->state[i].promotion),
+					sizeof(PR_CX_POLICY_VALUES));
+				MEMCPY(&(processor->power.state[i].demotion),
+					&(power_info->state[i].demotion),
+					sizeof(PR_CX_POLICY_VALUES));
+			}
+		}
+	}
+		break;
+
+	case PR_COMMAND_GET_PERF_INFO:
+		status = bm_copy_to_buffer(&(request->buffer),
+			&(processor->performance), sizeof(PR_PERFORMANCE));
+		break;
+
+	case PR_COMMAND_GET_PERF_STATE:
+		status = bm_copy_to_buffer(&(request->buffer),
+			&(processor->performance.active_state), sizeof(u32));
+		break;
+
+	case PR_COMMAND_SET_PERF_LIMIT:
+	 {
+		u32 *limit = NULL;
+
+		status = bm_cast_buffer(&(request->buffer),
+			(void**)&limit, sizeof(u32));
+		if (ACPI_SUCCESS(status)) {
+			status = pr_perf_set_limit(processor, *limit);
+		}
+	}
+		break;
+
+	default:
+		status = AE_SUPPORT;
+		break;
+	}
+
+	request->status = status;
+
+	return(status);
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/processor/pr_osl.c linux/drivers/acpi/ospm/processor/pr_osl.c
--- v2.4.5/linux/drivers/acpi/ospm/processor/pr_osl.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/processor/pr_osl.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,305 @@
+/******************************************************************************
+ *
+ * Module Name: pr_osl.c
+ *   $Revision: 14 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <acpi.h>
+#include <bm.h>
+#include "pr.h"
+
+
+MODULE_AUTHOR("Andrew Grover");
+MODULE_DESCRIPTION("ACPI Component Architecture (CA) - IA32 Processor Driver");
+
+
+#define PR_PROC_ROOT		"processor"
+#define PR_PROC_STATUS		"status"
+#define PR_PROC_INFO		"info"
+
+extern struct proc_dir_entry	*bm_proc_root;
+static struct proc_dir_entry	*pr_proc_root = NULL;
+
+
+/****************************************************************************
+ * 
+ * FUNCTION:	pr_osl_proc_read_status
+ *
+ ****************************************************************************/
+
+static int
+pr_osl_proc_read_status (
+	char			*page, 
+	char			**start, 
+	off_t			off, 
+	int 			count, 
+	int 			*eof, 
+	void			*context)
+{
+	PR_CONTEXT		*processor = NULL;
+	char			*p = page;
+	int 			len = 0;
+
+	if (!context || (off != 0)) {
+		goto end;
+	}
+
+	processor = (PR_CONTEXT*)context;
+
+	p += sprintf(p, "Bus Mastering Activity:  %08x\n", 
+		processor->power.bm_activity);
+
+	p += sprintf(p, "C-State Utilization:     C1[%d] C2[%d] C3[%d]\n", 
+		processor->power.state[PR_C1].utilization,
+		processor->power.state[PR_C2].utilization,
+		processor->power.state[PR_C3].utilization);
+
+end:
+	len = (p - page);
+	if (len <= off+count) *eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len>count) len = count;
+	if (len<0) len = 0;
+
+	return(len);
+}
+
+
+/****************************************************************************
+ * 
+ * FUNCTION:	pr_osl_proc_read_info
+ *
+ ****************************************************************************/
+
+static int
+pr_osl_proc_read_info (
+	char			*page, 
+	char			**start, 
+	off_t			off, 
+	int 			count, 
+	int 			*eof, 
+	void			*context)
+{
+	PR_CONTEXT		*processor = NULL;
+	char			*p = page;
+	int 			len = 0;
+
+	if (!context || (off != 0)) {
+		goto end;
+	}
+
+	processor = (PR_CONTEXT*)context;
+
+	p += sprintf(p, "<TBD>\n");
+
+end:
+	len = (p - page);
+	if (len <= off+count) *eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len>count) len = count;
+	if (len<0) len = 0;
+
+	return(len);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	pr_osl_add_device
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+pr_osl_add_device(
+	PR_CONTEXT		*processor)
+{
+	u32			i = 0;
+	struct proc_dir_entry	*proc_entry = NULL;
+	char			processor_uid[16];
+
+	if (!processor) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	printk("Processor[%x]:", processor->uid);
+	for (i=0; i<processor->power.state_count; i++) {
+		if (processor->power.state[i].is_valid) {
+			printk(" C%d", i);
+		}
+	}
+
+	if (processor->performance.state_count > 1) {
+		printk(", throttling states: %d", processor->performance.state_count);
+	}
+
+	printk("\n");
+
+	sprintf(processor_uid, "%d", processor->uid);
+
+	proc_entry = proc_mkdir(processor_uid, pr_proc_root);
+	if (!proc_entry) {
+		return(AE_ERROR);
+	}
+
+	create_proc_read_entry(PR_PROC_STATUS, S_IFREG | S_IRUGO, 
+		proc_entry, pr_osl_proc_read_status, (void*)processor);
+
+	create_proc_read_entry(PR_PROC_INFO, S_IFREG | S_IRUGO, 
+		proc_entry, pr_osl_proc_read_info, (void*)processor);
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	pr_osl_remove_device
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+pr_osl_remove_device (
+	PR_CONTEXT		*processor)
+{
+	char			proc_entry[64];
+
+	if (!processor) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	sprintf(proc_entry, "%d/%s", processor->uid, PR_PROC_INFO);
+	remove_proc_entry(proc_entry, pr_proc_root);
+
+	sprintf(proc_entry, "%d/%s", processor->uid, PR_PROC_STATUS);
+	remove_proc_entry(proc_entry, pr_proc_root);
+
+	sprintf(proc_entry, "%d", processor->uid);
+	remove_proc_entry(proc_entry, pr_proc_root);
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	pr_osl_generate_event
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+pr_osl_generate_event (
+	u32			event,
+	PR_CONTEXT		*processor)
+{
+	ACPI_STATUS		status = AE_OK;
+	char			processor_uid[16];
+
+	if (!processor) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	switch (event) {
+
+	case PR_NOTIFY_PERF_STATES:
+	case PR_NOTIFY_POWER_STATES:
+		sprintf(processor_uid, "%d", processor->uid);
+		status = bm_osl_generate_event(processor->device_handle, 
+			PR_PROC_ROOT, processor_uid, event, 0);
+		break;
+
+	default:
+		return(AE_BAD_PARAMETER);
+		break;
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	pr_osl_init
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	0: Success
+ *
+ * DESCRIPTION: Module initialization.
+ *
+ ****************************************************************************/
+
+static int __init 
+pr_osl_init (void)
+{
+	ACPI_STATUS		status = AE_OK;
+
+	pr_proc_root = proc_mkdir(PR_PROC_ROOT, bm_proc_root);
+	if (!pr_proc_root) {
+		status = AE_ERROR;
+	}
+	else {
+		status = pr_initialize();
+		if (ACPI_FAILURE(status)) {
+			remove_proc_entry(PR_PROC_ROOT, bm_proc_root);
+		}
+
+	}
+
+	return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    pr_osl_cleanup
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	<none>
+ *
+ * DESCRIPTION: Module cleanup.
+ *
+ ****************************************************************************/
+
+static void __exit 
+pr_osl_cleanup (void)
+{
+	pr_terminate();
+
+	if (pr_proc_root) {
+		remove_proc_entry(PR_PROC_ROOT, bm_proc_root);
+	}
+
+	return;
+}
+
+
+module_init(pr_osl_init);
+module_exit(pr_osl_cleanup);
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/processor/prperf.c linux/drivers/acpi/ospm/processor/prperf.c
--- v2.4.5/linux/drivers/acpi/ospm/processor/prperf.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/processor/prperf.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,423 @@
+/*****************************************************************************
+ *
+ * Module Name: prperf.c
+ *              $Revision: 16 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * TBD: 1. Support ACPI 2.0 processor performance states (not just throttling).
+ *      2. Fully implement thermal -vs- power management limit control.
+ */
+
+
+#include <acpi.h>
+#include <bm.h>
+#include "pr.h"
+
+#define _COMPONENT		ACPI_PROCESSOR
+	MODULE_NAME		("prperf")
+
+
+/****************************************************************************
+ *                                  Globals
+ ****************************************************************************/
+
+extern FADT_DESCRIPTOR_REV2	acpi_fadt;
+const u32			POWER_OF_2[] = {1,2,4,8,16,32,64,128,256,512};
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    pr_perf_get_frequency
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+pr_perf_get_frequency (
+	PR_CONTEXT		*processor,
+	u32			*frequency) {
+	ACPI_STATUS		status = AE_OK;
+
+	if (!processor || !frequency) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	/* TBD: Generic method to calculate processor frequency. */
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    pr_perf_get_state
+ *
+ * PARAMETERS:
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+/* TBD:	Include support for _real_ performance states (not just throttling). */
+
+ACPI_STATUS
+pr_perf_get_state (
+	PR_CONTEXT              *processor,
+	u32                     *state)
+{
+	u32                     pblk_value = 0;
+	u32                     duty_mask = 0;
+	u32                     duty_cycle = 0;
+
+	if (!processor || !state) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	if (processor->performance.state_count == 1) {
+		*state = 0;
+		return(AE_OK);
+	}
+
+	pblk_value = acpi_os_in32(processor->pblk.address);
+
+	/*
+	 * Throttling Enabled?
+	 * -------------------
+	 * If so, calculate the current throttling state, otherwise return
+	 * '100% performance' (state 0).
+	 */
+	if (pblk_value & 0x00000010) {
+
+		duty_mask = processor->performance.state_count - 1;
+		duty_mask <<= acpi_fadt.duty_offset;
+
+		duty_cycle = pblk_value & duty_mask;
+		duty_cycle >>= acpi_fadt.duty_offset;
+
+		if (duty_cycle == 0) {
+			*state = 0;
+		}
+		else {
+			*state = processor->performance.state_count -
+				duty_cycle;
+		}
+	}
+	else {
+		*state = 0;
+	}
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    pr_perf_set_state
+ *
+ * PARAMETERS:
+ *
+ * RETURN:      AE_OK
+ *              AE_BAD_PARAMETER
+ *              AE_BAD_DATA         Invalid target throttling state.
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+/* TBD: Includes support for _real_ performance states (not just throttling). */
+
+ACPI_STATUS
+pr_perf_set_state (
+	PR_CONTEXT              *processor,
+	u32                     state)
+{
+	u32                     pblk_value = 0;
+	u32                     duty_mask = 0;
+	u32                     duty_cycle = 0;
+	u32                     i = 0;
+
+	if (!processor) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	if (state > (processor->performance.state_count - 1)) {
+		return(AE_BAD_DATA);
+	}
+
+	if (processor->performance.state_count == 1) {
+		return(AE_OK);
+	}
+
+	/*
+	 * Calculate Duty Cycle/Mask:
+	 * --------------------------
+	 * Note that we don't support duty_cycle values that span bit 4.
+	 */
+	if (state) {
+		duty_cycle = processor->performance.state_count - state;
+		duty_cycle <<= acpi_fadt.duty_offset;
+	}
+	else {
+		duty_cycle = 0;
+	}
+
+	duty_mask = ~((u32)(processor->performance.state_count - 1));
+	for (i=0; i<acpi_fadt.duty_offset; i++) {
+		duty_mask <<= acpi_fadt.duty_offset;
+		duty_mask += 1;
+	}
+
+	/*
+	 * Disable Throttling:
+	 * -------------------
+	 * Got to turn it off before you can change the duty_cycle value.
+	 * Throttling is disabled by writing a 0 to bit 4.
+	 */
+	pblk_value = acpi_os_in32(processor->pblk.address);
+	if (pblk_value & 0x00000010) {
+		pblk_value &= 0xFFFFFFEF;
+		acpi_os_out32(processor->pblk.address, pblk_value);
+	}
+
+	/*
+	 * Set Duty Cycle:
+	 * ---------------
+	 * Mask off the old duty_cycle value, mask in the new.
+	 */
+	pblk_value &= duty_mask;
+	pblk_value |= duty_cycle;
+	acpi_os_out32(processor->pblk.address, pblk_value);
+
+	/*
+	 * Enable Throttling:
+	 * ------------------
+	 * But only for non-zero (non-100% performance) states.
+	 */
+	if (state) {
+		pblk_value |= 0x00000010;
+		acpi_os_out32(processor->pblk.address, pblk_value);
+	}
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    pr_perf_set_limit
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+pr_perf_set_limit (
+	PR_CONTEXT              *processor,
+	u32                     limit)
+{
+	ACPI_STATUS		status = AE_OK;
+	PR_PERFORMANCE		*performance = NULL;
+
+	if (!processor) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	performance = &(processor->performance);
+
+	/*
+	 * Set Limit:
+	 * ----------
+	 * TBD:  Properly manage thermal and power limits (only set
+	 *	 performance state iff...).
+	 */
+	switch (limit) {
+
+	case PR_PERF_DEC:
+		if (performance->active_state <
+			(performance->state_count-1)) {
+			status = pr_perf_set_state(processor,
+				(performance->active_state-1));
+		}
+		break;
+
+	case PR_PERF_INC:
+		if (performance->active_state > 0) {
+			status = pr_perf_set_state(processor,
+				(performance->active_state+1));
+		}
+		break;
+
+	case PR_PERF_MAX:
+		if (performance->active_state != 0) {
+			status = pr_perf_set_state(processor, 0);
+		}
+		break;
+
+	default:
+		return(AE_BAD_DATA);
+		break;
+	}
+
+	if (ACPI_SUCCESS(status)) {
+		performance->thermal_limit = limit;
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *                             External Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:    pr_perf_add_device
+ *
+ * PARAMETERS:  processor		Our processor-specific context.
+ *
+ * RETURN:      AE_OK
+ *              AE_BAD_PARAMETER
+ *
+ * DESCRIPTION: Calculates the number of throttling states and the state
+ *              performance/power values.
+ *
+ ****************************************************************************/
+
+/* TBD: Support duty_cycle values that span bit 4. */
+
+ACPI_STATUS
+pr_perf_add_device (
+	PR_CONTEXT              *processor)
+{
+	ACPI_STATUS             status = AE_OK;
+	u32                     i = 0;
+	u32                     performance_step = 0;
+	u32                     percentage = 0;
+
+	if (!processor) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Valid PBLK?
+	 * -----------
+	 * For SMP it is common to have the first (boot) processor have a
+	 * valid PBLK while all others do not -- which implies that
+	 * throttling has system-wide effects (duty_cycle programmed into
+	 * the chipset effects all processors).
+	 */
+	if ((processor->pblk.length < 6) || !processor->pblk.address) {
+		processor->performance.state_count = 1;
+	}
+
+	/*
+	 * Valid Duty Offset/Width?
+	 * ------------------------
+	 * We currently only support duty_cycle values that fall within
+	 * bits 0-3, as things get complicated when this value spans bit 4
+	 * (the throttling enable/disable bit).
+	 */
+	else if ((acpi_fadt.duty_offset + acpi_fadt.duty_width) > 4) {
+		processor->performance.state_count = 1;
+	}
+
+	/*
+	 * Compute State Count:
+	 * --------------------
+	 * The number of throttling states is computed as 2^duty_width,
+	 * but limited by PR_MAX_THROTTLE_STATES.  Note that a duty_width
+	 * of zero results is one throttling state (100%).
+	 */
+	else {
+		processor->performance.state_count =
+			POWER_OF_2[acpi_fadt.duty_width];
+	}
+
+	if (processor->performance.state_count > PR_MAX_THROTTLE_STATES) {
+		processor->performance.state_count = PR_MAX_THROTTLE_STATES;
+	}
+
+	/*
+	 * Compute State Values:
+	 * ---------------------
+	 * Note that clock throttling displays a linear power/performance
+	 * relationship (at 50% performance the CPU will consume 50% power).
+	 */
+	performance_step = (1000 / processor->performance.state_count);
+
+	for (i=0; i<processor->performance.state_count; i++) {
+		percentage = (1000 - (performance_step * i))/10;
+		processor->performance.state[i].performance = percentage;
+		processor->performance.state[i].power = percentage;
+	}
+
+	/*
+	 * Get Current State:
+	 * ------------------
+	 */
+	status = pr_perf_get_state(processor,
+		&(processor->performance.active_state));
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    pr_perf_remove_device
+ *
+ * PARAMETERS:
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+pr_perf_remove_device (
+	PR_CONTEXT              *processor)
+{
+	ACPI_STATUS             status = AE_OK;
+
+	if (!processor) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	MEMSET(&(processor->performance), 0, sizeof(PR_PERFORMANCE));
+
+	return(status);
+}
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/processor/prpower.c linux/drivers/acpi/ospm/processor/prpower.c
--- v2.4.5/linux/drivers/acpi/ospm/processor/prpower.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/processor/prpower.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,640 @@
+/*****************************************************************************
+ *
+ * Module Name: prpower.c
+ *   $Revision: 25 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+/* TBD: Linux specific */
+#include <linux/sched.h>
+#include <linux/pm.h>
+
+#include <acpi.h>
+#include <bm.h>
+#include "pr.h"
+
+#define _COMPONENT		ACPI_PROCESSOR
+	MODULE_NAME		("prpower")
+
+
+/****************************************************************************
+ *                                  Globals
+ ****************************************************************************/
+
+extern FADT_DESCRIPTOR_REV2	acpi_fadt;
+static u32			last_idle_jiffies = 0;
+static PR_CONTEXT		*processor_list[NR_CPUS];
+static void			(*pr_pm_idle_save)(void) = NULL;
+
+
+/****************************************************************************
+ *                             External Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:    pr_power_activate_state
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+void
+pr_power_activate_state (
+	PR_CONTEXT		*processor,
+	u32			next_state)
+{
+	if (!processor) {
+		return;
+	}
+
+	processor->power.state[processor->power.active_state].promotion.count = 0;
+	processor->power.state[processor->power.active_state].demotion.count = 0;
+
+	/*
+	 * Cleanup from old state.
+	 */
+	switch (processor->power.active_state) {
+
+	case PR_C3:
+		/* Disable bus master reload */
+		acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK,
+			BM_RLD, 0);
+		break;
+	}
+
+	/*
+	 * Prepare to use new state.
+	 */
+	switch (next_state) {
+
+	case PR_C3:
+		/* Enable bus master reload */
+		acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK,
+			BM_RLD, 1);
+		break;
+	}
+
+	processor->power.active_state = next_state;
+	
+	return;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    pr_power_idle
+ *
+ * PARAMETERS:  <none>
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+void
+pr_power_idle (void)
+{
+	PR_CX			*c_state = NULL;
+	u32			next_state = 0;
+	u32			start_ticks, end_ticks, time_elapsed;
+	PR_CONTEXT		*processor = NULL;
+
+	processor = processor_list[smp_processor_id()];
+
+	if (!processor || processor->power.active_state == PR_C0) {
+		return;
+	}
+
+	next_state = processor->power.active_state;
+
+	/*
+	 * Log BM Activity:
+	 * ----------------
+	 * Read BM_STS and record its value for later use by C3 policy.
+	 * Note that we save the BM_STS values for the last 32 call to
+	 * this function (cycles).  Also note that we must clear BM_STS
+	 * if set (sticky).
+	 */
+	processor->power.bm_activity <<= 1;
+	if (acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_DO_NOT_LOCK, BM_STS)) {
+		processor->power.bm_activity |= 1;
+		acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK,
+			BM_STS, 1);
+	}
+
+	/*
+	 * Check OS Idleness:
+	 * ------------------
+	 * If the OS has been busy (hasn't called the idle handler in a while)
+	 * then automatically demote to the default power state (e.g. C1).
+	 *
+	 * TBD: Optimize by having scheduler determine business instead
+	 *      of having us try to calculate it.
+	 */
+	if (processor->power.active_state != processor->power.default_state) {
+		if ((jiffies - last_idle_jiffies) >= processor->power.busy_metric) {
+			next_state = processor->power.default_state;
+			if (next_state != processor->power.active_state) {
+				pr_power_activate_state(processor, next_state);
+			}
+		}
+	}
+
+	c_state = &(processor->power.state[processor->power.active_state]);
+
+	c_state->utilization++;
+
+	/*
+	 * Sleep:
+	 * ------
+	 * Invoke the current Cx state to put the processor to sleep.
+	 */
+	switch (processor->power.active_state) {
+
+	case PR_C1:
+		/* See how long we're asleep for */
+		acpi_get_timer(&start_ticks);
+		/* Invoke C1 */
+		enable(); halt();
+		/* Compute time elapsed */
+		acpi_get_timer(&end_ticks);
+		break;
+
+	case PR_C2:
+		/* Interrupts must be disabled during C2 transitions */
+		disable();
+		/* See how long we're asleep for */
+		acpi_get_timer(&start_ticks);
+		/* Invoke C2 */
+		acpi_os_in8(processor->power.p_lvl2);
+		/* Dummy op - must do something useless after P_LVL2 read */
+		acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_DO_NOT_LOCK,
+			BM_STS);
+		/* Compute time elapsed */
+		acpi_get_timer(&end_ticks);
+		/* Re-enable interrupts */
+		enable();
+		break;
+
+	case PR_C3:
+		/* Interrupts must be disabled during C3 transitions */
+		disable();
+		/* Disable bus master arbitration */
+		acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK,
+			ARB_DIS, 1);
+		/* See how long we're asleep for */
+		acpi_get_timer(&start_ticks);
+		/* Invoke C2 */
+		acpi_os_in8(processor->power.p_lvl3);
+		/* Dummy op - must do something useless after P_LVL3 read */
+		acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_DO_NOT_LOCK,
+			BM_STS);
+		/* Compute time elapsed */
+		acpi_get_timer(&end_ticks);
+		/* Enable bus master arbitration */
+		acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK,
+			ARB_DIS, 0);
+		/* Re-enable interrupts */
+		enable();
+		break;
+
+	default:
+		break;
+	}
+
+	/*
+	 * Compute the amount of time asleep (in the Cx state).
+	 *
+	 * TBD: Convert time_threshold to PM timer ticks initially to
+	 *      avoid having to do the math (acpi_get_timer_duration).
+	 */
+	acpi_get_timer_duration(start_ticks, end_ticks, &time_elapsed);
+
+	/*
+	 * Promotion?
+	 * ----------
+	 * Track the number of successful sleeps (time asleep is greater
+	 * than time_threshold) and promote when count_threashold is
+	 * reached.
+	 */
+	if ((c_state->promotion.target_state) && 	
+		(time_elapsed >= c_state->promotion.time_threshold)) {
+
+		c_state->promotion.count++;
+ 		c_state->demotion.count = 0;
+
+		if (c_state->promotion.count >=
+			c_state->promotion.count_threshold) {
+
+			/*
+			 * Bus Mastering Activity, if active and used
+			 * by this state's promotion policy, prevents
+			 * promotions from occuring.
+			 */
+			if (!(processor->power.bm_activity &
+				c_state->promotion.bm_threshold)) {
+				next_state = c_state->promotion.target_state;
+			}
+		}
+	}
+
+	/*
+	 * Demotion?
+	 * ---------
+	 * Track the number of shorts (time asleep is less than
+	 * time_threshold) and demote when count_threshold is reached.
+	 */
+	if (c_state->demotion.target_state) {
+			
+		if (time_elapsed < c_state->demotion.time_threshold) {
+
+			c_state->demotion.count++;
+			c_state->promotion.count = 0;
+
+			if (c_state->demotion.count >=
+				c_state->demotion.count_threshold) {
+				next_state = c_state->demotion.target_state;
+			}
+		}
+
+		/*
+		 * Bus Mastering Activity, if active and used by this
+		 * state's promotion policy, causes an immediate demotion
+		 * to occur.
+		 */
+		if (processor->power.bm_activity &
+			c_state->demotion.bm_threshold) {
+			next_state = c_state->demotion.target_state;
+		}
+	}
+
+	/*
+	 * New Cx State?
+	 * -------------
+	 * If we're going to start using a new Cx state we must clean up
+	 * from the previous and prepare to use the new.
+	 */
+	if (next_state != processor->power.active_state) {
+		pr_power_activate_state(processor, next_state);
+		processor->power.active_state = processor->power.active_state;
+	}
+
+	/*
+	 * Track OS Idleness:
+	 * ------------------
+	 * Record a jiffies timestamp to compute time elapsed between calls
+	 * to the idle handler.
+	 */
+	last_idle_jiffies = jiffies;
+
+	return;
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    pr_power_set_default_policy
+ *
+ * PARAMETERS:
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION: Sets the default Cx state policy (OS idle handler).  Our
+ *              scheme is to promote quickly to C2 but more conservatively
+ *              to C3.  We're favoring C2 for its characteristics of low
+ *              latency (quick response), good power savings, and ability
+ *              to allow bus mastering activity.
+ *
+ *              Note that Cx state policy is completely customizable, with
+ *              the goal of having heuristics to alter policy dynamically.
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+pr_power_set_default_policy (
+	PR_CONTEXT                 *processor)
+{
+	if (!processor) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Busy Metric:
+	 * ------------
+	 * Used to determine when the OS has been busy and thus when
+	 * policy should return to using the default Cx state (e.g. C1).
+	 * On Linux we use the number of jiffies (scheduler quantums)
+	 * that transpire between calls to the idle handler.
+	 *
+	 * TBD: Linux-specific.
+	 */
+	processor->power.busy_metric = 2;
+
+	/*
+	 * C1:
+	 * ---
+	 * C1 serves as our default state.  It must be valid.
+	 */
+	if (processor->power.state[PR_C1].is_valid) {
+		processor->power.active_state =
+			processor->power.default_state = PR_C1;
+	}
+	else {
+		processor->power.active_state =
+			processor->power.default_state = PR_C0;
+		return(AE_OK);
+	}
+
+	/*
+	 * C2:
+	 * ---
+	 * Set default C1 promotion and C2 demotion policies.
+	 */
+	if (processor->power.state[PR_C2].is_valid) {
+		/*
+		 * Promote from C1 to C2 anytime we're asleep in C1 for
+		 * longer than two times the C2 latency (to amortize cost
+		 * of transition).  Demote from C2 to C1 anytime we're
+		 * asleep in C2 for less than this time.
+		 */
+		processor->power.state[PR_C1].promotion.count_threshold = 1;
+		processor->power.state[PR_C1].promotion.time_threshold =
+			2 * processor->power.state[PR_C2].latency;
+		processor->power.state[PR_C1].promotion.target_state = PR_C2;
+
+		processor->power.state[PR_C2].demotion.count_threshold = 1;
+		processor->power.state[PR_C2].demotion.time_threshold =
+			2 * processor->power.state[PR_C2].latency;
+		processor->power.state[PR_C2].demotion.target_state = PR_C1;
+	}
+
+	/*
+	 * C3:
+	 * ---
+	 * Set default C2 promotion and C3 demotion policies.
+	 */
+	if ((processor->power.state[PR_C2].is_valid) &&
+		(processor->power.state[PR_C3].is_valid)) {
+		/*
+		 * Promote from C2 to C3 after 4 cycles of no bus
+		 * mastering activity (while maintaining sleep time
+		 * criteria).  Demote immediately on a short or
+		 * whenever bus mastering activity occurs.
+		 */
+		processor->power.state[PR_C2].promotion.count_threshold = 1;
+		processor->power.state[PR_C2].promotion.time_threshold =
+			2 * processor->power.state[PR_C3].latency;
+		processor->power.state[PR_C2].promotion.bm_threshold =
+			0x0000000F;
+		processor->power.state[PR_C2].promotion.target_state =
+			PR_C3;
+
+		processor->power.state[PR_C3].demotion.count_threshold = 1;
+		processor->power.state[PR_C3].demotion.time_threshold =
+			2 * processor->power.state[PR_C3].latency;
+		processor->power.state[PR_C3].demotion.bm_threshold =
+			0x0000000F;
+		processor->power.state[PR_C3].demotion.target_state =
+			PR_C2;
+	}
+
+	return(AE_OK);
+}
+
+/*****************************************************************************
+ *
+ * FUNCTION:    pr_power_add_device
+ *
+ * PARAMETERS:  <none>
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+/*
+ * TBD: 1. PROC_C1 support.
+ *      2. Symmetric Cx state support (different Cx states supported
+ *         by different CPUs results in lowest common denominator).
+ */
+
+ACPI_STATUS
+pr_power_add_device (
+	PR_CONTEXT                 *processor)
+{
+	if (!processor) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * State Count:
+	 * ------------
+	 * Fixed at four (C0-C3).  We use is_valid to determine whether or
+	 * not a state actually gets used.
+	 */
+	processor->power.state_count = PR_MAX_POWER_STATES;
+
+	/*
+	 * C0:
+	 * ---
+	 * C0 exists only as filler in our array. (Let's assume its valid!)
+	 */
+	processor->power.state[PR_C0].is_valid = TRUE;
+
+	/*
+	 * C1:
+	 * ---
+	 * ACPI states that C1 must be supported by all processors
+	 * with a latency so small that it can be ignored.
+	 *
+	 * TBD: What about PROC_C1 support?
+	 */
+	processor->power.state[PR_C1].is_valid = TRUE;
+
+	/*
+	 * C2:
+	 * ---
+	 * We're only supporting C2 on UP systems with latencies <= 100us.
+	 *
+	 * TBD: Support for C2 on MP (P_LVL2_UP) -- I'm taking the
+	 *      conservative approach for now.
+	 */
+	processor->power.state[PR_C2].latency = acpi_fadt.plvl2_lat;
+
+#ifdef CONFIG_SMP
+	if (smp_num_cpus == 1) {
+#endif /*CONFIG_SMP*/
+		if (acpi_fadt.plvl2_lat <= PR_MAX_C2_LATENCY) {
+			processor->power.state[PR_C2].is_valid = TRUE;
+			processor->power.p_lvl2 = processor->pblk.address + 4;
+		}
+#ifdef CONFIG_SMP
+	}
+#endif /*CONFIG_SMP*/
+
+
+	/*
+	 * C3:
+	 * ---
+	 * We're only supporting C3 on UP systems with latencies <= 1000us,
+	 * and that include the ability to disable bus mastering while in
+	 * C3 (ARB_DIS) but allows bus mastering requests to wake the system
+	 * from C3 (BM_RLD).  Note his method of maintaining cache coherency
+	 * (disabling of bus mastering) cannot be used on SMP systems, and
+	 * flushing caches (e.g. WBINVD) is simply too costly at this time.
+	 *
+	 * TBD: Support for C3 on MP -- I'm taking the conservative
+	 *      approach for now.
+	 */
+	processor->power.state[PR_C3].latency = acpi_fadt.plvl3_lat;
+
+#ifdef CONFIG_SMP
+	if (smp_num_cpus == 1) {
+#endif /*CONFIG_SMP*/
+		if ((acpi_fadt.plvl3_lat <= PR_MAX_C3_LATENCY) &&
+			(acpi_fadt.V1_pm2_cnt_blk && acpi_fadt.pm2_cnt_len)) {
+			/* TBD: Resolve issue with C3 and HDD corruption. */
+			processor->power.state[PR_C3].is_valid = FALSE;
+			/* processor->power.state[PR_C3].is_valid = TRUE;*/
+			processor->power.p_lvl3 = processor->pblk.address + 5;
+		}
+#ifdef CONFIG_SMP
+	}
+#endif /*CONFIG_SMP*/
+
+	/*
+	 * Set Default Policy:
+	 * -------------------
+	 * Now that we know which state are supported, set the default
+	 * policy.  Note that this policy can be changed dynamically
+	 * (e.g. encourage deeper sleeps to conserve battery life when
+	 * not on AC).
+	 */
+	pr_power_set_default_policy(processor);
+
+	/*
+	 * Save Processor Context:
+	 * -----------------------
+	 * TBD: Enhance Linux idle handler to take processor context
+	 *      parameter.
+	 */
+	processor_list[processor->uid] = processor;
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    pr_power_remove_device
+ *
+ * PARAMETERS:
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+pr_power_remove_device (
+	PR_CONTEXT              *processor)
+{
+	ACPI_STATUS             status = AE_OK;
+
+	if (!processor) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	MEMSET(&(processor->power), 0, sizeof(PR_POWER));
+
+	processor_list[processor->uid] = NULL;
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    pr_power_initialize
+ *
+ * PARAMETERS:  <none>
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+pr_power_initialize (void)
+{
+	u32			i = 0;
+
+	/* TBD: Linux-specific. */
+	for (i=0; i<NR_CPUS; i++) {
+		processor_list[i] = NULL;
+	}
+
+	/*
+	 * Install idle handler.
+	 *
+	 * TBD: Linux-specific (need OSL function).
+	 */
+	pr_pm_idle_save = pm_idle;
+	pm_idle = pr_power_idle;
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    pr_power_terminate
+ *
+ * PARAMETERS:  <none>
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+pr_power_terminate (void)
+{
+	/*
+	 * Remove idle handler.
+	 *
+	 * TBD: Linux-specific (need OSL function).
+	 */
+	pm_idle = pr_pm_idle_save;
+
+	return(AE_OK);
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/system/Makefile linux/drivers/acpi/ospm/system/Makefile
--- v2.4.5/linux/drivers/acpi/ospm/system/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/system/Makefile	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,6 @@
+O_TARGET	:= ospm_$(notdir $(CURDIR)).o
+obj-m		:= $(O_TARGET)
+EXTRA_CFLAGS	+= $(ACPI_CFLAGS)
+obj-y		:= $(patsubst %.c,%.o,$(wildcard *.c))
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/system/sm.c linux/drivers/acpi/ospm/system/sm.c
--- v2.4.5/linux/drivers/acpi/ospm/system/sm.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/system/sm.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,330 @@
+/*****************************************************************************
+ *
+ * Module Name: sm.c
+ *   $Revision: 16 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <acpi.h>
+#include "sm.h"
+
+
+#define _COMPONENT		ACPI_SYSTEM
+	MODULE_NAME 		("sm")
+
+
+/****************************************************************************
+ *                            Internal Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:	sm_print
+ *
+ * PARAMETERS:	
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION: Prints out information on a specific system.
+ *
+ ****************************************************************************/
+
+void
+sm_print (
+	SM_CONTEXT		*system)
+{
+
+	return;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	sm_add_device
+ *
+ * PARAMETERS:	
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+sm_add_device(
+	BM_HANDLE		device_handle,
+	void			**context)
+{
+	ACPI_STATUS 		status = AE_OK;
+	BM_DEVICE		*device = NULL;
+	SM_CONTEXT		*system = NULL;
+	u8			i, type_a, type_b;
+
+
+	if (!context || *context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Allocate a new SM_CONTEXT structure.
+	 */
+	system = acpi_os_callocate(sizeof(SM_CONTEXT));
+	if (!system) {
+		return(AE_NO_MEMORY);
+	}
+
+	/*
+	 * Get information on this device.
+	 */
+	status = bm_get_device_info(device_handle, &device);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	system->device_handle = device->handle;
+	system->acpi_handle = device->acpi_handle;
+
+	/*
+	 * Sx States:
+	 * ----------
+	 * Figure out which Sx states are supported.
+	 */
+	for (i=0; i<SM_MAX_SYSTEM_STATES; i++) {
+		if (ACPI_SUCCESS(acpi_hw_obtain_sleep_type_register_data(
+			i,
+			&type_a,
+			&type_b))) {
+			system->states[i] = TRUE;
+		}
+	}
+
+	status = sm_osl_add_device(system);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	*context = system;
+
+	sm_print(system);
+
+end:
+	if (ACPI_FAILURE(status)) {
+		acpi_os_free(system);
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	sm_remove_device
+ *
+ * PARAMETERS:	
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+sm_remove_device (
+	void			**context)
+{
+	ACPI_STATUS 		status = AE_OK;
+	SM_CONTEXT		*system = NULL;
+
+	if (!context || !*context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	system = (SM_CONTEXT*)*context;
+
+	status = sm_osl_remove_device(system);
+
+	acpi_os_free(system);
+
+	*context = NULL;
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *                             External Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:	sm_initialize
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+sm_initialize (void)
+{
+	ACPI_STATUS		status = AE_OK;
+	BM_DEVICE_ID		criteria;
+	BM_DRIVER		driver;
+
+	MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
+	MEMSET(&driver, 0, sizeof(BM_DRIVER));
+
+	/*
+	 * Register driver for the System device.
+	 */
+	criteria.type = BM_TYPE_SYSTEM;
+
+	driver.notify = &sm_notify;
+	driver.request = &sm_request;
+
+	status = bm_register_driver(&criteria, &driver);
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	sm_terminate
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+sm_terminate (void)
+{
+	ACPI_STATUS 		status = AE_OK;
+	BM_DEVICE_ID		criteria;
+	BM_DRIVER		driver;
+
+	MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
+	MEMSET(&driver, 0, sizeof(BM_DRIVER));
+
+	/*
+	 * Unregister driver for System devices.
+	 */
+	criteria.type = BM_TYPE_SYSTEM;
+
+	driver.notify = &sm_notify;
+	driver.request = &sm_request;
+
+	status = bm_unregister_driver(&criteria, &driver);
+
+	return(status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:	sm_notify
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+ACPI_STATUS
+sm_notify (
+	BM_NOTIFY		notify_type,
+	BM_HANDLE		device_handle,
+	void			**context)
+{
+	ACPI_STATUS 		status = AE_OK;
+
+	if (!context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	switch (notify_type) {
+
+	case BM_NOTIFY_DEVICE_ADDED:
+		status = sm_add_device(device_handle, context);
+		break;
+
+	case BM_NOTIFY_DEVICE_REMOVED:
+		status = sm_remove_device(context);
+		break;
+
+	default:
+		status = AE_SUPPORT;
+		break;
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	sm_request
+ *
+ * PARAMETERS:	
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+sm_request (
+	BM_REQUEST		*request,
+	void			*context)
+{
+	ACPI_STATUS 		status = AE_OK;
+
+	/*
+	 * Must have a valid request structure and context.
+	 */
+	if (!request || !context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Handle Request:
+	 * ---------------
+	 */
+	switch (request->command) {
+
+	default:
+		status = AE_SUPPORT;
+		break;
+	}
+
+	request->status = status;
+
+	return(status);
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/system/sm_osl.c linux/drivers/acpi/ospm/system/sm_osl.c
--- v2.4.5/linux/drivers/acpi/ospm/system/sm_osl.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/system/sm_osl.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,344 @@
+/******************************************************************************
+ *
+ * Module Name: sm_osl.c
+ *   $Revision: 10 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/pm.h>
+#include <asm/uaccess.h>
+
+#include <acpi.h>
+#include "sm.h"
+
+
+MODULE_AUTHOR("Andrew Grover");
+MODULE_DESCRIPTION("ACPI Component Architecture (CA) - ACPI System Driver");
+
+
+#define SM_PROC_INFO		"info"
+#define SM_PROC_DSDT		"dsdt"
+
+extern struct proc_dir_entry	*bm_proc_root;
+struct proc_dir_entry		*sm_proc_root = NULL;
+static void 			(*sm_pm_power_off)(void) = NULL;
+
+static ssize_t sm_osl_read_dsdt(struct file *, char *, size_t, loff_t *);
+
+static struct file_operations proc_dsdt_operations = {
+	read:		sm_osl_read_dsdt,
+};
+
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	sm_osl_proc_read_info
+ *
+ ****************************************************************************/
+
+static int
+sm_osl_proc_read_info (
+	char			*page,
+	char			**start,
+	off_t			off,
+	int 			count,
+	int 			*eof,
+	void			*context)
+{
+	ACPI_STATUS		status = AE_OK;
+	SM_CONTEXT		*system = NULL;
+	char			*p = page;
+	int			len;
+	ACPI_SYSTEM_INFO	system_info;
+	ACPI_BUFFER		buffer;
+	u32			i = 0;
+
+	if (!context) {
+		goto end;
+	}
+
+	system = (SM_CONTEXT*)context;
+
+	/* don't get status more than once for a single proc read */
+	if (off != 0) {
+		goto end;
+	}
+
+	/*
+	 * Get ACPI CA Information.
+	 */
+	buffer.length  = sizeof(system_info);
+	buffer.pointer = &system_info;
+
+	status = acpi_get_system_info(&buffer);
+	if (ACPI_FAILURE(status)) {
+		p += sprintf(p, "ACPI-CA Version:         unknown\n");
+	}
+	else {
+		p += sprintf(p, "ACPI-CA Version:         %x\n", 
+			system_info.acpi_ca_version);
+	}
+
+	p += sprintf(p, "Sx States Supported:     ");
+	for (i=0; i<SM_MAX_SYSTEM_STATES; i++) {
+		if (system->states[i]) {
+			p += sprintf(p, "S%d ", i);
+		}
+	}
+	p += sprintf(p, "\n");
+
+end:
+	len = (p - page);
+	if (len <= off+count) *eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len>count) len = count;
+	if (len<0) len = 0;
+
+	return(len);
+}
+
+/****************************************************************************
+ *
+ * FUNCTION:	sm_osl_read_dsdt
+ *
+ ****************************************************************************/
+
+static ssize_t
+sm_osl_read_dsdt(
+	struct file		*file, 
+	char			*buf, 
+	size_t			count, 
+	loff_t			*ppos)
+{
+	ACPI_BUFFER		acpi_buf;
+	void			*data;
+	size_t			size = 0;
+
+	acpi_buf.length = 0;
+	acpi_buf.pointer = NULL;
+
+
+	/* determine what buffer size we will need */
+	if (acpi_get_table(ACPI_TABLE_DSDT, 1, &acpi_buf) != AE_BUFFER_OVERFLOW) {
+		return 0;
+	}
+
+	acpi_buf.pointer = kmalloc(acpi_buf.length, GFP_KERNEL);
+	if (!acpi_buf.pointer) {
+		return -ENOMEM;
+	}
+
+	/* get the table for real */
+	if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_DSDT, 1, &acpi_buf))) {
+		kfree(acpi_buf.pointer);
+		return 0;
+	}
+
+	if (*ppos < acpi_buf.length) {
+		data = acpi_buf.pointer + file->f_pos;
+		size = acpi_buf.length - file->f_pos;
+		if (size > count)
+			size = count;
+		if (copy_to_user(buf, data, size)) {
+			kfree(acpi_buf.pointer);
+			return -EFAULT;
+		}
+	}
+
+	kfree(acpi_buf.pointer);
+
+	*ppos += size;
+
+	return size;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	sm_osl_power_down
+ *
+ ****************************************************************************/
+
+void
+sm_osl_power_down (void)
+{
+	ACPI_STATUS		status = AE_OK;
+
+	/* Power down the system (S5 = soft off). */
+	status = acpi_enter_sleep_state(ACPI_STATE_S5);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	sm_osl_add_device
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+sm_osl_add_device(
+	SM_CONTEXT		*system)
+{
+	u32			i = 0;
+	struct proc_dir_entry	*bm_proc_dsdt;
+
+	if (!system) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	printk("ACPI: System firmware supports");
+	for (i=0; i<SM_MAX_SYSTEM_STATES; i++) {
+		if (system->states[i]) {
+			printk(" S%d", i);
+		}
+	}
+	printk("\n");
+
+	if (system->states[ACPI_STATE_S5]) {
+		sm_pm_power_off = pm_power_off;
+		pm_power_off = sm_osl_power_down; 
+	}
+
+	create_proc_read_entry(SM_PROC_INFO, S_IRUGO, 
+		sm_proc_root, sm_osl_proc_read_info, (void*)system);
+
+	/* 
+	 * This returns more than a page, so we need to use our own file ops,
+	 * not proc's generic ones
+	 */
+	bm_proc_dsdt = create_proc_entry(SM_PROC_DSDT, S_IRUSR, sm_proc_root);
+	if (bm_proc_dsdt) {
+		bm_proc_dsdt->proc_fops = &proc_dsdt_operations;
+	}
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	sm_osl_remove_device
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+sm_osl_remove_device (
+	SM_CONTEXT		*system)
+{
+	if (!system) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	remove_proc_entry(SM_PROC_INFO, sm_proc_root);
+	remove_proc_entry(SM_PROC_DSDT, sm_proc_root);
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	sm_osl_generate_event
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+sm_osl_generate_event (
+	u32			event,
+	SM_CONTEXT		*system)
+{
+	ACPI_STATUS		status = AE_OK;
+
+	if (!system) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	switch (event) {
+
+	default:
+		return(AE_BAD_PARAMETER);
+		break;
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	sm_osl_init
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	0: Success
+ *
+ * DESCRIPTION: Module initialization.
+ *
+ ****************************************************************************/
+
+static int __init 
+sm_osl_init (void)
+{
+	ACPI_STATUS		status = AE_OK;
+
+	sm_proc_root = bm_proc_root;
+	if (!sm_proc_root) {
+		status = AE_ERROR;
+	}
+	else {
+		status = sm_initialize();
+	}
+
+	return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	sm_osl_cleanup
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	<none>
+ *
+ * DESCRIPTION: Module cleanup.
+ *
+ ****************************************************************************/
+
+static void __exit 
+sm_osl_cleanup (void)
+{
+	sm_terminate();
+
+	return;
+}
+
+
+module_init(sm_osl_init);
+module_exit(sm_osl_cleanup);
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/thermal/Makefile linux/drivers/acpi/ospm/thermal/Makefile
--- v2.4.5/linux/drivers/acpi/ospm/thermal/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/thermal/Makefile	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,6 @@
+O_TARGET	:= ospm_$(notdir $(CURDIR)).o
+obj-m		:= $(O_TARGET)
+EXTRA_CFLAGS	+= $(ACPI_CFLAGS)
+obj-y		:= $(patsubst %.c,%.o,$(wildcard *.c))
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/thermal/tz.c linux/drivers/acpi/ospm/thermal/tz.c
--- v2.4.5/linux/drivers/acpi/ospm/thermal/tz.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/thermal/tz.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,659 @@
+/*****************************************************************************
+ *
+ * Module Name: tz.c
+ *   $Revision: 38 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * TBD: 1. Finish /proc interface (threshold values, _SCP changes, etc.)
+ *	2. Update policy for ACPI 2.0 compliance
+ *	3. Check for all required methods prior to enabling a threshold
+ *	4. Support for multiple processors in a zone (passive cooling devices)
+ */
+
+#include <acpi.h>
+#include <bm.h>
+#include "tz.h"
+
+#define _COMPONENT		ACPI_THERMAL
+	MODULE_NAME		("tz")
+
+
+/****************************************************************************
+ *                            Internal Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:    tz_print
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION: Prints out information on a specific thermal zone.
+ *
+ ****************************************************************************/
+
+void
+tz_print (
+	TZ_CONTEXT		*thermal_zone)
+{
+
+	return;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    tz_get_temperaturee
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+tz_get_temperature (
+	TZ_CONTEXT              *thermal_zone,
+	u32                     *temperature)
+{
+	ACPI_STATUS             status = AE_OK;
+
+	if (!thermal_zone || !temperature) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Evaluate the _TMP driver method to get the current temperature.
+	 */
+	status = bm_evaluate_simple_integer(thermal_zone->acpi_handle,
+		"_TMP", temperature);
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    tz_set_cooling_preference
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+tz_set_cooling_preference (
+	TZ_CONTEXT              *thermal_zone,
+	TZ_COOLING_MODE         cooling_mode)
+{
+	ACPI_STATUS             status = AE_OK;
+	ACPI_OBJECT_LIST        arg_list;
+	ACPI_OBJECT             arg0;
+
+	if (!thermal_zone || ((cooling_mode != TZ_COOLING_MODE_ACTIVE) &&
+		(cooling_mode != TZ_COOLING_MODE_PASSIVE))) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Build the argument list, which simply consists of the current
+	 * cooling preference.
+	 */
+	MEMSET(&arg_list, 0, sizeof(ACPI_OBJECT));
+	arg_list.count = 1;
+	arg_list.pointer = &arg0;
+
+	MEMSET(&arg0, 0, sizeof(ACPI_OBJECT));
+	arg0.type = ACPI_TYPE_INTEGER;
+	arg0.integer.value = cooling_mode;
+
+	/*
+	 * Evaluate "_SCP" - setting the new cooling preference.
+	 */
+	status = acpi_evaluate_object(thermal_zone->acpi_handle, "_SCP",
+		&arg_list, NULL);
+
+	return(status);
+}
+
+
+/***************************************************************************
+ *
+ * FUNCTION:    tz_get_single_threshold
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+tz_get_single_threshold (
+	TZ_CONTEXT              *thermal_zone,
+	TZ_THRESHOLD            *threshold)
+{
+	ACPI_STATUS             status = AE_OK;
+
+	if (!thermal_zone || !threshold) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	switch (threshold->type) {
+
+	/*
+	 * Critical Threshold:
+	 * -------------------
+	 */
+	case TZ_THRESHOLD_CRITICAL:
+		threshold->index = 0;
+		threshold->cooling_devices.count = 0;
+		status = bm_evaluate_simple_integer(
+			thermal_zone->acpi_handle, "_CRT",
+			&(threshold->temperature));
+		break;
+
+	/*
+	 * Passive Threshold:
+	 * ------------------
+	 * Evaluate _PSV to get the threshold temperature and _PSL to get
+	 * references to all passive cooling devices.
+	 */
+	case TZ_THRESHOLD_PASSIVE:
+		threshold->index = 0;
+		threshold->cooling_devices.count = 0;
+		status = bm_evaluate_simple_integer(
+			thermal_zone->acpi_handle, "_PSV",
+			&(threshold->temperature));
+		if (ACPI_SUCCESS(status)) {
+			status = bm_evaluate_reference_list(
+				thermal_zone->acpi_handle, "_PSL",
+				&(threshold->cooling_devices));
+		}
+
+		break;
+
+	/*
+	 * Active Thresholds:
+	 * ------------------
+	 * Evaluate _ACx to get all threshold temperatures, and _ALx to get
+	 * references to all passive cooling devices.
+	 */
+	case TZ_THRESHOLD_ACTIVE:
+		 {
+			char object_name[5] = {'_','A', 'C',
+				('0'+threshold->index),'\0'};
+			status = bm_evaluate_simple_integer(
+				thermal_zone->acpi_handle, object_name,
+				&(threshold->temperature));
+			if (ACPI_SUCCESS(status)) {
+				object_name[2] = 'L';
+				status = bm_evaluate_reference_list(
+					thermal_zone->acpi_handle,
+					object_name,
+					&(threshold->cooling_devices));
+			}
+		}
+		break;
+
+	default:
+		status = AE_SUPPORT;
+		break;
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    tz_get_thresholds
+ *
+ * PARAMETERS:  thermal_zone          - Identifies the thermal zone to parse.
+ *              buffer      - Output buffer.
+ *
+ * RETURN:      ACPI_STATUS result code.
+ *
+ * DESCRIPTION: Builds a TZ_THRESHOLD_LIST structure containing information
+ *              on all thresholds for a given thermal zone.
+ *
+ * NOTES:       The current design limits the number of cooling devices
+ *              per theshold to the value specified by BM_MAX_HANDLES.
+ *              This simplifies parsing of thresholds by allowing a maximum
+ *              threshold list size to be computed (and enforced) -- which
+ *              allows all thresholds to be parsed in a single pass (since
+ *              memory must be contiguous when returned in the ACPI_BUFFER).
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+tz_get_thresholds (
+	TZ_CONTEXT              *thermal_zone,
+	TZ_THRESHOLD_LIST       *threshold_list)
+{
+	ACPI_STATUS             status = AE_OK;
+	TZ_THRESHOLD            *threshold = NULL;
+	u32                     i = 0;
+
+	if (!thermal_zone || !threshold_list) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	threshold_list->count = 0;
+
+	/*
+	 * Critical threshold:
+	 * -------------------
+	 * Every thermal zone must have one!
+	 */
+	threshold = &(threshold_list->thresholds[threshold_list->count]);
+	threshold->type = TZ_THRESHOLD_CRITICAL;
+
+	status = tz_get_single_threshold(thermal_zone, threshold);
+	if (ACPI_SUCCESS(status)) {
+		(threshold_list->count)++;
+	}
+	else {
+		return(status);
+	}
+
+
+	/*
+	 * Passive threshold:
+	 * ------------------
+	 */
+	threshold = &(threshold_list->thresholds[threshold_list->count]);
+	threshold->type = TZ_THRESHOLD_PASSIVE;
+
+	status = tz_get_single_threshold(thermal_zone, threshold);
+	if (ACPI_SUCCESS(status)) {
+		(threshold_list->count)++;
+	}
+
+	/*
+	 * Active threshold:
+	 * -----------------
+	 * Note that active thresholds are sorted by index (e.g. _AC0,
+	 * _AC1, ...), and thus from highest (_AC0) to lowest (_AC9)
+	 * temperature.
+	 */
+	for (i = 0; i < TZ_MAX_ACTIVE_THRESHOLDS; i++) {
+
+		threshold = &(threshold_list->thresholds[threshold_list->count]);
+		threshold->type = TZ_THRESHOLD_ACTIVE;
+		threshold->index = i;
+
+		status = tz_get_single_threshold(thermal_zone, threshold);
+		if (ACPI_SUCCESS(status)) {
+			(threshold_list->count)++;
+		}
+		else {
+			threshold->type = TZ_THRESHOLD_UNKNOWN;
+			threshold->index = 0;
+			thermal_zone->policy.active.threshold_count = i;
+			break;
+		}
+	}
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    tz_add_device
+ *
+ * PARAMETERS:  <none>
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+tz_add_device (
+	BM_HANDLE               device_handle,
+	void                    **context)
+{
+	ACPI_STATUS             status = AE_OK;
+	TZ_CONTEXT              *thermal_zone = NULL;
+	BM_DEVICE		*device = NULL;
+	ACPI_HANDLE             tmp_handle = NULL;
+	static u32		zone_count = 0;
+
+	if (!context || *context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Get information on this device.
+	 */
+	status = bm_get_device_info(device_handle, &device);
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	/*
+	 * Allocate a new Thermal Zone device.
+	 */
+	thermal_zone = acpi_os_callocate(sizeof(TZ_CONTEXT));
+	if (!thermal_zone) {
+		return AE_NO_MEMORY;
+	}
+
+	thermal_zone->device_handle = device->handle;
+	thermal_zone->acpi_handle = device->acpi_handle;
+
+	/* TBD: How to manage 'uid' when zones are Pn_p? */
+	sprintf(thermal_zone->uid, "%d", zone_count++);
+
+	/*
+	 * _TMP?
+	 * -----
+	 */
+	status = acpi_get_handle(thermal_zone->acpi_handle, "_TMP",
+		&tmp_handle);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	/*
+	 * Initialize Policy:
+	 * ------------------
+	 * TBD: Move all thermal zone policy to user-mode daemon...
+	 */
+	status = tz_policy_add_device(thermal_zone);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	status = tz_osl_add_device(thermal_zone);
+	if (ACPI_FAILURE(status)) {
+		goto end;
+	}
+
+	*context = thermal_zone;
+
+	tz_print(thermal_zone);
+
+end:
+	if (ACPI_FAILURE(status)) {
+		acpi_os_free(thermal_zone);
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    tz_remove_device
+ *
+ * PARAMETERS:  <none>
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+tz_remove_device (
+	void			**context)
+{
+	ACPI_STATUS		status = AE_OK;
+	TZ_CONTEXT		*thermal_zone = NULL;
+
+	if (!context || !*context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	thermal_zone = (TZ_CONTEXT*)(*context);
+
+	status = tz_osl_remove_device(thermal_zone);
+
+	/*
+	 * Remove Policy:
+	 * --------------
+	 * TBD: Move all thermal zone policy to user-mode daemon...
+	 */
+	status = tz_policy_remove_device(thermal_zone);
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	acpi_os_free(thermal_zone);
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *                            External Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ *
+ * FUNCTION:    tz_initialize
+ *
+ * PARAMETERS:  <none>
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+tz_initialize (void)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_DEVICE_ID		criteria;
+	BM_DRIVER		driver;
+
+	MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
+	MEMSET(&driver, 0, sizeof(BM_DRIVER));
+
+	/*
+	 * Register driver for thermal zone devices.
+	 */
+	criteria.type = BM_TYPE_THERMAL_ZONE;
+
+	driver.notify = &tz_notify;
+	driver.request = &tz_request;
+
+	status = bm_register_driver(&criteria, &driver);
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    tz_terminate
+ *
+ * PARAMETERS:  <none>
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+tz_terminate (void)
+{
+	ACPI_STATUS             status = AE_OK;
+	BM_DEVICE_ID		criteria;
+	BM_DRIVER		driver;
+
+	MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
+	MEMSET(&driver, 0, sizeof(BM_DRIVER));
+
+	/*
+	 * Unregister driver for thermal zone devices.
+	 */
+	criteria.type = BM_TYPE_THERMAL_ZONE;
+
+	driver.notify = &tz_notify;
+	driver.request = &tz_request;
+
+	status = bm_unregister_driver(&criteria, &driver);
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    tz_notify
+ *
+ * PARAMETERS:  <none>
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+ACPI_STATUS
+tz_notify (
+	BM_NOTIFY               notify_type,
+	BM_HANDLE               device_handle,
+	void                    **context)
+{
+	ACPI_STATUS             status = AE_OK;
+	TZ_CONTEXT		*thermal_zone = NULL;
+
+	if (!context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	thermal_zone = (TZ_CONTEXT*)*context;
+
+	switch (notify_type) {
+
+	case BM_NOTIFY_DEVICE_ADDED:
+		status = tz_add_device(device_handle, context);
+		break;
+
+	case BM_NOTIFY_DEVICE_REMOVED:
+		status = tz_remove_device(context);
+		break;
+
+	case TZ_NOTIFY_TEMPERATURE_CHANGE:
+		/* -------------------------------------------- */
+		/* TBD: Remove when policy moves to user-mode. */
+		tz_policy_check(*context);
+		/* -------------------------------------------- */
+		status = tz_get_temperature(thermal_zone,
+			&(thermal_zone->policy.temperature));
+		if (ACPI_SUCCESS(status)) {
+			status = tz_osl_generate_event(notify_type,
+				thermal_zone);
+		}
+		break;
+
+	case TZ_NOTIFY_THRESHOLD_CHANGE:
+		/* -------------------------------------------- */
+		/* TBD: Remove when policy moves to user-mode. */
+		status = tz_policy_remove_device(thermal_zone);
+		if (ACPI_SUCCESS(status)) {
+			status = tz_policy_add_device(thermal_zone);
+		}
+		/* -------------------------------------------- */
+		status = tz_osl_generate_event(notify_type, thermal_zone);
+		break;
+
+	case TZ_NOTIFY_DEVICE_LISTS_CHANGE:
+		/* -------------------------------------------- */
+		/* TBD: Remove when policy moves to user-mode. */
+		status = tz_policy_remove_device(thermal_zone);
+		if (ACPI_SUCCESS(status)) {
+			status = tz_policy_add_device(thermal_zone);
+		}
+		/* -------------------------------------------- */
+		status = tz_osl_generate_event(notify_type, thermal_zone);
+		break;
+
+	default:
+		status = AE_SUPPORT;
+		break;
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    tz_request
+ *
+ * PARAMETERS:
+ *
+ * RETURN:      Exception code.
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+tz_request (
+	BM_REQUEST		*request,
+	void                    *context)
+{
+	ACPI_STATUS             status = AE_OK;
+	TZ_CONTEXT              *thermal_zone = NULL;
+
+	/*
+	 * Must have a valid request structure and context.
+	 */
+	if (!request || !context) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	thermal_zone = (TZ_CONTEXT*)context;
+
+	/*
+	 * Handle request:
+	 * ---------------
+	 */
+	switch (request->command) {
+
+	default:
+		status = AE_SUPPORT;
+		break;
+	}
+
+	request->status = status;
+
+	return(status);
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/thermal/tz_osl.c linux/drivers/acpi/ospm/thermal/tz_osl.c
--- v2.4.5/linux/drivers/acpi/ospm/thermal/tz_osl.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/thermal/tz_osl.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,330 @@
+/******************************************************************************
+ *
+ * Module Name: tz_osl.c
+ *   $Revision: 18 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <acpi.h>
+#include "tz.h"
+
+
+MODULE_AUTHOR("Andrew Grover");
+MODULE_DESCRIPTION("ACPI Component Architecture (CA) - Thermal Zone Driver");
+
+int TZP = 0;
+MODULE_PARM(TZP, "i");
+MODULE_PARM_DESC(TZP, "Thermal zone polling frequency, in 1/10 seconds.\n");
+
+
+#define TZ_PROC_ROOT		"thermal"
+#define TZ_PROC_STATUS		"status"
+#define TZ_PROC_INFO		"info"
+
+extern struct proc_dir_entry	*bm_proc_root;
+static struct proc_dir_entry	*tz_proc_root = NULL;
+
+
+/****************************************************************************
+ * 
+ * FUNCTION:	tz_osl_proc_read_info
+ *
+ ****************************************************************************/
+
+static int
+tz_osl_proc_read_info (
+	char			*page, 
+	char			**start, 
+	off_t			off, 
+	int 			count, 
+	int 			*eof, 
+	void			*context)
+{
+	TZ_CONTEXT		*thermal_zone = NULL;
+	char			*p = page;
+	int 			len = 0;
+
+	if (!context || (off != 0)) {
+		goto end;
+	}
+
+	thermal_zone = (TZ_CONTEXT*)context;
+
+	p += sprintf(p, "<TBD>\n");
+
+end:
+	len = (p - page);
+	if (len <= off+count) *eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len>count) len = count;
+	if (len<0) len = 0;
+
+	return(len);
+}
+
+
+/****************************************************************************
+ * 
+ * FUNCTION:	tz_osl_proc_read_status
+ *
+ ****************************************************************************/
+
+static int
+tz_osl_proc_read_status (
+	char			*page, 
+	char			**start, 
+	off_t			off, 
+	int 			count, 
+	int 			*eof, 
+	void			*context)
+{
+	TZ_CONTEXT		*thermal_zone = NULL;
+	char			*p = page;
+	int 			len = 0;
+
+	if (!context || (off != 0)) {
+		goto end;
+	}
+
+	thermal_zone = (TZ_CONTEXT*)context;
+
+	p += sprintf(p, "Temperature:             %d (1/10th degrees Kelvin)\n", 
+		thermal_zone->policy.temperature);
+
+	p += sprintf(p, "State:                   ");
+	if (thermal_zone->policy.state & TZ_STATE_ACTIVE) {
+		p += sprintf(p, "active[%d] ", thermal_zone->policy.state & 0x07);
+	}
+	if (thermal_zone->policy.state & TZ_STATE_PASSIVE) {
+		p += sprintf(p, "passive ");
+	}
+	if (thermal_zone->policy.state & TZ_STATE_CRITICAL) {
+		p += sprintf(p, "critical ");
+	}
+	if (thermal_zone->policy.state == 0) {
+		p += sprintf(p, "ok ");
+	}
+	p += sprintf(p, "\n");
+
+	p += sprintf(p, "Cooling Mode:            ");
+	switch (thermal_zone->policy.cooling_mode) {
+	case TZ_COOLING_MODE_ACTIVE:
+		p += sprintf(p, "active (noisy)\n");
+		break;
+	case TZ_COOLING_MODE_PASSIVE:
+		p += sprintf(p, "passive (quiet)\n");
+		break;
+	default:
+		p += sprintf(p, "unknown\n");
+		break;
+	}
+
+	p += sprintf(p, "Polling Frequency:       ");
+	switch (thermal_zone->policy.polling_freq) {
+	case 0:
+		p += sprintf(p, "n/a\n");
+		break;
+	default:
+		p += sprintf(p, "%d (1/10th seconds)\n", thermal_zone->policy.polling_freq);
+		break;
+	}
+
+end:
+	len = (p - page);
+	if (len <= off+count) *eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len>count) len = count;
+	if (len<0) len = 0;
+
+	return(len);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	tz_osl_add_device
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+tz_osl_add_device(
+	TZ_CONTEXT		*thermal_zone)
+{
+	struct proc_dir_entry	*proc_entry = NULL;
+
+	if (!thermal_zone) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	printk("Thermal Zone: found\n");
+
+	proc_entry = proc_mkdir(thermal_zone->uid, tz_proc_root);
+	if (!proc_entry) {
+		return(AE_ERROR);
+	}
+
+	create_proc_read_entry(TZ_PROC_STATUS, S_IFREG | S_IRUGO, 
+		proc_entry, tz_osl_proc_read_status, (void*)thermal_zone);
+
+	create_proc_read_entry(TZ_PROC_INFO, S_IFREG | S_IRUGO, 
+		proc_entry, tz_osl_proc_read_info, (void*)thermal_zone);
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	tz_osl_remove_device
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+tz_osl_remove_device (
+	TZ_CONTEXT		*thermal_zone)
+{
+	char			proc_entry[64];
+
+	if (!thermal_zone) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	sprintf(proc_entry, "%s/%s", thermal_zone->uid, TZ_PROC_INFO);
+	remove_proc_entry(proc_entry, tz_proc_root);
+
+	sprintf(proc_entry, "%s/%s", thermal_zone->uid, TZ_PROC_STATUS);
+	remove_proc_entry(proc_entry, tz_proc_root);
+
+	sprintf(proc_entry, "%s", thermal_zone->uid);
+	remove_proc_entry(proc_entry, tz_proc_root);
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	tz_osl_generate_event
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+tz_osl_generate_event (
+	u32			event,
+	TZ_CONTEXT		*thermal_zone)
+{
+	ACPI_STATUS		status = AE_OK;
+
+	if (!thermal_zone) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	switch (event) {
+
+	case TZ_NOTIFY_TEMPERATURE_CHANGE:
+		status = bm_osl_generate_event(thermal_zone->device_handle, 
+			TZ_PROC_ROOT, thermal_zone->uid, event, 
+			thermal_zone->policy.temperature);
+		break;
+
+	case TZ_NOTIFY_THRESHOLD_CHANGE:
+	case TZ_NOTIFY_DEVICE_LISTS_CHANGE:
+		status = bm_osl_generate_event(thermal_zone->device_handle, 
+			TZ_PROC_ROOT, thermal_zone->uid, event, 0);
+		break;
+
+	default:
+		return(AE_BAD_PARAMETER);
+		break;
+	}
+
+	return(status);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	tz_osl_init
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	0: Success
+ *
+ * DESCRIPTION: Module initialization.
+ *
+ ****************************************************************************/
+
+static int __init 
+tz_osl_init (void)
+{
+	ACPI_STATUS		status = AE_OK;
+
+	tz_proc_root = proc_mkdir(TZ_PROC_ROOT, bm_proc_root);
+	if (!tz_proc_root) {
+		status = AE_ERROR;
+	}
+	else {
+		status = tz_initialize();
+		if (ACPI_FAILURE(status)) {
+			remove_proc_entry(TZ_PROC_ROOT, bm_proc_root);
+		}
+
+	}
+
+	return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:	tz_osl_cleanup
+ *
+ * PARAMETERS:	<none>
+ *
+ * RETURN:	<none>
+ *
+ * DESCRIPTION: Module cleanup.
+ *
+ ****************************************************************************/
+
+static void __exit 
+tz_osl_cleanup (void)
+{
+	tz_terminate();
+
+	if (tz_proc_root) {
+		remove_proc_entry(TZ_PROC_ROOT, bm_proc_root);
+	}
+
+	return;
+}
+
+
+module_init(tz_osl_init);
+module_exit(tz_osl_cleanup);
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/ospm/thermal/tzpolicy.c linux/drivers/acpi/ospm/thermal/tzpolicy.c
--- v2.4.5/linux/drivers/acpi/ospm/thermal/tzpolicy.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/ospm/thermal/tzpolicy.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,640 @@
+/****************************************************************************
+ *
+ * Module Name: tzpolicy.c -
+ *   $Revision: 27 $
+ *
+ ****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 Andrew Grover
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * TBD: 1. Move to user-space!
+ *	2. Support ACPI 2.0 items (e.g. _TZD, _HOT).
+ *      3. Support performance-limit control for non-processor devices
+ *         (those listed in _TZD, e.g. graphics).
+ */
+
+/* TBD: Linux specific */
+#include <linux/proc_fs.h>
+#include <linux/sysctl.h>
+#include <linux/pm.h>
+
+#include <acpi.h>
+#include <bm.h>
+#include "tz.h"
+
+
+#define _COMPONENT		ACPI_THERMAL
+	MODULE_NAME		("tzpolicy")
+
+
+/****************************************************************************
+ *                                  Globals
+ ****************************************************************************/
+
+extern int TZP;
+
+void
+tz_policy_run (
+	unsigned long           data);
+
+
+/****************************************************************************
+ *                              Internal Functions
+ ****************************************************************************/
+
+ACPI_STATUS
+set_performance_limit (
+	BM_HANDLE               device_handle,
+	u32			flag)
+{
+	ACPI_STATUS             status;
+	BM_REQUEST              request;
+
+	request.status = AE_OK;
+	request.handle = device_handle;
+	request.command = PR_COMMAND_SET_PERF_LIMIT;
+	request.buffer.length = sizeof(u32);
+	request.buffer.pointer = &flag;
+
+	status = bm_request(&request);
+
+	if (ACPI_FAILURE(status)) {
+		return status;
+	}
+	else {
+		return request.status;
+	}
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    tz_policy_critical
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+tz_policy_critical(
+	TZ_CONTEXT		*tz)
+{
+	if (!tz || !tz->policy.critical.threshold) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	if (tz->policy.temperature >=
+		tz->policy.critical.threshold->temperature) {
+		/* TBD:	Need method for calling 'halt' - OSL function? */
+	}
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    tz_policy_passive
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+tz_policy_passive(
+	TZ_CONTEXT		*tz)
+{
+	TZ_PASSIVE_POLICY	*passive = NULL;
+	static u32		last_temperature = 0;
+	s32			trend = 0;
+	u32			i = 0;
+
+	if (!tz || !tz->policy.passive.threshold) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	passive = &(tz->policy.passive);
+
+	if (tz->policy.temperature >= passive->threshold->temperature) {
+		/*
+		 * Thermal trend?
+		 * --------------
+		 * Using the passive cooling equation (see the ACPI
+		 * Specification), calculate the current thermal trend
+		 * (a.k.a. performance delta).
+		 */
+		trend = passive->tc1 *
+			(tz->policy.temperature - last_temperature) +
+			passive->tc2 *
+			(tz->policy.temperature - passive->threshold->temperature);
+
+		last_temperature = tz->policy.temperature;
+
+		/*
+		 * Heating Up?
+		 * -----------
+		 * Decrease thermal performance limit on all passive
+		 * cooling devices (processors).
+		 */
+		if (trend > 0) {
+			for (i=0; i<passive->threshold->cooling_devices.count; i++) {
+				set_performance_limit(
+					passive->threshold->cooling_devices.handles[i],
+					PR_PERF_DEC);
+			}
+		}
+		/*
+		 * Cooling Off?
+		 * ------------
+		 * Increase thermal performance limit on all passive
+		 * cooling devices (processors).
+		 */
+		else if (trend < 0) {
+			for (i=0; i<passive->threshold->cooling_devices.count; i++) {
+				set_performance_limit(
+					passive->threshold->cooling_devices.handles[i],
+					PR_PERF_INC);
+			}
+		}
+	}
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    tz_policy_active
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+tz_policy_active(
+	TZ_CONTEXT              *tz)
+{
+	ACPI_STATUS             status = AE_OK;
+	TZ_THRESHOLD            *active = NULL;
+	u32                     i,j = 0;
+
+	if (!tz || !tz->policy.active.threshold) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	for (i = 0; i < TZ_MAX_ACTIVE_THRESHOLDS; i++) {
+
+		active = tz->policy.active.threshold[i];
+		if (!active) {
+			break;
+		}
+
+		/*
+		 * Above Threshold?
+		 * ----------------
+		 * If not already enabled, turn ON all cooling devices
+		 * associated with this active threshold.
+		 */
+		if ((tz->policy.temperature >= active->temperature) &&
+			(active->cooling_state != TZ_COOLING_ENABLED)) {
+
+			for (j = 0; j < active->cooling_devices.count; j++) {
+
+				status = bm_set_device_power_state(
+					active->cooling_devices.handles[j],
+					ACPI_STATE_D0);
+
+				if (ACPI_SUCCESS(status)) {
+				}
+				else {
+				}
+			}
+
+			active->cooling_state = TZ_COOLING_ENABLED;
+		}
+		/*
+		 * Below Threshold?
+		 * ----------------
+		 * Turn OFF all cooling devices associated with this
+		 * threshold.  Note that by checking "if not disabled" we
+		 * turn off all cooling devices for thresholds in the
+		 * TZ_COOLING_STATE_UNKNOWN state, useful as a level-set
+		 * during the first pass.
+		 */
+		else if (active->cooling_state != TZ_COOLING_DISABLED) {
+
+			for (j = 0; j < active->cooling_devices.count; j++) {
+
+				status = bm_set_device_power_state(
+					active->cooling_devices.handles[j],
+					ACPI_STATE_D3);
+
+				if (ACPI_SUCCESS(status)) {
+				}
+				else {
+				}
+			}
+
+			active->cooling_state = TZ_COOLING_DISABLED;
+		}
+	}
+
+	return(AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    tz_policy_check
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION: Note that this function will get called whenever:
+ *                1. A thermal event occurs.
+ *                2. The polling/sampling time period expires.
+ *
+ ****************************************************************************/
+
+void
+tz_policy_check (
+	void                    *context)
+{
+	ACPI_STATUS             status = AE_OK;
+	TZ_CONTEXT              *tz = NULL;
+	u32                     previous_temperature = 0;
+	u32                     previous_state = 0;
+	u32                     active_index = 0;
+	u32                     i = 0;
+	u32                     sleep_time = 0;
+
+	if (!context) {
+		return;
+	}
+
+	tz = (TZ_CONTEXT*)context;
+
+	/*
+	 * Preserve Previous State:
+	 * ------------------------
+	 */
+	previous_temperature = tz->policy.temperature;
+	previous_state = tz->policy.state;
+
+	/*
+	 * Get Temperature:
+	 * ----------------
+	 */
+	status = tz_get_temperature(tz, &(tz->policy.temperature));
+	if (ACPI_FAILURE(status)) {
+		return;
+	}
+
+	/*
+	 * Calculate State:
+	 * ----------------
+	 */
+	tz->policy.state = TZ_STATE_OK;
+
+	/* Critical? */
+	if ((tz->policy.critical.threshold) &&
+		(tz->policy.temperature >= tz->policy.critical.threshold->temperature)) {
+		tz->policy.state |= TZ_STATE_CRITICAL;
+	}
+
+	/* Passive? */
+	if ((tz->policy.passive.threshold) &&
+		(tz->policy.temperature >= tz->policy.passive.threshold->temperature)) {
+		tz->policy.state |= TZ_STATE_PASSIVE;
+	}
+
+	/* Active? */
+	if (tz->policy.active.threshold[0]) {
+		for (i=0; i<tz->policy.active.threshold_count; i++) {
+			if ((tz->policy.active.threshold[i]) &&
+				(tz->policy.temperature >= tz->policy.active.threshold[i]->temperature)) {
+			    tz->policy.state |= TZ_STATE_ACTIVE;
+			    if (tz->policy.active.threshold[i]->index > active_index) {
+				    active_index = tz->policy.active.threshold[i]->index;
+			    }
+			}
+		}
+		tz->policy.state |= active_index;
+	}
+
+	/*
+	 * Invoke Policy:
+	 * --------------
+	 * Note that policy must be invoked both when 'going into' a
+	 * policy state (e.g. to allow fans to be turned on) and 'going
+	 * out of' a policy state (e.g. to allow fans to be turned off);
+	 * thus we must preserve the previous state.
+	 */
+	if (tz->policy.state & TZ_STATE_CRITICAL) {
+		tz_policy_critical(tz);
+	}
+	if ((tz->policy.state & TZ_STATE_PASSIVE) ||
+		(previous_state & TZ_STATE_PASSIVE)) {
+		tz_policy_passive(tz);
+	}
+	if ((tz->policy.state & TZ_STATE_ACTIVE) ||
+		(previous_state & TZ_STATE_ACTIVE)) {
+		tz_policy_active(tz);
+	}
+
+	/*
+	 * Calculate Sleep Time:
+	 * ---------------------
+	 * If we're in the passive state, use _TSP's value.  Otherwise
+	 * use _TZP or the OS's default polling frequency.  If no polling
+	 * frequency is specified then we'll wait forever (that is, until
+	 * a thermal event occurs -- e.g. never poll).  Note that _TSP
+	 * and _TZD values are given in 1/10th seconds.
+	 */
+	if (tz->policy.state & TZ_STATE_PASSIVE) {
+		sleep_time = tz->policy.passive.tsp * 100;
+	}
+	else if (tz->policy.polling_freq > 0) {
+		sleep_time = tz->policy.polling_freq * 100;
+	}
+	else {
+		sleep_time = WAIT_FOREVER;
+	}
+
+
+	/*
+	 * Schedule Next Poll:
+	 * -------------------
+	 */
+	if (sleep_time < WAIT_FOREVER) {
+		if (timer_pending(&(tz->policy.timer))) {
+			mod_timer(&(tz->policy.timer),
+				(HZ*sleep_time)/1000);
+		}
+		else {
+			tz->policy.timer.data = (u32)tz;
+			tz->policy.timer.function = tz_policy_run;
+			tz->policy.timer.expires =
+				jiffies + (HZ*sleep_time)/1000;
+			add_timer(&(tz->policy.timer));
+		}
+	}
+	else {
+		if (timer_pending(&(tz->policy.timer))) {
+			del_timer(&(tz->policy.timer));
+		}
+	}
+
+	return;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    tz_policy_run
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+void
+tz_policy_run (
+	unsigned long           data)
+{
+	ACPI_STATUS             status = AE_OK;
+
+	if (!data) {
+		return;
+	}
+
+	/*
+	 * Defer to Non-Interrupt Level:
+	 * -----------------------------
+	 * Note that all Linux kernel timers run at interrupt-level (ack!).
+	 */
+	status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
+		tz_policy_check, (void*)data);
+	if (ACPI_FAILURE(status)) {
+	}
+
+	return;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    tz_policy_add_device
+ *
+ * PARAMETERS:
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+tz_policy_add_device (
+	TZ_CONTEXT		*tz)
+{
+	ACPI_STATUS             status = AE_OK;
+	TZ_THRESHOLD            *threshold = NULL;
+	u32                     i,j = 0;
+
+	if (!tz) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Temperature:
+	 * ------------
+	 * Make sure we can read the zone's current temperature (_TMP).
+	 * If we can't, there's no use in doing any policy (abort).
+	 */
+	status = tz_get_temperature(tz, &(tz->policy.temperature));
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	/*
+	 * Polling Frequency:
+	 * ------------------
+	 * If a _TZP object doesn't exist, use the OS default polling
+	 * frequency.
+	 */
+	status = bm_evaluate_simple_integer(tz->acpi_handle, "_TZP",
+		&(tz->policy.polling_freq));
+	if (ACPI_FAILURE(status)) {
+		tz->policy.polling_freq = TZP;
+	}
+	status = AE_OK;
+
+	/*
+	 * Get Thresholds:
+	 * ---------------
+	 * Get all of the zone's thresholds, parse, and organize for
+	 * later use.
+	 */
+	status = tz_get_thresholds(tz, &(tz->policy.threshold_list));
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	/*
+	 * Initialize Policies:
+	 * --------------------
+	 */
+	for (i = 0; i < tz->policy.threshold_list.count; i++) {
+
+		threshold = &(tz->policy.threshold_list.thresholds[i]);
+
+		switch (threshold->type) {
+
+		case TZ_THRESHOLD_CRITICAL:
+			tz->policy.critical.threshold = threshold;
+			break;
+
+		case TZ_THRESHOLD_PASSIVE:
+
+			/*
+			 * Set thermal performance limit on all processors
+			 * to max.
+			 */
+			for (j=0; j<threshold->cooling_devices.count; j++) {
+				set_performance_limit(
+					threshold->cooling_devices.handles[j],
+					PR_PERF_MAX);
+			}
+
+			/*
+			 * Get passive cooling constants.
+			 */
+			status = bm_evaluate_simple_integer(tz->acpi_handle,
+				"_TC1", &(tz->policy.passive.tc1));
+			if (ACPI_FAILURE(status)) {
+				break;
+			}
+
+			status = bm_evaluate_simple_integer(tz->acpi_handle,
+				"_TC2", &(tz->policy.passive.tc2));
+			if (ACPI_FAILURE(status)) {
+				break;
+			}
+
+			status = bm_evaluate_simple_integer(tz->acpi_handle,
+				"_TSP", &(tz->policy.passive.tsp));
+			if (ACPI_FAILURE(status)) {
+				break;
+			}
+
+			tz->policy.passive.threshold = threshold;
+
+			tz_policy_passive(tz);
+
+			break;
+
+		case TZ_THRESHOLD_ACTIVE:
+			tz->policy.active.threshold[threshold->index] = threshold;
+			tz_policy_active(tz);
+			break;
+		}
+	}
+
+	if (ACPI_FAILURE(status)) {
+		return(status);
+	}
+
+	/*
+	 * Initialize Policy Timer:
+	 * ------------------------
+	 * TBD: Linux-specific - remove when policy moves to user-space.
+	 */
+	init_timer(&(tz->policy.timer));
+
+	/*
+	 * Start Policy:
+	 * -------------
+	 * Run an initial check using this zone's policy.
+	 */
+	tz_policy_check(tz);
+
+	return(status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    tz_policy_remove_device
+ *
+ * PARAMETERS:
+ *
+ * RETURN:	
+ *
+ * DESCRIPTION:
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+tz_policy_remove_device(
+	TZ_CONTEXT		*tz)
+{
+	u32			i = 0;
+
+	if (!tz) {
+		return(AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Delete the thermal zone policy timer entry, if exists.
+	 */
+	if (timer_pending(&(tz->policy.timer))) {
+		del_timer(&(tz->policy.timer));
+	}
+
+	/*
+	 * Reset thermal performance limit on all processors back to max.
+	 */
+	if (tz->policy.passive.threshold) {
+		for (i=0; i<tz->policy.passive.threshold->cooling_devices.count; i++) {
+			set_performance_limit(
+				tz->policy.passive.threshold->cooling_devices.handles[i],
+				PR_PERF_MAX);
+		}
+	}
+
+	return(AE_OK);
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/parser/Makefile linux/drivers/acpi/parser/Makefile
--- v2.4.5/linux/drivers/acpi/parser/Makefile	Fri Dec 29 14:07:21 2000
+++ linux/drivers/acpi/parser/Makefile	Wed Jun 20 17:47:40 2001
@@ -1,16 +1,12 @@
 #
 # Makefile for all Linux ACPI interpreter subdirectories
+# EXCEPT for the ospm directory
 #
 
-O_TARGET := ../$(shell basename `pwd`).o
+O_TARGET := $(notdir $(CURDIR)).o
 
 obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c))
 
-EXTRA_CFLAGS += -I../include
-
 EXTRA_CFLAGS += $(ACPI_CFLAGS)
 
 include $(TOPDIR)/Rules.make
-
-clean:
-	$(RM) *.o 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/parser/psargs.c linux/drivers/acpi/parser/psargs.c
--- v2.4.5/linux/drivers/acpi/parser/psargs.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/parser/psargs.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: psargs - Parse AML opcode arguments
- *              $Revision: 43 $
+ *              $Revision: 47 $
  *
  *****************************************************************************/
 
@@ -29,7 +29,7 @@
 #include "amlcode.h"
 #include "acnamesp.h"
 
-#define _COMPONENT          PARSER
+#define _COMPONENT          ACPI_PARSER
 	 MODULE_NAME         ("psargs")
 
 
@@ -58,8 +58,7 @@
 	parser_state->aml++;
 
 
-	switch (encoded_length >> 6) /* bits 6-7 contain encoding scheme */
-	{
+	switch (encoded_length >> 6) /* bits 6-7 contain encoding scheme */ {
 	case 0: /* 1-byte encoding (bits 0-5) */
 
 		length = (encoded_length & 0x3F);
@@ -158,8 +157,7 @@
 
 	/* Decode the path */
 
-	switch (GET8 (end))
-	{
+	switch (GET8 (end)) {
 	case 0:
 
 		/* Null_name */
@@ -244,7 +242,7 @@
 	if (!path || !method_call) {
 		/* Null name case, create a null namepath object */
 
-		acpi_ps_init_op (arg, AML_NAMEPATH_OP);
+		acpi_ps_init_op (arg, AML_INT_NAMEPATH_OP);
 		arg->value.name = path;
 		return;
 	}
@@ -272,11 +270,11 @@
 
 				count = acpi_ps_get_arg (op, 0);
 				if (count && count->opcode == AML_BYTE_OP) {
-					name_op = acpi_ps_alloc_op (AML_NAMEPATH_OP);
+					name_op = acpi_ps_alloc_op (AML_INT_NAMEPATH_OP);
 					if (name_op) {
 						/* Change arg into a METHOD CALL and attach the name */
 
-						acpi_ps_init_op (arg, AML_METHODCALL_OP);
+						acpi_ps_init_op (arg, AML_INT_METHODCALL_OP);
 
 						name_op->value.name = path;
 
@@ -308,7 +306,7 @@
 	 * pathname
 	 */
 
-	acpi_ps_init_op (arg, AML_NAMEPATH_OP);
+	acpi_ps_init_op (arg, AML_INT_NAMEPATH_OP);
 	arg->value.name = path;
 
 
@@ -338,7 +336,7 @@
 	if (!path || !method_call) {
 		/* Null name case, create a null namepath object */
 
-		acpi_ps_init_op (arg, AML_NAMEPATH_OP);
+		acpi_ps_init_op (arg, AML_INT_NAMEPATH_OP);
 		arg->value.name = path;
 		return;
 	}
@@ -367,11 +365,11 @@
 		if (ACPI_SUCCESS (status)) {
 			if (node->type == ACPI_TYPE_METHOD) {
 				method_node = node;
-				name_op = acpi_ps_alloc_op (AML_NAMEPATH_OP);
+				name_op = acpi_ps_alloc_op (AML_INT_NAMEPATH_OP);
 				if (name_op) {
 					/* Change arg into a METHOD CALL and attach name to it */
 
-					acpi_ps_init_op (arg, AML_METHODCALL_OP);
+					acpi_ps_init_op (arg, AML_INT_METHODCALL_OP);
 
 					name_op->value.name = path;
 
@@ -404,7 +402,7 @@
 	 * pathname.
 	 */
 
-	acpi_ps_init_op (arg, AML_NAMEPATH_OP);
+	acpi_ps_init_op (arg, AML_INT_NAMEPATH_OP);
 	arg->value.name = path;
 
 
@@ -435,8 +433,7 @@
 {
 
 
-	switch (arg_type)
-	{
+	switch (arg_type) {
 
 	case ARGP_BYTEDATA:
 
@@ -483,7 +480,7 @@
 	case ARGP_NAME:
 	case ARGP_NAMESTRING:
 
-		acpi_ps_init_op (arg, AML_NAMEPATH_OP);
+		acpi_ps_init_op (arg, AML_INT_NAMEPATH_OP);
 		arg->value.name = acpi_ps_get_next_namestring (parser_state);
 		break;
 	}
@@ -508,7 +505,7 @@
 acpi_ps_get_next_field (
 	ACPI_PARSE_STATE        *parser_state)
 {
-	ACPI_PTRDIFF            aml_offset = parser_state->aml -
+	u32                     aml_offset = parser_state->aml -
 			 parser_state->aml_start;
 	ACPI_PARSE_OBJECT       *field;
 	u16                     opcode;
@@ -517,25 +514,24 @@
 
 	/* determine field type */
 
-	switch (GET8 (parser_state->aml))
-	{
+	switch (GET8 (parser_state->aml)) {
 
 	default:
 
-		opcode = AML_NAMEDFIELD_OP;
+		opcode = AML_INT_NAMEDFIELD_OP;
 		break;
 
 
 	case 0x00:
 
-		opcode = AML_RESERVEDFIELD_OP;
+		opcode = AML_INT_RESERVEDFIELD_OP;
 		parser_state->aml++;
 		break;
 
 
 	case 0x01:
 
-		opcode = AML_ACCESSFIELD_OP;
+		opcode = AML_INT_ACCESSFIELD_OP;
 		parser_state->aml++;
 		break;
 	}
@@ -549,9 +545,8 @@
 
 		/* Decode the field type */
 
-		switch (opcode)
-		{
-		case AML_NAMEDFIELD_OP:
+		switch (opcode) {
+		case AML_INT_NAMEDFIELD_OP:
 
 			/* Get the 4-character name */
 
@@ -565,7 +560,7 @@
 			break;
 
 
-		case AML_RESERVEDFIELD_OP:
+		case AML_INT_RESERVEDFIELD_OP:
 
 			/* Get the length which is encoded as a package length */
 
@@ -573,7 +568,7 @@
 			break;
 
 
-		case AML_ACCESSFIELD_OP:
+		case AML_INT_ACCESSFIELD_OP:
 
 			/* Get Access_type and Access_atrib and merge into the field Op */
 
@@ -616,8 +611,7 @@
 	u32                     subop;
 
 
-	switch (arg_type)
-	{
+	switch (arg_type) {
 	case ARGP_BYTEDATA:
 	case ARGP_WORDDATA:
 	case ARGP_DWORDDATA:
@@ -676,7 +670,7 @@
 		if (parser_state->aml < parser_state->pkg_end) {
 			/* non-empty list */
 
-			arg = acpi_ps_alloc_op (AML_BYTELIST_OP);
+			arg = acpi_ps_alloc_op (AML_INT_BYTELIST_OP);
 			if (arg) {
 				/* fill in bytelist data */
 
@@ -692,16 +686,14 @@
 
 
 	case ARGP_TARGET:
-	case ARGP_SUPERNAME:
-		{
+	case ARGP_SUPERNAME: {
 			subop = acpi_ps_peek_opcode (parser_state);
 			if (subop == 0              ||
 				acpi_ps_is_leading_char (subop) ||
-				acpi_ps_is_prefix_char (subop))
-			{
+				acpi_ps_is_prefix_char (subop)) {
 				/* Null_name or Name_string */
 
-				arg = acpi_ps_alloc_op (AML_NAMEPATH_OP);
+				arg = acpi_ps_alloc_op (AML_INT_NAMEPATH_OP);
 				if (arg) {
 					acpi_ps_get_next_namepath (parser_state, arg, arg_count, 0);
 				}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/parser/psfind.c linux/drivers/acpi/parser/psfind.c
--- v2.4.5/linux/drivers/acpi/parser/psfind.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/parser/psfind.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,313 @@
+
+/******************************************************************************
+ *
+ * Module Name: psfind - Parse tree search routine
+ *              $Revision: 24 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "amlcode.h"
+
+#define _COMPONENT          ACPI_PARSER
+	 MODULE_NAME         ("psfind")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ps_get_parent
+ *
+ * PARAMETERS:  Op              - Get the parent of this Op
+ *
+ * RETURN:      The Parent op.
+ *
+ * DESCRIPTION: Get op's parent
+ *
+ ******************************************************************************/
+
+static ACPI_PARSE_OBJECT*
+acpi_ps_get_parent (
+	ACPI_PARSE_OBJECT       *op)
+{
+	ACPI_PARSE_OBJECT       *parent = op;
+
+
+	/* Traverse the tree upward (to root if necessary) */
+
+	while (parent) {
+		switch (parent->opcode) {
+		case AML_SCOPE_OP:
+		case AML_PACKAGE_OP:
+		case AML_METHOD_OP:
+		case AML_DEVICE_OP:
+		case AML_POWER_RES_OP:
+		case AML_THERMAL_ZONE_OP:
+
+			return (parent->parent);
+		}
+
+		parent = parent->parent;
+	}
+
+	return (parent);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ps_find_name
+ *
+ * PARAMETERS:  Scope           - Scope to search
+ *              Name            - ACPI name to search for
+ *              Opcode          - Opcode to search for
+ *
+ * RETURN:      Op containing the name
+ *
+ * DESCRIPTION: Find name segment from a list of acpi_ops.  Searches a single
+ *              scope, no more.
+ *
+ ******************************************************************************/
+
+static ACPI_PARSE_OBJECT *
+acpi_ps_find_name (
+	ACPI_PARSE_OBJECT       *scope,
+	u32                     name,
+	u32                     opcode)
+{
+	ACPI_PARSE_OBJECT       *op;
+	ACPI_PARSE_OBJECT       *field;
+
+
+	/* search scope level for matching name segment */
+
+	op = acpi_ps_get_child (scope);
+
+	while (op) {
+
+		if (acpi_ps_is_field_op (op->opcode)) {
+			/* Field, search named fields */
+
+			field = acpi_ps_get_child (op);
+			while (field) {
+				if (acpi_ps_is_named_op (field->opcode) &&
+				   acpi_ps_get_name (field) == name &&
+				   (!opcode || field->opcode == opcode)) {
+					return (field);
+				}
+
+				field = field->next;
+			}
+		}
+
+		else if (acpi_ps_is_create_field_op (op->opcode)) {
+			if (op->opcode == AML_CREATE_FIELD_OP) {
+				field = acpi_ps_get_arg (op, 3);
+			}
+
+			else {
+				/* Create_xXXField, check name */
+
+				field = acpi_ps_get_arg (op, 2);
+			}
+
+			if ((field) &&
+				(field->value.string) &&
+				(!STRNCMP (field->value.string, (char *) &name, ACPI_NAME_SIZE))) {
+				return (op);
+			}
+		}
+
+		else if ((acpi_ps_is_named_op (op->opcode)) &&
+				 (acpi_ps_get_name (op) == name) &&
+				 (!opcode || op->opcode == opcode || opcode == AML_SCOPE_OP)) {
+			break;
+		}
+
+		op = op->next;
+	}
+
+	return (op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ps_find
+ *
+ * PARAMETERS:  Scope           - Where to begin the search
+ *              Path            - ACPI Path to the named object
+ *              Opcode          - Opcode associated with the object
+ *              Create          - if TRUE, create the object if not found.
+ *
+ * RETURN:      Op if found, NULL otherwise.
+ *
+ * DESCRIPTION: Find object within scope
+ *
+ ******************************************************************************/
+
+ACPI_PARSE_OBJECT*
+acpi_ps_find (
+	ACPI_PARSE_OBJECT       *scope,
+	NATIVE_CHAR             *path,
+	u16                     opcode,
+	u32                     create)
+{
+	u32                     seg_count;
+	u32                     name;
+	u32                     name_op;
+	ACPI_PARSE_OBJECT       *op = NULL;
+	u8                      unprefixed = TRUE;
+
+
+	if (!scope || !path) {
+		return (NULL);
+	}
+
+
+	acpi_gbl_ps_find_count++;
+
+
+	/* Handle all prefixes in the name path */
+
+	while (acpi_ps_is_prefix_char (GET8 (path))) {
+		switch (GET8 (path)) {
+
+		case '\\':
+
+			/* Could just use a global for "root scope" here */
+
+			while (scope->parent) {
+				scope = scope->parent;
+			}
+
+			/* get first object within the scope */
+			/* TBD: [Investigate] OR - set next in root scope to point to the same value as arg */
+
+			/* Scope = Scope->Value.Arg; */
+
+			break;
+
+
+		case '^':
+
+			/* Go up to the next valid scoping Op (method, scope, etc.) */
+
+			if (acpi_ps_get_parent (scope)) {
+				scope = acpi_ps_get_parent (scope);
+			}
+
+			break;
+		}
+
+		unprefixed = FALSE;
+		path++;
+	}
+
+	/* get name segment count */
+
+	switch (GET8 (path)) {
+	case '\0':
+		seg_count = 0;
+
+		/* Null name case */
+
+		if (unprefixed) {
+			op = NULL;
+		}
+		else {
+			op = scope;
+		}
+
+
+		return (op);
+		break;
+
+	case AML_DUAL_NAME_PREFIX:
+		seg_count = 2;
+		path++;
+		break;
+
+	case AML_MULTI_NAME_PREFIX_OP:
+		seg_count = GET8 (path + 1);
+		path += 2;
+		break;
+
+	default:
+		seg_count = 1;
+		break;
+	}
+
+	/* match each name segment */
+
+	while (scope && seg_count) {
+		MOVE_UNALIGNED32_TO_32 (&name, path);
+		path += 4;
+		seg_count --;
+
+		if (seg_count) {
+			name_op = 0;
+		}
+		else {
+			name_op = opcode;
+		}
+
+		op = acpi_ps_find_name (scope, name, name_op);
+
+		if (!op) {
+			if (create) {
+				/* Create a new Scope level */
+
+				if (seg_count) {
+					op = acpi_ps_alloc_op (AML_SCOPE_OP);
+				}
+				else {
+					op = acpi_ps_alloc_op (opcode);
+				}
+
+				if (op) {
+					acpi_ps_set_name (op, name);
+					acpi_ps_append_arg (scope, op);
+
+				}
+			}
+
+			else if (unprefixed) {
+				/* Search higher scopes for unprefixed name */
+
+				while (!op && scope->parent) {
+					scope = scope->parent;
+					op = acpi_ps_find_name (scope, name, opcode);
+
+				}
+			}
+
+		}
+
+		unprefixed = FALSE;
+		scope = op;
+	}
+
+	return (op);
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/parser/psopcode.c linux/drivers/acpi/parser/psopcode.c
--- v2.4.5/linux/drivers/acpi/parser/psopcode.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/parser/psopcode.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: psopcode - Parser opcode information table
- *              $Revision: 27 $
+ *              $Revision: 32 $
  *
  *****************************************************************************/
 
@@ -29,7 +29,7 @@
 #include "amlcode.h"
 
 
-#define _COMPONENT          PARSER
+#define _COMPONENT          ACPI_PARSER
 	 MODULE_NAME         ("psopcode")
 
 
@@ -130,12 +130,12 @@
 #define ARGP_SIZE_OF_OP                 ARGP_LIST1 (ARGP_SUPERNAME)
 #define ARGP_INDEX_OP                   ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
 #define ARGP_MATCH_OP                   ARGP_LIST6 (ARGP_TERMARG,    ARGP_BYTEDATA,      ARGP_TERMARG,   ARGP_BYTEDATA,  ARGP_TERMARG,   ARGP_TERMARG)
-#define ARGP_DWORD_FIELD_OP             ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
-#define ARGP_WORD_FIELD_OP              ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
-#define ARGP_BYTE_FIELD_OP              ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
-#define ARGP_BIT_FIELD_OP               ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
+#define ARGP_CREATE_DWORD_FIELD_OP      ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
+#define ARGP_CREATE_WORD_FIELD_OP       ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
+#define ARGP_CREATE_BYTE_FIELD_OP       ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
+#define ARGP_CREATE_BIT_FIELD_OP        ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
 #define ARGP_TYPE_OP                    ARGP_LIST1 (ARGP_SUPERNAME)
-#define ARGP_QWORD_FIELD_OP             ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
+#define ARGP_CREATE_QWORD_FIELD_OP      ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
 #define ARGP_LAND_OP                    ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
 #define ARGP_LOR_OP                     ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
 #define ARGP_LNOT_OP                    ARGP_LIST1 (ARGP_TERMARG)
@@ -178,7 +178,7 @@
 #define ARGP_DEBUG_OP                   ARG_NONE
 #define ARGP_FATAL_OP                   ARGP_LIST3 (ARGP_BYTEDATA,   ARGP_DWORDDATA,     ARGP_TERMARG)
 #define ARGP_REGION_OP                  ARGP_LIST4 (ARGP_NAME,       ARGP_BYTEDATA,      ARGP_TERMARG,   ARGP_TERMARG)
-#define ARGP_DEF_FIELD_OP               ARGP_LIST4 (ARGP_PKGLENGTH,  ARGP_NAMESTRING,    ARGP_BYTEDATA,  ARGP_FIELDLIST)
+#define ARGP_FIELD_OP                   ARGP_LIST4 (ARGP_PKGLENGTH,  ARGP_NAMESTRING,    ARGP_BYTEDATA,  ARGP_FIELDLIST)
 #define ARGP_DEVICE_OP                  ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_OBJLIST)
 #define ARGP_PROCESSOR_OP               ARGP_LIST6 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_BYTEDATA,  ARGP_DWORDDATA, ARGP_BYTEDATA,  ARGP_OBJLIST)
 #define ARGP_POWER_RES_OP               ARGP_LIST5 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_BYTEDATA,  ARGP_WORDDATA,  ARGP_OBJLIST)
@@ -202,7 +202,7 @@
  * All AML opcodes and the runtime arguments for each.  Used by the AML interpreter  Each list is compressed
  * into a 32-bit number and stored in the master opcode table at the end of this file.
  *
- * (Used by Acpi_aml_prep_operands procedure and the ASL Compiler)
+ * (Used by Prep_operands procedure and the ASL Compiler)
  */
 
 #define ARGI_ZERO_OP                    ARG_NONE
@@ -260,12 +260,12 @@
 #define ARGI_SIZE_OF_OP                 ARGI_LIST1 (ARGI_DATAOBJECT)
 #define ARGI_INDEX_OP                   ARGI_LIST3 (ARGI_COMPLEXOBJ, ARGI_INTEGER,       ARGI_TARGETREF)
 #define ARGI_MATCH_OP                   ARGI_LIST6 (ARGI_PACKAGE,    ARGI_INTEGER,       ARGI_INTEGER,      ARGI_INTEGER,   ARGI_INTEGER,   ARGI_INTEGER)
-#define ARGI_DWORD_FIELD_OP             ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
-#define ARGI_WORD_FIELD_OP              ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
-#define ARGI_BYTE_FIELD_OP              ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
-#define ARGI_BIT_FIELD_OP               ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
+#define ARGI_CREATE_DWORD_FIELD_OP      ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
+#define ARGI_CREATE_WORD_FIELD_OP       ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
+#define ARGI_CREATE_BYTE_FIELD_OP       ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
+#define ARGI_CREATE_BIT_FIELD_OP        ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
 #define ARGI_TYPE_OP                    ARGI_LIST1 (ARGI_ANYTYPE)
-#define ARGI_QWORD_FIELD_OP             ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
+#define ARGI_CREATE_QWORD_FIELD_OP      ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
 #define ARGI_LAND_OP                    ARGI_LIST2 (ARGI_INTEGER,    ARGI_INTEGER)
 #define ARGI_LOR_OP                     ARGI_LIST2 (ARGI_INTEGER,    ARGI_INTEGER)
 #define ARGI_LNOT_OP                    ARGI_LIST1 (ARGI_INTEGER)
@@ -308,7 +308,7 @@
 #define ARGI_DEBUG_OP                   ARG_NONE
 #define ARGI_FATAL_OP                   ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_INTEGER)
 #define ARGI_REGION_OP                  ARGI_LIST2 (ARGI_INTEGER,    ARGI_INTEGER)
-#define ARGI_DEF_FIELD_OP               ARGI_INVALID_OPCODE
+#define ARGI_FIELD_OP                   ARGI_INVALID_OPCODE
 #define ARGI_DEVICE_OP                  ARGI_INVALID_OPCODE
 #define ARGI_PROCESSOR_OP               ARGI_INVALID_OPCODE
 #define ARGI_POWER_RES_OP               ARGI_INVALID_OPCODE
@@ -335,143 +335,143 @@
 
 static ACPI_OPCODE_INFO    aml_op_info[] =
 {
-/* Index          Opcode                                   Type                   Class                 Has Arguments?   Name                 Parser Args             Interpreter Args */
+/* Index          Opcode                                   Type                   Class                 Has Arguments?   Name                 Parser Args               Interpreter Args */
 
-/*  00 */   /* AML_ZERO_OP */               OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT|        AML_NO_ARGS,  "Zero",               ARGP_ZERO_OP,           ARGI_ZERO_OP),
-/*  01 */   /* AML_ONE_OP */                OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT|        AML_NO_ARGS,  "One",                ARGP_ONE_OP,            ARGI_ONE_OP),
-/*  02 */   /* AML_ALIAS_OP */              OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Alias",              ARGP_ALIAS_OP,          ARGI_ALIAS_OP),
-/*  03 */   /* AML_NAME_OP */               OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Name",               ARGP_NAME_OP,           ARGI_NAME_OP),
-/*  04 */   /* AML_BYTE_OP */               OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL|         AML_NO_ARGS,  "Byte_const",         ARGP_BYTE_OP,           ARGI_BYTE_OP),
-/*  05 */   /* AML_WORD_OP */               OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL|         AML_NO_ARGS,  "Word_const",         ARGP_WORD_OP,           ARGI_WORD_OP),
-/*  06 */   /* AML_DWORD_OP */              OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL|         AML_NO_ARGS,  "Dword_const",        ARGP_DWORD_OP,          ARGI_DWORD_OP),
-/*  07 */   /* AML_STRING_OP */             OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL|         AML_NO_ARGS,  "String",             ARGP_STRING_OP,         ARGI_STRING_OP),
-/*  08 */   /* AML_SCOPE_OP */              OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Scope",              ARGP_SCOPE_OP,          ARGI_SCOPE_OP),
-/*  09 */   /* AML_BUFFER_OP */             OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DATA_TERM|       AML_HAS_ARGS, "Buffer",             ARGP_BUFFER_OP,         ARGI_BUFFER_OP),
-/*  0A */   /* AML_PACKAGE_OP */            OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DATA_TERM|       AML_HAS_ARGS, "Package",            ARGP_PACKAGE_OP,        ARGI_PACKAGE_OP),
-/*  0B */   /* AML_METHOD_OP */             OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Method",             ARGP_METHOD_OP,         ARGI_METHOD_OP),
-/*  0C */   /* AML_LOCAL0 */                OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE|  AML_NO_ARGS,  "Local0",             ARGP_LOCAL0,            ARGI_LOCAL0),
-/*  0D */   /* AML_LOCAL1 */                OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE|  AML_NO_ARGS,  "Local1",             ARGP_LOCAL1,            ARGI_LOCAL1),
-/*  0E */   /* AML_LOCAL2 */                OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE|  AML_NO_ARGS,  "Local2",             ARGP_LOCAL2,            ARGI_LOCAL2),
-/*  0F */   /* AML_LOCAL3 */                OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE|  AML_NO_ARGS,  "Local3",             ARGP_LOCAL3,            ARGI_LOCAL3),
-/*  10 */   /* AML_LOCAL4 */                OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE|  AML_NO_ARGS,  "Local4",             ARGP_LOCAL4,            ARGI_LOCAL4),
-/*  11 */   /* AML_LOCAL5 */                OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE|  AML_NO_ARGS,  "Local5",             ARGP_LOCAL5,            ARGI_LOCAL5),
-/*  12 */   /* AML_LOCAL6 */                OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE|  AML_NO_ARGS,  "Local6",             ARGP_LOCAL6,            ARGI_LOCAL6),
-/*  13 */   /* AML_LOCAL7 */                OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE|  AML_NO_ARGS,  "Local7",             ARGP_LOCAL7,            ARGI_LOCAL7),
-/*  14 */   /* AML_ARG0 */                  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS,  "Arg0",               ARGP_ARG0,              ARGI_ARG0),
-/*  15 */   /* AML_ARG1 */                  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS,  "Arg1",               ARGP_ARG1,              ARGI_ARG1),
-/*  16 */   /* AML_ARG2 */                  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS,  "Arg2",               ARGP_ARG2,              ARGI_ARG2),
-/*  17 */   /* AML_ARG3 */                  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS,  "Arg3",               ARGP_ARG3,              ARGI_ARG3),
-/*  18 */   /* AML_ARG4 */                  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS,  "Arg4",               ARGP_ARG4,              ARGI_ARG4),
-/*  19 */   /* AML_ARG5 */                  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS,  "Arg5",               ARGP_ARG5,              ARGI_ARG5),
-/*  1_a */  /* AML_ARG6 */                  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS,  "Arg6",               ARGP_ARG6,              ARGI_ARG6),
-/*  1_b */  /* AML_STORE_OP */              OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "Store",              ARGP_STORE_OP,          ARGI_STORE_OP),
-/*  1_c */  /* AML_REF_OF_OP */             OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2|        AML_HAS_ARGS, "Ref_of",             ARGP_REF_OF_OP,         ARGI_REF_OF_OP),
-/*  1_d */  /* AML_ADD_OP */                OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "Add",                ARGP_ADD_OP,            ARGI_ADD_OP),
-/*  1_e */  /* AML_CONCAT_OP */             OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "Concatenate",        ARGP_CONCAT_OP,         ARGI_CONCAT_OP),
-/*  1_f */  /* AML_SUBTRACT_OP */           OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "Subtract",           ARGP_SUBTRACT_OP,       ARGI_SUBTRACT_OP),
-/*  20 */   /* AML_INCREMENT_OP */          OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2|        AML_HAS_ARGS, "Increment",          ARGP_INCREMENT_OP,      ARGI_INCREMENT_OP),
-/*  21 */   /* AML_DECREMENT_OP */          OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2|        AML_HAS_ARGS, "Decrement",          ARGP_DECREMENT_OP,      ARGI_DECREMENT_OP),
-/*  22 */   /* AML_MULTIPLY_OP */           OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "Multiply",           ARGP_MULTIPLY_OP,       ARGI_MULTIPLY_OP),
-/*  23 */   /* AML_DIVIDE_OP */             OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "Divide",             ARGP_DIVIDE_OP,         ARGI_DIVIDE_OP),
-/*  24 */   /* AML_SHIFT_LEFT_OP */         OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "Shift_left",         ARGP_SHIFT_LEFT_OP,     ARGI_SHIFT_LEFT_OP),
-/*  25 */   /* AML_SHIFT_RIGHT_OP */        OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "Shift_right",        ARGP_SHIFT_RIGHT_OP,    ARGI_SHIFT_RIGHT_OP),
-/*  26 */   /* AML_BIT_AND_OP */            OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "And",                ARGP_BIT_AND_OP,        ARGI_BIT_AND_OP),
-/*  27 */   /* AML_BIT_NAND_OP */           OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "NAnd",               ARGP_BIT_NAND_OP,       ARGI_BIT_NAND_OP),
-/*  28 */   /* AML_BIT_OR_OP */             OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "Or",                 ARGP_BIT_OR_OP,         ARGI_BIT_OR_OP),
-/*  29 */   /* AML_BIT_NOR_OP */            OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "NOr",                ARGP_BIT_NOR_OP,        ARGI_BIT_NOR_OP),
-/*  2_a */  /* AML_BIT_XOR_OP */            OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "XOr",                ARGP_BIT_XOR_OP,        ARGI_BIT_XOR_OP),
-/*  2_b */  /* AML_BIT_NOT_OP */            OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "Not",                ARGP_BIT_NOT_OP,        ARGI_BIT_NOT_OP),
+/*  00 */   /* AML_ZERO_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT|        AML_NO_ARGS,  "Zero",               ARGP_ZERO_OP,              ARGI_ZERO_OP),
+/*  01 */   /* AML_ONE_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT|        AML_NO_ARGS,  "One",                ARGP_ONE_OP,               ARGI_ONE_OP),
+/*  02 */   /* AML_ALIAS_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Alias",              ARGP_ALIAS_OP,             ARGI_ALIAS_OP),
+/*  03 */   /* AML_NAME_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Name",               ARGP_NAME_OP,              ARGI_NAME_OP),
+/*  04 */   /* AML_BYTE_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL|         AML_NO_ARGS,  "Byte_const",         ARGP_BYTE_OP,              ARGI_BYTE_OP),
+/*  05 */   /* AML_WORD_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL|         AML_NO_ARGS,  "Word_const",         ARGP_WORD_OP,              ARGI_WORD_OP),
+/*  06 */   /* AML_DWORD_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL|         AML_NO_ARGS,  "Dword_const",        ARGP_DWORD_OP,             ARGI_DWORD_OP),
+/*  07 */   /* AML_STRING_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL|         AML_NO_ARGS,  "String",             ARGP_STRING_OP,            ARGI_STRING_OP),
+/*  08 */   /* AML_SCOPE_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Scope",              ARGP_SCOPE_OP,             ARGI_SCOPE_OP),
+/*  09 */   /* AML_BUFFER_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DATA_TERM|       AML_HAS_ARGS, "Buffer",             ARGP_BUFFER_OP,            ARGI_BUFFER_OP),
+/*  0A */   /* AML_PACKAGE_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DATA_TERM|       AML_HAS_ARGS, "Package",            ARGP_PACKAGE_OP,           ARGI_PACKAGE_OP),
+/*  0B */   /* AML_METHOD_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Method",             ARGP_METHOD_OP,            ARGI_METHOD_OP),
+/*  0C */   /* AML_LOCAL0 */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE|  AML_NO_ARGS,  "Local0",             ARGP_LOCAL0,               ARGI_LOCAL0),
+/*  0D */   /* AML_LOCAL1 */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE|  AML_NO_ARGS,  "Local1",             ARGP_LOCAL1,               ARGI_LOCAL1),
+/*  0E */   /* AML_LOCAL2 */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE|  AML_NO_ARGS,  "Local2",             ARGP_LOCAL2,               ARGI_LOCAL2),
+/*  0F */   /* AML_LOCAL3 */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE|  AML_NO_ARGS,  "Local3",             ARGP_LOCAL3,               ARGI_LOCAL3),
+/*  10 */   /* AML_LOCAL4 */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE|  AML_NO_ARGS,  "Local4",             ARGP_LOCAL4,               ARGI_LOCAL4),
+/*  11 */   /* AML_LOCAL5 */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE|  AML_NO_ARGS,  "Local5",             ARGP_LOCAL5,               ARGI_LOCAL5),
+/*  12 */   /* AML_LOCAL6 */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE|  AML_NO_ARGS,  "Local6",             ARGP_LOCAL6,               ARGI_LOCAL6),
+/*  13 */   /* AML_LOCAL7 */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE|  AML_NO_ARGS,  "Local7",             ARGP_LOCAL7,               ARGI_LOCAL7),
+/*  14 */   /* AML_ARG0 */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS,  "Arg0",               ARGP_ARG0,                 ARGI_ARG0),
+/*  15 */   /* AML_ARG1 */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS,  "Arg1",               ARGP_ARG1,                 ARGI_ARG1),
+/*  16 */   /* AML_ARG2 */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS,  "Arg2",               ARGP_ARG2,                 ARGI_ARG2),
+/*  17 */   /* AML_ARG3 */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS,  "Arg3",               ARGP_ARG3,                 ARGI_ARG3),
+/*  18 */   /* AML_ARG4 */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS,  "Arg4",               ARGP_ARG4,                 ARGI_ARG4),
+/*  19 */   /* AML_ARG5 */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS,  "Arg5",               ARGP_ARG5,                 ARGI_ARG5),
+/*  1_a */  /* AML_ARG6 */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS,  "Arg6",               ARGP_ARG6,                 ARGI_ARG6),
+/*  1_b */  /* AML_STORE_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "Store",              ARGP_STORE_OP,             ARGI_STORE_OP),
+/*  1_c */  /* AML_REF_OF_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2|        AML_HAS_ARGS, "Ref_of",             ARGP_REF_OF_OP,            ARGI_REF_OF_OP),
+/*  1_d */  /* AML_ADD_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "Add",                ARGP_ADD_OP,               ARGI_ADD_OP),
+/*  1_e */  /* AML_CONCAT_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "Concatenate",        ARGP_CONCAT_OP,            ARGI_CONCAT_OP),
+/*  1_f */  /* AML_SUBTRACT_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "Subtract",           ARGP_SUBTRACT_OP,          ARGI_SUBTRACT_OP),
+/*  20 */   /* AML_INCREMENT_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2|        AML_HAS_ARGS, "Increment",          ARGP_INCREMENT_OP,         ARGI_INCREMENT_OP),
+/*  21 */   /* AML_DECREMENT_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2|        AML_HAS_ARGS, "Decrement",          ARGP_DECREMENT_OP,         ARGI_DECREMENT_OP),
+/*  22 */   /* AML_MULTIPLY_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "Multiply",           ARGP_MULTIPLY_OP,          ARGI_MULTIPLY_OP),
+/*  23 */   /* AML_DIVIDE_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "Divide",             ARGP_DIVIDE_OP,            ARGI_DIVIDE_OP),
+/*  24 */   /* AML_SHIFT_LEFT_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "Shift_left",         ARGP_SHIFT_LEFT_OP,        ARGI_SHIFT_LEFT_OP),
+/*  25 */   /* AML_SHIFT_RIGHT_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "Shift_right",        ARGP_SHIFT_RIGHT_OP,       ARGI_SHIFT_RIGHT_OP),
+/*  26 */   /* AML_BIT_AND_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "And",                ARGP_BIT_AND_OP,           ARGI_BIT_AND_OP),
+/*  27 */   /* AML_BIT_NAND_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "NAnd",               ARGP_BIT_NAND_OP,          ARGI_BIT_NAND_OP),
+/*  28 */   /* AML_BIT_OR_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "Or",                 ARGP_BIT_OR_OP,            ARGI_BIT_OR_OP),
+/*  29 */   /* AML_BIT_NOR_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "NOr",                ARGP_BIT_NOR_OP,           ARGI_BIT_NOR_OP),
+/*  2_a */  /* AML_BIT_XOR_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "XOr",                ARGP_BIT_XOR_OP,           ARGI_BIT_XOR_OP),
+/*  2_b */  /* AML_BIT_NOT_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "Not",                ARGP_BIT_NOT_OP,           ARGI_BIT_NOT_OP),
 /*  2_c */  /* AML_FIND_SET_LEFT_BIT_OP */  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "Find_set_left_bit",  ARGP_FIND_SET_LEFT_BIT_OP, ARGI_FIND_SET_LEFT_BIT_OP),
-/*  2_d */  /* AML_FIND_SET_RIGHT_BIT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "Find_set_right_bit", ARGP_FIND_SET_RIGHT_BIT_OP, ARGI_FIND_SET_RIGHT_BIT_OP),
-/*  2_e */  /* AML_DEREF_OF_OP */           OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2|        AML_HAS_ARGS, "Deref_of",           ARGP_DEREF_OF_OP,       ARGI_DEREF_OF_OP),
-/*  2_f */  /* AML_NOTIFY_OP */             OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC1|         AML_HAS_ARGS, "Notify",             ARGP_NOTIFY_OP,         ARGI_NOTIFY_OP),
-/*  30 */   /* AML_SIZE_OF_OP */            OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2|        AML_HAS_ARGS, "Size_of",            ARGP_SIZE_OF_OP,        ARGI_SIZE_OF_OP),
-/*  31 */   /* AML_INDEX_OP */              OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_INDEX|           AML_HAS_ARGS, "Index",              ARGP_INDEX_OP,          ARGI_INDEX_OP),
-/*  32 */   /* AML_MATCH_OP */              OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MATCH|           AML_HAS_ARGS, "Match",              ARGP_MATCH_OP,          ARGI_MATCH_OP),
-/*  33 */   /* AML_DWORD_FIELD_OP */        OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CREATE_FIELD|    AML_HAS_ARGS, "Create_dWord_field", ARGP_DWORD_FIELD_OP,    ARGI_DWORD_FIELD_OP),
-/*  34 */   /* AML_WORD_FIELD_OP */         OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CREATE_FIELD|    AML_HAS_ARGS, "Create_word_field",  ARGP_WORD_FIELD_OP,     ARGI_WORD_FIELD_OP),
-/*  35 */   /* AML_BYTE_FIELD_OP */         OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CREATE_FIELD|    AML_HAS_ARGS, "Create_byte_field",  ARGP_BYTE_FIELD_OP,     ARGI_BYTE_FIELD_OP),
-/*  36 */   /* AML_BIT_FIELD_OP */          OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CREATE_FIELD|    AML_HAS_ARGS, "Create_bit_field",   ARGP_BIT_FIELD_OP,      ARGI_BIT_FIELD_OP),
-/*  37 */   /* AML_TYPE_OP */               OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2|        AML_HAS_ARGS, "Object_type",        ARGP_TYPE_OP,           ARGI_TYPE_OP),
-/*  38 */   /* AML_LAND_OP */               OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2|         AML_HAS_ARGS, "LAnd",               ARGP_LAND_OP,           ARGI_LAND_OP),
-/*  39 */   /* AML_LOR_OP */                OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2|         AML_HAS_ARGS, "LOr",                ARGP_LOR_OP,            ARGI_LOR_OP),
-/*  3_a */  /* AML_LNOT_OP */               OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2|        AML_HAS_ARGS, "LNot",               ARGP_LNOT_OP,           ARGI_LNOT_OP),
-/*  3_b */  /* AML_LEQUAL_OP */             OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2|         AML_HAS_ARGS, "LEqual",             ARGP_LEQUAL_OP,         ARGI_LEQUAL_OP),
-/*  3_c */  /* AML_LGREATER_OP */           OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2|         AML_HAS_ARGS, "LGreater",           ARGP_LGREATER_OP,       ARGI_LGREATER_OP),
-/*  3_d */  /* AML_LLESS_OP */              OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2|         AML_HAS_ARGS, "LLess",              ARGP_LLESS_OP,          ARGI_LLESS_OP),
-/*  3_e */  /* AML_IF_OP */                 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL|         AML_HAS_ARGS, "If",                 ARGP_IF_OP,             ARGI_IF_OP),
-/*  3_f */  /* AML_ELSE_OP */               OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL|         AML_HAS_ARGS, "Else",               ARGP_ELSE_OP,           ARGI_ELSE_OP),
-/*  40 */   /* AML_WHILE_OP */              OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL|         AML_HAS_ARGS, "While",              ARGP_WHILE_OP,          ARGI_WHILE_OP),
-/*  41 */   /* AML_NOOP_OP   */             OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL|         AML_NO_ARGS,  "Noop",               ARGP_NOOP_OP,           ARGI_NOOP_OP),
-/*  42 */   /* AML_RETURN_OP */             OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL|         AML_HAS_ARGS, "Return",             ARGP_RETURN_OP,         ARGI_RETURN_OP),
-/*  43 */   /* AML_BREAK_OP */              OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL|         AML_NO_ARGS,  "Break",              ARGP_BREAK_OP,          ARGI_BREAK_OP),
-/*  44 */   /* AML_BREAK_POINT_OP */        OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL|         AML_NO_ARGS,  "Break_point",        ARGP_BREAK_POINT_OP,    ARGI_BREAK_POINT_OP),
-/*  45 */   /* AML_ONES_OP */               OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT|        AML_NO_ARGS,  "Ones",               ARGP_ONES_OP,           ARGI_ONES_OP),
+/*  2_d */  /* AML_FIND_SET_RIGHT_BIT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "Find_set_right_bit", ARGP_FIND_SET_RIGHT_BIT_OP,ARGI_FIND_SET_RIGHT_BIT_OP),
+/*  2_e */  /* AML_DEREF_OF_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2|        AML_HAS_ARGS, "Deref_of",           ARGP_DEREF_OF_OP,          ARGI_DEREF_OF_OP),
+/*  2_f */  /* AML_NOTIFY_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC1|         AML_HAS_ARGS, "Notify",             ARGP_NOTIFY_OP,            ARGI_NOTIFY_OP),
+/*  30 */   /* AML_SIZE_OF_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2|        AML_HAS_ARGS, "Size_of",            ARGP_SIZE_OF_OP,           ARGI_SIZE_OF_OP),
+/*  31 */   /* AML_INDEX_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_INDEX|           AML_HAS_ARGS, "Index",              ARGP_INDEX_OP,             ARGI_INDEX_OP),
+/*  32 */   /* AML_MATCH_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MATCH|           AML_HAS_ARGS, "Match",              ARGP_MATCH_OP,             ARGI_MATCH_OP),
+/*  33 */   /* AML_CREATE_DWORD_FIELD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CREATE_FIELD|    AML_HAS_ARGS, "Create_dWord_field", ARGP_CREATE_DWORD_FIELD_OP,ARGI_CREATE_DWORD_FIELD_OP),
+/*  34 */   /* AML_CREATE_WORD_FIELD_OP */  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CREATE_FIELD|    AML_HAS_ARGS, "Create_word_field",  ARGP_CREATE_WORD_FIELD_OP, ARGI_CREATE_WORD_FIELD_OP),
+/*  35 */   /* AML_CREATE_BYTE_FIELD_OP */  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CREATE_FIELD|    AML_HAS_ARGS, "Create_byte_field",  ARGP_CREATE_BYTE_FIELD_OP, ARGI_CREATE_BYTE_FIELD_OP),
+/*  36 */   /* AML_CREATE_BIT_FIELD_OP */   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CREATE_FIELD|    AML_HAS_ARGS, "Create_bit_field",   ARGP_CREATE_BIT_FIELD_OP,  ARGI_CREATE_BIT_FIELD_OP),
+/*  37 */   /* AML_TYPE_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2|        AML_HAS_ARGS, "Object_type",        ARGP_TYPE_OP,              ARGI_TYPE_OP),
+/*  38 */   /* AML_LAND_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2|         AML_HAS_ARGS, "LAnd",               ARGP_LAND_OP,              ARGI_LAND_OP),
+/*  39 */   /* AML_LOR_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2|         AML_HAS_ARGS, "LOr",                ARGP_LOR_OP,               ARGI_LOR_OP),
+/*  3_a */  /* AML_LNOT_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2|        AML_HAS_ARGS, "LNot",               ARGP_LNOT_OP,              ARGI_LNOT_OP),
+/*  3_b */  /* AML_LEQUAL_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2|         AML_HAS_ARGS, "LEqual",             ARGP_LEQUAL_OP,            ARGI_LEQUAL_OP),
+/*  3_c */  /* AML_LGREATER_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2|         AML_HAS_ARGS, "LGreater",           ARGP_LGREATER_OP,          ARGI_LGREATER_OP),
+/*  3_d */  /* AML_LLESS_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2|         AML_HAS_ARGS, "LLess",              ARGP_LLESS_OP,             ARGI_LLESS_OP),
+/*  3_e */  /* AML_IF_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL|         AML_HAS_ARGS, "If",                 ARGP_IF_OP,                ARGI_IF_OP),
+/*  3_f */  /* AML_ELSE_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL|         AML_HAS_ARGS, "Else",               ARGP_ELSE_OP,              ARGI_ELSE_OP),
+/*  40 */   /* AML_WHILE_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL|         AML_HAS_ARGS, "While",              ARGP_WHILE_OP,             ARGI_WHILE_OP),
+/*  41 */   /* AML_NOOP_OP   */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL|         AML_NO_ARGS,  "Noop",               ARGP_NOOP_OP,              ARGI_NOOP_OP),
+/*  42 */   /* AML_RETURN_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL|         AML_HAS_ARGS, "Return",             ARGP_RETURN_OP,            ARGI_RETURN_OP),
+/*  43 */   /* AML_BREAK_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL|         AML_NO_ARGS,  "Break",              ARGP_BREAK_OP,             ARGI_BREAK_OP),
+/*  44 */   /* AML_BREAK_POINT_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL|         AML_NO_ARGS,  "Break_point",        ARGP_BREAK_POINT_OP,       ARGI_BREAK_POINT_OP),
+/*  45 */   /* AML_ONES_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT|        AML_NO_ARGS,  "Ones",               ARGP_ONES_OP,              ARGI_ONES_OP),
 
 /* Prefixed opcodes (Two-byte opcodes with a prefix op) */
 
-/*  46 */   /* AML_MUTEX_OP */              OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Mutex",              ARGP_MUTEX_OP,          ARGI_MUTEX_OP),
-/*  47 */   /* AML_EVENT_OP */              OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_NO_ARGS,  "Event",              ARGP_EVENT_OP,          ARGI_EVENT_OP),
-/*  48 */   /* AML_COND_REF_OF_OP */        OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "Cond_ref_of",        ARGP_COND_REF_OF_OP,    ARGI_COND_REF_OF_OP),
-/*  49 */   /* AML_CREATE_FIELD_OP */       OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CREATE_FIELD|    AML_HAS_ARGS, "Create_field",       ARGP_CREATE_FIELD_OP,   ARGI_CREATE_FIELD_OP),
-/*  4_a */  /* AML_LOAD_OP */               OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_RECONFIGURATION| AML_HAS_ARGS, "Load",               ARGP_LOAD_OP,           ARGI_LOAD_OP),
-/*  4_b */  /* AML_STALL_OP */              OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC1|        AML_HAS_ARGS, "Stall",              ARGP_STALL_OP,          ARGI_STALL_OP),
-/*  4_c */  /* AML_SLEEP_OP */              OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC1|        AML_HAS_ARGS, "Sleep",              ARGP_SLEEP_OP,          ARGI_SLEEP_OP),
-/*  4_d */  /* AML_ACQUIRE_OP */            OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_s|       AML_HAS_ARGS, "Acquire",            ARGP_ACQUIRE_OP,        ARGI_ACQUIRE_OP),
-/*  4_e */  /* AML_SIGNAL_OP */             OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC1|        AML_HAS_ARGS, "Signal",             ARGP_SIGNAL_OP,         ARGI_SIGNAL_OP),
-/*  4_f */  /* AML_WAIT_OP */               OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_s|       AML_HAS_ARGS, "Wait",               ARGP_WAIT_OP,           ARGI_WAIT_OP),
-/*  50 */   /* AML_RESET_OP */              OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC1|        AML_HAS_ARGS, "Reset",              ARGP_RESET_OP,          ARGI_RESET_OP),
-/*  51 */   /* AML_RELEASE_OP */            OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC1|        AML_HAS_ARGS, "Release",            ARGP_RELEASE_OP,        ARGI_RELEASE_OP),
-/*  52 */   /* AML_FROM_BCD_OP */           OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "From_bCD",           ARGP_FROM_BCD_OP,       ARGI_FROM_BCD_OP),
-/*  53 */   /* AML_TO_BCD_OP */             OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "To_bCD",             ARGP_TO_BCD_OP,         ARGI_TO_BCD_OP),
-/*  54 */   /* AML_UNLOAD_OP */             OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_RECONFIGURATION| AML_HAS_ARGS, "Unload",             ARGP_UNLOAD_OP,         ARGI_UNLOAD_OP),
-/*  55 */   /* AML_REVISION_OP */           OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT|        AML_NO_ARGS,  "Revision",           ARGP_REVISION_OP,       ARGI_REVISION_OP),
-/*  56 */   /* AML_DEBUG_OP */              OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT|        AML_NO_ARGS,  "Debug",              ARGP_DEBUG_OP,          ARGI_DEBUG_OP),
-/*  57 */   /* AML_FATAL_OP */              OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_FATAL|           AML_HAS_ARGS, "Fatal",              ARGP_FATAL_OP,          ARGI_FATAL_OP),
-/*  58 */   /* AML_REGION_OP */             OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Op_region",          ARGP_REGION_OP,         ARGI_REGION_OP),
-/*  59 */   /* AML_DEF_FIELD_OP */          OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Field",              ARGP_DEF_FIELD_OP,      ARGI_DEF_FIELD_OP),
-/*  5_a */  /* AML_DEVICE_OP */             OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Device",             ARGP_DEVICE_OP,         ARGI_DEVICE_OP),
-/*  5_b */  /* AML_PROCESSOR_OP */          OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Processor",          ARGP_PROCESSOR_OP,      ARGI_PROCESSOR_OP),
-/*  5_c */  /* AML_POWER_RES_OP */          OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Power_resource",     ARGP_POWER_RES_OP,      ARGI_POWER_RES_OP),
-/*  5_d */  /* AML_THERMAL_ZONE_OP */       OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Thermal_zone",       ARGP_THERMAL_ZONE_OP,   ARGI_THERMAL_ZONE_OP),
-/*  5_e */  /* AML_INDEX_FIELD_OP */        OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Index_field",        ARGP_INDEX_FIELD_OP,    ARGI_INDEX_FIELD_OP),
-/*  5_f */  /* AML_BANK_FIELD_OP */         OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Bank_field",         ARGP_BANK_FIELD_OP,     ARGI_BANK_FIELD_OP),
+/*  46 */   /* AML_MUTEX_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Mutex",              ARGP_MUTEX_OP,             ARGI_MUTEX_OP),
+/*  47 */   /* AML_EVENT_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_NO_ARGS,  "Event",              ARGP_EVENT_OP,             ARGI_EVENT_OP),
+/*  48 */   /* AML_COND_REF_OF_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "Cond_ref_of",        ARGP_COND_REF_OF_OP,       ARGI_COND_REF_OF_OP),
+/*  49 */   /* AML_CREATE_FIELD_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CREATE_FIELD|    AML_HAS_ARGS, "Create_field",       ARGP_CREATE_FIELD_OP,      ARGI_CREATE_FIELD_OP),
+/*  4_a */  /* AML_LOAD_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_RECONFIGURATION| AML_HAS_ARGS, "Load",               ARGP_LOAD_OP,              ARGI_LOAD_OP),
+/*  4_b */  /* AML_STALL_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC1|        AML_HAS_ARGS, "Stall",              ARGP_STALL_OP,             ARGI_STALL_OP),
+/*  4_c */  /* AML_SLEEP_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC1|        AML_HAS_ARGS, "Sleep",              ARGP_SLEEP_OP,             ARGI_SLEEP_OP),
+/*  4_d */  /* AML_ACQUIRE_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_s|       AML_HAS_ARGS, "Acquire",            ARGP_ACQUIRE_OP,           ARGI_ACQUIRE_OP),
+/*  4_e */  /* AML_SIGNAL_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC1|        AML_HAS_ARGS, "Signal",             ARGP_SIGNAL_OP,            ARGI_SIGNAL_OP),
+/*  4_f */  /* AML_WAIT_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_s|       AML_HAS_ARGS, "Wait",               ARGP_WAIT_OP,              ARGI_WAIT_OP),
+/*  50 */   /* AML_RESET_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC1|        AML_HAS_ARGS, "Reset",              ARGP_RESET_OP,             ARGI_RESET_OP),
+/*  51 */   /* AML_RELEASE_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC1|        AML_HAS_ARGS, "Release",            ARGP_RELEASE_OP,           ARGI_RELEASE_OP),
+/*  52 */   /* AML_FROM_BCD_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "From_bCD",           ARGP_FROM_BCD_OP,          ARGI_FROM_BCD_OP),
+/*  53 */   /* AML_TO_BCD_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "To_bCD",             ARGP_TO_BCD_OP,            ARGI_TO_BCD_OP),
+/*  54 */   /* AML_UNLOAD_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_RECONFIGURATION| AML_HAS_ARGS, "Unload",             ARGP_UNLOAD_OP,            ARGI_UNLOAD_OP),
+/*  55 */   /* AML_REVISION_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT|        AML_NO_ARGS,  "Revision",           ARGP_REVISION_OP,          ARGI_REVISION_OP),
+/*  56 */   /* AML_DEBUG_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT|        AML_NO_ARGS,  "Debug",              ARGP_DEBUG_OP,             ARGI_DEBUG_OP),
+/*  57 */   /* AML_FATAL_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_FATAL|           AML_HAS_ARGS, "Fatal",              ARGP_FATAL_OP,             ARGI_FATAL_OP),
+/*  58 */   /* AML_REGION_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Op_region",          ARGP_REGION_OP,            ARGI_REGION_OP),
+/*  59 */   /* AML_FIELD_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Field",              ARGP_FIELD_OP,             ARGI_FIELD_OP),
+/*  5_a */  /* AML_DEVICE_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Device",             ARGP_DEVICE_OP,            ARGI_DEVICE_OP),
+/*  5_b */  /* AML_PROCESSOR_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Processor",          ARGP_PROCESSOR_OP,         ARGI_PROCESSOR_OP),
+/*  5_c */  /* AML_POWER_RES_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Power_resource",     ARGP_POWER_RES_OP,         ARGI_POWER_RES_OP),
+/*  5_d */  /* AML_THERMAL_ZONE_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Thermal_zone",       ARGP_THERMAL_ZONE_OP,      ARGI_THERMAL_ZONE_OP),
+/*  5_e */  /* AML_INDEX_FIELD_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Index_field",        ARGP_INDEX_FIELD_OP,       ARGI_INDEX_FIELD_OP),
+/*  5_f */  /* AML_BANK_FIELD_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT|    AML_HAS_ARGS, "Bank_field",         ARGP_BANK_FIELD_OP,        ARGI_BANK_FIELD_OP),
 
 /* Internal opcodes that map to invalid AML opcodes */
 
-/*  60 */   /* AML_LNOTEQUAL_OP */          OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS|           AML_HAS_ARGS, "LNot_equal",         ARGP_LNOTEQUAL_OP,      ARGI_LNOTEQUAL_OP),
-/*  61 */   /* AML_LLESSEQUAL_OP */         OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS|           AML_HAS_ARGS, "LLess_equal",        ARGP_LLESSEQUAL_OP,     ARGI_LLESSEQUAL_OP),
-/*  62 */   /* AML_LGREATEREQUAL_OP */      OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS|           AML_HAS_ARGS, "LGreater_equal",     ARGP_LGREATEREQUAL_OP,  ARGI_LGREATEREQUAL_OP),
-/*  63 */   /* AML_NAMEPATH_OP */           OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL|         AML_NO_ARGS,  "Name_path",          ARGP_NAMEPATH_OP,       ARGI_NAMEPATH_OP),
-/*  64 */   /* AML_METHODCALL_OP */         OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_CALL|     AML_HAS_ARGS, "Method_call",        ARGP_METHODCALL_OP,     ARGI_METHODCALL_OP),
-/*  65 */   /* AML_BYTELIST_OP */           OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL|         AML_NO_ARGS,  "Byte_list",          ARGP_BYTELIST_OP,       ARGI_BYTELIST_OP),
-/*  66 */   /* AML_RESERVEDFIELD_OP */      OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS|           AML_NO_ARGS,  "Reserved_field",     ARGP_RESERVEDFIELD_OP,  ARGI_RESERVEDFIELD_OP),
-/*  67 */   /* AML_NAMEDFIELD_OP */         OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS|           AML_NO_ARGS,  "Named_field",        ARGP_NAMEDFIELD_OP,     ARGI_NAMEDFIELD_OP),
-/*  68 */   /* AML_ACCESSFIELD_OP */        OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS|           AML_NO_ARGS,  "Access_field",       ARGP_ACCESSFIELD_OP,    ARGI_ACCESSFIELD_OP),
-/*  69 */   /* AML_STATICSTRING_OP */       OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS|           AML_NO_ARGS,  "Static_string",      ARGP_STATICSTRING_OP,   ARGI_STATICSTRING_OP),
-/*  6_a */  /* AML_RETURN_VALUE_OP */       OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_RETURN|          AML_HAS_ARGS, "[Return Value]",     ARG_NONE,               ARG_NONE),
-/*  6_b */  /* UNKNOWN OPCODES */           OP_INFO_ENTRY (ACPI_OP_TYPE_UNKNOWN | OPTYPE_BOGUS|          AML_HAS_ARGS, "UNKNOWN_OP!",        ARG_NONE,               ARG_NONE),
-/*  6_c */  /* ASCII CHARACTERS */          OP_INFO_ENTRY (ACPI_OP_TYPE_ASCII  | OPTYPE_BOGUS|           AML_HAS_ARGS, "ASCII_ONLY!",        ARG_NONE,               ARG_NONE),
-/*  6_d */  /* PREFIX CHARACTERS */         OP_INFO_ENTRY (ACPI_OP_TYPE_PREFIX | OPTYPE_BOGUS|           AML_HAS_ARGS, "PREFIX_ONLY!",       ARG_NONE,               ARG_NONE),
+/*  60 */   /* AML_LNOTEQUAL_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS|           AML_HAS_ARGS, "LNot_equal",         ARGP_LNOTEQUAL_OP,         ARGI_LNOTEQUAL_OP),
+/*  61 */   /* AML_LLESSEQUAL_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS|           AML_HAS_ARGS, "LLess_equal",        ARGP_LLESSEQUAL_OP,        ARGI_LLESSEQUAL_OP),
+/*  62 */   /* AML_LGREATEREQUAL_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS|           AML_HAS_ARGS, "LGreater_equal",     ARGP_LGREATEREQUAL_OP,     ARGI_LGREATEREQUAL_OP),
+/*  63 */   /* AML_INT_NAMEPATH_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL|         AML_NO_ARGS,  "Name_path",          ARGP_NAMEPATH_OP,          ARGI_NAMEPATH_OP),
+/*  64 */   /* AML_INT_METHODCALL_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_CALL|     AML_HAS_ARGS, "Method_call",        ARGP_METHODCALL_OP,        ARGI_METHODCALL_OP),
+/*  65 */   /* AML_INT_BYTELIST_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL|         AML_NO_ARGS,  "Byte_list",          ARGP_BYTELIST_OP,          ARGI_BYTELIST_OP),
+/*  66 */   /* AML_INT_RESERVEDFIELD_OP */  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS|           AML_NO_ARGS,  "Reserved_field",     ARGP_RESERVEDFIELD_OP,     ARGI_RESERVEDFIELD_OP),
+/*  67 */   /* AML_INT_NAMEDFIELD_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS|           AML_NO_ARGS,  "Named_field",        ARGP_NAMEDFIELD_OP,        ARGI_NAMEDFIELD_OP),
+/*  68 */   /* AML_INT_ACCESSFIELD_OP */	OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS|           AML_NO_ARGS,  "Access_field",       ARGP_ACCESSFIELD_OP,       ARGI_ACCESSFIELD_OP),
+/*  69 */   /* AML_INT_STATICSTRING_OP */   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS|           AML_NO_ARGS,  "Static_string",      ARGP_STATICSTRING_OP,      ARGI_STATICSTRING_OP),
+/*  6_a */  /* AML_INT_RETURN_VALUE_OP */   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_RETURN|          AML_HAS_ARGS, "[Return Value]",     ARG_NONE,                  ARG_NONE),
+/*  6_b */  /* UNKNOWN OPCODES */	 OP_INFO_ENTRY (ACPI_OP_TYPE_UNKNOWN | OPTYPE_BOGUS|          AML_HAS_ARGS, "UNKNOWN_OP!",        ARG_NONE,                  ARG_NONE),
+/*  6_c */  /* ASCII CHARACTERS */	   OP_INFO_ENTRY (ACPI_OP_TYPE_ASCII  | OPTYPE_BOGUS|           AML_HAS_ARGS, "ASCII_ONLY!",        ARG_NONE,                  ARG_NONE),
+/*  6_d */  /* PREFIX CHARACTERS */	  OP_INFO_ENTRY (ACPI_OP_TYPE_PREFIX | OPTYPE_BOGUS|           AML_HAS_ARGS, "PREFIX_ONLY!",       ARG_NONE,                  ARG_NONE),
 
 
 /* ACPI 2.0 (new) opcodes */
 
-/*  6_e */  /* AML_QWORD_OP */              OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL|         AML_NO_ARGS,  "Qword_const",        ARGP_QWORD_OP,          ARGI_QWORD_OP),
-/*  6_f */  /* AML_VAR_PACKAGE_OP */        OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DATA_TERM|       AML_HAS_ARGS, "Var_package",        ARGP_VAR_PACKAGE_OP,    ARGI_VAR_PACKAGE_OP),
-/*  70 */   /* AML_CONCAT_RES_OP */         OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "Concat_res",         ARGP_CONCAT_RES_OP,     ARGI_CONCAT_RES_OP),
-/*  71 */   /* AML_MOD_OP */                OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "Mod",                ARGP_MOD_OP,            ARGI_MOD_OP),
-/*  72 */   /* AML_QWORD_FIELD_OP */        OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CREATE_FIELD|    AML_HAS_ARGS, "Create_qWord_field", ARGP_QWORD_FIELD_OP,    ARGI_QWORD_FIELD_OP),
-/*  73 */   /* AML_TO_BUFFER_OP */          OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "To_buffer",          ARGP_TO_BUFFER_OP,      ARGI_TO_BUFFER_OP),
-/*  74 */   /* AML_TO_DEC_STR_OP */         OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "To_dec_string",      ARGP_TO_DEC_STR_OP,     ARGI_TO_DEC_STR_OP),
-/*  75 */   /* AML_TO_HEX_STR_OP */         OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "To_hex_string",      ARGP_TO_HEX_STR_OP,     ARGI_TO_HEX_STR_OP),
-/*  76 */   /* AML_TO_INTEGER_OP */         OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "To_integer",         ARGP_TO_INTEGER_OP,     ARGI_TO_INTEGER_OP),
-/*  77 */   /* AML_TO_STRING_OP */          OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "To_string",          ARGP_TO_STRING_OP,      ARGI_TO_STRING_OP),
-/*  78 */   /* AML_COPY_OP */               OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "Copy",               ARGP_COPY_OP,           ARGI_COPY_OP),
-/*  79 */   /* AML_MID_OP */                OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "Mid",                ARGP_MID_OP,            ARGI_MID_OP),
-/*  7_a */  /* AML_CONTINUE_OP */           OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL|         AML_NO_ARGS,  "Continue",           ARGP_CONTINUE_OP,       ARGI_CONTINUE_OP),
-/*  7_b */  /* AML_LOAD_TABLE_OP */         OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "Load_table",         ARGP_LOAD_TABLE_OP,     ARGI_LOAD_TABLE_OP),
-/*  7_c */  /* AML_DATA_REGION_OP */        OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "Data_op_region",     ARGP_DATA_REGION_OP,    ARGI_DATA_REGION_OP),
+/*  6_e */  /* AML_QWORD_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL|         AML_NO_ARGS,  "Qword_const",        ARGP_QWORD_OP,             ARGI_QWORD_OP),
+/*  6_f */  /* AML_VAR_PACKAGE_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DATA_TERM|       AML_HAS_ARGS, "Var_package",        ARGP_VAR_PACKAGE_OP,       ARGI_VAR_PACKAGE_OP),
+/*  70 */   /* AML_CONCAT_RES_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "Concat_res",         ARGP_CONCAT_RES_OP,        ARGI_CONCAT_RES_OP),
+/*  71 */   /* AML_MOD_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r|       AML_HAS_ARGS, "Mod",                ARGP_MOD_OP,               ARGI_MOD_OP),
+/*  72 */   /* AML_CREATE_QWORD_FIELD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CREATE_FIELD|    AML_HAS_ARGS, "Create_qWord_field", ARGP_CREATE_QWORD_FIELD_OP,ARGI_CREATE_QWORD_FIELD_OP),
+/*  73 */   /* AML_TO_BUFFER_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "To_buffer",          ARGP_TO_BUFFER_OP,         ARGI_TO_BUFFER_OP),
+/*  74 */   /* AML_TO_DEC_STR_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "To_dec_string",      ARGP_TO_DEC_STR_OP,        ARGI_TO_DEC_STR_OP),
+/*  75 */   /* AML_TO_HEX_STR_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "To_hex_string",      ARGP_TO_HEX_STR_OP,        ARGI_TO_HEX_STR_OP),
+/*  76 */   /* AML_TO_INTEGER_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "To_integer",         ARGP_TO_INTEGER_OP,        ARGI_TO_INTEGER_OP),
+/*  77 */   /* AML_TO_STRING_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "To_string",          ARGP_TO_STRING_OP,         ARGI_TO_STRING_OP),
+/*  78 */   /* AML_COPY_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "Copy_object",        ARGP_COPY_OP,              ARGI_COPY_OP),
+/*  79 */   /* AML_MID_OP */	   OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "Mid",                ARGP_MID_OP,               ARGI_MID_OP),
+/*  7_a */  /* AML_CONTINUE_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL|         AML_NO_ARGS,  "Continue",           ARGP_CONTINUE_OP,          ARGI_CONTINUE_OP),
+/*  7_b */  /* AML_LOAD_TABLE_OP */	  OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "Load_table",         ARGP_LOAD_TABLE_OP,        ARGI_LOAD_TABLE_OP),
+/*  7_c */  /* AML_DATA_REGION_OP */	 OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r|      AML_HAS_ARGS, "Data_op_region",     ARGP_DATA_REGION_OP,       ARGI_DATA_REGION_OP),
 
 };
 
@@ -484,38 +484,38 @@
 {
 /*              0     1     2     3     4     5     6     7  */
 /*              8     9     A     B     C     D     E     F  */
-/* 0x00 */    0x00, 0x01, _UNK, _UNK, _UNK, _UNK, 0x02, _UNK,
-/* 0x08 */    0x03, _UNK, 0x04, 0x05, 0x06, 0x07, 0x6E, _UNK,
-/* 0x10 */    0x08, 0x09, 0x0a, 0x6F, 0x0b, _UNK, _UNK, _UNK,
-/* 0x18 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x20 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x28 */    _UNK, _UNK, _UNK, _UNK, _UNK, 0x63, _PFX, _PFX,
-/* 0x30 */    0x67, 0x66, 0x68, 0x65, 0x69, 0x64, 0x6A, _UNK,
-/* 0x38 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x40 */    _UNK, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
-/* 0x48 */    _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
-/* 0x50 */    _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
-/* 0x58 */    _ASC, _ASC, _ASC, _UNK, _PFX, _UNK, _PFX, _ASC,
-/* 0x60 */    0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
-/* 0x68 */    0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, _UNK,
-/* 0x70 */    0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22,
-/* 0x78 */    0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
-/* 0x80 */    0x2b, 0x2c, 0x2d, 0x2e, 0x70, 0x71, 0x2f, 0x30,
-/* 0x88 */    0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x72,
-/* 0x90 */    0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x73, 0x74,
-/* 0x98 */    0x75, 0x76, _UNK, _UNK, 0x77, 0x78, 0x79, 0x7A,
-/* 0xA0 */    0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x60, 0x61,
-/* 0xA8 */    0x62, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xB0 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xB8 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xC0 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xC8 */    _UNK, _UNK, _UNK, _UNK, 0x44, _UNK, _UNK, _UNK,
-/* 0xD0 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xD8 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xE0 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xE8 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xF0 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xF8 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x45,
+/* 0x00 */	0x00, 0x01, _UNK, _UNK, _UNK, _UNK, 0x02, _UNK,
+/* 0x08 */	0x03, _UNK, 0x04, 0x05, 0x06, 0x07, 0x6E, _UNK,
+/* 0x10 */	0x08, 0x09, 0x0a, 0x6F, 0x0b, _UNK, _UNK, _UNK,
+/* 0x18 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x20 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x28 */	_UNK, _UNK, _UNK, _UNK, _UNK, 0x63, _PFX, _PFX,
+/* 0x30 */	0x67, 0x66, 0x68, 0x65, 0x69, 0x64, 0x6A, _UNK,
+/* 0x38 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x40 */	_UNK, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
+/* 0x48 */	_ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
+/* 0x50 */	_ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
+/* 0x58 */	_ASC, _ASC, _ASC, _UNK, _PFX, _UNK, _PFX, _ASC,
+/* 0x60 */	0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
+/* 0x68 */	0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, _UNK,
+/* 0x70 */	0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22,
+/* 0x78 */	0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
+/* 0x80 */	0x2b, 0x2c, 0x2d, 0x2e, 0x70, 0x71, 0x2f, 0x30,
+/* 0x88 */	0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x72,
+/* 0x90 */	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x73, 0x74,
+/* 0x98 */	0x75, 0x76, _UNK, _UNK, 0x77, 0x78, 0x79, 0x7A,
+/* 0xA0 */	0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x60, 0x61,
+/* 0xA8 */	0x62, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xB0 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xB8 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xC0 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xC8 */	_UNK, _UNK, _UNK, _UNK, 0x44, _UNK, _UNK, _UNK,
+/* 0xD0 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xD8 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xE0 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xE8 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xF0 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xF8 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x45,
 };
 
 
@@ -523,24 +523,24 @@
 {
 /*              0     1     2     3     4     5     6     7  */
 /*              8     9     A     B     C     D     E     F  */
-/* 0x00 */    _UNK, 0x46, 0x47, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x08 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x10 */    _UNK, _UNK, 0x48, 0x49, _UNK, _UNK, _UNK, _UNK,
-/* 0x18 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x7B,
-/* 0x20 */    0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
-/* 0x28 */    0x52, 0x53, 0x54, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x30 */    0x55, 0x56, 0x57, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x38 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x40 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x48 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x50 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x58 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x60 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x68 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x70 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x78 */    _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x80 */    0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
-/* 0x88 */    0x7C,
+/* 0x00 */	_UNK, 0x46, 0x47, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x08 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x10 */	_UNK, _UNK, 0x48, 0x49, _UNK, _UNK, _UNK, _UNK,
+/* 0x18 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x7B,
+/* 0x20 */	0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
+/* 0x28 */	0x52, 0x53, 0x54, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x30 */	0x55, 0x56, 0x57, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x38 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x40 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x48 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x50 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x58 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x60 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x68 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x70 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x78 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x80 */	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+/* 0x88 */	0x7C,
 };
 
 
@@ -567,6 +567,9 @@
 	u8                      lower_opcode;
 
 
+	PROC_NAME ("Ps_get_opcode_info");
+
+
 	/* Split the 16-bit opcode into separate bytes */
 
 	upper_opcode = (u8) (opcode >> 8);
@@ -581,8 +584,7 @@
 	 * Detect normal 8-bit opcode or extended 16-bit opcode
 	 */
 
-	switch (upper_opcode)
-	{
+	switch (upper_opcode) {
 	case 0:
 
 		/* Simple (8-bit) opcode: 0-255, can't index beyond table  */
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/parser/psparse.c linux/drivers/acpi/parser/psparse.c
--- v2.4.5/linux/drivers/acpi/parser/psparse.c	Mon Jan 29 10:15:59 2001
+++ linux/drivers/acpi/parser/psparse.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: psparse - Parser top level AML parse routines
- *              $Revision: 74 $
+ *              $Revision: 85 $
  *
  *****************************************************************************/
 
@@ -39,8 +39,9 @@
 #include "amlcode.h"
 #include "acnamesp.h"
 #include "acdebug.h"
+#include "acinterp.h"
 
-#define _COMPONENT          PARSER
+#define _COMPONENT          ACPI_PARSER
 	 MODULE_NAME         ("psparse")
 
 
@@ -111,9 +112,9 @@
 	 *
 	 *    if (Opcode == AML_EXTOP
 	 *       || (Opcode == AML_LNOT
-	 *          && (GET8 (Acpi_aml) == AML_LEQUAL
-	 *               || GET8 (Acpi_aml) == AML_LGREATER
-	 *               || GET8 (Acpi_aml) == AML_LLESS)))
+	 *          && (GET8 (Aml) == AML_LEQUAL
+	 *               || GET8 (Aml) == AML_LGREATER
+	 *               || GET8 (Aml) == AML_LLESS)))
 	 *
 	 *     extended Opcode, !=, <=, or >=
 	 */
@@ -135,8 +136,8 @@
  *
  * FUNCTION:    Acpi_ps_create_state
  *
- * PARAMETERS:  Acpi_aml            - Acpi_aml code pointer
- *              Acpi_aml_size       - Length of AML code
+ * PARAMETERS:  Aml             - Aml code pointer
+ *              Aml_size        - Length of AML code
  *
  * RETURN:      A new parser state object
  *
@@ -152,7 +153,7 @@
 	ACPI_PARSE_STATE        *parser_state;
 
 
-	parser_state = acpi_cm_callocate (sizeof (ACPI_PARSE_STATE));
+	parser_state = acpi_ut_callocate (sizeof (ACPI_PARSE_STATE));
 	if (!parser_state) {
 		return (NULL);
 	}
@@ -260,8 +261,7 @@
 		(opcode_class != OPTYPE_LOCAL_VARIABLE) &&
 		(opcode_class != OPTYPE_METHOD_ARGUMENT) &&
 		(opcode_class != OPTYPE_DATA_TERM)      &&
-		(op->opcode  != AML_NAMEPATH_OP))
-	{
+		(op->opcode  != AML_INT_NAMEPATH_OP)) {
 		/* Make sure that we only delete this subtree */
 
 		if (op->parent) {
@@ -272,8 +272,7 @@
 
 			parent_info = acpi_ps_get_opcode_info (op->parent->opcode);
 
-			switch (ACPI_GET_OP_CLASS (parent_info))
-			{
+			switch (ACPI_GET_OP_CLASS (parent_info)) {
 			case OPTYPE_CONTROL:        /* IF, ELSE, WHILE only */
 				break;
 
@@ -284,15 +283,14 @@
 				 * op must be replace by a placeholder return op
 				 */
 
-				if ((op->parent->opcode == AML_REGION_OP)       ||
-					(op->parent->opcode == AML_CREATE_FIELD_OP) ||
-					(op->parent->opcode == AML_BIT_FIELD_OP)    ||
-					(op->parent->opcode == AML_BYTE_FIELD_OP)   ||
-					(op->parent->opcode == AML_WORD_FIELD_OP)   ||
-					(op->parent->opcode == AML_DWORD_FIELD_OP)  ||
-					(op->parent->opcode == AML_QWORD_FIELD_OP))
-				{
-					replacement_op = acpi_ps_alloc_op (AML_RETURN_VALUE_OP);
+				if ((op->parent->opcode == AML_REGION_OP)               ||
+					(op->parent->opcode == AML_CREATE_FIELD_OP)         ||
+					(op->parent->opcode == AML_CREATE_BIT_FIELD_OP)     ||
+					(op->parent->opcode == AML_CREATE_BYTE_FIELD_OP)    ||
+					(op->parent->opcode == AML_CREATE_WORD_FIELD_OP)    ||
+					(op->parent->opcode == AML_CREATE_DWORD_FIELD_OP)   ||
+					(op->parent->opcode == AML_CREATE_QWORD_FIELD_OP)) {
+					replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
 					if (!replacement_op) {
 						return (FALSE);
 					}
@@ -301,7 +299,7 @@
 				break;
 
 			default:
-				replacement_op = acpi_ps_alloc_op (AML_RETURN_VALUE_OP);
+				replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
 				if (!replacement_op) {
 					return (FALSE);
 				}
@@ -388,8 +386,7 @@
 	u32                     package_length;
 
 
-	switch (callback_status)
-	{
+	switch (callback_status) {
 	case AE_CTRL_TERMINATE:
 
 		/*
@@ -505,7 +502,7 @@
 	ACPI_PARSE2_OBJECT      *deferred_op;
 	u32                     arg_count;      /* push for fixed or var args */
 	u32                     arg_types = 0;
-	ACPI_PTRDIFF            aml_offset;
+	u32                     aml_offset;
 	u16                     opcode;
 	ACPI_PARSE_OBJECT       pre_op;
 	ACPI_PARSE_STATE        *parser_state;
@@ -528,8 +525,7 @@
 				(parser_state->scope->parse_scope.op->opcode == AML_WHILE_OP)) &&
 				(walk_state->control_state) &&
 				(walk_state->control_state->common.state ==
-					CONTROL_PREDICATE_EXECUTING))
-			{
+					CONTROL_PREDICATE_EXECUTING)) {
 
 				/*
 				 * A predicate was just completed, get the value of the
@@ -538,8 +534,7 @@
 
 				status = acpi_ds_get_predicate_value (walk_state, NULL, TRUE);
 				if (ACPI_FAILURE (status) &&
-					((status & AE_CODE_MASK) != AE_CODE_CONTROL))
-				{
+					((status & AE_CODE_MASK) != AE_CODE_CONTROL)) {
 					return (status);
 				}
 
@@ -577,8 +572,7 @@
 			 */
 
 			op_info = acpi_ps_get_opcode_info (opcode);
-			switch (ACPI_GET_OP_TYPE (op_info))
-			{
+			switch (ACPI_GET_OP_TYPE (op_info)) {
 			case ACPI_OP_TYPE_OPCODE:
 
 				/* Found opcode info, this is a normal opcode */
@@ -594,7 +588,7 @@
 				 * string.  Convert the bare name string to a namepath.
 				 */
 
-				opcode = AML_NAMEPATH_OP;
+				opcode = AML_INT_NAMEPATH_OP;
 				arg_types = ARGP_NAMESTRING;
 				break;
 
@@ -684,12 +678,12 @@
 				}
 
 
-				if ((op->opcode == AML_CREATE_FIELD_OP) ||
-					(op->opcode == AML_BIT_FIELD_OP)    ||
-					(op->opcode == AML_BYTE_FIELD_OP)   ||
-					(op->opcode == AML_WORD_FIELD_OP)   ||
-					(op->opcode == AML_DWORD_FIELD_OP))
-				 {
+				if ((op->opcode == AML_CREATE_FIELD_OP)        ||
+					(op->opcode == AML_CREATE_BIT_FIELD_OP)    ||
+					(op->opcode == AML_CREATE_BYTE_FIELD_OP)   ||
+					(op->opcode == AML_CREATE_WORD_FIELD_OP)   ||
+					(op->opcode == AML_CREATE_DWORD_FIELD_OP)  ||
+					(op->opcode == AML_CREATE_QWORD_FIELD_OP)) {
 					/*
 					 * Backup to beginning of Create_xXXfield declaration
 					 * Body_length is unknown until we parse the body
@@ -733,8 +727,7 @@
 		if (arg_types)  /* Are there any arguments that must be processed? */ {
 			/* get arguments */
 
-			switch (op->opcode)
-			{
+			switch (op->opcode) {
 			case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
 			case AML_WORD_OP:       /* AML_WORDDATA_ARG */
 			case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
@@ -746,7 +739,7 @@
 						 GET_CURRENT_ARG_TYPE (arg_types), op);
 				break;
 
-			case AML_NAMEPATH_OP:   /* AML_NAMESTRING_ARG */
+			case AML_INT_NAMEPATH_OP:   /* AML_NAMESTRING_ARG */
 
 				acpi_ps_get_next_namepath (parser_state, op, &arg_count, 1);
 				arg_types = 0;
@@ -783,8 +776,8 @@
 						 */
 
 						deferred_op->data   = parser_state->aml;
-						deferred_op->length = parser_state->pkg_end -
-								  parser_state->aml;
+						deferred_op->length = (u32) (parser_state->pkg_end -
+								   parser_state->aml);
 
 						/*
 						 * Skip body of method.  For Op_regions, we must continue
@@ -824,19 +817,18 @@
 						 * know the length.
 						 */
 
-						deferred_op->length = parser_state->aml -
-								 deferred_op->data;
+						deferred_op->length = (u32) (parser_state->aml -
+								   deferred_op->data);
 					}
 				}
 			}
 
-			if ((op->opcode == AML_CREATE_FIELD_OP) ||
-				(op->opcode == AML_BIT_FIELD_OP)    ||
-				(op->opcode == AML_BYTE_FIELD_OP)   ||
-				(op->opcode == AML_WORD_FIELD_OP)   ||
-				(op->opcode == AML_DWORD_FIELD_OP)  ||
-				(op->opcode == AML_QWORD_FIELD_OP))
-			{
+			if ((op->opcode == AML_CREATE_FIELD_OP)         ||
+				(op->opcode == AML_CREATE_BIT_FIELD_OP)     ||
+				(op->opcode == AML_CREATE_BYTE_FIELD_OP)    ||
+				(op->opcode == AML_CREATE_WORD_FIELD_OP)    ||
+				(op->opcode == AML_CREATE_DWORD_FIELD_OP)   ||
+				(op->opcode == AML_CREATE_QWORD_FIELD_OP)) {
 				/*
 				 * Backup to beginning of Create_xXXfield declaration (1 for
 				 * Opcode)
@@ -844,7 +836,8 @@
 				 * Body_length is unknown until we parse the body
 				 */
 				deferred_op = (ACPI_PARSE2_OBJECT *) op;
-				deferred_op->length = parser_state->aml - deferred_op->data;
+				deferred_op->length = (u32) (parser_state->aml -
+						  deferred_op->data);
 			}
 
 			/* This op complete, notify the dispatcher */
@@ -873,8 +866,7 @@
 			}
 
 
-			switch (status)
-			{
+			switch (status) {
 			case AE_OK:
 				break;
 
@@ -908,8 +900,7 @@
 				status = AE_OK;
 
 				/* Clean up */
-				do
-				{
+				do {
 					if (op) {
 						acpi_ps_complete_this_op (walk_state, op);
 					}
@@ -970,8 +961,7 @@
 	 * sequential closing braces).  We want to terminate each one cleanly.
 	 */
 
-	do
-	{
+	do {
 		if (op) {
 			if (walk_state->ascending_callback != NULL) {
 				status = walk_state->ascending_callback (walk_state, op);
@@ -985,8 +975,7 @@
 					status = AE_OK;
 
 					/* Clean up */
-					do
-					{
+					do {
 						if (op) {
 							acpi_ps_complete_this_op (walk_state, op);
 						}
@@ -1068,8 +1057,11 @@
 	/* Create and initialize a new walk list */
 
 	walk_list.walk_state = NULL;
+	walk_list.acquired_mutex_list.prev = NULL;
+	walk_list.acquired_mutex_list.next = NULL;
 
-	walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, parser_state->start_op, mth_desc, &walk_list);
+	walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, parser_state->start_op,
+			   mth_desc, &walk_list);
 	if (!walk_state) {
 		status = AE_NO_MEMORY;
 		goto cleanup;
@@ -1180,15 +1172,14 @@
 		 /* Delete this walk state and all linked control states */
 
 		acpi_ps_cleanup_scope (walk_state->parser_state);
-		acpi_cm_free (walk_state->parser_state);
+		acpi_ut_free (walk_state->parser_state);
 		acpi_ds_delete_walk_state (walk_state);
 
 	   /* Check if we have restarted a preempted walk */
 
 		walk_state = acpi_ds_get_current_walk_state (&walk_list);
 		if (walk_state &&
-			ACPI_SUCCESS (status))
-		{
+			ACPI_SUCCESS (status)) {
 			/* There is another walk state, restart it */
 
 			/*
@@ -1212,13 +1203,14 @@
 		else if (return_desc) {
 			/* Caller doesn't want it, must delete it */
 
-			acpi_cm_remove_reference (return_desc);
+			acpi_ut_remove_reference (return_desc);
 		}
 	}
 
 
 	/* Normal exit */
 
+	acpi_ex_release_all_mutexes ((ACPI_OPERAND_OBJECT *) &walk_list.acquired_mutex_list);
 	acpi_gbl_current_walk_list = prev_walk_list;
 	return (status);
 
@@ -1229,8 +1221,9 @@
 
 	acpi_ds_delete_walk_state (walk_state);
 	acpi_ps_cleanup_scope (parser_state);
-	acpi_cm_free (parser_state);
+	acpi_ut_free (parser_state);
 
+	acpi_ex_release_all_mutexes ((ACPI_OPERAND_OBJECT *)&walk_list.acquired_mutex_list);
 	acpi_gbl_current_walk_list = prev_walk_list;
 
 	return (status);
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/parser/psscope.c linux/drivers/acpi/parser/psscope.c
--- v2.4.5/linux/drivers/acpi/parser/psscope.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/parser/psscope.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: psscope - Parser scope stack management routines
- *              $Revision: 24 $
+ *              $Revision: 27 $
  *
  *****************************************************************************/
 
@@ -27,7 +27,7 @@
 #include "acpi.h"
 #include "acparser.h"
 
-#define _COMPONENT          PARSER
+#define _COMPONENT          ACPI_PARSER
 	 MODULE_NAME         ("psscope")
 
 
@@ -95,7 +95,7 @@
 	ACPI_GENERIC_STATE      *scope;
 
 
-	scope = acpi_cm_create_generic_state ();
+	scope = acpi_ut_create_generic_state ();
 	if (!scope) {
 		return (AE_NO_MEMORY);
 	}
@@ -137,7 +137,7 @@
 	ACPI_GENERIC_STATE      *scope;
 
 
-	scope = acpi_cm_create_generic_state ();
+	scope = acpi_ut_create_generic_state ();
 	if (!scope) {
 		return (AE_NO_MEMORY);
 	}
@@ -150,7 +150,7 @@
 
 	/* Push onto scope stack */
 
-	acpi_cm_push_generic_state (&parser_state->scope, scope);
+	acpi_ut_push_generic_state (&parser_state->scope, scope);
 
 
 	if (arg_count == ACPI_VAR_ARGS) {
@@ -199,7 +199,7 @@
 	 * Only pop the scope if there is in fact a next scope
 	 */
 	if (scope->common.next) {
-		scope = acpi_cm_pop_generic_state (&parser_state->scope);
+		scope = acpi_ut_pop_generic_state (&parser_state->scope);
 
 
 		/* return to parsing previous op */
@@ -211,7 +211,7 @@
 
 		/* All done with this scope state structure */
 
-		acpi_cm_delete_generic_state (scope);
+		acpi_ut_delete_generic_state (scope);
 	}
 
 	else {
@@ -255,8 +255,8 @@
 	/* Delete anything on the scope stack */
 
 	while (parser_state->scope) {
-		scope = acpi_cm_pop_generic_state (&parser_state->scope);
-		acpi_cm_delete_generic_state (scope);
+		scope = acpi_ut_pop_generic_state (&parser_state->scope);
+		acpi_ut_delete_generic_state (scope);
 	}
 
 	return;
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/parser/pstree.c linux/drivers/acpi/parser/pstree.c
--- v2.4.5/linux/drivers/acpi/parser/pstree.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/parser/pstree.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: pstree - Parser op tree manipulation/traversal/search
- *              $Revision: 27 $
+ *              $Revision: 30 $
  *
  *****************************************************************************/
 
@@ -28,7 +28,7 @@
 #include "acparser.h"
 #include "amlcode.h"
 
-#define _COMPONENT          PARSER
+#define _COMPONENT          ACPI_PARSER
 	 MODULE_NAME         ("pstree")
 
 
@@ -174,13 +174,12 @@
 	ACPI_PARSE_OBJECT       *child = NULL;
 
 
-	switch (op->opcode)
-	{
+	switch (op->opcode) {
 	case AML_SCOPE_OP:
 	case AML_ELSE_OP:
 	case AML_DEVICE_OP:
 	case AML_THERMAL_ZONE_OP:
-	case AML_METHODCALL_OP:
+	case AML_INT_METHODCALL_OP:
 
 		child = acpi_ps_get_arg (op, 0);
 		break;
@@ -191,7 +190,7 @@
 	case AML_METHOD_OP:
 	case AML_IF_OP:
 	case AML_WHILE_OP:
-	case AML_DEF_FIELD_OP:
+	case AML_FIELD_OP:
 
 		child = acpi_ps_get_arg (op, 1);
 		break;
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/parser/psutils.c linux/drivers/acpi/parser/psutils.c
--- v2.4.5/linux/drivers/acpi/parser/psutils.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/parser/psutils.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: psutils - Parser miscellaneous utilities (Parser only)
- *              $Revision: 32 $
+ *              $Revision: 37 $
  *
  *****************************************************************************/
 
@@ -28,7 +28,7 @@
 #include "acparser.h"
 #include "amlcode.h"
 
-#define _COMPONENT          PARSER
+#define _COMPONENT          ACPI_PARSER
 	 MODULE_NAME         ("psutils")
 
 
@@ -94,6 +94,9 @@
 	u8                      flags;
 
 
+	PROC_NAME ("Ps_alloc_op");
+
+
 	/* Allocate the minimum required size object */
 
 	if (acpi_ps_is_deferred_op (opcode)) {
@@ -125,7 +128,7 @@
 		 * Check if there is an Op already available in the cache
 		 */
 
-		acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
+		acpi_ut_acquire_mutex (ACPI_MTX_CACHES);
 		acpi_gbl_parse_cache_requests++;
 		if (acpi_gbl_parse_cache) {
 			/* Extract an op from the front of the cache list */
@@ -142,7 +145,7 @@
 			MEMSET (op, 0, sizeof (ACPI_PARSE_OBJECT));
 
 		}
-		acpi_cm_release_mutex (ACPI_MTX_CACHES);
+		acpi_ut_release_mutex (ACPI_MTX_CACHES);
 	}
 
 	else {
@@ -153,7 +156,7 @@
 		 * Check if there is an Op already available in the cache
 		 */
 
-		acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
+		acpi_ut_acquire_mutex (ACPI_MTX_CACHES);
 		acpi_gbl_ext_parse_cache_requests++;
 		if (acpi_gbl_ext_parse_cache) {
 			/* Extract an op from the front of the cache list */
@@ -170,14 +173,14 @@
 			MEMSET (op, 0, sizeof (ACPI_PARSE2_OBJECT));
 
 		}
-		acpi_cm_release_mutex (ACPI_MTX_CACHES);
+		acpi_ut_release_mutex (ACPI_MTX_CACHES);
 	}
 
 
 	/* Allocate a new Op if necessary */
 
 	if (!op) {
-		op = acpi_cm_callocate (size);
+		op = acpi_ut_callocate (size);
 	}
 
 	/* Initialize the Op */
@@ -207,6 +210,7 @@
 acpi_ps_free_op (
 	ACPI_PARSE_OBJECT       *op)
 {
+	PROC_NAME ("Ps_free_op");
 
 
 
@@ -221,13 +225,13 @@
 			MEMSET (op, 0, sizeof (ACPI_PARSE_OBJECT));
 			op->flags = PARSEOP_IN_CACHE;
 
-			acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
+			acpi_ut_acquire_mutex (ACPI_MTX_CACHES);
 			acpi_gbl_parse_cache_depth++;
 
 			op->next = acpi_gbl_parse_cache;
 			acpi_gbl_parse_cache = op;
 
-			acpi_cm_release_mutex (ACPI_MTX_CACHES);
+			acpi_ut_release_mutex (ACPI_MTX_CACHES);
 			return;
 		}
 	}
@@ -243,13 +247,13 @@
 			MEMSET (op, 0, sizeof (ACPI_PARSE2_OBJECT));
 			op->flags = PARSEOP_IN_CACHE;
 
-			acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
+			acpi_ut_acquire_mutex (ACPI_MTX_CACHES);
 			acpi_gbl_ext_parse_cache_depth++;
 
 			op->next = (ACPI_PARSE_OBJECT *) acpi_gbl_ext_parse_cache;
 			acpi_gbl_ext_parse_cache = (ACPI_PARSE2_OBJECT *) op;
 
-			acpi_cm_release_mutex (ACPI_MTX_CACHES);
+			acpi_ut_release_mutex (ACPI_MTX_CACHES);
 			return;
 		}
 	}
@@ -259,7 +263,7 @@
 	 * Not a GENERIC OP, or the cache is full, just free the Op
 	 */
 
-	acpi_cm_free (op);
+	acpi_ut_free (op);
 }
 
 
@@ -288,7 +292,7 @@
 		/* Delete one cached state object */
 
 		next = acpi_gbl_parse_cache->next;
-		acpi_cm_free (acpi_gbl_parse_cache);
+		acpi_ut_free (acpi_gbl_parse_cache);
 		acpi_gbl_parse_cache = next;
 		acpi_gbl_parse_cache_depth--;
 	}
@@ -299,7 +303,7 @@
 		/* Delete one cached state object */
 
 		next = acpi_gbl_ext_parse_cache->next;
-		acpi_cm_free (acpi_gbl_ext_parse_cache);
+		acpi_ut_free (acpi_gbl_ext_parse_cache);
 		acpi_gbl_ext_parse_cache = (ACPI_PARSE2_OBJECT *) next;
 		acpi_gbl_ext_parse_cache_depth--;
 	}
@@ -350,28 +354,29 @@
 	u16                     opcode)
 {
 	return ((u8)
-		   (opcode == AML_SCOPE_OP          ||
-			opcode == AML_DEVICE_OP         ||
-			opcode == AML_THERMAL_ZONE_OP   ||
-			opcode == AML_METHOD_OP         ||
-			opcode == AML_POWER_RES_OP      ||
-			opcode == AML_PROCESSOR_OP      ||
-			opcode == AML_DEF_FIELD_OP      ||
-			opcode == AML_INDEX_FIELD_OP    ||
-			opcode == AML_BANK_FIELD_OP     ||
-			opcode == AML_NAMEDFIELD_OP     ||
-			opcode == AML_NAME_OP           ||
-			opcode == AML_ALIAS_OP          ||
-			opcode == AML_MUTEX_OP          ||
-			opcode == AML_EVENT_OP          ||
-			opcode == AML_REGION_OP         ||
-			opcode == AML_CREATE_FIELD_OP   ||
-			opcode == AML_BIT_FIELD_OP      ||
-			opcode == AML_BYTE_FIELD_OP     ||
-			opcode == AML_WORD_FIELD_OP     ||
-			opcode == AML_DWORD_FIELD_OP    ||
-			opcode == AML_METHODCALL_OP     ||
-			opcode == AML_NAMEPATH_OP));
+		   (opcode == AML_SCOPE_OP              ||
+			opcode == AML_DEVICE_OP             ||
+			opcode == AML_THERMAL_ZONE_OP       ||
+			opcode == AML_METHOD_OP             ||
+			opcode == AML_POWER_RES_OP          ||
+			opcode == AML_PROCESSOR_OP          ||
+			opcode == AML_FIELD_OP              ||
+			opcode == AML_INDEX_FIELD_OP        ||
+			opcode == AML_BANK_FIELD_OP         ||
+			opcode == AML_INT_NAMEDFIELD_OP     ||
+			opcode == AML_NAME_OP               ||
+			opcode == AML_ALIAS_OP              ||
+			opcode == AML_MUTEX_OP              ||
+			opcode == AML_EVENT_OP              ||
+			opcode == AML_REGION_OP             ||
+			opcode == AML_CREATE_FIELD_OP       ||
+			opcode == AML_CREATE_BIT_FIELD_OP   ||
+			opcode == AML_CREATE_BYTE_FIELD_OP  ||
+			opcode == AML_CREATE_WORD_FIELD_OP  ||
+			opcode == AML_CREATE_DWORD_FIELD_OP ||
+			opcode == AML_CREATE_QWORD_FIELD_OP ||
+			opcode == AML_INT_METHODCALL_OP     ||
+			opcode == AML_INT_NAMEPATH_OP));
 }
 
 u8
@@ -385,7 +390,7 @@
 			opcode == AML_METHOD_OP         ||
 			opcode == AML_POWER_RES_OP      ||
 			opcode == AML_PROCESSOR_OP      ||
-			opcode == AML_DEF_FIELD_OP      ||
+			opcode == AML_FIELD_OP          ||
 			opcode == AML_INDEX_FIELD_OP    ||
 			opcode == AML_BANK_FIELD_OP     ||
 			opcode == AML_NAME_OP           ||
@@ -393,7 +398,7 @@
 			opcode == AML_MUTEX_OP          ||
 			opcode == AML_EVENT_OP          ||
 			opcode == AML_REGION_OP         ||
-			opcode == AML_NAMEDFIELD_OP));
+			opcode == AML_INT_NAMEDFIELD_OP));
 }
 
 
@@ -408,27 +413,28 @@
 	u16                     opcode)
 {
 	return ((u8)
-		   (opcode == AML_SCOPE_OP          ||
-			opcode == AML_DEVICE_OP         ||
-			opcode == AML_THERMAL_ZONE_OP   ||
-			opcode == AML_METHOD_OP         ||
-			opcode == AML_POWER_RES_OP      ||
-			opcode == AML_PROCESSOR_OP      ||
-			opcode == AML_NAMEDFIELD_OP     ||
-			opcode == AML_NAME_OP           ||
-			opcode == AML_ALIAS_OP          ||
-			opcode == AML_MUTEX_OP          ||
-			opcode == AML_EVENT_OP          ||
-			opcode == AML_REGION_OP         ||
-
-
-			opcode == AML_CREATE_FIELD_OP   ||
-			opcode == AML_BIT_FIELD_OP      ||
-			opcode == AML_BYTE_FIELD_OP     ||
-			opcode == AML_WORD_FIELD_OP     ||
-			opcode == AML_DWORD_FIELD_OP    ||
-			opcode == AML_METHODCALL_OP     ||
-			opcode == AML_NAMEPATH_OP));
+		   (opcode == AML_SCOPE_OP              ||
+			opcode == AML_DEVICE_OP             ||
+			opcode == AML_THERMAL_ZONE_OP       ||
+			opcode == AML_METHOD_OP             ||
+			opcode == AML_POWER_RES_OP          ||
+			opcode == AML_PROCESSOR_OP          ||
+			opcode == AML_INT_NAMEDFIELD_OP     ||
+			opcode == AML_NAME_OP               ||
+			opcode == AML_ALIAS_OP              ||
+			opcode == AML_MUTEX_OP              ||
+			opcode == AML_EVENT_OP              ||
+			opcode == AML_REGION_OP             ||
+
+
+			opcode == AML_CREATE_FIELD_OP       ||
+			opcode == AML_CREATE_BIT_FIELD_OP   ||
+			opcode == AML_CREATE_BYTE_FIELD_OP  ||
+			opcode == AML_CREATE_WORD_FIELD_OP  ||
+			opcode == AML_CREATE_DWORD_FIELD_OP ||
+			opcode == AML_CREATE_QWORD_FIELD_OP ||
+			opcode == AML_INT_METHODCALL_OP     ||
+			opcode == AML_INT_NAMEPATH_OP));
 }
 
 
@@ -451,7 +457,7 @@
 			opcode == AML_MUTEX_OP          ||
 			opcode == AML_EVENT_OP          ||
 			opcode == AML_REGION_OP         ||
-			opcode == AML_NAMEDFIELD_OP));
+			opcode == AML_INT_NAMEDFIELD_OP));
 }
 
 
@@ -460,12 +466,13 @@
 	u16                     opcode)
 {
 	return ((u8)
-		   (opcode == AML_METHOD_OP         ||
-			opcode == AML_CREATE_FIELD_OP   ||
-			opcode == AML_BIT_FIELD_OP      ||
-			opcode == AML_BYTE_FIELD_OP     ||
-			opcode == AML_WORD_FIELD_OP     ||
-			opcode == AML_DWORD_FIELD_OP    ||
+		   (opcode == AML_METHOD_OP                 ||
+			opcode == AML_CREATE_FIELD_OP           ||
+			opcode == AML_CREATE_BIT_FIELD_OP       ||
+			opcode == AML_CREATE_BYTE_FIELD_OP      ||
+			opcode == AML_CREATE_WORD_FIELD_OP      ||
+			opcode == AML_CREATE_DWORD_FIELD_OP     ||
+			opcode == AML_CREATE_QWORD_FIELD_OP     ||
 			opcode == AML_REGION_OP));
 }
 
@@ -477,7 +484,7 @@
 acpi_ps_is_bytelist_op (
 	u16                     opcode)
 {
-	return ((u8) (opcode == AML_BYTELIST_OP));
+	return ((u8) (opcode == AML_INT_BYTELIST_OP));
 }
 
 
@@ -490,7 +497,7 @@
 {
 	return ((u8)
 			  (opcode == AML_CREATE_FIELD_OP
-			|| opcode == AML_DEF_FIELD_OP
+			|| opcode == AML_FIELD_OP
 			|| opcode == AML_INDEX_FIELD_OP
 			|| opcode == AML_BANK_FIELD_OP));
 }
@@ -504,11 +511,12 @@
 	u16                     opcode)
 {
 	return ((u8)
-		   (opcode == AML_CREATE_FIELD_OP   ||
-			opcode == AML_BIT_FIELD_OP      ||
-			opcode == AML_BYTE_FIELD_OP     ||
-			opcode == AML_WORD_FIELD_OP     ||
-			opcode == AML_DWORD_FIELD_OP));
+		   (opcode == AML_CREATE_FIELD_OP           ||
+			opcode == AML_CREATE_BIT_FIELD_OP       ||
+			opcode == AML_CREATE_BYTE_FIELD_OP      ||
+			opcode == AML_CREATE_WORD_FIELD_OP      ||
+			opcode == AML_CREATE_DWORD_FIELD_OP     ||
+			opcode == AML_CREATE_QWORD_FIELD_OP));
 }
 
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/parser/pswalk.c linux/drivers/acpi/parser/pswalk.c
--- v2.4.5/linux/drivers/acpi/parser/pswalk.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/parser/pswalk.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: pswalk - Parser routines to walk parsed op tree(s)
- *              $Revision: 52 $
+ *              $Revision: 55 $
  *
  *****************************************************************************/
 
@@ -31,7 +31,7 @@
 #include "acnamesp.h"
 #include "acinterp.h"
 
-#define _COMPONENT          PARSER
+#define _COMPONENT          ACPI_PARSER
 	 MODULE_NAME         ("pswalk")
 
 
@@ -243,6 +243,9 @@
 	/* Create and initialize a new walk list */
 
 	walk_list.walk_state = NULL;
+	walk_list.acquired_mutex_list.prev = NULL;
+	walk_list.acquired_mutex_list.next = NULL;
+
 	walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, &walk_list);
 	if (!walk_state) {
 		return;
@@ -271,6 +274,7 @@
 
 	/* We are done with this walk */
 
+	acpi_ex_release_all_mutexes ((ACPI_OPERAND_OBJECT *) &walk_list.acquired_mutex_list);
 	acpi_ds_delete_walk_state (walk_state);
 
 	return;
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/parser/psxface.c linux/drivers/acpi/parser/psxface.c
--- v2.4.5/linux/drivers/acpi/parser/psxface.c	Mon Jan 29 10:15:59 2001
+++ linux/drivers/acpi/parser/psxface.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: psxface - Parser external interfaces
- *              $Revision: 40 $
+ *              $Revision: 44 $
  *
  *****************************************************************************/
 
@@ -32,7 +32,7 @@
 #include "acnamesp.h"
 
 
-#define _COMPONENT          PARSER
+#define _COMPONENT          ACPI_PARSER
 	 MODULE_NAME         ("psxface")
 
 
@@ -79,7 +79,7 @@
 
 	/* Init for new method, wait on concurrency semaphore */
 
-	status = acpi_ds_begin_method_execution (method_node, obj_desc);
+	status = acpi_ds_begin_method_execution (method_node, obj_desc, NULL);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
@@ -91,7 +91,7 @@
 		 */
 
 		for (i = 0; params[i]; i++) {
-			acpi_cm_add_reference (params[i]);
+			acpi_ut_add_reference (params[i]);
 		}
 	}
 
@@ -141,7 +141,7 @@
 		/* Take away the extra reference that we gave the parameters above */
 
 		for (i = 0; params[i]; i++) {
-			acpi_cm_update_object_reference (params[i], REF_DECREMENT);
+			acpi_ut_update_object_reference (params[i], REF_DECREMENT);
 		}
 	}
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/power.c linux/drivers/acpi/power.c
--- v2.4.5/linux/drivers/acpi/power.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/power.c	Wed Dec 31 16:00:00 1969
@@ -1,137 +0,0 @@
-/*
- *  power.c - Overall power driver. Also handles AC adapter device.
- *
- *  Copyright (C) 2000 Andrew Grover
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include "acpi.h"
-#include "driver.h"
-
-#define _COMPONENT	OS_DEPENDENT
-	MODULE_NAME	("power")
-
-int acpi_cmbatt_init(void);
-int acpi_cmbatt_terminate(void);
-
-/* ACPI-specific defines */
-#define ACPI_AC_ADAPTER_HID	"ACPI0003"
-
-static int ac_count = 0;
-static ACPI_HANDLE ac_handle = 0;
-
-/*
- * We found a device with the correct HID
- */
-static ACPI_STATUS
-acpi_found_ac_adapter(ACPI_HANDLE handle, u32 level, void *ctx, void **value)
-{
-	ACPI_DEVICE_INFO	info;
-
-	if (ac_count > 0) {
-		printk(KERN_ERR "AC Adapter: more than one!\n");
-		return (AE_OK);
-	}
-
-	if (!ACPI_SUCCESS(acpi_get_object_info(handle, &info))) {
-		printk(KERN_ERR "AC Adapter: Could not get AC Adapter object info\n");
-		return (AE_OK);
-	}
-
-	if (!(info.valid & ACPI_VALID_STA)) {
-		printk(KERN_ERR "AC Adapter: Battery _STA invalid\n");
-		return AE_OK;
-	}
-
-	printk(KERN_INFO "AC Adapter: found\n");
-
-	ac_handle = handle;
-
-	ac_count++;
-
-	return AE_OK;
-}
-
-static int
-proc_read_ac_adapter_status(char *page, char **start, off_t off,
-				int count, int *eof, void *data)
-{
-	ACPI_OBJECT obj;
-	ACPI_BUFFER buf;
-
-	char *p = page;
-	int len;
-
-	buf.length = sizeof(obj);
-	buf.pointer = &obj;
-	if (!ACPI_SUCCESS(acpi_evaluate_object(ac_handle, "_PSR", NULL, &buf))
-		|| obj.type != ACPI_TYPE_INTEGER) {
-		p += sprintf(p, "Could not read AC status\n");
-		goto end;
-	}
-
-	if (obj.integer.value)
-		p += sprintf(p, "on-line\n");
-	else
-		p += sprintf(p, "off-line\n");
-
-end:
-	len = (p - page);
-	if (len <= off+count) *eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len>count) len = count;
-	if (len<0) len = 0;
-	return len;
-}
-
-int
-acpi_power_init(void)
-{
-	acpi_get_devices(ACPI_AC_ADAPTER_HID, 
-			acpi_found_ac_adapter,
-			NULL,
-			NULL);
-
-	if (!proc_mkdir("power", NULL))
-		return 0;
-
-	if (ac_handle) {
-		create_proc_read_entry("power/ac", 0, NULL,
-			proc_read_ac_adapter_status, NULL);
-	}
-
-	acpi_cmbatt_init();
-
-	return 0;
-}
-
-int
-acpi_power_terminate(void)
-{
-	acpi_cmbatt_terminate();
-
-	if (ac_handle) {
-		remove_proc_entry("power/ac", NULL);
-	}
-
-	remove_proc_entry("power", NULL);
-
-	return 0;
-}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/resources/Makefile linux/drivers/acpi/resources/Makefile
--- v2.4.5/linux/drivers/acpi/resources/Makefile	Fri Dec 29 14:07:21 2000
+++ linux/drivers/acpi/resources/Makefile	Wed Jun 20 17:47:40 2001
@@ -1,16 +1,12 @@
 #
 # Makefile for all Linux ACPI interpreter subdirectories
+# EXCEPT for the ospm directory
 #
 
-O_TARGET := ../$(shell basename `pwd`).o
+O_TARGET := $(notdir $(CURDIR)).o
 
 obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c))
 
-EXTRA_CFLAGS += -I../include
-
 EXTRA_CFLAGS += $(ACPI_CFLAGS)
 
 include $(TOPDIR)/Rules.make
-
-clean:
-	$(RM) *.o 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/resources/rsaddr.c linux/drivers/acpi/resources/rsaddr.c
--- v2.4.5/linux/drivers/acpi/resources/rsaddr.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/resources/rsaddr.c	Wed Jun 20 17:47:40 2001
@@ -1,10 +1,7 @@
 /*******************************************************************************
  *
- * Module Name: rsaddr - Acpi_rs_address16_resource
- *                       Acpi_rs_address16_stream
- *                       Acpi_rs_address32_resource
- *                       Acpi_rs_address32_stream
- *              $Revision: 14 $
+ * Module Name: rsaddr - Address resource descriptors (16/32/64)
+ *              $Revision: 18 $
  *
  ******************************************************************************/
 
@@ -30,7 +27,7 @@
 #include "acpi.h"
 #include "acresrc.h"
 
-#define _COMPONENT          RESOURCE_MANAGER
+#define _COMPONENT          ACPI_RESOURCES
 	 MODULE_NAME         ("rsaddr")
 
 
@@ -39,20 +36,20 @@
  * FUNCTION:    Acpi_rs_address16_resource
  *
  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
- *                                              stream
+ *                                        stream
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes consumed from
- *                                          the Byte_stream_buffer
+ *                                        the number of bytes consumed from
+ *                                        the Byte_stream_buffer
  *              Output_buffer           - Pointer to the user's return buffer
  *              Structure_size          - u32 pointer that is filled with
- *                                          the number of bytes in the filled
- *                                          in structure
+ *                                        the number of bytes in the filled
+ *                                        in structure
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *                  structure pointed to by the Output_buffer. Return the
- *                  number of bytes consumed from the byte stream.
+ *              structure pointed to by the Output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
  *
  ******************************************************************************/
 
@@ -64,26 +61,22 @@
 	u32                     *structure_size)
 {
 	u8                      *buffer = byte_stream_buffer;
-	RESOURCE                *output_struct = (RESOURCE *) * output_buffer;
+	ACPI_RESOURCE           *output_struct = (ACPI_RESOURCE *) *output_buffer;
+	NATIVE_CHAR             *temp_ptr;
+	u32                     struct_size = SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS16);
+	u32                     index;
 	u16                     temp16;
 	u8                      temp8;
-	u32                     index;
-	u32                     struct_size = sizeof(ADDRESS16_RESOURCE) +
-			  RESOURCE_LENGTH_NO_DATA;
 
 
 	/*
 	 * Point past the Descriptor to get the number of bytes consumed
 	 */
 	buffer += 1;
-
 	MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
 
 	*bytes_consumed = temp16 + 3;
-
-	output_struct->id = address16;
-
-	output_struct->length = struct_size;
+	output_struct->id = ACPI_RSTYPE_ADDRESS16;
 
 	/*
 	 * Get the Resource Type (Byte3)
@@ -93,7 +86,7 @@
 
 	/* Values 0-2 are valid */
 	if (temp8 > 2) {
-		return (AE_AML_ERROR);
+		return (AE_AML_INVALID_RESOURCE_TYPE);
 	}
 
 	output_struct->data.address16.resource_type = temp8 & 0x03;
@@ -144,7 +137,7 @@
 		}
 
 		else {
-			/* BUS_NUMBER_RANGE == Address32_data->Resource_type */
+			/* BUS_NUMBER_RANGE == Address16.Data->Resource_type */
 			/* Nothing needs to be filled in */
 		}
 	}
@@ -167,25 +160,22 @@
 	 * Get Max_address_range (Bytes 10-11)
 	 */
 	buffer += 2;
-	MOVE_UNALIGNED16_TO_16
-		(&output_struct->data.address16.max_address_range,
-		 buffer);
+	MOVE_UNALIGNED16_TO_16 (&output_struct->data.address16.max_address_range,
+			 buffer);
 
 	/*
 	 * Get Address_translation_offset (Bytes 12-13)
 	 */
 	buffer += 2;
-	MOVE_UNALIGNED16_TO_16
-		(&output_struct->data.address16.address_translation_offset,
-		 buffer);
+	MOVE_UNALIGNED16_TO_16 (&output_struct->data.address16.address_translation_offset,
+			 buffer);
 
 	/*
 	 * Get Address_length (Bytes 14-15)
 	 */
 	buffer += 2;
-	MOVE_UNALIGNED16_TO_16
-		(&output_struct->data.address16.address_length,
-		 buffer);
+	MOVE_UNALIGNED16_TO_16 (&output_struct->data.address16.address_length,
+			 buffer);
 
 	/*
 	 * Resource Source Index (if present)
@@ -194,30 +184,36 @@
 
 	/*
 	 * This will leave us pointing to the Resource Source Index
-	 *  If it is present, then save it off and calculate the
-	 *  pointer to where the null terminated string goes:
-	 *  Each Interrupt takes 32-bits + the 5 bytes of the
-	 *  stream that are default.
+	 * If it is present, then save it off and calculate the
+	 * pointer to where the null terminated string goes:
+	 * Each Interrupt takes 32-bits + the 5 bytes of the
+	 * stream that are default.
 	 */
 	if (*bytes_consumed > 16) {
 		/* Dereference the Index */
 
 		temp8 = *buffer;
-		output_struct->data.address16.resource_source_index =
-				(u32) temp8;
+		output_struct->data.address16.resource_source.index = (u32) temp8;
 
 		/* Point to the String */
 
 		buffer += 1;
 
+		/* Point the String pointer to the end of this structure */
+
+		output_struct->data.address16.resource_source.string_ptr =
+				(NATIVE_CHAR *)((u8 * )output_struct + struct_size);
+
+		temp_ptr = output_struct->data.address16.resource_source.string_ptr;
+
 		/* Copy the string into the buffer */
 
 		index = 0;
 
 		while (0x00 != *buffer) {
-			output_struct->data.address16.resource_source[index] =
-				*buffer;
+			*temp_ptr = *buffer;
 
+			temp_ptr += 1;
 			buffer += 1;
 			index += 1;
 		}
@@ -225,31 +221,34 @@
 		/*
 		 * Add the terminating null
 		 */
-		output_struct->data.address16.resource_source[index] = 0x00;
+		*temp_ptr = 0x00;
 
-		output_struct->data.address16.resource_source_string_length =
-				index + 1;
+		output_struct->data.address16.resource_source.string_length = index + 1;
 
 		/*
-		 * In order for the Struct_size to fall on a 32-bit boundry,
-		 *  calculate the length of the string and expand the
-		 *  Struct_size to the next 32-bit boundry.
+		 * In order for the Struct_size to fall on a 32-bit boundary,
+		 * calculate the length of the string and expand the
+		 * Struct_size to the next 32-bit boundary.
 		 */
 		temp8 = (u8) (index + 1);
 		struct_size += ROUND_UP_TO_32_bITS (temp8);
-		output_struct->length = struct_size;
 	}
+
 	else {
-		output_struct->data.address16.resource_source_index = 0x00;
-		output_struct->data.address16.resource_source_string_length = 0;
-		output_struct->data.address16.resource_source[0] = 0x00;
+		output_struct->data.address16.resource_source.index = 0x00;
+		output_struct->data.address16.resource_source.string_length = 0;
+		output_struct->data.address16.resource_source.string_ptr = NULL;
 	}
 
 	/*
+	 * Set the Length parameter
+	 */
+	output_struct->length = struct_size;
+
+	/*
 	 * Return the final size of the structure
 	 */
 	*structure_size = struct_size;
-
 	return (AE_OK);
 }
 
@@ -261,19 +260,19 @@
  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
  *              Output_buffer           - Pointer to the user's return buffer
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes of the
- *                                          Output_buffer used
+ *                                        the number of bytes of the
+ *                                        Output_buffer used
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the linked list resource structure and fills in the
- *                  the appropriate bytes in a byte stream
+ *              the appropriate bytes in a byte stream
  *
  ******************************************************************************/
 
 ACPI_STATUS
 acpi_rs_address16_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed)
 {
@@ -343,42 +342,42 @@
 	 * Set the address space granularity
 	 */
 	MOVE_UNALIGNED16_TO_16 (buffer,
-			 &linked_list->data.address16.granularity);
+			   &linked_list->data.address16.granularity);
 	buffer += 2;
 
 	/*
 	 * Set the address range minimum
 	 */
 	MOVE_UNALIGNED16_TO_16 (buffer,
-			 &linked_list->data.address16.min_address_range);
+			   &linked_list->data.address16.min_address_range);
 	buffer += 2;
 
 	/*
 	 * Set the address range maximum
 	 */
 	MOVE_UNALIGNED16_TO_16 (buffer,
-			 &linked_list->data.address16.max_address_range);
+			   &linked_list->data.address16.max_address_range);
 	buffer += 2;
 
 	/*
 	 * Set the address translation offset
 	 */
 	MOVE_UNALIGNED16_TO_16 (buffer,
-			  &linked_list->data.address16.address_translation_offset);
+			   &linked_list->data.address16.address_translation_offset);
 	buffer += 2;
 
 	/*
 	 * Set the address length
 	 */
 	MOVE_UNALIGNED16_TO_16 (buffer,
-			 &linked_list->data.address16.address_length);
+			   &linked_list->data.address16.address_length);
 	buffer += 2;
 
 	/*
 	 * Resource Source Index and Resource Source are optional
 	 */
-	if (0 != linked_list->data.address16.resource_source_string_length) {
-		temp8 = (u8) linked_list->data.address16.resource_source_index;
+	if (0 != linked_list->data.address16.resource_source.string_length) {
+		temp8 = (u8) linked_list->data.address16.resource_source.index;
 
 		*buffer = temp8;
 		buffer += 1;
@@ -388,21 +387,21 @@
 		/*
 		 * Copy the string
 		 */
-		STRCPY (temp_pointer, linked_list->data.address16.resource_source);
+		STRCPY (temp_pointer,
+				linked_list->data.address16.resource_source.string_ptr);
 
 		/*
 		 * Buffer needs to be set to the length of the sting + one for the
 		 *  terminating null
 		 */
-		buffer += (STRLEN (linked_list->data.address16.resource_source) + 1);
+		buffer += (STRLEN (linked_list->data.address16.resource_source.string_ptr)
+				 + 1);
 	}
 
 	/*
 	 * Return the number of bytes consumed in this operation
 	 */
-	actual_bytes = (u32) ((NATIVE_UINT) buffer -
-			   (NATIVE_UINT) *output_buffer);
-
+	actual_bytes = POINTER_DIFF (buffer, *output_buffer);
 	*bytes_consumed = actual_bytes;
 
 	/*
@@ -411,7 +410,6 @@
 	 */
 	actual_bytes -= 3;
 	MOVE_UNALIGNED16_TO_16 (length_field, &actual_bytes);
-
 	return (AE_OK);
 }
 
@@ -421,20 +419,20 @@
  * FUNCTION:    Acpi_rs_address32_resource
  *
  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
- *                                          stream
+ *                                        stream
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes consumed from
- *                                          the Byte_stream_buffer
+ *                                        the number of bytes consumed from
+ *                                        the Byte_stream_buffer
  *              Output_buffer           - Pointer to the user's return buffer
  *              Structure_size          - u32 pointer that is filled with
- *                                          the number of bytes in the filled
- *                                          in structure
+ *                                        the number of bytes in the filled
+ *                                        in structure
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *                  structure pointed to by the Output_buffer. Return the
- *                  number of bytes consumed from the byte stream.
+ *              structure pointed to by the Output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
  *
  ******************************************************************************/
 
@@ -446,19 +444,18 @@
 	u32                     *structure_size)
 {
 	u8                      *buffer;
-	RESOURCE                *output_struct;
+	ACPI_RESOURCE           *output_struct;
 	u16                     temp16;
 	u8                      temp8;
+	NATIVE_CHAR             *temp_ptr;
 	u32                     struct_size;
 	u32                     index;
 
 
 	buffer = byte_stream_buffer;
+	output_struct = (ACPI_RESOURCE *) *output_buffer;
 
-	output_struct = (RESOURCE *) *output_buffer;
-
-	struct_size = sizeof (ADDRESS32_RESOURCE) +
-			  RESOURCE_LENGTH_NO_DATA;
+	struct_size = SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS32);
 
 	/*
 	 * Point past the Descriptor to get the number of bytes consumed
@@ -468,7 +465,7 @@
 
 	*bytes_consumed = temp16 + 3;
 
-	output_struct->id = address32;
+	output_struct->id = ACPI_RSTYPE_ADDRESS32;
 
 	/*
 	 * Get the Resource Type (Byte3)
@@ -478,7 +475,7 @@
 
 	/* Values 0-2 are valid */
 	if(temp8 > 2) {
-		return (AE_AML_ERROR);
+		return (AE_AML_INVALID_RESOURCE_TYPE);
 	}
 
 	output_struct->data.address32.resource_type = temp8 & 0x03;
@@ -560,9 +557,8 @@
 	 * Get Address_translation_offset (Bytes 18-21)
 	 */
 	buffer += 4;
-	MOVE_UNALIGNED32_TO_32
-			 (&output_struct->data.address32.address_translation_offset,
-				 buffer);
+	MOVE_UNALIGNED32_TO_32 (&output_struct->data.address32.address_translation_offset,
+			 buffer);
 
 	/*
 	 * Get Address_length (Bytes 22-25)
@@ -578,27 +574,35 @@
 
 	/*
 	 * This will leave us pointing to the Resource Source Index
-	 *  If it is present, then save it off and calculate the
-	 *  pointer to where the null terminated string goes:
-	 *  Each Interrupt takes 32-bits + the 5 bytes of the
-	 *  stream that are default.
+	 * If it is present, then save it off and calculate the
+	 * pointer to where the null terminated string goes:
 	 */
 	if (*bytes_consumed > 26) {
 		/* Dereference the Index */
 
 		temp8 = *buffer;
-		output_struct->data.address32.resource_source_index = (u32)temp8;
+		output_struct->data.address32.resource_source.index =
+				(u32) temp8;
 
 		/* Point to the String */
 
 		buffer += 1;
 
+		/* Point the String pointer to the end of this structure */
+
+		output_struct->data.address32.resource_source.string_ptr =
+				(NATIVE_CHAR *)((u8 *)output_struct + struct_size);
+
+		temp_ptr = output_struct->data.address32.resource_source.string_ptr;
+
 		/* Copy the string into the buffer */
 
 		index = 0;
 
 		while (0x00 != *buffer) {
-			output_struct->data.address32.resource_source[index] = *buffer;
+			*temp_ptr = *buffer;
+
+			temp_ptr += 1;
 			buffer += 1;
 			index += 1;
 		}
@@ -606,23 +610,22 @@
 		/*
 		 * Add the terminating null
 		 */
-		output_struct->data.address32.resource_source[index] = 0x00;
-
-		output_struct->data.address32.resource_source_string_length = index + 1;
+		*temp_ptr = 0x00;
+		output_struct->data.address32.resource_source.string_length = index + 1;
 
 		/*
-		 * In order for the Struct_size to fall on a 32-bit boundry,
+		 * In order for the Struct_size to fall on a 32-bit boundary,
 		 *  calculate the length of the string and expand the
-		 *  Struct_size to the next 32-bit boundry.
+		 *  Struct_size to the next 32-bit boundary.
 		 */
 		temp8 = (u8) (index + 1);
 		struct_size += ROUND_UP_TO_32_bITS (temp8);
 	}
 
 	else {
-		output_struct->data.address32.resource_source_index = 0x00;
-		output_struct->data.address32.resource_source_string_length = 0;
-		output_struct->data.address32.resource_source[0] = 0x00;
+		output_struct->data.address32.resource_source.index = 0x00;
+		output_struct->data.address32.resource_source.string_length = 0;
+		output_struct->data.address32.resource_source.string_ptr = NULL;
 	}
 
 	/*
@@ -634,7 +637,6 @@
 	 * Return the final size of the structure
 	 */
 	*structure_size = struct_size;
-
 	return (AE_OK);
 }
 
@@ -646,19 +648,19 @@
  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
  *              Output_buffer           - Pointer to the user's return buffer
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes of the
- *                                          Output_buffer used
+ *                                        the number of bytes of the
+ *                                        Output_buffer used
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the linked list resource structure and fills in the
- *                  the appropriate bytes in a byte stream
+ *              the appropriate bytes in a byte stream
  *
  ******************************************************************************/
 
 ACPI_STATUS
 acpi_rs_address32_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed)
 {
@@ -680,7 +682,7 @@
 	 * Set a pointer to the Length field - to be filled in later
 	 */
 
-	length_field = (u16 *)buffer;
+	length_field = (u16 *) buffer;
 	buffer += 2;
 
 	/*
@@ -730,21 +732,21 @@
 	 * Set the address space granularity
 	 */
 	MOVE_UNALIGNED32_TO_32 (buffer,
-			 &linked_list->data.address32.granularity);
+			  &linked_list->data.address32.granularity);
 	buffer += 4;
 
 	/*
 	 * Set the address range minimum
 	 */
 	MOVE_UNALIGNED32_TO_32 (buffer,
-			 &linked_list->data.address32.min_address_range);
+			  &linked_list->data.address32.min_address_range);
 	buffer += 4;
 
 	/*
 	 * Set the address range maximum
 	 */
 	MOVE_UNALIGNED32_TO_32 (buffer,
-			 &linked_list->data.address32.max_address_range);
+			  &linked_list->data.address32.max_address_range);
 	buffer += 4;
 
 	/*
@@ -758,14 +760,14 @@
 	 * Set the address length
 	 */
 	MOVE_UNALIGNED32_TO_32 (buffer,
-			 &linked_list->data.address32.address_length);
+			  &linked_list->data.address32.address_length);
 	buffer += 4;
 
 	/*
 	 * Resource Source Index and Resource Source are optional
 	 */
-	if (0 != linked_list->data.address32.resource_source_string_length) {
-		temp8 = (u8) linked_list->data.address32.resource_source_index;
+	if (0 != linked_list->data.address32.resource_source.string_length) {
+		temp8 = (u8) linked_list->data.address32.resource_source.index;
 
 		*buffer = temp8;
 		buffer += 1;
@@ -775,27 +777,414 @@
 		/*
 		 * Copy the string
 		 */
-		STRCPY (temp_pointer, linked_list->data.address32.resource_source);
+		STRCPY (temp_pointer,
+			linked_list->data.address32.resource_source.string_ptr);
 
 		/*
 		 * Buffer needs to be set to the length of the sting + one for the
 		 *  terminating null
 		 */
-		buffer += (STRLEN (linked_list->data.address32.resource_source) + 1);
+		buffer += (STRLEN (linked_list->data.address32.resource_source.string_ptr) + 1);
 	}
 
 	/*
 	 * Return the number of bytes consumed in this operation
 	 */
-	*bytes_consumed = (u32) ((NATIVE_UINT) buffer -
-			   (NATIVE_UINT) *output_buffer);
+	*bytes_consumed = POINTER_DIFF (buffer, *output_buffer);
 
 	/*
 	 * Set the length field to the number of bytes consumed
 	 *  minus the header size (3 bytes)
 	 */
 	*length_field = (u16) (*bytes_consumed - 3);
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_rs_address64_resource
+ *
+ * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
+ *                                        stream
+ *              Bytes_consumed          - u32 pointer that is filled with
+ *                                        the number of bytes consumed from
+ *                                        the Byte_stream_buffer
+ *              Output_buffer           - Pointer to the user's return buffer
+ *              Structure_size          - u32 pointer that is filled with
+ *                                        the number of bytes in the filled
+ *                                        in structure
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the resource byte stream and fill out the appropriate
+ *              structure pointed to by the Output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_rs_address64_resource (
+	u8                      *byte_stream_buffer,
+	u32                     *bytes_consumed,
+	u8                      **output_buffer,
+	u32                     *structure_size)
+{
+	u8                      *buffer;
+	ACPI_RESOURCE           *output_struct;
+	u16                     temp16;
+	u8                      temp8;
+	NATIVE_CHAR             *temp_ptr;
+	u32                     struct_size;
+	u32                     index;
+
+
+	buffer = byte_stream_buffer;
+	output_struct = (ACPI_RESOURCE *) *output_buffer;
+
+	struct_size = SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS64);
+
+	/*
+	 * Point past the Descriptor to get the number of bytes consumed
+	 */
+	buffer += 1;
+	MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
+
+	*bytes_consumed = temp16 + 3;
+	output_struct->id = ACPI_RSTYPE_ADDRESS64;
+
+	/*
+	 * Get the Resource Type (Byte3)
+	 */
+	buffer += 2;
+	temp8 = *buffer;
+
+	/* Values 0-2 are valid */
+	if(temp8 > 2) {
+		return (AE_AML_INVALID_RESOURCE_TYPE);
+	}
+
+	output_struct->data.address64.resource_type = temp8 & 0x03;
+
+	/*
+	 * Get the General Flags (Byte4)
+	 */
+	buffer += 1;
+	temp8 = *buffer;
+
+	/*
+	 * Producer / Consumer
+	 */
+	output_struct->data.address64.producer_consumer = temp8 & 0x01;
+
+	/*
+	 * Decode
+	 */
+	output_struct->data.address64.decode = (temp8 >> 1) & 0x01;
+
+	/*
+	 * Min Address Fixed
+	 */
+	output_struct->data.address64.min_address_fixed = (temp8 >> 2) & 0x01;
+
+	/*
+	 * Max Address Fixed
+	 */
+	output_struct->data.address64.max_address_fixed = (temp8 >> 3) & 0x01;
+
+	/*
+	 * Get the Type Specific Flags (Byte5)
+	 */
+	buffer += 1;
+	temp8 = *buffer;
+
+	if (MEMORY_RANGE == output_struct->data.address64.resource_type) {
+		output_struct->data.address64.attribute.memory.read_write_attribute =
+				(u16) (temp8 & 0x01);
+
+		output_struct->data.address64.attribute.memory.cache_attribute =
+				(u16) ((temp8 >> 1) & 0x0F);
+	}
+
+	else {
+		if (IO_RANGE == output_struct->data.address64.resource_type) {
+			output_struct->data.address64.attribute.io.range_attribute =
+				(u16) (temp8 & 0x03);
+		}
+
+		else {
+			/* BUS_NUMBER_RANGE == Output_struct->Data.Address64.Resource_type */
+			/* Nothing needs to be filled in */
+		}
+	}
+
+	/*
+	 * Get Granularity (Bytes 6-13)
+	 */
+	buffer += 1;
+	MOVE_UNALIGNED64_TO_64 (&output_struct->data.address64.granularity,
+			 buffer);
+
+	/*
+	 * Get Min_address_range (Bytes 14-21)
+	 */
+	buffer += 8;
+	MOVE_UNALIGNED64_TO_64 (&output_struct->data.address64.min_address_range,
+			 buffer);
+
+	/*
+	 * Get Max_address_range (Bytes 22-29)
+	 */
+	buffer += 8;
+	MOVE_UNALIGNED64_TO_64 (&output_struct->data.address64.max_address_range,
+			 buffer);
+
+	/*
+	 * Get Address_translation_offset (Bytes 30-37)
+	 */
+	buffer += 8;
+	MOVE_UNALIGNED64_TO_64 (&output_struct->data.address64.address_translation_offset,
+			 buffer);
+
+	/*
+	 * Get Address_length (Bytes 38-45)
+	 */
+	buffer += 8;
+	MOVE_UNALIGNED64_TO_64 (&output_struct->data.address64.address_length,
+			 buffer);
+
+	/*
+	 * Resource Source Index (if present)
+	 */
+	buffer += 8;
+
+	/*
+	 * This will leave us pointing to the Resource Source Index
+	 * If it is present, then save it off and calculate the
+	 * pointer to where the null terminated string goes:
+	 * Each Interrupt takes 32-bits + the 5 bytes of the
+	 * stream that are default.
+	 */
+	if (*bytes_consumed > 46) {
+		/* Dereference the Index */
+
+		temp8 = *buffer;
+		output_struct->data.address64.resource_source.index =
+				(u32) temp8;
+
+		/* Point to the String */
+
+		buffer += 1;
+
+		/* Point the String pointer to the end of this structure */
+
+		output_struct->data.address64.resource_source.string_ptr =
+				(NATIVE_CHAR *)((u8 *)output_struct + struct_size);
+
+		temp_ptr = output_struct->data.address64.resource_source.string_ptr;
+
+		/* Copy the string into the buffer */
+
+		index = 0;
+
+		while (0x00 != *buffer) {
+			*temp_ptr = *buffer;
+
+			temp_ptr += 1;
+			buffer += 1;
+			index += 1;
+		}
+
+		/*
+		 * Add the terminating null
+		 */
+		*temp_ptr = 0x00;
+
+		output_struct->data.address64.resource_source.string_length = index + 1;
+
+		/*
+		 * In order for the Struct_size to fall on a 32-bit boundary,
+		 * calculate the length of the string and expand the
+		 * Struct_size to the next 32-bit boundary.
+		 */
+		temp8 = (u8) (index + 1);
+		struct_size += ROUND_UP_TO_32_bITS (temp8);
+	}
+
+	else {
+		output_struct->data.address64.resource_source.index = 0x00;
+		output_struct->data.address64.resource_source.string_length = 0;
+		output_struct->data.address64.resource_source.string_ptr = NULL;
+	}
+
+	/*
+	 * Set the Length parameter
+	 */
+	output_struct->length = struct_size;
+
+	/*
+	 * Return the final size of the structure
+	 */
+	*structure_size = struct_size;
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_rs_address64_stream
+ *
+ * PARAMETERS:  Linked_list             - Pointer to the resource linked list
+ *              Output_buffer           - Pointer to the user's return buffer
+ *              Bytes_consumed          - u32 pointer that is filled with
+ *                                        the number of bytes of the
+ *                                        Output_buffer used
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the linked list resource structure and fills in the
+ *              the appropriate bytes in a byte stream
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_rs_address64_stream (
+	ACPI_RESOURCE           *linked_list,
+	u8                      **output_buffer,
+	u32                     *bytes_consumed)
+{
+	u8                      *buffer;
+	u16                     *length_field;
+	u8                      temp8;
+	NATIVE_CHAR             *temp_pointer;
+
+
+	buffer = *output_buffer;
+
+	/*
+	 * The descriptor field is static
+	 */
+	*buffer = 0x8A;
+	buffer += 1;
+
+	/*
+	 * Set a pointer to the Length field - to be filled in later
+	 */
+
+	length_field = (u16 *)buffer;
+	buffer += 2;
+
+	/*
+	 * Set the Resource Type (Memory, Io, Bus_number)
+	 */
+	temp8 = (u8) (linked_list->data.address64.resource_type & 0x03);
+
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Set the general flags
+	 */
+	temp8 = (u8) (linked_list->data.address64.producer_consumer & 0x01);
+	temp8 |= (linked_list->data.address64.decode & 0x01) << 1;
+	temp8 |= (linked_list->data.address64.min_address_fixed & 0x01) << 2;
+	temp8 |= (linked_list->data.address64.max_address_fixed & 0x01) << 3;
+
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Set the type specific flags
+	 */
+	temp8 = 0;
+
+	if(MEMORY_RANGE == linked_list->data.address64.resource_type) {
+		temp8 = (u8)
+			(linked_list->data.address64.attribute.memory.read_write_attribute &
+			0x01);
+
+		temp8 |=
+			(linked_list->data.address64.attribute.memory.cache_attribute &
+			 0x0F) << 1;
+	}
+
+	else if (IO_RANGE == linked_list->data.address64.resource_type) {
+		temp8 = (u8)
+			(linked_list->data.address64.attribute.io.range_attribute &
+			 0x03);
+	}
+
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Set the address space granularity
+	 */
+	MOVE_UNALIGNED64_TO_64 (buffer,
+			   &linked_list->data.address64.granularity);
+	buffer += 8;
+
+	/*
+	 * Set the address range minimum
+	 */
+	MOVE_UNALIGNED64_TO_64 (buffer,
+			   &linked_list->data.address64.min_address_range);
+	buffer += 8;
 
+	/*
+	 * Set the address range maximum
+	 */
+	MOVE_UNALIGNED64_TO_64 (buffer,
+			   &linked_list->data.address64.max_address_range);
+	buffer += 8;
+
+	/*
+	 * Set the address translation offset
+	 */
+	MOVE_UNALIGNED64_TO_64 (buffer,
+			   &linked_list->data.address64.address_translation_offset);
+	buffer += 8;
+
+	/*
+	 * Set the address length
+	 */
+	MOVE_UNALIGNED64_TO_64 (buffer,
+			   &linked_list->data.address64.address_length);
+	buffer += 8;
+
+	/*
+	 * Resource Source Index and Resource Source are optional
+	 */
+	if (0 != linked_list->data.address64.resource_source.string_length) {
+		temp8 = (u8) linked_list->data.address64.resource_source.index;
+
+		*buffer = temp8;
+		buffer += 1;
+
+		temp_pointer = (NATIVE_CHAR *) buffer;
+
+		/*
+		 * Copy the string
+		 */
+		STRCPY (temp_pointer, linked_list->data.address64.resource_source.string_ptr);
+
+		/*
+		 * Buffer needs to be set to the length of the sting + one for the
+		 *  terminating null
+		 */
+		buffer += (STRLEN (linked_list->data.address64.resource_source.string_ptr) + 1);
+	}
+
+	/*
+	 * Return the number of bytes consumed in this operation
+	 */
+	*bytes_consumed = POINTER_DIFF (buffer, *output_buffer);
+
+	/*
+	 * Set the length field to the number of bytes consumed
+	 * minus the header size (3 bytes)
+	 */
+	*length_field = (u16) (*bytes_consumed - 3);
 	return (AE_OK);
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/resources/rscalc.c linux/drivers/acpi/resources/rscalc.c
--- v2.4.5/linux/drivers/acpi/resources/rscalc.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/resources/rscalc.c	Wed Jun 20 17:47:40 2001
@@ -1,8 +1,7 @@
 /*******************************************************************************
  *
- * Module Name: rscalc - Acpi_rs_calculate_byte_stream_length
- *                       Acpi_rs_calculate_list_length
- *              $Revision: 21 $
+ * Module Name: rscalc - Calculate stream and list lengths
+ *              $Revision: 30 $
  *
  ******************************************************************************/
 
@@ -30,7 +29,7 @@
 #include "amlcode.h"
 #include "acnamesp.h"
 
-#define _COMPONENT          RESOURCE_MANAGER
+#define _COMPONENT          ACPI_RESOURCES
 	 MODULE_NAME         ("rscalc")
 
 
@@ -40,9 +39,9 @@
  *
  * PARAMETERS:  Linked_list         - Pointer to the resource linked list
  *              Size_needed         - u32 pointer of the size buffer needed
- *                                      to properly return the parsed data
+ *                                    to properly return the parsed data
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Takes the resource byte stream and parses it once, calculating
  *              the size buffer needed to hold the linked list that conveys
@@ -52,214 +51,195 @@
 
 ACPI_STATUS
 acpi_rs_calculate_byte_stream_length (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u32                     *size_needed)
 {
 	u32                     byte_stream_size_needed = 0;
 	u32                     segment_size;
-	EXTENDED_IRQ_RESOURCE   *ex_irq = NULL;
+	ACPI_RESOURCE_EXT_IRQ   *ex_irq = NULL;
 	u8                      done = FALSE;
 
 
 	while (!done) {
-
 		/*
-		 * Init the variable that will hold the size to add to the
-		 *  total.
+		 * Init the variable that will hold the size to add to the total.
 		 */
 		segment_size = 0;
 
-		switch (linked_list->id)
-		{
-		case irq:
+		switch (linked_list->id) {
+		case ACPI_RSTYPE_IRQ:
 			/*
 			 * IRQ Resource
-			 */
-			/*
 			 * For an IRQ Resource, Byte 3, although optional, will
-			 *  always be created - it holds IRQ information.
+			 * always be created - it holds IRQ information.
 			 */
 			segment_size = 4;
 			break;
 
-		case dma:
+		case ACPI_RSTYPE_DMA:
 			/*
 			 * DMA Resource
-			 */
-			/*
 			 * For this resource the size is static
 			 */
 			segment_size = 3;
 			break;
 
-		case start_dependent_functions:
+		case ACPI_RSTYPE_START_DPF:
 			/*
 			 * Start Dependent Functions Resource
-			 */
-			/*
 			 * For a Start_dependent_functions Resource, Byte 1,
 			 * although optional, will always be created.
 			 */
 			segment_size = 2;
 			break;
 
-		case end_dependent_functions:
+		case ACPI_RSTYPE_END_DPF:
 			/*
 			 * End Dependent Functions Resource
-			 */
-			/*
 			 * For this resource the size is static
 			 */
 			segment_size = 1;
 			break;
 
-		case io:
+		case ACPI_RSTYPE_IO:
 			/*
 			 * IO Port Resource
-			 */
-			/*
 			 * For this resource the size is static
 			 */
 			segment_size = 8;
 			break;
 
-		case fixed_io:
+		case ACPI_RSTYPE_FIXED_IO:
 			/*
 			 * Fixed IO Port Resource
-			 */
-			/*
 			 * For this resource the size is static
 			 */
 			segment_size = 4;
 			break;
 
-		case vendor_specific:
+		case ACPI_RSTYPE_VENDOR:
 			/*
 			 * Vendor Defined Resource
-			 */
-			/*
 			 * For a Vendor Specific resource, if the Length is
-			 *  between 1 and 7 it will be created as a Small
-			 *  Resource data type, otherwise it is a Large
-			 *  Resource data type.
+			 * between 1 and 7 it will be created as a Small
+			 * Resource data type, otherwise it is a Large
+			 * Resource data type.
 			 */
-			if(linked_list->data.vendor_specific.length > 7) {
+			if (linked_list->data.vendor_specific.length > 7) {
 				segment_size = 3;
 			}
 			else {
 				segment_size = 1;
 			}
-			segment_size +=
-				linked_list->data.vendor_specific.length;
+			segment_size += linked_list->data.vendor_specific.length;
 			break;
 
-		case end_tag:
+		case ACPI_RSTYPE_END_TAG:
 			/*
 			 * End Tag
-			 */
-			/*
 			 * For this resource the size is static
 			 */
 			segment_size = 2;
 			done = TRUE;
 			break;
 
-		case memory24:
+		case ACPI_RSTYPE_MEM24:
 			/*
 			 * 24-Bit Memory Resource
-			 */
-			/*
 			 * For this resource the size is static
 			 */
 			segment_size = 12;
 			break;
 
-		case memory32:
+		case ACPI_RSTYPE_MEM32:
 			/*
 			 * 32-Bit Memory Range Resource
-			 */
-			/*
 			 * For this resource the size is static
 			 */
 			segment_size = 20;
 			break;
 
-		case fixed_memory32:
+		case ACPI_RSTYPE_FIXED_MEM32:
 			/*
 			 * 32-Bit Fixed Memory Resource
-			 */
-			/*
 			 * For this resource the size is static
 			 */
 			segment_size = 12;
 			break;
 
-		case address16:
+		case ACPI_RSTYPE_ADDRESS16:
 			/*
 			 * 16-Bit Address Resource
-			 */
-			/*
 			 * The base size of this byte stream is 16. If a
-			 *  Resource Source string is not NULL, add 1 for
-			 *  the Index + the length of the null terminated
-			 *  string Resource Source + 1 for the null.
+			 * Resource Source string is not NULL, add 1 for
+			 * the Index + the length of the null terminated
+			 * string Resource Source + 1 for the null.
 			 */
 			segment_size = 16;
 
-			if(NULL != linked_list->data.address16.resource_source) {
+			if (NULL != linked_list->data.address16.resource_source.string_ptr) {
 				segment_size += (1 +
-					linked_list->data.address16.resource_source_string_length);
+					linked_list->data.address16.resource_source.string_length);
 			}
 			break;
 
-		case address32:
+		case ACPI_RSTYPE_ADDRESS32:
 			/*
 			 * 32-Bit Address Resource
-			 */
-			/*
 			 * The base size of this byte stream is 26. If a Resource
-			 *  Source string is not NULL, add 1 for the Index + the
-			 *  length of the null terminated string Resource Source +
-			 *  1 for the null.
+			 * Source string is not NULL, add 1 for the Index + the
+			 * length of the null terminated string Resource Source +
+			 * 1 for the null.
 			 */
 			segment_size = 26;
 
-			if(NULL != linked_list->data.address16.resource_source) {
+			if (NULL != linked_list->data.address32.resource_source.string_ptr) {
 				segment_size += (1 +
-					linked_list->data.address16.resource_source_string_length);
+					linked_list->data.address32.resource_source.string_length);
 			}
 			break;
 
-		case extended_irq:
+		case ACPI_RSTYPE_ADDRESS64:
 			/*
-			 * Extended IRQ Resource
+			 * 64-Bit Address Resource
+			 * The base size of this byte stream is 46. If a Resource
+			 * Source string is not NULL, add 1 for the Index + the
+			 * length of the null terminated string Resource Source +
+			 * 1 for the null.
 			 */
+			segment_size = 46;
+
+			if (NULL != linked_list->data.address64.resource_source.string_ptr) {
+				segment_size += (1 +
+					linked_list->data.address64.resource_source.string_length);
+			}
+			break;
+
+		case ACPI_RSTYPE_EXT_IRQ:
 			/*
+			 * Extended IRQ Resource
 			 * The base size of this byte stream is 9. This is for an
-			 *  Interrupt table length of 1.  For each additional
-			 *  interrupt, add 4.
+			 * Interrupt table length of 1.  For each additional
+			 * interrupt, add 4.
 			 * If a Resource Source string is not NULL, add 1 for the
-			 *  Index + the length of the null terminated string
-			 *  Resource Source + 1 for the null.
+			 * Index + the length of the null terminated string
+			 * Resource Source + 1 for the null.
 			 */
-			segment_size = 9;
+			segment_size = 9 +
+				((linked_list->data.extended_irq.number_of_interrupts - 1) * 4);
 
-			segment_size +=
-				(linked_list->data.extended_irq.number_of_interrupts -
-				 1) * 4;
-
-			if(NULL != ex_irq->resource_source) {
+			if (NULL != ex_irq->resource_source.string_ptr) {
 				segment_size += (1 +
-					linked_list->data.extended_irq.resource_source_string_length);
+					linked_list->data.extended_irq.resource_source.string_length);
 			}
 			break;
 
 		default:
 			/*
 			 * If we get here, everything is out of sync,
-			 *  so exit with an error
+			 * so exit with an error
 			 */
-			return (AE_AML_ERROR);
+			return (AE_AML_INVALID_RESOURCE_TYPE);
 			break;
 
 		} /* switch (Linked_list->Id) */
@@ -272,15 +252,14 @@
 		/*
 		 * Point to the next object
 		 */
-		linked_list = (RESOURCE *) ((NATIVE_UINT) linked_list +
-				  (NATIVE_UINT) linked_list->length);
+		linked_list = POINTER_ADD (ACPI_RESOURCE,
+				  linked_list, linked_list->length);
 	}
 
 	/*
 	 * This is the data the caller needs
 	 */
 	*size_needed = byte_stream_size_needed;
-
 	return (AE_OK);
 }
 
@@ -292,10 +271,10 @@
  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource byte stream
  *              Byte_stream_buffer_length - Size of Byte_stream_buffer
  *              Size_needed             - u32 pointer of the size buffer
- *                                          needed to properly return the
- *                                          parsed data
+ *                                        needed to properly return the
+ *                                        parsed data
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Takes the resource byte stream and parses it once, calculating
  *              the size buffer needed to hold the linked list that conveys
@@ -325,402 +304,383 @@
 
 	while (bytes_parsed < byte_stream_buffer_length) {
 		/*
-		 * Look at the next byte in the stream
+		 * The next byte in the stream is the resource type
 		 */
-		resource_type = *byte_stream_buffer;
+		resource_type = acpi_rs_get_resource_type (*byte_stream_buffer);
 
-		/*
-		 * See if this is a small or large resource
-		 */
-		if(resource_type & 0x80) {
+		switch (resource_type) {
+		case RESOURCE_DESC_MEMORY_24:
 			/*
-			 * Large Resource Type
+			 * 24-Bit Memory Resource
 			 */
-			switch (resource_type)
-			{
-			case MEMORY_RANGE_24:
-				/*
-				 * 24-Bit Memory Resource
-				 */
-				bytes_consumed = 12;
+			bytes_consumed = 12;
 
-				structure_size = sizeof (MEMORY24_RESOURCE) +
-						  RESOURCE_LENGTH_NO_DATA;
-				break;
+			structure_size = SIZEOF_RESOURCE (ACPI_RESOURCE_MEM24);
+			break;
 
-			case LARGE_VENDOR_DEFINED:
-				/*
-				 * Vendor Defined Resource
-				 */
-				buffer = byte_stream_buffer;
-				++buffer;
 
-				MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
-				bytes_consumed = temp16 + 3;
+		case RESOURCE_DESC_LARGE_VENDOR:
+			/*
+			 * Vendor Defined Resource
+			 */
+			buffer = byte_stream_buffer;
+			++buffer;
 
-				/*
-				 * Ensure a 32-bit boundary for the structure
-				 */
-				temp16 = (u16) ROUND_UP_TO_32_bITS (temp16);
+			MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
+			bytes_consumed = temp16 + 3;
 
-				structure_size = sizeof (VENDOR_RESOURCE) +
-						  RESOURCE_LENGTH_NO_DATA +
-						  (temp16 * sizeof (u8));
-				break;
+			/*
+			 * Ensure a 32-bit boundary for the structure
+			 */
+			temp16 = (u16) ROUND_UP_TO_32_bITS (temp16);
 
-			case MEMORY_RANGE_32:
-				/*
-				 * 32-Bit Memory Range Resource
-				 */
+			structure_size = SIZEOF_RESOURCE (ACPI_RESOURCE_VENDOR) +
+					   (temp16 * sizeof (u8));
+			break;
 
-				bytes_consumed = 20;
 
-				structure_size = sizeof (MEMORY32_RESOURCE) +
-						  RESOURCE_LENGTH_NO_DATA;
-				break;
+		case RESOURCE_DESC_MEMORY_32:
+			/*
+			 * 32-Bit Memory Range Resource
+			 */
 
-			case FIXED_MEMORY_RANGE_32:
-				/*
-				 * 32-Bit Fixed Memory Resource
-				 */
-				bytes_consumed = 12;
+			bytes_consumed = 20;
 
-				structure_size = sizeof(FIXED_MEMORY32_RESOURCE) +
-						  RESOURCE_LENGTH_NO_DATA;
-				break;
+			structure_size = SIZEOF_RESOURCE (ACPI_RESOURCE_MEM32);
+			break;
 
-			case DWORD_ADDRESS_SPACE:
-				/*
-				 * 32-Bit Address Resource
-				 */
-				buffer = byte_stream_buffer;
 
-				++buffer;
-				MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
+		case RESOURCE_DESC_FIXED_MEMORY_32:
+			/*
+			 * 32-Bit Fixed Memory Resource
+			 */
+			bytes_consumed = 12;
 
-				bytes_consumed = temp16 + 3;
+			structure_size = SIZEOF_RESOURCE (ACPI_RESOURCE_FIXED_MEM32);
+			break;
 
-				/*
-				 * Resource Source Index and Resource Source are
-				 *  optional elements.  Check the length of the
-				 *  Bytestream.  If it is greater than 23, that
-				 *  means that an Index exists and is followed by
-				 *  a null termininated string.  Therefore, set
-				 *  the temp variable to the length minus the minimum
-				 *  byte stream length plus the byte for the Index to
-				 *  determine the size of the NULL terminiated string.
-				 */
-				if (23 < temp16) {
-					temp8 = (u8) (temp16 - 24);
-				}
-				else {
-					temp8 = 0;
-				}
 
-				/*
-				 * Ensure a 32-bit boundary for the structure
-				 */
-				temp8 = (u8) ROUND_UP_TO_32_bITS (temp8);
+		case RESOURCE_DESC_QWORD_ADDRESS_SPACE:
+			/*
+			 * 64-Bit Address Resource
+			 */
+			buffer = byte_stream_buffer;
 
-				structure_size = sizeof (ADDRESS32_RESOURCE) +
-						  RESOURCE_LENGTH_NO_DATA +
-						  (temp8 * sizeof (u8));
-				break;
+			++buffer;
+			MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
 
-			case WORD_ADDRESS_SPACE:
-				/*
-				 * 16-Bit Address Resource
-				 */
-				buffer = byte_stream_buffer;
+			bytes_consumed = temp16 + 3;
 
-				++buffer;
-				MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
+			/*
+			 * Resource Source Index and Resource Source are
+			 * optional elements.  Check the length of the
+			 * Bytestream.  If it is greater than 43, that
+			 * means that an Index exists and is followed by
+			 * a null termininated string.  Therefore, set
+			 * the temp variable to the length minus the minimum
+			 * byte stream length plus the byte for the Index to
+			 * determine the size of the NULL terminiated string.
+			 */
+			if (43 < temp16) {
+				temp8 = (u8) (temp16 - 44);
+			}
+			else {
+				temp8 = 0;
+			}
 
-				bytes_consumed = temp16 + 3;
+			/*
+			 * Ensure a 64-bit boundary for the structure
+			 */
+			temp8 = (u8) ROUND_UP_TO_64_bITS (temp8);
 
-				/*
-				 * Resource Source Index and Resource Source are
-				 *  optional elements.  Check the length of the
-				 *  Bytestream.  If it is greater than 13, that
-				 *  means that an Index exists and is followed by
-				 *  a null termininated string.  Therefore, set
-				 *  the temp variable to the length minus the minimum
-				 *  byte stream length plus the byte for the Index to
-				 *  determine the size of the NULL terminiated string.
-				 */
-				if (13 < temp16) {
-					temp8 = (u8) (temp16 - 14);
-				}
-				else {
-					temp8 = 0;
-				}
+			structure_size = SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS64) +
+					   (temp8 * sizeof (u8));
+			break;
 
-				/*
-				 * Ensure a 32-bit boundry for the structure
-				 */
-				temp8 = (u8) ROUND_UP_TO_32_bITS (temp8);
 
-				structure_size = sizeof (ADDRESS16_RESOURCE) +
-						  RESOURCE_LENGTH_NO_DATA +
-						  (temp8 * sizeof (u8));
-				break;
+		case RESOURCE_DESC_DWORD_ADDRESS_SPACE:
+			/*
+			 * 32-Bit Address Resource
+			 */
+			buffer = byte_stream_buffer;
 
-			case EXTENDED_IRQ:
-				/*
-				 * Extended IRQ
-				 */
-				buffer = byte_stream_buffer;
+			++buffer;
+			MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
 
-				++buffer;
-				MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
+			bytes_consumed = temp16 + 3;
 
-				bytes_consumed = temp16 + 3;
+			/*
+			 * Resource Source Index and Resource Source are
+			 * optional elements.  Check the length of the
+			 * Bytestream.  If it is greater than 23, that
+			 * means that an Index exists and is followed by
+			 * a null termininated string.  Therefore, set
+			 * the temp variable to the length minus the minimum
+			 * byte stream length plus the byte for the Index to
+			 * determine the size of the NULL terminiated string.
+			 */
+			if (23 < temp16) {
+				temp8 = (u8) (temp16 - 24);
+			}
+			else {
+				temp8 = 0;
+			}
 
-				/*
-				 * Point past the length field and the
-				 *  Interrupt vector flags to save off the
-				 *  Interrupt table length to the Temp8 variable.
-				 */
-				buffer += 3;
-				temp8 = *buffer;
+			/*
+			 * Ensure a 32-bit boundary for the structure
+			 */
+			temp8 = (u8) ROUND_UP_TO_32_bITS (temp8);
 
-				/*
-				 * To compensate for multiple interrupt numbers,
-				 *  Add 4 bytes for each additional interrupts
-				 *  greater than 1
-				 */
-				additional_bytes = (u8) ((temp8 - 1) * 4);
+			structure_size = SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS32) +
+					   (temp8 * sizeof (u8));
+			break;
 
-				/*
-				 * Resource Source Index and Resource Source are
-				 *  optional elements.  Check the length of the
-				 *  Bytestream.  If it is greater than 9, that
-				 *  means that an Index exists and is followed by
-				 *  a null termininated string.  Therefore, set
-				 *  the temp variable to the length minus the minimum
-				 *  byte stream length plus the byte for the Index to
-				 *  determine the size of the NULL terminiated string.
-				 */
-				if (9 + additional_bytes < temp16) {
-					temp8 = (u8) (temp16 - (9 + additional_bytes));
-				}
 
-				else {
-					temp8 = 0;
-				}
+		case RESOURCE_DESC_WORD_ADDRESS_SPACE:
+			/*
+			 * 16-Bit Address Resource
+			 */
+			buffer = byte_stream_buffer;
 
-				/*
-				 * Ensure a 32-bit boundry for the structure
-				 */
-				temp8 = (u8) ROUND_UP_TO_32_bITS (temp8);
+			++buffer;
+			MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
 
-				structure_size = sizeof (EXTENDED_IRQ_RESOURCE) +
-						  RESOURCE_LENGTH_NO_DATA +
-						  (additional_bytes * sizeof (u8)) +
-						  (temp8 * sizeof (u8));
+			bytes_consumed = temp16 + 3;
 
-				break;
+			/*
+			 * Resource Source Index and Resource Source are
+			 * optional elements.  Check the length of the
+			 * Bytestream.  If it is greater than 13, that
+			 * means that an Index exists and is followed by
+			 * a null termininated string.  Therefore, set
+			 * the temp variable to the length minus the minimum
+			 * byte stream length plus the byte for the Index to
+			 * determine the size of the NULL terminiated string.
+			 */
+			if (13 < temp16) {
+				temp8 = (u8) (temp16 - 14);
+			}
+			else {
+				temp8 = 0;
+			}
 
-/* TBD: [Future] 64-bit not currently supported */
-/*
-			case 0x8A:
-				break;
-*/
+			/*
+			 * Ensure a 32-bit boundary for the structure
+			 */
+			temp8 = (u8) ROUND_UP_TO_32_bITS (temp8);
 
-			default:
-				/*
-				 * If we get here, everything is out of sync,
-				 *  so exit with an error
-				 */
-				return (AE_AML_ERROR);
-				break;
-			}
-		}
+			structure_size = SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS16) +
+					   (temp8 * sizeof (u8));
+			break;
 
-		else {
+
+		case RESOURCE_DESC_EXTENDED_XRUPT:
 			/*
-			 * Small Resource Type
-			 *  Only bits 7:3 are valid
+			 * Extended IRQ
 			 */
-			resource_type >>= 3;
+			buffer = byte_stream_buffer;
 
-			switch (resource_type)
-			{
-			case IRQ_FORMAT:
-				/*
-				 * IRQ Resource
-				 */
-				/*
-				 * Determine if it there are two or three
-				 *  trailing bytes
-				 */
-				buffer = byte_stream_buffer;
-				temp8 = *buffer;
+			++buffer;
+			MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
 
-				if(temp8 & 0x01) {
-					bytes_consumed = 4;
-				}
+			bytes_consumed = temp16 + 3;
 
-				else {
-					bytes_consumed = 3;
-				}
+			/*
+			 * Point past the length field and the
+			 * Interrupt vector flags to save off the
+			 * Interrupt table length to the Temp8 variable.
+			 */
+			buffer += 3;
+			temp8 = *buffer;
 
-				/*
-				 * Point past the descriptor
-				 */
-				++buffer;
+			/*
+			 * To compensate for multiple interrupt numbers, add 4 bytes for
+			 * each additional interrupts greater than 1
+			 */
+			additional_bytes = (u8) ((temp8 - 1) * 4);
 
-				/*
-				 * Look at the number of bits set
-				 */
-				MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
+			/*
+			 * Resource Source Index and Resource Source are
+			 * optional elements.  Check the length of the
+			 * Bytestream.  If it is greater than 9, that
+			 * means that an Index exists and is followed by
+			 * a null termininated string.  Therefore, set
+			 * the temp variable to the length minus the minimum
+			 * byte stream length plus the byte for the Index to
+			 * determine the size of the NULL terminiated string.
+			 */
+			if (9 + additional_bytes < temp16) {
+				temp8 = (u8) (temp16 - (9 + additional_bytes));
+			}
 
-				for (index = 0; index < 16; index++) {
-					if (temp16 & 0x1) {
-						++number_of_interrupts;
-					}
+			else {
+				temp8 = 0;
+			}
 
-					temp16 >>= 1;
-				}
+			/*
+			 * Ensure a 32-bit boundary for the structure
+			 */
+			temp8 = (u8) ROUND_UP_TO_32_bITS (temp8);
 
-				structure_size = sizeof (IO_RESOURCE) +
-						  RESOURCE_LENGTH_NO_DATA +
-						  (number_of_interrupts * sizeof (u32));
-				break;
+			structure_size = SIZEOF_RESOURCE (ACPI_RESOURCE_EXT_IRQ) +
+					   (additional_bytes * sizeof (u8)) +
+					   (temp8 * sizeof (u8));
+			break;
 
 
-			case DMA_FORMAT:
+		case RESOURCE_DESC_IRQ_FORMAT:
+			/*
+			 * IRQ Resource.
+			 * Determine if it there are two or three trailing bytes
+			 */
+			buffer = byte_stream_buffer;
+			temp8 = *buffer;
 
-				/*
-				 * DMA Resource
-				 */
-				buffer = byte_stream_buffer;
+			if(temp8 & 0x01) {
+				bytes_consumed = 4;
+			}
 
+			else {
 				bytes_consumed = 3;
+			}
 
-				/*
-				 * Point past the descriptor
-				 */
-				++buffer;
-
-				/*
-				 * Look at the number of bits set
-				 */
-				temp8 = *buffer;
+			/*
+			 * Point past the descriptor
+			 */
+			++buffer;
 
-				for(index = 0; index < 8; index++) {
-					if(temp8 & 0x1) {
-						++number_of_channels;
-					}
+			/*
+			 * Look at the number of bits set
+			 */
+			MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
 
-					temp8 >>= 1;
+			for (index = 0; index < 16; index++) {
+				if (temp16 & 0x1) {
+					++number_of_interrupts;
 				}
 
-				structure_size = sizeof (DMA_RESOURCE) +
-						  RESOURCE_LENGTH_NO_DATA +
-						  (number_of_channels * sizeof (u32));
-				break;
+				temp16 >>= 1;
+			}
 
+			structure_size = SIZEOF_RESOURCE (ACPI_RESOURCE_IO) +
+					   (number_of_interrupts * sizeof (u32));
+			break;
 
-			case START_DEPENDENT_TAG:
 
-				/*
-				 * Start Dependent Functions Resource
-				 */
-				/*
-				 * Determine if it there are two or three trailing bytes
-				 */
-				buffer = byte_stream_buffer;
-				temp8 = *buffer;
+		case RESOURCE_DESC_DMA_FORMAT:
+			/*
+			 * DMA Resource
+			 */
+			buffer = byte_stream_buffer;
+			bytes_consumed = 3;
 
-				if(temp8 & 0x01) {
-					bytes_consumed = 2;
-				}
-				else {
-					bytes_consumed = 1;
+			/*
+			 * Point past the descriptor
+			 */
+			++buffer;
+
+			/*
+			 * Look at the number of bits set
+			 */
+			temp8 = *buffer;
+
+			for(index = 0; index < 8; index++) {
+				if(temp8 & 0x1) {
+					++number_of_channels;
 				}
 
+				temp8 >>= 1;
+			}
 
-				structure_size =
-						sizeof (START_DEPENDENT_FUNCTIONS_RESOURCE) +
-						RESOURCE_LENGTH_NO_DATA;
-				break;
+			structure_size = SIZEOF_RESOURCE (ACPI_RESOURCE_DMA) +
+					   (number_of_channels * sizeof (u32));
+			break;
 
 
-			case END_DEPENDENT_TAG:
+		case RESOURCE_DESC_START_DEPENDENT:
+			/*
+			 * Start Dependent Functions Resource
+			 * Determine if it there are two or three trailing bytes
+			 */
+			buffer = byte_stream_buffer;
+			temp8 = *buffer;
 
-				/*
-				 * End Dependent Functions Resource
-				 */
+			if(temp8 & 0x01) {
+				bytes_consumed = 2;
+			}
+			else {
 				bytes_consumed = 1;
-				structure_size = RESOURCE_LENGTH;
-				break;
-
+			}
 
-			case IO_PORT_DESCRIPTOR:
-				/*
-				 * IO Port Resource
-				 */
-				bytes_consumed = 8;
-				structure_size = sizeof (IO_RESOURCE) +
-						  RESOURCE_LENGTH_NO_DATA;
-				break;
+			structure_size = SIZEOF_RESOURCE (ACPI_RESOURCE_START_DPF);
+			break;
 
 
-			case FIXED_LOCATION_IO_DESCRIPTOR:
+		case RESOURCE_DESC_END_DEPENDENT:
+			/*
+			 * End Dependent Functions Resource
+			 */
+			bytes_consumed = 1;
+			structure_size = ACPI_RESOURCE_LENGTH;
+			break;
 
-				/*
-				 * Fixed IO Port Resource
-				 */
-				bytes_consumed = 4;
-				structure_size = sizeof (FIXED_IO_RESOURCE) +
-						  RESOURCE_LENGTH_NO_DATA;
-				break;
 
+		case RESOURCE_DESC_IO_PORT:
+			/*
+			 * IO Port Resource
+			 */
+			bytes_consumed = 8;
+			structure_size = SIZEOF_RESOURCE (ACPI_RESOURCE_IO);
+			break;
 
-			case SMALL_VENDOR_DEFINED:
 
-				/*
-				 * Vendor Specific Resource
-				 */
-				buffer = byte_stream_buffer;
+		case RESOURCE_DESC_FIXED_IO_PORT:
+			/*
+			 * Fixed IO Port Resource
+			 */
+			bytes_consumed = 4;
+			structure_size = SIZEOF_RESOURCE (ACPI_RESOURCE_FIXED_IO);
+			break;
 
-				temp8 = *buffer;
-				temp8 = (u8) (temp8 & 0x7);
-				bytes_consumed = temp8 + 1;
 
-				/*
-				 * Ensure a 32-bit boundry for the structure
-				 */
-				temp8 = (u8) ROUND_UP_TO_32_bITS (temp8);
-				structure_size = sizeof (VENDOR_RESOURCE) +
-						  RESOURCE_LENGTH_NO_DATA +
-						  (temp8 * sizeof (u8));
-				break;
+		case RESOURCE_DESC_SMALL_VENDOR:
+			/*
+			 * Vendor Specific Resource
+			 */
+			buffer = byte_stream_buffer;
 
+			temp8 = *buffer;
+			temp8 = (u8) (temp8 & 0x7);
+			bytes_consumed = temp8 + 1;
 
-			case END_TAG:
+			/*
+			 * Ensure a 32-bit boundary for the structure
+			 */
+			temp8 = (u8) ROUND_UP_TO_32_bITS (temp8);
+			structure_size = SIZEOF_RESOURCE (ACPI_RESOURCE_VENDOR) +
+					   (temp8 * sizeof (u8));
+			break;
 
-				/*
-				 * End Tag
-				 */
-				bytes_consumed = 2;
-				structure_size = RESOURCE_LENGTH;
-				byte_stream_buffer_length = bytes_parsed;
-				break;
 
+		case RESOURCE_DESC_END_TAG:
+			/*
+			 * End Tag
+			 */
+			bytes_consumed = 2;
+			structure_size = ACPI_RESOURCE_LENGTH;
+			byte_stream_buffer_length = bytes_parsed;
+			break;
 
-			default:
-				/*
-				 * If we get here, everything is out of sync,
-				 *  so exit with an error
-				 */
-				return (AE_AML_ERROR);
-				break;
 
-			} /* switch */
+		default:
+			/*
+			 * If we get here, everything is out of sync,
+			 *  so exit with an error
+			 */
+			return (AE_AML_INVALID_RESOURCE_TYPE);
+			break;
+		}
 
-		}  /* if(Resource_type & 0x80) */
 
 		/*
 		 * Update the return value and counter
@@ -732,14 +692,13 @@
 		 * Set the byte stream to point to the next resource
 		 */
 		byte_stream_buffer += bytes_consumed;
-
 	}
 
+
 	/*
 	 * This is the data the caller needs
 	 */
 	*size_needed = buffer_size;
-
 	return (AE_OK);
 }
 
@@ -750,14 +709,14 @@
  *
  * PARAMETERS:  Package_object          - Pointer to the package object
  *              Buffer_size_needed      - u32 pointer of the size buffer
- *                                          needed to properly return the
- *                                          parsed data
+ *                                        needed to properly return the
+ *                                        parsed data
  *
- * RETURN:      Status  AE_OK
+ * RETURN:      Status
  *
  * DESCRIPTION: Given a package representing a PCI routing table, this
- *                calculates the size of the corresponding linked list of
- *                descriptions.
+ *              calculates the size of the corresponding linked list of
+ *              descriptions.
  *
  ******************************************************************************/
 
@@ -785,11 +744,6 @@
 	 * The minus one is to subtract the size of the u8 Source[1]
 	 * member because it is added below.
 	 *
-	 * NOTE: The Number_of_elements is incremented by one to add an end
-	 * table structure that is essentially a structure of zeros.
-	 */
-
-	/*
 	 * But each PRT_ENTRY structure has a pointer to a string and
 	 * the size of that string must be found.
 	 */
@@ -815,8 +769,7 @@
 		for (table_index = 0; table_index < 4 && !name_found; table_index++) {
 			if ((ACPI_TYPE_STRING == (*sub_object_list)->common.type) ||
 				((INTERNAL_TYPE_REFERENCE == (*sub_object_list)->common.type) &&
-					((*sub_object_list)->reference.op_code == AML_NAMEPATH_OP)))
-			{
+					((*sub_object_list)->reference.opcode == AML_INT_NAMEPATH_OP))) {
 				name_found = TRUE;
 			}
 
@@ -841,20 +794,21 @@
 				 */
 				temp_size_needed += (*sub_object_list)->string.length;
 			}
+
 			else {
-				temp_size_needed += acpi_ns_get_pathname_length ((*sub_object_list)->reference.node);
+				temp_size_needed += acpi_ns_get_pathname_length (
+						   (*sub_object_list)->reference.node);
 			}
 		}
 
 		else {
 			/*
 			 * If no name was found, then this is a NULL, which is
-			 *  translated as a u32 zero.
+			 * translated as a u32 zero.
 			 */
-			temp_size_needed += sizeof(u32);
+			temp_size_needed += sizeof (u32);
 		}
 
-
 		/* Round up the size since each element must be aligned */
 
 		temp_size_needed = ROUND_UP_TO_64_bITS (temp_size_needed);
@@ -866,7 +820,9 @@
 	}
 
 
-	*buffer_size_needed = temp_size_needed;
-
+	/*
+	 * Adding an extra element to the end of the list, essentially a NULL terminator
+	 */
+	*buffer_size_needed = temp_size_needed + sizeof (PCI_ROUTING_TABLE);
 	return (AE_OK);
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/resources/rscreate.c linux/drivers/acpi/resources/rscreate.c
--- v2.4.5/linux/drivers/acpi/resources/rscreate.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/resources/rscreate.c	Wed Jun 20 17:47:40 2001
@@ -1,9 +1,7 @@
 /*******************************************************************************
  *
- * Module Name: rscreate - Acpi_rs_create_resource_list
- *                         Acpi_rs_create_pci_routing_table
- *                         Acpi_rs_create_byte_stream
- *              $Revision: 25 $
+ * Module Name: rscreate - Create resource lists/tables
+ *              $Revision: 33 $
  *
  ******************************************************************************/
 
@@ -31,7 +29,7 @@
 #include "amlcode.h"
 #include "acnamesp.h"
 
-#define _COMPONENT          RESOURCE_MANAGER
+#define _COMPONENT          ACPI_RESOURCES
 	 MODULE_NAME         ("rscreate")
 
 
@@ -39,8 +37,7 @@
  *
  * FUNCTION:    Acpi_rs_create_resource_list
  *
- * PARAMETERS:
- *              Byte_stream_buffer      - Pointer to the resource byte stream
+ * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource byte stream
  *              Output_buffer           - Pointer to the user's buffer
  *              Output_buffer_length    - Pointer to the size of Output_buffer
  *
@@ -63,9 +60,9 @@
 {
 
 	ACPI_STATUS             status;
-	u8                      *byte_stream_start = NULL;
+	u8                      *byte_stream_start;
 	u32                     list_size_needed = 0;
-	u32                     byte_stream_buffer_length = 0;
+	u32                     byte_stream_buffer_length;
 
 
 	/*
@@ -79,8 +76,7 @@
 	 * Pass the Byte_stream_buffer into a module that can calculate
 	 * the buffer size needed for the linked list
 	 */
-	status = acpi_rs_calculate_list_length (byte_stream_start,
-			 byte_stream_buffer_length,
+	status = acpi_rs_calculate_list_length (byte_stream_start, byte_stream_buffer_length,
 			 &list_size_needed);
 
 	/*
@@ -101,8 +97,7 @@
 		 */
 		MEMSET (output_buffer, 0x00, *output_buffer_length);
 
-		status = acpi_rs_byte_stream_to_list (byte_stream_start,
-				 byte_stream_buffer_length,
+		status = acpi_rs_byte_stream_to_list (byte_stream_start, byte_stream_buffer_length,
 				 &output_buffer);
 
 		/*
@@ -121,7 +116,6 @@
 
 	*output_buffer_length = list_size_needed;
 	return (AE_OK);
-
 }
 
 
@@ -129,9 +123,8 @@
  *
  * FUNCTION:    Acpi_rs_create_pci_routing_table
  *
- * PARAMETERS:
- *              Package_object          - Pointer to an ACPI_OPERAND_OBJECT
- *                                          package
+ * PARAMETERS:  Package_object          - Pointer to an ACPI_OPERAND_OBJECT
+ *                                        package
  *              Output_buffer           - Pointer to the user's buffer
  *              Output_buffer_length    - Size of Output_buffer
  *
@@ -167,8 +160,12 @@
 	 * Params already validated, so we don't re-validate here
 	 */
 
-	status = acpi_rs_calculate_pci_routing_table_length(package_object,
-			  &buffer_size_needed);
+	status = acpi_rs_calculate_pci_routing_table_length (package_object,
+			 &buffer_size_needed);
+
+	if (!ACPI_SUCCESS(status)) {
+		return (status);
+	}
 
 	/*
 	 * If the data will fit into the available buffer
@@ -240,8 +237,7 @@
 			sub_object_list++;
 
 			if (ACPI_TYPE_INTEGER == (*sub_object_list)->common.type) {
-				user_prt->pin =
-						(u32) (*sub_object_list)->integer.value;
+				user_prt->pin = (u32) (*sub_object_list)->integer.value;
 			}
 
 			else {
@@ -253,10 +249,10 @@
 			 */
 			sub_object_list++;
 
-			switch ((*sub_object_list)->common.type)
-			{
+			switch ((*sub_object_list)->common.type) {
 			case INTERNAL_TYPE_REFERENCE:
-				if ((*sub_object_list)->reference.op_code != AML_NAMEPATH_OP) {
+
+				if ((*sub_object_list)->reference.opcode != AML_INT_NAMEPATH_OP) {
 					return (AE_BAD_DATA);
 				}
 
@@ -298,6 +294,7 @@
 
 
 			default:
+
 			   return (AE_BAD_DATA);
 			   break;
 			}
@@ -312,8 +309,7 @@
 			sub_object_list++;
 
 			if (ACPI_TYPE_INTEGER == (*sub_object_list)->common.type) {
-				user_prt->source_index =
-						(u32) (*sub_object_list)->integer.value;
+				user_prt->source_index = (u32) (*sub_object_list)->integer.value;
 			}
 
 			else {
@@ -338,7 +334,6 @@
 	 * Report the amount of buffer used
 	 */
 	*output_buffer_length = buffer_size_needed;
-
 	return (AE_OK);
 }
 
@@ -347,8 +342,7 @@
  *
  * FUNCTION:    Acpi_rs_create_byte_stream
  *
- * PARAMETERS:
- *              Linked_list_buffer      - Pointer to the resource linked list
+ * PARAMETERS:  Linked_list_buffer      - Pointer to the resource linked list
  *              Output_buffer           - Pointer to the user's buffer
  *              Output_buffer_length    - Size of Output_buffer
  *
@@ -365,7 +359,7 @@
 
 ACPI_STATUS
 acpi_rs_create_byte_stream (
-	RESOURCE                *linked_list_buffer,
+	ACPI_RESOURCE           *linked_list_buffer,
 	u8                      *output_buffer,
 	u32                     *output_buffer_length)
 {
@@ -400,8 +394,7 @@
 		 */
 		MEMSET (output_buffer, 0x00, *output_buffer_length);
 
-		status = acpi_rs_list_to_byte_stream (linked_list_buffer,
-				 byte_stream_size_needed,
+		status = acpi_rs_list_to_byte_stream (linked_list_buffer, byte_stream_size_needed,
 				 &output_buffer);
 
 		/*
@@ -412,6 +405,7 @@
 		}
 
 	}
+
 	else {
 		*output_buffer_length = byte_stream_size_needed;
 		return (AE_BUFFER_OVERFLOW);
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/resources/rsdump.c linux/drivers/acpi/resources/rsdump.c
--- v2.4.5/linux/drivers/acpi/resources/rsdump.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/resources/rsdump.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
- * Module Name: rsdump - Functions do dump out the resource structures.
- *              $Revision: 16 $
+ * Module Name: rsdump - Functions to display the resource structures.
+ *              $Revision: 20 $
  *
  ******************************************************************************/
 
@@ -27,7 +27,7 @@
 #include "acpi.h"
 #include "acresrc.h"
 
-#define _COMPONENT          RESOURCE_MANAGER
+#define _COMPONENT          ACPI_RESOURCES
 	 MODULE_NAME         ("rsdump")
 
 
@@ -37,7 +37,7 @@
  *
  * PARAMETERS:  Data            - pointer to the resource structure to dump.
  *
- * RETURN:
+ * RETURN:      None
  *
  * DESCRIPTION: Prints out the various members of the Data structure type.
  *
@@ -45,28 +45,24 @@
 
 void
 acpi_rs_dump_irq (
-	RESOURCE_DATA           *data)
+	ACPI_RESOURCE_DATA      *data)
 {
-	IRQ_RESOURCE            *irq_data = (IRQ_RESOURCE*) data;
+	ACPI_RESOURCE_IRQ       *irq_data = (ACPI_RESOURCE_IRQ *) data;
 	u8                      index = 0;
 
 
-	acpi_os_printf ("\t_iRQ Resource\n");
+	acpi_os_printf ("IRQ Resource\n");
 
-	acpi_os_printf ("\t\t%s Triggered\n",
-			 LEVEL_SENSITIVE == irq_data->edge_level ?
-			 "Level" : "Edge");
+	acpi_os_printf ("  %s Triggered\n",
+			 LEVEL_SENSITIVE == irq_data->edge_level ? "Level" : "Edge");
 
-	acpi_os_printf ("\t\t_active %s\n",
-			 ACTIVE_LOW == irq_data->active_high_low ?
-			 "Low" : "High");
+	acpi_os_printf ("  Active %s\n",
+			 ACTIVE_LOW == irq_data->active_high_low ? "Low" : "High");
 
-	acpi_os_printf ("\t\t%s\n",
-			 SHARED == irq_data->shared_exclusive ?
-			 "Shared" : "Exclusive");
+	acpi_os_printf ("  %s\n",
+			 SHARED == irq_data->shared_exclusive ? "Shared" : "Exclusive");
 
-	acpi_os_printf ("\t\t%X Interrupts ( ",
-			 irq_data->number_of_interrupts);
+	acpi_os_printf ("  %X Interrupts ( ", irq_data->number_of_interrupts);
 
 	for (index = 0; index < irq_data->number_of_interrupts; index++) {
 		acpi_os_printf ("%X ", irq_data->interrupts[index]);
@@ -83,7 +79,7 @@
  *
  * PARAMETERS:  Data            - pointer to the resource structure to dump.
  *
- * RETURN:
+ * RETURN:      None
  *
  * DESCRIPTION: Prints out the various members of the Data structure type.
  *
@@ -91,62 +87,59 @@
 
 void
 acpi_rs_dump_dma (
-	RESOURCE_DATA           *data)
+	ACPI_RESOURCE_DATA      *data)
 {
-	DMA_RESOURCE            *dma_data = (DMA_RESOURCE*) data;
+	ACPI_RESOURCE_DMA       *dma_data = (ACPI_RESOURCE_DMA *) data;
 	u8                      index = 0;
 
 
-	acpi_os_printf ("\t_dMA Resource\n");
+	acpi_os_printf ("DMA Resource\n");
 
-	switch (dma_data->type)
-	{
+	switch (dma_data->type) {
 	case COMPATIBILITY:
-		acpi_os_printf ("\t\t_compatibility mode\n");
+		acpi_os_printf ("  Compatibility mode\n");
 		break;
 
 	case TYPE_A:
-		acpi_os_printf ("\t\t_type A\n");
+		acpi_os_printf ("  Type A\n");
 		break;
 
 	case TYPE_B:
-		acpi_os_printf ("\t\t_type B\n");
+		acpi_os_printf ("  Type B\n");
 		break;
 
 	case TYPE_F:
-		acpi_os_printf ("\t\t_type F\n");
+		acpi_os_printf ("  Type F\n");
 		break;
 
 	default:
-		acpi_os_printf ("\t\t_invalid DMA type\n");
+		acpi_os_printf ("  Invalid DMA type\n");
 		break;
 	}
 
-	acpi_os_printf ("\t\t%sBus Master\n",
-			 BUS_MASTER == dma_data->bus_master ?
-			 "" : "Not a ");
+	acpi_os_printf ("  %sBus Master\n",
+			 BUS_MASTER == dma_data->bus_master ? "" : "Not a ");
 
-	switch (dma_data->transfer)
-	{
+
+	switch (dma_data->transfer) {
 	case TRANSFER_8:
-		acpi_os_printf ("\t\t8-bit only transfer\n");
+		acpi_os_printf ("  8-bit only transfer\n");
 		break;
 
 	case TRANSFER_8_16:
-		acpi_os_printf ("\t\t8 and 16-bit transfer\n");
+		acpi_os_printf ("  8 and 16-bit transfer\n");
 		break;
 
 	case TRANSFER_16:
-		acpi_os_printf ("\t\t16 bit only transfer\n");
+		acpi_os_printf ("  16 bit only transfer\n");
 		break;
 
 	default:
-		acpi_os_printf ("\t\t_invalid transfer preference\n");
+		acpi_os_printf ("  Invalid transfer preference\n");
 		break;
 	}
 
-	acpi_os_printf ("\t\t_number of Channels: %X ( ",
-			 dma_data->number_of_channels);
+	acpi_os_printf ("  Number of Channels: %X ( ", dma_data->number_of_channels);
 
 	for (index = 0; index < dma_data->number_of_channels; index++) {
 		acpi_os_printf ("%X ", dma_data->channels[index]);
@@ -163,7 +156,7 @@
  *
  * PARAMETERS:  Data            - pointer to the resource structure to dump.
  *
- * RETURN:
+ * RETURN:      None
  *
  * DESCRIPTION: Prints out the various members of the Data structure type.
  *
@@ -171,49 +164,47 @@
 
 void
 acpi_rs_dump_start_dependent_functions (
-	RESOURCE_DATA               *data)
+	ACPI_RESOURCE_DATA          *data)
 {
-	START_DEPENDENT_FUNCTIONS_RESOURCE *sdf_data =
-			   (START_DEPENDENT_FUNCTIONS_RESOURCE*) data;
+	ACPI_RESOURCE_START_DPF     *sdf_data = (ACPI_RESOURCE_START_DPF *) data;
+
 
+	acpi_os_printf ("Start Dependent Functions Resource\n");
 
-	acpi_os_printf ("\t_start Dependent Functions Resource\n");
 
-	switch (sdf_data->compatibility_priority)
-	{
+	switch (sdf_data->compatibility_priority) {
 	case GOOD_CONFIGURATION:
-		acpi_os_printf ("\t\t_good configuration\n");
+		acpi_os_printf ("  Good configuration\n");
 		break;
 
 	case ACCEPTABLE_CONFIGURATION:
-		acpi_os_printf ("\t\t_acceptable configuration\n");
+		acpi_os_printf ("  Acceptable configuration\n");
 		break;
 
 	case SUB_OPTIMAL_CONFIGURATION:
-		acpi_os_printf ("\t\t_sub-optimal configuration\n");
+		acpi_os_printf ("  Sub-optimal configuration\n");
 		break;
 
 	default:
-		acpi_os_printf ("\t\t_invalid compatibility priority\n");
+		acpi_os_printf ("  Invalid compatibility priority\n");
 		break;
 	}
 
-	switch(sdf_data->performance_robustness)
-	{
+	switch(sdf_data->performance_robustness) {
 	case GOOD_CONFIGURATION:
-		acpi_os_printf ("\t\t_good configuration\n");
+		acpi_os_printf ("  Good configuration\n");
 		break;
 
 	case ACCEPTABLE_CONFIGURATION:
-		acpi_os_printf ("\t\t_acceptable configuration\n");
+		acpi_os_printf ("  Acceptable configuration\n");
 		break;
 
 	case SUB_OPTIMAL_CONFIGURATION:
-		acpi_os_printf ("\t\t_sub-optimal configuration\n");
+		acpi_os_printf ("  Sub-optimal configuration\n");
 		break;
 
 	default:
-		acpi_os_printf ("\t\t_invalid performance "
+		acpi_os_printf ("  Invalid performance "
 				  "robustness preference\n");
 		break;
 	}
@@ -228,7 +219,7 @@
  *
  * PARAMETERS:  Data            - pointer to the resource structure to dump.
  *
- * RETURN:
+ * RETURN:      None
  *
  * DESCRIPTION: Prints out the various members of the Data structure type.
  *
@@ -236,26 +227,26 @@
 
 void
 acpi_rs_dump_io (
-	RESOURCE_DATA       *data)
+	ACPI_RESOURCE_DATA      *data)
 {
-	IO_RESOURCE         *io_data = (IO_RESOURCE*) data;
+	ACPI_RESOURCE_IO        *io_data = (ACPI_RESOURCE_IO *) data;
 
 
-	acpi_os_printf ("\t_io Resource\n");
+	acpi_os_printf ("Io Resource\n");
 
-	acpi_os_printf ("\t\t%d bit decode\n",
+	acpi_os_printf ("  %d bit decode\n",
 			 DECODE_16 == io_data->io_decode ? 16 : 10);
 
-	acpi_os_printf ("\t\t_range minimum base: %08X\n",
+	acpi_os_printf ("  Range minimum base: %08X\n",
 			 io_data->min_base_address);
 
-	acpi_os_printf ("\t\t_range maximum base: %08X\n",
+	acpi_os_printf ("  Range maximum base: %08X\n",
 			 io_data->max_base_address);
 
-	acpi_os_printf ("\t\t_alignment: %08X\n",
+	acpi_os_printf ("  Alignment: %08X\n",
 			 io_data->alignment);
 
-	acpi_os_printf ("\t\t_range Length: %08X\n",
+	acpi_os_printf ("  Range Length: %08X\n",
 			 io_data->range_length);
 
 	return;
@@ -268,7 +259,7 @@
  *
  * PARAMETERS:  Data            - pointer to the resource structure to dump.
  *
- * RETURN:
+ * RETURN:      None
  *
  * DESCRIPTION: Prints out the various members of the Data structure type.
  *
@@ -276,16 +267,16 @@
 
 void
 acpi_rs_dump_fixed_io (
-	RESOURCE_DATA           *data)
+	ACPI_RESOURCE_DATA      *data)
 {
-	FIXED_IO_RESOURCE       *fixed_io_data = (FIXED_IO_RESOURCE*) data;
+	ACPI_RESOURCE_FIXED_IO  *fixed_io_data = (ACPI_RESOURCE_FIXED_IO *) data;
 
 
-	acpi_os_printf ("\t_fixed Io Resource\n");
-	acpi_os_printf ("\t\t_range base address: %08X",
+	acpi_os_printf ("Fixed Io Resource\n");
+	acpi_os_printf ("  Range base address: %08X",
 			 fixed_io_data->base_address);
 
-	acpi_os_printf ("\t\t_range length: %08X",
+	acpi_os_printf ("  Range length: %08X",
 			 fixed_io_data->range_length);
 
 	return;
@@ -298,7 +289,7 @@
  *
  * PARAMETERS:  Data            - pointer to the resource structure to dump.
  *
- * RETURN:
+ * RETURN:      None
  *
  * DESCRIPTION: Prints out the various members of the Data structure type.
  *
@@ -306,18 +297,18 @@
 
 void
 acpi_rs_dump_vendor_specific (
-	RESOURCE_DATA           *data)
+	ACPI_RESOURCE_DATA      *data)
 {
-	VENDOR_RESOURCE         *vendor_data = (VENDOR_RESOURCE*) data;
+	ACPI_RESOURCE_VENDOR    *vendor_data = (ACPI_RESOURCE_VENDOR *) data;
 	u16                     index = 0;
 
 
-	acpi_os_printf ("\t_vendor Specific Resource\n");
+	acpi_os_printf ("Vendor Specific Resource\n");
 
-	acpi_os_printf ("\t\t_length: %08X\n", vendor_data->length);
+	acpi_os_printf ("  Length: %08X\n", vendor_data->length);
 
 	for (index = 0; index < vendor_data->length; index++) {
-		acpi_os_printf ("\t\t_byte %X: %08X\n",
+		acpi_os_printf ("  Byte %X: %08X\n",
 				 index, vendor_data->reserved[index]);
 	}
 
@@ -331,7 +322,7 @@
  *
  * PARAMETERS:  Data            - pointer to the resource structure to dump.
  *
- * RETURN:
+ * RETURN:      None
  *
  * DESCRIPTION: Prints out the various members of the Data structure type.
  *
@@ -339,28 +330,28 @@
 
 void
 acpi_rs_dump_memory24 (
-	RESOURCE_DATA           *data)
+	ACPI_RESOURCE_DATA      *data)
 {
-	MEMORY24_RESOURCE       *memory24_data = (MEMORY24_RESOURCE*) data;
+	ACPI_RESOURCE_MEM24     *memory24_data = (ACPI_RESOURCE_MEM24 *) data;
 
 
-	acpi_os_printf ("\t24-Bit Memory Range Resource\n");
+	acpi_os_printf ("24-Bit Memory Range Resource\n");
 
-	acpi_os_printf ("\t\t_read%s\n",
+	acpi_os_printf ("  Read%s\n",
 			 READ_WRITE_MEMORY ==
 			 memory24_data->read_write_attribute ?
 			 "/Write" : " only");
 
-	acpi_os_printf ("\t\t_range minimum base: %08X\n",
+	acpi_os_printf ("  Range minimum base: %08X\n",
 			 memory24_data->min_base_address);
 
-	acpi_os_printf ("\t\t_range maximum base: %08X\n",
+	acpi_os_printf ("  Range maximum base: %08X\n",
 			 memory24_data->max_base_address);
 
-	acpi_os_printf ("\t\t_alignment: %08X\n",
+	acpi_os_printf ("  Alignment: %08X\n",
 			 memory24_data->alignment);
 
-	acpi_os_printf ("\t\t_range length: %08X\n",
+	acpi_os_printf ("  Range length: %08X\n",
 			 memory24_data->range_length);
 
 	return;
@@ -373,7 +364,7 @@
  *
  * PARAMETERS:  Data            - pointer to the resource structure to dump.
  *
- * RETURN:
+ * RETURN:      None
  *
  * DESCRIPTION: Prints out the various members of the Data structure type.
  *
@@ -381,28 +372,28 @@
 
 void
 acpi_rs_dump_memory32 (
-	RESOURCE_DATA           *data)
+	ACPI_RESOURCE_DATA      *data)
 {
-	MEMORY32_RESOURCE       *memory32_data = (MEMORY32_RESOURCE*) data;
+	ACPI_RESOURCE_MEM32     *memory32_data = (ACPI_RESOURCE_MEM32 *) data;
 
 
-	acpi_os_printf ("\t32-Bit Memory Range Resource\n");
+	acpi_os_printf ("32-Bit Memory Range Resource\n");
 
-	acpi_os_printf ("\t\t_read%s\n",
+	acpi_os_printf ("  Read%s\n",
 			 READ_WRITE_MEMORY ==
 			 memory32_data->read_write_attribute ?
 			 "/Write" : " only");
 
-	acpi_os_printf ("\t\t_range minimum base: %08X\n",
+	acpi_os_printf ("  Range minimum base: %08X\n",
 			 memory32_data->min_base_address);
 
-	acpi_os_printf ("\t\t_range maximum base: %08X\n",
+	acpi_os_printf ("  Range maximum base: %08X\n",
 			 memory32_data->max_base_address);
 
-	acpi_os_printf ("\t\t_alignment: %08X\n",
+	acpi_os_printf ("  Alignment: %08X\n",
 			 memory32_data->alignment);
 
-	acpi_os_printf ("\t\t_range length: %08X\n",
+	acpi_os_printf ("  Range length: %08X\n",
 			 memory32_data->range_length);
 
 	return;
@@ -423,22 +414,22 @@
 
 void
 acpi_rs_dump_fixed_memory32 (
-	RESOURCE_DATA           *data)
+	ACPI_RESOURCE_DATA          *data)
 {
-	FIXED_MEMORY32_RESOURCE *fixed_memory32_data = (FIXED_MEMORY32_RESOURCE*) data;
+	ACPI_RESOURCE_FIXED_MEM32   *fixed_memory32_data = (ACPI_RESOURCE_FIXED_MEM32 *) data;
 
 
-	acpi_os_printf ("\t32-Bit Fixed Location Memory Range Resource\n");
+	acpi_os_printf ("32-Bit Fixed Location Memory Range Resource\n");
 
-	acpi_os_printf ("\t\t_read%s\n",
+	acpi_os_printf ("  Read%s\n",
 			 READ_WRITE_MEMORY ==
 			 fixed_memory32_data->read_write_attribute ?
 			 "/Write" : " Only");
 
-	acpi_os_printf ("\t\t_range base address: %08X\n",
+	acpi_os_printf ("  Range base address: %08X\n",
 			 fixed_memory32_data->range_base_address);
 
-	acpi_os_printf ("\t\t_range length: %08X\n",
+	acpi_os_printf ("  Range length: %08X\n",
 			 fixed_memory32_data->range_length);
 
 	return;
@@ -451,7 +442,7 @@
  *
  * PARAMETERS:  Data            - pointer to the resource structure to dump.
  *
- * RETURN:
+ * RETURN:      None
  *
  * DESCRIPTION: Prints out the various members of the Data structure type.
  *
@@ -459,49 +450,47 @@
 
 void
 acpi_rs_dump_address16 (
-	RESOURCE_DATA           *data)
+	ACPI_RESOURCE_DATA      *data)
 {
-	ADDRESS16_RESOURCE      *address16_data = (ADDRESS16_RESOURCE*) data;
+	ACPI_RESOURCE_ADDRESS16 *address16_data = (ACPI_RESOURCE_ADDRESS16 *) data;
 
 
-	acpi_os_printf ("\t16-Bit Address Space Resource\n");
-	acpi_os_printf ("\t\t_resource Type: ");
+	acpi_os_printf ("16-Bit Address Space Resource\n");
+	acpi_os_printf ("  Resource Type: ");
 
-	switch (address16_data->resource_type)
-	{
+	switch (address16_data->resource_type) {
 	case MEMORY_RANGE:
 
 		acpi_os_printf ("Memory Range\n");
 
-		switch (address16_data->attribute.memory.cache_attribute)
-		{
+		switch (address16_data->attribute.memory.cache_attribute) {
 		case NON_CACHEABLE_MEMORY:
-			acpi_os_printf ("\t\t_type Specific: "
+			acpi_os_printf ("  Type Specific: "
 					  "Noncacheable memory\n");
 			break;
 
 		case CACHABLE_MEMORY:
-			acpi_os_printf ("\t\t_type Specific: "
+			acpi_os_printf ("  Type Specific: "
 					  "Cacheable memory\n");
 			break;
 
 		case WRITE_COMBINING_MEMORY:
-			acpi_os_printf ("\t\t_type Specific: "
+			acpi_os_printf ("  Type Specific: "
 					  "Write-combining memory\n");
 			break;
 
 		case PREFETCHABLE_MEMORY:
-			acpi_os_printf ("\t\t_type Specific: "
+			acpi_os_printf ("  Type Specific: "
 					  "Prefetchable memory\n");
 			break;
 
 		default:
-			acpi_os_printf ("\t\t_type Specific: "
+			acpi_os_printf ("  Type Specific: "
 					  "Invalid cache attribute\n");
 			break;
 		}
 
-		acpi_os_printf ("\t\t_type Specific: Read%s\n",
+		acpi_os_printf ("  Type Specific: Read%s\n",
 			READ_WRITE_MEMORY ==
 			address16_data->attribute.memory.read_write_attribute ?
 			"/Write" : " Only");
@@ -511,25 +500,24 @@
 
 		acpi_os_printf ("I/O Range\n");
 
-		switch (address16_data->attribute.io.range_attribute)
-		{
+		switch (address16_data->attribute.io.range_attribute) {
 		case NON_ISA_ONLY_RANGES:
-			acpi_os_printf ("\t\t_type Specific: "
+			acpi_os_printf ("  Type Specific: "
 					  "Non-ISA Io Addresses\n");
 			break;
 
 		case ISA_ONLY_RANGES:
-			acpi_os_printf ("\t\t_type Specific: "
+			acpi_os_printf ("  Type Specific: "
 					  "ISA Io Addresses\n");
 			break;
 
 		case ENTIRE_RANGE:
-			acpi_os_printf ("\t\t_type Specific: "
+			acpi_os_printf ("  Type Specific: "
 					  "ISA and non-ISA Io Addresses\n");
 			break;
 
 		default:
-			acpi_os_printf ("\t\t_type Specific: "
+			acpi_os_printf ("  Type Specific: "
 					  "Invalid range attribute\n");
 			break;
 		}
@@ -546,42 +534,42 @@
 		return;
 	}
 
-	acpi_os_printf ("\t\t_resource %s\n",
+	acpi_os_printf ("  Resource %s\n",
 			CONSUMER == address16_data->producer_consumer ?
 			"Consumer" : "Producer");
 
-	acpi_os_printf ("\t\t%s decode\n",
+	acpi_os_printf ("  %s decode\n",
 			 SUB_DECODE == address16_data->decode ?
 			 "Subtractive" : "Positive");
 
-	acpi_os_printf ("\t\t_min address is %s fixed\n",
+	acpi_os_printf ("  Min address is %s fixed\n",
 			 ADDRESS_FIXED == address16_data->min_address_fixed ?
 			 "" : "not");
 
-	acpi_os_printf ("\t\t_max address is %s fixed\n",
+	acpi_os_printf ("  Max address is %s fixed\n",
 			 ADDRESS_FIXED == address16_data->max_address_fixed ?
 			 "" : "not");
 
-	acpi_os_printf ("\t\t_granularity: %08X\n",
+	acpi_os_printf ("  Granularity: %08X\n",
 			 address16_data->granularity);
 
-	acpi_os_printf ("\t\t_address range min: %08X\n",
+	acpi_os_printf ("  Address range min: %08X\n",
 			 address16_data->min_address_range);
 
-	acpi_os_printf ("\t\t_address range max: %08X\n",
+	acpi_os_printf ("  Address range max: %08X\n",
 			 address16_data->max_address_range);
 
-	acpi_os_printf ("\t\t_address translation offset: %08X\n",
+	acpi_os_printf ("  Address translation offset: %08X\n",
 			 address16_data->address_translation_offset);
 
-	acpi_os_printf ("\t\t_address Length: %08X\n",
+	acpi_os_printf ("  Address Length: %08X\n",
 			 address16_data->address_length);
 
-	if (0xFF != address16_data->resource_source_index) {
-		acpi_os_printf ("\t\t_resource Source Index: %X\n",
-				 address16_data->resource_source_index);
-		acpi_os_printf ("\t\t_resource Source: %s\n",
-				 address16_data->resource_source);
+	if (0xFF != address16_data->resource_source.index) {
+		acpi_os_printf ("  Resource Source Index: %X\n",
+				 address16_data->resource_source.index);
+		acpi_os_printf ("  Resource Source: %s\n",
+				 address16_data->resource_source.string_ptr);
 	}
 
 	return;
@@ -594,7 +582,7 @@
  *
  * PARAMETERS:  Data            - pointer to the resource structure to dump.
  *
- * RETURN:
+ * RETURN:      None
  *
  * DESCRIPTION: Prints out the various members of the Data structure type.
  *
@@ -602,48 +590,46 @@
 
 void
 acpi_rs_dump_address32 (
-	RESOURCE_DATA           *data)
+	ACPI_RESOURCE_DATA      *data)
 {
-	ADDRESS32_RESOURCE      *address32_data = (ADDRESS32_RESOURCE*) data;
+	ACPI_RESOURCE_ADDRESS32 *address32_data = (ACPI_RESOURCE_ADDRESS32 *) data;
 
 
-	acpi_os_printf ("\t32-Bit Address Space Resource\n");
+	acpi_os_printf ("32-Bit Address Space Resource\n");
 
-	switch (address32_data->resource_type)
-	{
+	switch (address32_data->resource_type) {
 	case MEMORY_RANGE:
 
-		acpi_os_printf ("\t\t_resource Type: Memory Range\n");
+		acpi_os_printf ("  Resource Type: Memory Range\n");
 
-		switch (address32_data->attribute.memory.cache_attribute)
-		{
+		switch (address32_data->attribute.memory.cache_attribute) {
 		case NON_CACHEABLE_MEMORY:
-			acpi_os_printf ("\t\t_type Specific: "
+			acpi_os_printf ("  Type Specific: "
 					  "Noncacheable memory\n");
 			break;
 
 		case CACHABLE_MEMORY:
-			acpi_os_printf ("\t\t_type Specific: "
+			acpi_os_printf ("  Type Specific: "
 					  "Cacheable memory\n");
 			break;
 
 		case WRITE_COMBINING_MEMORY:
-			acpi_os_printf ("\t\t_type Specific: "
+			acpi_os_printf ("  Type Specific: "
 					  "Write-combining memory\n");
 			break;
 
 		case PREFETCHABLE_MEMORY:
-			acpi_os_printf ("\t\t_type Specific: "
+			acpi_os_printf ("  Type Specific: "
 					  "Prefetchable memory\n");
 			break;
 
 		default:
-			acpi_os_printf ("\t\t_type Specific: "
+			acpi_os_printf ("  Type Specific: "
 					  "Invalid cache attribute\n");
 			break;
 		}
 
-		acpi_os_printf ("\t\t_type Specific: Read%s\n",
+		acpi_os_printf ("  Type Specific: Read%s\n",
 			READ_WRITE_MEMORY ==
 			address32_data->attribute.memory.read_write_attribute ?
 			"/Write" : " Only");
@@ -651,27 +637,26 @@
 
 	case IO_RANGE:
 
-		acpi_os_printf ("\t\t_resource Type: Io Range\n");
+		acpi_os_printf ("  Resource Type: Io Range\n");
 
-		switch (address32_data->attribute.io.range_attribute)
-			{
+		switch (address32_data->attribute.io.range_attribute) {
 			case NON_ISA_ONLY_RANGES:
-				acpi_os_printf ("\t\t_type Specific: "
+				acpi_os_printf ("  Type Specific: "
 						  "Non-ISA Io Addresses\n");
 				break;
 
 			case ISA_ONLY_RANGES:
-				acpi_os_printf ("\t\t_type Specific: "
+				acpi_os_printf ("  Type Specific: "
 						  "ISA Io Addresses\n");
 				break;
 
 			case ENTIRE_RANGE:
-				acpi_os_printf ("\t\t_type Specific: "
+				acpi_os_printf ("  Type Specific: "
 						  "ISA and non-ISA Io Addresses\n");
 				break;
 
 			default:
-				acpi_os_printf ("\t\t_type Specific: "
+				acpi_os_printf ("  Type Specific: "
 						  "Invalid Range attribute");
 				break;
 			}
@@ -679,51 +664,190 @@
 
 	case BUS_NUMBER_RANGE:
 
-		acpi_os_printf ("\t\t_resource Type: Bus Number Range\n");
+		acpi_os_printf ("  Resource Type: Bus Number Range\n");
 		break;
 
 	default:
 
-		acpi_os_printf ("\t\t_invalid Resource Type..exiting.\n");
+		acpi_os_printf ("  Invalid Resource Type..exiting.\n");
 		return;
 	}
 
-	acpi_os_printf ("\t\t_resource %s\n",
+	acpi_os_printf ("  Resource %s\n",
 			 CONSUMER == address32_data->producer_consumer ?
 			 "Consumer" : "Producer");
 
-	acpi_os_printf ("\t\t%s decode\n",
+	acpi_os_printf ("  %s decode\n",
 			 SUB_DECODE == address32_data->decode ?
 			 "Subtractive" : "Positive");
 
-	acpi_os_printf ("\t\t_min address is %s fixed\n",
+	acpi_os_printf ("  Min address is %s fixed\n",
 			 ADDRESS_FIXED == address32_data->min_address_fixed ?
 			 "" : "not ");
 
-	acpi_os_printf ("\t\t_max address is %s fixed\n",
+	acpi_os_printf ("  Max address is %s fixed\n",
 			 ADDRESS_FIXED == address32_data->max_address_fixed ?
 			 "" : "not ");
 
-	acpi_os_printf ("\t\t_granularity: %08X\n",
+	acpi_os_printf ("  Granularity: %08X\n",
 			 address32_data->granularity);
 
-	acpi_os_printf ("\t\t_address range min: %08X\n",
+	acpi_os_printf ("  Address range min: %08X\n",
 			 address32_data->min_address_range);
 
-	acpi_os_printf ("\t\t_address range max: %08X\n",
+	acpi_os_printf ("  Address range max: %08X\n",
 			 address32_data->max_address_range);
 
-	acpi_os_printf ("\t\t_address translation offset: %08X\n",
+	acpi_os_printf ("  Address translation offset: %08X\n",
 			 address32_data->address_translation_offset);
 
-	acpi_os_printf ("\t\t_address Length: %08X\n",
+	acpi_os_printf ("  Address Length: %08X\n",
 			 address32_data->address_length);
 
-	if(0xFF != address32_data->resource_source_index) {
-		acpi_os_printf ("\t\t_resource Source Index: %X\n",
-				 address32_data->resource_source_index);
-		acpi_os_printf ("\t\t_resource Source: %s\n",
-				 address32_data->resource_source);
+	if(0xFF != address32_data->resource_source.index) {
+		acpi_os_printf ("  Resource Source Index: %X\n",
+				 address32_data->resource_source.index);
+		acpi_os_printf ("  Resource Source: %s\n",
+				 address32_data->resource_source.string_ptr);
+	}
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_rs_dump_address64
+ *
+ * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Prints out the various members of the Data structure type.
+ *
+ ******************************************************************************/
+
+void
+acpi_rs_dump_address64 (
+	ACPI_RESOURCE_DATA      *data)
+{
+	ACPI_RESOURCE_ADDRESS64 *address64_data = (ACPI_RESOURCE_ADDRESS64 *) data;
+
+
+	acpi_os_printf ("64-Bit Address Space Resource\n");
+
+	switch (address64_data->resource_type) {
+	case MEMORY_RANGE:
+
+		acpi_os_printf ("  Resource Type: Memory Range\n");
+
+		switch (address64_data->attribute.memory.cache_attribute) {
+		case NON_CACHEABLE_MEMORY:
+			acpi_os_printf ("  Type Specific: "
+					  "Noncacheable memory\n");
+			break;
+
+		case CACHABLE_MEMORY:
+			acpi_os_printf ("  Type Specific: "
+					  "Cacheable memory\n");
+			break;
+
+		case WRITE_COMBINING_MEMORY:
+			acpi_os_printf ("  Type Specific: "
+					  "Write-combining memory\n");
+			break;
+
+		case PREFETCHABLE_MEMORY:
+			acpi_os_printf ("  Type Specific: "
+					  "Prefetchable memory\n");
+			break;
+
+		default:
+			acpi_os_printf ("  Type Specific: "
+					  "Invalid cache attribute\n");
+			break;
+		}
+
+		acpi_os_printf ("  Type Specific: Read%s\n",
+			READ_WRITE_MEMORY ==
+			address64_data->attribute.memory.read_write_attribute ?
+			"/Write" : " Only");
+		break;
+
+	case IO_RANGE:
+
+		acpi_os_printf ("  Resource Type: Io Range\n");
+
+		switch (address64_data->attribute.io.range_attribute) {
+			case NON_ISA_ONLY_RANGES:
+				acpi_os_printf ("  Type Specific: "
+						  "Non-ISA Io Addresses\n");
+				break;
+
+			case ISA_ONLY_RANGES:
+				acpi_os_printf ("  Type Specific: "
+						  "ISA Io Addresses\n");
+				break;
+
+			case ENTIRE_RANGE:
+				acpi_os_printf ("  Type Specific: "
+						  "ISA and non-ISA Io Addresses\n");
+				break;
+
+			default:
+				acpi_os_printf ("  Type Specific: "
+						  "Invalid Range attribute");
+				break;
+			}
+		break;
+
+	case BUS_NUMBER_RANGE:
+
+		acpi_os_printf ("  Resource Type: Bus Number Range\n");
+		break;
+
+	default:
+
+		acpi_os_printf ("  Invalid Resource Type..exiting.\n");
+		return;
+	}
+
+	acpi_os_printf ("  Resource %s\n",
+			 CONSUMER == address64_data->producer_consumer ?
+			 "Consumer" : "Producer");
+
+	acpi_os_printf ("  %s decode\n",
+			 SUB_DECODE == address64_data->decode ?
+			 "Subtractive" : "Positive");
+
+	acpi_os_printf ("  Min address is %s fixed\n",
+			 ADDRESS_FIXED == address64_data->min_address_fixed ?
+			 "" : "not ");
+
+	acpi_os_printf ("  Max address is %s fixed\n",
+			 ADDRESS_FIXED == address64_data->max_address_fixed ?
+			 "" : "not ");
+
+	acpi_os_printf ("  Granularity: %16X\n",
+			 address64_data->granularity);
+
+	acpi_os_printf ("  Address range min: %16X\n",
+			 address64_data->min_address_range);
+
+	acpi_os_printf ("  Address range max: %16X\n",
+			 address64_data->max_address_range);
+
+	acpi_os_printf ("  Address translation offset: %16X\n",
+			 address64_data->address_translation_offset);
+
+	acpi_os_printf ("  Address Length: %16X\n",
+			 address64_data->address_length);
+
+	if(0xFF != address64_data->resource_source.index) {
+		acpi_os_printf ("  Resource Source Index: %X\n",
+				 address64_data->resource_source.index);
+		acpi_os_printf ("  Resource Source: %s\n",
+				 address64_data->resource_source.string_ptr);
 	}
 
 	return;
@@ -736,7 +860,7 @@
  *
  * PARAMETERS:  Data            - pointer to the resource structure to dump.
  *
- * RETURN:
+ * RETURN:      None
  *
  * DESCRIPTION: Prints out the various members of the Data structure type.
  *
@@ -744,31 +868,31 @@
 
 void
 acpi_rs_dump_extended_irq (
-	RESOURCE_DATA           *data)
+	ACPI_RESOURCE_DATA      *data)
 {
-	EXTENDED_IRQ_RESOURCE   *ext_irq_data = (EXTENDED_IRQ_RESOURCE*) data;
+	ACPI_RESOURCE_EXT_IRQ   *ext_irq_data = (ACPI_RESOURCE_EXT_IRQ *) data;
 	u8                      index = 0;
 
 
-	acpi_os_printf ("\t_extended IRQ Resource\n");
+	acpi_os_printf ("Extended IRQ Resource\n");
 
-	acpi_os_printf ("\t\t_resource %s\n",
+	acpi_os_printf ("  Resource %s\n",
 			 CONSUMER == ext_irq_data->producer_consumer ?
 			 "Consumer" : "Producer");
 
-	acpi_os_printf ("\t\t%s\n",
+	acpi_os_printf ("  %s\n",
 			 LEVEL_SENSITIVE == ext_irq_data->edge_level ?
 			 "Level" : "Edge");
 
-	acpi_os_printf ("\t\t_active %s\n",
+	acpi_os_printf ("  Active %s\n",
 			 ACTIVE_LOW == ext_irq_data->active_high_low ?
 			 "low" : "high");
 
-	acpi_os_printf ("\t\t%s\n",
+	acpi_os_printf ("  %s\n",
 			 SHARED == ext_irq_data->shared_exclusive ?
 			 "Shared" : "Exclusive");
 
-	acpi_os_printf ("\t\t_interrupts : %X ( ",
+	acpi_os_printf ("  Interrupts : %X ( ",
 			 ext_irq_data->number_of_interrupts);
 
 	for (index = 0; index < ext_irq_data->number_of_interrupts; index++) {
@@ -777,11 +901,11 @@
 
 	acpi_os_printf (")\n");
 
-	if(0xFF != ext_irq_data->resource_source_index) {
-		acpi_os_printf ("\t\t_resource Source Index: %X",
-				 ext_irq_data->resource_source_index);
-		acpi_os_printf ("\t\t_resource Source: %s",
-				 ext_irq_data->resource_source);
+	if(0xFF != ext_irq_data->resource_source.index) {
+		acpi_os_printf ("  Resource Source Index: %X",
+				 ext_irq_data->resource_source.index);
+		acpi_os_printf ("  Resource Source: %s",
+				 ext_irq_data->resource_source.string_ptr);
 	}
 
 	return;
@@ -794,7 +918,7 @@
  *
  * PARAMETERS:  Data            - pointer to the resource structure to dump.
  *
- * RETURN:
+ * RETURN:      None
  *
  * DESCRIPTION: Dispatches the structure to the correct dump routine.
  *
@@ -802,7 +926,7 @@
 
 void
 acpi_rs_dump_resource_list (
-	RESOURCE            *resource)
+	ACPI_RESOURCE       *resource)
 {
 	u8                  count = 0;
 	u8                  done = FALSE;
@@ -810,66 +934,69 @@
 
 	if (acpi_dbg_level & TRACE_RESOURCES && _COMPONENT & acpi_dbg_layer) {
 		while (!done) {
-			acpi_os_printf ("\t_resource structure %x.\n", count++);
+			acpi_os_printf ("Resource structure %x.\n", count++);
 
-			switch (resource->id)
-			{
-			case irq:
+			switch (resource->id) {
+			case ACPI_RSTYPE_IRQ:
 				acpi_rs_dump_irq (&resource->data);
 				break;
 
-			case dma:
+			case ACPI_RSTYPE_DMA:
 				acpi_rs_dump_dma (&resource->data);
 				break;
 
-			case start_dependent_functions:
+			case ACPI_RSTYPE_START_DPF:
 				acpi_rs_dump_start_dependent_functions (&resource->data);
 				break;
 
-			case end_dependent_functions:
-				acpi_os_printf ("\t_end_dependent_functions Resource\n");
+			case ACPI_RSTYPE_END_DPF:
+				acpi_os_printf ("End_dependent_functions Resource\n");
 				/* Acpi_rs_dump_end_dependent_functions (Resource->Data);*/
 				break;
 
-			case io:
+			case ACPI_RSTYPE_IO:
 				acpi_rs_dump_io (&resource->data);
 				break;
 
-			case fixed_io:
+			case ACPI_RSTYPE_FIXED_IO:
 				acpi_rs_dump_fixed_io (&resource->data);
 				break;
 
-			case vendor_specific:
+			case ACPI_RSTYPE_VENDOR:
 				acpi_rs_dump_vendor_specific (&resource->data);
 				break;
 
-			case end_tag:
+			case ACPI_RSTYPE_END_TAG:
 				/*Rs_dump_end_tag (Resource->Data);*/
-				acpi_os_printf ("\t_end_tag Resource\n");
+				acpi_os_printf ("End_tag Resource\n");
 				done = TRUE;
 				break;
 
-			case memory24:
+			case ACPI_RSTYPE_MEM24:
 				acpi_rs_dump_memory24 (&resource->data);
 				break;
 
-			case memory32:
+			case ACPI_RSTYPE_MEM32:
 				acpi_rs_dump_memory32 (&resource->data);
 				break;
 
-			case fixed_memory32:
+			case ACPI_RSTYPE_FIXED_MEM32:
 				acpi_rs_dump_fixed_memory32 (&resource->data);
 				break;
 
-			case address16:
+			case ACPI_RSTYPE_ADDRESS16:
 				acpi_rs_dump_address16 (&resource->data);
 				break;
 
-			case address32:
+			case ACPI_RSTYPE_ADDRESS32:
 				acpi_rs_dump_address32 (&resource->data);
 				break;
 
-			case extended_irq:
+			case ACPI_RSTYPE_ADDRESS64:
+				acpi_rs_dump_address64 (&resource->data);
+				break;
+
+			case ACPI_RSTYPE_EXT_IRQ:
 				acpi_rs_dump_extended_irq (&resource->data);
 				break;
 
@@ -879,8 +1006,7 @@
 
 			}
 
-			resource = (RESOURCE *) ((NATIVE_UINT) resource +
-					 (NATIVE_UINT) resource->length);
+			resource = POINTER_ADD (ACPI_RESOURCE, resource, resource->length);
 		}
 	}
 
@@ -893,7 +1019,7 @@
  *
  * PARAMETERS:  Data            - pointer to the routing table to dump.
  *
- * RETURN:
+ * RETURN:      None
  *
  * DESCRIPTION: Dispatches the structures to the correct dump routine.
  *
@@ -913,16 +1039,16 @@
 		prt_element = (PCI_ROUTING_TABLE *) buffer;
 
 		while (!done) {
-			acpi_os_printf ("\t_pCI IRQ Routing Table structure %X.\n", count++);
+			acpi_os_printf ("PCI IRQ Routing Table structure %X.\n", count++);
 
-			acpi_os_printf ("\t\t_address: %X\n",
+			acpi_os_printf ("  Address: %X\n",
 					 prt_element->address);
 
-			acpi_os_printf ("\t\t_pin: %X\n", prt_element->pin);
+			acpi_os_printf ("  Pin: %X\n", prt_element->pin);
 
-			acpi_os_printf ("\t\t_source: %s\n", prt_element->source);
+			acpi_os_printf ("  Source: %s\n", prt_element->source);
 
-			acpi_os_printf ("\t\t_source_index: %X\n",
+			acpi_os_printf ("  Source_index: %X\n",
 					 prt_element->source_index);
 
 			buffer += prt_element->length;
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/resources/rsio.c linux/drivers/acpi/resources/rsio.c
--- v2.4.5/linux/drivers/acpi/resources/rsio.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/resources/rsio.c	Wed Jun 20 17:47:40 2001
@@ -1,12 +1,7 @@
 /*******************************************************************************
  *
- * Module Name: rsio - Acpi_rs_io_resource
- *                     Acpi_rs_fixed_io_resource
- *                     Acpi_rs_io_stream
- *                     Acpi_rs_fixed_io_stream
- *                     Acpi_rs_dma_resource
- *                     Acpi_rs_dma_stream
- *              $Revision: 12 $
+ * Module Name: rsio - IO and DMA resource descriptors
+ *              $Revision: 14 $
  *
  ******************************************************************************/
 
@@ -32,7 +27,7 @@
 #include "acpi.h"
 #include "acresrc.h"
 
-#define _COMPONENT          RESOURCE_MANAGER
+#define _COMPONENT          ACPI_RESOURCES
 	 MODULE_NAME         ("rsio")
 
 
@@ -41,20 +36,20 @@
  * FUNCTION:    Acpi_rs_io_resource
  *
  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
- *                                          stream
+ *                                        stream
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes consumed from
- *                                          the Byte_stream_buffer
+ *                                        the number of bytes consumed from
+ *                                        the Byte_stream_buffer
  *              Output_buffer           - Pointer to the user's return buffer
  *              Structure_size          - u32 pointer that is filled with
- *                                          the number of bytes in the filled
- *                                          in structure
+ *                                        the number of bytes in the filled
+ *                                        in structure
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *                  structure pointed to by the Output_buffer. Return the
- *                  number of bytes consumed from the byte stream.
+ *              structure pointed to by the Output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
  *
  ******************************************************************************/
 
@@ -66,11 +61,10 @@
 	u32                     *structure_size)
 {
 	u8                      *buffer = byte_stream_buffer;
-	RESOURCE                *output_struct = (RESOURCE *) * output_buffer;
+	ACPI_RESOURCE           *output_struct = (ACPI_RESOURCE *) *output_buffer;
 	u16                     temp16 = 0;
 	u8                      temp8 = 0;
-	u32                     struct_size = sizeof (IO_RESOURCE) +
-			  RESOURCE_LENGTH_NO_DATA;
+	u32                     struct_size = SIZEOF_RESOURCE (ACPI_RESOURCE_IO);
 
 
 	/*
@@ -78,7 +72,7 @@
 	 */
 	*bytes_consumed = 8;
 
-	output_struct->id = io;
+	output_struct->id = ACPI_RSTYPE_IO;
 
 	/*
 	 * Check Decode
@@ -129,7 +123,6 @@
 	 * Return the final size of the structure
 	 */
 	*structure_size = struct_size;
-
 	return (AE_OK);
 }
 
@@ -139,20 +132,20 @@
  * FUNCTION:    Acpi_rs_fixed_io_resource
  *
  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
- *                                          stream
+ *                                        stream
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes consumed from
- *                                          the Byte_stream_buffer
+ *                                        the number of bytes consumed from
+ *                                        the Byte_stream_buffer
  *              Output_buffer           - Pointer to the user's return buffer
  *              Structure_size          - u32 pointer that is filled with
- *                                          the number of bytes in the filled
- *                                          in structure
+ *                                        the number of bytes in the filled
+ *                                        in structure
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *                  structure pointed to by the Output_buffer. Return the
- *                  number of bytes consumed from the byte stream.
+ *              structure pointed to by the Output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
  *
  ******************************************************************************/
 
@@ -164,11 +157,10 @@
 	u32                     *structure_size)
 {
 	u8                      *buffer = byte_stream_buffer;
-	RESOURCE                *output_struct = (RESOURCE *) * output_buffer;
+	ACPI_RESOURCE           *output_struct = (ACPI_RESOURCE *) *output_buffer;
 	u16                     temp16 = 0;
 	u8                      temp8 = 0;
-	u32                     struct_size = sizeof (FIXED_IO_RESOURCE) +
-			  RESOURCE_LENGTH_NO_DATA;
+	u32                     struct_size = SIZEOF_RESOURCE (ACPI_RESOURCE_FIXED_IO);
 
 
 	/*
@@ -176,7 +168,7 @@
 	 */
 	*bytes_consumed = 4;
 
-	output_struct->id = fixed_io;
+	output_struct->id = ACPI_RSTYPE_FIXED_IO;
 
 	/*
 	 * Check Range Base Address
@@ -203,7 +195,6 @@
 	 * Return the final size of the structure
 	 */
 	*structure_size = struct_size;
-
 	return (AE_OK);
 }
 
@@ -215,19 +206,19 @@
  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
  *              Output_buffer           - Pointer to the user's return buffer
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes of the
- *                                          Output_buffer used
+ *                                        the number of bytes of the
+ *                                        Output_buffer used
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the linked list resource structure and fills in the
- *                  the appropriate bytes in a byte stream
+ *              the appropriate bytes in a byte stream
  *
  ******************************************************************************/
 
 ACPI_STATUS
 acpi_rs_io_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed)
 {
@@ -285,9 +276,7 @@
 	/*
 	 * Return the number of bytes consumed in this operation
 	 */
-	*bytes_consumed = (u32) ((NATIVE_UINT) buffer -
-			   (NATIVE_UINT) *output_buffer);
-
+	*bytes_consumed = POINTER_DIFF (buffer, *output_buffer);
 	return (AE_OK);
 }
 
@@ -299,19 +288,19 @@
  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
  *              Output_buffer           - Pointer to the user's return buffer
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes of the
- *                                          Output_buffer used
+ *                                        the number of bytes of the
+ *                                        Output_buffer used
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the linked list resource structure and fills in the
- *                  the appropriate bytes in a byte stream
+ *              the appropriate bytes in a byte stream
  *
  ******************************************************************************/
 
 ACPI_STATUS
 acpi_rs_fixed_io_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed)
 {
@@ -346,9 +335,7 @@
 	/*
 	 * Return the number of bytes consumed in this operation
 	 */
-	*bytes_consumed = (u32) ((NATIVE_UINT) buffer -
-			   (NATIVE_UINT) *output_buffer);
-
+	*bytes_consumed = POINTER_DIFF (buffer, *output_buffer);
 	return (AE_OK);
 }
 
@@ -358,20 +345,20 @@
  * FUNCTION:    Acpi_rs_dma_resource
  *
  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
- *                                          stream
+ *                                        stream
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes consumed from
- *                                          the Byte_stream_buffer
+ *                                        the number of bytes consumed from
+ *                                        the Byte_stream_buffer
  *              Output_buffer           - Pointer to the user's return buffer
  *              Structure_size          - u32 pointer that is filled with
- *                                          the number of bytes in the filled
- *                                          in structure
+ *                                        the number of bytes in the filled
+ *                                        in structure
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *                  structure pointed to by the Output_buffer. Return the
- *                  number of bytes consumed from the byte stream.
+ *              structure pointed to by the Output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
  *
  ******************************************************************************/
 
@@ -383,19 +370,18 @@
 	u32                     *structure_size)
 {
 	u8                      *buffer = byte_stream_buffer;
-	RESOURCE                *output_struct = (RESOURCE *) * output_buffer;
+	ACPI_RESOURCE           *output_struct = (ACPI_RESOURCE *) *output_buffer;
 	u8                      temp8 = 0;
 	u8                      index;
 	u8                      i;
-	u32                     struct_size = sizeof(DMA_RESOURCE) +
-			  RESOURCE_LENGTH_NO_DATA;
+	u32                     struct_size = SIZEOF_RESOURCE (ACPI_RESOURCE_DMA);
 
 
 	/*
 	 * The number of bytes consumed are Constant
 	 */
 	*bytes_consumed = 3;
-	output_struct->id = dma;
+	output_struct->id = ACPI_RSTYPE_DMA;
 
 	/*
 	 * Point to the 8-bits of Byte 1
@@ -453,7 +439,6 @@
 	 * Return the final size of the structure
 	 */
 	*structure_size = struct_size;
-
 	return (AE_OK);
 }
 
@@ -465,19 +450,19 @@
  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
  *              Output_buffer           - Pointer to the user's return buffer
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes of the
- *                                          Output_buffer used
+ *                                        the number of bytes of the
+ *                                        Output_buffer used
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the linked list resource structure and fills in the
- *                  the appropriate bytes in a byte stream
+ *              the appropriate bytes in a byte stream
  *
  ******************************************************************************/
 
 ACPI_STATUS
 acpi_rs_dma_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed)
 {
@@ -499,8 +484,7 @@
 	 */
 	for (index = 0;
 		 index < linked_list->data.dma.number_of_channels;
-		 index++)
-	{
+		 index++) {
 		temp16 = (u16) linked_list->data.dma.channels[index];
 		temp8 |= 0x1 << temp16;
 	}
@@ -521,9 +505,7 @@
 	/*
 	 * Return the number of bytes consumed in this operation
 	 */
-	*bytes_consumed = (u32) ((NATIVE_UINT) buffer -
-			   (NATIVE_UINT) *output_buffer);
-
+	*bytes_consumed = POINTER_DIFF (buffer, *output_buffer);
 	return (AE_OK);
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/resources/rsirq.c linux/drivers/acpi/resources/rsirq.c
--- v2.4.5/linux/drivers/acpi/resources/rsirq.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/resources/rsirq.c	Wed Jun 20 17:47:40 2001
@@ -1,10 +1,7 @@
 /*******************************************************************************
  *
- * Module Name: rsirq - Acpi_rs_irq_resource,
- *                      Acpi_rs_irq_stream
- *                      Acpi_rs_extended_irq_resource
- *                      Acpi_rs_extended_irq_stream
- *              $Revision: 13 $
+ * Module Name: rsirq - IRQ resource descriptors
+ *              $Revision: 17 $
  *
  ******************************************************************************/
 
@@ -30,7 +27,7 @@
 #include "acpi.h"
 #include "acresrc.h"
 
-#define _COMPONENT          RESOURCE_MANAGER
+#define _COMPONENT          ACPI_RESOURCES
 	 MODULE_NAME         ("rsirq")
 
 
@@ -39,20 +36,20 @@
  * FUNCTION:    Acpi_rs_irq_resource
  *
  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
- *                                          stream
+ *                                        stream
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes consumed from
- *                                          the Byte_stream_buffer
+ *                                        the number of bytes consumed from
+ *                                        the Byte_stream_buffer
  *              Output_buffer           - Pointer to the user's return buffer
  *              Structure_size          - u32 pointer that is filled with
- *                                          the number of bytes in the filled
- *                                          in structure
+ *                                        the number of bytes in the filled
+ *                                        in structure
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *                  structure pointed to by the Output_buffer. Return the
- *                  number of bytes consumed from the byte stream.
+ *              structure pointed to by the Output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
  *
  ******************************************************************************/
 
@@ -64,13 +61,12 @@
 	u32                     *structure_size)
 {
 	u8                      *buffer = byte_stream_buffer;
-	RESOURCE                *output_struct = (RESOURCE *) * output_buffer;
+	ACPI_RESOURCE           *output_struct = (ACPI_RESOURCE *) *output_buffer;
 	u16                     temp16 = 0;
 	u8                      temp8 = 0;
 	u8                      index;
 	u8                      i;
-	u32                     struct_size = sizeof (IRQ_RESOURCE) +
-			  RESOURCE_LENGTH_NO_DATA;
+	u32                     struct_size = SIZEOF_RESOURCE (ACPI_RESOURCE_IRQ);
 
 
 	/*
@@ -79,7 +75,7 @@
 	 */
 	temp8 = *buffer;
 	*bytes_consumed = (temp8 & 0x03) + 1;
-	output_struct->id = irq;
+	output_struct->id = ACPI_RSTYPE_IRQ;
 
 	/*
 	 * Point to the 16-bits of Bytes 1 and 2
@@ -128,8 +124,8 @@
 			else {
 				/*
 				 * Only _LL and _HE polarity/trigger interrupts
-				 *  are allowed (ACPI spec v1.0b ection 6.4.2.1),
-				 *  so an error will occur if we reach this point
+				 * are allowed (ACPI spec v1.0b ection 6.4.2.1),
+				 * so an error will occur if we reach this point
 				 */
 				return (AE_BAD_DATA);
 			}
@@ -144,7 +140,7 @@
 	else {
 		/*
 		 * Assume Edge Sensitive, Active High, Non-Sharable
-		 *  per ACPI Specification
+		 * per ACPI Specification
 		 */
 		output_struct->data.irq.edge_level = EDGE_SENSITIVE;
 		output_struct->data.irq.active_high_low = ACTIVE_HIGH;
@@ -160,7 +156,6 @@
 	 * Return the final size of the structure
 	 */
 	*structure_size = struct_size;
-
 	return (AE_OK);
 }
 
@@ -172,19 +167,19 @@
  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
  *              Output_buffer           - Pointer to the user's return buffer
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes of the
- *                                          Output_buffer used
+ *                                        the number of bytes of the
+ *                                        Output_buffer used
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the linked list resource structure and fills in the
- *                  the appropriate bytes in a byte stream
+ *              the appropriate bytes in a byte stream
  *
  ******************************************************************************/
 
 ACPI_STATUS
 acpi_rs_irq_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed)
 {
@@ -197,15 +192,15 @@
 
 	/*
 	 * The descriptor field is set based upon whether a third byte is
-	 *  needed to contain the IRQ Information.
+	 * needed to contain the IRQ Information.
 	 */
 	if (EDGE_SENSITIVE == linked_list->data.irq.edge_level &&
 		ACTIVE_HIGH == linked_list->data.irq.active_high_low &&
-		EXCLUSIVE == linked_list->data.irq.shared_exclusive)
-	{
+		EXCLUSIVE == linked_list->data.irq.shared_exclusive) {
 		*buffer = 0x22;
 		IRQinfo_byte_needed = FALSE;
 	}
+
 	else {
 		*buffer = 0x23;
 		IRQinfo_byte_needed = TRUE;
@@ -219,8 +214,7 @@
 	 */
 	for(index = 0;
 		index < linked_list->data.irq.number_of_interrupts;
-		index++)
-	{
+		index++) {
 		temp8 = (u8) linked_list->data.irq.interrupts[index];
 		temp16 |= 0x1 << temp8;
 	}
@@ -237,8 +231,7 @@
 				 0x01) << 4);
 
 		if (LEVEL_SENSITIVE == linked_list->data.irq.edge_level &&
-			ACTIVE_LOW == linked_list->data.irq.active_high_low)
-		{
+			ACTIVE_LOW == linked_list->data.irq.active_high_low) {
 			temp8 |= 0x08;
 		}
 
@@ -253,9 +246,7 @@
 	/*
 	 * Return the number of bytes consumed in this operation
 	 */
-	*bytes_consumed = (u32) ((NATIVE_UINT) buffer -
-			   (NATIVE_UINT) *output_buffer);
-
+	*bytes_consumed = POINTER_DIFF (buffer, *output_buffer);
 	return (AE_OK);
 }
 
@@ -265,20 +256,20 @@
  * FUNCTION:    Acpi_rs_extended_irq_resource
  *
  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
- *                                          stream
+ *                                        stream
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes consumed from
- *                                          the Byte_stream_buffer
+ *                                        the number of bytes consumed from
+ *                                        the Byte_stream_buffer
  *              Output_buffer           - Pointer to the user's return buffer
  *              Structure_size          - u32 pointer that is filled with
- *                                          the number of bytes in the filled
- *                                          in structure
+ *                                        the number of bytes in the filled
+ *                                        in structure
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *                  structure pointed to by the Output_buffer. Return the
- *                  number of bytes consumed from the byte stream.
+ *              structure pointed to by the Output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
  *
  ******************************************************************************/
 
@@ -290,12 +281,12 @@
 	u32                     *structure_size)
 {
 	u8                      *buffer = byte_stream_buffer;
-	RESOURCE                *output_struct = (RESOURCE *) * output_buffer;
+	ACPI_RESOURCE           *output_struct = (ACPI_RESOURCE *) *output_buffer;
 	u16                     temp16 = 0;
 	u8                      temp8 = 0;
+	NATIVE_CHAR             *temp_ptr;
 	u8                      index;
-	u32                     struct_size = sizeof (EXTENDED_IRQ_RESOURCE) +
-			  RESOURCE_LENGTH_NO_DATA;
+	u32                     struct_size = SIZEOF_RESOURCE (ACPI_RESOURCE_EXT_IRQ);
 
 
 	/*
@@ -305,7 +296,7 @@
 	MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
 
 	*bytes_consumed = temp16 + 3;
-	output_struct->id = extended_irq;
+	output_struct->id = ACPI_RSTYPE_EXT_IRQ;
 
 	/*
 	 * Point to the Byte3
@@ -332,8 +323,8 @@
 		else {
 			/*
 			 * Only _LL and _HE polarity/trigger interrupts
-			 *  are allowed (ACPI spec v1.0b ection 6.4.2.1),
-			 *  so an error will occur if we reach this point
+			 * are allowed (ACPI spec v1.0b ection 6.4.2.1),
+			 * so an error will occur if we reach this point
 			 */
 			return (AE_BAD_DATA);
 		}
@@ -342,8 +333,7 @@
 	/*
 	 * Check for sharable
 	 */
-	output_struct->data.extended_irq.shared_exclusive =
-			(temp8 >> 3) & 0x01;
+	output_struct->data.extended_irq.shared_exclusive = (temp8 >> 3) & 0x01;
 
 	/*
 	 * Point to Byte4 (IRQ Table length)
@@ -355,9 +345,9 @@
 
 	/*
 	 * Add any additional structure size to properly calculate
-	 *  the next pointer at the end of this function
+	 * the next pointer at the end of this function
 	 */
-	 struct_size += (temp8 - 1) * 4;
+	struct_size += (temp8 - 1) * 4;
 
 	/*
 	 * Point to Byte5 (First IRQ Number)
@@ -378,33 +368,38 @@
 
 	/*
 	 * This will leave us pointing to the Resource Source Index
-	 *  If it is present, then save it off and calculate the
-	 *  pointer to where the null terminated string goes:
-	 *  Each Interrupt takes 32-bits + the 5 bytes of the
-	 *  stream that are default.
+	 * If it is present, then save it off and calculate the
+	 * pointer to where the null terminated string goes:
+	 * Each Interrupt takes 32-bits + the 5 bytes of the
+	 * stream that are default.
 	 */
 	if (*bytes_consumed >
-		(u32)(output_struct->data.extended_irq.number_of_interrupts *
-		 4) + 5)
-	{
+		(u32)(output_struct->data.extended_irq.number_of_interrupts * 4) + 5) {
 		/* Dereference the Index */
 
 		temp8 = *buffer;
-		output_struct->data.extended_irq.resource_source_index =
-				(u32)temp8;
+		output_struct->data.extended_irq.resource_source.index = (u32) temp8;
 
 		/* Point to the String */
 
 		buffer += 1;
 
+		/*
+		 * Point the String pointer to the end of this structure.
+		 */
+		output_struct->data.extended_irq.resource_source.string_ptr =
+				(NATIVE_CHAR *)(output_struct + struct_size);
+
+		temp_ptr = output_struct->data.extended_irq.resource_source.string_ptr;
+
 		/* Copy the string into the buffer */
 
 		index = 0;
 
 		while (0x00 != *buffer) {
-			output_struct->data.extended_irq.resource_source[index] =
-					*buffer;
+			*temp_ptr = *buffer;
 
+			temp_ptr += 1;
 			buffer += 1;
 			index += 1;
 		}
@@ -412,23 +407,22 @@
 		/*
 		 * Add the terminating null
 		 */
-		output_struct->data.extended_irq.resource_source[index] = 0x00;
-		output_struct->data.extended_irq.resource_source_string_length =
-				index + 1;
+		*temp_ptr = 0x00;
+		output_struct->data.extended_irq.resource_source.string_length = index + 1;
 
 		/*
-		 * In order for the Struct_size to fall on a 32-bit boundry,
-		 *  calculate the length of the string and expand the
-		 *  Struct_size to the next 32-bit boundry.
+		 * In order for the Struct_size to fall on a 32-bit boundary,
+		 * calculate the length of the string and expand the
+		 * Struct_size to the next 32-bit boundary.
 		 */
 		temp8 = (u8) (index + 1);
-		temp8 = (u8) ROUND_UP_TO_32_bITS (temp8);
+		struct_size += ROUND_UP_TO_32_bITS (temp8);
 	}
 
 	else {
-		output_struct->data.extended_irq.resource_source_index = 0x00;
-		output_struct->data.extended_irq.resource_source_string_length = 0;
-		output_struct->data.extended_irq.resource_source[0] = 0x00;
+		output_struct->data.extended_irq.resource_source.index = 0x00;
+		output_struct->data.extended_irq.resource_source.string_length = 0;
+		output_struct->data.extended_irq.resource_source.string_ptr = NULL;
 	}
 
 	/*
@@ -440,7 +434,6 @@
 	 * Return the final size of the structure
 	 */
 	*structure_size = struct_size;
-
 	return (AE_OK);
 }
 
@@ -452,10 +445,10 @@
  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
  *              Output_buffer           - Pointer to the user's return buffer
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes of the
- *                                          Output_buffer used
+ *                                        the number of bytes of the
+ *                                        Output_buffer used
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the linked list resource structure and fills in the
  *              the appropriate bytes in a byte stream
@@ -464,7 +457,7 @@
 
 ACPI_STATUS
 acpi_rs_extended_irq_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed)
 {
@@ -484,7 +477,6 @@
 	/*
 	 * Set a pointer to the Length field - to be filled in later
 	 */
-
 	length_field = (u16 *)buffer;
 	buffer += 2;
 
@@ -492,12 +484,10 @@
 	 * Set the Interrupt vector flags
 	 */
 	temp8 = (u8)(linked_list->data.extended_irq.producer_consumer & 0x01);
-
 	temp8 |= ((linked_list->data.extended_irq.shared_exclusive & 0x01) << 3);
 
 	if (LEVEL_SENSITIVE == linked_list->data.extended_irq.edge_level &&
-	   ACTIVE_LOW == linked_list->data.extended_irq.active_high_low)
-	{
+	   ACTIVE_LOW == linked_list->data.extended_irq.active_high_low) {
 		temp8 |= 0x04;
 	}
 	else {
@@ -515,10 +505,8 @@
 	*buffer = temp8;
 	buffer += 1;
 
-	for (index = 0;
-		 index < linked_list->data.extended_irq.number_of_interrupts;
-		 index++)
-	{
+	for (index = 0; index < linked_list->data.extended_irq.number_of_interrupts;
+		 index++) {
 		MOVE_UNALIGNED32_TO_32 (buffer,
 				  &linked_list->data.extended_irq.interrupts[index]);
 		buffer += 4;
@@ -527,8 +515,8 @@
 	/*
 	 * Resource Source Index and Resource Source are optional
 	 */
-	if (0 != linked_list->data.extended_irq.resource_source_string_length) {
-		*buffer = (u8) linked_list->data.extended_irq.resource_source_index;
+	if (0 != linked_list->data.extended_irq.resource_source.string_length) {
+		*buffer = (u8) linked_list->data.extended_irq.resource_source.index;
 		buffer += 1;
 
 		temp_pointer = (NATIVE_CHAR *) buffer;
@@ -536,27 +524,26 @@
 		/*
 		 * Copy the string
 		 */
-		STRCPY (temp_pointer, linked_list->data.extended_irq.resource_source);
+		STRCPY (temp_pointer,
+			linked_list->data.extended_irq.resource_source.string_ptr);
 
 		/*
 		 * Buffer needs to be set to the length of the sting + one for the
-		 *  terminating null
+		 * terminating null
 		 */
-		buffer += (STRLEN (linked_list->data.extended_irq.resource_source) + 1);
+		buffer += (STRLEN (linked_list->data.extended_irq.resource_source.string_ptr) + 1);
 	}
 
 	/*
 	 * Return the number of bytes consumed in this operation
 	 */
-	*bytes_consumed = (u32) ((NATIVE_UINT) buffer -
-			   (NATIVE_UINT) *output_buffer);
+	*bytes_consumed = POINTER_DIFF (buffer, *output_buffer);
 
 	/*
 	 * Set the length field to the number of bytes consumed
-	 *  minus the header size (3 bytes)
+	 * minus the header size (3 bytes)
 	 */
 	*length_field = (u16) (*bytes_consumed - 3);
-
 	return (AE_OK);
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/resources/rslist.c linux/drivers/acpi/resources/rslist.c
--- v2.4.5/linux/drivers/acpi/resources/rslist.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/resources/rslist.c	Wed Jun 20 17:47:40 2001
@@ -1,8 +1,7 @@
 /*******************************************************************************
  *
- * Module Name: rslist - Acpi_rs_byte_stream_to_list
- *                       Acpi_list_to_byte_stream
- *              $Revision: 11 $
+ * Module Name: rslist - Linked list utilities
+ *              $Revision: 17 $
  *
  ******************************************************************************/
 
@@ -28,20 +27,64 @@
 #include "acpi.h"
 #include "acresrc.h"
 
-#define _COMPONENT          RESOURCE_MANAGER
+#define _COMPONENT          ACPI_RESOURCES
 	 MODULE_NAME         ("rslist")
 
 
 /*******************************************************************************
  *
+ * FUNCTION:    Acpi_rs_get_resource_type
+ *
+ * PARAMETERS:  Resource_start_byte     - Byte 0 of a resource descriptor
+ *
+ * RETURN:      The Resource Type (Name) with no extraneous bits
+ *
+ * DESCRIPTION: Extract the Resource Type/Name from the first byte of
+ *              a resource descriptor.
+ *
+ ******************************************************************************/
+
+u8
+acpi_rs_get_resource_type (
+	u8                      resource_start_byte)
+{
+
+	/*
+	 * Determine if this is a small or large resource
+	 */
+	switch (resource_start_byte & RESOURCE_DESC_TYPE_MASK) {
+	case RESOURCE_DESC_TYPE_SMALL:
+
+		/*
+		 * Small Resource Type -- Only bits 6:3 are valid
+		 */
+		return ((u8) (resource_start_byte & RESOURCE_DESC_SMALL_MASK));
+		break;
+
+
+	case RESOURCE_DESC_TYPE_LARGE:
+
+		/*
+		 * Large Resource Type -- All bits are valid
+		 */
+		return (resource_start_byte);
+		break;
+	}
+
+	return (0xFF);
+}
+
+
+/*******************************************************************************
+ *
  * FUNCTION:    Acpi_rs_byte_stream_to_list
  *
  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource byte stream
  *              Byte_stream_buffer_length - Length of Byte_stream_buffer
  *              Output_buffer           - Pointer to the buffer that will
- *                                          contain the output structures
+ *                                        contain the output structures
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Takes the resource byte stream and parses it, creating a
  *              linked list of resources in the caller's output buffer
@@ -64,223 +107,170 @@
 
 
 	while (bytes_parsed < byte_stream_buffer_length &&
-			FALSE == end_tag_processed)
-	{
+			FALSE == end_tag_processed) {
 		/*
-		 * Look at the next byte in the stream
+		 * The next byte in the stream is the resource type
 		 */
-		resource_type = *byte_stream_buffer;
+		resource_type = acpi_rs_get_resource_type (*byte_stream_buffer);
 
-		/*
-		 * See if this is a small or large resource
-		 */
-		if(resource_type & 0x80) {
+		switch (resource_type) {
+		case RESOURCE_DESC_MEMORY_24:
 			/*
-			 * Large Resource Type
+			 * 24-Bit Memory Resource
 			 */
-			switch (resource_type)
-			{
-			case MEMORY_RANGE_24:
-				/*
-				 * 24-Bit Memory Resource
-				 */
-				status = acpi_rs_memory24_resource(byte_stream_buffer,
-						   &bytes_consumed,
-						   buffer,
-						   &structure_size);
-
-				break;
-
-			case LARGE_VENDOR_DEFINED:
-				/*
-				 * Vendor Defined Resource
-				 */
-				status = acpi_rs_vendor_resource(byte_stream_buffer,
-						 &bytes_consumed,
-						 buffer,
-						 &structure_size);
-
-				break;
-
-			case MEMORY_RANGE_32:
-				/*
-				 * 32-Bit Memory Range Resource
-				 */
-				status = acpi_rs_memory32_range_resource(byte_stream_buffer,
-						  &bytes_consumed,
-						  buffer,
-						  &structure_size);
-
-				break;
-
-			case FIXED_MEMORY_RANGE_32:
-				/*
-				 * 32-Bit Fixed Memory Resource
-				 */
-				status = acpi_rs_fixed_memory32_resource(byte_stream_buffer,
-						  &bytes_consumed,
-						  buffer,
-						  &structure_size);
-
-				break;
-
-			case DWORD_ADDRESS_SPACE:
-				/*
-				 * 32-Bit Address Resource
-				 */
-				status = acpi_rs_address32_resource(byte_stream_buffer,
-						 &bytes_consumed,
-						 buffer,
-						 &structure_size);
-
-				break;
-
-			case WORD_ADDRESS_SPACE:
-				/*
-				 * 16-Bit Address Resource
-				 */
-				status = acpi_rs_address16_resource(byte_stream_buffer,
-						 &bytes_consumed,
-						 buffer,
-						 &structure_size);
-
-				break;
-
-			case EXTENDED_IRQ:
-				/*
-				 * Extended IRQ
-				 */
-				status = acpi_rs_extended_irq_resource(byte_stream_buffer,
-						   &bytes_consumed,
-						   buffer,
-						   &structure_size);
+			status = acpi_rs_memory24_resource (byte_stream_buffer,
+					 &bytes_consumed, buffer, &structure_size);
+			break;
 
-				break;
 
-/* TBD: [Future] 64-bit not currently supported */
-/*
-			case 0x8A:
-				break;
-*/
-
-			default:
-				/*
-				 * If we get here, everything is out of sync,
-				 *  so exit with an error
-				 */
-				return (AE_AML_ERROR);
-				break;
-			}
-		}
+		case RESOURCE_DESC_LARGE_VENDOR:
+			/*
+			 * Vendor Defined Resource
+			 */
+			status = acpi_rs_vendor_resource (byte_stream_buffer,
+					 &bytes_consumed, buffer, &structure_size);
+			break;
+
+
+		case RESOURCE_DESC_MEMORY_32:
+			/*
+			 * 32-Bit Memory Range Resource
+			 */
+			status = acpi_rs_memory32_range_resource (byte_stream_buffer,
+					 &bytes_consumed, buffer, &structure_size);
+			break;
+
+
+		case RESOURCE_DESC_FIXED_MEMORY_32:
+			/*
+			 * 32-Bit Fixed Memory Resource
+			 */
+			status = acpi_rs_fixed_memory32_resource (byte_stream_buffer,
+					 &bytes_consumed, buffer, &structure_size);
+			break;
+
+
+		case RESOURCE_DESC_QWORD_ADDRESS_SPACE:
+			/*
+			 * 64-Bit Address Resource
+			 */
+			status = acpi_rs_address64_resource (byte_stream_buffer,
+					 &bytes_consumed, buffer, &structure_size);
+			break;
+
+
+		case RESOURCE_DESC_DWORD_ADDRESS_SPACE:
+			/*
+			 * 32-Bit Address Resource
+			 */
+			status = acpi_rs_address32_resource (byte_stream_buffer,
+					 &bytes_consumed, buffer, &structure_size);
+			break;
+
+
+		case RESOURCE_DESC_WORD_ADDRESS_SPACE:
+			/*
+			 * 16-Bit Address Resource
+			 */
+			status = acpi_rs_address16_resource (byte_stream_buffer,
+					 &bytes_consumed, buffer, &structure_size);
+			break;
+
+
+		case RESOURCE_DESC_EXTENDED_XRUPT:
+			/*
+			 * Extended IRQ
+			 */
+			status = acpi_rs_extended_irq_resource (byte_stream_buffer,
+					 &bytes_consumed, buffer, &structure_size);
+			break;
+
+
+		case RESOURCE_DESC_IRQ_FORMAT:
+			/*
+			 * IRQ Resource
+			 */
+			status = acpi_rs_irq_resource (byte_stream_buffer,
+					 &bytes_consumed, buffer, &structure_size);
+			break;
+
+
+		case RESOURCE_DESC_DMA_FORMAT:
+			/*
+			 * DMA Resource
+			 */
+			status = acpi_rs_dma_resource (byte_stream_buffer,
+					 &bytes_consumed, buffer, &structure_size);
+			break;
+
+
+		case RESOURCE_DESC_START_DEPENDENT:
+			/*
+			 * Start Dependent Functions Resource
+			 */
+			status = acpi_rs_start_dependent_functions_resource (byte_stream_buffer,
+					 &bytes_consumed, buffer, &structure_size);
+			break;
+
+
+		case RESOURCE_DESC_END_DEPENDENT:
+			/*
+			 * End Dependent Functions Resource
+			 */
+			status = acpi_rs_end_dependent_functions_resource (byte_stream_buffer,
+					 &bytes_consumed, buffer, &structure_size);
+			break;
+
+
+		case RESOURCE_DESC_IO_PORT:
+			/*
+			 * IO Port Resource
+			 */
+			status = acpi_rs_io_resource (byte_stream_buffer,
+					 &bytes_consumed, buffer, &structure_size);
+			break;
+
+
+		case RESOURCE_DESC_FIXED_IO_PORT:
+			/*
+			 * Fixed IO Port Resource
+			 */
+			status = acpi_rs_fixed_io_resource (byte_stream_buffer,
+					 &bytes_consumed, buffer, &structure_size);
+			break;
+
 
-		else {
+		case RESOURCE_DESC_SMALL_VENDOR:
 			/*
-			 * Small Resource Type
-			 *  Only bits 7:3 are valid
+			 * Vendor Specific Resource
 			 */
-			resource_type >>= 3;
+			status = acpi_rs_vendor_resource (byte_stream_buffer,
+					 &bytes_consumed, buffer, &structure_size);
+			break;
 
-			switch(resource_type)
-			{
-			case IRQ_FORMAT:
-				/*
-				 * IRQ Resource
-				 */
-				status = acpi_rs_irq_resource(byte_stream_buffer,
-						 &bytes_consumed,
-						 buffer,
-						 &structure_size);
-
-				break;
-
-			case DMA_FORMAT:
-				/*
-				 * DMA Resource
-				 */
-				status = acpi_rs_dma_resource(byte_stream_buffer,
-						 &bytes_consumed,
-						 buffer,
-						 &structure_size);
-
-				break;
-
-			case START_DEPENDENT_TAG:
-				/*
-				 * Start Dependent Functions Resource
-				 */
-				status = acpi_rs_start_dependent_functions_resource(byte_stream_buffer,
-						   &bytes_consumed,
-						   buffer,
-						   &structure_size);
-
-				break;
-
-			case END_DEPENDENT_TAG:
-				/*
-				 * End Dependent Functions Resource
-				 */
-				status = acpi_rs_end_dependent_functions_resource(byte_stream_buffer,
-						 &bytes_consumed,
-						 buffer,
-						 &structure_size);
-
-				break;
-
-			case IO_PORT_DESCRIPTOR:
-				/*
-				 * IO Port Resource
-				 */
-				status = acpi_rs_io_resource(byte_stream_buffer,
-						   &bytes_consumed,
-						   buffer,
-						   &structure_size);
-
-				break;
-
-			case FIXED_LOCATION_IO_DESCRIPTOR:
-				/*
-				 * Fixed IO Port Resource
-				 */
-				status = acpi_rs_fixed_io_resource(byte_stream_buffer,
-						  &bytes_consumed,
-						  buffer,
-						  &structure_size);
-
-				break;
-
-			case SMALL_VENDOR_DEFINED:
-				/*
-				 * Vendor Specific Resource
-				 */
-				status = acpi_rs_vendor_resource(byte_stream_buffer,
-						 &bytes_consumed,
-						 buffer,
-						 &structure_size);
-
-				break;
-
-			case END_TAG:
-				/*
-				 * End Tag
-				 */
-				status = acpi_rs_end_tag_resource(byte_stream_buffer,
-						 &bytes_consumed,
-						 buffer,
-						 &structure_size);
-				end_tag_processed = TRUE;
-
-				break;
-
-			default:
-				/*
-				 * If we get here, everything is out of sync,
-				 *  so exit with an error
-				 */
-				return (AE_AML_ERROR);
-				break;
 
-			} /* switch */
-		}  /* end else */
+		case RESOURCE_DESC_END_TAG:
+			/*
+			 * End Tag
+			 */
+			end_tag_processed = TRUE;
+			status = acpi_rs_end_tag_resource (byte_stream_buffer,
+					 &bytes_consumed, buffer, &structure_size);
+			break;
+
+
+		default:
+			/*
+			 * Invalid/Unknowns resource type
+			 */
+			status = AE_AML_ERROR;
+			break;
+		}
+
+
+		if (!ACPI_SUCCESS(status)) {
+			return (status);
+		}
 
 		/*
 		 * Update the return value and counter
@@ -316,15 +306,15 @@
  *
  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
  *              Byte_steam_size_needed  - Calculated size of the byte stream
- *                                          needed from calling
- *                                          Acpi_rs_calculate_byte_stream_length()
- *                                          The size of the Output_buffer is
- *                                          guaranteed to be >=
- *                                          Byte_stream_size_needed
+ *                                        needed from calling
+ *                                        Acpi_rs_calculate_byte_stream_length()
+ *                                        The size of the Output_buffer is
+ *                                        guaranteed to be >=
+ *                                        Byte_stream_size_needed
  *              Output_buffer           - Pointer to the buffer that will
- *                                          contain the byte stream
+ *                                        contain the byte stream
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Takes the resource linked list and parses it, creating a
  *              byte stream of resources in the caller's output buffer
@@ -333,7 +323,7 @@
 
 ACPI_STATUS
 acpi_rs_list_to_byte_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u32                     byte_stream_size_needed,
 	u8                      **output_buffer)
 {
@@ -344,78 +334,63 @@
 
 
 	while (!done) {
-		switch (linked_list->id)
-		{
-		case irq:
+		switch (linked_list->id) {
+		case ACPI_RSTYPE_IRQ:
 			/*
 			 * IRQ Resource
 			 */
-			status = acpi_rs_irq_stream (linked_list,
-					   &buffer,
-					   &bytes_consumed);
+			status = acpi_rs_irq_stream (linked_list, &buffer, &bytes_consumed);
 			break;
 
-		case dma:
+		case ACPI_RSTYPE_DMA:
 			/*
 			 * DMA Resource
 			 */
-			status = acpi_rs_dma_stream (linked_list,
-					   &buffer,
-					   &bytes_consumed);
+			status = acpi_rs_dma_stream (linked_list, &buffer, &bytes_consumed);
 			break;
 
-		case start_dependent_functions:
+		case ACPI_RSTYPE_START_DPF:
 			/*
 			 * Start Dependent Functions Resource
 			 */
 			status = acpi_rs_start_dependent_functions_stream (linked_list,
-					  &buffer,
-					  &bytes_consumed);
+					  &buffer, &bytes_consumed);
 			break;
 
-		case end_dependent_functions:
+		case ACPI_RSTYPE_END_DPF:
 			/*
 			 * End Dependent Functions Resource
 			 */
 			status = acpi_rs_end_dependent_functions_stream (linked_list,
-					   &buffer,
-					   &bytes_consumed);
+					  &buffer, &bytes_consumed);
 			break;
 
-		case io:
+		case ACPI_RSTYPE_IO:
 			/*
 			 * IO Port Resource
 			 */
-			status = acpi_rs_io_stream (linked_list,
-					  &buffer,
-					  &bytes_consumed);
+			status = acpi_rs_io_stream (linked_list, &buffer, &bytes_consumed);
 			break;
 
-		case fixed_io:
+		case ACPI_RSTYPE_FIXED_IO:
 			/*
 			 * Fixed IO Port Resource
 			 */
-			status = acpi_rs_fixed_io_stream (linked_list,
-					 &buffer,
-					 &bytes_consumed);
+			status = acpi_rs_fixed_io_stream (linked_list, &buffer, &bytes_consumed);
 			break;
 
-		case vendor_specific:
+		case ACPI_RSTYPE_VENDOR:
 			/*
 			 * Vendor Defined Resource
 			 */
-			status = acpi_rs_vendor_stream (linked_list,
-					   &buffer,
-					   &bytes_consumed);
+			status = acpi_rs_vendor_stream (linked_list, &buffer, &bytes_consumed);
 			break;
 
-		case end_tag:
+		case ACPI_RSTYPE_END_TAG:
 			/*
 			 * End Tag
 			 */
-			status = acpi_rs_end_tag_stream (linked_list,
-					   &buffer,
-					   &bytes_consumed);
+			status = acpi_rs_end_tag_stream (linked_list, &buffer, &bytes_consumed);
 
 			/*
 			 * An End Tag indicates the end of the Resource Template
@@ -423,58 +398,59 @@
 			done = TRUE;
 			break;
 
-		case memory24:
+		case ACPI_RSTYPE_MEM24:
 			/*
 			 * 24-Bit Memory Resource
 			 */
-			status = acpi_rs_memory24_stream (linked_list,
-					  &buffer,
-					  &bytes_consumed);
+			status = acpi_rs_memory24_stream (linked_list, &buffer, &bytes_consumed);
 			break;
 
-		case memory32:
+		case ACPI_RSTYPE_MEM32:
 			/*
 			 * 32-Bit Memory Range Resource
 			 */
-			status = acpi_rs_memory32_range_stream (linked_list,
-					 &buffer,
+			status = acpi_rs_memory32_range_stream (linked_list, &buffer,
 					 &bytes_consumed);
 			break;
 
-		case fixed_memory32:
+		case ACPI_RSTYPE_FIXED_MEM32:
 			/*
 			 * 32-Bit Fixed Memory Resource
 			 */
-			status = acpi_rs_fixed_memory32_stream (linked_list,
-					 &buffer,
+			status = acpi_rs_fixed_memory32_stream (linked_list, &buffer,
 					 &bytes_consumed);
 			break;
 
-		case address16:
+		case ACPI_RSTYPE_ADDRESS16:
 			/*
 			 * 16-Bit Address Descriptor Resource
 			 */
-			status = acpi_rs_address16_stream (linked_list,
-					   &buffer,
-					   &bytes_consumed);
+			status = acpi_rs_address16_stream (linked_list, &buffer,
+					 &bytes_consumed);
 			break;
 
-		case address32:
+		case ACPI_RSTYPE_ADDRESS32:
 			/*
 			 * 32-Bit Address Descriptor Resource
 			 */
-			status = acpi_rs_address32_stream (linked_list,
-					   &buffer,
-					   &bytes_consumed);
+			status = acpi_rs_address32_stream (linked_list, &buffer,
+					 &bytes_consumed);
+			break;
+
+		case ACPI_RSTYPE_ADDRESS64:
+			/*
+			 * 64-Bit Address Descriptor Resource
+			 */
+			status = acpi_rs_address64_stream (linked_list, &buffer,
+					 &bytes_consumed);
 			break;
 
-		case extended_irq:
+		case ACPI_RSTYPE_EXT_IRQ:
 			/*
 			 * Extended IRQ Resource
 			 */
-			status = acpi_rs_extended_irq_stream (linked_list,
-					  &buffer,
-					  &bytes_consumed);
+			status = acpi_rs_extended_irq_stream (linked_list, &buffer,
+					 &bytes_consumed);
 			break;
 
 		default:
@@ -482,11 +458,16 @@
 			 * If we get here, everything is out of sync,
 			 *  so exit with an error
 			 */
-			return (AE_BAD_DATA);
+			status = AE_BAD_DATA;
 			break;
 
 		} /* switch (Linked_list->Id) */
 
+
+		if (!ACPI_SUCCESS(status)) {
+			return (status);
+		}
+
 		/*
 		 * Set the Buffer to point to the open byte
 		 */
@@ -495,10 +476,10 @@
 		/*
 		 * Point to the next object
 		 */
-		linked_list = (RESOURCE *) ((NATIVE_UINT) linked_list +
-				  (NATIVE_UINT) linked_list->length);
+		linked_list = POINTER_ADD (ACPI_RESOURCE,
+				  linked_list, linked_list->length);
 	}
 
-	return  (AE_OK);
+	return (AE_OK);
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/resources/rsmemory.c linux/drivers/acpi/resources/rsmemory.c
--- v2.4.5/linux/drivers/acpi/resources/rsmemory.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/resources/rsmemory.c	Wed Jun 20 17:47:40 2001
@@ -1,12 +1,7 @@
 /*******************************************************************************
  *
- * Module Name: rsmem24 - Acpi_rs_memory24_resource
- *                        Acpi_rs_memory24_stream
- *                        Acpi_rs_memory32_range_resource
- *                        Acpi_rs_fixed_memory32_resource
- *                        Acpi_rs_memory32_range_stream
- *                        Acpi_rs_fixed_memory32_stream
- *              $Revision: 12 $
+ * Module Name: rsmem24 - Memory resource descriptors
+ *              $Revision: 14 $
  *
  ******************************************************************************/
 
@@ -32,7 +27,7 @@
 #include "acpi.h"
 #include "acresrc.h"
 
-#define _COMPONENT          RESOURCE_MANAGER
+#define _COMPONENT          ACPI_RESOURCES
 	 MODULE_NAME         ("rsmemory")
 
 
@@ -41,20 +36,20 @@
  * FUNCTION:    Acpi_rs_memory24_resource
  *
  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
- *                                          stream
+ *                                        stream
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes consumed from
- *                                          the Byte_stream_buffer
+ *                                        the number of bytes consumed from
+ *                                        the Byte_stream_buffer
  *              Output_buffer           - Pointer to the user's return buffer
  *              Structure_size          - u32 pointer that is filled with
- *                                          the number of bytes in the filled
- *                                          in structure
+ *                                        the number of bytes in the filled
+ *                                        in structure
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *                  structure pointed to by the Output_buffer. Return the
- *                  number of bytes consumed from the byte stream.
+ *              structure pointed to by the Output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
  *
  ******************************************************************************/
 
@@ -66,11 +61,10 @@
 	u32                     *structure_size)
 {
 	u8                      *buffer = byte_stream_buffer;
-	RESOURCE                *output_struct = (RESOURCE *) * output_buffer;
+	ACPI_RESOURCE           *output_struct = (ACPI_RESOURCE *) *output_buffer;
 	u16                     temp16 = 0;
 	u8                      temp8 = 0;
-	u32                     struct_size = sizeof (MEMORY24_RESOURCE) +
-			  RESOURCE_LENGTH_NO_DATA;
+	u32                     struct_size = SIZEOF_RESOURCE (ACPI_RESOURCE_MEM24);
 
 
 	/*
@@ -81,7 +75,7 @@
 	MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
 	buffer += 2;
 	*bytes_consumed = temp16 + 3;
-	output_struct->id = memory24;
+	output_struct->id = ACPI_RSTYPE_MEM24;
 
 	/*
 	 * Check Byte 3 the Read/Write bit
@@ -126,7 +120,6 @@
 	 * Return the final size of the structure
 	 */
 	*structure_size = struct_size;
-
 	return (AE_OK);
 }
 
@@ -138,19 +131,19 @@
  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
  *              Output_buffer           - Pointer to the user's return buffer
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes of the
- *                                          Output_buffer used
+ *                                        the number of bytes of the
+ *                                        Output_buffer used
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the linked list resource structure and fills in the
- *                  the appropriate bytes in a byte stream
+ *              the appropriate bytes in a byte stream
  *
  ******************************************************************************/
 
 ACPI_STATUS
 acpi_rs_memory24_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed)
 {
@@ -206,9 +199,7 @@
 	/*
 	 * Return the number of bytes consumed in this operation
 	 */
-	*bytes_consumed = (u32) ((NATIVE_UINT) buffer -
-			   (NATIVE_UINT) *output_buffer);
-
+	*bytes_consumed = POINTER_DIFF (buffer, *output_buffer);
 	return (AE_OK);
 }
 
@@ -218,20 +209,20 @@
  * FUNCTION:    Acpi_rs_memory32_range_resource
  *
  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
- *                                          stream
+ *                                        stream
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes consumed from
- *                                          the Byte_stream_buffer
+ *                                        the number of bytes consumed from
+ *                                        the Byte_stream_buffer
  *              Output_buffer           - Pointer to the user's return buffer
  *              Structure_size          - u32 pointer that is filled with
- *                                          the number of bytes in the filled
- *                                          in structure
+ *                                        the number of bytes in the filled
+ *                                        in structure
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *                  structure pointed to by the Output_buffer. Return the
- *                  number of bytes consumed from the byte stream.
+ *              structure pointed to by the Output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
  *
  ******************************************************************************/
 
@@ -243,11 +234,10 @@
 	u32                     *structure_size)
 {
 	u8                      *buffer = byte_stream_buffer;
-	RESOURCE                *output_struct = (RESOURCE *) * output_buffer;
+	ACPI_RESOURCE           *output_struct = (ACPI_RESOURCE *) *output_buffer;
 	u16                     temp16 = 0;
 	u8                      temp8 = 0;
-	u32                     struct_size = sizeof (MEMORY32_RESOURCE) +
-			  RESOURCE_LENGTH_NO_DATA;
+	u32                     struct_size = SIZEOF_RESOURCE (ACPI_RESOURCE_MEM32);
 
 
 	/*
@@ -259,11 +249,11 @@
 	buffer += 2;
 	*bytes_consumed = temp16 + 3;
 
-	output_struct->id = memory32;
+	output_struct->id = ACPI_RSTYPE_MEM32;
 
 	/*
 	 *  Point to the place in the output buffer where the data portion will
-	 *    begin.
+	 *  begin.
 	 *  1. Set the RESOURCE_DATA * Data to point to it's own address, then
 	 *  2. Set the pointer to the next address.
 	 *
@@ -313,7 +303,6 @@
 	 * Return the final size of the structure
 	 */
 	*structure_size = struct_size;
-
 	return (AE_OK);
 }
 
@@ -323,20 +312,20 @@
  * FUNCTION:    Acpi_rs_fixed_memory32_resource
  *
  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
- *                                          stream
+ *                                        stream
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes consumed from
- *                                          the Byte_stream_buffer
+ *                                        the number of bytes consumed from
+ *                                        the Byte_stream_buffer
  *              Output_buffer           - Pointer to the user's return buffer
  *              Structure_size          - u32 pointer that is filled with
- *                                          the number of bytes in the filled
- *                                          in structure
+ *                                        the number of bytes in the filled
+ *                                        in structure
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *                  structure pointed to by the Output_buffer. Return the
- *                  number of bytes consumed from the byte stream.
+ *              structure pointed to by the Output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
  *
  ******************************************************************************/
 
@@ -348,11 +337,10 @@
 	u32                     *structure_size)
 {
 	u8                      *buffer = byte_stream_buffer;
-	RESOURCE                *output_struct = (RESOURCE *) * output_buffer;
+	ACPI_RESOURCE           *output_struct = (ACPI_RESOURCE *) *output_buffer;
 	u16                     temp16 = 0;
 	u8                      temp8 = 0;
-	u32                     struct_size = sizeof (FIXED_MEMORY32_RESOURCE) +
-			  RESOURCE_LENGTH_NO_DATA;
+	u32                     struct_size = SIZEOF_RESOURCE (ACPI_RESOURCE_FIXED_MEM32);
 
 
 	/*
@@ -364,7 +352,7 @@
 	buffer += 2;
 	*bytes_consumed = temp16 + 3;
 
-	output_struct->id = fixed_memory32;
+	output_struct->id = ACPI_RSTYPE_FIXED_MEM32;
 
 	/*
 	 * Check Byte 3 the Read/Write bit
@@ -395,7 +383,6 @@
 	 * Return the final size of the structure
 	 */
 	*structure_size = struct_size;
-
 	return (AE_OK);
 }
 
@@ -407,19 +394,19 @@
  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
  *              Output_buffer           - Pointer to the user's return buffer
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes of the
- *                                          Output_buffer used
+ *                                        the number of bytes of the
+ *                                        Output_buffer used
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the linked list resource structure and fills in the
- *                  the appropriate bytes in a byte stream
+ *              the appropriate bytes in a byte stream
  *
  ******************************************************************************/
 
 ACPI_STATUS
 acpi_rs_memory32_range_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed)
 {
@@ -476,9 +463,7 @@
 	/*
 	 * Return the number of bytes consumed in this operation
 	 */
-	*bytes_consumed = (u32) ((NATIVE_UINT) buffer -
-			   (NATIVE_UINT) *output_buffer);
-
+	*bytes_consumed = POINTER_DIFF (buffer, *output_buffer);
 	return (AE_OK);
 }
 
@@ -490,19 +475,19 @@
  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
  *              Output_buffer           - Pointer to the user's return buffer
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes of the
- *                                          Output_buffer used
+ *                                        the number of bytes of the
+ *                                        Output_buffer used
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the linked list resource structure and fills in the
- *                  the appropriate bytes in a byte stream
+ *              the appropriate bytes in a byte stream
  *
  ******************************************************************************/
 
 ACPI_STATUS
 acpi_rs_fixed_memory32_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed)
 {
@@ -549,9 +534,7 @@
 	/*
 	 * Return the number of bytes consumed in this operation
 	 */
-	*bytes_consumed = (u32) ((NATIVE_UINT) buffer -
-			   (NATIVE_UINT) *output_buffer);
-
+	*bytes_consumed = POINTER_DIFF (buffer, *output_buffer);
 	return (AE_OK);
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/resources/rsmisc.c linux/drivers/acpi/resources/rsmisc.c
--- v2.4.5/linux/drivers/acpi/resources/rsmisc.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/resources/rsmisc.c	Wed Jun 20 17:47:40 2001
@@ -1,14 +1,7 @@
 /*******************************************************************************
  *
- * Module Name: rsmisc - Acpi_rs_end_tag_resource
- *                       Acpi_rs_end_tag_stream
- *                       Acpi_rs_vendor_resource
- *                       Acpi_rs_vendor_stream
- *                       Acpi_rs_start_dependent_functions_resource
- *                       Acpi_rs_end_dependent_functions_resource
- *                       Acpi_rs_start_dependent_functions_stream
- *                       Acpi_rs_end_dependent_functions_stream
- *              $Revision: 12 $
+ * Module Name: rsmisc - Miscellaneous resource descriptors
+ *              $Revision: 15 $
  *
  ******************************************************************************/
 
@@ -34,7 +27,7 @@
 #include "acpi.h"
 #include "acresrc.h"
 
-#define _COMPONENT          RESOURCE_MANAGER
+#define _COMPONENT          ACPI_RESOURCES
 	 MODULE_NAME         ("rsmisc")
 
 
@@ -43,20 +36,20 @@
  * FUNCTION:    Acpi_rs_end_tag_resource
  *
  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
- *                                          stream
+ *                                        stream
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes consumed from
- *                                          the Byte_stream_buffer
+ *                                        the number of bytes consumed from
+ *                                        the Byte_stream_buffer
  *              Output_buffer           - Pointer to the user's return buffer
  *              Structure_size          - u32 pointer that is filled with
- *                                          the number of bytes in the filled
- *                                          in structure
+ *                                        the number of bytes in the filled
+ *                                        in structure
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *                  structure pointed to by the Output_buffer. Return the
- *                  number of bytes consumed from the byte stream.
+ *              structure pointed to by the Output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
  *
  ******************************************************************************/
 
@@ -67,8 +60,8 @@
 	u8                      **output_buffer,
 	u32                     *structure_size)
 {
-	RESOURCE                *output_struct = (RESOURCE *) * output_buffer;
-	u32                     struct_size = RESOURCE_LENGTH;
+	ACPI_RESOURCE           *output_struct = (ACPI_RESOURCE *) *output_buffer;
+	u32                     struct_size = ACPI_RESOURCE_LENGTH;
 
 
 	/*
@@ -79,7 +72,7 @@
 	/*
 	 *  Fill out the structure
 	 */
-	output_struct->id = end_tag;
+	output_struct->id = ACPI_RSTYPE_END_TAG;
 
 	/*
 	 * Set the Length parameter
@@ -90,7 +83,6 @@
 	 * Return the final size of the structure
 	 */
 	*structure_size = struct_size;
-
 	return (AE_OK);
 }
 
@@ -102,19 +94,19 @@
  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
  *              Output_buffer           - Pointer to the user's return buffer
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes of the
- *                                          Output_buffer used
+ *                                        the number of bytes of the
+ *                                        Output_buffer used
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the linked list resource structure and fills in the
- *                  the appropriate bytes in a byte stream
+ *              the appropriate bytes in a byte stream
  *
  ******************************************************************************/
 
 ACPI_STATUS
 acpi_rs_end_tag_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed)
 {
@@ -130,7 +122,7 @@
 
 	/*
 	 * Set the Checksum - zero means that the resource data is treated as if
-	 *  the checksum operation succeeded (ACPI Spec 1.0b Section 6.4.2.8)
+	 * the checksum operation succeeded (ACPI Spec 1.0b Section 6.4.2.8)
 	 */
 	temp8 = 0;
 
@@ -140,9 +132,7 @@
 	/*
 	 * Return the number of bytes consumed in this operation
 	 */
-	*bytes_consumed = (u32) ((NATIVE_UINT) buffer -
-			   (NATIVE_UINT) *output_buffer);
-
+	*bytes_consumed = POINTER_DIFF (buffer, *output_buffer);
 	return (AE_OK);
 }
 
@@ -152,20 +142,20 @@
  * FUNCTION:    Acpi_rs_vendor_resource
  *
  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
- *                                          stream
+ *                                        stream
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes consumed from
- *                                          the Byte_stream_buffer
+ *                                        the number of bytes consumed from
+ *                                        the Byte_stream_buffer
  *              Output_buffer           - Pointer to the user's return buffer
  *              Structure_size          - u32 pointer that is filled with
- *                                          the number of bytes in the filled
- *                                          in structure
+ *                                        the number of bytes in the filled
+ *                                        in structure
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *                  structure pointed to by the Output_buffer. Return the
- *                  number of bytes consumed from the byte stream.
+ *              structure pointed to by the Output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
  *
  ******************************************************************************/
 
@@ -177,12 +167,11 @@
 	u32                     *structure_size)
 {
 	u8                      *buffer = byte_stream_buffer;
-	RESOURCE                *output_struct = (RESOURCE *) * output_buffer;
+	ACPI_RESOURCE           *output_struct = (ACPI_RESOURCE *) *output_buffer;
 	u16                     temp16 = 0;
 	u8                      temp8 = 0;
 	u8                      index;
-	u32                     struct_size = sizeof (VENDOR_RESOURCE) +
-			  RESOURCE_LENGTH_NO_DATA;
+	u32                     struct_size = SIZEOF_RESOURCE (ACPI_RESOURCE_VENDOR);
 
 
 	/*
@@ -193,9 +182,8 @@
 	if (temp8 & 0x80) {
 		/*
 		 * Large Item
+		 * Point to the length field
 		 */
-		/* Point to the length field */
-
 		buffer += 1;
 
 		/* Dereference */
@@ -214,10 +202,8 @@
 	else {
 		/*
 		 * Small Item
+		 * Dereference the size
 		 */
-
-		/* Dereference the size */
-
 		temp16 = (u8)(*buffer & 0x07);
 
 		/* Calculate bytes consumed */
@@ -229,7 +215,7 @@
 		buffer += 1;
 	}
 
-	output_struct->id = vendor_specific;
+	output_struct->id = ACPI_RSTYPE_VENDOR;
 	output_struct->data.vendor_specific.length = temp16;
 
 	for (index = 0; index < temp16; index++) {
@@ -238,9 +224,9 @@
 	}
 
 	/*
-	 * In order for the Struct_size to fall on a 32-bit boundry,
-	 *  calculate the length of the vendor string and expand the
-	 *  Struct_size to the next 32-bit boundry.
+	 * In order for the Struct_size to fall on a 32-bit boundary,
+	 * calculate the length of the vendor string and expand the
+	 * Struct_size to the next 32-bit boundary.
 	 */
 	struct_size += ROUND_UP_TO_32_bITS (temp16);
 
@@ -253,7 +239,6 @@
 	 * Return the final size of the structure
 	 */
 	*structure_size = struct_size;
-
 	return (AE_OK);
 }
 
@@ -265,19 +250,19 @@
  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
  *              Output_buffer           - Pointer to the user's return buffer
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes of the
- *                                          Output_buffer used
+ *                                        the number of bytes of the
+ *                                        Output_buffer used
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the linked list resource structure and fills in the
- *                  the appropriate bytes in a byte stream
+ *              the appropriate bytes in a byte stream
  *
  ******************************************************************************/
 
 ACPI_STATUS
 acpi_rs_vendor_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed)
 {
@@ -290,12 +275,9 @@
 	/*
 	 * Dereference the length to find if this is a large or small item.
 	 */
-
 	if(linked_list->data.vendor_specific.length > 7) {
 		/*
 		 * Large Item
-		 */
-		/*
 		 * Set the descriptor field and length bytes
 		 */
 		*buffer = 0x84;
@@ -310,9 +292,6 @@
 	else {
 		/*
 		 * Small Item
-		 */
-
-		/*
 		 * Set the descriptor field
 		 */
 		temp8 = 0x70;
@@ -335,9 +314,7 @@
 	/*
 	 * Return the number of bytes consumed in this operation
 	 */
-	*bytes_consumed = (u32) ((NATIVE_UINT) buffer -
-			   (NATIVE_UINT) *output_buffer);
-
+	*bytes_consumed = POINTER_DIFF (buffer, *output_buffer);
 	return (AE_OK);
 }
 
@@ -347,20 +324,20 @@
  * FUNCTION:    Acpi_rs_start_dependent_functions_resource
  *
  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
- *                                          stream
+ *                                        stream
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes consumed from
- *                                          the Byte_stream_buffer
+ *                                        the number of bytes consumed from
+ *                                        the Byte_stream_buffer
  *              Output_buffer           - Pointer to the user's return buffer
  *              Structure_size          - u32 pointer that is filled with
- *                                          the number of bytes in the filled
- *                                          in structure
+ *                                        the number of bytes in the filled
+ *                                        in structure
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *                  structure pointed to by the Output_buffer. Return the
- *                  number of bytes consumed from the byte stream.
+ *              structure pointed to by the Output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
  *
  ******************************************************************************/
 
@@ -372,11 +349,9 @@
 	u32                     *structure_size)
 {
 	u8                      *buffer = byte_stream_buffer;
-	RESOURCE                *output_struct = (RESOURCE *) * output_buffer;
+	ACPI_RESOURCE          *output_struct = (ACPI_RESOURCE *) *output_buffer;
 	u8                      temp8 = 0;
-	u32                     struct_size =
-			  sizeof(START_DEPENDENT_FUNCTIONS_RESOURCE) +
-			  RESOURCE_LENGTH_NO_DATA;
+	u32                     struct_size = SIZEOF_RESOURCE (ACPI_RESOURCE_START_DPF);
 
 
 	/*
@@ -386,7 +361,7 @@
 
 	*bytes_consumed = (temp8 & 0x01) + 1;
 
-	output_struct->id = start_dependent_functions;
+	output_struct->id = ACPI_RSTYPE_START_DPF;
 
 	/*
 	 * Point to Byte 1 if it is used
@@ -398,29 +373,27 @@
 		/*
 		 * Check Compatibility priority
 		 */
-		output_struct->data.start_dependent_functions.compatibility_priority =
-				temp8 & 0x03;
+		output_struct->data.start_dpf.compatibility_priority = temp8 & 0x03;
 
-		if (3 == output_struct->data.start_dependent_functions.compatibility_priority) {
+		if (3 == output_struct->data.start_dpf.compatibility_priority) {
 			return (AE_AML_ERROR);
 		}
 
 		/*
 		 * Check Performance/Robustness preference
 		 */
-		output_struct->data.start_dependent_functions.performance_robustness =
-				(temp8 >> 2) & 0x03;
+		output_struct->data.start_dpf.performance_robustness = (temp8 >> 2) & 0x03;
 
-		if (3 == output_struct->data.start_dependent_functions.performance_robustness) {
+		if (3 == output_struct->data.start_dpf.performance_robustness) {
 			return (AE_AML_ERROR);
 		}
 	}
 
 	else {
-		output_struct->data.start_dependent_functions.compatibility_priority =
+		output_struct->data.start_dpf.compatibility_priority =
 				ACCEPTABLE_CONFIGURATION;
 
-		output_struct->data.start_dependent_functions.performance_robustness =
+		output_struct->data.start_dpf.performance_robustness =
 				ACCEPTABLE_CONFIGURATION;
 	}
 
@@ -433,7 +406,6 @@
 	 * Return the final size of the structure
 	 */
 	*structure_size = struct_size;
-
 	return (AE_OK);
 }
 
@@ -443,20 +415,20 @@
  * FUNCTION:    Acpi_rs_end_dependent_functions_resource
  *
  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource input byte
- *                                          stream
+ *                                        stream
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes consumed from
- *                                          the Byte_stream_buffer
+ *                                        the number of bytes consumed from
+ *                                        the Byte_stream_buffer
  *              Output_buffer           - Pointer to the user's return buffer
  *              Structure_size          - u32 pointer that is filled with
- *                                          the number of bytes in the filled
- *                                          in structure
+ *                                        the number of bytes in the filled
+ *                                        in structure
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *                  structure pointed to by the Output_buffer. Return the
- *                  number of bytes consumed from the byte stream.
+ *              structure pointed to by the Output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
  *
  ******************************************************************************/
 
@@ -467,8 +439,8 @@
 	u8                      **output_buffer,
 	u32                     *structure_size)
 {
-	RESOURCE                *output_struct = (RESOURCE *) * output_buffer;
-	u32                     struct_size = RESOURCE_LENGTH;
+	ACPI_RESOURCE           *output_struct = (ACPI_RESOURCE *) *output_buffer;
+	u32                     struct_size = ACPI_RESOURCE_LENGTH;
 
 
 	/*
@@ -479,7 +451,7 @@
 	/*
 	 *  Fill out the structure
 	 */
-	output_struct->id = end_dependent_functions;
+	output_struct->id = ACPI_RSTYPE_END_DPF;
 
 	/*
 	 * Set the Length parameter
@@ -490,7 +462,6 @@
 	 * Return the final size of the structure
 	 */
 	*structure_size = struct_size;
-
 	return (AE_OK);
 }
 
@@ -502,19 +473,19 @@
  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
  *              Output_buffer           - Pointer to the user's return buffer
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes of the
- *                                          Output_buffer used
+ *                                        the number of bytes of the
+ *                                        Output_buffer used
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the linked list resource structure and fills in the
- *                  the appropriate bytes in a byte stream
+ *              the appropriate bytes in a byte stream
  *
  ******************************************************************************/
 
 ACPI_STATUS
 acpi_rs_start_dependent_functions_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed)
 {
@@ -524,13 +495,12 @@
 
 	/*
 	 * The descriptor field is set based upon whether a byte is needed
-	 *  to contain Priority data.
+	 * to contain Priority data.
 	 */
 	if (ACCEPTABLE_CONFIGURATION ==
-			linked_list->data.start_dependent_functions.compatibility_priority &&
+			linked_list->data.start_dpf.compatibility_priority &&
 		ACCEPTABLE_CONFIGURATION ==
-			linked_list->data.start_dependent_functions.performance_robustness)
-	{
+			linked_list->data.start_dpf.performance_robustness) {
 		*buffer = 0x30;
 	}
 	else {
@@ -541,13 +511,10 @@
 		 * Set the Priority Byte Definition
 		 */
 		temp8 = 0;
-		temp8 = (u8)
-			((linked_list->data.start_dependent_functions.performance_robustness &
-			  0x03) << 2);
-		temp8 |=
-			(linked_list->data.start_dependent_functions.compatibility_priority &
-			 0x03);
-
+		temp8 = (u8) ((linked_list->data.start_dpf.performance_robustness &
+				   0x03) << 2);
+		temp8 |= (linked_list->data.start_dpf.compatibility_priority &
+				   0x03);
 		*buffer = temp8;
 	}
 
@@ -556,9 +523,7 @@
 	/*
 	 * Return the number of bytes consumed in this operation
 	 */
-	*bytes_consumed = (u32) ((NATIVE_UINT) buffer -
-			   (NATIVE_UINT) *output_buffer);
-
+	*bytes_consumed = POINTER_DIFF (buffer, *output_buffer);
 	return (AE_OK);
 }
 
@@ -570,19 +535,19 @@
  * PARAMETERS:  Linked_list             - Pointer to the resource linked list
  *              Output_buffer           - Pointer to the user's return buffer
  *              Bytes_consumed          - u32 pointer that is filled with
- *                                          the number of bytes of the
- *                                          Output_buffer used
+ *                                        the number of bytes of the
+ *                                        Output_buffer used
  *
- * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
+ * RETURN:      Status
  *
  * DESCRIPTION: Take the linked list resource structure and fills in the
- *                  the appropriate bytes in a byte stream
+ *              the appropriate bytes in a byte stream
  *
  ******************************************************************************/
 
 ACPI_STATUS
 acpi_rs_end_dependent_functions_stream (
-	RESOURCE                *linked_list,
+	ACPI_RESOURCE           *linked_list,
 	u8                      **output_buffer,
 	u32                     *bytes_consumed
 	)
@@ -599,9 +564,7 @@
 	/*
 	 * Return the number of bytes consumed in this operation
 	 */
-	*bytes_consumed = (u32) ((NATIVE_UINT) buffer -
-			   (NATIVE_UINT) *output_buffer);
-
+	*bytes_consumed = POINTER_DIFF (buffer, *output_buffer);
 	return (AE_OK);
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/resources/rsutils.c linux/drivers/acpi/resources/rsutils.c
--- v2.4.5/linux/drivers/acpi/resources/rsutils.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/resources/rsutils.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: rsutils - Utilities for the resource manager
- *              $Revision: 14 $
+ *              $Revision: 19 $
  *
  ******************************************************************************/
 
@@ -29,7 +29,7 @@
 #include "acresrc.h"
 
 
-#define _COMPONENT          RESOURCE_MANAGER
+#define _COMPONENT          ACPI_RESOURCES
 	 MODULE_NAME         ("rsutils")
 
 
@@ -41,7 +41,7 @@
  *              Ret_buffer      - a pointer to a buffer structure for the
  *                                  results
  *
- * RETURN:      Status          - the status of the call
+ * RETURN:      Status
  *
  * DESCRIPTION: This function is called to get the _PRT value of an object
  *              contained in an object specified by the handle passed in
@@ -96,8 +96,7 @@
 	 *  byte stream buffer that comes back from the _CRS method
 	 *  execution.
 	 */
-	status = acpi_rs_create_pci_routing_table (ret_obj,
-			  ret_buffer->pointer,
+	status = acpi_rs_create_pci_routing_table (ret_obj, ret_buffer->pointer,
 			  &buffer_space_needed);
 
 	/*
@@ -111,8 +110,7 @@
 
 cleanup:
 
-	acpi_cm_remove_reference (ret_obj);
-
+	acpi_ut_remove_reference (ret_obj);
 	return (status);
 }
 
@@ -125,7 +123,7 @@
  *              Ret_buffer      - a pointer to a buffer structure for the
  *                                  results
  *
- * RETURN:      Status          - the status of the call
+ * RETURN:      Status
  *
  * DESCRIPTION: This function is called to get the _CRS value of an object
  *              contained in an object specified by the handle passed in
@@ -177,10 +175,8 @@
 	 *  byte stream buffer that comes back from the _CRS method
 	 *  execution.
 	 */
-	status = acpi_rs_create_resource_list (ret_obj,
-			  ret_buffer->pointer,
-			  &buffer_space_needed);
-
+	status = acpi_rs_create_resource_list (ret_obj, ret_buffer->pointer,
+			 &buffer_space_needed);
 
 
 	/*
@@ -194,8 +190,7 @@
 
 cleanup:
 
-	acpi_cm_remove_reference (ret_obj);
-
+	acpi_ut_remove_reference (ret_obj);
 	return (status);
 }
 
@@ -208,7 +203,7 @@
  *              Ret_buffer      - a pointer to a buffer structure for the
  *                                  results
  *
- * RETURN:      Status          - the status of the call
+ * RETURN:      Status
  *
  * DESCRIPTION: This function is called to get the _PRS value of an object
  *              contained in an object specified by the handle passed in
@@ -260,9 +255,8 @@
 	 *  byte stream buffer that comes back from the _CRS method
 	 *  execution.
 	 */
-	status = acpi_rs_create_resource_list (ret_obj,
-			  ret_buffer->pointer,
-			  &buffer_space_needed);
+	status = acpi_rs_create_resource_list (ret_obj, ret_buffer->pointer,
+			 &buffer_space_needed);
 
 	/*
 	 * Tell the user how much of the buffer we have used or is needed
@@ -275,8 +269,7 @@
 
 cleanup:
 
-	acpi_cm_remove_reference (ret_obj);
-
+	acpi_ut_remove_reference (ret_obj);
 	return (status);
 }
 
@@ -289,7 +282,7 @@
  *              In_buffer       - a pointer to a buffer structure of the
  *                                  parameter
  *
- * RETURN:      Status          - the status of the call
+ * RETURN:      Status
  *
  * DESCRIPTION: This function is called to set the _SRS of an object contained
  *              in an object specified by the handle passed in
@@ -315,20 +308,19 @@
 
 	/*
 	 * The In_buffer parameter will point to a linked list of
-	 *  resource parameters.  It needs to be formatted into a
-	 *  byte stream to be sent in as an input parameter.
+	 * resource parameters.  It needs to be formatted into a
+	 * byte stream to be sent in as an input parameter.
 	 */
 	buffer_size_needed = 0;
 
 	/*
 	 * First call is to get the buffer size needed
 	 */
-	status = acpi_rs_create_byte_stream (in_buffer->pointer,
-			   byte_stream,
-			   &buffer_size_needed);
+	status = acpi_rs_create_byte_stream (in_buffer->pointer, byte_stream,
+			 &buffer_size_needed);
 	/*
 	 * We expect a return of AE_BUFFER_OVERFLOW
-	 *  if not, exit with the error
+	 * if not, exit with the error
 	 */
 	if (AE_BUFFER_OVERFLOW != status) {
 		return (status);
@@ -337,7 +329,7 @@
 	/*
 	 * Allocate the buffer needed
 	 */
-	byte_stream = acpi_cm_callocate(buffer_size_needed);
+	byte_stream = acpi_ut_callocate(buffer_size_needed);
 	if (NULL == byte_stream) {
 		return (AE_NO_MEMORY);
 	}
@@ -345,20 +337,19 @@
 	/*
 	 * Now call to convert the linked list into a byte stream
 	 */
-	status = acpi_rs_create_byte_stream (in_buffer->pointer,
-			   byte_stream,
-			   &buffer_size_needed);
+	status = acpi_rs_create_byte_stream (in_buffer->pointer, byte_stream,
+			 &buffer_size_needed);
 	if (ACPI_FAILURE (status)) {
 		goto cleanup;
 	}
 
 	/*
-	 *  Init the param object
+	 * Init the param object
 	 */
-	acpi_cm_init_static_object (&param_obj);
+	acpi_ut_init_static_object (&param_obj);
 
 	/*
-	 *  Method requires one parameter.  Set it up
+	 * Method requires one parameter.  Set it up
 	 */
 	params [0] = &param_obj;
 	params [1] = NULL;
@@ -371,17 +362,16 @@
 	param_obj.buffer.pointer = byte_stream;
 
 	/*
-	 *  Execute the method, no return value
+	 * Execute the method, no return value
 	 */
 	status = acpi_ns_evaluate_relative (handle, "_SRS", params, NULL);
 
 	/*
-	 *  Clean up and return the status from Acpi_ns_evaluate_relative
+	 * Clean up and return the status from Acpi_ns_evaluate_relative
 	 */
-
 cleanup:
 
-	acpi_cm_free (byte_stream);
+	acpi_ut_free (byte_stream);
 	return (status);
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/resources/rsxface.c linux/drivers/acpi/resources/rsxface.c
--- v2.4.5/linux/drivers/acpi/resources/rsxface.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/resources/rsxface.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
- * Module Name: rsxface - Public interfaces to the ACPI subsystem
- *              $Revision: 10 $
+ * Module Name: rsxface - Public interfaces to the resource manager
+ *              $Revision: 13 $
  *
  ******************************************************************************/
 
@@ -29,7 +29,7 @@
 #include "acnamesp.h"
 #include "acresrc.h"
 
-#define _COMPONENT          RESOURCE_MANAGER
+#define _COMPONENT          ACPI_RESOURCES
 	 MODULE_NAME         ("rsxface")
 
 
@@ -41,7 +41,7 @@
  *              Ret_buffer      - a pointer to a buffer to receive the
  *                                current resources for the device
  *
- * RETURN:      Status          - the status of the call
+ * RETURN:      Status
  *
  * DESCRIPTION: This function is called to get the IRQ routing table for a
  *              specific bus.  The caller must first acquire a handle for the
@@ -64,21 +64,26 @@
 	ACPI_STATUS             status;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/*
-	 *  Must have a valid handle and buffer, So we have to have a handle
-	 *  and a return buffer structure, and if there is a non-zero buffer length
-	 *  we also need a valid pointer in the buffer. If it's a zero buffer length,
-	 *  we'll be returning the needed buffer size, so keep going.
+	 * Must have a valid handle and buffer, So we have to have a handle
+	 * and a return buffer structure, and if there is a non-zero buffer length
+	 * we also need a valid pointer in the buffer. If it's a zero buffer length,
+	 * we'll be returning the needed buffer size, so keep going.
 	 */
 	if ((!device_handle)        ||
 		(!ret_buffer)           ||
-		((!ret_buffer->pointer) && (ret_buffer->length)))
-	{
+		((!ret_buffer->pointer) && (ret_buffer->length))) {
 		return (AE_BAD_PARAMETER);
 	}
 
 	status = acpi_rs_get_prt_method_data (device_handle, ret_buffer);
-
 	return (status);
 }
 
@@ -92,7 +97,7 @@
  *              Ret_buffer      - a pointer to a buffer to receive the
  *                                current resources for the device
  *
- * RETURN:      Status          - the status of the call
+ * RETURN:      Status
  *
  * DESCRIPTION: This function is called to get the current resources for a
  *              specific device.  The caller must first acquire a handle for
@@ -115,21 +120,26 @@
 	ACPI_STATUS             status;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/*
-	 *  Must have a valid handle and buffer, So we have to have a handle
-	 *  and a return buffer structure, and if there is a non-zero buffer length
-	 *  we also need a valid pointer in the buffer. If it's a zero buffer length,
-	 *  we'll be returning the needed buffer size, so keep going.
+	 * Must have a valid handle and buffer, So we have to have a handle
+	 * and a return buffer structure, and if there is a non-zero buffer length
+	 * we also need a valid pointer in the buffer. If it's a zero buffer length,
+	 * we'll be returning the needed buffer size, so keep going.
 	 */
 	if ((!device_handle)        ||
 		(!ret_buffer)           ||
-		((ret_buffer->length) && (!ret_buffer->pointer)))
-	{
+		((ret_buffer->length) && (!ret_buffer->pointer))) {
 		return (AE_BAD_PARAMETER);
 	}
 
 	status = acpi_rs_get_crs_method_data (device_handle, ret_buffer);
-
 	return (status);
 }
 
@@ -143,7 +153,7 @@
  *              Ret_buffer      - a pointer to a buffer to receive the
  *                                resources for the device
  *
- * RETURN:      Status          - the status of the call
+ * RETURN:      Status
  *
  * DESCRIPTION: This function is called to get a list of the possible resources
  *              for a specific device.  The caller must first acquire a handle
@@ -163,21 +173,26 @@
 	ACPI_STATUS             status;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/*
-	 *  Must have a valid handle and buffer, So we have to have a handle
-	 *  and a return buffer structure, and if there is a non-zero buffer length
-	 *  we also need a valid pointer in the buffer. If it's a zero buffer length,
-	 *  we'll be returning the needed buffer size, so keep going.
+	 * Must have a valid handle and buffer, So we have to have a handle
+	 * and a return buffer structure, and if there is a non-zero buffer length
+	 * we also need a valid pointer in the buffer. If it's a zero buffer length,
+	 * we'll be returning the needed buffer size, so keep going.
 	 */
 	if ((!device_handle)        ||
 		(!ret_buffer)           ||
-		((ret_buffer->length) && (!ret_buffer->pointer)))
-	{
+		((ret_buffer->length) && (!ret_buffer->pointer))) {
 		return (AE_BAD_PARAMETER);
-   }
+	}
 
 	status = acpi_rs_get_prs_method_data (device_handle, ret_buffer);
-
 	return (status);
 }
 
@@ -191,7 +206,7 @@
  *              In_buffer       - a pointer to a buffer containing the
  *                                resources to be set for the device
  *
- * RETURN:      Status          - the status of the call
+ * RETURN:      Status
  *
  * DESCRIPTION: This function is called to set the current resources for a
  *              specific device.  The caller must first acquire a handle for
@@ -208,18 +223,23 @@
 	ACPI_STATUS             status;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/*
-	 *  Must have a valid handle and buffer
+	 * Must have a valid handle and buffer
 	 */
 	if ((!device_handle)      ||
 		(!in_buffer)          ||
 		(!in_buffer->pointer) ||
-		(!in_buffer->length))
-	{
+		(!in_buffer->length)) {
 		return (AE_BAD_PARAMETER);
 	}
 
 	status = acpi_rs_set_srs_method_data (device_handle, in_buffer);
-
 	return (status);
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/sys.c linux/drivers/acpi/sys.c
--- v2.4.5/linux/drivers/acpi/sys.c	Mon Jan 29 10:15:59 2001
+++ linux/drivers/acpi/sys.c	Wed Dec 31 16:00:00 1969
@@ -1,146 +0,0 @@
-/*
- *  sys.c - System management (suspend, ...)
- *
- *  Copyright (C) 2000 Andrew Henroid
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/kernel.h>
-#include <linux/pm.h>
-#include <linux/acpi.h>
-#include "acpi.h"
-#include "driver.h"
-
-#define _COMPONENT	OS_DEPENDENT
-	MODULE_NAME	("sys")
-
-struct acpi_enter_sx_ctx
-{
-	wait_queue_head_t wait;
-	unsigned int      state;
-};
-
-volatile acpi_sstate_t acpi_sleep_state = ACPI_STATE_S0;
-
-/*
- * Enter system sleep state
- */
-static void
-acpi_enter_sx_async(void *context)
-{
-	struct acpi_enter_sx_ctx *ctx = (struct acpi_enter_sx_ctx*) context;
-	ACPI_OBJECT_LIST arg_list;
-	ACPI_OBJECT arg;
-
-	acpi_enter_sleep_state(ctx->state);
-
-	/* either we are in S1, or the transition failed, as the other states resume
-           from the waking vector */
-	if (ctx->state != ACPI_STATE_S1) {
-		printk(KERN_ERR "Could not enter S%d\n", ctx->state);
-		goto out;
-	}
-
-	/* wait until S1 is entered */
-	while (!(acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, WAK_STS)))
-		safe_halt();
-
-	/* run the _WAK method */
-	memset(&arg_list, 0, sizeof(arg_list));
-	arg_list.count = 1;
-	arg_list.pointer = &arg;
-
-	memset(&arg, 0, sizeof(arg));
-	arg.type = ACPI_TYPE_INTEGER;
-	arg.integer.value = ctx->state;
-
-	acpi_evaluate_object(NULL, "\\_WAK", &arg_list, NULL);
-
- out:
-	acpi_sleep_state = ACPI_STATE_S0;
-
-	if (waitqueue_active(&ctx->wait))
-		wake_up_interruptible(&ctx->wait);
-}
-
-/*
- * Enter soft-off (S5)
- */
-static void
-acpi_power_off(void)
-{
-	struct acpi_enter_sx_ctx ctx;
-	
-	init_waitqueue_head(&ctx.wait);
-	ctx.state = ACPI_STATE_S5;
-	acpi_enter_sx_async(&ctx);
-}
-
-/*
- * Enter system sleep state and wait for completion
- */
-int
-acpi_enter_sx(acpi_sstate_t state)
-{
-	struct acpi_enter_sx_ctx ctx;
-	DECLARE_WAITQUEUE(wait, current);
-	int ret = 0;
-
-	init_waitqueue_head(&ctx.wait);
-	ctx.state = state;
-
-	set_current_state(TASK_INTERRUPTIBLE);
-	add_wait_queue(&ctx.wait, &wait);
-
-	if (acpi_os_queue_for_execution(0, acpi_enter_sx_async, &ctx))
-		ret = -1;
-
-	if (!ret)
-		schedule();
-
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&ctx.wait, &wait);
-
-	if (!ret && signal_pending(current))
-		ret = -ERESTARTSYS;
-
-	return ret;
-}
-
-int
-acpi_sys_init(void)
-{
-	u8 sx;
-	u8 type_a;
-	u8 type_b;
-
-	printk(KERN_INFO "ACPI: System firmware supports:");
-
-	for (sx = ACPI_STATE_S0; sx <= ACPI_STATE_S5; sx++) {
-		if (ACPI_SUCCESS(
-			   acpi_hw_obtain_sleep_type_register_data(sx,
-								   &type_a,
-								   &type_b))) {
-
-			printk(" S%d", sx);
-		}
-	}
-	printk("\n");
-	
-	pm_power_off = acpi_power_off;
-
-	return 0;
-}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/table.c linux/drivers/acpi/table.c
--- v2.4.5/linux/drivers/acpi/table.c	Mon Jan 29 10:15:59 2001
+++ linux/drivers/acpi/table.c	Wed Dec 31 16:00:00 1969
@@ -1,71 +0,0 @@
-/*
- *  table.c - ACPI tables, chipset, and errata handling
- *
- *  Copyright (C) 2000 Andrew Henroid
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pm.h>
-#include <linux/acpi.h>
-#include "acpi.h"
-#include "driver.h"
-
-#define _COMPONENT	OS_DEPENDENT
-	MODULE_NAME	("table")
-
-FADT_DESCRIPTOR acpi_fadt;
-
-/*
- * Fetch the fadt information
- */
-static int
-acpi_fetch_fadt(void)
-{
-	ACPI_BUFFER buffer;
-
-	memset(&acpi_fadt, 0, sizeof(acpi_fadt));
-	buffer.pointer = &acpi_fadt;
-	buffer.length = sizeof(acpi_fadt);
-	if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_FADT, 1, &buffer))) {
-		printk(KERN_ERR "ACPI: missing fadt\n");
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
-/*
- * Find and load ACPI tables
- */
-int
-acpi_find_and_load_tables(u64 rsdp)
-{
-	if (!ACPI_SUCCESS(acpi_load_tables(rsdp))) {
-		printk(KERN_INFO "ACPI: System description table load failed\n");
-		acpi_terminate();
-		return -1;
-	}
-
-	if (acpi_fetch_fadt()) {
-		acpi_terminate();
-		return -1;
-	}
-
-	return 0;
-}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/tables/Makefile linux/drivers/acpi/tables/Makefile
--- v2.4.5/linux/drivers/acpi/tables/Makefile	Fri Dec 29 14:07:21 2000
+++ linux/drivers/acpi/tables/Makefile	Wed Jun 20 17:47:40 2001
@@ -1,16 +1,12 @@
 #
 # Makefile for all Linux ACPI interpreter subdirectories
+# EXCEPT for the ospm directory
 #
 
-O_TARGET := ../$(shell basename `pwd`).o
+O_TARGET := $(notdir $(CURDIR)).o
 
 obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c))
 
-EXTRA_CFLAGS += -I../include
-
 EXTRA_CFLAGS += $(ACPI_CFLAGS)
 
 include $(TOPDIR)/Rules.make
-
-clean:
-	$(RM) *.o 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/tables/tbconvrt.c linux/drivers/acpi/tables/tbconvrt.c
--- v2.4.5/linux/drivers/acpi/tables/tbconvrt.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/tables/tbconvrt.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: tbconvrt - ACPI Table conversion utilities
- *              $Revision: 19 $
+ *              $Revision: 23 $
  *
  *****************************************************************************/
 
@@ -30,34 +30,13 @@
 #include "actbl.h"
 
 
-#define _COMPONENT          TABLE_MANAGER
+#define _COMPONENT          ACPI_TABLES
 	 MODULE_NAME         ("tbconvrt")
 
 
-/*
- * Build a GAS structure from earlier ACPI table entries (V1.0 and 0.71 extensions)
- *
- * 1) Address space
- * 2) Length in bytes -- convert to length in bits
- * 3) Bit offset is zero
- * 4) Reserved field is zero
- * 5) Expand address to 64 bits
- */
-#define ASL_BUILD_GAS_FROM_ENTRY(a,b,c,d)   {a.address_space_id = (u8) d;\
-			   a.register_bit_width = (u8) MUL_8 (b);\
-			   a.register_bit_offset = 0;\
-			   a.reserved = 0;\
-			   ACPI_STORE_ADDRESS (a.address,c);}
-
-
-/* ACPI V1.0 entries -- address space is always I/O */
-
-#define ASL_BUILD_GAS_FROM_V1_ENTRY(a,b,c)  ASL_BUILD_GAS_FROM_ENTRY(a,b,c,ADDRESS_SPACE_SYSTEM_IO)
-
-
 /*******************************************************************************
  *
- * FUNCTION:    Acpi_tb_convert_to_xsdt
+ * FUNCTION:    Acpi_tb_get_table_count
  *
  * PARAMETERS:
  *
@@ -67,20 +46,17 @@
  *
  ******************************************************************************/
 
-ACPI_STATUS
-acpi_tb_convert_to_xsdt (
-	ACPI_TABLE_DESC         *table_info,
-	u32                     *number_of_tables)
+u32
+acpi_tb_get_table_count (
+	RSDP_DESCRIPTOR         *RSDP,
+	ACPI_TABLE_HEADER       *RSDT)
 {
-	u32                     table_size;
 	u32                     pointer_size;
-	u32                     i;
-	XSDT_DESCRIPTOR         *new_table;
 
 
 #ifndef _IA64
 
-	if (acpi_gbl_RSDP->revision < 2) {
+	if (RSDP->revision < 2) {
 		pointer_size = sizeof (u32);
 	}
 
@@ -97,9 +73,34 @@
 	 * is architecture-dependent.
 	 */
 
-	table_size = table_info->pointer->length;
-	*number_of_tables = (table_size -
-			   sizeof (ACPI_TABLE_HEADER)) / pointer_size;
+	return ((RSDT->length - sizeof (ACPI_TABLE_HEADER)) / pointer_size);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_tb_convert_to_xsdt
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION:
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_tb_convert_to_xsdt (
+	ACPI_TABLE_DESC         *table_info,
+	u32                     *number_of_tables)
+{
+	u32                     table_size;
+	u32                     i;
+	XSDT_DESCRIPTOR         *new_table;
+
+
+	*number_of_tables = acpi_tb_get_table_count (acpi_gbl_RSDP, table_info->pointer);
+
 
 	/* Compute size of the converted XSDT */
 
@@ -108,7 +109,7 @@
 
 	/* Allocate an XSDT */
 
-	new_table = acpi_cm_callocate (table_size);
+	new_table = acpi_ut_callocate (table_size);
 	if (!new_table) {
 		return (AE_NO_MEMORY);
 	}
@@ -193,7 +194,7 @@
 	/* Acpi_gbl_FADT is valid */
 	/* Allocate and zero the 2.0 buffer */
 
-	FADT2 = acpi_cm_callocate (sizeof (FADT_DESCRIPTOR_REV2));
+	FADT2 = acpi_ut_callocate (sizeof (FADT_DESCRIPTOR_REV2));
 	if (FADT2 == NULL) {
 		return (AE_NO_MEMORY);
 	}
@@ -501,7 +502,7 @@
 
 	/* Allocate a common FACS */
 
-	common_facs = acpi_cm_callocate (sizeof (ACPI_COMMON_FACS));
+	common_facs = acpi_ut_callocate (sizeof (ACPI_COMMON_FACS));
 	if (!common_facs) {
 		return (AE_NO_MEMORY);
 	}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/tables/tbget.c linux/drivers/acpi/tables/tbget.c
--- v2.4.5/linux/drivers/acpi/tables/tbget.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/tables/tbget.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: tbget - ACPI Table get* routines
- *              $Revision: 43 $
+ *              $Revision: 48 $
  *
  *****************************************************************************/
 
@@ -29,11 +29,12 @@
 #include "actables.h"
 
 
-#define _COMPONENT          TABLE_MANAGER
+#define _COMPONENT          ACPI_TABLES
 	 MODULE_NAME         ("tbget")
 
 #define RSDP_CHECKSUM_LENGTH 20
 
+
 /*******************************************************************************
  *
  * FUNCTION:    Acpi_tb_get_table_ptr
@@ -72,13 +73,11 @@
 	 * For all table types (Single/Multiple), the first
 	 * instance is always in the list head.
 	 */
-
 	if (instance == 1) {
 		/*
 		 * Just pluck the pointer out of the global table!
 		 * Will be null if no table is present
 		 */
-
 		*table_ptr_loc = acpi_gbl_acpi_tables[table_type].pointer;
 		return (AE_OK);
 	}
@@ -92,11 +91,11 @@
 	}
 
 	/* Walk the list to get the desired table
-	 *  Since the if (Instance == 1) check above checked for the
-	 *  first table, setting Table_desc equal to the .Next member
-	 *  is actually pointing to the second table.  Therefore, we
-	 *  need to walk from the 2nd table until we reach the Instance
-	 *  that the user is looking for and return its table pointer.
+	 * Since the if (Instance == 1) check above checked for the
+	 * first table, setting Table_desc equal to the .Next member
+	 * is actually pointing to the second table.  Therefore, we
+	 * need to walk from the 2nd table until we reach the Instance
+	 * that the user is looking for and return its table pointer.
 	 */
 	table_desc = acpi_gbl_acpi_tables[table_type].next;
 	for (i = 2; i < instance; i++) {
@@ -159,7 +158,7 @@
 
 		/* Allocate buffer for the entire table */
 
-		full_table = acpi_cm_allocate (table_header->length);
+		full_table = acpi_ut_allocate (table_header->length);
 		if (!full_table) {
 			return (AE_NO_MEMORY);
 		}
@@ -182,8 +181,7 @@
 	else {
 		size = SIZE_IN_HEADER;
 
-		status = acpi_tb_map_acpi_table (physical_address, &size,
-				  (void **) &full_table);
+		status = acpi_tb_map_acpi_table (physical_address, &size, &full_table);
 		if (ACPI_FAILURE (status)) {
 			return (status);
 		}
@@ -382,8 +380,7 @@
 	/*
 	 * Obtain access to the RSDP structure
 	 */
-	status = acpi_os_map_memory (rsdp_physical_address,
-			  sizeof (RSDP_DESCRIPTOR),
+	status = acpi_os_map_memory (rsdp_physical_address, sizeof (RSDP_DESCRIPTOR),
 			  (void **) &table_ptr);
 	if (ACPI_FAILURE (status)) {
 		return (status);
@@ -439,32 +436,24 @@
 
 /*******************************************************************************
  *
- * FUNCTION:    Acpi_tb_get_table_rsdt
+ * FUNCTION:    Acpi_tb_get_rsdt_address
  *
- * PARAMETERS:  Number_of_tables    - Where the table count is placed
+ * PARAMETERS:  None
  *
- * RETURN:      Status
+ * RETURN:      RSDT physical address
  *
- * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
+ * DESCRIPTION: Extract the address of the RSDT or XSDT, depending on the
+ *              version of the RSDP
  *
  ******************************************************************************/
 
-ACPI_STATUS
-acpi_tb_get_table_rsdt (
-	u32                     *number_of_tables)
+ACPI_PHYSICAL_ADDRESS
+acpi_tb_get_rsdt_address (void)
 {
-	ACPI_TABLE_DESC         table_info;
-	ACPI_STATUS             status = AE_OK;
 	ACPI_PHYSICAL_ADDRESS   physical_address;
-	u32                     signature_length;
-	char                    *table_signature;
 
 
 	/*
-	 * Get the RSDT from the RSDP
-	 */
-
-	/*
 	 * For RSDP revision 0 or 1, we use the RSDT.
 	 * For RSDP revision 2 (and above), we use the XSDT
 	 */
@@ -475,17 +464,132 @@
 #else
 		physical_address = (ACPI_PHYSICAL_ADDRESS) acpi_gbl_RSDP->rsdt_physical_address;
 #endif
-		table_signature = RSDT_SIG;
-		signature_length = sizeof (RSDT_SIG) -1;
 	}
+
 	else {
 		physical_address = (ACPI_PHYSICAL_ADDRESS)
 				   ACPI_GET_ADDRESS (acpi_gbl_RSDP->xsdt_physical_address);
-		table_signature = XSDT_SIG;
-		signature_length = sizeof (XSDT_SIG) -1;
 	}
 
 
+	return (physical_address);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_tb_validate_rsdt
+ *
+ * PARAMETERS:  Table_ptr       - Addressable pointer to the RSDT.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Validate signature for the RSDT or XSDT
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_tb_validate_rsdt (
+	ACPI_TABLE_HEADER       *table_ptr)
+{
+	u32                     no_match;
+
+
+	/*
+	 * For RSDP revision 0 or 1, we use the RSDT.
+	 * For RSDP revision 2 (and above), we use the XSDT
+	 */
+	if (acpi_gbl_RSDP->revision < 2) {
+		no_match = STRNCMP ((char *) table_ptr, RSDT_SIG,
+				  sizeof (RSDT_SIG) -1);
+	}
+	else {
+		no_match = STRNCMP ((char *) table_ptr, XSDT_SIG,
+				  sizeof (XSDT_SIG) -1);
+	}
+
+
+	if (no_match) {
+		/* Invalid RSDT or XSDT signature */
+
+		REPORT_ERROR (("Invalid signature where RSDP indicates RSDT/XSDT should be located\n"));
+
+		return (AE_BAD_SIGNATURE);
+	}
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_tb_get_table_pointer
+ *
+ * PARAMETERS:  Physical_address    - Address from RSDT
+ *              Flags               - virtual or physical addressing
+ *              Table_ptr           - Addressable address (output)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create an addressable pointer to an ACPI table
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_tb_get_table_pointer (
+	ACPI_PHYSICAL_ADDRESS   physical_address,
+	u32                     flags,
+	u32                     *size,
+	ACPI_TABLE_HEADER       **table_ptr)
+{
+	ACPI_STATUS             status;
+
+
+	if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
+		*size = SIZE_IN_HEADER;
+		status = acpi_tb_map_acpi_table (physical_address, size, table_ptr);
+	}
+
+	else {
+		*size = 0;
+		*table_ptr = (ACPI_TABLE_HEADER *) (ACPI_TBLPTR) physical_address;
+
+		status = AE_OK;
+	}
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_tb_get_table_rsdt
+ *
+ * PARAMETERS:  Number_of_tables    - Where the table count is placed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_tb_get_table_rsdt (
+	u32                     *number_of_tables)
+{
+	ACPI_TABLE_DESC         table_info;
+	ACPI_STATUS             status;
+	ACPI_PHYSICAL_ADDRESS   physical_address;
+
+
+	/*
+	 * Get the RSDT from the RSDP
+	 */
+
+
+	physical_address = acpi_tb_get_rsdt_address ();
+
+
 	/* Get the RSDT/XSDT */
 
 	status = acpi_tb_get_table (physical_address, NULL, &table_info);
@@ -496,20 +600,16 @@
 
 	/* Check the RSDT or XSDT signature */
 
-	if (STRNCMP ((char *) table_info.pointer, table_signature,
-			  signature_length))
-	{
-		/* Invalid RSDT or XSDT signature */
-
-		REPORT_ERROR (("Invalid signature where RSDP indicates %s should be located\n",
-				  table_signature));
-
+	status = acpi_tb_validate_rsdt (table_info.pointer);
+	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
 
 
-	/* Valid RSDT signature, verify the checksum */
-
+	/*
+	 * Valid RSDT signature, verify the checksum.  If it fails, just
+	 * print a warning and ignore it.
+	 */
 	status = acpi_tb_verify_table_checksum (table_info.pointer);
 
 
@@ -538,7 +638,7 @@
  * FUNCTION:    Acpi_tb_get_table_facs
  *
  * PARAMETERS:  *Buffer_ptr             - If Buffer_ptr is valid, read data from
- *                                          buffer rather than searching memory
+ *                                        buffer rather than searching memory
  *              *Table_info             - Where the table info is returned
  *
  * RETURN:      Status
@@ -555,7 +655,7 @@
 	ACPI_TABLE_HEADER       *buffer_ptr,
 	ACPI_TABLE_DESC         *table_info)
 {
-	void                    *table_ptr = NULL;
+	ACPI_TABLE_HEADER       *table_ptr = NULL;
 	u32                     size;
 	u8                      allocation;
 	ACPI_STATUS             status = AE_OK;
@@ -573,7 +673,7 @@
 		 * Getting table from a file -- allocate a buffer and
 		 * read the table.
 		 */
-		table_ptr = acpi_cm_allocate (size);
+		table_ptr = acpi_ut_allocate (size);
 		if(!table_ptr) {
 			return (AE_NO_MEMORY);
 		}
@@ -590,7 +690,7 @@
 
 		status = acpi_tb_map_acpi_table ((ACPI_PHYSICAL_ADDRESS) ACPI_GET_ADDRESS (acpi_gbl_FADT->Xfirmware_ctrl),
 				   &size, &table_ptr);
-		if (ACPI_FAILURE(status)) {
+		if (ACPI_FAILURE (status)) {
 			return (status);
 		}
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/tables/tbinstal.c linux/drivers/acpi/tables/tbinstal.c
--- v2.4.5/linux/drivers/acpi/tables/tbinstal.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/tables/tbinstal.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: tbinstal - ACPI table installation and removal
- *              $Revision: 36 $
+ *              $Revision: 39 $
  *
  *****************************************************************************/
 
@@ -29,7 +29,7 @@
 #include "actables.h"
 
 
-#define _COMPONENT          TABLE_MANAGER
+#define _COMPONENT          ACPI_TABLES
 	 MODULE_NAME         ("tbinstal")
 
 
@@ -68,13 +68,13 @@
 
 	/* Lock tables while installing */
 
-	acpi_cm_acquire_mutex (ACPI_MTX_TABLES);
+	acpi_ut_acquire_mutex (ACPI_MTX_TABLES);
 
 	/* Install the table into the global data structure */
 
 	status = acpi_tb_init_table_descriptor (table_info->type, table_info);
 
-	acpi_cm_release_mutex (ACPI_MTX_TABLES);
+	acpi_ut_release_mutex (ACPI_MTX_TABLES);
 	return (status);
 }
 
@@ -127,8 +127,7 @@
 	for (i = 1; i < NUM_ACPI_TABLES; i++) {
 		if (!STRNCMP (table_header->signature,
 				  acpi_gbl_acpi_table_data[i].signature,
-				  acpi_gbl_acpi_table_data[i].sig_length))
-		{
+				  acpi_gbl_acpi_table_data[i].sig_length)) {
 			/*
 			 * Found a signature match, get the pertinent info from the
 			 * Table_data structure
@@ -226,7 +225,7 @@
 		 */
 
 		if (list_head->pointer) {
-			table_desc = acpi_cm_callocate (sizeof (ACPI_TABLE_DESC));
+			table_desc = acpi_ut_callocate (sizeof (ACPI_TABLE_DESC));
 			if (!table_desc) {
 				return (AE_NO_MEMORY);
 			}
@@ -262,7 +261,7 @@
 	table_desc->aml_pointer         = (u8 *) (table_desc->pointer + 1),
 	table_desc->aml_length          = (u32) (table_desc->length -
 			 (u32) sizeof (ACPI_TABLE_HEADER));
-	table_desc->table_id            = acpi_cm_allocate_owner_id (OWNER_TYPE_TABLE);
+	table_desc->table_id            = acpi_ut_allocate_owner_id (OWNER_TYPE_TABLE);
 	table_desc->loaded_into_namespace = FALSE;
 
 	/*
@@ -337,7 +336,7 @@
 	}
 
 
-	acpi_cm_acquire_mutex (ACPI_MTX_TABLES);
+	acpi_ut_acquire_mutex (ACPI_MTX_TABLES);
 
 	/* Free the table */
 
@@ -346,8 +345,7 @@
 
 	/* Clear the appropriate "typed" global table pointer */
 
-	switch (type)
-	{
+	switch (type) {
 	case ACPI_TABLE_RSDP:
 		acpi_gbl_RSDP = NULL;
 		break;
@@ -374,7 +372,7 @@
 		break;
 	}
 
-	acpi_cm_release_mutex (ACPI_MTX_TABLES);
+	acpi_ut_release_mutex (ACPI_MTX_TABLES);
 
 	return;
 }
@@ -445,8 +443,7 @@
 	if (table_desc->pointer) {
 		/* Valid table, determine type of memory allocation */
 
-		switch (table_desc->allocation)
-		{
+		switch (table_desc->allocation) {
 
 		case ACPI_MEM_NOT_ALLOCATED:
 			break;
@@ -454,7 +451,7 @@
 
 		case ACPI_MEM_ALLOCATED:
 
-			acpi_cm_free (table_desc->base_pointer);
+			acpi_ut_free (table_desc->base_pointer);
 			break;
 
 
@@ -527,7 +524,7 @@
 		/* Free the table descriptor */
 
 		next_desc = table_desc->next;
-		acpi_cm_free (table_desc);
+		acpi_ut_free (table_desc);
 	}
 
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/tables/tbutils.c linux/drivers/acpi/tables/tbutils.c
--- v2.4.5/linux/drivers/acpi/tables/tbutils.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/tables/tbutils.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: tbutils - Table manipulation utilities
- *              $Revision: 33 $
+ *              $Revision: 38 $
  *
  *****************************************************************************/
 
@@ -29,7 +29,7 @@
 #include "acinterp.h"
 
 
-#define _COMPONENT          TABLE_MANAGER
+#define _COMPONENT          ACPI_TABLES
 	 MODULE_NAME         ("tbutils")
 
 
@@ -57,8 +57,7 @@
 
 	for (i = 0; i < ACPI_TABLE_MAX; i++) {
 		list_head = &acpi_gbl_acpi_tables[i];
-		do
-		{
+		do {
 			if (list_head->table_id == table_id) {
 				*table_desc = list_head;
 				return (AE_OK);
@@ -108,8 +107,7 @@
 	/* Check for a pointer within the DSDT */
 
 	if ((acpi_gbl_DSDT) &&
-		(IS_IN_ACPI_TABLE (where, acpi_gbl_DSDT)))
-	{
+		(IS_IN_ACPI_TABLE (where, acpi_gbl_DSDT))) {
 		return (TRUE);
 	}
 
@@ -177,6 +175,9 @@
 	ACPI_NAME               signature;
 
 
+	PROC_NAME ("Tb_validate_table_header");
+
+
 	/* Verify that this is a valid address */
 
 	if (!acpi_os_readable (table_header, sizeof (ACPI_TABLE_HEADER))) {
@@ -187,8 +188,8 @@
 	/* Ensure that the signature is 4 ASCII characters */
 
 	MOVE_UNALIGNED32_TO_32 (&signature, &table_header->signature);
-	if (!acpi_cm_valid_acpi_name (signature)) {
-		REPORT_WARNING (("Invalid table signature found\n"));
+	if (!acpi_ut_valid_acpi_name (signature)) {
+		REPORT_WARNING (("Invalid table signature %4.4s found\n", &signature));
 		return (AE_BAD_SIGNATURE);
 	}
 
@@ -224,7 +225,7 @@
 acpi_tb_map_acpi_table (
 	ACPI_PHYSICAL_ADDRESS   physical_address,
 	u32                     *size,
-	void                    **logical_address)
+	ACPI_TABLE_HEADER       **logical_address)
 {
 	ACPI_TABLE_HEADER       *table;
 	u32                     table_size = *size;
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/tables/tbxface.c linux/drivers/acpi/tables/tbxface.c
--- v2.4.5/linux/drivers/acpi/tables/tbxface.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/tables/tbxface.c	Wed Jun 20 17:47:40 2001
@@ -2,7 +2,7 @@
  *
  * Module Name: tbxface - Public interfaces to the ACPI subsystem
  *                         ACPI table oriented interfaces
- *              $Revision: 34 $
+ *              $Revision: 39 $
  *
  *****************************************************************************/
 
@@ -31,7 +31,7 @@
 #include "actables.h"
 
 
-#define _COMPONENT          TABLE_MANAGER
+#define _COMPONENT          ACPI_TABLES
 	 MODULE_NAME         ("tbxface")
 
 
@@ -52,16 +52,23 @@
 acpi_load_tables (
 	ACPI_PHYSICAL_ADDRESS   rsdp_physical_address)
 {
-	ACPI_STATUS             status = AE_OK;
+	ACPI_STATUS             status;
 	u32                     number_of_tables = 0;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/* Map and validate the RSDP */
 
 	status = acpi_tb_verify_rsdp (rsdp_physical_address);
 	if (ACPI_FAILURE (status)) {
 		REPORT_ERROR (("Acpi_load_tables: RSDP Failed validation: %s\n",
-				  acpi_cm_format_exception (status)));
+				  acpi_ut_format_exception (status)));
 		goto error_exit;
 	}
 
@@ -70,7 +77,7 @@
 	status = acpi_tb_get_table_rsdt (&number_of_tables);
 	if (ACPI_FAILURE (status)) {
 		REPORT_ERROR (("Acpi_load_tables: Could not load RSDT: %s\n",
-				  acpi_cm_format_exception (status)));
+				  acpi_ut_format_exception (status)));
 		goto error_exit;
 	}
 
@@ -79,7 +86,7 @@
 	status = acpi_tb_get_all_tables (number_of_tables, NULL);
 	if (ACPI_FAILURE (status)) {
 		REPORT_ERROR (("Acpi_load_tables: Error getting required tables (DSDT/FADT/FACS): %s\n",
-				  acpi_cm_format_exception (status)));
+				  acpi_ut_format_exception (status)));
 		goto error_exit;
 	}
 
@@ -89,7 +96,7 @@
 	status = acpi_ns_load_namespace ();
 	if (ACPI_FAILURE (status)) {
 		REPORT_ERROR (("Acpi_load_tables: Could not load namespace: %s\n",
-				  acpi_cm_format_exception (status)));
+				  acpi_ut_format_exception (status)));
 		goto error_exit;
 	}
 
@@ -98,7 +105,7 @@
 
 error_exit:
 	REPORT_ERROR (("Acpi_load_tables: Could not load tables: %s\n",
-			  acpi_cm_format_exception (status)));
+			  acpi_ut_format_exception (status)));
 
 	return (status);
 }
@@ -118,8 +125,6 @@
  *              a valid header.  The header fields will be verified, and if it
  *              is determined that the table is invalid, the call will fail.
  *
- *              If the call fails an appropriate status will be returned.
- *
  ******************************************************************************/
 
 ACPI_STATUS
@@ -130,6 +135,13 @@
 	ACPI_TABLE_DESC         table_info;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	if (!table_ptr) {
 		return (AE_BAD_PARAMETER);
 	}
@@ -182,7 +194,15 @@
 	ACPI_TABLE_TYPE         table_type)
 {
 	ACPI_TABLE_DESC         *list_head;
+	ACPI_STATUS             status;
+
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
 
 	/* Parameter validation */
 
@@ -194,15 +214,13 @@
 	/* Find all tables of the requested type */
 
 	list_head = &acpi_gbl_acpi_tables[table_type];
-	do
-	{
+	do {
 		/*
 		 * Delete all namespace entries owned by this table.  Note that these
 		 * entries can appear anywhere in the namespace by virtue of the AML
 		 * "Scope" operator.  Thus, we need to track ownership by an ID, not
 		 * simply a position within the hierarchy
 		 */
-
 		acpi_ns_delete_namespace_by_owner (list_head->table_id);
 
 		/* Delete (or unmap) the actual table */
@@ -234,9 +252,6 @@
  *              function is not valid for the RSD PTR table since it does not
  *              have a standard header and is fixed length.
  *
- *              If the operation fails for any reason an appropriate status will
- *              be returned and the contents of Out_table_header are undefined.
- *
  ******************************************************************************/
 
 ACPI_STATUS
@@ -249,10 +264,16 @@
 	ACPI_STATUS             status;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	if ((instance == 0)                 ||
 		(table_type == ACPI_TABLE_RSDP) ||
-		(!out_table_header))
-	{
+		(!out_table_header)) {
 		return (AE_BAD_PARAMETER);
 	}
 
@@ -260,8 +281,7 @@
 
 	if ((table_type > ACPI_TABLE_MAX)   ||
 		(IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags) &&
-		 instance > 1))
-	{
+		 instance > 1)) {
 		return (AE_BAD_PARAMETER);
 	}
 
@@ -311,9 +331,6 @@
  *              copied into the Out_buffer->Buf_ptr buffer. This table will be
  *              a complete table including the header.
  *
- *              If the operation fails an appropriate status will be returned
- *              and the contents of Out_buffer are undefined.
- *
  ******************************************************************************/
 
 ACPI_STATUS
@@ -327,13 +344,19 @@
 	u32                     ret_buf_len;
 
 
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	/*
 	 *  If we have a buffer, we must have a length too
 	 */
 	if ((instance == 0)                 ||
 		(!ret_buffer)                   ||
-		((!ret_buffer->pointer) && (ret_buffer->length)))
-	{
+		((!ret_buffer->pointer) && (ret_buffer->length))) {
 		return (AE_BAD_PARAMETER);
 	}
 
@@ -341,8 +364,7 @@
 
 	if ((table_type > ACPI_TABLE_MAX)   ||
 		(IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags) &&
-		 instance > 1))
-	{
+		 instance > 1)) {
 		return (AE_BAD_PARAMETER);
 	}
 
@@ -356,7 +378,7 @@
 
 	/*
 	 * Acpi_tb_get_table_ptr will return a NULL pointer if the
-	 *  table is not loaded.
+	 * table is not loaded.
 	 */
 	if (tbl_ptr == NULL) {
 		return (AE_NOT_EXIST);
@@ -389,4 +411,5 @@
 
 	return (AE_OK);
 }
+
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/tables/tbxfroot.c linux/drivers/acpi/tables/tbxfroot.c
--- v2.4.5/linux/drivers/acpi/tables/tbxfroot.c	Mon Jan 22 13:23:43 2001
+++ linux/drivers/acpi/tables/tbxfroot.c	Wed Jun 20 17:47:40 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: tbxfroot - Find the root ACPI table (RSDT)
- *              $Revision: 35 $
+ *              $Revision: 39 $
  *
  *****************************************************************************/
 
@@ -29,7 +29,7 @@
 #include "actables.h"
 
 
-#define _COMPONENT          TABLE_MANAGER
+#define _COMPONENT          ACPI_TABLES
 	 MODULE_NAME         ("tbxfroot")
 
 #define RSDP_CHECKSUM_LENGTH 20
@@ -57,7 +57,7 @@
 
 	/* Get the RSDP */
 
-	status = acpi_tb_find_rsdp (&table_info);
+	status = acpi_tb_find_rsdp (&table_info, ACPI_LOGICAL_ADDRESSING);
 	if (ACPI_FAILURE (status)) {
 		return (AE_NO_ACPI_TABLES);
 	}
@@ -94,15 +94,13 @@
 
 	for (offset = 0, mem_rover = start_address;
 		 offset < length;
-		 offset += RSDP_SCAN_STEP, mem_rover += RSDP_SCAN_STEP)
-	{
+		 offset += RSDP_SCAN_STEP, mem_rover += RSDP_SCAN_STEP) {
 
 		/* The signature and checksum must both be correct */
 
 		if (STRNCMP ((NATIVE_CHAR *) mem_rover,
 				RSDP_SIG, sizeof (RSDP_SIG)-1) == 0 &&
-			acpi_tb_checksum (mem_rover, RSDP_CHECKSUM_LENGTH) == 0)
-		{
+			acpi_tb_checksum (mem_rover, RSDP_CHECKSUM_LENGTH) == 0) {
 			/* If so, we have found the RSDP */
 
 			return (mem_rover);
@@ -119,9 +117,9 @@
  *
  * FUNCTION:    Acpi_tb_find_rsdp
  *
- * PARAMETERS:  *Buffer_ptr             - If == NULL, read data from buffer
- *                                        rather than searching memory
- *              *Table_info             - Where the table info is returned
+ * PARAMETERS:  *Table_info             - Where the table info is returned
+ *              Flags                   - Current memory mode (logical vs.
+ *                                        physical addressing)
  *
  * RETURN:      Status
  *
@@ -136,7 +134,8 @@
 
 ACPI_STATUS
 acpi_tb_find_rsdp (
-	ACPI_TABLE_DESC         *table_info)
+	ACPI_TABLE_DESC         *table_info,
+	u32                     flags)
 {
 	u8                      *table_ptr;
 	u8                      *mem_rover;
@@ -145,70 +144,231 @@
 
 
 	/*
-	 * Search memory for RSDP.  First map low physical memory.
+	 * Scan supports either 1) Logical addressing or 2) Physical addressing
 	 */
+	if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
+		/*
+		 * 1) Search EBDA (low memory) paragraphs
+		 */
+		status = acpi_os_map_memory (LO_RSDP_WINDOW_BASE, LO_RSDP_WINDOW_SIZE,
+				  (void **) &table_ptr);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
 
-	status = acpi_os_map_memory (LO_RSDP_WINDOW_BASE, LO_RSDP_WINDOW_SIZE,
-			  (void **)&table_ptr);
+		mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, LO_RSDP_WINDOW_SIZE);
+		acpi_os_unmap_memory (table_ptr, LO_RSDP_WINDOW_SIZE);
 
-	if (ACPI_FAILURE (status)) {
-		return (status);
+		if (mem_rover) {
+			/* Found it, return the physical address */
+
+			phys_addr = LO_RSDP_WINDOW_BASE;
+			phys_addr += (mem_rover - table_ptr);
+
+			table_info->physical_address = phys_addr;
+
+			return (AE_OK);
+		}
+
+		/*
+		 * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h
+		 */
+		status = acpi_os_map_memory (HI_RSDP_WINDOW_BASE, HI_RSDP_WINDOW_SIZE,
+				  (void **) &table_ptr);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+
+		mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, HI_RSDP_WINDOW_SIZE);
+		acpi_os_unmap_memory (table_ptr, HI_RSDP_WINDOW_SIZE);
+
+		if (mem_rover) {
+			/* Found it, return the physical address */
+
+			phys_addr = HI_RSDP_WINDOW_BASE;
+			phys_addr += (mem_rover - table_ptr);
+
+			table_info->physical_address = phys_addr;
+
+			return (AE_OK);
+		}
 	}
 
+
 	/*
-	 * 1) Search EBDA (low memory) paragraphs
+	 * Physical addressing
 	 */
+	else {
+		/*
+		 * 1) Search EBDA (low memory) paragraphs
+		 */
+		mem_rover = acpi_tb_scan_memory_for_rsdp ((u8 *) LO_RSDP_WINDOW_BASE,
+				  LO_RSDP_WINDOW_SIZE);
+		if (mem_rover) {
+			/* Found it, return the physical address */
 
-	mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, LO_RSDP_WINDOW_SIZE);
+			table_info->physical_address = (ACPI_TBLPTR) mem_rover;
+			return (AE_OK);
+		}
 
-	/* This mapping is no longer needed */
+		/*
+		 * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h
+		 */
+		mem_rover = acpi_tb_scan_memory_for_rsdp ((u8 *) HI_RSDP_WINDOW_BASE,
+				  HI_RSDP_WINDOW_SIZE);
+		if (mem_rover) {
+			/* Found it, return the physical address */
 
-	acpi_os_unmap_memory (table_ptr, LO_RSDP_WINDOW_SIZE);
+			table_info->physical_address = (ACPI_TBLPTR) mem_rover;
+			return (AE_OK);
+		}
+	}
 
-	if (mem_rover) {
-		/* Found it, return the physical address */
 
-		phys_addr = LO_RSDP_WINDOW_BASE;
-		phys_addr += (mem_rover - table_ptr);
+	/* RSDP signature was not found */
 
-		table_info->physical_address = phys_addr;
+	return (AE_NOT_FOUND);
+}
 
-		return (AE_OK);
-	}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_get_firmware_table
+ *
+ * PARAMETERS:  Signature       - Any ACPI table signature
+ *              Instance        - the non zero instance of the table, allows
+ *                                support for multiple tables of the same type
+ *              Flags           - 0: Physical/Virtual support
+ *              Ret_buffer      - pointer to a structure containing a buffer to
+ *                                receive the table
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to get an ACPI table.  The caller
+ *              supplies an Out_buffer large enough to contain the entire ACPI
+ *              table.  Upon completion
+ *              the Out_buffer->Length field will indicate the number of bytes
+ *              copied into the Out_buffer->Buf_ptr buffer. This table will be
+ *              a complete table including the header.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_get_firmware_table (
+	ACPI_STRING             signature,
+	u32                     instance,
+	u32                     flags,
+	ACPI_TABLE_HEADER       **table_pointer)
+{
+	ACPI_PHYSICAL_ADDRESS   physical_address;
+	ACPI_TABLE_DESC         table_info;
+	ACPI_TABLE_HEADER       *rsdt_ptr;
+	ACPI_TABLE_HEADER       *table_ptr;
+	ACPI_STATUS             status;
+	u32                     rsdt_size;
+	u32                     table_size;
+	u32                     table_count;
+	u32                     i;
+	u32                     j;
 
 
 	/*
-	 * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h
+	 * Ensure that at least the table manager is initialized.  We don't
+	 * require that the entire ACPI subsystem is up for this interface
 	 */
 
-	status = acpi_os_map_memory (HI_RSDP_WINDOW_BASE, HI_RSDP_WINDOW_SIZE,
-			  (void **)&table_ptr);
 
+	/*
+	 *  If we have a buffer, we must have a length too
+	 */
+	if ((instance == 0)                 ||
+		(!signature)                    ||
+		(!table_pointer)) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	/* Get the RSDP by scanning low memory */
+
+	status = acpi_tb_find_rsdp (&table_info, flags);
+	if (ACPI_FAILURE (status)) {
+		return (AE_NO_ACPI_TABLES);
+	}
+
+	acpi_gbl_RSDP = (RSDP_DESCRIPTOR *) table_info.pointer;
+
+
+	/* Get the RSDT and validate it */
+
+	physical_address = acpi_tb_get_rsdt_address ();
+	status = acpi_tb_get_table_pointer (physical_address, flags, &rsdt_size, &rsdt_ptr);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
 
-	mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, HI_RSDP_WINDOW_SIZE);
+	status = acpi_tb_validate_rsdt (rsdt_ptr);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
 
-	/* This mapping is no longer needed */
+	/* Get the number of table pointers within the RSDT */
 
-	acpi_os_unmap_memory (table_ptr, HI_RSDP_WINDOW_SIZE);
+	table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, rsdt_ptr);
 
-	if (mem_rover) {
-		/* Found it, return the physical address */
 
-		phys_addr = HI_RSDP_WINDOW_BASE;
-		phys_addr += (mem_rover - table_ptr);
+	/*
+	 * Search the RSDT/XSDT for the correct instance of the
+	 * requested table
+	 */
+	for (i = 0, j = 0; i < table_count; i++) {
+		/* Get the next table pointer */
+
+		if (acpi_gbl_RSDP->revision < 2) {
+			physical_address = ((RSDT_DESCRIPTOR *) rsdt_ptr)->table_offset_entry[i];
+		}
+		else {
+			physical_address = (ACPI_PHYSICAL_ADDRESS)
+				ACPI_GET_ADDRESS (((XSDT_DESCRIPTOR *) rsdt_ptr)->table_offset_entry[i]);
+		}
+
+		/* Get addressibility if necessary */
+
+		status = acpi_tb_get_table_pointer (physical_address, flags, &table_size, &table_ptr);
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+
+		/* Compare table signatures and table instance */
 
-		table_info->physical_address = phys_addr;
+		if (!STRNCMP ((char *) table_ptr, signature, STRLEN (signature))) {
+			/* An instance of the table was found */
 
-		return (AE_OK);
+			j++;
+			if (j >= instance) {
+				/* Found the correct instance */
+
+				*table_pointer = table_ptr;
+				goto cleanup;
+			}
+		}
+
+		/* Delete table mapping if using virtual addressing */
+
+		if (table_size) {
+			acpi_os_unmap_memory (table_ptr, table_size);
+		}
 	}
 
+	/* Did not find the table */
 
-	/* RSDP signature was not found */
+	status = AE_NOT_EXIST;
 
-	return (AE_NOT_FOUND);
+
+cleanup:
+	if (rsdt_size) {
+		acpi_os_unmap_memory (rsdt_ptr, rsdt_size);
+	}
+	return (status);
 }
 
 
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/utilities/Makefile linux/drivers/acpi/utilities/Makefile
--- v2.4.5/linux/drivers/acpi/utilities/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/utilities/Makefile	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,12 @@
+#
+# Makefile for all Linux ACPI interpreter subdirectories
+# EXCEPT for the ospm directory
+#
+
+O_TARGET := $(notdir $(CURDIR)).o
+
+obj-$(CONFIG_ACPI) := $(patsubst %.c,%.o,$(wildcard *.c))
+
+EXTRA_CFLAGS += $(ACPI_CFLAGS)
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/utilities/utalloc.c linux/drivers/acpi/utilities/utalloc.c
--- v2.4.5/linux/drivers/acpi/utilities/utalloc.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/utilities/utalloc.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,169 @@
+/******************************************************************************
+ *
+ * Module Name: utalloc - local memory allocation routines
+ *              $Revision: 90 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "acinterp.h"
+#include "acnamesp.h"
+#include "acglobal.h"
+
+#define _COMPONENT          ACPI_UTILITIES
+	 MODULE_NAME         ("utalloc")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    _Ut_allocate
+ *
+ * PARAMETERS:  Size                - Size of the allocation
+ *              Component           - Component type of caller
+ *              Module              - Source file name of caller
+ *              Line                - Line number of caller
+ *
+ * RETURN:      Address of the allocated memory on success, NULL on failure.
+ *
+ * DESCRIPTION: The subsystem's equivalent of malloc.
+ *
+ ******************************************************************************/
+
+void *
+_ut_allocate (
+	u32                     size,
+	u32                     component,
+	NATIVE_CHAR             *module,
+	u32                     line)
+{
+	void                    *address = NULL;
+
+
+	/* Check for an inadvertent size of zero bytes */
+
+	if (!size) {
+		_REPORT_ERROR (module, line, component,
+				("Ut_allocate: Attempt to allocate zero bytes\n"));
+		size = 1;
+	}
+
+	address = acpi_os_allocate (size);
+	if (!address) {
+		/* Report allocation error */
+
+		_REPORT_ERROR (module, line, component,
+				("Ut_allocate: Could not allocate size %X\n", size));
+
+		return (NULL);
+	}
+
+
+	return (address);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    _Ut_callocate
+ *
+ * PARAMETERS:  Size                - Size of the allocation
+ *              Component           - Component type of caller
+ *              Module              - Source file name of caller
+ *              Line                - Line number of caller
+ *
+ * RETURN:      Address of the allocated memory on success, NULL on failure.
+ *
+ * DESCRIPTION: Subsystem equivalent of calloc.
+ *
+ ******************************************************************************/
+
+void *
+_ut_callocate (
+	u32                     size,
+	u32                     component,
+	NATIVE_CHAR             *module,
+	u32                     line)
+{
+	void                    *address = NULL;
+
+
+	/* Check for an inadvertent size of zero bytes */
+
+	if (!size) {
+		_REPORT_ERROR (module, line, component,
+				("Ut_callocate: Attempt to allocate zero bytes\n"));
+		return (NULL);
+	}
+
+
+	address = acpi_os_callocate (size);
+	if (!address) {
+		/* Report allocation error */
+
+		_REPORT_ERROR (module, line, component,
+				("Ut_callocate: Could not allocate size %X\n", size));
+		return (NULL);
+	}
+
+
+	return (address);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    _Ut_free
+ *
+ * PARAMETERS:  Address             - Address of the memory to deallocate
+ *              Component           - Component type of caller
+ *              Module              - Source file name of caller
+ *              Line                - Line number of caller
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Frees the memory at Address
+ *
+ ******************************************************************************/
+
+void
+_ut_free (
+	void                    *address,
+	u32                     component,
+	NATIVE_CHAR             *module,
+	u32                     line)
+{
+
+	if (NULL == address) {
+		_REPORT_ERROR (module, line, component,
+			("_Ut_free: Trying to delete a NULL address\n"));
+
+		return;
+	}
+
+
+	acpi_os_free (address);
+
+	return;
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/utilities/utcopy.c linux/drivers/acpi/utilities/utcopy.c
--- v2.4.5/linux/drivers/acpi/utilities/utcopy.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/utilities/utcopy.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,707 @@
+/******************************************************************************
+ *
+ * Module Name: utcopy - Internal to external object translation utilities
+ *              $Revision: 74 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acinterp.h"
+#include "acnamesp.h"
+#include "amlcode.h"
+
+
+#define _COMPONENT          ACPI_UTILITIES
+	 MODULE_NAME         ("utcopy")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_copy_isimple_to_esimple
+ *
+ * PARAMETERS:  *Internal_object    - Pointer to the object we are examining
+ *              *Buffer             - Where the object is returned
+ *              *Space_used         - Where the data length is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to place a simple object in a user
+ *              buffer.
+ *
+ *              The buffer is assumed to have sufficient space for the object.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+acpi_ut_copy_isimple_to_esimple (
+	ACPI_OPERAND_OBJECT     *internal_object,
+	ACPI_OBJECT             *external_object,
+	u8                      *data_space,
+	u32                     *buffer_space_used)
+{
+	u32                     length = 0;
+	ACPI_STATUS             status = AE_OK;
+
+
+	/*
+	 * Check for NULL object case (could be an uninitialized
+	 * package element
+	 */
+
+	if (!internal_object) {
+		*buffer_space_used = 0;
+		return (AE_OK);
+	}
+
+	/* Always clear the external object */
+
+	MEMSET (external_object, 0, sizeof (ACPI_OBJECT));
+
+	/*
+	 * In general, the external object will be the same type as
+	 * the internal object
+	 */
+
+	external_object->type = internal_object->common.type;
+
+	/* However, only a limited number of external types are supported */
+
+	switch (internal_object->common.type) {
+
+	case ACPI_TYPE_STRING:
+
+		length = internal_object->string.length + 1;
+		external_object->string.length = internal_object->string.length;
+		external_object->string.pointer = (NATIVE_CHAR *) data_space;
+		MEMCPY ((void *) data_space, (void *) internal_object->string.pointer, length);
+		break;
+
+
+	case ACPI_TYPE_BUFFER:
+
+		length = internal_object->buffer.length;
+		external_object->buffer.length = internal_object->buffer.length;
+		external_object->buffer.pointer = data_space;
+		MEMCPY ((void *) data_space, (void *) internal_object->buffer.pointer, length);
+		break;
+
+
+	case ACPI_TYPE_INTEGER:
+
+		external_object->integer.value= internal_object->integer.value;
+		break;
+
+
+	case INTERNAL_TYPE_REFERENCE:
+
+		/*
+		 * This is an object reference.  Attempt to dereference it.
+		 */
+
+		switch (internal_object->reference.opcode) {
+		case AML_ZERO_OP:
+			external_object->type = ACPI_TYPE_INTEGER;
+			external_object->integer.value = 0;
+			break;
+
+		case AML_ONE_OP:
+			external_object->type = ACPI_TYPE_INTEGER;
+			external_object->integer.value = 1;
+			break;
+
+		case AML_ONES_OP:
+			external_object->type = ACPI_TYPE_INTEGER;
+			external_object->integer.value = ACPI_INTEGER_MAX;
+			break;
+
+		case AML_INT_NAMEPATH_OP:
+			/*
+			 * This is a named reference, get the string.  We already know that
+			 * we have room for it, use max length
+			 */
+			length = MAX_STRING_LENGTH;
+			external_object->type = ACPI_TYPE_STRING;
+			external_object->string.pointer = (NATIVE_CHAR *) data_space;
+			status = acpi_ns_handle_to_pathname ((ACPI_HANDLE *) internal_object->reference.node,
+					 &length, (char *) data_space);
+
+			/* Converted (external) string length is returned from above */
+
+			external_object->string.length = length;
+			break;
+
+		default:
+			/*
+			 * Use the object type of "Any" to indicate a reference
+			 * to object containing a handle to an ACPI named object.
+			 */
+			external_object->type = ACPI_TYPE_ANY;
+			external_object->reference.handle = internal_object->reference.node;
+			break;
+		}
+		break;
+
+
+	case ACPI_TYPE_PROCESSOR:
+
+		external_object->processor.proc_id = internal_object->processor.proc_id;
+		external_object->processor.pblk_address = internal_object->processor.address;
+		external_object->processor.pblk_length = internal_object->processor.length;
+		break;
+
+
+	case ACPI_TYPE_POWER:
+
+		external_object->power_resource.system_level =
+				   internal_object->power_resource.system_level;
+
+		external_object->power_resource.resource_order =
+				   internal_object->power_resource.resource_order;
+		break;
+
+
+	default:
+		/*
+		 * There is no corresponding external object type
+		 */
+		return (AE_SUPPORT);
+		break;
+	}
+
+
+	*buffer_space_used = (u32) ROUND_UP_TO_NATIVE_WORD (length);
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_copy_ielement_to_eelement
+ *
+ * PARAMETERS:  ACPI_PKG_CALLBACK
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Copy one package element to another package element
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_copy_ielement_to_eelement (
+	u8                      object_type,
+	ACPI_OPERAND_OBJECT     *source_object,
+	ACPI_GENERIC_STATE      *state,
+	void                    *context)
+{
+	ACPI_STATUS             status = AE_OK;
+	ACPI_PKG_INFO           *info = (ACPI_PKG_INFO *) context;
+	u32                     object_space;
+	u32                     this_index;
+	ACPI_OBJECT             *target_object;
+
+
+	this_index      = state->pkg.index;
+	target_object   = (ACPI_OBJECT *)
+			   &((ACPI_OBJECT *)(state->pkg.dest_object))->package.elements[this_index];
+
+
+	switch (object_type) {
+	case ACPI_COPY_TYPE_SIMPLE:
+
+		/*
+		 * This is a simple or null object -- get the size
+		 */
+
+		status = acpi_ut_copy_isimple_to_esimple (source_object,
+				  target_object, info->free_space, &object_space);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+
+		break;
+
+	case ACPI_COPY_TYPE_PACKAGE:
+
+		/*
+		 * Build the package object
+		 */
+		target_object->type             = ACPI_TYPE_PACKAGE;
+		target_object->package.count    = source_object->package.count;
+		target_object->package.elements = (ACPI_OBJECT *) info->free_space;
+
+		/*
+		 * Pass the new package object back to the package walk routine
+		 */
+		state->pkg.this_target_obj = target_object;
+
+		/*
+		 * Save space for the array of objects (Package elements)
+		 * update the buffer length counter
+		 */
+		object_space = (u32) ROUND_UP_TO_NATIVE_WORD (
+				   target_object->package.count * sizeof (ACPI_OBJECT));
+		break;
+
+	default:
+		return (AE_BAD_PARAMETER);
+	}
+
+
+	info->free_space  += object_space;
+	info->length      += object_space;
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_copy_ipackage_to_epackage
+ *
+ * PARAMETERS:  *Internal_object    - Pointer to the object we are returning
+ *              *Buffer             - Where the object is returned
+ *              *Space_used         - Where the object length is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to place a package object in a user
+ *              buffer.  A package object by definition contains other objects.
+ *
+ *              The buffer is assumed to have sufficient space for the object.
+ *              The caller must have verified the buffer length needed using the
+ *              Acpi_ut_get_object_size function before calling this function.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+acpi_ut_copy_ipackage_to_epackage (
+	ACPI_OPERAND_OBJECT     *internal_object,
+	u8                      *buffer,
+	u32                     *space_used)
+{
+	ACPI_OBJECT             *external_object;
+	ACPI_STATUS             status;
+	ACPI_PKG_INFO           info;
+
+
+	/*
+	 * First package at head of the buffer
+	 */
+	external_object = (ACPI_OBJECT *) buffer;
+
+	/*
+	 * Free space begins right after the first package
+	 */
+	info.length      = 0;
+	info.object_space = 0;
+	info.num_packages = 1;
+	info.free_space  = buffer + ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
+
+
+	external_object->type              = internal_object->common.type;
+	external_object->package.count     = internal_object->package.count;
+	external_object->package.elements  = (ACPI_OBJECT *) info.free_space;
+
+
+	/*
+	 * Build an array of ACPI_OBJECTS in the buffer
+	 * and move the free space past it
+	 */
+
+	info.free_space += external_object->package.count *
+			  ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
+
+
+	status = acpi_ut_walk_package_tree (internal_object, external_object,
+			 acpi_ut_copy_ielement_to_eelement, &info);
+
+	*space_used = info.length;
+
+	return (status);
+
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_copy_iobject_to_eobject
+ *
+ * PARAMETERS:  *Internal_object    - The internal object to be converted
+ *              *Buffer_ptr         - Where the object is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to build an API object to be returned to
+ *              the caller.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_copy_iobject_to_eobject (
+	ACPI_OPERAND_OBJECT     *internal_object,
+	ACPI_BUFFER             *ret_buffer)
+{
+	ACPI_STATUS             status;
+
+
+	if (IS_THIS_OBJECT_TYPE (internal_object, ACPI_TYPE_PACKAGE)) {
+		/*
+		 * Package object:  Copy all subobjects (including
+		 * nested packages)
+		 */
+		status = acpi_ut_copy_ipackage_to_epackage (internal_object,
+				  ret_buffer->pointer, &ret_buffer->length);
+	}
+
+	else {
+		/*
+		 * Build a simple object (no nested objects)
+		 */
+		status = acpi_ut_copy_isimple_to_esimple (internal_object,
+				  (ACPI_OBJECT *) ret_buffer->pointer,
+				  ((u8 *) ret_buffer->pointer +
+				  ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT))),
+				  &ret_buffer->length);
+		/*
+		 * build simple does not include the object size in the length
+		 * so we add it in here
+		 */
+		ret_buffer->length += sizeof (ACPI_OBJECT);
+	}
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_copy_esimple_to_isimple
+ *
+ * PARAMETERS:  *External_object   - The external object to be converted
+ *              *Internal_object   - Where the internal object is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function copies an external object to an internal one.
+ *              NOTE: Pointers can be copied, we don't need to copy data.
+ *              (The pointers have to be valid in our address space no matter
+ *              what we do with them!)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_copy_esimple_to_isimple (
+	ACPI_OBJECT             *external_object,
+	ACPI_OPERAND_OBJECT     *internal_object)
+{
+
+
+	internal_object->common.type = (u8) external_object->type;
+
+	switch (external_object->type) {
+
+	case ACPI_TYPE_STRING:
+
+		internal_object->string.length = external_object->string.length;
+		internal_object->string.pointer = external_object->string.pointer;
+		break;
+
+
+	case ACPI_TYPE_BUFFER:
+
+		internal_object->buffer.length = external_object->buffer.length;
+		internal_object->buffer.pointer = external_object->buffer.pointer;
+		break;
+
+
+	case ACPI_TYPE_INTEGER:
+		/*
+		 * Number is included in the object itself
+		 */
+		internal_object->integer.value  = external_object->integer.value;
+		break;
+
+
+	default:
+		return (AE_CTRL_RETURN_VALUE);
+		break;
+	}
+
+
+	return (AE_OK);
+}
+
+
+#ifdef ACPI_FUTURE_IMPLEMENTATION
+
+/* Code to convert packages that are parameters to control methods */
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_copy_epackage_to_ipackage
+ *
+ * PARAMETERS:  *Internal_object   - Pointer to the object we are returning
+ *              *Buffer         - Where the object is returned
+ *              *Space_used     - Where the length of the object is returned
+ *
+ * RETURN:      Status          - the status of the call
+ *
+ * DESCRIPTION: This function is called to place a package object in a user
+ *              buffer.  A package object by definition contains other objects.
+ *
+ *              The buffer is assumed to have sufficient space for the object.
+ *              The caller must have verified the buffer length needed using the
+ *              Acpi_ut_get_object_size function before calling this function.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+acpi_ut_copy_epackage_to_ipackage (
+	ACPI_OPERAND_OBJECT     *internal_object,
+	u8                      *buffer,
+	u32                     *space_used)
+{
+	u8                      *free_space;
+	ACPI_OBJECT             *external_object;
+	u32                     length = 0;
+	u32                     this_index;
+	u32                     object_space = 0;
+	ACPI_OPERAND_OBJECT     *this_internal_obj;
+	ACPI_OBJECT             *this_external_obj;
+
+
+	/*
+	 * First package at head of the buffer
+	 */
+	external_object = (ACPI_OBJECT *)buffer;
+
+	/*
+	 * Free space begins right after the first package
+	 */
+	free_space = buffer + sizeof(ACPI_OBJECT);
+
+
+	external_object->type              = internal_object->common.type;
+	external_object->package.count     = internal_object->package.count;
+	external_object->package.elements  = (ACPI_OBJECT *)free_space;
+
+
+	/*
+	 * Build an array of ACPI_OBJECTS in the buffer
+	 * and move the free space past it
+	 */
+
+	free_space += external_object->package.count * sizeof(ACPI_OBJECT);
+
+
+	/* Call Walk_package */
+
+}
+
+#endif /* Future implementation */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_copy_eobject_to_iobject
+ *
+ * PARAMETERS:  *Internal_object   - The external object to be converted
+ *              *Buffer_ptr     - Where the internal object is returned
+ *
+ * RETURN:      Status          - the status of the call
+ *
+ * DESCRIPTION: Converts an external object to an internal object.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_copy_eobject_to_iobject (
+	ACPI_OBJECT             *external_object,
+	ACPI_OPERAND_OBJECT     *internal_object)
+{
+	ACPI_STATUS             status;
+
+
+	if (external_object->type == ACPI_TYPE_PACKAGE) {
+		/*
+		 * Package objects contain other objects (which can be objects)
+		 * buildpackage does it all
+		 *
+		 * TBD: Package conversion must be completed and tested
+		 * NOTE: this code converts packages as input parameters to
+		 * control methods only.  This is a very, very rare case.
+		 */
+/*
+		Status = Acpi_ut_copy_epackage_to_ipackage(Internal_object,
+				 Ret_buffer->Pointer,
+				 &Ret_buffer->Length);
+*/
+		return (AE_NOT_IMPLEMENTED);
+	}
+
+	else {
+		/*
+		 * Build a simple object (no nested objects)
+		 */
+		status = acpi_ut_copy_esimple_to_isimple (external_object, internal_object);
+		/*
+		 * build simple does not include the object size in the length
+		 * so we add it in here
+		 */
+	}
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_copy_ielement_to_ielement
+ *
+ * PARAMETERS:  ACPI_PKG_CALLBACK
+ *
+ * RETURN:      Status          - the status of the call
+ *
+ * DESCRIPTION: Copy one package element to another package element
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_copy_ielement_to_ielement (
+	u8                      object_type,
+	ACPI_OPERAND_OBJECT     *source_object,
+	ACPI_GENERIC_STATE      *state,
+	void                    *context)
+{
+	ACPI_STATUS             status = AE_OK;
+	u32                     this_index;
+	ACPI_OPERAND_OBJECT     **this_target_ptr;
+	ACPI_OPERAND_OBJECT     *target_object;
+
+
+	this_index    = state->pkg.index;
+	this_target_ptr = (ACPI_OPERAND_OBJECT **)
+			   &state->pkg.dest_object->package.elements[this_index];
+
+	switch (object_type) {
+	case 0:
+
+		/*
+		 * This is a simple object, just copy it
+		 */
+		target_object = acpi_ut_create_internal_object (source_object->common.type);
+		if (!target_object) {
+			return (AE_NO_MEMORY);
+		}
+
+		status = acpi_ex_store_object_to_object (source_object, target_object,
+				  (ACPI_WALK_STATE *) context);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+
+		*this_target_ptr = target_object;
+		break;
+
+
+	case 1:
+		/*
+		 * This object is a package - go down another nesting level
+		 * Create and build the package object
+		 */
+		target_object = acpi_ut_create_internal_object (ACPI_TYPE_PACKAGE);
+		if (!target_object) {
+			/* TBD: must delete package created up to this point */
+
+			return (AE_NO_MEMORY);
+		}
+
+		target_object->package.count = source_object->package.count;
+
+		/*
+		 * Pass the new package object back to the package walk routine
+		 */
+		state->pkg.this_target_obj = target_object;
+
+		/*
+		 * Store the object pointer in the parent package object
+		 */
+		*this_target_ptr = target_object;
+		break;
+
+	default:
+		return (AE_BAD_PARAMETER);
+	}
+
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_copy_ipackage_to_ipackage
+ *
+ * PARAMETERS:  *Source_obj     - Pointer to the source package object
+ *              *Dest_obj       - Where the internal object is returned
+ *
+ * RETURN:      Status          - the status of the call
+ *
+ * DESCRIPTION: This function is called to copy an internal package object
+ *              into another internal package object.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_copy_ipackage_to_ipackage (
+	ACPI_OPERAND_OBJECT     *source_obj,
+	ACPI_OPERAND_OBJECT     *dest_obj,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_STATUS             status = AE_OK;
+
+
+	dest_obj->common.type   = source_obj->common.type;
+	dest_obj->package.count = source_obj->package.count;
+
+
+	/*
+	 * Create the object array and walk the source package tree
+	 */
+
+	dest_obj->package.elements = acpi_ut_callocate ((source_obj->package.count + 1) *
+			 sizeof (void *));
+	dest_obj->package.next_element = dest_obj->package.elements;
+
+	if (!dest_obj->package.elements) {
+		REPORT_ERROR (
+			("Aml_build_copy_internal_package_object: Package allocation failure\n"));
+		return (AE_NO_MEMORY);
+	}
+
+
+	status = acpi_ut_walk_package_tree (source_obj, dest_obj,
+			 acpi_ut_copy_ielement_to_ielement, walk_state);
+
+	return (status);
+}
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/utilities/utdebug.c linux/drivers/acpi/utilities/utdebug.c
--- v2.4.5/linux/drivers/acpi/utilities/utdebug.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/utilities/utdebug.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,594 @@
+/******************************************************************************
+ *
+ * Module Name: utdebug - Debug print routines
+ *              $Revision: 72 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+
+#define _COMPONENT          ACPI_UTILITIES
+	 MODULE_NAME         ("utdebug")
+
+
+u32             prev_thread_id = 0xFFFFFFFF;
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Get/Set debug level
+ *
+ * DESCRIPTION: Get or set value of the debug flag
+ *
+ *              These are used to allow user's to get/set the debug level
+ *
+ ****************************************************************************/
+
+
+u32
+get_debug_level (void)
+{
+
+	return (acpi_dbg_level);
+}
+
+void
+set_debug_level (
+	u32                     new_debug_level)
+{
+
+	acpi_dbg_level = new_debug_level;
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Function_trace
+ *
+ * PARAMETERS:  Module_name         - Caller's module name (for error output)
+ *              Line_number         - Caller's line number (for error output)
+ *              Component_id        - Caller's component ID (for error output)
+ *              Function_name       - Name of Caller's function
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Function entry trace.  Prints only if TRACE_FUNCTIONS bit is
+ *              set in Debug_level
+ *
+ ****************************************************************************/
+
+void
+function_trace (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	NATIVE_CHAR             *function_name)
+{
+
+	acpi_gbl_nesting_level++;
+
+	debug_print (module_name, line_number, component_id,
+			 TRACE_FUNCTIONS,
+			 " %2.2ld Entered Function: %s\n",
+			 acpi_gbl_nesting_level, function_name);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Function_trace_ptr
+ *
+ * PARAMETERS:  Module_name         - Caller's module name (for error output)
+ *              Line_number         - Caller's line number (for error output)
+ *              Component_id        - Caller's component ID (for error output)
+ *              Function_name       - Name of Caller's function
+ *              Pointer             - Pointer to display
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Function entry trace.  Prints only if TRACE_FUNCTIONS bit is
+ *              set in Debug_level
+ *
+ ****************************************************************************/
+
+void
+function_trace_ptr (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	NATIVE_CHAR             *function_name,
+	void                    *pointer)
+{
+
+	acpi_gbl_nesting_level++;
+	debug_print (module_name, line_number, component_id, TRACE_FUNCTIONS,
+			 " %2.2ld Entered Function: %s, %p\n",
+			 acpi_gbl_nesting_level, function_name, pointer);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Function_trace_str
+ *
+ * PARAMETERS:  Module_name         - Caller's module name (for error output)
+ *              Line_number         - Caller's line number (for error output)
+ *              Component_id        - Caller's component ID (for error output)
+ *              Function_name       - Name of Caller's function
+ *              String              - Additional string to display
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Function entry trace.  Prints only if TRACE_FUNCTIONS bit is
+ *              set in Debug_level
+ *
+ ****************************************************************************/
+
+void
+function_trace_str (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	NATIVE_CHAR             *function_name,
+	NATIVE_CHAR             *string)
+{
+
+	acpi_gbl_nesting_level++;
+	debug_print (module_name, line_number, component_id, TRACE_FUNCTIONS,
+			 " %2.2ld Entered Function: %s, %s\n",
+			 acpi_gbl_nesting_level, function_name, string);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Function_trace_u32
+ *
+ * PARAMETERS:  Module_name         - Caller's module name (for error output)
+ *              Line_number         - Caller's line number (for error output)
+ *              Component_id        - Caller's component ID (for error output)
+ *              Function_name       - Name of Caller's function
+ *              Integer             - Integer to display
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Function entry trace.  Prints only if TRACE_FUNCTIONS bit is
+ *              set in Debug_level
+ *
+ ****************************************************************************/
+
+void
+function_trace_u32 (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	NATIVE_CHAR             *function_name,
+	u32                     integer)
+{
+
+	acpi_gbl_nesting_level++;
+	debug_print (module_name, line_number, component_id, TRACE_FUNCTIONS,
+			 " %2.2ld Entered Function: %s, %lX\n",
+			 acpi_gbl_nesting_level, function_name, integer);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Function_exit
+ *
+ * PARAMETERS:  Module_name         - Caller's module name (for error output)
+ *              Line_number         - Caller's line number (for error output)
+ *              Component_id        - Caller's component ID (for error output)
+ *              Function_name       - Name of Caller's function
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Function exit trace.  Prints only if TRACE_FUNCTIONS bit is
+ *              set in Debug_level
+ *
+ ****************************************************************************/
+
+void
+function_exit (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	NATIVE_CHAR             *function_name)
+{
+
+	debug_print (module_name, line_number, component_id, TRACE_FUNCTIONS,
+			 " %2.2ld Exiting Function: %s\n",
+			 acpi_gbl_nesting_level, function_name);
+
+	acpi_gbl_nesting_level--;
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Function_status_exit
+ *
+ * PARAMETERS:  Module_name         - Caller's module name (for error output)
+ *              Line_number         - Caller's line number (for error output)
+ *              Component_id        - Caller's component ID (for error output)
+ *              Function_name       - Name of Caller's function
+ *              Status              - Exit status code
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Function exit trace.  Prints only if TRACE_FUNCTIONS bit is
+ *              set in Debug_level. Prints exit status also.
+ *
+ ****************************************************************************/
+
+void
+function_status_exit (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	NATIVE_CHAR             *function_name,
+	ACPI_STATUS             status)
+{
+
+	debug_print (module_name, line_number, component_id,
+		TRACE_FUNCTIONS,
+		" %2.2ld Exiting Function: %s, %s\n",
+		acpi_gbl_nesting_level,
+		function_name,
+		acpi_ut_format_exception (status));
+
+	acpi_gbl_nesting_level--;
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Function_value_exit
+ *
+ * PARAMETERS:  Module_name         - Caller's module name (for error output)
+ *              Line_number         - Caller's line number (for error output)
+ *              Component_id        - Caller's component ID (for error output)
+ *              Function_name       - Name of Caller's function
+ *              Value               - Value to be printed with exit msg
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Function exit trace.  Prints only if TRACE_FUNCTIONS bit is
+ *              set in Debug_level. Prints exit value also.
+ *
+ ****************************************************************************/
+
+void
+function_value_exit (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	NATIVE_CHAR             *function_name,
+	ACPI_INTEGER            value)
+{
+
+	debug_print (module_name, line_number, component_id, TRACE_FUNCTIONS,
+			 " %2.2ld Exiting Function: %s, %X\n",
+			 acpi_gbl_nesting_level, function_name, value);
+
+	acpi_gbl_nesting_level--;
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Function_ptr_exit
+ *
+ * PARAMETERS:  Module_name         - Caller's module name (for error output)
+ *              Line_number         - Caller's line number (for error output)
+ *              Component_id        - Caller's component ID (for error output)
+ *              Function_name       - Name of Caller's function
+ *              Value               - Value to be printed with exit msg
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Function exit trace.  Prints only if TRACE_FUNCTIONS bit is
+ *              set in Debug_level. Prints exit value also.
+ *
+ ****************************************************************************/
+
+void
+function_ptr_exit (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	NATIVE_CHAR             *function_name,
+	u8                      *ptr)
+{
+
+	debug_print (module_name, line_number, component_id, TRACE_FUNCTIONS,
+			 " %2.2ld Exiting Function: %s, %p\n",
+			 acpi_gbl_nesting_level, function_name, ptr);
+
+	acpi_gbl_nesting_level--;
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Debug_print
+ *
+ * PARAMETERS:  Module_name         - Caller's module name (for error output)
+ *              Line_number         - Caller's line number (for error output)
+ *              Component_id        - Caller's component ID (for error output)
+ *              Print_level         - Requested debug print level
+ *              Format              - Printf format field
+ *              ...                 - Optional printf arguments
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print error message with prefix consisting of the module name,
+ *              line number, and component ID.
+ *
+ ****************************************************************************/
+
+void
+debug_print (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	u32                     print_level,
+	NATIVE_CHAR             *format,
+	...)
+{
+	va_list                 args;
+	u32                     thread_id;
+
+
+	thread_id = acpi_os_get_thread_id ();
+
+
+	/* Both the level and the component must be enabled */
+
+	if ((print_level & acpi_dbg_level) &&
+		(component_id & acpi_dbg_layer)) {
+		va_start (args, format);
+
+		if (thread_id != prev_thread_id) {
+			if (TRACE_THREADS & acpi_dbg_level) {
+				acpi_os_printf ("\n**** Context Switch from TID %X to TID %X ****\n\n",
+					prev_thread_id, thread_id);
+			}
+
+			prev_thread_id = thread_id;
+		}
+
+		if (TRACE_THREADS & acpi_dbg_level) {
+			acpi_os_printf ("%8s-%04d[%04X]: ", module_name, line_number, thread_id);
+		}
+		else {
+			acpi_os_printf ("%8s-%04d: ", module_name, line_number);
+		}
+
+		acpi_os_vprintf (format, args);
+	}
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Debug_print_prefix
+ *
+ * PARAMETERS:  Module_name         - Caller's module name (for error output)
+ *              Line_number         - Caller's line number (for error output)
+ *              Component_id        - Caller's component ID (for error output)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print the prefix part of an error message, consisting of the
+ *              module name, and line number
+ *
+ ****************************************************************************/
+
+void
+debug_print_prefix (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number)
+{
+	u32                     thread_id;
+
+
+	thread_id = acpi_os_get_thread_id ();
+
+	if (thread_id != prev_thread_id) {
+		if (TRACE_THREADS & acpi_dbg_level) {
+			acpi_os_printf ("\n**** Context Switch from TID %X to TID %X ****\n\n",
+				prev_thread_id, thread_id);
+		}
+
+		prev_thread_id = thread_id;
+	}
+
+	if (TRACE_THREADS & acpi_dbg_level) {
+		acpi_os_printf ("%8s-%04d[%04X]: ", module_name, line_number, thread_id);
+	}
+	else {
+		acpi_os_printf ("%8s-%04d: ", module_name, line_number);
+	}
+
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Debug_print_raw
+ *
+ * PARAMETERS:  Format              - Printf format field
+ *              ...                 - Optional printf arguments
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print error message -- without module/line indentifiers
+ *
+ ****************************************************************************/
+
+void
+debug_print_raw (
+	NATIVE_CHAR             *format,
+	...)
+{
+	va_list                 args;
+
+
+	va_start (args, format);
+
+	acpi_os_vprintf (format, args);
+
+	va_end (args);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_dump_buffer
+ *
+ * PARAMETERS:  Buffer              - Buffer to dump
+ *              Count               - Amount to dump, in bytes
+ *              Component_iD        - Caller's component ID
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Generic dump buffer in both hex and ascii.
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_dump_buffer (
+	u8                      *buffer,
+	u32                     count,
+	u32                     display,
+	u32                     component_id)
+{
+	u32                     i = 0;
+	u32                     j;
+	u32                     temp32;
+	u8                      buf_char;
+
+
+	/* Only dump the buffer if tracing is enabled */
+
+	if (!((TRACE_TABLES & acpi_dbg_level) &&
+		(component_id & acpi_dbg_layer))) {
+		return;
+	}
+
+
+	/*
+	 * Nasty little dump buffer routine!
+	 */
+	while (i < count) {
+		/* Print current offset */
+
+		acpi_os_printf ("%05X  ", i);
+
+
+		/* Print 16 hex chars */
+
+		for (j = 0; j < 16;) {
+			if (i + j >= count) {
+				acpi_os_printf ("\n");
+				return;
+			}
+
+			/* Make sure that the s8 doesn't get sign-extended! */
+
+			switch (display) {
+			/* Default is BYTE display */
+
+			default:
+
+				acpi_os_printf ("%02X ",
+						*((u8 *) &buffer[i + j]));
+				j += 1;
+				break;
+
+
+			case DB_WORD_DISPLAY:
+
+				MOVE_UNALIGNED16_TO_32 (&temp32,
+						 &buffer[i + j]);
+				acpi_os_printf ("%04X ", temp32);
+				j += 2;
+				break;
+
+
+			case DB_DWORD_DISPLAY:
+
+				MOVE_UNALIGNED32_TO_32 (&temp32,
+						 &buffer[i + j]);
+				acpi_os_printf ("%08X ", temp32);
+				j += 4;
+				break;
+
+
+			case DB_QWORD_DISPLAY:
+
+				MOVE_UNALIGNED32_TO_32 (&temp32,
+						 &buffer[i + j]);
+				acpi_os_printf ("%08X", temp32);
+
+				MOVE_UNALIGNED32_TO_32 (&temp32,
+						 &buffer[i + j + 4]);
+				acpi_os_printf ("%08X ", temp32);
+				j += 8;
+				break;
+			}
+		}
+
+
+		/*
+		 * Print the ASCII equivalent characters
+		 * But watch out for the bad unprintable ones...
+		 */
+
+		for (j = 0; j < 16; j++) {
+			if (i + j >= count) {
+				acpi_os_printf ("\n");
+				return;
+			}
+
+			buf_char = buffer[i + j];
+			if ((buf_char > 0x1F && buf_char < 0x2E) ||
+				(buf_char > 0x2F && buf_char < 0x61) ||
+				(buf_char > 0x60 && buf_char < 0x7F)) {
+				acpi_os_printf ("%c", buf_char);
+			}
+			else {
+				acpi_os_printf (".");
+			}
+		}
+
+		/* Done with that line. */
+
+		acpi_os_printf ("\n");
+		i += 16;
+	}
+
+	return;
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/utilities/utdelete.c linux/drivers/acpi/utilities/utdelete.c
--- v2.4.5/linux/drivers/acpi/utilities/utdelete.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/utilities/utdelete.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,602 @@
+/*******************************************************************************
+ *
+ * Module Name: utdelete - object deletion and reference count utilities
+ *              $Revision: 71 $
+ *
+ ******************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acinterp.h"
+#include "acnamesp.h"
+#include "actables.h"
+#include "acparser.h"
+
+#define _COMPONENT          ACPI_UTILITIES
+	 MODULE_NAME         ("utdelete")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_delete_internal_obj
+ *
+ * PARAMETERS:  *Object        - Pointer to the list to be deleted
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Low level object deletion, after reference counts have been
+ *              updated (All reference counts, including sub-objects!)
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_delete_internal_obj (
+	ACPI_OPERAND_OBJECT     *object)
+{
+	void                    *obj_pointer = NULL;
+	ACPI_OPERAND_OBJECT     *handler_desc;
+
+
+	if (!object) {
+		return;
+	}
+
+	/*
+	 * Must delete or free any pointers within the object that are not
+	 * actual ACPI objects (for example, a raw buffer pointer).
+	 */
+
+	switch (object->common.type) {
+
+	case ACPI_TYPE_STRING:
+
+		/* Free the actual string buffer */
+
+		obj_pointer = object->string.pointer;
+		break;
+
+
+	case ACPI_TYPE_BUFFER:
+
+		/* Free the actual buffer */
+
+		obj_pointer = object->buffer.pointer;
+		break;
+
+
+	case ACPI_TYPE_PACKAGE:
+
+		/*
+		 * Elements of the package are not handled here, they are deleted
+		 * separately
+		 */
+
+		/* Free the (variable length) element pointer array */
+
+		obj_pointer = object->package.elements;
+		break;
+
+
+	case ACPI_TYPE_MUTEX:
+
+		acpi_ex_unlink_mutex (object);
+		acpi_os_delete_semaphore (object->mutex.semaphore);
+		break;
+
+
+	case ACPI_TYPE_EVENT:
+
+		acpi_os_delete_semaphore (object->event.semaphore);
+		object->event.semaphore = NULL;
+		break;
+
+
+	case ACPI_TYPE_METHOD:
+
+		/* Delete the method semaphore if it exists */
+
+		if (object->method.semaphore) {
+			acpi_os_delete_semaphore (object->method.semaphore);
+			object->method.semaphore = NULL;
+		}
+
+		break;
+
+
+	case ACPI_TYPE_REGION:
+
+		if (object->region.extra) {
+			/*
+			 * Free the Region_context if and only if the handler is one of the
+			 * default handlers -- and therefore, we created the context object
+			 * locally, it was not created by an external caller.
+			 */
+			handler_desc = object->region.addr_handler;
+			if ((handler_desc) &&
+				(handler_desc->addr_handler.hflags == ADDR_HANDLER_DEFAULT_INSTALLED)) {
+				obj_pointer = object->region.extra->extra.region_context;
+			}
+
+			/* Now we can free the Extra object */
+
+			acpi_ut_delete_object_desc (object->region.extra);
+		}
+		break;
+
+
+	case ACPI_TYPE_BUFFER_FIELD:
+
+		if (object->buffer_field.extra) {
+			acpi_ut_delete_object_desc (object->buffer_field.extra);
+		}
+		break;
+
+	default:
+		break;
+	}
+
+
+	/*
+	 * Delete any allocated memory found above
+	 */
+	if (obj_pointer) {
+		if (!acpi_tb_system_table_pointer (obj_pointer)) {
+			acpi_ut_free (obj_pointer);
+		}
+	}
+
+
+	/* Only delete the object if it was dynamically allocated */
+
+
+	if (!(object->common.flags & AOPOBJ_STATIC_ALLOCATION)) {
+		acpi_ut_delete_object_desc (object);
+	}
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_delete_internal_object_list
+ *
+ * PARAMETERS:  *Obj_list       - Pointer to the list to be deleted
+ *
+ * RETURN:      Status          - the status of the call
+ *
+ * DESCRIPTION: This function deletes an internal object list, including both
+ *              simple objects and package objects
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_delete_internal_object_list (
+	ACPI_OPERAND_OBJECT     **obj_list)
+{
+	ACPI_OPERAND_OBJECT     **internal_obj;
+
+
+	/* Walk the null-terminated internal list */
+
+	for (internal_obj = obj_list; *internal_obj; internal_obj++) {
+		/*
+		 * Check for a package
+		 * Simple objects are simply stored in the array and do not
+		 * need to be deleted separately.
+		 */
+
+		if (IS_THIS_OBJECT_TYPE ((*internal_obj), ACPI_TYPE_PACKAGE)) {
+			/* Delete the package */
+
+			/*
+			 * TBD: [Investigate] This might not be the right thing to do,
+			 * depending on how the internal package object was allocated!!!
+			 */
+			acpi_ut_delete_internal_obj (*internal_obj);
+		}
+
+	}
+
+	/* Free the combined parameter pointer list and object array */
+
+	acpi_ut_free (obj_list);
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_update_ref_count
+ *
+ * PARAMETERS:  *Object         - Object whose ref count is to be updated
+ *              Action          - What to do
+ *
+ * RETURN:      New ref count
+ *
+ * DESCRIPTION: Modify the ref count and return it.
+ *
+ ******************************************************************************/
+
+static void
+acpi_ut_update_ref_count (
+	ACPI_OPERAND_OBJECT     *object,
+	u32                     action)
+{
+	u16                     count;
+	u16                     new_count;
+
+
+	PROC_NAME ("Ut_update_ref_count");
+
+	if (!object) {
+		return;
+	}
+
+
+	count = object->common.reference_count;
+	new_count = count;
+
+	/*
+	 * Reference count action (increment, decrement, or force delete)
+	 */
+
+	switch (action) {
+
+	case REF_INCREMENT:
+
+		new_count++;
+		object->common.reference_count = new_count;
+
+		break;
+
+
+	case REF_DECREMENT:
+
+		if (count < 1) {
+			new_count = 0;
+		}
+
+		else {
+			new_count--;
+
+		}
+
+
+		object->common.reference_count = new_count;
+		if (new_count == 0) {
+			acpi_ut_delete_internal_obj (object);
+		}
+
+		break;
+
+
+	case REF_FORCE_DELETE:
+
+		new_count = 0;
+		object->common.reference_count = new_count;
+		acpi_ut_delete_internal_obj (object);
+		break;
+
+
+	default:
+
+		break;
+	}
+
+
+	/*
+	 * Sanity check the reference count, for debug purposes only.
+	 * (A deleted object will have a huge reference count)
+	 */
+
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_update_object_reference
+ *
+ * PARAMETERS:  *Object             - Increment ref count for this object
+ *                                    and all sub-objects
+ *              Action              - Either REF_INCREMENT or REF_DECREMENT or
+ *                                    REF_FORCE_DELETE
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Increment the object reference count
+ *
+ * Object references are incremented when:
+ * 1) An object is attached to a Node (namespace object)
+ * 2) An object is copied (all subobjects must be incremented)
+ *
+ * Object references are decremented when:
+ * 1) An object is detached from an Node
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_update_object_reference (
+	ACPI_OPERAND_OBJECT     *object,
+	u16                     action)
+{
+	ACPI_STATUS             status;
+	u32                     i;
+	ACPI_OPERAND_OBJECT     *next;
+	ACPI_OPERAND_OBJECT     *new;
+	ACPI_GENERIC_STATE       *state_list = NULL;
+	ACPI_GENERIC_STATE       *state;
+
+
+	/* Ignore a null object ptr */
+
+	if (!object) {
+		return (AE_OK);
+	}
+
+
+	/*
+	 * Make sure that this isn't a namespace handle or an AML pointer
+	 */
+
+	if (VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_NAMED)) {
+		return (AE_OK);
+	}
+
+	if (acpi_tb_system_table_pointer (object)) {
+		return (AE_OK);
+	}
+
+
+	state = acpi_ut_create_update_state (object, action);
+
+	while (state) {
+		object = state->update.object;
+		action = state->update.value;
+		acpi_ut_delete_generic_state (state);
+
+		/*
+		 * All sub-objects must have their reference count incremented also.
+		 * Different object types have different subobjects.
+		 */
+		switch (object->common.type) {
+
+		case ACPI_TYPE_DEVICE:
+
+			status = acpi_ut_create_update_state_and_push (object->device.addr_handler,
+					   action, &state_list);
+			if (ACPI_FAILURE (status)) {
+				return (status);
+			}
+
+			acpi_ut_update_ref_count (object->device.sys_handler, action);
+			acpi_ut_update_ref_count (object->device.drv_handler, action);
+			break;
+
+
+		case INTERNAL_TYPE_ADDRESS_HANDLER:
+
+			/* Must walk list of address handlers */
+
+			next = object->addr_handler.next;
+			while (next) {
+				new = next->addr_handler.next;
+				acpi_ut_update_ref_count (next, action);
+
+				next = new;
+			}
+			break;
+
+
+		case ACPI_TYPE_PACKAGE:
+
+			/*
+			 * We must update all the sub-objects of the package
+			 * (Each of whom may have their own sub-objects, etc.
+			 */
+			for (i = 0; i < object->package.count; i++) {
+				/*
+				 * Push each element onto the stack for later processing.
+				 * Note: There can be null elements within the package,
+				 * these are simply ignored
+				 */
+
+				status = acpi_ut_create_update_state_and_push (
+						 object->package.elements[i], action, &state_list);
+				if (ACPI_FAILURE (status)) {
+					return (status);
+				}
+			}
+			break;
+
+
+		case ACPI_TYPE_BUFFER_FIELD:
+
+			status = acpi_ut_create_update_state_and_push (
+					 object->buffer_field.buffer_obj, action, &state_list);
+
+			if (ACPI_FAILURE (status)) {
+				return (status);
+			}
+			break;
+
+
+		case INTERNAL_TYPE_REGION_FIELD:
+
+			status = acpi_ut_create_update_state_and_push (
+					 object->field.region_obj, action, &state_list);
+			if (ACPI_FAILURE (status)) {
+				return (status);
+			}
+		   break;
+
+
+		case INTERNAL_TYPE_BANK_FIELD:
+
+			status = acpi_ut_create_update_state_and_push (
+					 object->bank_field.bank_register_obj, action, &state_list);
+			if (ACPI_FAILURE (status)) {
+				return (status);
+			}
+
+			status = acpi_ut_create_update_state_and_push (
+					 object->bank_field.region_obj, action, &state_list);
+			if (ACPI_FAILURE (status)) {
+				return (status);
+			}
+			break;
+
+
+		case INTERNAL_TYPE_INDEX_FIELD:
+
+			status = acpi_ut_create_update_state_and_push (
+					 object->index_field.index_obj, action, &state_list);
+			if (ACPI_FAILURE (status)) {
+				return (status);
+			}
+
+			status = acpi_ut_create_update_state_and_push (
+					 object->index_field.data_obj, action, &state_list);
+			if (ACPI_FAILURE (status)) {
+				return (status);
+			}
+			break;
+
+
+		case ACPI_TYPE_REGION:
+
+	/* TBD: [Investigate]
+			Acpi_ut_update_ref_count (Object->Region.Addr_handler, Action);
+	*/
+/*
+			Status =
+				Acpi_ut_create_update_state_and_push (Object->Region.Addr_handler,
+						   Action, &State_list);
+			if (ACPI_FAILURE (Status))
+			{
+				return (Status);
+			}
+*/
+			break;
+
+
+		case INTERNAL_TYPE_REFERENCE:
+
+			break;
+		}
+
+
+		/*
+		 * Now we can update the count in the main object.  This can only
+		 * happen after we update the sub-objects in case this causes the
+		 * main object to be deleted.
+		 */
+
+		acpi_ut_update_ref_count (object, action);
+
+
+		/* Move on to the next object to be updated */
+
+		state = acpi_ut_pop_generic_state (&state_list);
+	}
+
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_add_reference
+ *
+ * PARAMETERS:  *Object        - Object whose reference count is to be
+ *                                  incremented
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Add one reference to an ACPI object
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_add_reference (
+	ACPI_OPERAND_OBJECT     *object)
+{
+
+
+	/*
+	 * Ensure that we have a valid object
+	 */
+
+	if (!acpi_ut_valid_internal_object (object)) {
+		return;
+	}
+
+	/*
+	 * We have a valid ACPI internal object, now increment the reference count
+	 */
+
+	acpi_ut_update_object_reference (object, REF_INCREMENT);
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_remove_reference
+ *
+ * PARAMETERS:  *Object        - Object whose ref count will be decremented
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Decrement the reference count of an ACPI internal object
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_remove_reference (
+	ACPI_OPERAND_OBJECT     *object)
+{
+
+
+	/*
+	 * Ensure that we have a valid object
+	 */
+
+	if (!acpi_ut_valid_internal_object (object)) {
+		return;
+	}
+
+	/*
+	 * Decrement the reference count, and only actually delete the object
+	 * if the reference count becomes 0.  (Must also decrement the ref count
+	 * of all subobjects!)
+	 */
+
+	acpi_ut_update_object_reference (object, REF_DECREMENT);
+	return;
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/utilities/uteval.c linux/drivers/acpi/utilities/uteval.c
--- v2.4.5/linux/drivers/acpi/utilities/uteval.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/utilities/uteval.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,308 @@
+/******************************************************************************
+ *
+ * Module Name: uteval - Object evaluation
+ *              $Revision: 27 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acnamesp.h"
+#include "acinterp.h"
+
+
+#define _COMPONENT          ACPI_UTILITIES
+	 MODULE_NAME         ("uteval")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_evaluate_numeric_object
+ *
+ * PARAMETERS:  *Object_name        - Object name to be evaluated
+ *              Device_node         - Node for the device
+ *              *Address            - Where the value is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: evaluates a numeric namespace object for a selected device
+ *              and stores results in *Address.
+ *
+ *              NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_evaluate_numeric_object (
+	NATIVE_CHAR             *object_name,
+	ACPI_NAMESPACE_NODE     *device_node,
+	ACPI_INTEGER            *address)
+{
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	ACPI_STATUS             status;
+
+
+	/* Execute the method */
+
+	status = acpi_ns_evaluate_relative (device_node, object_name, NULL, &obj_desc);
+	if (ACPI_FAILURE (status)) {
+
+		return (status);
+	}
+
+
+	/* Did we get a return object? */
+
+	if (!obj_desc) {
+		return (AE_TYPE);
+	}
+
+	/* Is the return object of the correct type? */
+
+	if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
+		status = AE_TYPE;
+	}
+	else {
+		/*
+		 * Since the structure is a union, setting any field will set all
+		 * of the variables in the union
+		 */
+		*address = obj_desc->integer.value;
+	}
+
+	/* On exit, we must delete the return object */
+
+	acpi_ut_remove_reference (obj_desc);
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_execute_HID
+ *
+ * PARAMETERS:  Device_node         - Node for the device
+ *              *Hid                - Where the HID is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Executes the _HID control method that returns the hardware
+ *              ID of the device.
+ *
+ *              NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_execute_HID (
+	ACPI_NAMESPACE_NODE     *device_node,
+	ACPI_DEVICE_ID          *hid)
+{
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	ACPI_STATUS             status;
+
+
+	/* Execute the method */
+
+	status = acpi_ns_evaluate_relative (device_node,
+			 METHOD_NAME__HID, NULL, &obj_desc);
+	if (ACPI_FAILURE (status)) {
+
+
+		return (status);
+	}
+
+	/* Did we get a return object? */
+
+	if (!obj_desc) {
+		return (AE_TYPE);
+	}
+
+	/*
+	 *  A _HID can return either a Number (32 bit compressed EISA ID) or
+	 *  a string
+	 */
+	if ((obj_desc->common.type != ACPI_TYPE_INTEGER) &&
+		(obj_desc->common.type != ACPI_TYPE_STRING)) {
+		status = AE_TYPE;
+	}
+
+	else {
+		if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
+			/* Convert the Numeric HID to string */
+
+			acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, hid->buffer);
+		}
+
+		else {
+			/* Copy the String HID from the returned object */
+
+			STRNCPY(hid->buffer, obj_desc->string.pointer, sizeof(hid->buffer));
+		}
+	}
+
+
+	/* On exit, we must delete the return object */
+
+	acpi_ut_remove_reference (obj_desc);
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_execute_UID
+ *
+ * PARAMETERS:  Device_node         - Node for the device
+ *              *Uid                - Where the UID is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Executes the _UID control method that returns the hardware
+ *              ID of the device.
+ *
+ *              NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_execute_UID (
+	ACPI_NAMESPACE_NODE     *device_node,
+	ACPI_DEVICE_ID          *uid)
+{
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	ACPI_STATUS             status;
+
+
+	PROC_NAME ("Ut_execute_UID");
+
+
+	/* Execute the method */
+
+	status = acpi_ns_evaluate_relative (device_node,
+			 METHOD_NAME__UID, NULL, &obj_desc);
+	if (ACPI_FAILURE (status)) {
+
+
+		return (status);
+	}
+
+	/* Did we get a return object? */
+
+	if (!obj_desc) {
+		return (AE_TYPE);
+	}
+
+	/*
+	 *  A _UID can return either a Number (32 bit compressed EISA ID) or
+	 *  a string
+	 */
+	if ((obj_desc->common.type != ACPI_TYPE_INTEGER) &&
+		(obj_desc->common.type != ACPI_TYPE_STRING)) {
+		status = AE_TYPE;
+	}
+
+	else {
+		if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
+			/* Convert the Numeric UID to string */
+
+			acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->buffer);
+		}
+
+		else {
+			/* Copy the String UID from the returned object */
+
+			STRNCPY(uid->buffer, obj_desc->string.pointer, sizeof(uid->buffer));
+		}
+	}
+
+
+	/* On exit, we must delete the return object */
+
+	acpi_ut_remove_reference (obj_desc);
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_execute_STA
+ *
+ * PARAMETERS:  Device_node         - Node for the device
+ *              *Flags              - Where the status flags are returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Executes _STA for selected device and stores results in
+ *              *Flags.
+ *
+ *              NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_execute_STA (
+	ACPI_NAMESPACE_NODE     *device_node,
+	u32                     *flags)
+{
+	ACPI_OPERAND_OBJECT     *obj_desc;
+	ACPI_STATUS             status;
+
+
+	/* Execute the method */
+
+	status = acpi_ns_evaluate_relative (device_node,
+			 METHOD_NAME__STA, NULL, &obj_desc);
+	if (AE_NOT_FOUND == status) {
+		*flags = 0x0F;
+		status = AE_OK;
+	}
+
+
+	else /* success */ {
+		/* Did we get a return object? */
+
+		if (!obj_desc) {
+			return (AE_TYPE);
+		}
+
+		/* Is the return object of the correct type? */
+
+		if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
+			status = AE_TYPE;
+		}
+
+		else {
+			/* Extract the status flags */
+
+			*flags = (u32) obj_desc->integer.value;
+		}
+
+		/* On exit, we must delete the return object */
+
+		acpi_ut_remove_reference (obj_desc);
+	}
+
+	return (status);
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/utilities/utglobal.c linux/drivers/acpi/utilities/utglobal.c
--- v2.4.5/linux/drivers/acpi/utilities/utglobal.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/utilities/utglobal.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,483 @@
+/******************************************************************************
+ *
+ * Module Name: utglobal - Global variables for the ACPI subsystem
+ *              $Revision: 123 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#define DEFINE_ACPI_GLOBALS
+
+#include "acpi.h"
+#include "acevents.h"
+#include "acnamesp.h"
+#include "acinterp.h"
+#include "amlcode.h"
+
+
+#define _COMPONENT          ACPI_UTILITIES
+	 MODULE_NAME         ("utglobal")
+
+
+/******************************************************************************
+ *
+ * Static global variable initialization.
+ *
+ ******************************************************************************/
+
+/*
+ * We want the debug switches statically initialized so they
+ * are already set when the debugger is entered.
+ */
+
+/* Debug switch - level and trace mask */
+
+u32                         acpi_dbg_level = NORMAL_DEFAULT;
+
+/* Debug switch - layer (component) mask */
+
+u32                         acpi_dbg_layer = ACPI_COMPONENT_DEFAULT;
+u32                         acpi_gbl_nesting_level = 0;
+
+
+/* Debugger globals */
+
+u8                          acpi_gbl_db_terminate_threads = FALSE;
+u8                          acpi_gbl_method_executing = FALSE;
+
+/* System flags */
+
+u32                         acpi_gbl_system_flags = 0;
+u32                         acpi_gbl_startup_flags = 0;
+
+/* System starts unitialized! */
+u8                          acpi_gbl_shutdown = TRUE;
+
+
+u8                          acpi_gbl_decode_to8bit [8] = {1,2,4,8,16,32,64,128};
+
+
+/******************************************************************************
+ *
+ * Namespace globals
+ *
+ ******************************************************************************/
+
+
+/*
+ * Names built-in to the interpreter
+ *
+ * Initial values are currently supported only for types String and Number.
+ * To avoid type punning, both are specified as strings in this table.
+ *
+ * NOTES:
+ * 1) _SB_ is defined to be a device to allow _SB_/_INI to be run
+ *    during the initialization sequence.
+ */
+
+PREDEFINED_NAMES            acpi_gbl_pre_defined_names[] =
+{ {"_GPE",    INTERNAL_TYPE_DEF_ANY},
+	{"_PR_",    INTERNAL_TYPE_DEF_ANY},
+	{"_SB_",    ACPI_TYPE_DEVICE},
+	{"_SI_",    INTERNAL_TYPE_DEF_ANY},
+	{"_TZ_",    INTERNAL_TYPE_DEF_ANY},
+	{"_REV",    ACPI_TYPE_INTEGER, "2"},
+	{"_OS_",    ACPI_TYPE_STRING, ACPI_OS_NAME},
+	{"_GL_",    ACPI_TYPE_MUTEX, "0"},
+	{NULL,      ACPI_TYPE_ANY}           /* Table terminator */
+};
+
+
+/*
+ * Properties of the ACPI Object Types, both internal and external.
+ *
+ * Elements of Acpi_ns_properties are bit significant
+ * and the table is indexed by values of ACPI_OBJECT_TYPE
+ */
+
+u8                          acpi_gbl_ns_properties[] =
+{
+	NSP_NORMAL,                 /* 00 Any              */
+	NSP_NORMAL,                 /* 01 Number           */
+	NSP_NORMAL,                 /* 02 String           */
+	NSP_NORMAL,                 /* 03 Buffer           */
+	NSP_LOCAL,                  /* 04 Package          */
+	NSP_NORMAL,                 /* 05 Field_unit       */
+	NSP_NEWSCOPE | NSP_LOCAL,   /* 06 Device           */
+	NSP_LOCAL,                  /* 07 Acpi_event       */
+	NSP_NEWSCOPE | NSP_LOCAL,   /* 08 Method           */
+	NSP_LOCAL,                  /* 09 Mutex            */
+	NSP_LOCAL,                  /* 10 Region           */
+	NSP_NEWSCOPE | NSP_LOCAL,   /* 11 Power            */
+	NSP_NEWSCOPE | NSP_LOCAL,   /* 12 Processor        */
+	NSP_NEWSCOPE | NSP_LOCAL,   /* 13 Thermal          */
+	NSP_NORMAL,                 /* 14 Buffer_field     */
+	NSP_NORMAL,                 /* 15 Ddb_handle       */
+	NSP_NORMAL,                 /* 16 Debug Object     */
+	NSP_NORMAL,                 /* 17 Def_field        */
+	NSP_NORMAL,                 /* 18 Bank_field       */
+	NSP_NORMAL,                 /* 19 Index_field      */
+	NSP_NORMAL,                 /* 20 Reference        */
+	NSP_NORMAL,                 /* 21 Alias            */
+	NSP_NORMAL,                 /* 22 Notify           */
+	NSP_NORMAL,                 /* 23 Address Handler  */
+	NSP_NEWSCOPE | NSP_LOCAL,   /* 24 Resource Desc    */
+	NSP_NEWSCOPE | NSP_LOCAL,   /* 25 Resource Field   */
+	NSP_NORMAL,                 /* 26 Def_field_defn   */
+	NSP_NORMAL,                 /* 27 Bank_field_defn  */
+	NSP_NORMAL,                 /* 28 Index_field_defn */
+	NSP_NORMAL,                 /* 29 If               */
+	NSP_NORMAL,                 /* 30 Else             */
+	NSP_NORMAL,                 /* 31 While            */
+	NSP_NEWSCOPE,               /* 32 Scope            */
+	NSP_LOCAL,                  /* 33 Def_any          */
+	NSP_NORMAL,                 /* 34 Extra            */
+	NSP_NORMAL                  /* 35 Invalid          */
+};
+
+
+/* Hex to ASCII conversion table */
+
+NATIVE_CHAR                 acpi_gbl_hex_to_ascii[] =
+			  {'0','1','2','3','4','5','6','7',
+			  '8','9','A','B','C','D','E','F'};
+
+
+/******************************************************************************
+ *
+ * Table globals
+ *
+ * NOTE: This table includes ONLY the ACPI tables that the subsystem consumes.
+ * it is NOT an exhaustive list of all possible ACPI tables.  All ACPI tables
+ * that are not used by the subsystem are simply ignored.
+ *
+ ******************************************************************************/
+
+
+ACPI_TABLE_DESC             acpi_gbl_acpi_tables[NUM_ACPI_TABLES];
+
+
+ACPI_TABLE_SUPPORT          acpi_gbl_acpi_table_data[NUM_ACPI_TABLES] =
+{
+	/***********    Name,    Signature,  Signature size,    How many allowed?,   Supported?  Global typed pointer */
+
+	/* RSDP 0 */ {RSDP_NAME, RSDP_SIG, sizeof (RSDP_SIG)-1, ACPI_TABLE_SINGLE,   AE_OK,      NULL},
+	/* DSDT 1 */ {DSDT_SIG,  DSDT_SIG, sizeof (DSDT_SIG)-1, ACPI_TABLE_SINGLE,   AE_OK,      (void **) &acpi_gbl_DSDT},
+	/* FADT 2 */ {FADT_SIG,  FADT_SIG, sizeof (FADT_SIG)-1, ACPI_TABLE_SINGLE,   AE_OK,      (void **) &acpi_gbl_FADT},
+	/* FACS 3 */ {FACS_SIG,  FACS_SIG, sizeof (FACS_SIG)-1, ACPI_TABLE_SINGLE,   AE_OK,      (void **) &acpi_gbl_FACS},
+	/* PSDT 4 */ {PSDT_SIG,  PSDT_SIG, sizeof (PSDT_SIG)-1, ACPI_TABLE_MULTIPLE, AE_OK,      NULL},
+	/* SSDT 5 */ {SSDT_SIG,  SSDT_SIG, sizeof (SSDT_SIG)-1, ACPI_TABLE_MULTIPLE, AE_OK,      NULL},
+	/* XSDT 6 */ {XSDT_SIG,  XSDT_SIG, sizeof (RSDT_SIG)-1, ACPI_TABLE_SINGLE,   AE_OK,      NULL},
+};
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_valid_object_type
+ *
+ * PARAMETERS:  None.
+ *
+ * RETURN:      TRUE if valid object type
+ *
+ * DESCRIPTION: Validate an object type
+ *
+ ****************************************************************************/
+
+u8
+acpi_ut_valid_object_type (
+	u32                     type)
+{
+
+	if (type > ACPI_TYPE_MAX)
+	{
+		if ((type < INTERNAL_TYPE_BEGIN) ||
+			(type > INTERNAL_TYPE_MAX))
+		{
+			return (FALSE);
+		}
+	}
+
+	return (TRUE);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_format_exception
+ *
+ * PARAMETERS:  Status              - Acpi status to be formatted
+ *
+ * RETURN:      Formatted status string
+ *
+ * DESCRIPTION: Convert an ACPI exception to a string
+ *
+ ****************************************************************************/
+
+NATIVE_CHAR *
+acpi_ut_format_exception (
+	ACPI_STATUS             status)
+{
+	NATIVE_CHAR             *exception = "UNKNOWN_STATUS";
+	ACPI_STATUS             sub_status;
+
+
+	sub_status = (status & ~AE_CODE_MASK);
+
+
+	switch (status & AE_CODE_MASK)
+	{
+	case AE_CODE_ENVIRONMENTAL:
+
+		if (sub_status <= AE_CODE_ENV_MAX)
+		{
+			exception = acpi_gbl_exception_names_env [sub_status];
+		}
+		break;
+
+	case AE_CODE_PROGRAMMER:
+
+		if (sub_status <= AE_CODE_PGM_MAX)
+		{
+			exception = acpi_gbl_exception_names_pgm [sub_status -1];
+		}
+		break;
+
+	case AE_CODE_ACPI_TABLES:
+
+		if (sub_status <= AE_CODE_TBL_MAX)
+		{
+			exception = acpi_gbl_exception_names_tbl [sub_status -1];
+		}
+		break;
+
+	case AE_CODE_AML:
+
+		if (sub_status <= AE_CODE_AML_MAX)
+		{
+			exception = acpi_gbl_exception_names_aml [sub_status -1];
+		}
+		break;
+
+	case AE_CODE_CONTROL:
+
+		if (sub_status <= AE_CODE_CTRL_MAX)
+		{
+			exception = acpi_gbl_exception_names_ctrl [sub_status -1];
+		}
+		break;
+
+	default:
+		break;
+	}
+
+
+	return (exception);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_allocate_owner_id
+ *
+ * PARAMETERS:  Id_type         - Type of ID (method or table)
+ *
+ * DESCRIPTION: Allocate a table or method owner id
+ *
+ ***************************************************************************/
+
+ACPI_OWNER_ID
+acpi_ut_allocate_owner_id (
+	u32                     id_type)
+{
+	ACPI_OWNER_ID           owner_id = 0xFFFF;
+
+
+	acpi_ut_acquire_mutex (ACPI_MTX_CACHES);
+
+	switch (id_type)
+	{
+	case OWNER_TYPE_TABLE:
+
+		owner_id = acpi_gbl_next_table_owner_id;
+		acpi_gbl_next_table_owner_id++;
+
+		if (acpi_gbl_next_table_owner_id == FIRST_METHOD_ID)
+		{
+			acpi_gbl_next_table_owner_id = FIRST_TABLE_ID;
+		}
+		break;
+
+
+	case OWNER_TYPE_METHOD:
+
+		owner_id = acpi_gbl_next_method_owner_id;
+		acpi_gbl_next_method_owner_id++;
+
+		if (acpi_gbl_next_method_owner_id == FIRST_TABLE_ID)
+		{
+			acpi_gbl_next_method_owner_id = FIRST_METHOD_ID;
+		}
+		break;
+	}
+
+
+	acpi_ut_release_mutex (ACPI_MTX_CACHES);
+
+	return (owner_id);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_init_globals
+ *
+ * PARAMETERS:  none
+ *
+ * DESCRIPTION: Init library globals.  All globals that require specific
+ *              initialization should be initialized here!
+ *
+ ***************************************************************************/
+
+void
+acpi_ut_init_globals (
+	void)
+{
+	u32                     i;
+
+
+	/* ACPI table structure */
+
+	for (i = 0; i < NUM_ACPI_TABLES; i++)
+	{
+		acpi_gbl_acpi_tables[i].prev        = &acpi_gbl_acpi_tables[i];
+		acpi_gbl_acpi_tables[i].next        = &acpi_gbl_acpi_tables[i];
+		acpi_gbl_acpi_tables[i].pointer     = NULL;
+		acpi_gbl_acpi_tables[i].length      = 0;
+		acpi_gbl_acpi_tables[i].allocation  = ACPI_MEM_NOT_ALLOCATED;
+		acpi_gbl_acpi_tables[i].count       = 0;
+	}
+
+
+	/* Address Space handler array */
+
+	for (i = 0; i < ACPI_NUM_ADDRESS_SPACES; i++)
+	{
+		acpi_gbl_address_spaces[i].handler  = NULL;
+		acpi_gbl_address_spaces[i].context  = NULL;
+	}
+
+	/* Mutex locked flags */
+
+	for (i = 0; i < NUM_MTX; i++)
+	{
+		acpi_gbl_acpi_mutex_info[i].mutex   = NULL;
+		acpi_gbl_acpi_mutex_info[i].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+		acpi_gbl_acpi_mutex_info[i].use_count = 0;
+	}
+
+	/* Global notify handlers */
+
+	acpi_gbl_sys_notify.handler         = NULL;
+	acpi_gbl_drv_notify.handler         = NULL;
+
+	/* Global "typed" ACPI table pointers */
+
+	acpi_gbl_RSDP                       = NULL;
+	acpi_gbl_XSDT                       = NULL;
+	acpi_gbl_FACS                       = NULL;
+	acpi_gbl_FADT                       = NULL;
+	acpi_gbl_DSDT                       = NULL;
+
+
+	/* Global Lock support */
+
+	acpi_gbl_global_lock_acquired       = FALSE;
+	acpi_gbl_global_lock_thread_count   = 0;
+
+	/* Miscellaneous variables */
+
+	acpi_gbl_system_flags               = 0;
+	acpi_gbl_startup_flags              = 0;
+	acpi_gbl_rsdp_original_location     = 0;
+	acpi_gbl_cm_single_step             = FALSE;
+	acpi_gbl_db_terminate_threads       = FALSE;
+	acpi_gbl_shutdown                   = FALSE;
+	acpi_gbl_ns_lookup_count            = 0;
+	acpi_gbl_ps_find_count              = 0;
+	acpi_gbl_acpi_hardware_present      = TRUE;
+	acpi_gbl_next_table_owner_id        = FIRST_TABLE_ID;
+	acpi_gbl_next_method_owner_id       = FIRST_METHOD_ID;
+	acpi_gbl_debugger_configuration     = DEBUGGER_THREADING;
+
+	/* Cache of small "state" objects */
+
+	acpi_gbl_generic_state_cache        = NULL;
+	acpi_gbl_generic_state_cache_depth  = 0;
+	acpi_gbl_state_cache_requests       = 0;
+	acpi_gbl_state_cache_hits           = 0;
+
+	acpi_gbl_parse_cache                = NULL;
+	acpi_gbl_parse_cache_depth          = 0;
+	acpi_gbl_parse_cache_requests       = 0;
+	acpi_gbl_parse_cache_hits           = 0;
+
+	acpi_gbl_ext_parse_cache            = NULL;
+	acpi_gbl_ext_parse_cache_depth      = 0;
+	acpi_gbl_ext_parse_cache_requests   = 0;
+	acpi_gbl_ext_parse_cache_hits       = 0;
+
+	acpi_gbl_object_cache               = NULL;
+	acpi_gbl_object_cache_depth         = 0;
+	acpi_gbl_object_cache_requests      = 0;
+	acpi_gbl_object_cache_hits          = 0;
+
+	acpi_gbl_walk_state_cache           = NULL;
+	acpi_gbl_walk_state_cache_depth     = 0;
+	acpi_gbl_walk_state_cache_requests  = 0;
+	acpi_gbl_walk_state_cache_hits      = 0;
+
+	/* Hardware oriented */
+
+	acpi_gbl_gpe0enable_register_save   = NULL;
+	acpi_gbl_gpe1_enable_register_save  = NULL;
+	acpi_gbl_original_mode              = SYS_MODE_UNKNOWN;   /*  original ACPI/legacy mode   */
+	acpi_gbl_gpe_registers              = NULL;
+	acpi_gbl_gpe_info                   = NULL;
+
+	/* Namespace */
+
+	acpi_gbl_root_node                  = NULL;
+
+	acpi_gbl_root_node_struct.name      = ACPI_ROOT_NAME;
+	acpi_gbl_root_node_struct.data_type = ACPI_DESC_TYPE_NAMED;
+	acpi_gbl_root_node_struct.type      = ACPI_TYPE_ANY;
+	acpi_gbl_root_node_struct.child     = NULL;
+	acpi_gbl_root_node_struct.peer      = NULL;
+	acpi_gbl_root_node_struct.object    = NULL;
+	acpi_gbl_root_node_struct.flags     = ANOBJ_END_OF_PEER_LIST;
+
+	/* Memory allocation metrics - compiled out in non-debug mode. */
+
+	INITIALIZE_ALLOCATION_METRICS();
+
+	return;
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/utilities/utinit.c linux/drivers/acpi/utilities/utinit.c
--- v2.4.5/linux/drivers/acpi/utilities/utinit.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/utilities/utinit.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,247 @@
+/******************************************************************************
+ *
+ * Module Name: utinit - Common ACPI subsystem initialization
+ *              $Revision: 96 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "achware.h"
+#include "acnamesp.h"
+#include "acevents.h"
+#include "acparser.h"
+#include "acdispat.h"
+
+#define _COMPONENT          ACPI_UTILITIES
+	 MODULE_NAME         ("utinit")
+
+
+#define ACPI_OFFSET(d,o)    ((u32) &(((d *)0)->o))
+#define ACPI_FADT_OFFSET(o) ACPI_OFFSET (FADT_DESCRIPTOR, o)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_fadt_register_error
+ *
+ * PARAMETERS:  *Register_name          - Pointer to string identifying register
+ *              Value                   - Actual register contents value
+ *              Acpi_test_spec_section  - TDS section containing assertion
+ *              Acpi_assertion          - Assertion number being tested
+ *
+ * RETURN:      AE_BAD_VALUE
+ *
+ * DESCRIPTION: Display failure message and link failure to TDS assertion
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+acpi_ut_fadt_register_error (
+	NATIVE_CHAR             *register_name,
+	u32                     value,
+	u32                     offset)
+{
+
+	REPORT_ERROR (
+		("Invalid FADT value %s=%lX at offset %lX FADT=%p\n",
+		register_name, value, offset, acpi_gbl_FADT));
+
+
+	return (AE_BAD_VALUE);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_validate_fadt
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Validate various ACPI registers in the FADT
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_validate_fadt (
+	void)
+{
+	ACPI_STATUS                 status = AE_OK;
+
+
+	/*
+	 * Verify Fixed ACPI Description Table fields,
+	 * but don't abort on any problems, just display error
+	 */
+
+	if (acpi_gbl_FADT->pm1_evt_len < 4) {
+		status = acpi_ut_fadt_register_error ("PM1_EVT_LEN",
+				  (u32) acpi_gbl_FADT->pm1_evt_len,
+				  ACPI_FADT_OFFSET (pm1_evt_len));
+	}
+
+	if (!acpi_gbl_FADT->pm1_cnt_len) {
+		status = acpi_ut_fadt_register_error ("PM1_CNT_LEN", 0,
+				  ACPI_FADT_OFFSET (pm1_cnt_len));
+	}
+
+	if (!ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm1a_evt_blk.address)) {
+		status = acpi_ut_fadt_register_error ("X_PM1a_EVT_BLK", 0,
+				  ACPI_FADT_OFFSET (Xpm1a_evt_blk.address));
+	}
+
+	if (!ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm1a_cnt_blk.address)) {
+		status = acpi_ut_fadt_register_error ("X_PM1a_CNT_BLK", 0,
+				  ACPI_FADT_OFFSET (Xpm1a_cnt_blk.address));
+	}
+
+	if (!ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm_tmr_blk.address)) {
+		status = acpi_ut_fadt_register_error ("X_PM_TMR_BLK", 0,
+				  ACPI_FADT_OFFSET (Xpm_tmr_blk.address));
+	}
+
+	if ((ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm2_cnt_blk.address) &&
+		!acpi_gbl_FADT->pm2_cnt_len)) {
+		status = acpi_ut_fadt_register_error ("PM2_CNT_LEN",
+				  (u32) acpi_gbl_FADT->pm2_cnt_len,
+				  ACPI_FADT_OFFSET (pm2_cnt_len));
+	}
+
+	if (acpi_gbl_FADT->pm_tm_len < 4) {
+		status = acpi_ut_fadt_register_error ("PM_TM_LEN",
+				  (u32) acpi_gbl_FADT->pm_tm_len,
+				  ACPI_FADT_OFFSET (pm_tm_len));
+	}
+
+	/* length of GPE blocks must be a multiple of 2 */
+
+
+	if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) &&
+		(acpi_gbl_FADT->gpe0blk_len & 1)) {
+		status = acpi_ut_fadt_register_error ("(x)GPE0_BLK_LEN",
+				  (u32) acpi_gbl_FADT->gpe0blk_len,
+				  ACPI_FADT_OFFSET (gpe0blk_len));
+	}
+
+	if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) &&
+		(acpi_gbl_FADT->gpe1_blk_len & 1)) {
+		status = acpi_ut_fadt_register_error ("(x)GPE1_BLK_LEN",
+				  (u32) acpi_gbl_FADT->gpe1_blk_len,
+				  ACPI_FADT_OFFSET (gpe1_blk_len));
+	}
+
+	return (status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_terminate
+ *
+ * PARAMETERS:  none
+ *
+ * RETURN:      none
+ *
+ * DESCRIPTION: free memory allocated for table storage.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_terminate (void)
+{
+
+
+	/* Free global tables, etc. */
+
+	if (acpi_gbl_gpe0enable_register_save) {
+		acpi_ut_free (acpi_gbl_gpe0enable_register_save);
+	}
+
+	if (acpi_gbl_gpe1_enable_register_save) {
+		acpi_ut_free (acpi_gbl_gpe1_enable_register_save);
+	}
+
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_subsystem_shutdown
+ *
+ * PARAMETERS:  none
+ *
+ * RETURN:      none
+ *
+ * DESCRIPTION: Shutdown the various subsystems.  Don't delete the mutex
+ *              objects here -- because the AML debugger may be still running.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_subsystem_shutdown (void)
+{
+
+	/* Just exit if subsystem is already shutdown */
+
+	if (acpi_gbl_shutdown) {
+		return (AE_OK);
+	}
+
+	/* Subsystem appears active, go ahead and shut it down */
+
+	acpi_gbl_shutdown = TRUE;
+
+	/* Close the Namespace */
+
+	acpi_ns_terminate ();
+
+	/* Close the Acpi_event Handling */
+
+	acpi_ev_terminate ();
+
+	/* Close the globals */
+
+	acpi_ut_terminate ();
+
+	/* Flush the local cache(s) */
+
+	acpi_ut_delete_generic_state_cache ();
+	acpi_ut_delete_object_cache ();
+	acpi_ds_delete_walk_state_cache ();
+
+	/* Close the Parser */
+
+	/* TBD: [Restructure] Acpi_ps_terminate () */
+
+	acpi_ps_delete_parse_cache ();
+
+	/* Debug only - display leftover memory allocation, if any */
+#ifdef ENABLE_DEBUGGER
+	acpi_ut_dump_current_allocations (ACPI_UINT32_MAX, NULL);
+#endif
+
+	return (AE_OK);
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/utilities/utmisc.c linux/drivers/acpi/utilities/utmisc.c
--- v2.4.5/linux/drivers/acpi/utilities/utmisc.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/utilities/utmisc.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,1043 @@
+/*******************************************************************************
+ *
+ * Module Name: utmisc - common utility procedures
+ *              $Revision: 42 $
+ *
+ ******************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acevents.h"
+#include "achware.h"
+#include "acnamesp.h"
+#include "acinterp.h"
+#include "amlcode.h"
+#include "acdebug.h"
+
+
+#define _COMPONENT          ACPI_UTILITIES
+	 MODULE_NAME         ("utmisc")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_valid_acpi_name
+ *
+ * PARAMETERS:  Character           - The character to be examined
+ *
+ * RETURN:      1 if Character may appear in a name, else 0
+ *
+ * DESCRIPTION: Check for a valid ACPI name.  Each character must be one of:
+ *              1) Upper case alpha
+ *              2) numeric
+ *              3) underscore
+ *
+ ******************************************************************************/
+
+u8
+acpi_ut_valid_acpi_name (
+	u32                     name)
+{
+	NATIVE_CHAR             *name_ptr = (NATIVE_CHAR *) &name;
+	u32                     i;
+
+
+	for (i = 0; i < ACPI_NAME_SIZE; i++) {
+		if (!((name_ptr[i] == '_') ||
+			  (name_ptr[i] >= 'A' && name_ptr[i] <= 'Z') ||
+			  (name_ptr[i] >= '0' && name_ptr[i] <= '9'))) {
+			return (FALSE);
+		}
+	}
+
+
+	return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_valid_acpi_character
+ *
+ * PARAMETERS:  Character           - The character to be examined
+ *
+ * RETURN:      1 if Character may appear in a name, else 0
+ *
+ * DESCRIPTION: Check for a printable character
+ *
+ ******************************************************************************/
+
+u8
+acpi_ut_valid_acpi_character (
+	NATIVE_CHAR             character)
+{
+
+	return ((u8)   ((character == '_') ||
+			   (character >= 'A' && character <= 'Z') ||
+			   (character >= '0' && character <= '9')));
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_strupr
+ *
+ * PARAMETERS:  Src_string      - The source string to convert to
+ *
+ * RETURN:      Src_string
+ *
+ * DESCRIPTION: Convert string to uppercase
+ *
+ ******************************************************************************/
+
+NATIVE_CHAR *
+acpi_ut_strupr (
+	NATIVE_CHAR             *src_string)
+{
+	NATIVE_CHAR             *string;
+
+
+	/* Walk entire string, uppercasing the letters */
+
+	for (string = src_string; *string; ) {
+		*string = (char) TOUPPER (*string);
+		string++;
+	}
+
+
+	return (src_string);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_mutex_initialize
+ *
+ * PARAMETERS:  None.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create the system mutex objects.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_mutex_initialize (
+	void)
+{
+	u32                     i;
+	ACPI_STATUS             status;
+
+
+	/*
+	 * Create each of the predefined mutex objects
+	 */
+	for (i = 0; i < NUM_MTX; i++) {
+		status = acpi_ut_create_mutex (i);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+	}
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_mutex_terminate
+ *
+ * PARAMETERS:  None.
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Delete all of the system mutex objects.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_mutex_terminate (
+	void)
+{
+	u32                     i;
+
+
+	/*
+	 * Delete each predefined mutex object
+	 */
+	for (i = 0; i < NUM_MTX; i++) {
+		acpi_ut_delete_mutex (i);
+	}
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_create_mutex
+ *
+ * PARAMETERS:  Mutex_iD        - ID of the mutex to be created
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a mutex object.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_create_mutex (
+	ACPI_MUTEX_HANDLE       mutex_id)
+{
+	ACPI_STATUS             status = AE_OK;
+
+
+	if (mutex_id > MAX_MTX) {
+		return (AE_BAD_PARAMETER);
+	}
+
+
+	if (!acpi_gbl_acpi_mutex_info[mutex_id].mutex) {
+		status = acpi_os_create_semaphore (1, 1,
+				  &acpi_gbl_acpi_mutex_info[mutex_id].mutex);
+		acpi_gbl_acpi_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+		acpi_gbl_acpi_mutex_info[mutex_id].use_count = 0;
+	}
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_delete_mutex
+ *
+ * PARAMETERS:  Mutex_iD        - ID of the mutex to be deleted
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Delete a mutex object.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_delete_mutex (
+	ACPI_MUTEX_HANDLE       mutex_id)
+{
+	ACPI_STATUS             status;
+
+
+	if (mutex_id > MAX_MTX) {
+		return (AE_BAD_PARAMETER);
+	}
+
+
+	status = acpi_os_delete_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex);
+
+	acpi_gbl_acpi_mutex_info[mutex_id].mutex = NULL;
+	acpi_gbl_acpi_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_acquire_mutex
+ *
+ * PARAMETERS:  Mutex_iD        - ID of the mutex to be acquired
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Acquire a mutex object.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_acquire_mutex (
+	ACPI_MUTEX_HANDLE       mutex_id)
+{
+	ACPI_STATUS             status;
+	u32                     i;
+	u32                     this_thread_id;
+
+
+	PROC_NAME ("Ut_acquire_mutex");
+
+
+	if (mutex_id > MAX_MTX) {
+		return (AE_BAD_PARAMETER);
+	}
+
+
+	this_thread_id = acpi_os_get_thread_id ();
+
+	/*
+	 * Deadlock prevention.  Check if this thread owns any mutexes of value
+	 * greater than or equal to this one.  If so, the thread has violated
+	 * the mutex ordering rule.  This indicates a coding error somewhere in
+	 * the ACPI subsystem code.
+	 */
+	for (i = mutex_id; i < MAX_MTX; i++) {
+		if (acpi_gbl_acpi_mutex_info[i].owner_id == this_thread_id) {
+			if (i == mutex_id) {
+				return (AE_ALREADY_ACQUIRED);
+			}
+
+			return (AE_ACQUIRE_DEADLOCK);
+		}
+	}
+
+
+	status = acpi_os_wait_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex,
+			   1, WAIT_FOREVER);
+
+	if (ACPI_SUCCESS (status)) {
+		acpi_gbl_acpi_mutex_info[mutex_id].use_count++;
+		acpi_gbl_acpi_mutex_info[mutex_id].owner_id = this_thread_id;
+	}
+
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_release_mutex
+ *
+ * PARAMETERS:  Mutex_iD        - ID of the mutex to be released
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Release a mutex object.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_release_mutex (
+	ACPI_MUTEX_HANDLE       mutex_id)
+{
+	ACPI_STATUS             status;
+	u32                     i;
+	u32                     this_thread_id;
+
+
+	PROC_NAME ("Ut_release_mutex");
+
+
+	this_thread_id = acpi_os_get_thread_id ();
+	if (mutex_id > MAX_MTX) {
+		return (AE_BAD_PARAMETER);
+	}
+
+
+	/*
+	 * Mutex must be acquired in order to release it!
+	 */
+	if (acpi_gbl_acpi_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) {
+		return (AE_NOT_ACQUIRED);
+	}
+
+
+	/*
+	 * Deadlock prevention.  Check if this thread owns any mutexes of value
+	 * greater than this one.  If so, the thread has violated the mutex
+	 * ordering rule.  This indicates a coding error somewhere in
+	 * the ACPI subsystem code.
+	 */
+	for (i = mutex_id; i < MAX_MTX; i++) {
+		if (acpi_gbl_acpi_mutex_info[i].owner_id == this_thread_id) {
+			if (i == mutex_id) {
+				continue;
+			}
+
+			return (AE_RELEASE_DEADLOCK);
+		}
+	}
+
+
+	/* Mark unlocked FIRST */
+
+	acpi_gbl_acpi_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+
+	status = acpi_os_signal_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex, 1);
+
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_create_update_state_and_push
+ *
+ * PARAMETERS:  *Object         - Object to be added to the new state
+ *              Action          - Increment/Decrement
+ *              State_list      - List the state will be added to
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Create a new state and push it
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_create_update_state_and_push (
+	ACPI_OPERAND_OBJECT     *object,
+	u16                     action,
+	ACPI_GENERIC_STATE      **state_list)
+{
+	ACPI_GENERIC_STATE       *state;
+
+
+	/* Ignore null objects; these are expected */
+
+	if (!object) {
+		return (AE_OK);
+	}
+
+	state = acpi_ut_create_update_state (object, action);
+	if (!state) {
+		return (AE_NO_MEMORY);
+	}
+
+
+	acpi_ut_push_generic_state (state_list, state);
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_create_pkg_state_and_push
+ *
+ * PARAMETERS:  *Object         - Object to be added to the new state
+ *              Action          - Increment/Decrement
+ *              State_list      - List the state will be added to
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Create a new state and push it
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_create_pkg_state_and_push (
+	void                    *internal_object,
+	void                    *external_object,
+	u16                     index,
+	ACPI_GENERIC_STATE      **state_list)
+{
+	ACPI_GENERIC_STATE       *state;
+
+
+	state = acpi_ut_create_pkg_state (internal_object, external_object, index);
+	if (!state) {
+		return (AE_NO_MEMORY);
+	}
+
+
+	acpi_ut_push_generic_state (state_list, state);
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_push_generic_state
+ *
+ * PARAMETERS:  List_head           - Head of the state stack
+ *              State               - State object to push
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Push a state object onto a state stack
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_push_generic_state (
+	ACPI_GENERIC_STATE      **list_head,
+	ACPI_GENERIC_STATE      *state)
+{
+	/* Push the state object onto the front of the list (stack) */
+
+	state->common.next = *list_head;
+	*list_head = state;
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_pop_generic_state
+ *
+ * PARAMETERS:  List_head           - Head of the state stack
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Pop a state object from a state stack
+ *
+ ******************************************************************************/
+
+ACPI_GENERIC_STATE *
+acpi_ut_pop_generic_state (
+	ACPI_GENERIC_STATE      **list_head)
+{
+	ACPI_GENERIC_STATE      *state;
+
+
+	/* Remove the state object at the head of the list (stack) */
+
+	state = *list_head;
+	if (state) {
+		/* Update the list head */
+
+		*list_head = state->common.next;
+	}
+
+	return (state);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_create_generic_state
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a generic state object.  Attempt to obtain one from
+ *              the global state cache;  If none available, create a new one.
+ *
+ ******************************************************************************/
+
+ACPI_GENERIC_STATE *
+acpi_ut_create_generic_state (void)
+{
+	ACPI_GENERIC_STATE      *state;
+
+
+	acpi_ut_acquire_mutex (ACPI_MTX_CACHES);
+
+	acpi_gbl_state_cache_requests++;
+
+	/* Check the cache first */
+
+	if (acpi_gbl_generic_state_cache) {
+		/* There is an object available, use it */
+
+		state = acpi_gbl_generic_state_cache;
+		acpi_gbl_generic_state_cache = state->common.next;
+		state->common.next = NULL;
+
+		acpi_gbl_state_cache_hits++;
+		acpi_gbl_generic_state_cache_depth--;
+
+		acpi_ut_release_mutex (ACPI_MTX_CACHES);
+
+	}
+
+	else {
+		/* The cache is empty, create a new object */
+
+		acpi_ut_release_mutex (ACPI_MTX_CACHES);
+
+		state = acpi_ut_callocate (sizeof (ACPI_GENERIC_STATE));
+	}
+
+	/* Initialize */
+
+	if (state) {
+		/* Always zero out the object before init */
+
+		MEMSET (state, 0, sizeof (ACPI_GENERIC_STATE));
+
+		state->common.data_type = ACPI_DESC_TYPE_STATE;
+	}
+
+	return (state);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_create_update_state
+ *
+ * PARAMETERS:  Object              - Initial Object to be installed in the
+ *                                    state
+ *              Action              - Update action to be performed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
+ *              to update reference counts and delete complex objects such
+ *              as packages.
+ *
+ ******************************************************************************/
+
+ACPI_GENERIC_STATE *
+acpi_ut_create_update_state (
+	ACPI_OPERAND_OBJECT     *object,
+	u16                     action)
+{
+	ACPI_GENERIC_STATE      *state;
+
+
+	/* Create the generic state object */
+
+	state = acpi_ut_create_generic_state ();
+	if (!state) {
+		return (NULL);
+	}
+
+	/* Init fields specific to the update struct */
+
+	state->update.object = object;
+	state->update.value  = action;
+
+	return (state);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_create_pkg_state
+ *
+ * PARAMETERS:  Object              - Initial Object to be installed in the
+ *                                    state
+ *              Action              - Update action to be performed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
+ *              to update reference counts and delete complex objects such
+ *              as packages.
+ *
+ ******************************************************************************/
+
+ACPI_GENERIC_STATE *
+acpi_ut_create_pkg_state (
+	void                    *internal_object,
+	void                    *external_object,
+	u16                     index)
+{
+	ACPI_GENERIC_STATE      *state;
+
+
+	/* Create the generic state object */
+
+	state = acpi_ut_create_generic_state ();
+	if (!state) {
+		return (NULL);
+	}
+
+	/* Init fields specific to the update struct */
+
+	state->pkg.source_object = (ACPI_OPERAND_OBJECT *) internal_object;
+	state->pkg.dest_object  = external_object;
+	state->pkg.index        = index;
+	state->pkg.num_packages = 1;
+
+	return (state);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_create_control_state
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a "Control State" - a flavor of the generic state used
+ *              to support nested IF/WHILE constructs in the AML.
+ *
+ ******************************************************************************/
+
+ACPI_GENERIC_STATE *
+acpi_ut_create_control_state (
+	void)
+{
+	ACPI_GENERIC_STATE      *state;
+
+
+	/* Create the generic state object */
+
+	state = acpi_ut_create_generic_state ();
+	if (!state) {
+		return (NULL);
+	}
+
+
+	/* Init fields specific to the control struct */
+
+	state->common.state = CONTROL_CONDITIONAL_EXECUTING;
+
+	return (state);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_delete_generic_state
+ *
+ * PARAMETERS:  State               - The state object to be deleted
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Put a state object back into the global state cache.  The object
+ *              is not actually freed at this time.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_delete_generic_state (
+	ACPI_GENERIC_STATE      *state)
+{
+
+	/* If cache is full, just free this state object */
+
+	if (acpi_gbl_generic_state_cache_depth >= MAX_STATE_CACHE_DEPTH) {
+		acpi_ut_free (state);
+	}
+
+	/* Otherwise put this object back into the cache */
+
+	else {
+		acpi_ut_acquire_mutex (ACPI_MTX_CACHES);
+
+		/* Clear the state */
+
+		MEMSET (state, 0, sizeof (ACPI_GENERIC_STATE));
+		state->common.data_type = ACPI_DESC_TYPE_STATE;
+
+		/* Put the object at the head of the global cache list */
+
+		state->common.next = acpi_gbl_generic_state_cache;
+		acpi_gbl_generic_state_cache = state;
+		acpi_gbl_generic_state_cache_depth++;
+
+
+		acpi_ut_release_mutex (ACPI_MTX_CACHES);
+	}
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_delete_generic_state_cache
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Purge the global state object cache.  Used during subsystem
+ *              termination.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_delete_generic_state_cache (
+	void)
+{
+	ACPI_GENERIC_STATE      *next;
+
+
+	/* Traverse the global cache list */
+
+	while (acpi_gbl_generic_state_cache) {
+		/* Delete one cached state object */
+
+		next = acpi_gbl_generic_state_cache->common.next;
+		acpi_ut_free (acpi_gbl_generic_state_cache);
+		acpi_gbl_generic_state_cache = next;
+		acpi_gbl_generic_state_cache_depth--;
+	}
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_resolve_package_references
+ *
+ * PARAMETERS:  Obj_desc        - The Package object on which to resolve refs
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Walk through a package and turn internal references into values
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_resolve_package_references (
+	ACPI_OPERAND_OBJECT     *obj_desc)
+{
+	u32                     count;
+	ACPI_OPERAND_OBJECT     *sub_object;
+
+
+	if (obj_desc->common.type != ACPI_TYPE_PACKAGE) {
+		/* The object must be a package */
+
+		REPORT_ERROR (("Must resolve Package Refs on a Package\n"));
+		return(AE_ERROR);
+	}
+
+	/*
+	 * TBD: what about nested packages? */
+
+	for (count = 0; count < obj_desc->package.count; count++) {
+		sub_object = obj_desc->package.elements[count];
+
+		if (sub_object->common.type == INTERNAL_TYPE_REFERENCE) {
+			if (sub_object->reference.opcode == AML_ZERO_OP) {
+				sub_object->common.type = ACPI_TYPE_INTEGER;
+				sub_object->integer.value = 0;
+			}
+
+			else if (sub_object->reference.opcode == AML_ONE_OP) {
+				sub_object->common.type = ACPI_TYPE_INTEGER;
+				sub_object->integer.value = 1;
+			}
+
+			else if (sub_object->reference.opcode == AML_ONES_OP) {
+				sub_object->common.type = ACPI_TYPE_INTEGER;
+				sub_object->integer.value = ACPI_INTEGER_MAX;
+			}
+		}
+	}
+
+	return(AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_walk_package_tree
+ *
+ * PARAMETERS:  Obj_desc        - The Package object on which to resolve refs
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Walk through a package
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_walk_package_tree (
+	ACPI_OPERAND_OBJECT     *source_object,
+	void                    *target_object,
+	ACPI_PKG_CALLBACK       walk_callback,
+	void                    *context)
+{
+	ACPI_STATUS             status = AE_OK;
+	ACPI_GENERIC_STATE      *state_list = NULL;
+	ACPI_GENERIC_STATE      *state;
+	u32                     this_index;
+	ACPI_OPERAND_OBJECT     *this_source_obj;
+
+
+	state = acpi_ut_create_pkg_state (source_object, target_object, 0);
+	if (!state) {
+		return (AE_NO_MEMORY);
+	}
+
+	while (state) {
+		this_index    = state->pkg.index;
+		this_source_obj = (ACPI_OPERAND_OBJECT *)
+				  state->pkg.source_object->package.elements[this_index];
+
+		/*
+		 * Check for
+		 * 1) An uninitialized package element.  It is completely
+		 *      legal to declare a package and leave it uninitialized
+		 * 2) Not an internal object - can be a namespace node instead
+		 * 3) Any type other than a package.  Packages are handled in else
+		 *      case below.
+		 */
+		if ((!this_source_obj) ||
+			(!VALID_DESCRIPTOR_TYPE (
+					this_source_obj, ACPI_DESC_TYPE_INTERNAL)) ||
+			(!IS_THIS_OBJECT_TYPE (
+					this_source_obj, ACPI_TYPE_PACKAGE))) {
+
+			status = walk_callback (ACPI_COPY_TYPE_SIMPLE, this_source_obj,
+					 state, context);
+			if (ACPI_FAILURE (status)) {
+				/* TBD: must delete package created up to this point */
+
+				return (status);
+			}
+
+			state->pkg.index++;
+			while (state->pkg.index >= state->pkg.source_object->package.count) {
+				/*
+				 * We've handled all of the objects at this level,  This means
+				 * that we have just completed a package.  That package may
+				 * have contained one or more packages itself.
+				 *
+				 * Delete this state and pop the previous state (package).
+				 */
+				acpi_ut_delete_generic_state (state);
+				state = acpi_ut_pop_generic_state (&state_list);
+
+
+				/* Finished when there are no more states */
+
+				if (!state) {
+					/*
+					 * We have handled all of the objects in the top level
+					 * package just add the length of the package objects
+					 * and exit
+					 */
+					return (AE_OK);
+				}
+
+				/*
+				 * Go back up a level and move the index past the just
+				 * completed package object.
+				 */
+				state->pkg.index++;
+			}
+		}
+
+		else {
+			/* This is a sub-object of type package */
+
+			status = walk_callback (ACPI_COPY_TYPE_PACKAGE, this_source_obj,
+					  state, context);
+			if (ACPI_FAILURE (status)) {
+				/* TBD: must delete package created up to this point */
+
+				return (status);
+			}
+
+
+			/*
+			 * The callback above returned a new target package object.
+			 */
+
+			/*
+			 * Push the current state and create a new one
+			 */
+			acpi_ut_push_generic_state (&state_list, state);
+			state = acpi_ut_create_pkg_state (this_source_obj,
+					   state->pkg.this_target_obj, 0);
+			if (!state) {
+				/* TBD: must delete package created up to this point */
+
+				return (AE_NO_MEMORY);
+			}
+		}
+	}
+
+	/* We should never get here */
+
+	return (AE_AML_INTERNAL);
+
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    _Report_error
+ *
+ * PARAMETERS:  Module_name         - Caller's module name (for error output)
+ *              Line_number         - Caller's line number (for error output)
+ *              Component_id        - Caller's component ID (for error output)
+ *              Message             - Error message to use on failure
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print error message
+ *
+ ******************************************************************************/
+
+void
+_report_error (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id)
+{
+
+
+	acpi_os_printf ("%8s-%04d: *** Error: ", module_name, line_number);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    _Report_warning
+ *
+ * PARAMETERS:  Module_name         - Caller's module name (for error output)
+ *              Line_number         - Caller's line number (for error output)
+ *              Component_id        - Caller's component ID (for error output)
+ *              Message             - Error message to use on failure
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print warning message
+ *
+ ******************************************************************************/
+
+void
+_report_warning (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id)
+{
+
+	acpi_os_printf ("%8s-%04d: *** Warning: ", module_name, line_number);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    _Report_info
+ *
+ * PARAMETERS:  Module_name         - Caller's module name (for error output)
+ *              Line_number         - Caller's line number (for error output)
+ *              Component_id        - Caller's component ID (for error output)
+ *              Message             - Error message to use on failure
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print information message
+ *
+ ******************************************************************************/
+
+void
+_report_info (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id)
+{
+
+	acpi_os_printf ("%8s-%04d: *** Info: ", module_name, line_number);
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/utilities/utobject.c linux/drivers/acpi/utilities/utobject.c
--- v2.4.5/linux/drivers/acpi/utilities/utobject.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/utilities/utobject.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,625 @@
+/******************************************************************************
+ *
+ * Module Name: utobject - ACPI object create/delete/size/cache routines
+ *              $Revision: 46 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acinterp.h"
+#include "acnamesp.h"
+#include "actables.h"
+#include "amlcode.h"
+
+
+#define _COMPONENT          ACPI_UTILITIES
+	 MODULE_NAME         ("utobject")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    _Ut_create_internal_object
+ *
+ * PARAMETERS:  Address             - Address of the memory to deallocate
+ *              Component           - Component type of caller
+ *              Module              - Source file name of caller
+ *              Line                - Line number of caller
+ *              Type                - ACPI Type of the new object
+ *
+ * RETURN:      Object              - The new object.  Null on failure
+ *
+ * DESCRIPTION: Create and initialize a new internal object.
+ *
+ * NOTE:        We always allocate the worst-case object descriptor because
+ *              these objects are cached, and we want them to be
+ *              one-size-satisifies-any-request.  This in itself may not be
+ *              the most memory efficient, but the efficiency of the object
+ *              cache should more than make up for this!
+ *
+ ******************************************************************************/
+
+ACPI_OPERAND_OBJECT  *
+_ut_create_internal_object (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	ACPI_OBJECT_TYPE8       type)
+{
+	ACPI_OPERAND_OBJECT     *object;
+
+
+	/* Allocate the raw object descriptor */
+
+	object = _ut_allocate_object_desc (module_name, line_number, component_id);
+	if (!object) {
+		/* Allocation failure */
+
+		return (NULL);
+	}
+
+	/* Save the object type in the object descriptor */
+
+	object->common.type = type;
+
+	/* Init the reference count */
+
+	object->common.reference_count = 1;
+
+	/* Any per-type initialization should go here */
+
+
+	return (object);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_valid_internal_object
+ *
+ * PARAMETERS:  Operand             - Object to be validated
+ *
+ * RETURN:      Validate a pointer to be an ACPI_OPERAND_OBJECT
+ *
+ ******************************************************************************/
+
+u8
+acpi_ut_valid_internal_object (
+	void                    *object)
+{
+
+	PROC_NAME ("Ut_valid_internal_object");
+
+
+	/* Check for a null pointer */
+
+	if (!object) {
+		return (FALSE);
+	}
+
+	/* Check for a pointer within one of the ACPI tables */
+
+	if (acpi_tb_system_table_pointer (object)) {
+		return (FALSE);
+	}
+
+	/* Check the descriptor type field */
+
+	if (!VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_INTERNAL)) {
+		/* Not an ACPI internal object, do some further checking */
+
+
+
+
+		return (FALSE);
+	}
+
+
+	/* The object appears to be a valid ACPI_OPERAND_OBJECT  */
+
+	return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    _Ut_allocate_object_desc
+ *
+ * PARAMETERS:  Module_name         - Caller's module name (for error output)
+ *              Line_number         - Caller's line number (for error output)
+ *              Component_id        - Caller's component ID (for error output)
+ *              Message             - Error message to use on failure
+ *
+ * RETURN:      Pointer to newly allocated object descriptor.  Null on error
+ *
+ * DESCRIPTION: Allocate a new object descriptor.  Gracefully handle
+ *              error conditions.
+ *
+ ******************************************************************************/
+
+void *
+_ut_allocate_object_desc (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id)
+{
+	ACPI_OPERAND_OBJECT     *object;
+
+
+	acpi_ut_acquire_mutex (ACPI_MTX_CACHES);
+
+	acpi_gbl_object_cache_requests++;
+
+	/* Check the cache first */
+
+	if (acpi_gbl_object_cache) {
+		/* There is an object available, use it */
+
+		object = acpi_gbl_object_cache;
+		acpi_gbl_object_cache = object->cache.next;
+		object->cache.next = NULL;
+
+		acpi_gbl_object_cache_hits++;
+		acpi_gbl_object_cache_depth--;
+
+		acpi_ut_release_mutex (ACPI_MTX_CACHES);
+	}
+
+	else {
+		/* The cache is empty, create a new object */
+
+		acpi_ut_release_mutex (ACPI_MTX_CACHES);
+
+		/* Attempt to allocate new descriptor */
+
+		object = _ut_callocate (sizeof (ACPI_OPERAND_OBJECT), component_id,
+				  module_name, line_number);
+		if (!object) {
+			/* Allocation failed */
+
+			_REPORT_ERROR (module_name, line_number, component_id,
+					  ("Could not allocate an object descriptor\n"));
+
+			return (NULL);
+		}
+
+		/* Memory allocation metrics - compiled out in non debug mode. */
+
+		INCREMENT_OBJECT_METRICS (sizeof (ACPI_OPERAND_OBJECT));
+	}
+
+	/* Mark the descriptor type */
+
+	object->common.data_type = ACPI_DESC_TYPE_INTERNAL;
+
+	return (object);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_delete_object_desc
+ *
+ * PARAMETERS:  Object          - Acpi internal object to be deleted
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Free an ACPI object descriptor or add it to the object cache
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_delete_object_desc (
+	ACPI_OPERAND_OBJECT     *object)
+{
+
+
+	/* Make sure that the object isn't already in the cache */
+
+	if (object->common.data_type == (ACPI_DESC_TYPE_INTERNAL | ACPI_CACHED_OBJECT)) {
+		return;
+	}
+
+	/* Object must be an ACPI_OPERAND_OBJECT  */
+
+	if (object->common.data_type != ACPI_DESC_TYPE_INTERNAL) {
+		return;
+	}
+
+
+	/* If cache is full, just free this object */
+
+	if (acpi_gbl_object_cache_depth >= MAX_OBJECT_CACHE_DEPTH) {
+		/*
+		 * Memory allocation metrics.  Call the macro here since we only
+		 * care about dynamically allocated objects.
+		 */
+		DECREMENT_OBJECT_METRICS (sizeof (ACPI_OPERAND_OBJECT));
+
+		acpi_ut_free (object);
+		return;
+	}
+
+	acpi_ut_acquire_mutex (ACPI_MTX_CACHES);
+
+	/* Clear the entire object.  This is important! */
+
+	MEMSET (object, 0, sizeof (ACPI_OPERAND_OBJECT));
+	object->common.data_type = ACPI_DESC_TYPE_INTERNAL | ACPI_CACHED_OBJECT;
+
+	/* Put the object at the head of the global cache list */
+
+	object->cache.next = acpi_gbl_object_cache;
+	acpi_gbl_object_cache = object;
+	acpi_gbl_object_cache_depth++;
+
+
+	acpi_ut_release_mutex (ACPI_MTX_CACHES);
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_delete_object_cache
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Purge the global state object cache.  Used during subsystem
+ *              termination.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_delete_object_cache (
+	void)
+{
+	ACPI_OPERAND_OBJECT     *next;
+
+
+	/* Traverse the global cache list */
+
+	while (acpi_gbl_object_cache) {
+		/* Delete one cached state object */
+
+		next = acpi_gbl_object_cache->cache.next;
+		acpi_gbl_object_cache->cache.next = NULL;
+
+		/*
+		 * Memory allocation metrics.  Call the macro here since we only
+		 * care about dynamically allocated objects.
+		 */
+		DECREMENT_OBJECT_METRICS (sizeof (ACPI_OPERAND_OBJECT));
+
+		acpi_ut_free (acpi_gbl_object_cache);
+		acpi_gbl_object_cache = next;
+		acpi_gbl_object_cache_depth--;
+	}
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_init_static_object
+ *
+ * PARAMETERS:  Obj_desc            - Pointer to a "static" object - on stack
+ *                                    or in the data segment.
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Initialize a static object.  Sets flags to disallow dynamic
+ *              deletion of the object.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_init_static_object (
+	ACPI_OPERAND_OBJECT     *obj_desc)
+{
+
+
+	if (!obj_desc) {
+		return;
+	}
+
+
+	/*
+	 * Clear the entire descriptor
+	 */
+	MEMSET ((void *) obj_desc, 0, sizeof (ACPI_OPERAND_OBJECT));
+
+
+	/*
+	 * Initialize the header fields
+	 * 1) This is an ACPI_OPERAND_OBJECT  descriptor
+	 * 2) The size is the full object (worst case)
+	 * 3) The flags field indicates static allocation
+	 * 4) Reference count starts at one (not really necessary since the
+	 *    object can't be deleted, but keeps everything sane)
+	 */
+
+	obj_desc->common.data_type      = ACPI_DESC_TYPE_INTERNAL;
+	obj_desc->common.flags          = AOPOBJ_STATIC_ALLOCATION;
+	obj_desc->common.reference_count = 1;
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_get_simple_object_size
+ *
+ * PARAMETERS:  *Internal_object    - Pointer to the object we are examining
+ *              *Ret_length         - Where the length is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to determine the space required to
+ *              contain a simple object for return to an API user.
+ *
+ *              The length includes the object structure plus any additional
+ *              needed space.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_get_simple_object_size (
+	ACPI_OPERAND_OBJECT     *internal_object,
+	u32                     *obj_length)
+{
+	u32                     length;
+	ACPI_STATUS             status = AE_OK;
+
+
+	/* Handle a null object (Could be a uninitialized package element -- which is legal) */
+
+	if (!internal_object) {
+		*obj_length = 0;
+		return (AE_OK);
+	}
+
+
+	/* Start with the length of the Acpi object */
+
+	length = sizeof (ACPI_OBJECT);
+
+	if (VALID_DESCRIPTOR_TYPE (internal_object, ACPI_DESC_TYPE_NAMED)) {
+		/* Object is a named object (reference), just return the length */
+
+		*obj_length = (u32) ROUND_UP_TO_NATIVE_WORD (length);
+		return (status);
+	}
+
+
+	/*
+	 * The final length depends on the object type
+	 * Strings and Buffers are packed right up against the parent object and
+	 * must be accessed bytewise or there may be alignment problems on
+	 * certain processors
+	 */
+
+	switch (internal_object->common.type) {
+
+	case ACPI_TYPE_STRING:
+
+		length += internal_object->string.length + 1;
+		break;
+
+
+	case ACPI_TYPE_BUFFER:
+
+		length += internal_object->buffer.length;
+		break;
+
+
+	case ACPI_TYPE_INTEGER:
+	case ACPI_TYPE_PROCESSOR:
+	case ACPI_TYPE_POWER:
+
+		/*
+		 * No extra data for these types
+		 */
+		break;
+
+
+	case INTERNAL_TYPE_REFERENCE:
+
+		/*
+		 * The only type that should be here is internal opcode NAMEPATH_OP -- since
+		 * this means an object reference
+		 */
+		if (internal_object->reference.opcode != AML_INT_NAMEPATH_OP) {
+			status = AE_TYPE;
+		}
+
+		else {
+			/*
+			 * Get the actual length of the full pathname to this object.
+			 * The reference will be converted to the pathname to the object
+			 */
+			length += ROUND_UP_TO_NATIVE_WORD (acpi_ns_get_pathname_length (internal_object->reference.node));
+		}
+		break;
+
+
+	default:
+
+		status = AE_TYPE;
+		break;
+	}
+
+
+	/*
+	 * Account for the space required by the object rounded up to the next
+	 * multiple of the machine word size.  This keeps each object aligned
+	 * on a machine word boundary. (preventing alignment faults on some
+	 * machines.)
+	 */
+	*obj_length = (u32) ROUND_UP_TO_NATIVE_WORD (length);
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_get_element_length
+ *
+ * PARAMETERS:  ACPI_PKG_CALLBACK
+ *
+ * RETURN:      Status          - the status of the call
+ *
+ * DESCRIPTION: Get the length of one package element.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_get_element_length (
+	u8                      object_type,
+	ACPI_OPERAND_OBJECT     *source_object,
+	ACPI_GENERIC_STATE      *state,
+	void                    *context)
+{
+	ACPI_STATUS             status = AE_OK;
+	ACPI_PKG_INFO           *info = (ACPI_PKG_INFO *) context;
+	u32                     object_space;
+
+
+	switch (object_type) {
+	case 0:
+
+		/*
+		 * Simple object - just get the size (Null object/entry is handled
+		 * here also) and sum it into the running package length
+		 */
+		status = acpi_ut_get_simple_object_size (source_object, &object_space);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+
+		info->length += object_space;
+		break;
+
+
+	case 1:
+		/* Package - nothing much to do here, let the walk handle it */
+
+		info->num_packages++;
+		state->pkg.this_target_obj = NULL;
+		break;
+
+	default:
+		return (AE_BAD_PARAMETER);
+	}
+
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_get_package_object_size
+ *
+ * PARAMETERS:  *Internal_object    - Pointer to the object we are examining
+ *              *Ret_length         - Where the length is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to determine the space required to
+ *              contain a package object for return to an API user.
+ *
+ *              This is moderately complex since a package contains other
+ *              objects including packages.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_get_package_object_size (
+	ACPI_OPERAND_OBJECT     *internal_object,
+	u32                     *obj_length)
+{
+	ACPI_STATUS             status;
+	ACPI_PKG_INFO           info;
+
+
+	info.length      = 0;
+	info.object_space = 0;
+	info.num_packages = 1;
+
+	status = acpi_ut_walk_package_tree (internal_object, NULL,
+			 acpi_ut_get_element_length, &info);
+
+	/*
+	 * We have handled all of the objects in all levels of the package.
+	 * just add the length of the package objects themselves.
+	 * Round up to the next machine word.
+	 */
+	info.length += ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)) *
+			  info.num_packages;
+
+	/* Return the total package length */
+
+	*obj_length = info.length;
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_get_object_size
+ *
+ * PARAMETERS:  *Internal_object    - Pointer to the object we are examining
+ *              *Ret_length         - Where the length will be returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to determine the space required to
+ *              contain an object for return to an API user.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_ut_get_object_size(
+	ACPI_OPERAND_OBJECT     *internal_object,
+	u32                     *obj_length)
+{
+	ACPI_STATUS             status;
+
+
+	if ((VALID_DESCRIPTOR_TYPE (internal_object, ACPI_DESC_TYPE_INTERNAL)) &&
+		(IS_THIS_OBJECT_TYPE (internal_object, ACPI_TYPE_PACKAGE))) {
+		status = acpi_ut_get_package_object_size (internal_object, obj_length);
+	}
+
+	else {
+		status = acpi_ut_get_simple_object_size (internal_object, obj_length);
+	}
+
+	return (status);
+}
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/utilities/utxface.c linux/drivers/acpi/utilities/utxface.c
--- v2.4.5/linux/drivers/acpi/utilities/utxface.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/utilities/utxface.c	Wed Jun 20 17:47:40 2001
@@ -0,0 +1,476 @@
+/******************************************************************************
+ *
+ * Module Name: utxface - External interfaces for "global" ACPI functions
+ *              $Revision: 72 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acevents.h"
+#include "achware.h"
+#include "acnamesp.h"
+#include "acinterp.h"
+#include "amlcode.h"
+#include "acdebug.h"
+
+
+#define _COMPONENT          ACPI_UTILITIES
+	 MODULE_NAME         ("utxface")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_initialize_subsystem
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initializes all global variables.  This is the first function
+ *              called, so any early initialization belongs here.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_initialize_subsystem (
+	void)
+{
+	ACPI_STATUS             status;
+
+
+	/* Initialize all globals used by the subsystem */
+
+	acpi_ut_init_globals ();
+
+	/* Initialize the OS-Dependent layer */
+
+	status = acpi_os_initialize ();
+	if (ACPI_FAILURE (status)) {
+		REPORT_ERROR (("OSD failed to initialize, %s\n",
+			acpi_ut_format_exception (status)));
+		return (status);
+	}
+
+	/* Create the default mutex objects */
+
+	status = acpi_ut_mutex_initialize ();
+	if (ACPI_FAILURE (status)) {
+		REPORT_ERROR (("Global mutex creation failure, %s\n",
+			acpi_ut_format_exception (status)));
+		return (status);
+	}
+
+	/*
+	 * Initialize the namespace manager and
+	 * the root of the namespace tree
+	 */
+
+	status = acpi_ns_root_initialize ();
+	if (ACPI_FAILURE (status)) {
+		REPORT_ERROR (("Namespace initialization failure, %s\n",
+			acpi_ut_format_exception (status)));
+		return (status);
+	}
+
+
+	/* If configured, initialize the AML debugger */
+
+	DEBUGGER_EXEC (acpi_db_initialize ());
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_enable_subsystem
+ *
+ * PARAMETERS:  Flags           - Init/enable Options
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Completes the subsystem initialization including hardware.
+ *              Puts system into ACPI mode if it isn't already.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_enable_subsystem (
+	u32                     flags)
+{
+	ACPI_STATUS             status = AE_OK;
+
+
+	/* Sanity check the FADT for valid values */
+
+	status = acpi_ut_validate_fadt ();
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/*
+	 * Install the default Op_region handlers. These are
+	 * installed unless other handlers have already been
+	 * installed via the Install_address_space_handler interface
+	 */
+
+	if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
+		status = acpi_ev_install_default_address_space_handlers ();
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+	}
+
+	/*
+	 * We must initialize the hardware before we can enable ACPI.
+	 */
+
+	if (!(flags & ACPI_NO_HARDWARE_INIT)) {
+		status = acpi_hw_initialize ();
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+	}
+
+	/*
+	 * Enable ACPI on this platform
+	 */
+
+	if (!(flags & ACPI_NO_ACPI_ENABLE)) {
+		status = acpi_enable ();
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+	}
+
+	/*
+	 * Note:
+	 * We must have the hardware AND events initialized before we can execute
+	 * ANY control methods SAFELY.  Any control method can require ACPI hardware
+	 * support, so the hardware MUST be initialized before execution!
+	 */
+
+	if (!(flags & ACPI_NO_EVENT_INIT)) {
+		status = acpi_ev_initialize ();
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+	}
+
+
+	/*
+	 * Initialize all device objects in the namespace
+	 * This runs the _STA and _INI methods.
+	 */
+
+	if (!(flags & ACPI_NO_DEVICE_INIT)) {
+		status = acpi_ns_initialize_devices ();
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+	}
+
+
+	/*
+	 * Initialize the objects that remain uninitialized.  This
+	 * runs the executable AML that is part of the declaration of Op_regions
+	 * and Fields.
+	 */
+
+	if (!(flags & ACPI_NO_OBJECT_INIT)) {
+		status = acpi_ns_initialize_objects ();
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+	}
+
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_terminate
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Shutdown the ACPI subsystem.  Release all resources.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_terminate (void)
+{
+	ACPI_STATUS             status;
+
+
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/* Terminate the AML Debugger if present */
+
+	DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE);
+
+	/* TBD: [Investigate] This is no longer needed?*/
+/*    Acpi_ut_release_mutex (ACPI_MTX_DEBUG_CMD_READY); */
+
+
+	/* Shutdown and free all resources */
+
+	acpi_ut_subsystem_shutdown ();
+
+
+	/* Free the mutex objects */
+
+	acpi_ut_mutex_terminate ();
+
+
+	/* Now we can shutdown the OS-dependent layer */
+
+	acpi_os_terminate ();
+
+	return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    Acpi_get_system_info
+ *
+ * PARAMETERS:  Out_buffer      - a pointer to a buffer to receive the
+ *                                resources for the device
+ *              Buffer_length   - the number of bytes available in the buffer
+ *
+ * RETURN:      Status          - the status of the call
+ *
+ * DESCRIPTION: This function is called to get information about the current
+ *              state of the ACPI subsystem.  It will return system information
+ *              in the Out_buffer.
+ *
+ *              If the function fails an appropriate status will be returned
+ *              and the value of Out_buffer is undefined.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_get_system_info (
+	ACPI_BUFFER             *out_buffer)
+{
+	ACPI_SYSTEM_INFO        *info_ptr;
+	u32                     i;
+	ACPI_STATUS             status;
+
+
+	/* Ensure that ACPI has been initialized */
+
+	ACPI_IS_INITIALIZATION_COMPLETE (status);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/*
+	 *  Must have a valid buffer
+	 */
+	if ((!out_buffer)         ||
+		(!out_buffer->pointer)) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	if (out_buffer->length < sizeof (ACPI_SYSTEM_INFO)) {
+		/*
+		 *  Caller's buffer is too small
+		 */
+		out_buffer->length = sizeof (ACPI_SYSTEM_INFO);
+
+		return (AE_BUFFER_OVERFLOW);
+	}
+
+
+	/*
+	 *  Set return length and get data
+	 */
+	out_buffer->length = sizeof (ACPI_SYSTEM_INFO);
+	info_ptr = (ACPI_SYSTEM_INFO *) out_buffer->pointer;
+
+	info_ptr->acpi_ca_version   = ACPI_CA_VERSION;
+
+	/* System flags (ACPI capabilities) */
+
+	info_ptr->flags             = acpi_gbl_system_flags;
+
+	/* Timer resolution - 24 or 32 bits  */
+	if (!acpi_gbl_FADT) {
+		info_ptr->timer_resolution = 0;
+	}
+	else if (acpi_gbl_FADT->tmr_val_ext == 0) {
+		info_ptr->timer_resolution = 24;
+	}
+	else {
+		info_ptr->timer_resolution = 32;
+	}
+
+	/* Clear the reserved fields */
+
+	info_ptr->reserved1         = 0;
+	info_ptr->reserved2         = 0;
+
+	/* Current debug levels */
+
+	info_ptr->debug_layer       = acpi_dbg_layer;
+	info_ptr->debug_level       = acpi_dbg_level;
+
+	/* Current status of the ACPI tables, per table type */
+
+	info_ptr->num_table_types = NUM_ACPI_TABLES;
+	for (i = 0; i < NUM_ACPI_TABLES; i++) {
+		info_ptr->table_info[i].count = acpi_gbl_acpi_tables[i].count;
+	}
+
+	return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    Acpi_format_exception
+ *
+ * PARAMETERS:  Out_buffer      - a pointer to a buffer to receive the
+ *                                exception name
+ *
+ * RETURN:      Status          - the status of the call
+ *
+ * DESCRIPTION: This function translates an ACPI exception into an ASCII string.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_format_exception (
+	ACPI_STATUS             exception,
+	ACPI_BUFFER             *out_buffer)
+{
+	u32                     length;
+	NATIVE_CHAR             *formatted_exception;
+
+
+	/*
+	 *  Must have a valid buffer
+	 */
+	if ((!out_buffer)         ||
+		(!out_buffer->pointer)) {
+		return (AE_BAD_PARAMETER);
+	}
+
+
+	/* Convert the exception code (Handles bad exception codes) */
+
+	formatted_exception = acpi_ut_format_exception (exception);
+
+	/*
+	 * Get length of string and check if it will fit in caller's buffer
+	 */
+
+	length = STRLEN (formatted_exception);
+	if (out_buffer->length < length) {
+		out_buffer->length = length;
+		return (AE_BUFFER_OVERFLOW);
+	}
+
+
+	/* Copy the string, all done */
+
+	STRCPY (out_buffer->pointer, formatted_exception);
+
+	return (AE_OK);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_allocate
+ *
+ * PARAMETERS:  Size                - Size of the allocation
+ *
+ * RETURN:      Address of the allocated memory on success, NULL on failure.
+ *
+ * DESCRIPTION: The subsystem's equivalent of malloc.
+ *              External front-end to the Ut* memory manager
+ *
+ ****************************************************************************/
+
+void *
+acpi_allocate (
+	u32                     size)
+{
+
+	return (acpi_ut_allocate (size));
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_callocate
+ *
+ * PARAMETERS:  Size                - Size of the allocation
+ *
+ * RETURN:      Address of the allocated memory on success, NULL on failure.
+ *
+ * DESCRIPTION: The subsystem's equivalent of calloc.
+ *              External front-end to the Ut* memory manager
+ *
+ ****************************************************************************/
+
+void *
+acpi_callocate (
+	u32                     size)
+{
+
+	return (acpi_ut_callocate (size));
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_free
+ *
+ * PARAMETERS:  Address             - Address of the memory to deallocate
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Frees the memory at Address
+ *              External front-end to the Ut* memory manager
+ *
+ ****************************************************************************/
+
+void
+acpi_free (
+	void                    *address)
+{
+
+	acpi_ut_free (address);
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/atm/ambassador.c linux/drivers/atm/ambassador.c
--- v2.4.5/linux/drivers/atm/ambassador.c	Fri Dec 29 14:35:47 2000
+++ linux/drivers/atm/ambassador.c	Wed Jun 27 16:18:13 2001
@@ -613,19 +613,21 @@
     while (timeout) {
       // go to sleep
       // PRINTD (DBG_CMD, "wait: sleeping %lu for command", timeout);
+      set_current_state(TASK_UNINTERRUPTIBLE);
       timeout = schedule_timeout (timeout);
-      // woken up by timeout or signal
     }
     
     // wait for my slot to be reached (all waiters are here or above, until...)
     while (ptrs->out != my_slot) {
       PRINTD (DBG_CMD, "wait: command slot (now at %p)", ptrs->out);
+      set_current_state(TASK_UNINTERRUPTIBLE);
       schedule();
     }
     
     // wait on my slot (... one gets to its slot, and... )
     while (ptrs->out->request != cpu_to_be32 (SRB_COMPLETE)) {
       PRINTD (DBG_CMD, "wait: command slot completion");
+      set_current_state(TASK_UNINTERRUPTIBLE);
       schedule();
     }
     
@@ -1986,6 +1988,7 @@
   
   while (!lb->result || lb->result == cpu_to_be32 (COMMAND_IN_PROGRESS))
     if (timeout) {
+      set_current_state(TASK_UNINTERRUPTIBLE);
       timeout = schedule_timeout (timeout);
     } else {
       PRINTD (DBG_LOAD|DBG_ERR, "command %d timed out", cmd);
@@ -2110,12 +2113,15 @@
     unsigned long timeout;
     // 4.2 second wait
     timeout = HZ*42/10;
-    while (timeout)
+    while (timeout) {
+      set_current_state(TASK_UNINTERRUPTIBLE);
       timeout = schedule_timeout (timeout);
+    }
     // half second time-out
     timeout = HZ/2;
     while (!rd_plain (dev, offsetof(amb_mem, mb.loader.ready)))
       if (timeout) {
+        set_current_state(TASK_UNINTERRUPTIBLE);
 	timeout = schedule_timeout (timeout);
       } else {
 	PRINTD (DBG_LOAD|DBG_ERR, "reset timed out");
@@ -2255,8 +2261,10 @@
   u32 minor;
   command cmd;
   cmd.request = cpu_to_be32 (SRB_GET_VERSION);
-  while (command_do (dev, &cmd))
+  while (command_do (dev, &cmd)) {
+    set_current_state(TASK_UNINTERRUPTIBLE);
     schedule();
+  }
   major = be32_to_cpu (cmd.args.version.major);
   minor = be32_to_cpu (cmd.args.version.minor);
   PRINTK (KERN_INFO, "microcode version is %u.%u", major, minor);
@@ -2280,8 +2288,10 @@
   }
   
   cmd.request = cpu_to_be32 (SRB_GET_BIA);
-  while (command_do (dev, &cmd))
+  while (command_do (dev, &cmd)) {
+    set_current_state(TASK_UNINTERRUPTIBLE);
     schedule();
+  }
   lower4 = be32_to_cpu (cmd.args.bia.lower4);
   upper2 = be32_to_cpu (cmd.args.bia.upper2);
   PRINTD (DBG_LOAD, "BIA: lower4: %08x, upper2 %04x", lower4, upper2);
@@ -2362,7 +2372,7 @@
   struct pci_dev * pci_dev;
   int devs;
   
-  void do_pci_device (void) {
+  void __init do_pci_device (void) {
     amb_dev * dev;
     
     // read resources from PCI configuration space
diff -u --recursive --new-file v2.4.5/linux/drivers/atm/fore200e.c linux/drivers/atm/fore200e.c
--- v2.4.5/linux/drivers/atm/fore200e.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/atm/fore200e.c	Wed Jun 27 16:18:13 2001
@@ -439,6 +439,7 @@
 
     case FORE200E_STATE_BLANK:
 	/* nothing to do for that state */
+	break;
     }
 }
 
@@ -2023,8 +2024,10 @@
     if (!prom)
 	return -ENOMEM;
     ok = fore200e->bus->prom_read(fore200e, prom);
-    if (ok < 0)
+    if (ok < 0) {
+	fore200e_kfree(prom);
 	return -EBUSY;
+    }
 	
     printk(FORE200E "device %s, rev. %c, S/N: %d, ESI: %02x:%02x:%02x:%02x:%02x:%02x\n", 
 	   fore200e->name, 
diff -u --recursive --new-file v2.4.5/linux/drivers/atm/fore200e_mkfirm.c linux/drivers/atm/fore200e_mkfirm.c
--- v2.4.5/linux/drivers/atm/fore200e_mkfirm.c	Mon Feb 21 16:32:27 2000
+++ linux/drivers/atm/fore200e_mkfirm.c	Wed Jun 20 11:10:27 2001
@@ -10,8 +10,9 @@
 */
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <sys/types.h>
-#include <sys/time.h>
+#include <time.h>
 
 char* default_basename = "pca200e"; /* was initially written for the PCA-200E firmware */
 char* default_infname  = "<stdin>";
diff -u --recursive --new-file v2.4.5/linux/drivers/atm/idt77105.c linux/drivers/atm/idt77105.c
--- v2.4.5/linux/drivers/atm/idt77105.c	Thu Jul  6 21:37:24 2000
+++ linux/drivers/atm/idt77105.c	Wed Jun 27 16:18:13 2001
@@ -144,18 +144,18 @@
 static int fetch_stats(struct atm_dev *dev,struct idt77105_stats *arg,int zero)
 {
 	unsigned long flags;
-	int error;
+	struct idt77105_stats stats;
 
-	error = 0;
 	save_flags(flags);
 	cli();
-	if (arg)
-		error = copy_to_user(arg,&PRIV(dev)->stats,
-		    sizeof(struct idt77105_stats));
-	if (zero && !error)
-		memset(&PRIV(dev)->stats,0,sizeof(struct idt77105_stats));
+	memcpy(&stats, &PRIV(dev)->stats, sizeof(struct idt77105_stats));
+	if (zero)
+		memset(&PRIV(dev)->stats, 0, sizeof(struct idt77105_stats));
 	restore_flags(flags);
-	return error ? -EFAULT : sizeof(struct idt77105_stats);
+	if (arg == NULL)
+		return 0;
+	return copy_to_user(arg, &PRIV(dev)->stats,
+		    sizeof(struct idt77105_stats)) ? -EFAULT : 0;
 }
 
 
diff -u --recursive --new-file v2.4.5/linux/drivers/atm/iphase.c linux/drivers/atm/iphase.c
--- v2.4.5/linux/drivers/atm/iphase.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/atm/iphase.c	Wed Jun 27 14:13:01 2001
@@ -97,6 +97,10 @@
 MODULE_PARM(IADebugFlag, "i");
 #endif
 
+#if BITS_PER_LONG != 32
+#  error FIXME: this driver only works on 32-bit platforms
+#endif
+
 /**************************** IA_LIB **********************************/
 
 static void ia_init_rtn_q (IARTN_Q *que) 
diff -u --recursive --new-file v2.4.5/linux/drivers/atm/nicstar.c linux/drivers/atm/nicstar.c
--- v2.4.5/linux/drivers/atm/nicstar.c	Sun Mar 25 18:24:31 2001
+++ linux/drivers/atm/nicstar.c	Wed Jun 27 14:13:01 2001
@@ -62,6 +62,9 @@
 #include "idt77105.h"
 #endif /* CONFIG_ATM_NICSTAR_USE_IDT77105 */
 
+#if BITS_PER_LONG != 32
+#  error FIXME: this driver requires a 32-bit platform
+#endif
 
 /* Additional code ************************************************************/
 
diff -u --recursive --new-file v2.4.5/linux/drivers/atm/uPD98402.c linux/drivers/atm/uPD98402.c
--- v2.4.5/linux/drivers/atm/uPD98402.c	Fri Apr 14 09:37:10 2000
+++ linux/drivers/atm/uPD98402.c	Wed Jun 27 16:19:07 2001
@@ -86,16 +86,17 @@
 static int get_sense(struct atm_dev *dev,u8 *arg)
 {
 	unsigned long flags;
- 	int error;
+	unsigned char s[3];
 
 	save_flags(flags);
 	cli();
-	error = put_user(GET(C11R),arg) || put_user(GET(C12R),arg+1) ||
-	    put_user(GET(C13R),arg+2);
+	s[0] = GET(C11R);
+	s[1] = GET(C12R);
+	s[2] = GET(C13R);
 	restore_flags(flags);
-	error = error || put_user(0xff,arg+3) || put_user(0xff,arg+4) ||
-	    put_user(0xff,arg+5);
-	return error ? -EFAULT : 0;
+	return (put_user(s[0], arg) || put_user(s[1], arg+1) ||
+	    put_user(s[2], arg+2) || put_user(0xff, arg+3) ||
+	    put_user(0xff, arg+4) || put_user(0xff, arg+5)) ? -EFAULT : 0;
 }
 
 
diff -u --recursive --new-file v2.4.5/linux/drivers/atm/zatm.c linux/drivers/atm/zatm.c
--- v2.4.5/linux/drivers/atm/zatm.c	Wed Apr 11 19:02:30 2001
+++ linux/drivers/atm/zatm.c	Wed Jun 27 16:19:07 2001
@@ -255,9 +255,7 @@
 
 static void drain_free(struct atm_dev *dev,int pool)
 {
-	struct sk_buff *skb;
-
-	while ((skb = skb_dequeue(&ZATM_DEV(dev)->pool[pool]))) kfree_skb(skb);
+	skb_queue_purge(&ZATM_DEV(dev)->pool[pool]);
 }
 
 
@@ -1464,6 +1462,9 @@
 
 	DPRINTK("zatm_start\n");
 	zatm_dev = ZATM_DEV(dev);
+	zatm_dev->rx_map = zatm_dev->tx_map = NULL;
+	for (i = 0; i < NR_MBX; i++)
+		zatm_dev->mbx_start[i] = 0;
 	if (request_irq(zatm_dev->irq,&zatm_int,SA_SHIRQ,DEV_LABEL,dev)) {
 		printk(KERN_ERR DEV_LABEL "(itf %d): IRQ%d is already in use\n",
 		    dev->number,zatm_dev->irq);
@@ -1496,25 +1497,27 @@
 	    "%ld VCs\n",dev->number,NR_SHAPERS,pools,rx,
 	    (zatm_dev->mem-curr*4)/VC_SIZE);
 	/* create mailboxes */
-	for (i = 0; i < NR_MBX; i++) zatm_dev->mbx_start[i] = 0;
 	for (i = 0; i < NR_MBX; i++)
 		if (mbx_entries[i]) {
 			unsigned long here;
 
 			here = (unsigned long) kmalloc(2*MBX_SIZE(i),
 			    GFP_KERNEL);
-			if (!here) return -ENOMEM;
+			if (!here) {
+				error = -ENOMEM;
+				goto out;
+			}
 			if ((here^(here+MBX_SIZE(i))) & ~0xffffUL)/* paranoia */
 				here = (here & ~0xffffUL)+0x10000;
+			zatm_dev->mbx_start[i] = here;
 			if ((here^virt_to_bus((void *) here)) & 0xffff) {
 				printk(KERN_ERR DEV_LABEL "(itf %d): system "
 				    "bus incompatible with driver\n",
 				    dev->number);
-				kfree((void *) here);
-				return -ENODEV;
+				error = -ENODEV;
+				goto out;
 			}
 			DPRINTK("mbx@0x%08lx-0x%08lx\n",here,here+MBX_SIZE(i));
-			zatm_dev->mbx_start[i] = here;
 			zatm_dev->mbx_end[i] = (here+MBX_SIZE(i)) & 0xffff;
 			zout(virt_to_bus((void *) here) >> 16,MSH(i));
 			zout(virt_to_bus((void *) here),MSL(i));
@@ -1523,15 +1526,25 @@
 			zout(here & 0xffff,MWA(i));
 		}
 	error = start_tx(dev);
-	if (error) return error;
+	if (error) goto out;
 	error = start_rx(dev);
-	if (error) return error;
+	if (error) goto out;
 	error = dev->phy->start(dev);
-	if (error) return error;
+	if (error) goto out;
 	zout(0xffffffff,IMR); /* enable interrupts */
 	/* enable TX & RX */
 	zout(zin(GMR) | uPD98401_GMR_SE | uPD98401_GMR_RE,GMR);
 	return 0;
+    out:
+	for (i = 0; i < NR_MBX; i++)
+		if (zatm_dev->mbx_start[i] != 0)
+			kfree((void *) zatm_dev->mbx_start[i]);
+	if (zatm_dev->rx_map != NULL)
+		kfree(zatm_dev->rx_map);
+	if (zatm_dev->tx_map != NULL)
+		kfree(zatm_dev->tx_map);
+	free_irq(zatm_dev->irq, dev);
+	return error;
 }
 
 
@@ -1681,22 +1694,16 @@
 		case ZATM_GETTHIST:
 			{
 				int i;
-
+				struct zatm_t_hist hs[ZATM_TIMER_HISTORY_SIZE];
 				save_flags(flags);
 				cli();
-				for (i = 0; i < ZATM_TIMER_HISTORY_SIZE; i++) {
-					if (!copy_to_user(
-					    (struct zatm_t_hist *) arg+i,
-					    &zatm_dev->timer_history[
+				for (i = 0; i < ZATM_TIMER_HISTORY_SIZE; i++)
+					hs[i] = zatm_dev->timer_history[
 					    (zatm_dev->th_curr+i) &
-					    (ZATM_TIMER_HISTORY_SIZE-1)],
-					    sizeof(struct zatm_t_hist)))
-						 continue;
-					restore_flags(flags);
-					return -EFAULT;
-				}
+					    (ZATM_TIMER_HISTORY_SIZE-1)];
 				restore_flags(flags);
-				return 0;
+				return copy_to_user((struct zatm_t_hist *) arg,
+				    hs, sizeof(hs)) ? -EFAULT : 0;
 			}
 #endif
 		default:
@@ -1828,11 +1835,11 @@
 			    zatm_dev),GFP_KERNEL);
 			if (!zatm_dev) {
 				printk(KERN_EMERG "zatm.c: memory shortage\n");
-				goto out;
+				return devs;
 			}
 		}
 	}
-out:
+	kfree(zatm_dev);
 	return devs;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/block/cciss.c linux/drivers/block/cciss.c
--- v2.4.5/linux/drivers/block/cciss.c	Tue May 22 10:23:16 2001
+++ linux/drivers/block/cciss.c	Wed Jun 27 16:19:34 2001
@@ -610,7 +610,10 @@
 		{
 			/* Copy the data into the buffer we created */ 
 			if (copy_from_user(buff, iocommand.buf, iocommand.buf_size))
+			{
+				kfree(buff);
 				return -EFAULT;
+			}
 		}
 		if ((c = cmd_alloc(h , 0)) == NULL)
 		{
@@ -680,6 +683,7 @@
 			{
                         	kfree(buff);
 				cmd_free(h, c, 0);
+				return -EFAULT;
 			}
                 }
                 kfree(buff);
diff -u --recursive --new-file v2.4.5/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- v2.4.5/linux/drivers/block/ll_rw_blk.c	Thu Apr 12 12:15:52 2001
+++ linux/drivers/block/ll_rw_blk.c	Tue Jun 12 11:17:17 2001
@@ -859,30 +859,34 @@
 void generic_make_request (int rw, struct buffer_head * bh)
 {
 	int major = MAJOR(bh->b_rdev);
+	int minorsize = 0;
 	request_queue_t *q;
 
 	if (!bh->b_end_io)
 		BUG();
 
-	if (blk_size[major]) {
-		unsigned long maxsector = (blk_size[major][MINOR(bh->b_rdev)] << 1) + 1;
+	/* Test device size, when known. */
+	if (blk_size[major])
+		minorsize = blk_size[major][MINOR(bh->b_rdev)];
+	if (minorsize) {
+		unsigned long maxsector = (minorsize << 1) + 1;
 		unsigned long sector = bh->b_rsector;
 		unsigned int count = bh->b_size >> 9;
 
 		if (maxsector < count || maxsector - count < sector) {
+			/* Yecch */
 			bh->b_state &= (1 << BH_Lock) | (1 << BH_Mapped);
-			if (blk_size[major][MINOR(bh->b_rdev)]) {
-				
-				/* This may well happen - the kernel calls bread()
-				   without checking the size of the device, e.g.,
-				   when mounting a device. */
-				printk(KERN_INFO
-				       "attempt to access beyond end of device\n");
-				printk(KERN_INFO "%s: rw=%d, want=%ld, limit=%d\n",
-				       kdevname(bh->b_rdev), rw,
-				       (sector + count)>>1,
-				       blk_size[major][MINOR(bh->b_rdev)]);
-			}
+
+			/* This may well happen - the kernel calls bread()
+			   without checking the size of the device, e.g.,
+			   when mounting a device. */
+			printk(KERN_INFO
+			       "attempt to access beyond end of device\n");
+			printk(KERN_INFO "%s: rw=%d, want=%ld, limit=%d\n",
+			       kdevname(bh->b_rdev), rw,
+			       (sector + count)>>1, minorsize);
+
+			/* Yecch again */
 			bh->b_end_io(bh, 0);
 			return;
 		}
@@ -900,7 +904,8 @@
 		q = blk_get_queue(bh->b_rdev);
 		if (!q) {
 			printk(KERN_ERR
-			       "generic_make_request: Trying to access nonexistent block-device %s (%ld)\n",
+			       "generic_make_request: Trying to access "
+			       "nonexistent block-device %s (%ld)\n",
 			       kdevname(bh->b_rdev), bh->b_rsector);
 			buffer_IO_error(bh);
 			break;
diff -u --recursive --new-file v2.4.5/linux/drivers/block/loop.c linux/drivers/block/loop.c
--- v2.4.5/linux/drivers/block/loop.c	Wed Apr 11 19:05:14 2001
+++ linux/drivers/block/loop.c	Mon Jun 11 19:15:27 2001
@@ -651,8 +651,8 @@
 	inode->i_mapping->gfp_mask = GFP_BUFFER;
 
 	bs = 0;
-	if (blksize_size[MAJOR(inode->i_rdev)])
-		bs = blksize_size[MAJOR(inode->i_rdev)][MINOR(inode->i_rdev)];
+	if (blksize_size[MAJOR(lo_device)])
+		bs = blksize_size[MAJOR(lo_device)][MINOR(lo_device)];
 	if (!bs)
 		bs = BLOCK_SIZE;
 
diff -u --recursive --new-file v2.4.5/linux/drivers/block/paride/pt.c linux/drivers/block/paride/pt.c
--- v2.4.5/linux/drivers/block/paride/pt.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/block/paride/pt.c	Wed Jun 27 17:10:55 2001
@@ -753,6 +753,10 @@
 			pt_rewind(unit);
 			return 0;
 
+		    case MTWEOF:
+			pt_write_fm(unit);
+			return 0;
+
 		    default:	
 			printk("%s: Unimplemented mt_op %d\n",PT.name,
 					mtop.mt_op);
diff -u --recursive --new-file v2.4.5/linux/drivers/block/ps2esdi.c linux/drivers/block/ps2esdi.c
--- v2.4.5/linux/drivers/block/ps2esdi.c	Thu May 24 15:14:08 2001
+++ linux/drivers/block/ps2esdi.c	Wed Jun 27 17:10:55 2001
@@ -420,6 +420,7 @@
 	request_dma(dma_arb_level, "ed");
 	request_region(io_base, 4, "ed");
 	blksize_size[MAJOR_NR] = ps2esdi_blocksizes;
+	max_sectors[MAJOR_NR] = ps2esdi_maxsect;
 
 	for (i = 0; i < ps2esdi_drives; i++) {
 		register_disk(&ps2esdi_gendisk,MKDEV(MAJOR_NR,i<<6),1<<6,
diff -u --recursive --new-file v2.4.5/linux/drivers/block/swim3.c linux/drivers/block/swim3.c
--- v2.4.5/linux/drivers/block/swim3.c	Tue May 22 10:23:16 2001
+++ linux/drivers/block/swim3.c	Wed Jun 27 13:37:35 2001
@@ -33,6 +33,7 @@
 
 #define MAJOR_NR	FLOPPY_MAJOR
 #include <linux/blk.h>
+#include <linux/devfs_fs_kernel.h>
 
 static int floppy_blocksizes[2] = {512,512};
 static int floppy_sizes[2] = {2880,2880};
@@ -248,10 +249,7 @@
 int swim3_init(void);
 
 #ifndef CONFIG_PMAC_PBOOK
-static inline int check_media_bay(struct device_node *which_bay, int what)
-{
-	return 1;
-}
+#define check_media_bay(which, what)	1
 #endif
 
 static void swim3_select(struct floppy_state *fs, int sel)
@@ -1014,10 +1012,14 @@
 	revalidate:		floppy_revalidate,
 };
 
+static devfs_handle_t floppy_devfs_handle;
+
 int swim3_init(void)
 {
 	struct device_node *swim;
 
+	floppy_devfs_handle = devfs_mk_dir(NULL, "floppy", NULL);
+
 	swim = find_devices("floppy");
 	while (swim && (floppy_count < MAX_FLOPPIES))
 	{
@@ -1034,7 +1036,7 @@
 
 	if (floppy_count > 0)
 	{
-		if (register_blkdev(MAJOR_NR, "fd", &floppy_fops)) {
+		if (devfs_register_blkdev(MAJOR_NR, "fd", &floppy_fops)) {
 			printk(KERN_ERR "Unable to get major %d for floppy\n",
 			       MAJOR_NR);
 			return -EBUSY;
@@ -1051,7 +1053,9 @@
 {
 	struct device_node *mediabay;
 	struct floppy_state *fs = &floppy_states[floppy_count];
-	
+	char floppy_name[16];
+	devfs_handle_t floppy_handle;
+
 	if (swim->n_addrs < 2)
 	{
 		printk(KERN_INFO "swim3: expecting 2 addrs (n_addrs:%d, n_intrs:%d)\n",
@@ -1108,6 +1112,12 @@
 
 	printk(KERN_INFO "fd%d: SWIM3 floppy controller %s\n", floppy_count,
 		mediabay ? "in media bay" : "");
+	sprintf(floppy_name, "%s%d", floppy_devfs_handle ? "" : "floppy",
+			floppy_count);
+	floppy_handle = devfs_register(floppy_devfs_handle, floppy_name, 
+			DEVFS_FL_DEFAULT, MAJOR_NR, floppy_count, 
+			S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP |S_IWGRP, 
+			&floppy_fops, NULL);
 
 	floppy_count++;
 	
diff -u --recursive --new-file v2.4.5/linux/drivers/bluetooth/Config.in linux/drivers/bluetooth/Config.in
--- v2.4.5/linux/drivers/bluetooth/Config.in	Wed Dec 31 16:00:00 1969
+++ linux/drivers/bluetooth/Config.in	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,8 @@
+mainmenu_option next_comment
+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
+
+endmenu
diff -u --recursive --new-file v2.4.5/linux/drivers/bluetooth/Makefile linux/drivers/bluetooth/Makefile
--- v2.4.5/linux/drivers/bluetooth/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/bluetooth/Makefile	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,11 @@
+#
+# Makefile for Bluetooth HCI device drivers.
+#
+
+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
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/drivers/bluetooth/hci_emu.c linux/drivers/bluetooth/hci_emu.c
--- v2.4.5/linux/drivers/bluetooth/hci_emu.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/bluetooth/hci_emu.c	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,335 @@
+/* 
+   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 loff_t hci_emu_chr_lseek(struct file * file, loff_t offset, int origin)
+{
+	return -ESPIPE;
+}
+
+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:	hci_emu_chr_lseek,
+	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);
diff -u --recursive --new-file v2.4.5/linux/drivers/bluetooth/hci_uart.c linux/drivers/bluetooth/hci_uart.c
--- v2.4.5/linux/drivers/bluetooth/hci_uart.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/bluetooth/hci_uart.c	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,575 @@
+/* 
+   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 UART driver.
+ *
+ * $Id: hci_uart.c,v 1.1 2001/06/01 08:12:10 davem Exp $    
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/version.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/poll.h>
+
+#include <linux/malloc.h>
+#include <linux/tty.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/signal.h>
+#include <linux/ioctl.h>
+#include <linux/skbuff.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/bluez.h>
+#include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/hci_uart.h>
+
+#ifndef HCI_UART_DEBUG
+#undef  DBG
+#define DBG( A... )
+#undef  DMP
+#define DMP( A... )
+#endif
+
+/* ------- Interface to HCI layer ------ */
+/* Initialize device */
+int n_hci_open(struct hci_dev *hdev)
+{
+	DBG("%s %p", hdev->name, hdev);
+
+	/* Nothing to do for UART driver */
+
+	hdev->flags |= HCI_RUNNING;
+
+	return 0;
+}
+
+/* Reset device */
+int n_hci_flush(struct hci_dev *hdev)
+{
+	struct n_hci *n_hci  = (struct n_hci *) hdev->driver_data;
+	struct tty_struct *tty = n_hci->tty;
+
+	DBG("hdev %p tty %p", hdev, tty);
+
+	/* Drop TX queue */
+	bluez_skb_queue_purge(&n_hci->txq);
+
+	/* Flush any pending characters in the driver and discipline. */
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+
+	return 0;
+}
+
+/* Close device */
+int n_hci_close(struct hci_dev *hdev)
+{
+	DBG("hdev %p", hdev);
+
+	hdev->flags &= ~HCI_RUNNING;
+
+	n_hci_flush(hdev);
+
+	return 0;
+}
+
+int n_hci_tx_wakeup(struct n_hci *n_hci)
+{
+	register struct tty_struct *tty = n_hci->tty;
+
+	if (test_and_set_bit(TRANS_SENDING, &n_hci->tx_state)) {
+		set_bit(TRANS_WAKEUP, &n_hci->tx_state);
+		return 0;
+	}
+
+	DBG("");
+	do {
+		register struct sk_buff *skb;
+		register int len;
+
+		clear_bit(TRANS_WAKEUP, &n_hci->tx_state);
+
+		if (!(skb = skb_dequeue(&n_hci->txq)))
+			break;
+
+		DMP(skb->data, skb->len);
+
+		/* Send frame to TTY driver */
+		tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
+		len = tty->driver.write(tty, 0, skb->data, skb->len);
+
+		n_hci->hdev.stat.byte_tx += len;
+
+		DBG("sent %d", len);
+
+		if (len == skb->len) {
+			/* Full frame was sent */
+			bluez_skb_free(skb);
+		} else {
+			/* Subtract sent part and requeue  */
+			skb_pull(skb, len);
+			skb_queue_head(&n_hci->txq, skb);
+		}
+	} while (test_bit(TRANS_WAKEUP, &n_hci->tx_state));
+	clear_bit(TRANS_SENDING, &n_hci->tx_state);
+
+	return 0;
+}
+
+/* Send frames from HCI layer */
+int n_hci_send_frame(struct sk_buff *skb)
+{
+	struct hci_dev* hdev = (struct hci_dev *) skb->dev;
+	struct tty_struct *tty;
+	struct n_hci *n_hci;
+
+	if (!hdev) {
+		ERR("Frame for uknown device (hdev=NULL)");
+		return -ENODEV;
+	}
+
+	if (!(hdev->flags & HCI_RUNNING))
+		return -EBUSY;
+
+	n_hci = (struct n_hci *) hdev->driver_data;
+	tty = n_hci2tty(n_hci);
+
+	DBG("%s: type %d len %d", hdev->name, skb->pkt_type, skb->len);
+
+	switch (skb->pkt_type) {
+		case HCI_COMMAND_PKT:
+			hdev->stat.cmd_tx++;
+			break;
+
+                case HCI_ACLDATA_PKT:
+			hdev->stat.acl_tx++;
+                        break;
+
+		case HCI_SCODATA_PKT:
+			hdev->stat.cmd_tx++;
+                        break;
+	};
+
+	/* Prepend skb with frame type and queue */
+	memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
+	skb_queue_tail(&n_hci->txq, skb);
+
+	n_hci_tx_wakeup(n_hci);
+
+	return 0;
+}
+
+/* ------ LDISC part ------ */
+
+/* n_hci_tty_open
+ * 
+ *     Called when line discipline changed to N_HCI.
+ *     
+ * Arguments:    
+ *     tty    pointer to tty info structure
+ * Return Value:    
+ *     0 if success, otherwise error code
+ */
+static int n_hci_tty_open(struct tty_struct *tty)
+{
+	struct n_hci *n_hci = tty2n_hci(tty);
+	struct hci_dev *hdev;
+
+	DBG("tty %p", tty);
+
+	if (n_hci)
+		return -EEXIST;
+
+	if (!(n_hci = kmalloc(sizeof(struct n_hci), GFP_KERNEL))) {
+		ERR("Can't allocate controll structure");
+		return -ENFILE;
+	}
+	memset(n_hci, 0, sizeof(struct n_hci));
+
+	/* Initialize and register HCI device */
+	hdev = &n_hci->hdev;
+
+	hdev->type = HCI_UART;
+	hdev->driver_data = n_hci;
+
+	hdev->open  = n_hci_open;
+	hdev->close = n_hci_close;
+	hdev->flush = n_hci_flush;
+	hdev->send  = n_hci_send_frame;
+
+	if (hci_register_dev(hdev) < 0) {
+		ERR("Can't register HCI device %s", hdev->name);
+		kfree(n_hci);
+		return -ENODEV;
+	}
+
+	tty->disc_data = n_hci;
+	n_hci->tty = tty;
+
+	spin_lock_init(&n_hci->rx_lock);
+	n_hci->rx_state = WAIT_PACKET_TYPE;
+
+	skb_queue_head_init(&n_hci->txq);
+
+	MOD_INC_USE_COUNT;
+
+	/* Flush any pending characters in the driver and discipline. */
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+
+	return 0;
+}
+
+/* n_hci_tty_close()
+ *
+ *    Called when the line discipline is changed to something
+ *    else, the tty is closed, or the tty detects a hangup.
+ */
+static void n_hci_tty_close(struct tty_struct *tty)
+{
+	struct n_hci *n_hci = tty2n_hci(tty);
+	struct hci_dev *hdev = &n_hci->hdev;
+
+	DBG("tty %p hdev %p", tty, hdev);
+
+	if (n_hci != NULL) {
+		n_hci_close(hdev);
+
+		if (hci_unregister_dev(hdev) < 0) {
+			ERR("Can't unregister HCI device %s",hdev->name);
+		}
+
+		hdev->driver_data = NULL;
+		tty->disc_data = NULL;
+		kfree(n_hci);
+
+		MOD_DEC_USE_COUNT;
+	}
+}
+
+/* n_hci_tty_wakeup()
+ *
+ *    Callback for transmit wakeup. Called when low level
+ *    device driver can accept more send data.
+ *
+ * Arguments:        tty    pointer to associated tty instance data
+ * Return Value:    None
+ */
+static void n_hci_tty_wakeup( struct tty_struct *tty )
+{
+	struct n_hci *n_hci = tty2n_hci(tty);
+
+	DBG("");
+
+	if (!n_hci)
+		return;
+
+	tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
+
+	if (tty != n_hci->tty)
+		return;
+
+	n_hci_tx_wakeup(n_hci);
+}
+
+/* n_hci_tty_room()
+ * 
+ *    Callback function from tty driver. Return the amount of 
+ *    space left in the receiver's buffer to decide if remote
+ *    transmitter is to be throttled.
+ *
+ * Arguments:        tty    pointer to associated tty instance data
+ * Return Value:    number of bytes left in receive buffer
+ */
+static int n_hci_tty_room (struct tty_struct *tty)
+{
+	return 65536;
+}
+
+static inline int n_hci_check_data_len(struct n_hci *n_hci, int len)
+{
+	register int room = skb_tailroom(n_hci->rx_skb);
+
+	DBG("len %d room %d", len, room);
+	if (!len) {
+		DMP(n_hci->rx_skb->data, n_hci->rx_skb->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);
+		n_hci->hdev.stat.err_rx++;
+	} else {
+		n_hci->rx_state = WAIT_DATA;
+		n_hci->rx_count = len;
+		return len;
+	}
+
+	n_hci->rx_state = WAIT_PACKET_TYPE;
+	n_hci->rx_skb   = NULL;
+	n_hci->rx_count = 0;
+	return 0;
+}
+
+static inline void n_hci_rx(struct n_hci *n_hci, const __u8 * data, char *flags, int count)
+{
+	register const char *ptr;
+	hci_event_hdr *eh;
+	hci_acl_hdr   *ah;
+	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);
+
+	n_hci->hdev.stat.byte_rx += count;
+
+	ptr = data;
+	while (count) {
+		if (n_hci->rx_count) {
+			len = MIN(n_hci->rx_count, count);
+			memcpy(skb_put(n_hci->rx_skb, len), ptr, len);
+			n_hci->rx_count -= len; count -= len; ptr += len;
+
+			if (n_hci->rx_count)
+				continue;
+
+			switch (n_hci->rx_state) {
+				case WAIT_DATA:
+					DBG("Complete data");
+
+					DMP(n_hci->rx_skb->data, n_hci->rx_skb->len);
+
+					hci_recv_frame(n_hci->rx_skb);
+
+					n_hci->rx_state = WAIT_PACKET_TYPE;
+					n_hci->rx_skb = NULL;
+					continue;
+
+				case WAIT_EVENT_HDR:
+					eh = (hci_event_hdr *) n_hci->rx_skb->data;
+
+					DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
+
+					n_hci_check_data_len(n_hci, eh->plen);
+					continue;
+
+				case WAIT_ACL_HDR:
+					ah = (hci_acl_hdr *) n_hci->rx_skb->data;
+					dlen = __le16_to_cpu(ah->dlen);
+
+					DBG("ACL header: dlen %d", dlen);
+
+					n_hci_check_data_len(n_hci, dlen);
+					continue;
+
+				case WAIT_SCO_HDR:
+					sh = (hci_sco_hdr *) n_hci->rx_skb->data;
+
+					DBG("SCO header: dlen %d", sh->dlen);
+
+					n_hci_check_data_len(n_hci, sh->dlen);
+					continue;
+			};
+		}
+
+		/* WAIT_PACKET_TYPE */
+		switch (*ptr) {
+			case HCI_EVENT_PKT:
+				DBG("Event packet");
+				n_hci->rx_state = WAIT_EVENT_HDR;
+				n_hci->rx_count = HCI_EVENT_HDR_SIZE;
+				type = HCI_EVENT_PKT;
+				break;
+
+			case HCI_ACLDATA_PKT:
+				DBG("ACL packet");
+				n_hci->rx_state = WAIT_ACL_HDR;
+				n_hci->rx_count = HCI_ACL_HDR_SIZE;
+				type = HCI_ACLDATA_PKT;
+				break;
+
+			case HCI_SCODATA_PKT:
+				DBG("SCO packet");
+				n_hci->rx_state = WAIT_SCO_HDR;
+				n_hci->rx_count = HCI_SCO_HDR_SIZE;
+				type = HCI_SCODATA_PKT;
+				break;
+
+			default:
+				ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
+				n_hci->hdev.stat.err_rx++;
+				ptr++; count--;
+				continue;
+		};
+		ptr++; count--;
+
+		/* Allocate packet */
+		if (!(n_hci->rx_skb = bluez_skb_alloc(HCI_MAX_READ, GFP_ATOMIC))) {
+			ERR("Can't allocate mem for new packet");
+
+			n_hci->rx_state = WAIT_PACKET_TYPE;
+			n_hci->rx_count = 0;
+			return;
+		}
+		n_hci->rx_skb->dev = (void *) &n_hci->hdev;
+		n_hci->rx_skb->pkt_type = type;
+	}
+}
+
+/* n_hci_tty_receive()
+ * 
+ *     Called by tty low level driver when receive data is
+ *     available.
+ *     
+ * Arguments:  tty          pointer to tty isntance data
+ *             data         pointer to received data
+ *             flags        pointer to flags for data
+ *             count        count of received data in bytes
+ *     
+ * Return Value:    None
+ */
+static void n_hci_tty_receive(struct tty_struct *tty, const __u8 * data, char *flags, int count)
+{
+	struct n_hci *n_hci = tty2n_hci(tty);
+
+	if (!n_hci || tty != n_hci->tty)
+		return;
+
+	spin_lock(&n_hci->rx_lock);
+	n_hci_rx(n_hci, data, flags, count);
+	spin_unlock(&n_hci->rx_lock);
+
+	if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver.unthrottle)
+		tty->driver.unthrottle(tty);
+}
+
+/* n_hci_tty_ioctl()
+ *
+ *    Process IOCTL system call for the tty device.
+ *
+ * Arguments:
+ *
+ *    tty        pointer to tty instance data
+ *    file       pointer to open file object for device
+ *    cmd        IOCTL command code
+ *    arg        argument for IOCTL call (cmd dependent)
+ *
+ * Return Value:    Command dependent
+ */
+static int n_hci_tty_ioctl (struct tty_struct *tty, struct file * file,
+                            unsigned int cmd, unsigned long arg)
+{
+	struct n_hci *n_hci = tty2n_hci(tty);
+	int error = 0;
+
+	DBG("");
+
+	/* Verify the status of the device */
+	if (!n_hci)
+		return -EBADF;
+
+	switch (cmd) {
+		default:
+			error = n_tty_ioctl(tty, file, cmd, arg);
+			break;
+	};
+
+	return error;
+}
+
+/*
+ * We don't provide read/write/poll interface for user space.
+ */
+static ssize_t n_hci_tty_read(struct tty_struct *tty, struct file *file, unsigned char *buf, size_t nr)
+{
+	return 0;
+}
+static ssize_t n_hci_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
+{
+	return 0;
+}
+static unsigned int n_hci_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait)
+{
+	return 0;
+}
+
+int __init n_hci_init(void)
+{
+	static struct tty_ldisc n_hci_ldisc;
+	int err;
+
+	INF("BlueZ HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc", 
+		BLUEZ_VER);
+	INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+
+	/* Register the tty discipline */
+
+	memset(&n_hci_ldisc, 0, sizeof (n_hci_ldisc));
+	n_hci_ldisc.magic       = TTY_LDISC_MAGIC;
+	n_hci_ldisc.name        = "n_hci";
+	n_hci_ldisc.open        = n_hci_tty_open;
+	n_hci_ldisc.close       = n_hci_tty_close;
+	n_hci_ldisc.read        = n_hci_tty_read;
+	n_hci_ldisc.write       = n_hci_tty_write;
+	n_hci_ldisc.ioctl       = n_hci_tty_ioctl;
+	n_hci_ldisc.poll        = n_hci_tty_poll;
+	n_hci_ldisc.receive_room= n_hci_tty_room;
+	n_hci_ldisc.receive_buf = n_hci_tty_receive;
+	n_hci_ldisc.write_wakeup= n_hci_tty_wakeup;
+
+	if ((err = tty_register_ldisc(N_HCI, &n_hci_ldisc))) {
+		ERR("Can't register HCI line discipline (%d)", err);
+		return err;
+	}
+
+	return 0;
+}
+
+void n_hci_cleanup(void)
+{
+	int err;
+
+	/* Release tty registration of line discipline */
+	if ((err = tty_register_ldisc(N_HCI, NULL)))
+		ERR("Can't unregister HCI line discipline (%d)", err);
+}
+
+module_init(n_hci_init);
+module_exit(n_hci_cleanup);
diff -u --recursive --new-file v2.4.5/linux/drivers/bluetooth/hci_usb.c linux/drivers/bluetooth/hci_usb.c
--- v2.4.5/linux/drivers/bluetooth/hci_usb.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/bluetooth/hci_usb.c	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,670 @@
+/* 
+   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 USB driver.
+ * Based on original USB Bluetooth driver for Linux kernel
+ *    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 $    
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/version.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/poll.h>
+
+#include <linux/malloc.h>
+#include <linux/tty.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/signal.h>
+#include <linux/ioctl.h>
+#include <linux/skbuff.h>
+
+#include <linux/usb.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/bluez.h>
+#include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/hci_usb.h>
+
+#ifndef HCI_USB_DEBUG
+#undef  DBG
+#define DBG( A... )
+#undef  DMP
+#define DMP( A... )
+#endif
+
+static struct usb_device_id usb_bluetooth_ids [] = {
+	{ USB_DEVICE_INFO(HCI_DEV_CLASS, HCI_DEV_SUBCLASS, HCI_DEV_PROTOCOL) },
+	{ }	/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE (usb, usb_bluetooth_ids);
+
+static int hci_usb_ctrl_msg(struct hci_usb *husb,  struct sk_buff *skb);
+static int hci_usb_write_msg(struct hci_usb *husb, struct sk_buff *skb);
+
+static void hci_usb_unlink_urbs(struct hci_usb *husb)
+{
+	usb_unlink_urb(husb->read_urb);
+	usb_unlink_urb(husb->intr_urb);
+	usb_unlink_urb(husb->ctrl_urb);
+	usb_unlink_urb(husb->write_urb);
+}
+
+static void hci_usb_free_bufs(struct hci_usb *husb)
+{
+	if (husb->read_urb) {
+		if (husb->read_urb->transfer_buffer)
+			kfree(husb->read_urb->transfer_buffer);
+		usb_free_urb(husb->read_urb);
+	}
+
+	if (husb->intr_urb) {
+		if (husb->intr_urb->transfer_buffer)
+			kfree(husb->intr_urb->transfer_buffer);
+		usb_free_urb(husb->intr_urb);
+	}
+
+	if (husb->ctrl_urb)
+		usb_free_urb(husb->ctrl_urb);
+
+	if (husb->write_urb)
+		usb_free_urb(husb->write_urb);
+
+	if (husb->intr_skb)
+		bluez_skb_free(husb->intr_skb);
+}
+
+/* ------- Interface to HCI layer ------ */
+/* Initialize device */
+int hci_usb_open(struct hci_dev *hdev)
+{
+	struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
+	int status;
+
+	DBG("%s", hdev->name);
+
+	husb->read_urb->dev = husb->udev;
+	if ((status = usb_submit_urb(husb->read_urb)))
+		DBG("read submit failed. %d", status);
+
+	husb->intr_urb->dev = husb->udev;
+	if ((status = usb_submit_urb(husb->intr_urb)))
+		DBG("interrupt submit failed. %d", status);
+
+	hdev->flags |= HCI_RUNNING;
+
+	return 0;
+}
+
+/* Reset device */
+int hci_usb_flush(struct hci_dev *hdev)
+{
+	struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
+
+	DBG("%s", hdev->name);
+
+	/* Drop TX queues */
+	bluez_skb_queue_purge(&husb->tx_ctrl_q);
+	bluez_skb_queue_purge(&husb->tx_write_q);
+
+	return 0;
+}
+
+/* Close device */
+int hci_usb_close(struct hci_dev *hdev)
+{
+	struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
+
+	DBG("%s", hdev->name);
+
+	hdev->flags &= ~HCI_RUNNING;
+	hci_usb_unlink_urbs(husb);
+
+	hci_usb_flush(hdev);
+
+	return 0;
+}
+
+void hci_usb_ctrl_wakeup(struct hci_usb *husb)
+{
+	struct sk_buff *skb;
+
+	if (test_and_set_bit(HCI_TX_CTRL, &husb->tx_state))
+		return;
+
+	DBG("%s", husb->hdev.name);
+
+	if (!(skb = skb_dequeue(&husb->tx_ctrl_q)))
+		goto done;
+
+	if (hci_usb_ctrl_msg(husb, skb)){
+		bluez_skb_free(skb);
+		goto done;
+	}
+
+	DMP(skb->data, skb->len);
+
+	husb->hdev.stat.byte_tx += skb->len;
+	return;
+
+done:
+	clear_bit(HCI_TX_CTRL, &husb->tx_state);
+	return;
+}
+
+void hci_usb_write_wakeup(struct hci_usb *husb)
+{
+	struct sk_buff *skb;
+
+	if (test_and_set_bit(HCI_TX_WRITE, &husb->tx_state))
+		return;
+
+	DBG("%s", husb->hdev.name);
+
+	if (!(skb = skb_dequeue(&husb->tx_write_q)))
+		goto done;
+
+	if (hci_usb_write_msg(husb, skb)) {
+		skb_queue_head(&husb->tx_write_q, skb);
+		goto done;
+	}
+
+	DMP(skb->data, skb->len);
+
+	husb->hdev.stat.byte_tx += skb->len;
+	return;
+
+done:
+	clear_bit(HCI_TX_WRITE, &husb->tx_state);
+	return;
+}
+
+/* Send frames from HCI layer */
+int hci_usb_send_frame(struct sk_buff *skb)
+{
+	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+	struct hci_usb *husb;
+
+	if (!hdev) {
+		ERR("frame for uknown device (hdev=NULL)");
+		return -ENODEV;
+	}
+
+	if (!(hdev->flags & HCI_RUNNING))
+		return 0;
+
+	husb = (struct hci_usb *) hdev->driver_data;
+
+	DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
+
+	switch (skb->pkt_type) {
+		case HCI_COMMAND_PKT:
+			skb_queue_tail(&husb->tx_ctrl_q, skb);
+			hci_usb_ctrl_wakeup(husb);
+			hdev->stat.cmd_tx++;
+			return 0;
+
+		case HCI_ACLDATA_PKT:
+			skb_queue_tail(&husb->tx_write_q, skb);
+			hci_usb_write_wakeup(husb);
+			hdev->stat.acl_tx++;
+			return 0;
+
+		case HCI_SCODATA_PKT:
+			return -EOPNOTSUPP;
+	};
+
+	return 0;
+}
+
+/* ---------- USB ------------- */
+
+static void hci_usb_ctrl(struct urb *urb)
+{
+	struct sk_buff *skb = (struct sk_buff *) urb->context;
+	struct hci_dev *hdev;
+	struct hci_usb *husb;
+
+	if (!skb)
+		return;
+	hdev = (struct hci_dev *) skb->dev;
+	husb = (struct hci_usb *) hdev->driver_data;
+
+	DBG("%s", hdev->name);
+
+	if (urb->status)
+		DBG("%s ctrl status: %d", hdev->name, urb->status);
+
+	clear_bit(HCI_TX_CTRL, &husb->tx_state);
+	bluez_skb_free(skb);
+
+	/* Wake up device */
+	hci_usb_ctrl_wakeup(husb);
+}
+
+static void hci_usb_bulk_write(struct urb *urb)
+{
+	struct sk_buff *skb = (struct sk_buff *) urb->context;
+	struct hci_dev *hdev;
+	struct hci_usb *husb;
+
+	if (!skb)
+		return;
+	hdev = (struct hci_dev *) skb->dev;
+	husb = (struct hci_usb *) hdev->driver_data;
+
+	DBG("%s", hdev->name);
+
+	if (urb->status)
+		DBG("%s bulk write status: %d", hdev->name, urb->status);
+
+	clear_bit(HCI_TX_WRITE, &husb->tx_state);
+	bluez_skb_free(skb);
+
+	/* Wake up device */
+	hci_usb_write_wakeup(husb);
+
+	return;
+}
+
+static void hci_usb_intr(struct urb *urb)
+{
+	struct hci_usb *husb = (struct hci_usb *) urb->context;
+	unsigned char *data = urb->transfer_buffer;
+	register int count  = urb->actual_length;
+	register struct sk_buff *skb = husb->intr_skb;
+	hci_event_hdr *eh;
+	register int len;
+
+	if (!husb)
+		return;
+
+	DBG("%s count %d", husb->hdev.name, count);
+
+	if (urb->status || !count) {
+		DBG("%s intr status %d, count %d", husb->hdev.name, urb->status, count);
+		return;
+	}
+
+	/* Do we really have to handle continuations here ? */
+	if (!skb) {
+		/* New frame */
+		if (count < HCI_EVENT_HDR_SIZE) {
+			DBG("%s bad frame len %d", husb->hdev.name, count);
+			return;
+		}
+
+		eh = (hci_event_hdr *) data;
+		len = eh->plen + HCI_EVENT_HDR_SIZE;
+
+		if (count > len) {
+			DBG("%s corrupted frame, len %d", husb->hdev.name, count);
+			return;
+		}
+
+		/* Allocate skb */
+		if (!(skb = bluez_skb_alloc(len, GFP_ATOMIC))) {
+			ERR("Can't allocate mem for new packet");
+			return;
+		}
+		skb->dev = (void *) &husb->hdev;
+		skb->pkt_type = HCI_EVENT_PKT;
+
+		husb->intr_skb = skb;
+		husb->intr_count = len;
+	} else {
+		/* Continuation */
+		if (count > husb->intr_count) {
+			ERR("%s bad frame len %d (expected %d)", husb->hdev.name, count, husb->intr_count);
+
+			bluez_skb_free(skb);
+			husb->intr_skb = NULL;
+			husb->intr_count = 0;
+			return;
+		}
+	}
+
+	memcpy(skb_put(skb, count), data, count);
+	husb->intr_count -= count;
+
+	DMP(data, count);
+
+	if (!husb->intr_count) {
+		/* Got complete frame */
+
+		husb->hdev.stat.byte_rx += skb->len;
+		hci_recv_frame(skb);
+
+		husb->intr_skb = NULL;
+	}
+}
+
+static void hci_usb_bulk_read(struct urb *urb)
+{
+	struct hci_usb *husb = (struct hci_usb *) urb->context;
+	unsigned char *data = urb->transfer_buffer;
+	int count = urb->actual_length, status;
+	struct sk_buff *skb;
+	hci_acl_hdr *ah;
+	register __u16 dlen;
+
+	if (!husb)
+		return;
+
+	DBG("%s status %d, count %d, flags %x", husb->hdev.name, urb->status, count, urb->transfer_flags);
+
+	if (urb->status) {
+		/* Do not re-submit URB on critical errors */
+		switch (urb->status) {
+			case -ENOENT:
+				return;
+			default:
+				goto resubmit;
+		};
+	}
+	if (!count)
+		goto resubmit;
+
+	DMP(data, count);
+
+	ah = (hci_acl_hdr *) data;
+	dlen = le16_to_cpu(ah->dlen);
+
+	/* Verify frame len and completeness */
+	if ((count - HCI_ACL_HDR_SIZE) != dlen) {
+		ERR("%s corrupted ACL packet: count %d, plen %d", husb->hdev.name, count, dlen);
+		goto resubmit;
+	}
+
+	/* Allocate packet */
+	if (!(skb = bluez_skb_alloc(count, GFP_ATOMIC))) {
+		ERR("Can't allocate mem for new packet");
+		goto resubmit;
+	}
+
+	memcpy(skb_put(skb, count), data, count);
+	skb->dev = (void *) &husb->hdev;
+	skb->pkt_type = HCI_ACLDATA_PKT;
+
+	husb->hdev.stat.byte_rx += skb->len;
+
+	hci_recv_frame(skb);
+
+resubmit:
+	husb->read_urb->dev = husb->udev;
+	if ((status = usb_submit_urb(husb->read_urb)))
+		DBG("%s read URB submit failed %d", husb->hdev.name, status);
+
+	DBG("%s read URB re-submited", husb->hdev.name);
+}
+
+static int hci_usb_ctrl_msg(struct hci_usb *husb, struct sk_buff *skb)
+{
+	struct urb *urb = husb->ctrl_urb;
+	devrequest *dr  = &husb->dev_req;
+	int pipe, status;
+
+	DBG("%s len %d", husb->hdev.name, skb->len);
+
+	pipe = usb_sndctrlpipe(husb->udev, 0);
+
+	dr->requesttype = HCI_CTRL_REQ;
+	dr->request = 0;
+	dr->index   = 0;
+	dr->value   = 0;
+	dr->length  = cpu_to_le16(skb->len);
+
+	FILL_CONTROL_URB(urb, husb->udev, pipe, (void*)dr, skb->data, skb->len,
+	                 hci_usb_ctrl, skb);
+
+	if ((status = usb_submit_urb(urb))) {
+		DBG("%s control URB submit failed %d", husb->hdev.name, status);
+		return status;
+	}
+
+	return 0;
+}
+
+static int hci_usb_write_msg(struct hci_usb *husb, struct sk_buff *skb)
+{
+	struct urb *urb = husb->write_urb;
+	int pipe, status;
+
+	DBG("%s len %d", husb->hdev.name, skb->len);
+
+	pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep_addr);
+
+	FILL_BULK_URB(urb, husb->udev, pipe, skb->data, skb->len,
+	              hci_usb_bulk_write, skb);
+	urb->transfer_flags |= USB_QUEUE_BULK;
+
+	if ((status = usb_submit_urb(urb))) {
+		DBG("%s write URB submit failed %d", husb->hdev.name, status);
+		return status;
+	}
+
+	return 0;
+}
+
+static void * hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
+{
+	struct usb_endpoint_descriptor *bulk_out_ep, *intr_in_ep, *bulk_in_ep;
+	struct usb_interface_descriptor *uif;
+	struct usb_endpoint_descriptor *ep;
+	struct hci_usb *husb;
+	struct hci_dev *hdev;
+	int i, size, pipe;
+	__u8 * buf;
+
+	DBG("udev %p ifnum %d", udev, ifnum);
+
+	/* Check device signature */
+	if ((udev->descriptor.bDeviceClass    != HCI_DEV_CLASS)   ||
+	    (udev->descriptor.bDeviceSubClass != HCI_DEV_SUBCLASS)||
+	    (udev->descriptor.bDeviceProtocol != HCI_DEV_PROTOCOL) )
+		return NULL;
+
+	MOD_INC_USE_COUNT;
+
+	uif = &udev->actconfig->interface[ifnum].altsetting[0];
+
+	if (uif->bNumEndpoints != 3) {
+		DBG("Wrong number of endpoints %d", uif->bNumEndpoints);
+		MOD_DEC_USE_COUNT;
+		return NULL;
+	}
+
+	bulk_out_ep = intr_in_ep = bulk_in_ep = NULL;
+
+	/* Find endpoints that we need */
+	for ( i = 0; i < uif->bNumEndpoints; ++i) {
+		ep = &uif->endpoint[i];
+
+		switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+			case USB_ENDPOINT_XFER_BULK:
+				if (ep->bEndpointAddress & USB_DIR_IN)
+					bulk_in_ep  = ep;
+				else
+					bulk_out_ep = ep;
+				break;
+
+			case USB_ENDPOINT_XFER_INT:
+				intr_in_ep = ep;
+				break;
+		};
+	}
+
+	if (!bulk_in_ep || !bulk_out_ep || !intr_in_ep) {
+		DBG("Endpoints not found: %p %p %p", bulk_in_ep, bulk_out_ep, intr_in_ep);
+		MOD_DEC_USE_COUNT;
+		return NULL;
+	}
+
+	if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
+		ERR("Can't allocate: control structure");
+		MOD_DEC_USE_COUNT;
+		return NULL;
+	}
+
+	memset(husb, 0, sizeof(struct hci_usb));
+
+	husb->udev = udev;
+	husb->bulk_out_ep_addr = bulk_out_ep->bEndpointAddress;
+
+	if (!(husb->ctrl_urb = usb_alloc_urb(0))) {
+		ERR("Can't allocate: control URB");
+		goto probe_error;
+	}
+
+	if (!(husb->write_urb = usb_alloc_urb(0))) {
+		ERR("Can't allocate: write URB");
+		goto probe_error;
+	}
+
+	if (!(husb->read_urb = usb_alloc_urb(0))) {
+		ERR("Can't allocate: read URB");
+		goto probe_error;
+	}
+
+	ep = bulk_in_ep;
+	pipe = usb_rcvbulkpipe(udev, ep->bEndpointAddress);
+	size = HCI_USB_MAX_READ;
+
+	if (!(buf = kmalloc(size, GFP_KERNEL))) {
+		ERR("Can't allocate: read buffer");
+		goto probe_error;
+	}
+
+	FILL_BULK_URB(husb->read_urb, udev, pipe, buf, size, hci_usb_bulk_read, husb);
+	husb->read_urb->transfer_flags |= USB_QUEUE_BULK;
+
+	ep = intr_in_ep;
+	pipe = usb_rcvintpipe(udev, ep->bEndpointAddress);
+	size = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
+
+	if (!(husb->intr_urb = usb_alloc_urb(0))) {
+		ERR("Can't allocate: interrupt URB");
+		goto probe_error;
+	}
+
+	if (!(buf = kmalloc(size, GFP_KERNEL))) {
+		ERR("Can't allocate: interrupt buffer");
+		goto probe_error;
+	}
+
+	FILL_INT_URB(husb->intr_urb, udev, pipe, buf, size, hci_usb_intr, husb, ep->bInterval);
+
+	skb_queue_head_init(&husb->tx_ctrl_q);
+	skb_queue_head_init(&husb->tx_write_q);
+
+	/* Initialize and register HCI device */
+	hdev = &husb->hdev;
+
+	hdev->type = HCI_USB;
+	hdev->driver_data = husb;
+
+	hdev->open  = hci_usb_open;
+	hdev->close = hci_usb_close;
+	hdev->flush = hci_usb_flush;
+	hdev->send	= hci_usb_send_frame;
+
+	if (hci_register_dev(hdev) < 0) {
+		ERR("Can't register HCI device %s", hdev->name);
+		goto probe_error;
+	}
+
+	return husb;
+
+probe_error:
+	hci_usb_free_bufs(husb);
+	kfree(husb);
+	MOD_DEC_USE_COUNT;
+	return NULL;
+}
+
+static void hci_usb_disconnect(struct usb_device *udev, void *ptr)
+{
+	struct hci_usb *husb = (struct hci_usb *) ptr;
+	struct hci_dev *hdev = &husb->hdev;
+
+	if (!husb)
+		return;
+
+	DBG("%s", hdev->name);
+
+	hci_usb_close(hdev);
+
+	if (hci_unregister_dev(hdev) < 0) {
+		ERR("Can't unregister HCI device %s", hdev->name);
+	}
+
+	hci_usb_free_bufs(husb);
+	kfree(husb);
+
+	MOD_DEC_USE_COUNT;
+}
+
+static struct usb_driver hci_usb_driver =
+{
+	name:           "hci_usb",
+	probe:          hci_usb_probe,
+	disconnect:     hci_usb_disconnect,
+	id_table:       usb_bluetooth_ids,
+};
+
+int hci_usb_init(void)
+{
+	int err;
+
+	INF("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",  
+		BLUEZ_VER);
+	INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+
+	if ((err = usb_register(&hci_usb_driver)) < 0)
+		ERR("Failed to register HCI USB driver");
+
+	return err;
+}
+
+void hci_usb_cleanup(void)
+{
+	usb_deregister(&hci_usb_driver);
+}
+
+module_init(hci_usb_init);
+module_exit(hci_usb_cleanup);
diff -u --recursive --new-file v2.4.5/linux/drivers/cdrom/mcdx.c linux/drivers/cdrom/mcdx.c
--- v2.4.5/linux/drivers/cdrom/mcdx.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/cdrom/mcdx.c	Wed Jun 27 14:13:01 2001
@@ -80,6 +80,10 @@
 #define	mcdx_drive_map mcdx
 #include "mcdx.h"
 
+#if BITS_PER_LONG != 32
+#  error FIXME: this driver only works on 32-bit platforms
+#endif
+
 #ifndef HZ
 #error HZ not defined
 #endif
diff -u --recursive --new-file v2.4.5/linux/drivers/char/agp/agp.h linux/drivers/char/agp/agp.h
--- v2.4.5/linux/drivers/char/agp/agp.h	Tue Feb 13 14:13:43 2001
+++ linux/drivers/char/agp/agp.h	Wed Jun 20 21:00:55 2001
@@ -92,7 +92,7 @@
 	u32 mode;
 	enum chipset_type type;
 	enum aper_size_type size_type;
-	u32 *key_list;
+	unsigned long *key_list;
 	atomic_t current_memory_agp;
 	atomic_t agp_in_use;
 	int max_memory_agp;	/* in number of pages */
diff -u --recursive --new-file v2.4.5/linux/drivers/char/agp/agpgart_be.c linux/drivers/char/agp/agpgart_be.c
--- v2.4.5/linux/drivers/char/agp/agpgart_be.c	Tue Feb 13 14:13:43 2001
+++ linux/drivers/char/agp/agpgart_be.c	Wed Jun 20 21:00:55 2001
@@ -67,7 +67,7 @@
 {
 #if defined(__i386__)
 	asm volatile ("wbinvd":::"memory");
-#elif defined(__alpha__) || defined(__ia64__)
+#elif defined(__alpha__) || defined(__ia64__) || defined(__sparc__)
 	/* ??? I wonder if we'll really need to flush caches, or if the
 	   core logic can manage to keep the system coherent.  The ARM
 	   speaks only of using `cflush' to get things in memory in
diff -u --recursive --new-file v2.4.5/linux/drivers/char/agp/agpgart_fe.c linux/drivers/char/agp/agpgart_fe.c
--- v2.4.5/linux/drivers/char/agp/agpgart_fe.c	Tue May 15 01:29:34 2001
+++ linux/drivers/char/agp/agpgart_fe.c	Wed Jun 27 17:10:55 2001
@@ -875,6 +875,9 @@
 	} else {
 		agp_segment *segment;
 
+		if (reserve.seg_count >= 16384)
+			return -EINVAL;
+			
 		segment = kmalloc((sizeof(agp_segment) * reserve.seg_count),
 				  GFP_KERNEL);
 
diff -u --recursive --new-file v2.4.5/linux/drivers/char/console.c linux/drivers/char/console.c
--- v2.4.5/linux/drivers/char/console.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/char/console.c	Tue Jun 12 11:17:17 2001
@@ -103,8 +103,6 @@
 #include <asm/uaccess.h>
 #include <asm/bitops.h>
 
-#include <asm/linux_logo.h>
-
 #include "console_macros.h"
 
 
@@ -2684,7 +2682,7 @@
 void poke_blanked_console(void)
 {
 	del_timer(&console_timer);	/* Can't use _sync here: called from tasklet */
-	if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
+	if (!vt_cons[fg_console] || vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
 		return;
 	if (console_blanked) {
 		console_timer.function = unblank_screen_t;
diff -u --recursive --new-file v2.4.5/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c
--- v2.4.5/linux/drivers/char/cyclades.c	Fri Apr  6 10:42:55 2001
+++ linux/drivers/char/cyclades.c	Wed Jun 27 17:10:55 2001
@@ -743,7 +743,7 @@
 #define NR_ISA_ADDRS (sizeof(cy_isa_addresses)/sizeof(unsigned char*))
 
 #ifdef MODULE
-static int maddr[NR_CARDS] = { 0, };
+static long maddr[NR_CARDS] = { 0, };
 static int irq[NR_CARDS]  = { 0, };
 
 MODULE_PARM(maddr, "1-" __MODULE_STRING(NR_CARDS) "l");
@@ -2983,10 +2983,11 @@
         return 0;
     }
 
-    CY_LOCK(info, flags);
     if (from_user) {
 	down(&tmp_buf_sem);
 	while (1) {
+	    int c1;
+	    
 	    c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
 				SERIAL_XMIT_SIZE - info->xmit_head));
 	    if (c <= 0)
@@ -2999,23 +3000,30 @@
 		}
 		break;
 	    }
-	    c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+	    CY_LOCK(info, flags);
+	    c1 = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
 			SERIAL_XMIT_SIZE - info->xmit_head));
+			
+	    if (c1 < c)
+	    	c = c1;
 	    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;
+            CY_UNLOCK(info, flags);
 	    buf += c;
 	    count -= c;
 	    ret += c;
 	}
 	up(&tmp_buf_sem);
     } else {
+	CY_LOCK(info, flags);
 	while (1) {
 	    c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, 
 			SERIAL_XMIT_SIZE - info->xmit_head));
-	    if (c <= 0) {
+	        
+	    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;
@@ -3023,8 +3031,8 @@
 	    count -= c;
 	    ret += c;
 	}
+        CY_UNLOCK(info, flags);
     }
-    CY_UNLOCK(info, flags);
 
     info->idle_stats.xmit_bytes += ret;
     info->idle_stats.xmit_idle   = jiffies;
diff -u --recursive --new-file v2.4.5/linux/drivers/char/drm/context.c linux/drivers/char/drm/context.c
--- v2.4.5/linux/drivers/char/drm/context.c	Tue Aug 29 14:09:15 2000
+++ linux/drivers/char/drm/context.c	Wed Jun 27 17:10:55 2001
@@ -91,10 +91,13 @@
 		atomic_dec(&dev->queuelist[i]->use_count);
 	}
 				/* Allocate a new queue */
-	down(&dev->struct_sem);
 	
 	queue = drm_alloc(sizeof(*queue), DRM_MEM_QUEUES);
+	if(queue == NULL)
+		return -ENOMEM;	
+
 	memset(queue, 0, sizeof(*queue));
+	down(&dev->struct_sem);
 	atomic_set(&queue->use_count, 1);
 	
 	++dev->queue_count;
diff -u --recursive --new-file v2.4.5/linux/drivers/char/drm/dma.c linux/drivers/char/drm/dma.c
--- v2.4.5/linux/drivers/char/drm/dma.c	Wed Nov 15 00:41:03 2000
+++ linux/drivers/char/drm/dma.c	Wed Jun 27 17:10:55 2001
@@ -38,7 +38,10 @@
 {
 	int i;
 	
-	dev->dma = drm_alloc(sizeof(*dev->dma), DRM_MEM_DRIVER);
+	if (!(dev->dma = drm_alloc(sizeof(*dev->dma), DRM_MEM_DRIVER))) {
+                printk(KERN_ERR "drm_dma_setup: can't drm_alloc dev->dma");
+                return;
+        }       
 	memset(dev->dma, 0, sizeof(*dev->dma));
 	for (i = 0; i <= DRM_MAX_ORDER; i++)
 		memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0]));
diff -u --recursive --new-file v2.4.5/linux/drivers/char/drm/ffb_drv.c linux/drivers/char/drm/ffb_drv.c
--- v2.4.5/linux/drivers/char/drm/ffb_drv.c	Sun May 20 12:11:38 2001
+++ linux/drivers/char/drm/ffb_drv.c	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-/* $Id: ffb_drv.c,v 1.12 2001/04/14 01:12:03 davem Exp $
+/* $Id: ffb_drv.c,v 1.14 2001/05/24 12:01:47 davem Exp $
  * ffb_drv.c: Creator/Creator3D direct rendering driver.
  *
  * Copyright (C) 2000 David S. Miller (davem@redhat.com)
@@ -719,9 +719,19 @@
 	current->state = TASK_RUNNING;
 	remove_wait_queue(&dev->lock.lock_queue, &entry);
 
-        if (!ret &&
-	    (dev->last_context != lock.context))
-		ffb_context_switch(dev, dev->last_context, lock.context);
+        if (!ret) {
+		sigemptyset(&dev->sigmask);
+		sigaddset(&dev->sigmask, SIGSTOP);
+		sigaddset(&dev->sigmask, SIGTSTP);
+		sigaddset(&dev->sigmask, SIGTTIN);
+		sigaddset(&dev->sigmask, SIGTTOU);
+		dev->sigdata.context = lock.context;
+		dev->sigdata.lock = dev->lock.hw_lock;
+		block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
+
+		if (dev->last_context != lock.context)
+			ffb_context_switch(dev, dev->last_context, lock.context);
+	}
 
         DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
 
@@ -770,6 +780,7 @@
 
 	wake_up_interruptible(&dev->lock.lock_queue);
 	
+	unblock_all_signals();
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/char/drm/i810_dma.c linux/drivers/char/drm/i810_dma.c
--- v2.4.5/linux/drivers/char/drm/i810_dma.c	Mon Mar 19 12:35:08 2001
+++ linux/drivers/char/drm/i810_dma.c	Wed Jun 27 17:10:55 2001
@@ -1286,6 +1286,8 @@
 	DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n",
 		  vertex.idx, vertex.used, vertex.discard);
 
+	if(vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL;
+
 	i810_dma_dispatch_vertex( dev, 
 				  dma->buflist[ vertex.idx ], 
 				  vertex.discard, vertex.used );
@@ -1409,7 +1411,7 @@
    	if (copy_from_user(&d, (drm_i810_copy_t *)arg, sizeof(d)))
 		return -EFAULT;
 
-	if(d.idx > dma->buf_count) return -EINVAL;
+	if(d.idx < 0 || d.idx > dma->buf_count) return -EINVAL;
 	buf = dma->buflist[ d.idx ];
    	buf_priv = buf->dev_private;
 	if (buf_priv->currently_mapped != I810_BUF_MAPPED) return -EPERM;
diff -u --recursive --new-file v2.4.5/linux/drivers/char/drm/mga_state.c linux/drivers/char/drm/mga_state.c
--- v2.4.5/linux/drivers/char/drm/mga_state.c	Thu Jan  4 14:06:18 2001
+++ linux/drivers/char/drm/mga_state.c	Wed Jun 27 17:10:55 2001
@@ -832,6 +832,7 @@
 		return -EINVAL;
 	}
 
+	if(iload.idx < 0 || iload.idx > dma->buf_count) return -EINVAL;
 	buf = dma->buflist[iload.idx];
 	buf_priv = buf->dev_private;
 	bus_address = buf->bus_address;
@@ -874,6 +875,8 @@
 		return -EINVAL;
 	}
 
+	if(vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL;
+
 	buf = dma->buflist[vertex.idx];
 	buf_priv = buf->dev_private;
 
@@ -920,6 +923,7 @@
 		return -EINVAL;
 	}
 
+	if(indices.idx < 0 || indices.idx > dma->buf_count) return -EINVAL;
 	buf = dma->buflist[indices.idx];
 	buf_priv = buf->dev_private;
 
diff -u --recursive --new-file v2.4.5/linux/drivers/char/drm/proc.c linux/drivers/char/drm/proc.c
--- v2.4.5/linux/drivers/char/drm/proc.c	Thu Jul 27 15:10:22 2000
+++ linux/drivers/char/drm/proc.c	Wed Jun 27 17:10:55 2001
@@ -92,6 +92,7 @@
 		if (!drm_dev_root) {
 			DRM_ERROR("Cannot create /proc/%s\n", drm_slot_name);
 			remove_proc_entry("dri", NULL);
+			break;
 		}
 		if (drm_dev_root->nlink == 2) break;
 		drm_dev_root = NULL;
diff -u --recursive --new-file v2.4.5/linux/drivers/char/drm/r128_drv.h linux/drivers/char/drm/r128_drv.h
--- v2.4.5/linux/drivers/char/drm/r128_drv.h	Fri Mar  2 18:38:37 2001
+++ linux/drivers/char/drm/r128_drv.h	Wed Jun 20 21:00:55 2001
@@ -385,16 +385,14 @@
 #define R128_MAX_VB_VERTS		(0xffff)
 
 
-#define R128_BASE(reg)		((u32)(dev_priv->mmio->handle))
+#define R128_BASE(reg)		((unsigned long)(dev_priv->mmio->handle))
 #define R128_ADDR(reg)		(R128_BASE(reg) + reg)
 
-#define R128_DEREF(reg)		*(__volatile__ int *)R128_ADDR(reg)
-#define R128_READ(reg)		R128_DEREF(reg)
-#define R128_WRITE(reg,val)	do { R128_DEREF(reg) = val; } while (0)
+#define R128_READ(reg)		readl(R128_ADDR(reg))
+#define R128_WRITE(reg,val)	writel(val,R128_ADDR(reg))
 
-#define R128_DEREF8(reg)	*(__volatile__ char *)R128_ADDR(reg)
-#define R128_READ8(reg)		R128_DEREF8(reg)
-#define R128_WRITE8(reg,val)	do { R128_DEREF8(reg) = val; } while (0)
+#define R128_READ8(reg)		readb(R128_ADDR(reg))
+#define R128_WRITE8(reg,val)	writeb(val,R128_ADDR(reg))
 
 #define R128_WRITE_PLL(addr,val)                                              \
 do {                                                                          \
diff -u --recursive --new-file v2.4.5/linux/drivers/char/drm/radeon_bufs.c linux/drivers/char/drm/radeon_bufs.c
--- v2.4.5/linux/drivers/char/drm/radeon_bufs.c	Mon Mar 19 12:35:08 2001
+++ linux/drivers/char/drm/radeon_bufs.c	Wed Jun 27 17:10:55 2001
@@ -132,6 +132,11 @@
 		buf->dev_priv_size = sizeof(drm_radeon_buf_priv_t);
 		buf->dev_private   = drm_alloc(sizeof(drm_radeon_buf_priv_t),
 					       DRM_MEM_BUFS);
+                if (!buf->dev_private) {
+                        up(&dev->struct_sem);
+                        atomic_dec(&dev->buf_alloc);
+                        return -ENOMEM;
+                }
 		memset(buf->dev_private, 0, buf->dev_priv_size);
 
 #if DRM_DMA_HISTOGRAM
diff -u --recursive --new-file v2.4.5/linux/drivers/char/epca.c linux/drivers/char/epca.c
--- v2.4.5/linux/drivers/char/epca.c	Tue May 22 10:23:16 2001
+++ linux/drivers/char/epca.c	Wed Jun 27 14:13:01 2001
@@ -60,6 +60,10 @@
 #include "epca.h"
 #include "epcaconfig.h"
 
+#if BITS_PER_LONG != 32
+#  error FIXME: this driver only works on 32-bit platforms
+#endif
+
 /* ---------------------- Begin defines ------------------------ */
 
 #define VERSION            "1.3.0.1-LK"
diff -u --recursive --new-file v2.4.5/linux/drivers/char/esp.c linux/drivers/char/esp.c
--- v2.4.5/linux/drivers/char/esp.c	Fri Apr  6 10:42:55 2001
+++ linux/drivers/char/esp.c	Wed Jun 27 14:13:01 2001
@@ -957,7 +957,7 @@
 		if (!dma_buffer)
 			info->stat_flags |= ESP_STAT_USE_PIO;
 		else if (request_dma(dma, "esp serial")) {
-			free_pages((unsigned int)dma_buffer,
+			free_pages((unsigned long)dma_buffer,
 				   get_order(DMA_BUFFER_SZ));
 			dma_buffer = 0;
 			info->stat_flags |= ESP_STAT_USE_PIO;
@@ -1061,7 +1061,7 @@
 
 		if (!current_port) {
 			free_dma(dma);
-			free_pages((unsigned int)dma_buffer,
+			free_pages((unsigned long)dma_buffer,
 				   get_order(DMA_BUFFER_SZ));
 			dma_buffer = 0;
 		}		
@@ -2770,7 +2770,7 @@
 	}
 
 	if (dma_buffer)
-		free_pages((unsigned int)dma_buffer,
+		free_pages((unsigned long)dma_buffer,
 			get_order(DMA_BUFFER_SZ));
 
 	if (tmp_buf)
diff -u --recursive --new-file v2.4.5/linux/drivers/char/i810-tco.c linux/drivers/char/i810-tco.c
--- v2.4.5/linux/drivers/char/i810-tco.c	Thu May 24 15:14:08 2001
+++ linux/drivers/char/i810-tco.c	Wed Jun 27 17:10:55 2001
@@ -232,19 +232,40 @@
 	}
 }
 
+/*
+ * Data for PCI driver interface
+ *
+ * This data only exists for exporting the supported
+ * PCI ids via MODULE_DEVICE_TABLE.  We do not actually
+ * register a pci_driver, because someone else might one day
+ * want to register another driver on the same PCI id.
+ */
+static struct pci_device_id i810tco_pci_tbl[] __initdata = {
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0,	PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0,	PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,	PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10,	PCI_ANY_ID, PCI_ANY_ID, },
+	{ 0, },
+};
+MODULE_DEVICE_TABLE (pci, i810tco_pci_tbl);
+
 static struct pci_dev *i810tco_pci;
 
 static unsigned char i810tco_getdevice (void)
 {
+	struct pci_dev *dev;
 	u8 val1, val2;
 	u16 badr;
 	/*
-	 *      Find the PCI device which has vendor id 0x8086
-	 *      and device ID 0x2410
+	 *      Find the PCI device
 	 */
-	i810tco_pci = pci_find_device (PCI_VENDOR_ID_INTEL,
-				       PCI_DEVICE_ID_INTEL_82801AA_0, NULL);
-	if (i810tco_pci) {
+
+	pci_for_each_dev(dev) {
+		if (pci_match_device(i810tco_pci_tbl, dev))
+			break;
+	}
+
+	if ((i810tco_pci = dev)) {
 		/*
 		 *      Find the ACPI base I/O address which is the base
 		 *      for the TCO registers (TCOBASE=ACPIBASE + 0x60)
diff -u --recursive --new-file v2.4.5/linux/drivers/char/n_r3964.c linux/drivers/char/n_r3964.c
--- v2.4.5/linux/drivers/char/n_r3964.c	Fri Apr 13 20:26:07 2001
+++ linux/drivers/char/n_r3964.c	Wed Jun 27 14:13:01 2001
@@ -132,10 +132,10 @@
 
 static int  r3964_open(struct tty_struct *tty);
 static void r3964_close(struct tty_struct *tty);
-static int  r3964_read(struct tty_struct *tty, struct file *file,
-                     unsigned char *buf, unsigned int nr);
-static int  r3964_write(struct tty_struct * tty, struct file * file,
-                      const unsigned char * buf, unsigned int nr);
+static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
+                     unsigned char *buf, size_t nr);
+static ssize_t r3964_write(struct tty_struct * tty, struct file * file,
+                      const unsigned char * buf, size_t nr);
 static int r3964_ioctl(struct tty_struct * tty, struct file * file,
                        unsigned int cmd, unsigned long arg);
 static void r3964_set_termios(struct tty_struct *tty, struct termios * old);
@@ -1238,8 +1238,8 @@
     MOD_DEC_USE_COUNT;
 }
 
-static int r3964_read(struct tty_struct *tty, struct file *file,
-                     unsigned char *buf, unsigned int nr)
+static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
+			  unsigned char *buf, size_t nr)
 {
    struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data;
    struct r3964_client_info *pClient;
@@ -1299,8 +1299,8 @@
    return -EPERM;
 }
 
-static int r3964_write(struct tty_struct * tty, struct file * file,
-                      const unsigned char *data, unsigned int count)
+static ssize_t r3964_write(struct tty_struct * tty, struct file * file,
+			   const unsigned char *data, size_t count)
 {
    struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data;
    struct r3964_block_header *pHeader;
diff -u --recursive --new-file v2.4.5/linux/drivers/char/nvram.c linux/drivers/char/nvram.c
--- v2.4.5/linux/drivers/char/nvram.c	Fri Feb  9 11:40:02 2001
+++ linux/drivers/char/nvram.c	Wed Jun 27 17:10:55 2001
@@ -113,7 +113,7 @@
 #define	NVRAM_EXCL		2		/* opened with O_EXCL */
 
 #define	RTC_FIRST_BYTE		14	/* RTC register number of first NVRAM byte */
-#define	NVRAM_BYTES			50	/* number of NVRAM bytes */
+#define	NVRAM_BYTES			128	/* number of NVRAM bytes */
 
 
 static int mach_check_checksum( void );
diff -u --recursive --new-file v2.4.5/linux/drivers/char/nwflash.c linux/drivers/char/nwflash.c
--- v2.4.5/linux/drivers/char/nwflash.c	Mon Sep 18 15:15:22 2000
+++ linux/drivers/char/nwflash.c	Wed Jun 27 14:12:04 2001
@@ -4,6 +4,14 @@
  *
  * 20/08/2000	RMK	use __ioremap to map flash into virtual memory
  *			make a few more places use "volatile"
+ * 22/05/2001	RMK	- Lock read against write
+ *			- merge printk level changes (with mods) from Alan Cox.
+ *			- use *ppos as the file position, not file->f_pos.
+ *			- fix check for out of range pos and r/w size
+ *
+ * Please note that we are tampering with the only flash chip in the
+ * machine, which contains the bootup code.  We therefore have the
+ * power to convert these machines into doorstops...
  */
 
 #include <linux/module.h>
@@ -16,6 +24,7 @@
 #include <linux/sched.h>
 #include <linux/miscdevice.h>
 #include <linux/spinlock.h>
+#include <linux/rwsem.h>
 #include <linux/init.h>
 
 #include <asm/hardware/dec21285.h>
@@ -28,21 +37,12 @@
 /*****************************************************************************/
 #include <asm/nwflash.h>
 
-//#define MINIKERNEL 1          //export flash write, erase routines for MiniKernel
+#define	NWFLASH_VERSION "6.4"
 
-#ifndef MINIKERNEL
-#define MSTATIC static
-#else
-#define MSTATIC
-#endif
-
-#define	NWFLASH_VERSION "6.3"
-
-MSTATIC void kick_open(void);
-MSTATIC int get_flash_id(void);
-MSTATIC int erase_block(int nBlock);
-MSTATIC int write_block(unsigned long p, const char *buf, int count);
-static int open_flash(struct inode *inodep, struct file *filep);
+static void kick_open(void);
+static int get_flash_id(void);
+static int erase_block(int nBlock);
+static int write_block(unsigned long p, const char *buf, int count);
 static int flash_ioctl(struct inode *inodep, struct file *filep, unsigned int cmd, unsigned long arg);
 static ssize_t flash_read(struct file *file, char *buf, size_t count, loff_t * ppos);
 static ssize_t flash_write(struct file *file, const char *buf, size_t count, loff_t * ppos);
@@ -58,27 +58,10 @@
 static int gbWriteEnable;
 static int gbWriteBase64Enable;
 static volatile unsigned char *FLASH_BASE;
-MSTATIC int gbFlashSize = KFLASH_SIZE;
+static int gbFlashSize = KFLASH_SIZE;
 
 extern spinlock_t gpio_lock;
 
-static struct file_operations flash_fops =
-{
-	owner:		THIS_MODULE,
-	llseek:		flash_llseek,
-	read:		flash_read,
-	write:		flash_write,
-	ioctl:		flash_ioctl,
-	open:		open_flash,
-};
-
-static struct miscdevice flash_miscdev =
-{
-	FLASH_MINOR,
-	"nwflash",
-	&flash_fops
-};
-
 /*
  * the delay routine - it is often required to let the flash "breeze"...
  */
@@ -88,7 +71,7 @@
 	schedule_timeout(timeout);
 }
 
-MSTATIC int get_flash_id(void)
+static int get_flash_id(void)
 {
 	volatile unsigned int c1, c2;
 
@@ -123,23 +106,8 @@
 	return c2;
 }
 
-static int open_flash(struct inode *inodep, struct file *filep)
-{
-	int id;
-
-	id = get_flash_id();
-	if ((id != KFLASH_ID) && (id != KFLASH_ID4)) {
-		printk("Flash: incorrect ID 0x%04X.\n", id);
-		return -ENXIO;
-	}
-
-	return 0;
-}
-
 static int flash_ioctl(struct inode *inodep, struct file *filep, unsigned int cmd, unsigned long arg)
 {
-//      printk("Flash_ioctl: cmd = 0x%X.\n",cmd);
-
 	switch (cmd) {
 	case CMD_WRITE_DISABLE:
 		gbWriteBase64Enable = 0;
@@ -159,41 +127,48 @@
 		gbWriteEnable = 0;
 		return -EINVAL;
 	}
-
 	return 0;
 }
 
-
-
-static ssize_t flash_read(struct file *file, char *buf, size_t count, loff_t * ppos)
+static ssize_t flash_read(struct file *file, char *buf, size_t size, loff_t * ppos)
 {
-	unsigned long p = file->f_pos;
-	int read;
+	struct inode *inode = file->f_dentry->d_inode;
+	unsigned long p = *ppos;
+	unsigned int count = size;
+	int ret = 0;
 
 	if (flashdebug)
-		printk("Flash_dev: flash_read: offset=0x%X, buffer=0x%X, count=0x%X.\n",
-		       (unsigned int) p, (unsigned int) buf, count);
-
+		printk(KERN_DEBUG "flash_read: flash_read: offset=0x%lX, buffer=%p, count=0x%X.\n",
+		       p, buf, count);
 
-	if (count < 0)
-		return -EINVAL;
+	if (count)
+		ret = -ENXIO;
 
-	if (count > gbFlashSize - p)
-		count = gbFlashSize - p;
+	if (p < gbFlashSize) {
+		if (count > gbFlashSize - p)
+			count = gbFlashSize - p;
 
-	read = 0;
+		/*
+		 * We now lock against reads and writes. --rmk
+		 */
+		if (down_interruptible(&inode->i_sem))
+			return -ERESTARTSYS;
 
-	if (copy_to_user(buf, (void *)(FLASH_BASE + p), count))
-		return -EFAULT;
-	read += count;
-	file->f_pos += read;
-	return read;
+		ret = copy_to_user(buf, (void *)(FLASH_BASE + p), count);
+		if (ret == 0) {
+			ret = count;
+			*ppos += count;
+		}
+		up(&inode->i_sem);
+	}
+	return ret;
 }
 
-static ssize_t flash_write(struct file *file, const char *buf, size_t count, loff_t * ppos)
+static ssize_t flash_write(struct file *file, const char *buf, size_t size, loff_t * ppos)
 {
 	struct inode *inode = file->f_dentry->d_inode;
-	unsigned long p = file->f_pos;
+	unsigned long p = *ppos;
+	unsigned int count = size;
 	int written;
 	int nBlock, temp, rc;
 	int i, j;
@@ -209,20 +184,19 @@
 		return -EINVAL;
 
 	/*
-	 * if byte count is -ve or to big - error!
+	 * check for out of range pos or count
 	 */
-	if (count < 0 || count > gbFlashSize - p)
-		return -EINVAL;
+	if (p >= gbFlashSize)
+		return count ? -ENXIO : 0;
 
+	if (count > gbFlashSize - p)
+		count = gbFlashSize - p;
+			
 	if (verify_area(VERIFY_READ, buf, count))
 		return -EFAULT;
 
-
 	/*
-	 * We now should lock around writes.  Really, we shouldn't
-	 * allow the flash to be opened more than once in write
-	 * mode though (note that you can't stop two processes having
-	 * it open even then). --rmk
+	 * We now lock against reads and writes. --rmk
 	 */
 	if (down_interruptible(&inode->i_sem))
 		return -ERESTARTSYS;
@@ -246,11 +220,12 @@
 		temp -= 1;
 
 	if (flashdebug)
-		printk("FlashWrite: writing %d block(s) starting at %d.\n", temp, nBlock);
+		printk(KERN_DEBUG "flash_write: writing %d block(s) "
+			"starting at %d.\n", temp, nBlock);
 
 	for (; temp; temp--, nBlock++) {
 		if (flashdebug)
-			printk("FlashWrite: erasing block %d.\n", nBlock);
+			printk(KERN_DEBUG "flash_write: erasing block %d.\n", nBlock);
 
 		/*
 		 * first we have to erase the block(s), where we will write...
@@ -264,14 +239,12 @@
 		} while (rc && i < 10);
 
 		if (rc) {
-			if (flashdebug)
-				printk("FlashWrite: erase error %X. Aborting...\n", rc);
-
+			printk(KERN_ERR "flash_write: erase error %x\n", rc);
 			break;
 		}
 		if (flashdebug)
-			printk("FlashWrite: writing offset %X, from buf %X, bytes left %X.\n",
-			       (unsigned int) p, (unsigned int) buf, count - written);
+			printk(KERN_DEBUG "flash_write: writing offset %lX, from buf "
+				"%p, bytes left %X.\n", p, buf, count - written);
 
 		/*
 		 * write_block will limit write to space left in this block
@@ -296,17 +269,16 @@
 
 		}
 		if (rc < 0) {
-			if (flashdebug)
-				printk("FlashWrite: write error %X. Aborting...\n", rc);
+			printk(KERN_ERR "flash_write: write error %X\n", rc);
 			break;
 		}
 		p += rc;
 		buf += rc;
 		written += rc;
-		file->f_pos += rc;
+		*ppos += rc;
 
 		if (flashdebug)
-			printk("FlashWrite: written 0x%X bytes OK.\n", written);
+			printk(KERN_DEBUG "flash_write: written 0x%X bytes OK.\n", written);
 	}
 
 	/*
@@ -331,8 +303,8 @@
 static long long flash_llseek(struct file *file, long long offset, int orig)
 {
 	if (flashdebug)
-		printk("Flash_dev: flash_lseek, offset=0x%X, orig=0x%X.\n",
-		       (unsigned int) offset, (unsigned int) orig);
+		printk(KERN_DEBUG "flash_llseek: offset=0x%X, orig=0x%X.\n",
+		       (unsigned int) offset, orig);
 
 	switch (orig) {
 	case 0:
@@ -362,7 +334,7 @@
  * so just go ahead and erase, what requested!
  */
 
-MSTATIC int erase_block(int nBlock)
+static int erase_block(int nBlock)
 {
 	volatile unsigned int c1;
 	volatile unsigned char *pWritePtr;
@@ -440,13 +412,12 @@
 	 * check if erase errors were reported
 	 */
 	if (c1 & 0x20) {
-		if (flashdebug)
-			printk("Flash_erase: err at %X.\n", (unsigned int) pWritePtr);
+		printk(KERN_ERR "flash_erase: err at %p\n", pWritePtr);
+
 		/*
 		 * reset error
 		 */
 		*(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
-
 		return -2;
 	}
 
@@ -459,9 +430,8 @@
 
 	for (temp = 0; temp < 16 * 1024; temp++, pWritePtr += 4) {
 		if ((temp1 = *(volatile unsigned int *) pWritePtr) != 0xFFFFFFFF) {
-			if (flashdebug)
-				printk("Flash_erase: verify err at %X = %X.\n",
-				       (unsigned int) pWritePtr, temp1);
+			printk(KERN_ERR "flash_erase: verify err at %p = %X\n",
+			       pWritePtr, temp1);
 			return -1;
 		}
 	}
@@ -473,7 +443,7 @@
 /*
  * write_block will limit number of bytes written to the space in this block
  */
-MSTATIC int write_block(unsigned long p, const char *buf, int count)
+static int write_block(unsigned long p, const char *buf, int count)
 {
 	volatile unsigned int c1;
 	volatile unsigned int c2;
@@ -591,7 +561,7 @@
 			 */
 			if (time_before(jiffies, timeout)) {
 				if (flashdebug)
-					printk("FlashWrite: Retrying write (addr=0x%X)...\n",
+					printk(KERN_DEBUG "write_block: Retrying write at 0x%X)n",
 					       pWritePtr - FLASH_BASE);
 
 				/*
@@ -609,7 +579,7 @@
 
 				goto WriteRetry;
 			} else {
-				printk("Timeout in flash write! (addr=0x%X) Aborting...\n",
+				printk(KERN_ERR "write_block: timeout at 0x%X\n",
 				       pWritePtr - FLASH_BASE);
 				/*
 				 * return error -2
@@ -636,9 +606,8 @@
 			return -EFAULT;
 		buf++;
 		if ((c1 = *pWritePtr++) != c) {
-			if (flashdebug)
-				printk("flash write verify error at 0x%X! (%02X!=%02X) Retrying...\n",
-				       (unsigned int) pWritePtr, c1, c);
+			printk(KERN_ERR "write_block: verify error at 0x%X (%02X!=%02X)\n",
+			       pWritePtr - FLASH_BASE, c1, c);
 			return 0;
 		}
 	}
@@ -647,7 +616,7 @@
 }
 
 
-MSTATIC void kick_open(void)
+static void kick_open(void)
 {
 	unsigned long flags;
 
@@ -665,7 +634,23 @@
 	udelay(25);
 }
 
-MSTATIC int __init nwflash_init(void)
+static struct file_operations flash_fops =
+{
+	owner:		THIS_MODULE,
+	llseek:		flash_llseek,
+	read:		flash_read,
+	write:		flash_write,
+	ioctl:		flash_ioctl,
+};
+
+static struct miscdevice flash_miscdev =
+{
+	FLASH_MINOR,
+	"nwflash",
+	&flash_fops
+};
+
+static int __init nwflash_init(void)
 {
 	int ret = -ENODEV;
 
@@ -677,6 +662,13 @@
 			goto out;
 
 		id = get_flash_id();
+		if ((id != KFLASH_ID) && (id != KFLASH_ID4)) {
+			ret = -ENXIO;
+			iounmap((void *)FLASH_BASE);
+			printk("Flash: incorrect ID 0x%04X.\n", id);
+			goto out;
+		}
+
 		printk("Flash ROM driver v.%s, flash device ID 0x%04X, size %d Mb.\n",
 		       NWFLASH_VERSION, id, gbFlashSize / (1024 * 1024));
 
@@ -688,7 +680,7 @@
 	return ret;
 }
 
-MSTATIC void __exit nwflash_exit(void)
+static void __exit nwflash_exit(void)
 {
 	misc_deregister(&flash_miscdev);
 	iounmap((void *)FLASH_BASE);
diff -u --recursive --new-file v2.4.5/linux/drivers/char/random.c linux/drivers/char/random.c
--- v2.4.5/linux/drivers/char/random.c	Tue May  1 16:05:00 2001
+++ linux/drivers/char/random.c	Tue Jun 12 11:49:36 2001
@@ -1793,7 +1793,7 @@
 			 void *newval, size_t newlen, void **context)
 {
 	unsigned char	tmp_uuid[16], *uuid;
-	int	len;
+	unsigned int	len;
 
 	if (!oldval || !oldlenp)
 		return 1;
@@ -1810,7 +1810,7 @@
 	if (len) {
 		if (len > 16)
 			len = 16;
-		if (copy_to_user(oldval, table->data, len))
+		if (copy_to_user(oldval, uuid, len))
 			return -EFAULT;
 		if (put_user(len, oldlenp))
 			return -EFAULT;
diff -u --recursive --new-file v2.4.5/linux/drivers/char/raw.c linux/drivers/char/raw.c
--- v2.4.5/linux/drivers/char/raw.c	Sun May 20 11:34:05 2001
+++ linux/drivers/char/raw.c	Wed Jun 27 17:10:55 2001
@@ -194,7 +194,7 @@
 			break;
 		
 		minor = rq.raw_minor;
-		if (minor == 0 || minor > MINORMASK) {
+		if (minor <= 0 || minor > MINORMASK) {
 			err = -EINVAL;
 			break;
 		}
diff -u --recursive --new-file v2.4.5/linux/drivers/char/rio/rioroute.c linux/drivers/char/rio/rioroute.c
--- v2.4.5/linux/drivers/char/rio/rioroute.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/char/rio/rioroute.c	Mon Jun 11 19:15:27 2001
@@ -657,6 +657,7 @@
 			*/
 			if (PortP->TxStart == 0) {
 					rio_dprintk (RIO_DEBUG_ROUTE, "Tx pkts not set up yet\n");
+					rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 					break;
 			}
 
diff -u --recursive --new-file v2.4.5/linux/drivers/char/rtc.c linux/drivers/char/rtc.c
--- v2.4.5/linux/drivers/char/rtc.c	Thu Jan  4 12:50:17 2001
+++ linux/drivers/char/rtc.c	Tue Jun 12 11:08:46 2001
@@ -73,6 +73,9 @@
 
 #ifdef __sparc__
 #include <asm/ebus.h>
+#ifdef __sparc_v9__
+#include <asm/isa.h>
+#endif
 
 static unsigned long rtc_port;
 static int rtc_irq;
@@ -622,22 +625,37 @@
 #ifdef __sparc__
 	struct linux_ebus *ebus;
 	struct linux_ebus_device *edev;
+#ifdef __sparc_v9__
+	struct isa_bridge *isa_br;
+	struct isa_device *isa_dev;
+#endif
 #endif
 
 #ifdef __sparc__
 	for_each_ebus(ebus) {
 		for_each_ebusdev(edev, ebus) {
 			if(strcmp(edev->prom_name, "rtc") == 0) {
+				rtc_port = edev->resource[0].start;
+				rtc_irq = edev->irqs[0];
 				goto found;
 			}
 		}
 	}
+#ifdef __sparc_v9__
+	for_each_isa(isa_br) {
+		for_each_isadev(isa_dev, isa_br) {
+			if (strcmp(isa_dev->prom_name, "rtc") == 0) {
+				rtc_port = isa_dev->resource.start;
+				rtc_irq = isa_dev->irq;
+				goto found;
+			}
+		}
+	}
+#endif
 	printk(KERN_ERR "rtc_init: no PC rtc found\n");
 	return -EIO;
 
 found:
-	rtc_port = edev->resource[0].start;
-	rtc_irq = edev->irqs[0];
 	/*
 	 * XXX Interrupt pin #7 in Espresso is shared between RTC and
 	 * PCI Slot 2 INTA# (and some INTx# in Slot 1). SA_INTERRUPT here
diff -u --recursive --new-file v2.4.5/linux/drivers/char/sbc60xxwdt.c linux/drivers/char/sbc60xxwdt.c
--- v2.4.5/linux/drivers/char/sbc60xxwdt.c	Tue May 22 10:23:16 2001
+++ linux/drivers/char/sbc60xxwdt.c	Wed Jun 27 17:10:55 2001
@@ -174,9 +174,13 @@
 
 		/* now scan */
 		for(ofs = 0; ofs != count; ofs++) 
+		{
+			char c;
+			if(get_user(c, buf+ofs))
+				return -EFAULT;
 			if(buf[ofs] == 'V')
 				wdt_expect_close = 1;
-
+		}
 		/* Well, anyhow someone wrote to us, we should return that favour */
 		next_heartbeat = jiffies + WDT_HEARTBEAT;
 		return 1;
diff -u --recursive --new-file v2.4.5/linux/drivers/char/sh-sci.c linux/drivers/char/sh-sci.c
--- v2.4.5/linux/drivers/char/sh-sci.c	Wed Apr 11 21:24:52 2001
+++ linux/drivers/char/sh-sci.c	Wed Jun 27 13:55:29 2001
@@ -1035,7 +1035,11 @@
 	memset(&sci_driver, 0, sizeof(sci_driver));
 	sci_driver.magic = TTY_DRIVER_MAGIC;
 	sci_driver.driver_name = "sci";
+#ifdef CONFIG_DEVFS_FS
+	sci_driver.name = "ttsc/%d";
+#else
 	sci_driver.name = "ttySC";
+#endif
 	sci_driver.major = SCI_MAJOR;
 	sci_driver.minor_start = SCI_MINOR_START;
 	sci_driver.num = SCI_NPORTS;
@@ -1070,7 +1074,11 @@
 #endif
 
 	sci_callout_driver = sci_driver;
+#ifdef CONFIG_DEVFS_FS
+	sci_callout_driver.name = "cusc/%d";
+#else
 	sci_callout_driver.name = "cusc";
+#endif
 	sci_callout_driver.major = SCI_MAJOR+1;
 	sci_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
 	sci_callout_driver.read_proc = NULL;
diff -u --recursive --new-file v2.4.5/linux/drivers/char/sh-sci.h linux/drivers/char/sh-sci.h
--- v2.4.5/linux/drivers/char/sh-sci.h	Wed Apr 11 21:24:52 2001
+++ linux/drivers/char/sh-sci.h	Wed Jun 27 13:55:29 2001
@@ -46,7 +46,7 @@
 # define SCPDR  0xA4000136 /* 8  bit SCI and SCIF */
 # define SCSCR_INIT(port)          0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
 # define SCI_AND_SCIF
-#elif defined(CONFIG_CPU_SUBTYPE_SH7750)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751)
 # define SCI_NPORTS 2
 # define SCI_INIT { \
   { {}, PORT_SCI,  0xffe00000, SCI_IRQS,      sci_init_pins_sci  }, \
@@ -294,7 +294,7 @@
 		return ctrl_inb(SCPDR)&0x04 ? 1 : 0; /* IRDA */
 	return 1;
 }
-#elif defined(CONFIG_CPU_SUBTYPE_SH7750)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751)
 static inline int sci_rxd_in(struct sci_port *port)
 {
 #ifndef SCIF_ONLY
diff -u --recursive --new-file v2.4.5/linux/drivers/char/sx.c linux/drivers/char/sx.c
--- v2.4.5/linux/drivers/char/sx.c	Fri Apr  6 10:42:55 2001
+++ linux/drivers/char/sx.c	Wed Jun 27 14:13:01 2001
@@ -467,7 +467,7 @@
 	int i, j, ch;
 
 	for (i=0;i<len;i+=16) {
-		printk ("%08x ", (int) addr+i);
+		printk ("%p ", addr+i);
 		for (j=0;j<16;j++) {
 			printk ("%02x %s", addr[j+i], (j==7)?" ":"");
 		}
@@ -1639,7 +1639,8 @@
 	int rc = 0;
 	int *descr = (int *)arg, i;
 	static struct sx_board *board = NULL;
-	int nbytes, offset, data;
+	int nbytes, offset;
+	unsigned long data;
 	char *tmp;
 
 	func_enter();
@@ -2098,7 +2099,7 @@
 	func_enter();
 
 	if (!IS_CF_BOARD (board)) {    
-		sx_dprintk (SX_DEBUG_PROBE, "Going to verify vpd prom at %x.\n", 
+		sx_dprintk (SX_DEBUG_PROBE, "Going to verify vpd prom at %lx.\n", 
 		            board->base + SX_VPD_ROM);
 
 		if (sx_debug & SX_DEBUG_PROBE)
@@ -2123,7 +2124,7 @@
 	printheader ();
 
 	if (!IS_CF_BOARD (board)) {
-		printk (KERN_DEBUG "sx: Found an SX board at %x\n", board->hw_base);
+		printk (KERN_DEBUG "sx: Found an SX board at %lx\n", board->hw_base);
 		printk (KERN_DEBUG "sx: hw_rev: %d, assembly level: %d, uniq ID:%08x, ", 
 		        vpdp.hwrev, vpdp.hwass, vpdp.uniqid);
 		printk (           "Manufactured: %d/%d\n", 
@@ -2140,7 +2141,7 @@
 
 		if (((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) == SX_ISA_UNIQUEID1) {
 			if (board->base & 0x8000) {
-				printk (KERN_WARNING "sx: Warning: There may be hardware problems with the card at %x.\n", board->base);
+				printk (KERN_WARNING "sx: Warning: There may be hardware problems with the card at %lx.\n", board->base);
 				printk (KERN_WARNING "sx: Read sx.txt for more info.\n");
 			}
 		}
@@ -2172,7 +2173,7 @@
 	int i;
 
 	func_enter();
-	sx_dprintk (SX_DEBUG_PROBE, "Going to verify SI signature %x.\n", 
+	sx_dprintk (SX_DEBUG_PROBE, "Going to verify SI signature %lx.\n", 
 	            board->base + SI2_ISA_ID_BASE);
 
 	if (sx_debug & SX_DEBUG_PROBE)
@@ -2188,7 +2189,7 @@
 
 	printheader ();
 
-	printk (KERN_DEBUG "sx: Found an SI board at %x\n", board->hw_base);
+	printk (KERN_DEBUG "sx: Found an SI board at %lx\n", board->hw_base);
 	/* Compared to the SX boards, it is a complete guess as to what
 		 this card is up to... */
 
@@ -2507,7 +2508,7 @@
 
 			board->irq = get_irq (pdev);
 
-			sx_dprintk (SX_DEBUG_PROBE, "Got a specialix card: %x/%x(%d) %x.\n", 
+			sx_dprintk (SX_DEBUG_PROBE, "Got a specialix card: %x/%lx(%d) %x.\n", 
 			            tint, boards[found].base, board->irq, board->flags);
 
 			if (probe_sx (board)) {
@@ -2569,8 +2570,8 @@
 			board->base2 =
 			board->base = (ulong) ioremap(board->hw_base, SI2_EISA_WINDOW_LEN);
 
-			sx_dprintk(SX_DEBUG_PROBE, "IO hw_base address: %x\n", board->hw_base);
-			sx_dprintk(SX_DEBUG_PROBE, "base: %x\n", board->base);
+			sx_dprintk(SX_DEBUG_PROBE, "IO hw_base address: %lx\n", board->hw_base);
+			sx_dprintk(SX_DEBUG_PROBE, "base: %lx\n", board->base);
 			board->irq = inb(board->eisa_base+0xc02)>>4; 
 			sx_dprintk(SX_DEBUG_PROBE, "IRQ: %d\n", board->irq);
 			
@@ -2602,7 +2603,7 @@
 	for (i = 0; i < SX_NBOARDS; i++) {
 		board = &boards[i];
 		if (board->flags & SX_BOARD_INITIALIZED) {
-			sx_dprintk (SX_DEBUG_CLEANUP, "Cleaning up board at %x\n", board->base);
+			sx_dprintk (SX_DEBUG_CLEANUP, "Cleaning up board at %lx\n", board->base);
 			/* The board should stop messing with us.
 			   (actually I mean the interrupt) */
 			sx_reset (board);
diff -u --recursive --new-file v2.4.5/linux/drivers/char/sx.h linux/drivers/char/sx.h
--- v2.4.5/linux/drivers/char/sx.h	Mon Dec 11 13:38:29 2000
+++ linux/drivers/char/sx.h	Wed Jun 27 14:13:01 2001
@@ -36,9 +36,9 @@
 
 struct sx_board {
   int magic;
-  unsigned int base;
-  unsigned int base2;
-  unsigned int hw_base;
+  unsigned long base;
+  unsigned long base2;
+  unsigned long hw_base;
   int eisa_base;
   int port_base; /* Number of the first port */
   struct sx_port *ports;
diff -u --recursive --new-file v2.4.5/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c
--- v2.4.5/linux/drivers/char/tty_io.c	Thu Apr 26 17:35:49 2001
+++ linux/drivers/char/tty_io.c	Wed Jun 27 13:37:35 2001
@@ -148,6 +148,7 @@
 extern long serial167_console_init(void);
 extern void console_8xx_init(void);
 extern int rs_8xx_init(void);
+extern void mac_scc_console_init(void);
 extern void hwc_console_init(void);
 extern void hwc_tty_init(void);
 extern void con3215_init(void);
@@ -2184,6 +2185,8 @@
 #ifdef CONFIG_SERIAL_CONSOLE
 #if (defined(CONFIG_8xx) || defined(CONFIG_8260))
 	console_8xx_init();
+#elif defined(CONFIG_MAC_SERIAL)
+	mac_scc_console_init();
 #elif defined(CONFIG_SERIAL)
 	serial_console_init();
 #endif /* CONFIG_8xx */
@@ -2306,9 +2309,6 @@
 #endif
 #ifdef CONFIG_COMPUTONE
 	ip2_init();
-#endif
-#ifdef CONFIG_MAC_SERIAL
-	macserial_init();
 #endif
 #ifdef CONFIG_ROCKETPORT
 	rp_init();
diff -u --recursive --new-file v2.4.5/linux/drivers/i2o/i2o_lan.c linux/drivers/i2o/i2o_lan.c
--- v2.4.5/linux/drivers/i2o/i2o_lan.c	Sun May 20 12:11:38 2001
+++ linux/drivers/i2o/i2o_lan.c	Mon Jun 11 19:15:27 2001
@@ -984,7 +984,7 @@
 		__raw_writel(priv->unit << 16 | lan_send_context, msg+2); // InitiatorContext
 		__raw_writel(1 << 30 | 1 << 3, msg+3); 		 	  // TransmitControlWord
 			// bit 30: reply as soon as transmission attempt is complete
-			// bit 3: Supress CRC generation
+			// bit 3: Suppress CRC generation
 		__raw_writel(0xD5000000 | skb->len, msg+4);  	     // MAC hdr included
 		__raw_writel((u32)skb, msg+5);  		     // TransactionContext
 		__raw_writel(virt_to_bus(skb->data), msg+6);
diff -u --recursive --new-file v2.4.5/linux/drivers/ide/hpt366.c linux/drivers/ide/hpt366.c
--- v2.4.5/linux/drivers/ide/hpt366.c	Sat May 19 17:43:06 2001
+++ linux/drivers/ide/hpt366.c	Wed Jun 27 17:10:55 2001
@@ -51,6 +51,16 @@
 };
 
 const char *bad_ata100_5[] = {
+	"IBM-DTLA-307075",
+	"IBM-DTLA-307060",
+	"IBM-DTLA-307045",
+	"IBM-DTLA-307030",
+	"IBM-DTLA-307020",
+	"IBM-DTLA-307015",
+	"IBM-DTLA-305040",
+	"IBM-DTLA-305030",
+	"IBM-DTLA-305020",
+	"WDC AC310200R",
 	NULL
 };
 
diff -u --recursive --new-file v2.4.5/linux/drivers/ide/ide-floppy.c linux/drivers/ide/ide-floppy.c
--- v2.4.5/linux/drivers/ide/ide-floppy.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/ide/ide-floppy.c	Thu Jun 14 14:16:58 2001
@@ -237,7 +237,7 @@
 	idefloppy_flexible_disk_page_t flexible_disk_page;	/* Copy of the flexible disk page */
 	int wp;							/* Write protect */
 
-	unsigned int flags;			/* Status/Action flags */
+	unsigned long flags;			/* Status/Action flags */
 } idefloppy_floppy_t;
 
 /*
diff -u --recursive --new-file v2.4.5/linux/drivers/ide/ide-pci.c linux/drivers/ide/ide-pci.c
--- v2.4.5/linux/drivers/ide/ide-pci.c	Sun May 20 11:32:11 2001
+++ linux/drivers/ide/ide-pci.c	Wed Jun 27 14:12:04 2001
@@ -34,7 +34,8 @@
 #define DEVID_PIIX4U	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801AA_1})
 #define DEVID_PIIX4U2	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82372FB_1})
 #define DEVID_PIIX4NX	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82451NX})
-#define DEVID_PIIX4U3	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82820FW_5})
+#define DEVID_PIIX4U3	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801BA_9})
+#define DEVID_PIIX4U4	((ide_pci_devid_t){PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801BA_8})
 #define DEVID_VIA_IDE	((ide_pci_devid_t){PCI_VENDOR_ID_VIA,     PCI_DEVICE_ID_VIA_82C561})
 #define DEVID_VP_IDE	((ide_pci_devid_t){PCI_VENDOR_ID_VIA,     PCI_DEVICE_ID_VIA_82C586_1})
 #define DEVID_PDC20246	((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246})
@@ -282,13 +283,16 @@
 #endif
 
 #ifdef CONFIG_BLK_DEV_SL82C105
+extern unsigned int pci_init_sl82c105(struct pci_dev *, const char *);
+extern void dma_init_sl82c105(ide_hwif_t *, unsigned long);
 extern void ide_init_sl82c105(ide_hwif_t *);
-extern void ide_dmacapable_sl82c105(ide_hwif_t *, unsigned long);
+#define PCI_W82C105	&pci_init_sl82c105
+#define DMA_W82C105	&dma_init_sl82c105
 #define INIT_W82C105	&ide_init_sl82c105
-#define DMA_W82C105	&ide_dmacapable_sl82c105
 #else
-#define INIT_W82C105	IDE_IGNORE
+#define PCI_W82C105	NULL
 #define DMA_W82C105	NULL
+#define INIT_W82C105	IDE_IGNORE
 #endif
 
 #ifdef CONFIG_BLK_DEV_TRM290
@@ -343,6 +347,7 @@
 	{DEVID_PIIX4U2,	"PIIX4",	PCI_PIIX,	ATA66_PIIX,	INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
 	{DEVID_PIIX4NX,	"PIIX4",	PCI_PIIX,	NULL,		INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
 	{DEVID_PIIX4U3,	"PIIX4",	PCI_PIIX,	ATA66_PIIX,	INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
+	{DEVID_PIIX4U4, "PIIX4",	PCI_PIIX,	ATA66_PIIX,	INIT_PIIX,	NULL,		{{0x41,0x80,0x80}, {0x43,0x80,0x80}},	ON_BOARD,	0 },
 	{DEVID_VIA_IDE,	"VIA_IDE",	NULL,		NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
 	{DEVID_VP_IDE,	"VP_IDE",	PCI_VIA82CXXX,	ATA66_VIA82CXXX,INIT_VIA82CXXX,	DMA_VIA82CXXX,	{{0x40,0x02,0x02}, {0x40,0x01,0x01}}, 	ON_BOARD,	0 },
 	{DEVID_PDC20246,"PDC20246",	PCI_PDC202XX,	NULL,		INIT_PDC202XX,	NULL,		{{0x50,0x02,0x02}, {0x50,0x04,0x04}}, 	OFF_BOARD,	16 },
@@ -367,7 +372,7 @@
 	{DEVID_AEC6210,	"AEC6210",	PCI_AEC62XX,	NULL,		INIT_AEC62XX,	DMA_AEC62XX,	{{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, 	OFF_BOARD,	0 },
 	{DEVID_AEC6260,	"AEC6260",	PCI_AEC62XX,	ATA66_AEC62XX,	INIT_AEC62XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	NEVER_BOARD,	0 },
 	{DEVID_AEC6260R,"AEC6260R",	PCI_AEC62XX,	ATA66_AEC62XX,	INIT_AEC62XX,	NULL,		{{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},	OFF_BOARD,	0 },
-	{DEVID_W82C105,	"W82C105",	NULL,		NULL,		INIT_W82C105,	DMA_W82C105,	{{0x40,0x01,0x01}, {0x40,0x10,0x10}}, 	ON_BOARD,	0 },
+	{DEVID_W82C105,	"W82C105",	PCI_W82C105,	NULL,		INIT_W82C105,	DMA_W82C105,	{{0x40,0x01,0x01}, {0x40,0x10,0x10}}, 	ON_BOARD,	0 },
 	{DEVID_UM8673F,	"UM8673F",	NULL,		NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
 	{DEVID_UM8886A,	"UM8886A",	NULL,		NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
 	{DEVID_UM8886BF,"UM8886BF",	NULL,		NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0 },
diff -u --recursive --new-file v2.4.5/linux/drivers/ide/ide-tape.c linux/drivers/ide/ide-tape.c
--- v2.4.5/linux/drivers/ide/ide-tape.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/ide/ide-tape.c	Tue Jun 12 11:09:03 2001
@@ -1,8 +1,10 @@
 /*
- * linux/drivers/ide/ide-tape.c		Version 1.16f	Dec  15, 1999
+ * linux/drivers/ide/ide-tape.c		Version 1.17a	Jan, 2001
  *
  * Copyright (C) 1995 - 1999 Gadi Oxman <gadio@netvision.net.il>
  *
+ * $Header$
+ *
  * This driver was constructed as a student project in the software laboratory
  * of the faculty of electrical engineering in the Technion - Israel's
  * Institute Of Technology, with the guide of Avner Lottem and Dr. Ilana David.
@@ -274,7 +276,21 @@
  *			this section correctly, a hypothetical and unwanted situation
  *			 is being described)
  * Ver 1.16f Dec 15 99   Change place of the secondary OnStream header frames.
- *
+ * Ver 1.17  Nov 2000 / Jan 2001  Marcel Mol, marcel@mesa.nl
+ *			- Add idetape_onstream_mode_sense_tape_parameter_page
+ *			  function to get tape capacity in frames: tape->capacity.
+ *			- Add support for DI-50 drives( or any DI- drive).
+ *			- 'workaround' for read error/blank block arround block 3000.
+ *			- Implement Early warning for end of media for Onstream.
+ *			- Cosmetic code changes for readability.
+ *			- Idetape_position_tape should not use SKIP bit during
+ *			  Onstream read recovery.
+ *			- Add capacity, logical_blk_num and first/last_frame_position
+ *			  to /proc/ide/hd?/settings.
+ *			- Module use count was gone in the Linux 2.4 driver.
+ * Ver 1.17a Apr 2001 Willem Riede osst@riede.org
+ * 			- Get drive's actual block size from mode sense block descriptor
+ * 			- Limit size of pipeline
  *
  * Here are some words from the first releases of hd.c, which are quoted
  * in ide.c and apply here as well:
@@ -384,7 +400,7 @@
  *		sharing a (fast) ATA-2 disk with any (slow) new ATAPI device.
  */
 
-#define IDETAPE_VERSION "1.16f"
+#define IDETAPE_VERSION "1.17a"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -421,7 +437,11 @@
 #define OS_CONFIG_PARTITION	(0xff)
 #define OS_DATA_PARTITION	(0)
 #define OS_PARTITION_VERSION	(1)
+#define OS_EW			300
+#define OS_ADR_MINREV		2
 
+#define OS_DATA_STARTFRAME1	20
+#define OS_DATA_ENDFRAME1	2980
 /*
  * partition
  */
@@ -512,12 +532,33 @@
 } os_header_t;
 
 /*
+ *	OnStream Tape Parameters Page
+ */
+typedef struct {
+	unsigned	page_code	:6;	/* Page code - Should be 0x2b */
+	unsigned	reserved1_6	:1;
+	unsigned	ps		:1;
+	__u8		reserved2;
+	__u8		density;		/* kbpi */
+	__u8		reserved3,reserved4;
+	__u16		segtrk;                 /* segment of per track */
+	__u16		trks;                   /* tracks per tape */
+	__u8		reserved5,reserved6,reserved7,reserved8,reserved9,reserved10;
+} onstream_tape_paramtr_page_t;
+
+/*
  * OnStream ADRL frame
  */
 #define OS_FRAME_SIZE	(32 * 1024 + 512)
 #define OS_DATA_SIZE	(32 * 1024)
 #define OS_AUX_SIZE	(512)
 
+/*
+ * internal error codes for onstream
+ */
+#define OS_PART_ERROR    2
+#define OS_WRITE_ERROR   1
+
 #include <linux/mtio.h>
 
 /**************************** Tunable parameters *****************************/
@@ -559,7 +600,7 @@
  *	is verified to be stable enough. This will make it much more
  *	esthetic.
  */
-#define IDETAPE_DEBUG_INFO		0
+#define IDETAPE_DEBUG_INFO		1
 #define IDETAPE_DEBUG_LOG		1
 #define IDETAPE_DEBUG_LOG_VERBOSE	0
 #define IDETAPE_DEBUG_BUGS		1
@@ -949,6 +990,7 @@
 	int eod_frame_addr;
 	unsigned long cmd_start_time;
 	unsigned long max_cmd_time;
+	unsigned capacity;
 
 	/*
 	 * Optimize the number of "buffer filling"
@@ -1157,7 +1199,7 @@
 typedef union {
 	unsigned all			:8;
 	struct {
-		unsigned dma		:1;	/* Using DMA of PIO */
+		unsigned dma		:1;	/* Using DMA or PIO */
 		unsigned reserved321	:3;	/* Reserved */
 		unsigned reserved654	:3;	/* Reserved (Tag Type) */
 		unsigned reserved7	:1;	/* Reserved */
@@ -1286,8 +1328,11 @@
  *	packet commands. Those packet commands are still not supported
  *	by ide-tape.
  */
+#define IDETAPE_BLOCK_DESCRIPTOR	0
 #define	IDETAPE_CAPABILITIES_PAGE	0x2a
+#define IDETAPE_PARAMTR_PAGE		0x2b   /* Onstream DI-x0 only */
 #define IDETAPE_BLOCK_SIZE_PAGE		0x30
+#define IDETAPE_BUFFER_FILLING_PAGE	0x33
 
 /*
  *	Mode Parameter Header for the MODE SENSE packet command
@@ -1428,6 +1473,14 @@
 #endif /* IDETAPE_DEBUG_LOG_VERBOSE */
 
 /*
+ *      Function declarations
+ *
+ */
+static void idetape_onstream_mode_sense_tape_parameter_page(ide_drive_t *drive, int debug);
+static int idetape_chrdev_release (struct inode *inode, struct file *filp);
+static void idetape_write_release (struct inode *inode);
+
+/*
  *	Too bad. The drive wants to send us data which we are not ready to accept.
  *	Just throw it away.
  */
@@ -1452,7 +1505,8 @@
 #endif /* IDETAPE_DEBUG_BUGS */
 		count = IDE_MIN (bh->b_size - atomic_read(&bh->b_count), bcount);
 		atapi_input_bytes (drive, bh->b_data + atomic_read(&bh->b_count), count);
-		bcount -= count; atomic_add(count, &bh->b_count);
+		bcount -= count;
+		atomic_add(count, &bh->b_count);
 		if (atomic_read(&bh->b_count) == bh->b_size) {
 			bh = bh->b_reqnext;
 			if (bh)
@@ -1476,7 +1530,9 @@
 #endif /* IDETAPE_DEBUG_BUGS */
 		count = IDE_MIN (pc->b_count, bcount);
 		atapi_output_bytes (drive, pc->b_data, count);
-		bcount -= count; pc->b_data += count; pc->b_count -= count;
+		bcount -= count;
+		pc->b_data += count;
+		pc->b_count -= count;
 		if (!pc->b_count) {
 			pc->bh = bh = bh->b_reqnext;
 			if (bh) {
@@ -1577,20 +1633,23 @@
  *	to analyze the request sense. We currently do not utilize this
  *	information.
  */
-static void idetape_analyze_error (ide_drive_t *drive,idetape_request_sense_result_t *result)
+static void idetape_analyze_error (ide_drive_t *drive, idetape_request_sense_result_t *result)
 {
 	idetape_tape_t *tape = drive->driver_data;
 	idetape_pc_t *pc = tape->failed_pc;
 
-	tape->sense = *result;
-	tape->sense_key = result->sense_key; tape->asc = result->asc; tape->ascq = result->ascq;
+	tape->sense     = *result;
+	tape->sense_key = result->sense_key;
+	tape->asc       = result->asc;
+	tape->ascq      = result->ascq;
 #if IDETAPE_DEBUG_LOG
 	/*
 	 *	Without debugging, we only log an error if we decided to
 	 *	give up retrying.
 	 */
 	if (tape->debug_level >= 1)
-		printk (KERN_INFO "ide-tape: pc = %x, sense key = %x, asc = %x, ascq = %x\n",pc->c[0],result->sense_key,result->asc,result->ascq);
+		printk (KERN_INFO "ide-tape: pc = %x, sense key = %x, asc = %x, ascq = %x\n",
+				pc->c[0], result->sense_key, result->asc, result->ascq);
 #if IDETAPE_DEBUG_LOG_VERBOSE
 	if (tape->debug_level >= 1)
 		printk (KERN_INFO "ide-tape: pc = %s, sense key = %x, asc = %x, ascq = %x\n",
@@ -1660,7 +1719,7 @@
 static void idetape_active_next_stage (ide_drive_t *drive)
 {
 	idetape_tape_t *tape = drive->driver_data;
-	idetape_stage_t *stage=tape->next_stage;
+	idetape_stage_t *stage = tape->next_stage;
 	struct request *rq = &stage->rq;
 
 #if IDETAPE_DEBUG_LOG
@@ -1676,9 +1735,9 @@
 
 	rq->buffer = NULL;
 	rq->bh = stage->bh;
-	tape->active_data_request=rq;
-	tape->active_stage=stage;
-	tape->next_stage=stage->next;
+	tape->active_data_request = rq;
+	tape->active_stage = stage;
+	tape->next_stage = stage->next;
 }
 
 /*
@@ -1756,12 +1815,12 @@
 		return;
 	}
 #endif /* IDETAPE_DEBUG_BUGS */
-	stage=tape->first_stage;
-	tape->first_stage=stage->next;
+	stage = tape->first_stage;
+	tape->first_stage = stage->next;
 	idetape_kfree_stage (tape, stage);
 	tape->nr_stages--;
 	if (tape->first_stage == NULL) {
-		tape->last_stage=NULL;
+		tape->last_stage = NULL;
 #if IDETAPE_DEBUG_BUGS
 		if (tape->next_stage != NULL)
 			printk (KERN_ERR "ide-tape: bug: tape->next_stage != NULL\n");
@@ -1821,12 +1880,12 @@
 			}
 #endif
 			if (tape->onstream && !tape->raw) {
-				if (tape->first_frame_position == 0xba4) {
+				if (tape->first_frame_position == OS_DATA_ENDFRAME1) { 
 #if ONSTREAM_DEBUG
-				if (tape->debug_level >= 2)
-					printk("ide-tape: %s: skipping over config parition..\n", tape->name);
+					if (tape->debug_level >= 2)
+						printk("ide-tape: %s: skipping over config parition..\n", tape->name);
 #endif
-					tape->onstream_write_error = 2;
+					tape->onstream_write_error = OS_PART_ERROR;
 					if (tape->sem)
 						up(tape->sem);
 				}
@@ -1839,7 +1898,7 @@
 				if (tape->onstream && !tape->raw && error == IDETAPE_ERROR_GENERAL && tape->sense.sense_key == 3) {
 					clear_bit (IDETAPE_PIPELINE_ERROR, &tape->flags);
 					printk(KERN_ERR "ide-tape: %s: write error, enabling error recovery\n", tape->name);
-					tape->onstream_write_error = 1;
+					tape->onstream_write_error = OS_WRITE_ERROR;
 					remove_stage = 0;
 					tape->nr_pending_stages++;
 					tape->next_stage = tape->first_stage;
@@ -1883,11 +1942,11 @@
 		printk (KERN_INFO "ide-tape: Reached idetape_request_sense_callback\n");
 #endif /* IDETAPE_DEBUG_LOG */
 	if (!tape->pc->error) {
-		idetape_analyze_error (drive,(idetape_request_sense_result_t *) tape->pc->buffer);
-		idetape_end_request (1,HWGROUP (drive));
+		idetape_analyze_error (drive, (idetape_request_sense_result_t *) tape->pc->buffer);
+		idetape_end_request (1, HWGROUP (drive));
 	} else {
 		printk (KERN_ERR "ide-tape: Error in REQUEST SENSE itself - Aborting request!\n");
-		idetape_end_request (0,HWGROUP (drive));
+		idetape_end_request (0, HWGROUP (drive));
 	}
 	return ide_stopped;
 }
@@ -1980,7 +2039,7 @@
 	idetape_status_reg_t status;
 	idetape_bcount_reg_t bcount;
 	idetape_ireason_reg_t ireason;
-	idetape_pc_t *pc=tape->pc;
+	idetape_pc_t *pc = tape->pc;
 
 	unsigned int temp;
 	unsigned long cmd_time;
@@ -2011,7 +2070,7 @@
 			 */
 			set_bit (PC_DMA_ERROR, &pc->flags);
 		} else if (!status.b.check) {
-			pc->actually_transferred=pc->request_transfer;
+			pc->actually_transferred = pc->request_transfer;
 			idetape_update_buffers (pc);
 		}
 #if IDETAPE_DEBUG_LOG
@@ -2064,7 +2123,7 @@
 			return ide_stopped;
 		}
 		if (tape->failed_pc == pc)
-			tape->failed_pc=NULL;
+			tape->failed_pc = NULL;
 		return pc->callback(drive);			/* Command finished - Call the callback function */
 	}
 #ifdef CONFIG_BLK_DEV_IDEDMA
@@ -2075,9 +2134,9 @@
 		return ide_do_reset (drive);
 	}
 #endif /* CONFIG_BLK_DEV_IDEDMA */
-	bcount.b.high=IN_BYTE (IDE_BCOUNTH_REG);			/* Get the number of bytes to transfer */
-	bcount.b.low=IN_BYTE (IDE_BCOUNTL_REG);				/* on this interrupt */
-	ireason.all=IN_BYTE (IDE_IREASON_REG);
+	bcount.b.high = IN_BYTE (IDE_BCOUNTH_REG);			/* Get the number of bytes to transfer */
+	bcount.b.low  = IN_BYTE (IDE_BCOUNTL_REG);			/* on this interrupt */
+	ireason.all   = IN_BYTE (IDE_IREASON_REG);
 
 	if (ireason.b.cod) {
 		printk (KERN_ERR "ide-tape: CoD != 0 in idetape_pc_intr\n");
@@ -2093,8 +2152,8 @@
 		if ( temp > pc->request_transfer) {
 			if (temp > pc->buffer_size) {
 				printk (KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n");
-				idetape_discard_data (drive,bcount.all);
-				ide_set_handler (drive,&idetape_pc_intr,IDETAPE_WAIT_CMD,NULL);
+				idetape_discard_data (drive, bcount.all);
+				ide_set_handler (drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);
 				return ide_started;
 			}
 #if IDETAPE_DEBUG_LOG
@@ -2114,13 +2173,13 @@
 		else
 			atapi_input_bytes (drive,pc->current_position,bcount.all);	/* Read the current buffer */
 	}
-	pc->actually_transferred+=bcount.all;					/* Update the current position */
+	pc->actually_transferred += bcount.all;					/* Update the current position */
 	pc->current_position+=bcount.all;
 #if IDETAPE_DEBUG_LOG
 	if (tape->debug_level >= 2)
 		printk(KERN_INFO "ide-tape: [cmd %x] transferred %d bytes on that interrupt\n", pc->c[0], bcount.all);
 #endif
-	ide_set_handler (drive,&idetape_pc_intr,IDETAPE_WAIT_CMD,NULL);		/* And set the interrupt handler again */
+	ide_set_handler (drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);	/* And set the interrupt handler again */
 	return ide_started;
 }
 
@@ -2178,7 +2237,7 @@
 		printk (KERN_ERR "ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n");
 		return startstop;
 	}
-	ireason.all=IN_BYTE (IDE_IREASON_REG);
+	ireason.all = IN_BYTE (IDE_IREASON_REG);
 	while (retries-- && (!ireason.b.cod || ireason.b.io)) {
 		printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing a packet command, retrying\n");
 		udelay(100);
@@ -2203,7 +2262,7 @@
 {
 	idetape_tape_t *tape = drive->driver_data;
 	idetape_bcount_reg_t bcount;
-	int dma_ok=0;
+	int dma_ok = 0;
 
 #if IDETAPE_DEBUG_BUGS
 	if (tape->pc->c[0] == IDETAPE_REQUEST_SENSE_CMD && pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) {
@@ -2212,8 +2271,8 @@
 #endif /* IDETAPE_DEBUG_BUGS */
 
 	if (tape->failed_pc == NULL && pc->c[0] != IDETAPE_REQUEST_SENSE_CMD)
-		tape->failed_pc=pc;
-	tape->pc=pc;							/* Set the current packet command */
+		tape->failed_pc = pc;
+	tape->pc = pc;							/* Set the current packet command */
 
 	if (pc->retries > IDETAPE_MAX_PC_RETRIES || test_bit (PC_ABORT, &pc->flags)) {
 		/*
@@ -2223,24 +2282,25 @@
 		 *	example).
 		 */
 		if (!test_bit (PC_ABORT, &pc->flags)) {
-			if (!(pc->c[0] == 0 && tape->sense_key == 2 && tape->asc == 4 && (tape->ascq == 1 || tape->ascq == 8))) {
+			if (!(pc->c[0] == IDETAPE_TEST_UNIT_READY_CMD && tape->sense_key == 2 &&
+			      tape->asc == 4 && (tape->ascq == 1 || tape->ascq == 8))) {
 				printk (KERN_ERR "ide-tape: %s: I/O error, pc = %2x, key = %2x, asc = %2x, ascq = %2x\n",
 					tape->name, pc->c[0], tape->sense_key, tape->asc, tape->ascq);
-				if (tape->onstream && pc->c[0] == 8 && tape->sense_key == 3 && tape->asc == 0x11)  /* AJN-1: 11 should be 0x11 */
+				if (tape->onstream && pc->c[0] == IDETAPE_READ_CMD && tape->sense_key == 3 && tape->asc == 0x11)  /* AJN-1: 11 should be 0x11 */
 					printk(KERN_ERR "ide-tape: %s: enabling read error recovery\n", tape->name);
 			}
 			pc->error = IDETAPE_ERROR_GENERAL;		/* Giving up */
 		}
-		tape->failed_pc=NULL;
+		tape->failed_pc = NULL;
 		return pc->callback(drive);
 	}
 #if IDETAPE_DEBUG_LOG
 	if (tape->debug_level >= 2)
-		printk (KERN_INFO "ide-tape: Retry number - %d\n",pc->retries);
+		printk (KERN_INFO "ide-tape: Retry number - %d\n", pc->retries);
 #endif /* IDETAPE_DEBUG_LOG */
 
 	pc->retries++;
-	pc->actually_transferred=0;					/* We haven't transferred any data yet */
+	pc->actually_transferred = 0;					/* We haven't transferred any data yet */
 	pc->current_position=pc->buffer;
 	bcount.all=pc->request_transfer;				/* Request to transfer the entire buffer at once */
 
@@ -2250,15 +2310,15 @@
 		(void) HWIF(drive)->dmaproc(ide_dma_off, drive);
 	}
 	if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
-		dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive);
+		dma_ok = !HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive);
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
 	if (IDE_CONTROL_REG)
-		OUT_BYTE (drive->ctl,IDE_CONTROL_REG);
-	OUT_BYTE (dma_ok ? 1:0,IDE_FEATURE_REG);			/* Use PIO/DMA */
-	OUT_BYTE (bcount.b.high,IDE_BCOUNTH_REG);
-	OUT_BYTE (bcount.b.low,IDE_BCOUNTL_REG);
-	OUT_BYTE (drive->select.all,IDE_SELECT_REG);
+		OUT_BYTE (drive->ctl, IDE_CONTROL_REG);
+	OUT_BYTE (dma_ok ? 1 : 0,    IDE_FEATURE_REG);			/* Use PIO/DMA */
+	OUT_BYTE (bcount.b.high,     IDE_BCOUNTH_REG);
+	OUT_BYTE (bcount.b.low,      IDE_BCOUNTL_REG);
+	OUT_BYTE (drive->select.all, IDE_SELECT_REG);
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (dma_ok) {						/* Begin DMA, if necessary */
 		set_bit (PC_DMA_IN_PROGRESS, &pc->flags);
@@ -2287,7 +2347,7 @@
 		printk (KERN_INFO "ide-tape: Reached idetape_pc_callback\n");
 #endif /* IDETAPE_DEBUG_LOG */
 
-	idetape_end_request (tape->pc->error ? 0:1, HWGROUP(drive));
+	idetape_end_request (tape->pc->error ? 0 : 1, HWGROUP(drive));
 	return ide_stopped;
 }
 
@@ -2298,11 +2358,14 @@
 {
 	idetape_init_pc (pc);
 	pc->c[0] = IDETAPE_MODE_SENSE_CMD;
-	pc->c[1] = 8;				/* DBD = 1 - Don't return block descriptors for now */
+	if (page_code != IDETAPE_BLOCK_DESCRIPTOR)
+		pc->c[1] = 8;			/* DBD = 1 - Don't return block descriptors */
 	pc->c[2] = page_code;
 	pc->c[3] = 255;				/* Don't limit the returned information */
 	pc->c[4] = 255;				/* (We will just discard data in that case) */
-	if (page_code == IDETAPE_CAPABILITIES_PAGE)
+	if (page_code == IDETAPE_BLOCK_DESCRIPTOR)
+		pc->request_transfer = 12;
+	else if (page_code == IDETAPE_CAPABILITIES_PAGE)
 		pc->request_transfer = 24;
 	else
 		pc->request_transfer = 50;
@@ -2333,7 +2396,7 @@
 	if (tape->debug_level >= 1)
 		printk(KERN_INFO "ide-tape: buffer fill callback, %d/%d\n", tape->cur_frames, tape->max_frames);
 #endif
-	idetape_end_request (tape->pc->error ? 0:1, HWGROUP(drive));
+	idetape_end_request (tape->pc->error ? 0 : 1, HWGROUP(drive));
 	return ide_stopped;
 }
 
@@ -2344,7 +2407,7 @@
 
 	pc = idetape_next_pc_storage (drive);
 	rq = idetape_next_rq_storage (drive);
-	idetape_create_mode_sense_cmd (pc, 0x33);
+	idetape_create_mode_sense_cmd (pc, IDETAPE_BUFFER_FILLING_PAGE);
 	pc->callback = idetape_onstream_buffer_fill_callback;
 	idetape_queue_pc_head (drive, pc, rq);
 }
@@ -2564,7 +2627,7 @@
 		 *	We do not support buffer cache originated requests.
 		 */
 		printk (KERN_NOTICE "ide-tape: %s: Unsupported command in request queue (%d)\n", drive->name, rq->cmd);
-		ide_end_request (0,HWGROUP (drive));			/* Let the common code handle it */
+		ide_end_request (0, HWGROUP (drive));			/* Let the common code handle it */
 		return ide_stopped;
 	}
 
@@ -2578,7 +2641,7 @@
 	if (postponed_rq != NULL)
 		if (rq != postponed_rq) {
 			printk (KERN_ERR "ide-tape: ide-tape.c bug - Two DSC requests were queued\n");
-			idetape_end_request (0,HWGROUP (drive));
+			idetape_end_request (0, HWGROUP (drive));
 			return ide_stopped;
 		}
 #endif /* IDETAPE_DEBUG_BUGS */
@@ -2624,8 +2687,15 @@
 		tape->insert_speed = tape->insert_size / 1024 * HZ / (jiffies - tape->insert_time);
 	calculate_speeds(drive);
 	if (tape->onstream && tape->max_frames &&
-	   ((rq->cmd == IDETAPE_WRITE_RQ && (tape->cur_frames == tape->max_frames || (tape->speed_control && tape->cur_frames > 5 && (tape->insert_speed > tape->max_insert_speed || (0 /* tape->cur_frames > 30 && tape->tape_still_time > 200 */))))) ||
-	    (rq->cmd == IDETAPE_READ_RQ && (tape->cur_frames == 0 || (tape->speed_control && (tape->cur_frames < tape->max_frames - 5) && tape->insert_speed > tape->max_insert_speed)) && rq->nr_sectors))) {
+	    ((rq->cmd == IDETAPE_WRITE_RQ &&
+              ( tape->cur_frames == tape->max_frames ||
+                ( tape->speed_control && tape->cur_frames > 5 &&
+                       (tape->insert_speed > tape->max_insert_speed ||
+                        (0 /* tape->cur_frames > 30 && tape->tape_still_time > 200 */) ) ) ) ) ||
+	     (rq->cmd == IDETAPE_READ_RQ &&
+	      ( tape->cur_frames == 0 ||
+		( tape->speed_control && (tape->cur_frames < tape->max_frames - 5) &&
+			tape->insert_speed > tape->max_insert_speed ) ) && rq->nr_sectors) ) ) {
 #if IDETAPE_DEBUG_LOG
 		if (tape->debug_level >= 4)
 			printk(KERN_INFO "ide-tape: postponing request, cmd %d, cur %d, max %d\n",
@@ -2672,7 +2742,7 @@
 				if (jiffies > tape->last_buffer_fill + 5 * HZ / 100)
 					tape->req_buffer_fill = 1;
 			}
-			pc=idetape_next_pc_storage (drive);
+			pc = idetape_next_pc_storage (drive);
 			idetape_create_read_cmd (tape, pc, rq->current_nr_sectors, rq->bh);
 			break;
 		case IDETAPE_WRITE_RQ:
@@ -2689,12 +2759,12 @@
 					tape->req_buffer_fill = 1;
 				calculate_speeds(drive);
 			}
-			pc=idetape_next_pc_storage (drive);
+			pc = idetape_next_pc_storage (drive);
 			idetape_create_write_cmd (tape, pc, rq->current_nr_sectors, rq->bh);
 			break;
 		case IDETAPE_READ_BUFFER_RQ:
 			tape->postpone_cnt = 0;
-			pc=idetape_next_pc_storage (drive);
+			pc = idetape_next_pc_storage (drive);
 			idetape_create_read_buffer_cmd (tape, pc, rq->current_nr_sectors, rq->bh);
 			break;
 		case IDETAPE_ABORTED_WRITE_RQ:
@@ -2710,7 +2780,7 @@
 			idetape_end_request (IDETAPE_ERROR_EOD, HWGROUP(drive));
 			return ide_stopped;
 		case IDETAPE_PC_RQ1:
-			pc=(idetape_pc_t *) rq->buffer;
+			pc = (idetape_pc_t *) rq->buffer;
 			rq->cmd = IDETAPE_PC_RQ2;
 			break;
 		case IDETAPE_PC_RQ2:
@@ -2718,7 +2788,7 @@
 			return ide_stopped;
 		default:
 			printk (KERN_ERR "ide-tape: bug in IDETAPE_RQ_CMD macro\n");
-			idetape_end_request (0,HWGROUP (drive));
+			idetape_end_request (0, HWGROUP (drive));
 			return ide_stopped;
 	}
 	return idetape_issue_packet_command (drive, pc);
@@ -2844,7 +2914,9 @@
 #endif /* IDETAPE_DEBUG_BUGS */
 		count = IDE_MIN (bh->b_size - atomic_read(&bh->b_count), n);
 		copy_from_user (bh->b_data + atomic_read(&bh->b_count), buf, count);
-		n -= count; atomic_add(count, &bh->b_count); buf += count;
+		n -= count;
+		atomic_add(count, &bh->b_count);
+		buf += count;
 		if (atomic_read(&bh->b_count) == bh->b_size) {
 			bh = bh->b_reqnext;
 			if (bh)
@@ -2868,7 +2940,10 @@
 #endif /* IDETAPE_DEBUG_BUGS */
 		count = IDE_MIN (tape->b_count, n);
 		copy_to_user (buf, tape->b_data, count);
-		n -= count; tape->b_data += count; tape->b_count -= count; buf += count;
+		n -= count;
+		tape->b_data += count;
+		tape->b_count -= count;
+		buf += count;
 		if (!tape->b_count) {
 			tape->bh = bh = bh->b_reqnext;
 			if (bh) {
@@ -2920,10 +2995,10 @@
 	if (tape->last_stage != NULL)
 		tape->last_stage->next=stage;
 	else
-		tape->first_stage=tape->next_stage=stage;
-	tape->last_stage=stage;
+		tape->first_stage = tape->next_stage=stage;
+	tape->last_stage = stage;
 	if (tape->next_stage == NULL)
-		tape->next_stage=tape->last_stage;
+		tape->next_stage = tape->last_stage;
 	tape->nr_stages++;
 	tape->nr_pending_stages++;
 	spin_unlock_irqrestore(&tape->spinlock, flags);
@@ -2953,26 +3028,21 @@
 		par->par_desc_ver = OS_PARTITION_VERSION;
 		par->wrt_pass_cntr = htons(0xffff);
 		par->first_frame_addr = htonl(0);
-		par->last_frame_addr = htonl(0xbb7);
+		par->last_frame_addr = htonl(0xbb7); /* 2999 */
+		aux->frame_seq_num = htonl(0);
+		aux->logical_blk_num_high = htonl(0);
+		aux->logical_blk_num = htonl(0);
+		aux->next_mark_addr = htonl(tape->first_mark_addr);
 	} else {
 		aux->update_frame_cntr = htonl(0);
 		par->partition_num = OS_DATA_PARTITION;
 		par->par_desc_ver = OS_PARTITION_VERSION;
 		par->wrt_pass_cntr = htons(tape->wrt_pass_cntr);
-		par->first_frame_addr = htonl(0x14);
-		par->last_frame_addr = htonl(19239 * 24);
-	}
-	if (frame_type != OS_FRAME_TYPE_HEADER) {
+		par->first_frame_addr = htonl(OS_DATA_STARTFRAME1);
+		par->last_frame_addr = htonl(tape->capacity);
 		aux->frame_seq_num = htonl(logical_blk_num);
 		aux->logical_blk_num_high = htonl(0);
 		aux->logical_blk_num = htonl(logical_blk_num);
-	} else {
-		aux->frame_seq_num = htonl(0);
-		aux->logical_blk_num_high = htonl(0);
-		aux->logical_blk_num = htonl(0);
-	}
-
-	if (frame_type != OS_FRAME_TYPE_HEADER) {
 		dat->dat_sz = 8;
 		dat->reserved1 = 0;
 		dat->entry_cnt = 1;
@@ -2987,11 +3057,10 @@
 		else
 			dat->dat_list[0].flags = OS_DAT_FLAGS_DATA;
 		dat->dat_list[0].reserved = 0;
-	} else
-		aux->next_mark_addr = htonl(tape->first_mark_addr);
-	aux->filemark_cnt = ntohl(tape->filemark_cnt);
-	aux->phys_fm = ntohl(0xffffffff);
-	aux->last_mark_addr = ntohl(tape->last_mark_addr);
+	} 
+	aux->filemark_cnt = ntohl(tape->filemark_cnt);		/* shouldn't this be htonl ?? */
+	aux->phys_fm = ntohl(0xffffffff);			/* shouldn't this be htonl ?? */
+	aux->last_mark_addr = ntohl(tape->last_mark_addr);	/* shouldn't this be htonl ?? */
 }
 
 /*
@@ -3026,10 +3095,10 @@
 	idetape_tape_t *tape = drive->driver_data;
 	idetape_read_position_result_t *result;
 	
-#if IDETAPE_DEBUG_LOG
-	if (tape->debug_level >= 4)
+//#if IDETAPE_DEBUG_LOG
+//	if (tape->debug_level >= 4)
 		printk (KERN_INFO "ide-tape: Reached idetape_read_position_callback\n");
-#endif /* IDETAPE_DEBUG_LOG */
+//#endif /* IDETAPE_DEBUG_LOG */
 
 	if (!tape->pc->error) {
 		result = (idetape_read_position_result_t *) tape->pc->buffer;
@@ -3042,7 +3111,7 @@
 		if (result->bpu) {
 			printk (KERN_INFO "ide-tape: Block location is unknown to the tape\n");
 			clear_bit (IDETAPE_ADDRESS_VALID, &tape->flags);
-			idetape_end_request (0,HWGROUP (drive));
+			idetape_end_request (0, HWGROUP (drive));
 		} else {
 #if IDETAPE_DEBUG_LOG
 			if (tape->debug_level >= 2)
@@ -3053,10 +3122,10 @@
 			tape->last_frame_position = ntohl (result->last_block);
 			tape->blocks_in_buffer = result->blocks_in_buffer[2];
 			set_bit (IDETAPE_ADDRESS_VALID, &tape->flags);
-			idetape_end_request (1,HWGROUP (drive));
+			idetape_end_request (1, HWGROUP (drive));
 		}
 	} else {
-		idetape_end_request (0,HWGROUP (drive));
+		idetape_end_request (0, HWGROUP (drive));
 	}
 	return ide_stopped;
 }
@@ -3076,8 +3145,8 @@
 	idetape_init_pc (pc);
 	pc->c[0] = IDETAPE_WRITE_FILEMARK_CMD;
 	if (tape->onstream)
-		pc->c[1] = 1;
-	pc->c[4] = write_filemark;
+		pc->c[1] = 1; /* Immed bit */
+	pc->c[4] = write_filemark;  /* not used for OnStream ?? */
 	set_bit (PC_WAIT_FOR_DSC, &pc->flags);
 	pc->callback = &idetape_pc_callback;
 }
@@ -3109,7 +3178,7 @@
  *	the request to the request list without waiting for it to be serviced !
  *	In that case, we usually use idetape_queue_pc_head.
  */
-static int __idetape_queue_pc_tail (ide_drive_t *drive,idetape_pc_t *pc)
+static int __idetape_queue_pc_tail (ide_drive_t *drive, idetape_pc_t *pc)
 {
 	struct request rq;
 
@@ -3150,7 +3219,7 @@
 			return 0;
 		if (tape->sense_key == 2 && tape->asc == 4 && tape->ascq == 2) {
 			idetape_create_load_unload_cmd (drive, &pc, IDETAPE_LU_LOAD_MASK);
-			__idetape_queue_pc_tail(drive,&pc);
+			__idetape_queue_pc_tail(drive, &pc);
 			idetape_create_test_unit_ready_cmd(&pc);
 			if (!__idetape_queue_pc_tail(drive, &pc))
 				return 0;
@@ -3169,7 +3238,8 @@
 	int rc;
 
 	rc = __idetape_queue_pc_tail(drive, pc);
-	if (rc)	return rc;
+	if (rc)
+		return rc;
 	if (tape->onstream && test_bit(PC_WAIT_FOR_DSC, &pc->flags))
 		rc = idetape_wait_ready(drive, 60 * 10 * HZ);   /* AJN-4: Changed from 5 to 10 minutes;
                           because retension takes approx. 8:20 with Onstream 30GB tape */
@@ -3182,7 +3252,7 @@
 	int rc;
 
 	idetape_create_write_filemark_cmd(drive, &pc, 0);
-	if ((rc = idetape_queue_pc_tail (drive,&pc)))
+	if ((rc = idetape_queue_pc_tail (drive, &pc)))
 		return rc;
 	idetape_wait_ready(drive, 60 * 5 * HZ);
 	return 0;
@@ -3202,11 +3272,16 @@
 	idetape_pc_t pc;
 	int position;
 
+//#if IDETAPE_DEBUG_LOG
+//        if (tape->debug_level >= 4)
+	printk (KERN_INFO "ide-tape: Reached idetape_read_position\n");
+//#endif /* IDETAPE_DEBUG_LOG */
+
 #ifdef NO_LONGER_REQUIRED
 	idetape_flush_tape_buffers(drive);
 #endif
 	idetape_create_read_position_cmd(&pc);
-	if (idetape_queue_pc_tail (drive,&pc))
+	if (idetape_queue_pc_tail (drive, &pc))
 		return -1;
 	position = tape->first_frame_position;
 #ifdef NO_LONGER_REQUIRED
@@ -3231,12 +3306,17 @@
 	idetape_init_pc (pc);
 	pc->c[0] = IDETAPE_LOCATE_CMD;
 	if (tape->onstream)
-		pc->c[1] = 1;
+		pc->c[1] = 1; /* Immediate bit */
 	else
 		pc->c[1] = 2;
 	put_unaligned (htonl (block), (unsigned int *) &pc->c[3]);
 	pc->c[8] = partition;
 	if (tape->onstream)
+                /*
+                 * Set SKIP bit.
+                 * In case of write error this will write buffered
+                 * data in the drive to this new position!
+                 */
 		pc->c[9] = skip << 7;
 	set_bit (PC_WAIT_FOR_DSC, &pc->flags);
 	pc->callback = &idetape_pc_callback;
@@ -3307,11 +3387,12 @@
 		__idetape_discard_read_pipeline(drive);
 	idetape_wait_ready(drive, 60 * 5 * HZ);
 	idetape_create_locate_cmd (drive, &pc, block, partition, skip);
-	retval=idetape_queue_pc_tail (drive,&pc);
-	if (retval) return (retval);
+	retval = idetape_queue_pc_tail (drive, &pc);
+	if (retval)
+		return (retval);
 
 	idetape_create_read_position_cmd (&pc);
-	return (idetape_queue_pc_tail (drive,&pc));
+	return (idetape_queue_pc_tail (drive, &pc));
 }
 
 static void idetape_discard_read_pipeline (ide_drive_t *drive, int restore_position)
@@ -3339,7 +3420,7 @@
 {
 	idetape_pc_t pc;
 
-	idetape_create_mode_sense_cmd (&pc, 0x33);
+	idetape_create_mode_sense_cmd (&pc, IDETAPE_BUFFER_FILLING_PAGE);
 	pc.callback = idetape_onstream_buffer_fill_callback;
 	(void) idetape_queue_pc_tail(drive, &pc);
 }
@@ -3447,33 +3528,41 @@
 	idetape_tape_t *tape = drive->driver_data;
 	unsigned int block;
 
-	if (tape->onstream_write_error == 1) {
-		printk(KERN_ERR "ide-tape: %s: detected physical bad block at %u\n", tape->name, ntohl(tape->sense.information));
-		block = ntohl(tape->sense.information) + 80;
+	if (tape->onstream_write_error == OS_WRITE_ERROR) {
+		printk(KERN_ERR "ide-tape: %s: onstream_write_error_recovery: detected physical bad block at %u, logical %u first frame %u last_frame %u bufblocks %u stages %u skipping %u frames\n",
+			tape->name, ntohl(tape->sense.information), tape->logical_blk_num,
+			tape->first_frame_position, tape->last_frame_position,
+			tape->blocks_in_buffer, tape->nr_stages,
+ 			(ntohl(tape->sense.command_specific) >> 16) & 0xff );
+		block = ntohl(tape->sense.information) + ((ntohl(tape->sense.command_specific) >> 16) & 0xff);
 		idetape_update_stats(drive);
 		printk(KERN_ERR "ide-tape: %s: relocating %d buffered logical blocks to physical block %u\n", tape->name, tape->cur_frames, block);
+#if 0  /* isn't once enough ??? MM */
 		idetape_update_stats(drive);
+#endif
 		if (tape->firmware_revision_num >= 106)
 			idetape_position_tape(drive, block, 0, 1);
 		else {
 			idetape_onstream_read_back_buffer(drive);
 			idetape_position_tape(drive, block, 0, 0);
 		}
+#if 0     /* already done in idetape_position_tape MM */
 		idetape_read_position(drive);
+#endif
 #if ONSTREAM_DEBUG
 		if (tape->debug_level >= 1)
 			printk(KERN_ERR "ide-tape: %s: positioning complete, cur_frames %d, pos %d, tape pos %d\n", tape->name, tape->cur_frames, tape->first_frame_position, tape->last_frame_position);
 #endif
-	} else if (tape->onstream_write_error == 2) {
+	} else if (tape->onstream_write_error == OS_PART_ERROR) {
 #if ONSTREAM_DEBUG
 		if (tape->debug_level >= 1)
 			printk(KERN_INFO "ide-tape: %s: skipping over config partition\n", tape->name);
 #endif
 		idetape_flush_tape_buffers(drive);
 		block = idetape_read_position(drive);
-		if (block != 0xba4) 
-			printk(KERN_ERR "ide-tape: warning, current position %d, expected %d\n", block, 0xba4);
-		idetape_position_tape(drive, 0xbb8, 0, 0);
+		if (block != OS_DATA_ENDFRAME1)  
+			printk(KERN_ERR "ide-tape: warning, current position %d, expected %d\n", block, OS_DATA_ENDFRAME1);
+		idetape_position_tape(drive, 0xbb8, 0, 0); /* 3000 */
 	}
 	tape->onstream_write_error = 0;
 }
@@ -3572,48 +3661,48 @@
 		return 1;
 	}
 	if (rq->errors == IDETAPE_ERROR_GENERAL) {
-		printk(KERN_INFO "ide-tape: %s: skipping frame, read error\n", tape->name);
+		printk(KERN_INFO "ide-tape: %s: skipping frame %d, read error\n", tape->name, tape->first_frame_position);
 		return 0;
 	}
 	if (rq->errors == IDETAPE_ERROR_EOD) {
-		printk(KERN_INFO "ide-tape: %s: skipping frame, eod\n", tape->name);
+		printk(KERN_INFO "ide-tape: %s: skipping frame %d, eod\n", tape->name, tape->first_frame_position);
 		return 0;
 	}
 	if (ntohl(aux->format_id) != 0) {
-		printk(KERN_INFO "ide-tape: %s: skipping frame, format_id %u\n", tape->name, ntohl(aux->format_id));
+		printk(KERN_INFO "ide-tape: %s: skipping frame %d, format_id %u\n", tape->name, tape->first_frame_position, ntohl(aux->format_id));
 		return 0;
 	}
 	if (memcmp(aux->application_sig, tape->application_sig, 4) != 0) {
-		printk(KERN_INFO "ide-tape: %s: skipping frame, incorrect application signature\n", tape->name);
+		printk(KERN_INFO "ide-tape: %s: skipping frame %d, incorrect application signature\n", tape->name, tape->first_frame_position);
 		return 0;
 	}
 	if (aux->frame_type != OS_FRAME_TYPE_DATA &&
 	    aux->frame_type != OS_FRAME_TYPE_EOD &&
 	    aux->frame_type != OS_FRAME_TYPE_MARKER) {
-		printk(KERN_INFO "ide-tape: %s: skipping frame, frame type %x\n", tape->name, aux->frame_type);
+		printk(KERN_INFO "ide-tape: %s: skipping frame %d, frame type %x\n", tape->name, tape->first_frame_position, aux->frame_type);
 		return 0;
 	}
 	if (par->partition_num != OS_DATA_PARTITION) {
 		if (!tape->linux_media || tape->linux_media_version != 2) {
-			printk(KERN_INFO "ide-tape: %s: skipping frame, partition num %d\n", tape->name, par->partition_num);
+			printk(KERN_INFO "ide-tape: %s: skipping frame %d, partition num %d\n", tape->name, tape->first_frame_position, par->partition_num);
 			return 0;
 		}
 	}
 	if (par->par_desc_ver != OS_PARTITION_VERSION) {
-		printk(KERN_INFO "ide-tape: %s: skipping frame, partition version %d\n", tape->name, par->par_desc_ver);
+		printk(KERN_INFO "ide-tape: %s: skipping frame %d, partition version %d\n", tape->name, tape->first_frame_position, par->par_desc_ver);
 		return 0;
 	}
 	if (ntohs(par->wrt_pass_cntr) != tape->wrt_pass_cntr) {
-		printk(KERN_INFO "ide-tape: %s: skipping frame, wrt_pass_cntr %d (expected %d)(logical_blk_num %u)\n", tape->name, ntohs(par->wrt_pass_cntr), tape->wrt_pass_cntr, ntohl(aux->logical_blk_num));
+		printk(KERN_INFO "ide-tape: %s: skipping frame %d, wrt_pass_cntr %d (expected %d)(logical_blk_num %u)\n", tape->name, tape->first_frame_position, ntohs(par->wrt_pass_cntr), tape->wrt_pass_cntr, ntohl(aux->logical_blk_num));
 		return 0;
 	}
 	if (aux->frame_seq_num != aux->logical_blk_num) {
-		printk(KERN_INFO "ide-tape: %s: skipping frame, seq != logical\n", tape->name);
+		printk(KERN_INFO "ide-tape: %s: skipping frame %d, seq != logical\n", tape->name, tape->first_frame_position);
 		return 0;
 	}
 	if (logical_blk_num != -1 && ntohl(aux->logical_blk_num) != logical_blk_num) {
 		if (!quiet)
-			printk(KERN_INFO "ide-tape: %s: skipping frame, logical_blk_num %u (expected %d)\n", tape->name, ntohl(aux->logical_blk_num), logical_blk_num);
+			printk(KERN_INFO "ide-tape: %s: skipping frame %d, logical_blk_num %u (expected %d)\n", tape->name, tape->first_frame_position, ntohl(aux->logical_blk_num), logical_blk_num);
 		return 0;
 	}
 	if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
@@ -3689,7 +3778,7 @@
 	idetape_switch_buffers (tape, new_stage);
 	idetape_init_stage(drive, new_stage, OS_FRAME_TYPE_DATA, tape->logical_blk_num);
 	tape->logical_blk_num++;
-	idetape_add_stage_tail (drive,new_stage);
+	idetape_add_stage_tail (drive, new_stage);
 	tape->pipeline_head++;
 #if USE_IOTRACE
 	IO_trace(IO_IDETAPE_FIFO, tape->pipeline_head, tape->buffer_head, tape->tape_head, tape->minor);
@@ -3766,7 +3855,7 @@
 	}
 #endif /* IDETAPE_DEBUG_BUGS */
 	if (tape->merge_stage_size) {
-		blocks=tape->merge_stage_size/tape->tape_block_size;
+		blocks = tape->merge_stage_size / tape->tape_block_size;
 		if (tape->merge_stage_size % tape->tape_block_size) {
 			blocks++;
 			i = tape->tape_block_size - tape->merge_stage_size % tape->tape_block_size;
@@ -3797,7 +3886,7 @@
 		tape->merge_stage = NULL;
 	}
 	clear_bit (IDETAPE_PIPELINE_ERROR, &tape->flags);
-	tape->chrdev_direction=idetape_direction_none;
+	tape->chrdev_direction = idetape_direction_none;
 
 	/*
 	 *	On the next backup, perform the feedback loop again.
@@ -3874,13 +3963,13 @@
 	rq.sector = tape->first_frame_position;
 	rq.nr_sectors = rq.current_nr_sectors = blocks;
 	if (!test_bit(IDETAPE_PIPELINE_ERROR, &tape->flags) && tape->nr_stages <= max_stages) {
-		new_stage=idetape_kmalloc_stage (tape);
+		new_stage = idetape_kmalloc_stage (tape);
 		while (new_stage != NULL) {
-			new_stage->rq=rq;
-			idetape_add_stage_tail (drive,new_stage);
+			new_stage->rq = rq;
+			idetape_add_stage_tail (drive, new_stage);
 			if (tape->nr_stages >= max_stages)
 				break;
-			new_stage=idetape_kmalloc_stage (tape);
+			new_stage = idetape_kmalloc_stage (tape);
 		}
 	}
 	if (!idetape_pipeline_active(tape)) {
@@ -3922,16 +4011,23 @@
 #endif
 				clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags);
 				position = idetape_read_position(drive);
+				printk(KERN_INFO "ide-tape: %s: blank block detected at %d\n", tape->name, position);
 				if (position >= 3000 && position < 3080)
-					position += 32;
-				if (position >= 2980 && position < 3000)
+					position += 32;  /* Why is this check and number ??? MM */
+				if (position >= OS_DATA_ENDFRAME1 && position < 3000)
 					position = 3000;
 				else
+					/*
+					 * compensate for write errors that generally skip 80 frames,
+					 * expect around 20 read errors in a row...
+					 */
 					position += 60;
-				if (position >= 2980 && position < 3000)
+				if (position >= OS_DATA_ENDFRAME1 && position < 3000)
 					position = 3000;
-				printk(KERN_INFO "ide-tape: %s: blank block detected, positioning tape to block %d\n", tape->name, position);
-				idetape_position_tape(drive, position, 0, 1);
+				printk(KERN_INFO "ide-tape: %s: positioning tape to block %d\n", tape->name, position);
+				if (position == 3000)  /* seems to be needed to correctly position at block 3000 MM */
+					idetape_position_tape(drive, 0, 0, 0);
+				idetape_position_tape(drive, position, 0, 0);
 				cnt += 40;
 				continue;
 			} else
@@ -4089,12 +4185,14 @@
 #endif /* IDETAPE_DEBUG_LOG */	
 	
 	idetape_create_rewind_cmd (drive, &pc);
-	retval=idetape_queue_pc_tail (drive,&pc);
-	if (retval) return retval;
+	retval = idetape_queue_pc_tail (drive, &pc);
+	if (retval)
+		return retval;
 
 	idetape_create_read_position_cmd (&pc);
-	retval = idetape_queue_pc_tail (drive,&pc);
-	if (retval) return retval;
+	retval = idetape_queue_pc_tail (drive, &pc);
+	if (retval)
+		return retval;
 	tape->logical_blk_num = 0;
 	return 0;
 }
@@ -4412,7 +4510,7 @@
 	switch (mt_op) {
 		case MTFSF:
 			idetape_create_space_cmd (&pc,mt_count-count,IDETAPE_SPACE_OVER_FILEMARK);
-			return (idetape_queue_pc_tail (drive,&pc));
+			return (idetape_queue_pc_tail (drive, &pc));
 		case MTFSFM:
 			if (!tape->capabilities.sprev)
 				return (-EIO);
@@ -4423,7 +4521,7 @@
 			if (!tape->capabilities.sprev)
 				return (-EIO);
 			idetape_create_space_cmd (&pc,-(mt_count+count),IDETAPE_SPACE_OVER_FILEMARK);
-			return (idetape_queue_pc_tail (drive,&pc));
+			return (idetape_queue_pc_tail (drive, &pc));
 		case MTBSFM:
 			if (!tape->capabilities.sprev)
 				return (-EIO);
@@ -4460,7 +4558,7 @@
 	struct inode *inode = file->f_dentry->d_inode;
 	ide_drive_t *drive = get_drive_ptr (inode->i_rdev);
 	idetape_tape_t *tape = drive->driver_data;
-	ssize_t bytes_read,temp,actually_read=0, rc;
+	ssize_t bytes_read,temp, actually_read = 0, rc;
 
 	if (ppos != &file->f_pos) {
 		/* "A request was outside the capabilities of the device." */
@@ -4482,28 +4580,32 @@
 	}
 	if ((rc = idetape_initiate_read(drive, tape->max_stages)) < 0)
 		return rc;
-	if (count==0)
+	if (count == 0)
 		return (0);
 	if (tape->merge_stage_size) {
-		actually_read=IDE_MIN (tape->merge_stage_size,count);
+		actually_read = IDE_MIN (tape->merge_stage_size, count);
 		idetape_copy_stage_to_user (tape, buf, tape->merge_stage, actually_read);
-		buf += actually_read; tape->merge_stage_size -= actually_read; count-=actually_read;
+		buf += actually_read;
+		tape->merge_stage_size -= actually_read;
+		count -= actually_read;
 	}
 	while (count >= tape->stage_size) {
-		bytes_read=idetape_add_chrdev_read_request (drive, tape->capabilities.ctl);
+		bytes_read = idetape_add_chrdev_read_request (drive, tape->capabilities.ctl);
 		if (bytes_read <= 0)
 			goto finish;
 		idetape_copy_stage_to_user (tape, buf, tape->merge_stage, bytes_read);
-		buf += bytes_read; count -= bytes_read; actually_read += bytes_read;
+		buf += bytes_read;
+		count -= bytes_read;
+		actually_read += bytes_read;
 	}
 	if (count) {
 		bytes_read=idetape_add_chrdev_read_request (drive, tape->capabilities.ctl);
 		if (bytes_read <= 0)
 			goto finish;
-		temp=IDE_MIN (count,bytes_read);
+		temp = IDE_MIN (count, bytes_read);
 		idetape_copy_stage_to_user (tape, buf, tape->merge_stage, temp);
-		actually_read+=temp;
-		tape->merge_stage_size=bytes_read-temp;
+		actually_read += temp;
+		tape->merge_stage_size = bytes_read-temp;
 	}
 finish:
 	if (!actually_read && test_bit (IDETAPE_FILEMARK, &tape->flags)) {
@@ -4515,7 +4617,8 @@
 		return 0;
 	}
 	if (tape->onstream && !actually_read && test_and_clear_bit(IDETAPE_READ_ERROR, &tape->flags)) {
-		printk(KERN_ERR "ide-tape: %s: unrecovered read error on logical block number %d, skipping\n", tape->name, tape->logical_blk_num);
+		printk(KERN_ERR "ide-tape: %s: unrecovered read error on logical block number %d, skipping\n",
+					tape->name, tape->logical_blk_num);
 		tape->logical_blk_num++;
 		return -EIO;
 	}
@@ -4576,6 +4679,37 @@
 	return;
 }
 
+static void idetape_write_filler (ide_drive_t *drive, int block, int cnt)
+{
+	idetape_tape_t *tape = drive->driver_data;
+	idetape_stage_t *stage;
+	int rc;
+
+	if (!tape->onstream || tape->raw)
+		return;
+	stage = __idetape_kmalloc_stage(tape, 1, 1);
+	if (stage == NULL)
+		return;
+	idetape_init_stage(drive, stage, OS_FRAME_TYPE_FILL, 0);
+	idetape_wait_ready(drive, 60 * 5 * HZ);
+	rc = idetape_position_tape(drive, block, 0, 0);
+#if ONSTREAM_DEBUG
+	printk(KERN_INFO "write_filler: positioning failed it returned %d\n", rc);
+#endif
+	if (rc != 0) 
+		return;	/* don't write fillers if we cannot position the tape. */
+
+	strcpy(stage->bh->b_data, "Filler");
+	while (cnt--) {
+		if (!idetape_queue_rw_tail (drive, IDETAPE_WRITE_RQ, 1, stage->bh)) {
+			printk(KERN_INFO "ide-tape: %s: write_filler: couldn't write header frame\n", tape->name);
+			__idetape_kfree_stage (stage);
+			return;
+		}
+	}
+	__idetape_kfree_stage (stage);
+}
+
 static void __idetape_write_header (ide_drive_t *drive, int block, int cnt)
 {
 	idetape_tape_t *tape = drive->driver_data;
@@ -4591,12 +4725,12 @@
 	memset(&header, 0, sizeof(header));
 	strcpy(header.ident_str, "ADR_SEQ");
 	header.major_rev = 1;
-	header.minor_rev = 2;
+	header.minor_rev = OS_ADR_MINREV;
 	header.par_num = 1;
 	header.partition.partition_num = OS_DATA_PARTITION;
 	header.partition.par_desc_ver = OS_PARTITION_VERSION;
-	header.partition.first_frame_addr = htonl(0x14);
-	header.partition.last_frame_addr = htonl(19239 * 24);
+	header.partition.first_frame_addr = htonl(OS_DATA_STARTFRAME1);
+	header.partition.last_frame_addr = htonl(tape->capacity);
 	header.partition.wrt_pass_cntr = htons(tape->wrt_pass_cntr);
 	header.partition.eod_frame_addr = htonl(tape->eod_frame_addr);
 	memcpy(stage->bh->b_data, &header, sizeof(header));
@@ -4623,7 +4757,7 @@
 		return;
 	tape->update_frame_cntr++;
 	__idetape_write_header(drive, 5, 5);
-	__idetape_write_header(drive, 0xbae, 5);
+	__idetape_write_header(drive, 0xbae, 5); /* 2990 */
 	if (locate_eod) {
 #if ONSTREAM_DEBUG
 		if (tape->debug_level >= 2)
@@ -4639,22 +4773,39 @@
 	struct inode *inode = file->f_dentry->d_inode;
 	ide_drive_t *drive = get_drive_ptr (inode->i_rdev);
 	idetape_tape_t *tape = drive->driver_data;
-	ssize_t retval,actually_written=0;
+	ssize_t retval, actually_written = 0;
 	int position;
 
 	if (ppos != &file->f_pos) {
 		/* "A request was outside the capabilities of the device." */
 		return -ENXIO;
 	}
-	if (tape->onstream && (count != tape->tape_block_size)) {
-		printk(KERN_ERR "ide-tape: %s: use %d bytes as block size (%Zd used)\n", tape->name, tape->tape_block_size, count);
-		return -EINVAL;
-	}
+
 #if IDETAPE_DEBUG_LOG
 	if (tape->debug_level >= 3)
 		printk (KERN_INFO "ide-tape: Reached idetape_chrdev_write, count %Zd\n", count);
 #endif /* IDETAPE_DEBUG_LOG */
 
+	if (tape->onstream) {
+		if (count != tape->tape_block_size) {
+			printk(KERN_ERR "ide-tape: %s: chrdev_write: use %d bytes as block size (%Zd used)\n",
+					tape->name, tape->tape_block_size, count);
+			return -EINVAL;
+		}
+		/*
+		 * Check if we reach the end of the tape. Just assume the whole pipeline
+		 * is filled with write requests!
+		 */
+		if (tape->first_frame_position + tape->nr_stages >= tape->capacity - OS_EW)  {
+#if ONSTREAM_DEBUG
+			printk(KERN_INFO, "chrdev_write: Write truncated at EOM early warning");
+#endif
+			if (tape->chrdev_direction == idetape_direction_write)
+				idetape_write_release(inode);
+			return -ENOSPC;
+		}
+	}
+
 	if (tape->chrdev_direction != idetape_direction_write) {	/* Initialize write operation */
 		if (tape->chrdev_direction == idetape_direction_read)
 			idetape_discard_read_pipeline (drive, 1);
@@ -4671,17 +4822,17 @@
 
 		if (tape->onstream) {
 			position = idetape_read_position(drive);
-			if (position <= 20) {
+			if (position <= OS_DATA_STARTFRAME1) {
 				tape->logical_blk_num = 0;
 				tape->wrt_pass_cntr++;
 #if ONSTREAM_DEBUG
 				if (tape->debug_level >= 2)
-					printk(KERN_INFO "ide-tape: %s: logical block num 0, setting eod to 20\n", tape->name);
+					printk(KERN_INFO "ide-tape: %s: logical block num 0, setting eod to %d\n", tape->name, OS_DATA_STARTFRAME1);
 				if (tape->debug_level >= 2)
 					printk(KERN_INFO "ide-tape: %s: allocating new write pass counter %d\n", tape->name, tape->wrt_pass_cntr);
 #endif
 				tape->filemark_cnt = 0;
-				tape->eod_frame_addr = 20;
+				tape->eod_frame_addr = OS_DATA_STARTFRAME1;
 				tape->first_mark_addr = tape->last_mark_addr = -1;
 				idetape_write_header(drive, 1);
 			}
@@ -4715,7 +4866,7 @@
 			printk("ide-tape: first_frame_position %d\n", tape->first_frame_position);
 #endif
 	}
-	if (count==0)
+	if (count == 0)
 		return (0);
 	if (tape->restart_speed_control_req)
 		idetape_restart_speed_control(drive);
@@ -4723,32 +4874,35 @@
 #if IDETAPE_DEBUG_BUGS
 		if (tape->merge_stage_size >= tape->stage_size) {
 			printk (KERN_ERR "ide-tape: bug: merge buffer too big\n");
-			tape->merge_stage_size=0;
+			tape->merge_stage_size = 0;
 		}
 #endif /* IDETAPE_DEBUG_BUGS */
-		actually_written=IDE_MIN (tape->stage_size-tape->merge_stage_size,count);
+		actually_written = IDE_MIN (tape->stage_size - tape->merge_stage_size, count);
 		idetape_copy_stage_from_user (tape, tape->merge_stage, buf, actually_written);
-		buf+=actually_written;tape->merge_stage_size+=actually_written;count-=actually_written;
+		buf += actually_written;
+		tape->merge_stage_size += actually_written;
+		count -= actually_written;
 
 		if (tape->merge_stage_size == tape->stage_size) {
 			tape->merge_stage_size = 0;
-			retval=idetape_add_chrdev_write_request (drive, tape->capabilities.ctl);
+			retval = idetape_add_chrdev_write_request (drive, tape->capabilities.ctl);
 			if (retval <= 0)
 				return (retval);
 		}
 	}
 	while (count >= tape->stage_size) {
 		idetape_copy_stage_from_user (tape, tape->merge_stage, buf, tape->stage_size);
-		buf+=tape->stage_size;count-=tape->stage_size;
-		retval=idetape_add_chrdev_write_request (drive, tape->capabilities.ctl);
-		actually_written+=tape->stage_size;
+		buf += tape->stage_size;
+		count -= tape->stage_size;
+		retval = idetape_add_chrdev_write_request (drive, tape->capabilities.ctl);
+		actually_written += tape->stage_size;
 		if (retval <= 0)
 			return (retval);
 	}
 	if (count) {
 		actually_written+=count;
 		idetape_copy_stage_from_user (tape, tape->merge_stage, buf, count);
-		tape->merge_stage_size+=count;
+		tape->merge_stage_size += count;
 	}
 	return (actually_written);
 }
@@ -4760,8 +4914,8 @@
 	idetape_pc_t pc;
 
 	if (!tape->onstream) {
-		idetape_create_write_filemark_cmd(drive, &pc,1);	/* Write a filemark */
-		if (idetape_queue_pc_tail (drive,&pc)) {
+		idetape_create_write_filemark_cmd(drive, &pc, 1);	/* Write a filemark */
+		if (idetape_queue_pc_tail (drive, &pc)) {
 			printk (KERN_ERR "ide-tape: Couldn't write a filemark\n");
 			return -EIO;
 		}
@@ -4937,24 +5091,24 @@
 			if (idetape_rewind_tape(drive))
 				return -EIO;
 			if (tape->onstream && !tape->raw)
-				return idetape_position_tape(drive, 20, 0, 0);
+				return idetape_position_tape(drive, OS_DATA_STARTFRAME1, 0, 0);
 			return 0;
 		case MTLOAD:
 			idetape_discard_read_pipeline (drive, 0);
 			idetape_create_load_unload_cmd (drive, &pc, IDETAPE_LU_LOAD_MASK);
-			return (idetape_queue_pc_tail (drive,&pc));
+			return (idetape_queue_pc_tail (drive, &pc));
 		case MTUNLOAD:
 		case MTOFFL:
 			idetape_discard_read_pipeline (drive, 0);
 			idetape_create_load_unload_cmd (drive, &pc,!IDETAPE_LU_LOAD_MASK);
-			return (idetape_queue_pc_tail (drive,&pc));
+			return (idetape_queue_pc_tail (drive, &pc));
 		case MTNOP:
 			idetape_discard_read_pipeline (drive, 0);
 			return (idetape_flush_tape_buffers (drive));
 		case MTRETEN:
 			idetape_discard_read_pipeline (drive, 0);
 			idetape_create_load_unload_cmd (drive, &pc,IDETAPE_LU_RETENSION_MASK | IDETAPE_LU_LOAD_MASK);
-			return (idetape_queue_pc_tail (drive,&pc));
+			return (idetape_queue_pc_tail (drive, &pc));
 		case MTEOM:
 			if (tape->onstream) {
 #if ONSTREAM_DEBUG
@@ -4968,24 +5122,30 @@
 					return -EIO;
 				return 0;
 			}
-			idetape_create_space_cmd (&pc,0,IDETAPE_SPACE_TO_EOD);
-			return (idetape_queue_pc_tail (drive,&pc));
+			idetape_create_space_cmd (&pc, 0, IDETAPE_SPACE_TO_EOD);
+			return (idetape_queue_pc_tail (drive, &pc));
 		case MTERASE:
 			if (tape->onstream) {
-				tape->eod_frame_addr = 20;
+				tape->eod_frame_addr = OS_DATA_STARTFRAME1;
 				tape->logical_blk_num = 0;
 				tape->first_mark_addr = tape->last_mark_addr = -1;
 				idetape_position_tape(drive, tape->eod_frame_addr, 0, 0);
 				idetape_write_eod(drive);
 				idetape_flush_tape_buffers (drive);
 				idetape_write_header(drive, 0);
+				/*
+				 * write filler frames to the unused frames...
+				 * REMOVE WHEN going to LIN4 application type...
+				 */
+				idetape_write_filler(drive, OS_DATA_STARTFRAME1 - 10, 10);
+				idetape_write_filler(drive, OS_DATA_ENDFRAME1, 10);
 				idetape_flush_tape_buffers (drive);
 				(void) idetape_rewind_tape (drive);
 				return 0;
 			}
 			(void) idetape_rewind_tape (drive);
 			idetape_create_erase_cmd (&pc);
-			return (idetape_queue_pc_tail (drive,&pc));
+			return (idetape_queue_pc_tail (drive, &pc));
 		case MTSETBLK:
 			if (tape->onstream) {
 				if (mt_count != tape->tape_block_size) {
@@ -5028,14 +5188,14 @@
 		case MTLOCK:
 			if (!idetape_create_prevent_cmd(drive, &pc, 1))
 				return 0;
-			retval = idetape_queue_pc_tail (drive,&pc);
+			retval = idetape_queue_pc_tail (drive, &pc);
 			if (retval) return retval;
 			tape->door_locked = DOOR_EXPLICITLY_LOCKED;
 			return 0;
 		case MTUNLOCK:
 			if (!idetape_create_prevent_cmd(drive, &pc, 0))
 				return 0;
-			retval = idetape_queue_pc_tail (drive,&pc);
+			retval = idetape_queue_pc_tail (drive, &pc);
 			if (retval) return retval;
 			tape->door_locked = DOOR_UNLOCKED;
 			return 0;
@@ -5113,7 +5273,7 @@
 				mtget.mt_gstat |= GMT_ONLINE(0xffffffff);
 				if (tape->first_stage && tape->first_stage->aux->frame_type == OS_FRAME_TYPE_EOD)
 					mtget.mt_gstat |= GMT_EOD(0xffffffff);
-				if (position <= 20)
+				if (position <= OS_DATA_STARTFRAME1)
 					mtget.mt_gstat |= GMT_BOT(0xffffffff);
 			}
 			if (copy_to_user ((char *) arg,(char *) &mtget, sizeof (struct mtget)))
@@ -5150,7 +5310,7 @@
 	tape->header_ok = tape->linux_media = 0;
 	tape->update_frame_cntr = 0;
 	tape->wrt_pass_cntr = 0;
-	tape->eod_frame_addr = 20;
+	tape->eod_frame_addr = OS_DATA_STARTFRAME1;
 	tape->first_mark_addr = tape->last_mark_addr = -1;
 	stage = __idetape_kmalloc_stage (tape, 0, 0);
 	if (stage == NULL)
@@ -5172,8 +5332,8 @@
 		__idetape_kfree_stage (stage);
 		return 0;
 	}
-	if (header->major_rev != 1 || (header->minor_rev != 1 && header->minor_rev != 2))
-		printk(KERN_INFO "ide-tape: warning: revision %d.%d detected (1.1/1.2 supported)\n", header->major_rev, header->minor_rev);
+	if (header->major_rev != 1 || (header->minor_rev > OS_ADR_MINREV))
+		printk(KERN_INFO "ide-tape: warning: revision %d.%d detected (up to 1.%d supported)\n", header->major_rev, header->minor_rev, OS_ADR_MINREV);
 	if (header->par_num != 1)
 		printk(KERN_INFO "ide-tape: warning: %d partitions defined, only one supported\n", header->par_num);
 	tape->wrt_pass_cntr = ntohs(header->partition.wrt_pass_cntr);
@@ -5182,12 +5342,14 @@
 	tape->first_mark_addr = ntohl(aux->next_mark_addr);
 	tape->last_mark_addr = ntohl(aux->last_mark_addr);
 	tape->update_frame_cntr = ntohl(aux->update_frame_cntr);
-	memcpy(tape->application_sig, aux->application_sig, 4); tape->application_sig[4] = 0;
+	memcpy(tape->application_sig, aux->application_sig, 4);
+	tape->application_sig[4] = 0;
 	if (memcmp(tape->application_sig, "LIN", 3) == 0) {
 		tape->linux_media = 1;
 		tape->linux_media_version = tape->application_sig[3] - '0';
 		if (tape->linux_media_version != 3)
-			printk(KERN_INFO "ide-tape: %s: Linux media version %d detected (current 3)\n", tape->name, tape->linux_media_version);
+			printk(KERN_INFO "ide-tape: %s: Linux media version %d detected (current 3)\n",
+					 tape->name, tape->linux_media_version);
 	} else {
 		printk(KERN_INFO "ide-tape: %s: non Linux media detected (%s)\n", tape->name, tape->application_sig);
 		tape->linux_media = 0;
@@ -5214,18 +5376,14 @@
 	for (block = 5; block < 10; block++)
 		if (__idetape_analyze_headers(drive, block))
 			goto ok;
-#if 0
-	for (block = 0xbae; block < 0xbb8; block++)
-#else
-	for (block = 0xbae; block < 0xbb3; block++)
-#endif
+	for (block = 0xbae; block < 0xbb3; block++) /* 2990 - 2994 */
 		if (__idetape_analyze_headers(drive, block))
 			goto ok;
 	printk(KERN_ERR "ide-tape: %s: failed to find valid ADRL header\n", tape->name);
 	return 0;
 ok:
-	if (position < 20)
-		position = 20;
+	if (position < OS_DATA_STARTFRAME1)
+		position = OS_DATA_STARTFRAME1;
 	idetape_position_tape(drive, position, 0, 0);
 	tape->header_ok = 1;
 	return 1;
@@ -5251,7 +5409,8 @@
 
 	if (test_and_set_bit (IDETAPE_BUSY, &tape->flags))
 		return -EBUSY;
-	if (!tape->onstream) {
+	MOD_INC_USE_COUNT;
+	if (!tape->onstream) {	
 		idetape_read_position(drive);
 		if (!test_bit (IDETAPE_ADDRESS_VALID, &tape->flags))
 			(void) idetape_rewind_tape (drive);
@@ -5263,18 +5422,22 @@
 			tape->tape_block_size = tape->stage_size = 32768;
 			tape->raw = 0;
 		}
+                idetape_onstream_mode_sense_tape_parameter_page(drive, tape->debug_level);
 	}
 	if (idetape_wait_ready(drive, 60 * HZ)) {
 		clear_bit(IDETAPE_BUSY, &tape->flags);
 		printk(KERN_ERR "ide-tape: %s: drive not ready\n", tape->name);
+		MOD_DEC_USE_COUNT;
 		return -EBUSY;
 	}
 	idetape_read_position(drive);
+	MOD_DEC_USE_COUNT;
 	clear_bit (IDETAPE_PIPELINE_ERROR, &tape->flags);
 
 	if (tape->chrdev_direction == idetape_direction_none) {
+		MOD_INC_USE_COUNT;
 		if (idetape_create_prevent_cmd(drive, &pc, 1)) {
-			if (!idetape_queue_pc_tail (drive,&pc)) {
+			if (!idetape_queue_pc_tail (drive, &pc)) {
 				if (tape->door_locked != DOOR_EXPLICITLY_LOCKED)
 					tape->door_locked = DOOR_LOCKED;
 			}
@@ -5287,6 +5450,28 @@
 	return 0;
 }
 
+static void idetape_write_release (struct inode *inode)
+{
+	ide_drive_t *drive = get_drive_ptr (inode->i_rdev);
+	idetape_tape_t *tape = drive->driver_data;
+	unsigned int minor=MINOR (inode->i_rdev);
+
+	idetape_empty_write_pipeline (drive);
+	tape->merge_stage = __idetape_kmalloc_stage (tape, 1, 0);
+	if (tape->merge_stage != NULL) {
+		idetape_pad_zeros (drive, tape->tape_block_size * (tape->user_bs_factor - 1));
+		__idetape_kfree_stage (tape->merge_stage);
+		tape->merge_stage = NULL;
+	}
+	idetape_write_filemark(drive);
+	idetape_write_eod(drive);
+	idetape_flush_tape_buffers (drive);
+	idetape_write_header(drive, minor >= 128);
+	idetape_flush_tape_buffers (drive);
+
+	return;
+}
+
 /*
  *	Our character device release function.
  */
@@ -5305,18 +5490,7 @@
 #endif /* IDETAPE_DEBUG_LOG */
 
 	if (tape->chrdev_direction == idetape_direction_write) {
-		idetape_empty_write_pipeline (drive);
-		tape->merge_stage = __idetape_kmalloc_stage (tape, 1, 0);
-		if (tape->merge_stage != NULL) {
-			idetape_pad_zeros (drive, tape->tape_block_size * (tape->user_bs_factor - 1));
-			__idetape_kfree_stage (tape->merge_stage);
-			tape->merge_stage = NULL;
-		}
-		idetape_write_filemark(drive);
-		idetape_write_eod(drive);
-		idetape_flush_tape_buffers (drive);
-		idetape_write_header(drive, minor >= 128);
-		idetape_flush_tape_buffers (drive);
+		idetape_write_release(inode);
 	}
 	if (tape->chrdev_direction == idetape_direction_read) {
 		if (minor < 128)
@@ -5333,9 +5507,10 @@
 	if (tape->chrdev_direction == idetape_direction_none) {
 		if (tape->door_locked != DOOR_EXPLICITLY_LOCKED) {
 			if (idetape_create_prevent_cmd(drive, &pc, 0))
-				if (!idetape_queue_pc_tail (drive,&pc))
+				if (!idetape_queue_pc_tail (drive, &pc))
 					tape->door_locked = DOOR_UNLOCKED;
 		}
+		MOD_DEC_USE_COUNT;
 	}
 	clear_bit (IDETAPE_BUSY, &tape->flags);
 	unlock_kernel();
@@ -5491,7 +5666,7 @@
 	pc.buffer[4 + 5] = vendor[3];
 	pc.buffer[4 + 6] = 0;
 	pc.buffer[4 + 7] = 0;
-	if (idetape_queue_pc_tail (drive,&pc))
+	if (idetape_queue_pc_tail (drive, &pc))
 		printk (KERN_ERR "ide-tape: Couldn't set vendor name to %s\n", vendor);
 
 }
@@ -5513,7 +5688,7 @@
 	pc.buffer[4 + 1] = 2;
 	pc.buffer[4 + 2] = 4;
 	pc.buffer[4 + 3] = retries;
-	if (idetape_queue_pc_tail (drive,&pc))
+	if (idetape_queue_pc_tail (drive, &pc))
 		printk (KERN_ERR "ide-tape: Couldn't set retries to %d\n", retries);
 }
 #endif
@@ -5530,8 +5705,8 @@
 	/*
 	 * Get the current block size from the block size mode page
 	 */
-	idetape_create_mode_sense_cmd (&pc,IDETAPE_BLOCK_SIZE_PAGE);
-	if (idetape_queue_pc_tail (drive,&pc))
+	idetape_create_mode_sense_cmd (&pc, IDETAPE_BLOCK_SIZE_PAGE);
+	if (idetape_queue_pc_tail (drive, &pc))
 		printk (KERN_ERR "ide-tape: can't get tape block size mode page\n");
 	header = (idetape_mode_parameter_header_t *) pc.buffer;
 	bs = (idetape_block_size_page_t *) (pc.buffer + sizeof(idetape_mode_parameter_header_t) + header->bdl);
@@ -5552,7 +5727,7 @@
 	bs->record32 = 0;
 	bs->record32_5 = 1;
 	idetape_create_mode_select_cmd(&pc, sizeof(*header) + sizeof(*bs));
-	if (idetape_queue_pc_tail (drive,&pc))
+	if (idetape_queue_pc_tail (drive, &pc))
 		printk (KERN_ERR "ide-tape: Couldn't set tape block size mode page\n");
 
 #if ONSTREAM_DEBUG
@@ -5575,7 +5750,7 @@
 	idetape_inquiry_result_t *inquiry;
 	
 	idetape_create_inquiry_cmd(&pc);
-	if (idetape_queue_pc_tail (drive,&pc)) {
+	if (idetape_queue_pc_tail (drive, &pc)) {
 		printk (KERN_ERR "ide-tape: %s: can't get INQUIRY results\n", tape->name);
 		return;
 	}
@@ -5618,6 +5793,34 @@
 }
 
 /*
+ *	idetape_get_mode_sense_parameters asks the tape about its various
+ *	parameters. This may work for other drives to???
+ */
+static void idetape_onstream_mode_sense_tape_parameter_page(ide_drive_t *drive, int debug)
+{
+	idetape_tape_t *tape = drive->driver_data;
+	idetape_pc_t pc;
+	idetape_mode_parameter_header_t *header;
+	onstream_tape_paramtr_page_t *prm;
+	
+	idetape_create_mode_sense_cmd (&pc, IDETAPE_PARAMTR_PAGE);
+	if (idetape_queue_pc_tail (drive, &pc)) {
+		printk (KERN_ERR "ide-tape: Can't get tape parameters page - probably no tape inserted in onstream drive\n");
+		return;
+	}
+	header = (idetape_mode_parameter_header_t *) pc.buffer;
+	prm = (onstream_tape_paramtr_page_t *) (pc.buffer + sizeof(idetape_mode_parameter_header_t) + header->bdl);
+
+        tape->capacity = ntohs(prm->segtrk) * ntohs(prm->trks);
+        if (debug) {
+	    printk (KERN_INFO "ide-tape: %s <-> %s: Tape length %dMB (%d frames/track, %d tracks = %d blocks, density: %dKbpi)\n",
+               drive->name, tape->name, tape->capacity/32, ntohs(prm->segtrk), ntohs(prm->trks), tape->capacity, prm->density);
+        }
+
+        return;
+}
+
+/*
  *	idetape_get_mode_sense_results asks the tape about its various
  *	parameters. In particular, we will adjust our data transfer buffer
  *	size to the recommended value as returned by the tape.
@@ -5629,8 +5832,8 @@
 	idetape_mode_parameter_header_t *header;
 	idetape_capabilities_page_t *capabilities;
 	
-	idetape_create_mode_sense_cmd (&pc,IDETAPE_CAPABILITIES_PAGE);
-	if (idetape_queue_pc_tail (drive,&pc)) {
+	idetape_create_mode_sense_cmd (&pc, IDETAPE_CAPABILITIES_PAGE);
+	if (idetape_queue_pc_tail (drive, &pc)) {
 		printk (KERN_ERR "ide-tape: Can't get tape parameters - assuming some default values\n");
 		tape->tape_block_size = 512; tape->capabilities.ctl = 52;
 		tape->capabilities.speed = 450; tape->capabilities.buffer_size = 6 * 52;
@@ -5692,6 +5895,34 @@
 #endif /* IDETAPE_DEBUG_INFO */
 }
 
+/*
+ *	ide_get_blocksize_from_block_descriptor does a mode sense page 0 with block descriptor
+ *	and if it succeeds sets the tape block size with the reported value
+ */
+static void idetape_get_blocksize_from_block_descriptor(ide_drive_t *drive)
+{
+
+	idetape_tape_t *tape = drive->driver_data;
+	idetape_pc_t pc;
+	idetape_mode_parameter_header_t *header;
+	idetape_parameter_block_descriptor_t *block_descrp;
+	
+	idetape_create_mode_sense_cmd (&pc, IDETAPE_BLOCK_DESCRIPTOR);
+	if (idetape_queue_pc_tail (drive, &pc)) {
+		printk (KERN_ERR "ide-tape: Can't get block descriptor\n");
+		if (tape->tape_block_size == 0) {
+			printk(KERN_WARNING "ide-tape: Cannot deal with zero block size, assume 32k\n");
+			tape->tape_block_size =  32768;
+		}
+		return;
+	}
+	header = (idetape_mode_parameter_header_t *) pc.buffer;
+	block_descrp = (idetape_parameter_block_descriptor_t *) (pc.buffer + sizeof(idetape_mode_parameter_header_t));
+	tape->tape_block_size =( block_descrp->length[0]<<16) + (block_descrp->length[1]<<8) + block_descrp->length[2];
+#if IDETAPE_DEBUG_INFO
+	printk (KERN_INFO "ide-tape: Adjusted block size - %d\n", tape->tape_block_size);
+#endif /* IDETAPE_DEBUG_INFO */
+}
 static void idetape_add_settings (ide_drive_t *drive)
 {
 	idetape_tape_t *tape = drive->driver_data;
@@ -5712,15 +5943,18 @@
 	ide_add_setting(drive,	"pipeline_head_speed_c",SETTING_READ,	-1,	-1,	TYPE_INT,	0,			0xffff,			1,				1,				&tape->controlled_pipeline_head_speed,	NULL);
 	ide_add_setting(drive,	"pipeline_head_speed_u",SETTING_READ,	-1,	-1,	TYPE_INT,	0,			0xffff,			1,				1,				&tape->uncontrolled_pipeline_head_speed,	NULL);
 	ide_add_setting(drive,	"avg_speed",	SETTING_READ,	-1,	-1,		TYPE_INT,	0,			0xffff,			1,				1,				&tape->avg_speed,		NULL);
+	ide_add_setting(drive,	"debug_level",SETTING_RW,	-1,	-1,		TYPE_INT,	0,			0xffff,			1,				1,				&tape->debug_level,		NULL);
 	if (tape->onstream) {
 		ide_add_setting(drive,	"cur_frames",	SETTING_READ,	-1,	-1,		TYPE_SHORT,	0,			0xffff,			1,				1,				&tape->cur_frames,		NULL);
 		ide_add_setting(drive,	"max_frames",	SETTING_READ,	-1,	-1,		TYPE_SHORT,	0,			0xffff,			1,				1,				&tape->max_frames,		NULL);
 		ide_add_setting(drive,	"insert_speed",	SETTING_READ,	-1,	-1,		TYPE_INT,	0,			0xffff,			1,				1,				&tape->insert_speed,		NULL);
 		ide_add_setting(drive,	"speed_control",SETTING_RW,	-1,	-1,		TYPE_INT,	0,			0xffff,			1,				1,				&tape->speed_control,		NULL);
-		ide_add_setting(drive,	"debug_level",SETTING_RW,	-1,	-1,		TYPE_INT,	0,			0xffff,			1,				1,				&tape->debug_level,		NULL);
 		ide_add_setting(drive,	"tape_still_time",SETTING_READ,	-1,	-1,		TYPE_INT,	0,			0xffff,			1,				1,				&tape->tape_still_time,		NULL);
 		ide_add_setting(drive,	"max_insert_speed",SETTING_RW,	-1,	-1,		TYPE_INT,	0,			0xffff,			1,				1,				&tape->max_insert_speed,	NULL);
 		ide_add_setting(drive,	"insert_size",	SETTING_READ,	-1,	-1,		TYPE_INT,	0,			0xffff,			1,				1,				&tape->insert_size,		NULL);
+		ide_add_setting(drive,	"capacity",	SETTING_READ,	-1,	-1,		TYPE_INT,	0,			0xffff,			1,				1,				&tape->capacity,		NULL);
+		ide_add_setting(drive,	"first_frame",	SETTING_READ,	-1,	-1,		TYPE_INT,	0,			0xffff,			1,				1,				&tape->first_frame_position,		NULL);
+		ide_add_setting(drive,	"logical_blk",	SETTING_READ,	-1,	-1,		TYPE_INT,	0,			0xffff,			1,				1,				&tape->logical_blk_num,		NULL);
 	}
 }
 
@@ -5742,12 +5976,13 @@
 	int speed;
 	struct idetape_id_gcw gcw;
 	int stage_size;
+	struct sysinfo si;
 
 	memset (tape, 0, sizeof (idetape_tape_t));
 	spin_lock_init(&tape->spinlock);
 	drive->driver_data = tape;
 	drive->ready_stat = 0;			/* An ATAPI device ignores DRDY */
-	if (strstr(drive->id->model, "OnStream DI-30"))
+	if (strstr(drive->id->model, "OnStream DI-"))
 		tape->onstream = 1;
 	drive->dsc_overlap = 1;
 #ifdef CONFIG_BLK_DEV_IDEPCI
@@ -5778,9 +6013,11 @@
 	
 	idetape_get_inquiry_results(drive);
 	idetape_get_mode_sense_results(drive);
-	if (tape->onstream)
+	idetape_get_blocksize_from_block_descriptor(drive);
+	if (tape->onstream) {
+		idetape_onstream_mode_sense_tape_parameter_page(drive, 1);
 		idetape_configure_onstream(drive);
-
+	}
 	tape->user_bs_factor = 1;
 	tape->stage_size = tape->capabilities.ctl * tape->tape_block_size;
 	while (tape->stage_size > 0xffff) {
@@ -5804,6 +6041,13 @@
 	speed = IDE_MAX (tape->capabilities.speed, tape->capabilities.max_speed);
 
 	tape->max_stages = speed * 1000 * 10 / tape->stage_size;
+
+	/*
+	 * 	Limit memory use for pipeline to 10% of physical memory
+	 */
+	si_meminfo(&si);
+	if ( tape->max_stages * tape->stage_size > si.totalram * si.mem_unit / 10)
+		tape->max_stages = si.totalram * si.mem_unit / (10 * tape->stage_size);
 	tape->min_pipeline = tape->max_stages;
 	tape->max_pipeline = tape->max_stages * 2;
 
@@ -5867,8 +6111,8 @@
 	char		*out = page;
 	int		len;
 
-	len = sprintf(out,"%s\n", tape->name);
-	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+	len = sprintf(out, "%s\n", tape->name);
+	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
 }
 
 static ide_proc_entry_t idetape_proc[] = {
@@ -5962,7 +6206,7 @@
 			continue;
 		}
 		if (drive->scsi) {
-			if (strstr(drive->id->model, "OnStream DI-30")) {
+			if (strstr(drive->id->model, "OnStream DI-")) {
 				printk("ide-tape: ide-scsi emulation is not supported for %s.\n", drive->id->model);
 			} else {
 				printk("ide-tape: passing drive %s to ide-scsi emulation.\n", drive->name);
diff -u --recursive --new-file v2.4.5/linux/drivers/ide/piix.c linux/drivers/ide/piix.c
--- v2.4.5/linux/drivers/ide/piix.c	Tue Mar  6 19:44:34 2001
+++ linux/drivers/ide/piix.c	Wed Jun 20 11:16:01 2001
@@ -108,7 +108,8 @@
 	c1 = inb_p((unsigned short)bibma + 0x0a);
 
 	switch(bmide_dev->device) {
-		case PCI_DEVICE_ID_INTEL_82820FW_5:
+		case PCI_DEVICE_ID_INTEL_82801BA_8:
+		case PCI_DEVICE_ID_INTEL_82801BA_9:
 			p += sprintf(p, "\n                                Intel PIIX4 Ultra 100 Chipset.\n");
 			break;
 		case PCI_DEVICE_ID_INTEL_82372FB_1:
@@ -358,7 +359,8 @@
 	byte			speed;
 
 	byte udma_66		= eighty_ninty_three(drive);
-	int ultra100		= ((dev->device == PCI_DEVICE_ID_INTEL_82820FW_5)) ? 1 : 0;
+	int ultra100		= ((dev->device == PCI_DEVICE_ID_INTEL_82801BA_8) ||
+				   (dev->device == PCI_DEVICE_ID_INTEL_82801BA_9)) ? 1 : 0;
 	int ultra66		= ((ultra100) ||
 				   (dev->device == PCI_DEVICE_ID_INTEL_82801AA_1) ||
 				   (dev->device == PCI_DEVICE_ID_INTEL_82372FB_1)) ? 1 : 0;
diff -u --recursive --new-file v2.4.5/linux/drivers/ide/rapide.c linux/drivers/ide/rapide.c
--- v2.4.5/linux/drivers/ide/rapide.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/ide/rapide.c	Wed Jun 27 14:12:04 2001
@@ -17,7 +17,7 @@
 
 #include <asm/ecard.h>
 
-static const card_ids __init rapide_cids[] = {
+static card_ids __init rapide_cids[] = {
 	{ MANU_YELLOWSTONE, PROD_YELLOWSTONE_RAPIDE32 },
 	{ 0xffff, 0xffff }
 };
diff -u --recursive --new-file v2.4.5/linux/drivers/ide/sl82c105.c linux/drivers/ide/sl82c105.c
--- v2.4.5/linux/drivers/ide/sl82c105.c	Tue Nov  7 11:02:24 2000
+++ linux/drivers/ide/sl82c105.c	Wed Jun 27 14:12:04 2001
@@ -56,10 +56,9 @@
 }
 
 /*
- * We only deal with PIO mode here - DMA mode 'using_dma' is not
- * initialised at the point that this function is called.
+ * Configure the drive and chipset for PIO
  */
-static void tune_sl82c105(ide_drive_t *drive, byte pio)
+static void config_for_pio(ide_drive_t *drive, int pio, int report)
 {
 	ide_hwif_t *hwif = HWIF(drive);
 	struct pci_dev *dev = hwif->pci_dev;
@@ -83,42 +82,212 @@
 	if (ide_config_drive_speed(drive, xfer_mode) == 0)
 		drv_ctrl = get_timing_sl82c105(&p);
 
+	if (drive->using_dma == 0) {
+		/*
+		 * If we are actually using MW DMA, then we can not
+		 * reprogram the interface drive control register.
+		 */
+		pci_write_config_word(dev, reg, drv_ctrl);
+		pci_read_config_word(dev, reg, &drv_ctrl);
+
+		if (report) {
+			printk("%s: selected %s (%dns) (%04X)\n", drive->name,
+			       ide_xfer_verbose(xfer_mode), p.cycle_time, drv_ctrl);
+		}
+	}
+}
+
+/*
+ * Configure the drive and the chipset for DMA
+ */
+static int config_for_dma(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = HWIF(drive);
+	struct pci_dev *dev = hwif->pci_dev;
+	unsigned short drv_ctrl = 0x909;
+	unsigned int reg;
+
+	reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0);
+
+	if (ide_config_drive_speed(drive, XFER_MW_DMA_2) == 0)
+		drv_ctrl = 0x0240;
+
 	pci_write_config_word(dev, reg, drv_ctrl);
-	pci_read_config_word(dev, reg, &drv_ctrl);
 
-	printk("%s: selected %s (%dns) (%04X)\n", drive->name,
-	       ide_xfer_verbose(xfer_mode), p.cycle_time, drv_ctrl);
+	return 0;
 }
-#endif
 
-void __init ide_dmacapable_sl82c105(ide_hwif_t *hwif, unsigned long dmabase)
+/*
+ * Check to see if the drive and
+ * chipset is capable of DMA mode
+ */
+static int sl82c105_check_drive(ide_drive_t *drive)
+{
+	ide_dma_action_t dma_func = ide_dma_off_quietly;
+
+	do {
+		struct hd_driveid *id = drive->id;
+		ide_hwif_t *hwif = HWIF(drive);
+
+		if (!hwif->autodma)
+			break;
+
+		if (!id || !(id->capability & 1))
+			break;
+
+		/* Consult the list of known "bad" drives */
+		if (ide_dmaproc(ide_dma_bad_drive, drive)) {
+			dma_func = ide_dma_off;
+			break;
+		}
+
+		if (id->field_valid & 2) {
+			if  (id->dma_mword & 7 || id->dma_1word & 7)
+				dma_func = ide_dma_on;
+			break;
+		}
+
+		if (ide_dmaproc(ide_dma_good_drive, drive)) {
+			dma_func = ide_dma_on;
+			break;
+		}
+	} while (0);
+
+	return HWIF(drive)->dmaproc(dma_func, drive);
+}
+
+/*
+ * Our own dmaproc, only to intercept ide_dma_check
+ */
+static int sl82c105_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
+{
+	switch (func) {
+	case ide_dma_check:
+		return sl82c105_check_drive(drive);
+	case ide_dma_on:
+		if (config_for_dma(drive))
+			func = ide_dma_off;
+		/* fall through */
+	case ide_dma_off_quietly:
+	case ide_dma_off:
+		config_for_pio(drive, 4, 0);
+		break;
+	default:
+		break;
+	}
+	return ide_dmaproc(func, drive);
+}
+
+/*
+ * We only deal with PIO mode here - DMA mode 'using_dma' is not
+ * initialised at the point that this function is called.
+ */
+static void tune_sl82c105(ide_drive_t *drive, byte pio)
+{
+	config_for_pio(drive, pio, 1);
+
+	/*
+	 * We support 32-bit I/O on this interface, and it
+	 * doesn't have problems with interrupts.
+	 */
+	drive->io_32bit = 1;
+	drive->unmask = 1;
+}
+
+/*
+ * Return the revision of the Winbond bridge
+ * which this function is part of.
+ */
+static unsigned int sl82c105_bridge_revision(struct pci_dev *dev)
 {
+	struct pci_dev *bridge;
 	unsigned char rev;
 
-	pci_read_config_byte(hwif->pci_dev, PCI_REVISION_ID, &rev);
+	bridge = pci_find_device(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553, NULL);
 
+	/*
+	 * If we are part of a Winbond 553
+	 */
+	if (!bridge || bridge->class >> 8 != PCI_CLASS_BRIDGE_ISA)
+		return -1;
+
+	if (bridge->bus != dev->bus ||
+	    PCI_SLOT(bridge->devfn) != PCI_SLOT(dev->devfn))
+		return -1;
+
+	/*
+	 * We need to find function 0's revision, not function 1
+	 */
+	pci_read_config_byte(bridge, PCI_REVISION_ID, &rev);
+
+	return rev;
+}
+
+/*
+ * Enable the PCI device
+ */
+unsigned int __init pci_init_sl82c105(struct pci_dev *dev, const char *msg)
+{
+	unsigned char ctrl_stat;
+
+	/*
+	 * Enable the ports
+	 */
+	pci_read_config_byte(dev, 0x40, &ctrl_stat);
+	pci_write_config_byte(dev, 0x40, ctrl_stat | 0x33);
+
+	return dev->irq;
+}
+
+void __init dma_init_sl82c105(ide_hwif_t *hwif, unsigned long dma_base)
+{
+	unsigned int rev;
+	byte dma_state;
+
+	dma_state = inb(dma_base + 2);
+	rev = sl82c105_bridge_revision(hwif->pci_dev);
 	if (rev <= 5) {
 		hwif->autodma = 0;
 		hwif->drives[0].autotune = 1;
 		hwif->drives[1].autotune = 1;
-		printk("    %s: revision %d, Bus-Master DMA disabled\n",
+		printk("    %s: Winbond 553 bridge revision %d, BM-DMA disabled\n",
 		       hwif->name, rev);
+		dma_state &= ~0x60;
+	} else {
+		dma_state |= 0x60;
+		hwif->autodma = 1;
 	}
-	ide_setup_dma(hwif, dmabase, 8);
+	outb(dma_state, dma_base + 2);
+
+	hwif->dmaproc = NULL;
+	ide_setup_dma(hwif, dma_base, 8);
+	if (hwif->dmaproc)
+		hwif->dmaproc = sl82c105_dmaproc;
 }
 
+/*
+ * Initialise the chip
+ */
 void __init ide_init_sl82c105(ide_hwif_t *hwif)
 {
-	struct pci_dev *dev = hwif->pci_dev;
+	hwif->tuneproc = tune_sl82c105;
+}
 
-#ifdef CONFIG_ARCH_NETWINDER
-	unsigned char ctrl_stat;
+#else
 
-	pci_read_config_byte(dev, 0x40, &ctrl_stat);
-	pci_write_config_byte(dev, 0x40, ctrl_stat | 0x33);
+unsigned int pci_init_sl82c105(struct pci_dev *dev, const char *msg)
+{
+	return ide_special_settings(dev, msg);
+}
 
-	hwif->tuneproc = tune_sl82c105;
-#else
+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);
@@ -134,5 +303,6 @@
 	printk("IDE control/status register: %08x\n",t32);
 	pci_write_config_dword(dev, 0x40, 0x10ff08a1);
 #endif /* CONFIG_MBX */
-#endif
 }
+#endif
+
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/avmb1/b1.c linux/drivers/isdn/avmb1/b1.c
--- v2.4.5/linux/drivers/isdn/avmb1/b1.c	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/b1.c	Tue Jun 12 13:03:18 2001
@@ -1,114 +1,9 @@
 /*
- * $Id: b1.c,v 1.20.6.4 2001/04/20 02:41:59 keil Exp $
+ * $Id: b1.c,v 1.20.6.6 2001/05/17 21:15:33 kai Exp $
  * 
  * Common module for AVM B1 cards.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
- * 
- * $Log: b1.c,v $
- * Revision 1.20.6.4  2001/04/20 02:41:59  keil
- * changes from mainstream
- *
- * Revision 1.20.6.3  2001/03/21 08:52:20  kai
- * merge from main branch: fix buffer for revision string (calle)
- *
- * Revision 1.20.6.2  2001/03/15 15:11:23  kai
- * *** empty log message ***
- *
- * Revision 1.20.6.1  2001/02/13 11:43:29  kai
- * more compatility changes for 2.2.19
- *
- * Revision 1.20  2000/11/23 20:45:14  kai
- * fixed module_init/exit stuff
- * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
- *
- * Revision 1.19  2000/11/19 17:02:47  kai
- * compatibility cleanup - part 3
- *
- * Revision 1.18  2000/11/19 17:01:53  kai
- * compatibility cleanup - part 2
- *
- * Revision 1.17  2000/11/01 14:05:02  calle
- * - use module_init/module_exit from linux/init.h.
- * - all static struct variables are initialized with "membername:" now.
- * - avm_cs.c, let it work with newer pcmcia-cs.
- *
- * Revision 1.16  2000/08/04 15:36:31  calle
- * copied wrong from file to file :-(
- *
- * Revision 1.15  2000/08/04 12:20:08  calle
- * - Fix unsigned/signed warning in the right way ...
- *
- * Revision 1.14  2000/06/19 16:51:53  keil
- * don't free skb in irq context
- *
- * Revision 1.13  2000/01/25 14:33:38  calle
- * - Added Support AVM B1 PCI V4.0 (tested with prototype)
- *   - splitted up t1pci.c into b1dma.c for common function with b1pciv4
- *   - support for revision register
- *
- * Revision 1.12  1999/11/05 16:38:01  calle
- * Cleanups before kernel 2.4:
- * - Changed all messages to use card->name or driver->name instead of
- *   constant string.
- * - Moved some data from struct avmcard into new struct avmctrl_info.
- *   Changed all lowlevel capi driver to match the new structur.
- *
- * Revision 1.11  1999/10/11 22:04:12  keil
- * COMPAT_NEED_UACCESS (no include in isdn_compat.h)
- *
- * Revision 1.10  1999/09/15 08:16:03  calle
- * Implementation of 64Bit extention complete.
- *
- * Revision 1.9  1999/09/07 09:02:53  calle
- * SETDATA removed. Now inside the kernel the datapart of DATA_B3_REQ and
- * DATA_B3_IND is always directly after the CAPI message. The "Data" member
- * ist never used inside the kernel.
- *
- * Revision 1.8  1999/08/22 20:26:22  calle
- * backported changes from kernel 2.3.14:
- * - several #include "config.h" gone, others come.
- * - "struct device" changed to "struct net_device" in 2.3.14, added a
- *   define in isdn_compat.h for older kernel versions.
- *
- * Revision 1.7  1999/08/04 10:10:09  calle
- * Bugfix: corrected /proc functions, added structure for new AVM cards.
- *
- * Revision 1.6  1999/07/23 08:51:04  calle
- * small fix and typo in checkin before.
- *
- * Revision 1.5  1999/07/23 08:41:48  calle
- * prepared for new AVM cards.
- *
- * Revision 1.4  1999/07/09 15:05:38  keil
- * compat.h is now isdn_compat.h
- *
- * Revision 1.3  1999/07/06 07:41:59  calle
- * - changes in /proc interface
- * - check and changed calls to [dev_]kfree_skb and [dev_]alloc_skb.
- *
- * Revision 1.2  1999/07/05 15:09:47  calle
- * - renamed "appl_release" to "appl_released".
- * - version und profile data now cleared on controller reset
- * - extended /proc interface, to allow driver and controller specific
- *   informations to include by driver hackers.
- *
- * Revision 1.1  1999/07/01 15:26:23  calle
- * complete new version (I love it):
- * + new hardware independed "capi_driver" interface that will make it easy to:
- *   - support other controllers with CAPI-2.0 (i.e. USB Controller)
- *   - write a CAPI-2.0 for the passive cards
- *   - support serial link CAPI-2.0 boxes.
- * + wrote "capi_driver" for all supported cards.
- * + "capi_driver" (supported cards) now have to be configured with
- *   make menuconfig, in the past all supported cards where included
- *   at once.
- * + new and better informations in /proc/capi/
- * + new ioctl to switch trace of capi messages per controller
- *   using "avmcapictrl trace [contr] on|off|...."
- * + complete testcircle with all supported cards and also the
- *   PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done.
- *
  *
  */
 
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/avmb1/b1dma.c linux/drivers/isdn/avmb1/b1dma.c
--- v2.4.5/linux/drivers/isdn/avmb1/b1dma.c	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/b1dma.c	Tue Jun 12 13:03:18 2001
@@ -1,59 +1,10 @@
 /*
- * $Id: b1dma.c,v 1.11.6.4 2001/04/20 02:41:59 keil Exp $
+ * $Id: b1dma.c,v 1.11.6.6 2001/05/17 21:15:33 kai Exp $
  * 
  * Common module for AVM B1 cards that support dma with AMCC
  * 
  * (c) Copyright 2000 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
- * $Log: b1dma.c,v $
- * Revision 1.11.6.4  2001/04/20 02:41:59  keil
- * changes from mainstream
- *
- * Revision 1.11.6.3  2001/03/21 08:52:21  kai
- * merge from main branch: fix buffer for revision string (calle)
- *
- * Revision 1.11.6.2  2001/03/15 15:11:23  kai
- * *** empty log message ***
- *
- * Revision 1.11.6.1  2001/02/13 11:43:29  kai
- * more compatility changes for 2.2.19
- *
- * Revision 1.11  2000/11/19 17:02:47  kai
- * compatibility cleanup - part 3
- *
- * Revision 1.10  2000/11/19 17:01:53  kai
- * compatibility cleanup - part 2
- *
- * Revision 1.9  2000/11/01 14:05:02  calle
- * - use module_init/module_exit from linux/init.h.
- * - all static struct variables are initialized with "membername:" now.
- * - avm_cs.c, let it work with newer pcmcia-cs.
- *
- * Revision 1.8  2000/10/10 17:44:19  kai
- * changes from/for 2.2.18
- *
- * Revision 1.7  2000/08/04 12:20:08  calle
- * - Fix unsigned/signed warning in the right way ...
- *
- * Revision 1.6  2000/06/29 13:59:06  calle
- * Bugfix: reinit txdma without interrupt will confuse some AMCC chips.
- *
- * Revision 1.5  2000/06/19 16:51:53  keil
- * don't free skb in irq context
- *
- * Revision 1.4  2000/04/03 16:38:05  calle
- * made suppress_pollack static.
- *
- * Revision 1.3  2000/02/26 01:00:53  keil
- * changes from 2.3.47
- *
- * Revision 1.2  2000/01/25 14:44:47  calle
- * typo in b1pciv4_detect().
- *
- * Revision 1.1  2000/01/25 14:36:43  calle
- * common function for  T1 PCI and B1 PCI V4.
- *
- *
  */
 
 #include <linux/config.h>
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/avmb1/b1isa.c linux/drivers/isdn/avmb1/b1isa.c
--- v2.4.5/linux/drivers/isdn/avmb1/b1isa.c	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/b1isa.c	Tue Jun 12 13:03:18 2001
@@ -1,83 +1,10 @@
 /*
- * $Id: b1isa.c,v 1.10.6.4 2001/03/21 08:52:21 kai Exp $
+ * $Id: b1isa.c,v 1.10.6.5 2001/05/17 20:41:51 kai Exp $
  * 
  * Module for AVM B1 ISA-card.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
- * $Log: b1isa.c,v $
- * Revision 1.10.6.4  2001/03/21 08:52:21  kai
- * merge from main branch: fix buffer for revision string (calle)
- *
- * Revision 1.10.6.3  2001/03/15 15:11:23  kai
- * *** empty log message ***
- *
- * Revision 1.10.6.2  2001/02/16 16:43:23  kai
- * Changes from -ac16, little bug fixes, typos and the like
- *
- * Revision 1.10.6.1  2001/02/13 11:43:29  kai
- * more compatility changes for 2.2.19
- *
- * Revision 1.10  2000/11/23 20:45:14  kai
- * fixed module_init/exit stuff
- * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
- *
- * Revision 1.9  2000/11/01 14:05:02  calle
- * - use module_init/module_exit from linux/init.h.
- * - all static struct variables are initialized with "membername:" now.
- * - avm_cs.c, let it work with newer pcmcia-cs.
- *
- * Revision 1.8  2000/04/03 13:29:24  calle
- * make Tim Waugh happy (module unload races in 2.3.99-pre3).
- * no real problem there, but now it is much cleaner ...
- *
- * Revision 1.7  2000/02/02 18:36:03  calle
- * - Modules are now locked while init_module is running
- * - fixed problem with memory mapping if address is not aligned
- *
- * Revision 1.6  2000/01/25 14:37:39  calle
- * new message after successful detection including card revision and
- * used resources.
- *
- * Revision 1.5  1999/11/05 16:38:01  calle
- * Cleanups before kernel 2.4:
- * - Changed all messages to use card->name or driver->name instead of
- *   constant string.
- * - Moved some data from struct avmcard into new struct avmctrl_info.
- *   Changed all lowlevel capi driver to match the new structur.
- *
- * Revision 1.4  1999/08/22 20:26:24  calle
- * backported changes from kernel 2.3.14:
- * - several #include "config.h" gone, others come.
- * - "struct device" changed to "struct net_device" in 2.3.14, added a
- *   define in isdn_compat.h for older kernel versions.
- *
- * Revision 1.3  1999/07/09 15:05:40  keil
- * compat.h is now isdn_compat.h
- *
- * Revision 1.2  1999/07/05 15:09:49  calle
- * - renamed "appl_release" to "appl_released".
- * - version und profile data now cleared on controller reset
- * - extended /proc interface, to allow driver and controller specific
- *   informations to include by driver hackers.
- *
- * Revision 1.1  1999/07/01 15:26:27  calle
- * complete new version (I love it):
- * + new hardware independed "capi_driver" interface that will make it easy to:
- *   - support other controllers with CAPI-2.0 (i.e. USB Controller)
- *   - write a CAPI-2.0 for the passive cards
- *   - support serial link CAPI-2.0 boxes.
- * + wrote "capi_driver" for all supported cards.
- * + "capi_driver" (supported cards) now have to be configured with
- *   make menuconfig, in the past all supported cards where included
- *   at once.
- * + new and better informations in /proc/capi/
- * + new ioctl to switch trace of capi messages per controller
- *   using "avmcapictrl trace [contr] on|off|...."
- * + complete testcircle with all supported cards and also the
- *   PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done.
- *
- *
  */
 
 #include <linux/module.h>
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/avmb1/b1pci.c linux/drivers/isdn/avmb1/b1pci.c
--- v2.4.5/linux/drivers/isdn/avmb1/b1pci.c	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/b1pci.c	Tue Jun 12 13:03:18 2001
@@ -1,111 +1,10 @@
 /*
- * $Id: b1pci.c,v 1.29.6.3 2001/04/20 02:41:59 keil Exp $
+ * $Id: b1pci.c,v 1.29.6.4 2001/05/17 20:41:51 kai Exp $
  * 
  * Module for AVM B1 PCI-card.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
- * $Log: b1pci.c,v $
- * Revision 1.29.6.3  2001/04/20 02:41:59  keil
- * changes from mainstream
- *
- * Revision 1.29.6.2  2001/03/21 08:52:21  kai
- * merge from main branch: fix buffer for revision string (calle)
- *
- * Revision 1.29.6.1  2000/11/28 12:02:45  kai
- * MODULE_DEVICE_TABLE for 2.4
- *
- * Revision 1.29.2.2  2000/11/26 17:47:53  kai
- * added PCI_DEV_TABLE for 2.4
- *
- * Revision 1.29.2.1  2000/11/26 17:14:19  kai
- * fix device ids
- * also needs patches to include/linux/pci_ids.h
- *
- * Revision 1.29  2000/11/23 20:45:14  kai
- * fixed module_init/exit stuff
- * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
- *
- * Revision 1.28  2000/11/01 14:05:02  calle
- * - use module_init/module_exit from linux/init.h.
- * - all static struct variables are initialized with "membername:" now.
- * - avm_cs.c, let it work with newer pcmcia-cs.
- *
- * Revision 1.27  2000/08/08 09:24:19  calle
- * calls to pci_enable_device surounded by #ifndef COMPAT_HAS_2_2_PCI
- *
- * Revision 1.26  2000/07/20 10:21:21  calle
- * Bugfix: driver will not be unregistered, if not cards were detected.
- *         this result in an oops in kcapi.c
- *
- * Revision 1.25  2000/05/29 12:29:18  keil
- * make pci_enable_dev compatible to 2.2 kernel versions
- *
- * Revision 1.24  2000/05/19 15:43:22  calle
- * added calls to pci_device_start().
- *
- * Revision 1.23  2000/05/06 00:52:36  kai
- * merged changes from kernel tree
- * fixed timer and net_device->name breakage
- *
- * Revision 1.22  2000/04/21 13:01:33  calle
- * Revision in b1pciv4 driver was missing.
- *
- * Revision 1.21  2000/04/03 13:29:24  calle
- * make Tim Waugh happy (module unload races in 2.3.99-pre3).
- * no real problem there, but now it is much cleaner ...
- *
- * Revision 1.20  2000/02/02 18:36:03  calle
- * - Modules are now locked while init_module is running
- * - fixed problem with memory mapping if address is not aligned
- *
- * Revision 1.19  2000/01/25 14:33:38  calle
- * - Added Support AVM B1 PCI V4.0 (tested with prototype)
- *   - splitted up t1pci.c into b1dma.c for common function with b1pciv4
- *   - support for revision register
- *
- * Revision 1.18  1999/11/05 16:38:01  calle
- * Cleanups before kernel 2.4:
- * - Changed all messages to use card->name or driver->name instead of
- *   constant string.
- * - Moved some data from struct avmcard into new struct avmctrl_info.
- *   Changed all lowlevel capi driver to match the new structur.
- *
- * Revision 1.17  1999/10/05 06:50:07  calle
- * Forgot SA_SHIRQ as argument to request_irq.
- *
- * Revision 1.16  1999/08/11 21:01:07  keil
- * new PCI codefix
- *
- * Revision 1.15  1999/08/10 16:02:27  calle
- * struct pci_dev changed in 2.3.13. Made the necessary changes.
- *
- * Revision 1.14  1999/07/09 15:05:41  keil
- * compat.h is now isdn_compat.h
- *
- * Revision 1.13  1999/07/05 15:09:50  calle
- * - renamed "appl_release" to "appl_released".
- * - version und profile data now cleared on controller reset
- * - extended /proc interface, to allow driver and controller specific
- *   informations to include by driver hackers.
- *
- * Revision 1.12  1999/07/01 15:26:29  calle
- * complete new version (I love it):
- * + new hardware independed "capi_driver" interface that will make it easy to:
- *   - support other controllers with CAPI-2.0 (i.e. USB Controller)
- *   - write a CAPI-2.0 for the passive cards
- *   - support serial link CAPI-2.0 boxes.
- * + wrote "capi_driver" for all supported cards.
- * + "capi_driver" (supported cards) now have to be configured with
- *   make menuconfig, in the past all supported cards where included
- *   at once.
- * + new and better informations in /proc/capi/
- * + new ioctl to switch trace of capi messages per controller
- *   using "avmcapictrl trace [contr] on|off|...."
- * + complete testcircle with all supported cards and also the
- *   PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done.
- *
- *
  */
 
 #include <linux/config.h>
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/avmb1/b1pcmcia.c linux/drivers/isdn/avmb1/b1pcmcia.c
--- v2.4.5/linux/drivers/isdn/avmb1/b1pcmcia.c	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/b1pcmcia.c	Tue Jun 12 13:03:18 2001
@@ -1,89 +1,10 @@
 /*
- * $Id: b1pcmcia.c,v 1.12.6.3 2001/03/21 08:52:21 kai Exp $
+ * $Id: b1pcmcia.c,v 1.12.6.4 2001/05/17 20:41:51 kai Exp $
  * 
  * Module for AVM B1/M1/M2 PCMCIA-card.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
- * $Log: b1pcmcia.c,v $
- * Revision 1.12.6.3  2001/03/21 08:52:21  kai
- * merge from main branch: fix buffer for revision string (calle)
- *
- * Revision 1.12.6.2  2001/02/16 16:43:23  kai
- * Changes from -ac16, little bug fixes, typos and the like
- *
- * Revision 1.12.6.1  2001/02/13 11:43:29  kai
- * more compatility changes for 2.2.19
- *
- * Revision 1.12  2000/11/23 20:45:14  kai
- * fixed module_init/exit stuff
- * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
- *
- * Revision 1.11  2000/11/01 14:05:02  calle
- * - use module_init/module_exit from linux/init.h.
- * - all static struct variables are initialized with "membername:" now.
- * - avm_cs.c, let it work with newer pcmcia-cs.
- *
- * Revision 1.10  2000/05/06 00:52:36  kai
- * merged changes from kernel tree
- * fixed timer and net_device->name breakage
- *
- * Revision 1.9  2000/04/03 13:29:24  calle
- * make Tim Waugh happy (module unload races in 2.3.99-pre3).
- * no real problem there, but now it is much cleaner ...
- *
- * Revision 1.8  2000/03/06 18:00:23  calle
- * - Middleware extention now working with 2.3.49 (capifs).
- * - Fixed typos in debug section of capi.c
- * - Bugfix: Makefile corrected for b1pcmcia.c
- *
- * Revision 1.7  2000/02/02 18:36:03  calle
- * - Modules are now locked while init_module is running
- * - fixed problem with memory mapping if address is not aligned
- *
- * Revision 1.6  2000/01/25 14:37:39  calle
- * new message after successful detection including card revision and
- * used resources.
- *
- * Revision 1.5  1999/11/05 16:38:01  calle
- * Cleanups before kernel 2.4:
- * - Changed all messages to use card->name or driver->name instead of
- *   constant string.
- * - Moved some data from struct avmcard into new struct avmctrl_info.
- *   Changed all lowlevel capi driver to match the new structur.
- *
- * Revision 1.4  1999/08/22 20:26:26  calle
- * backported changes from kernel 2.3.14:
- * - several #include "config.h" gone, others come.
- * - "struct device" changed to "struct net_device" in 2.3.14, added a
- *   define in isdn_compat.h for older kernel versions.
- *
- * Revision 1.3  1999/07/09 15:05:41  keil
- * compat.h is now isdn_compat.h
- *
- * Revision 1.2  1999/07/05 15:09:51  calle
- * - renamed "appl_release" to "appl_released".
- * - version und profile data now cleared on controller reset
- * - extended /proc interface, to allow driver and controller specific
- *   informations to include by driver hackers.
- *
- * Revision 1.1  1999/07/01 15:26:30  calle
- * complete new version (I love it):
- * + new hardware independed "capi_driver" interface that will make it easy to:
- *   - support other controllers with CAPI-2.0 (i.e. USB Controller)
- *   - write a CAPI-2.0 for the passive cards
- *   - support serial link CAPI-2.0 boxes.
- * + wrote "capi_driver" for all supported cards.
- * + "capi_driver" (supported cards) now have to be configured with
- *   make menuconfig, in the past all supported cards where included
- *   at once.
- * + new and better informations in /proc/capi/
- * + new ioctl to switch trace of capi messages per controller
- *   using "avmcapictrl trace [contr] on|off|...."
- * + complete testcircle with all supported cards and also the
- *   PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done.
- *
- *
  */
 
 #include <linux/module.h>
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/avmb1/c4.c linux/drivers/isdn/avmb1/c4.c
--- v2.4.5/linux/drivers/isdn/avmb1/c4.c	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/c4.c	Wed Jun 27 17:10:55 2001
@@ -1,104 +1,9 @@
 /*
- * $Id: c4.c,v 1.20.6.6 2001/04/20 02:41:59 keil Exp $
+ * $Id: c4.c,v 1.20.6.10 2001/06/09 15:14:15 kai Exp $
  * 
- * Module for AVM C4 card.
+ * Module for AVM C4 & C2 card.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
- * 
- * $Log: c4.c,v $
- * Revision 1.20.6.6  2001/04/20 02:41:59  keil
- * changes from mainstream
- *
- * Revision 1.20.6.5  2001/03/21 08:52:21  kai
- * merge from main branch: fix buffer for revision string (calle)
- *
- * Revision 1.20.6.4  2001/03/15 15:11:23  kai
- * *** empty log message ***
- *
- * Revision 1.20.6.3  2001/02/16 16:43:23  kai
- * Changes from -ac16, little bug fixes, typos and the like
- *
- * Revision 1.20.6.2  2001/02/13 11:43:29  kai
- * more compatility changes for 2.2.19
- *
- * Revision 1.20.6.1  2000/11/28 12:02:45  kai
- * MODULE_DEVICE_TABLE for 2.4
- *
- * Revision 1.20.2.2  2000/11/26 17:47:53  kai
- * added PCI_DEV_TABLE for 2.4
- *
- * Revision 1.20.2.1  2000/11/26 17:14:19  kai
- * fix device ids
- * also needs patches to include/linux/pci_ids.h
- *
- * Revision 1.20  2000/11/23 20:45:14  kai
- * fixed module_init/exit stuff
- * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
- *
- * Revision 1.19  2000/11/19 17:02:47  kai
- * compatibility cleanup - part 3
- *
- * Revision 1.18  2000/11/01 14:05:02  calle
- * - use module_init/module_exit from linux/init.h.
- * - all static struct variables are initialized with "membername:" now.
- * - avm_cs.c, let it work with newer pcmcia-cs.
- *
- * Revision 1.17  2000/10/10 17:44:19  kai
- * changes from/for 2.2.18
- *
- * Revision 1.16  2000/08/20 07:30:13  keil
- * changes for 2.4
- *
- * Revision 1.15  2000/08/08 09:24:19  calle
- * calls to pci_enable_device surounded by #ifndef COMPAT_HAS_2_2_PCI
- *
- * Revision 1.14  2000/08/04 12:20:08  calle
- * - Fix unsigned/signed warning in the right way ...
- *
- * Revision 1.13  2000/07/20 10:21:21  calle
- * Bugfix: driver will not be unregistered, if not cards were detected.
- *         this result in an oops in kcapi.c
- *
- * Revision 1.12  2000/06/19 16:51:53  keil
- * don't free skb in irq context
- *
- * Revision 1.11  2000/06/19 15:11:24  keil
- * avoid use of freed structs
- * changes from 2.4.0-ac21
- *
- * Revision 1.10  2000/05/29 12:29:18  keil
- * make pci_enable_dev compatible to 2.2 kernel versions
- *
- * Revision 1.9  2000/05/19 15:43:22  calle
- * added calls to pci_device_start().
- *
- * Revision 1.8  2000/04/03 16:38:05  calle
- * made suppress_pollack static.
- *
- * Revision 1.7  2000/04/03 13:29:24  calle
- * make Tim Waugh happy (module unload races in 2.3.99-pre3).
- * no real problem there, but now it is much cleaner ...
- *
- * Revision 1.6  2000/03/17 12:21:08  calle
- * send patchvalues now working.
- *
- * Revision 1.5  2000/03/16 15:21:03  calle
- * Bugfix in c4_remove: loop 5 times instead of 4 :-(
- *
- * Revision 1.4  2000/02/02 18:36:03  calle
- * - Modules are now locked while init_module is running
- * - fixed problem with memory mapping if address is not aligned
- *
- * Revision 1.3  2000/01/25 14:37:39  calle
- * new message after successful detection including card revision and
- * used resources.
- *
- * Revision 1.2  2000/01/21 20:52:58  keil
- * pci_find_subsys as local function for 2.2.X kernel
- *
- * Revision 1.1  2000/01/20 10:51:37  calle
- * Added driver for C4.
- *
  *
  */
 
@@ -122,15 +27,11 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.20.6.8 $";
+static char *revision = "$Revision: 1.20.6.10 $";
 
 #undef CONFIG_C4_DEBUG
 #undef CONFIG_C4_POLLDEBUG
 
-/* ------------------------------------------------------------- */
-#ifndef PCI_DEVICE_ID_AVM_C2
-#define PCI_DEVICE_ID_AVM_C2	0x1100
-#endif
 /* ------------------------------------------------------------- */
 
 static int suppress_pollack;
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/avmb1/capi.c linux/drivers/isdn/avmb1/capi.c
--- v2.4.5/linux/drivers/isdn/avmb1/capi.c	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/capi.c	Wed Jun 27 17:10:55 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: capi.c,v 1.44.6.11 2001/05/17 20:41:51 kai Exp $
+ * $Id: capi.c,v 1.44.6.12 2001/06/09 15:14:15 kai Exp $
  *
  * CAPI 2.0 Interface for Linux
  *
@@ -43,7 +43,7 @@
 #include "capifs.h"
 #endif
 
-static char *revision = "$Revision: 1.44.6.11 $";
+static char *revision = "$Revision: 1.44.6.12 $";
 
 MODULE_AUTHOR("Carsten Paeth (calle@calle.in-berlin.de)");
 
@@ -256,7 +256,6 @@
 void capiminor_free(struct capiminor *mp)
 {
 	struct capiminor **pp;
-	struct sk_buff *skb;
 
 	pp = &minors;
 	while (*pp) {
@@ -264,12 +263,9 @@
 			*pp = (*pp)->next;
 			if (mp->ttyskb) kfree_skb(mp->ttyskb);
 			mp->ttyskb = 0;
-			while ((skb = skb_dequeue(&mp->recvqueue)) != 0)
-				kfree_skb(skb);
-			while ((skb = skb_dequeue(&mp->inqueue)) != 0)
-				kfree_skb(skb);
-			while ((skb = skb_dequeue(&mp->outqueue)) != 0)
-				kfree_skb(skb);
+			skb_queue_purge(&mp->recvqueue);
+			skb_queue_purge(&mp->inqueue);
+			skb_queue_purge(&mp->outqueue);
 			capiminor_del_all_ack(mp);
 			kmem_cache_free(capiminor_cachep, mp);
 			MOD_DEC_USE_COUNT;
@@ -411,15 +407,12 @@
 static void capidev_free(struct capidev *cdev)
 {
 	struct capidev **pp;
-	struct sk_buff *skb;
 
 	if (cdev->applid)
 		(*capifuncs->capi_release) (cdev->applid);
 	cdev->applid = 0;
 
-	while ((skb = skb_dequeue(&cdev->recvqueue)) != 0) {
-		kfree_skb(skb);
-	}
+	skb_queue_purge(&cdev->recvqueue);
 	
 	pp=&capidev_openlist;
 	while (*pp && *pp != cdev) pp = &(*pp)->next;
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/avmb1/capicmd.h linux/drivers/isdn/avmb1/capicmd.h
--- v2.4.5/linux/drivers/isdn/avmb1/capicmd.h	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/capicmd.h	Tue Jun 12 13:03:18 2001
@@ -1,31 +1,9 @@
 /*
- * $Id: capicmd.h,v 1.2 2000/03/03 15:50:42 calle Exp $
+ * $Id: capicmd.h,v 1.2.6.1 2001/05/17 20:41:51 kai Exp $
  * 
  * CAPI 2.0 Interface for Linux
  * 
  * Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
- * 
- * $Log: capicmd.h,v $
- * Revision 1.2  2000/03/03 15:50:42  calle
- * - kernel CAPI:
- *   - Changed parameter "param" in capi_signal from __u32 to void *.
- *   - rewrote notifier handling in kcapi.c
- *   - new notifier NCCI_UP and NCCI_DOWN
- * - User CAPI:
- *   - /dev/capi20 is now a cloning device.
- *   - middleware extentions prepared.
- * - capidrv.c
- *   - locking of list operations and module count updates.
- *
- * Revision 1.1  1997/03/04 21:50:30  calle
- * Frirst version in isdn4linux
- *
- * Revision 2.2  1997/02/12 09:31:39  calle
- * new version
- *
- * Revision 1.1  1997/01/31 10:32:20  calle
- * Initial revision
- *
  * 
  */
 #ifndef __CAPICMD_H__
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/avmb1/capifs.c linux/drivers/isdn/avmb1/capifs.c
--- v2.4.5/linux/drivers/isdn/avmb1/capifs.c	Thu May 24 15:42:58 2001
+++ linux/drivers/isdn/avmb1/capifs.c	Tue Jun 12 13:03:18 2001
@@ -1,10 +1,10 @@
 /*
  * $Id: capifs.c,v 1.14.6.7 2001/05/24 08:29:08 kai Exp $
- *
+ * 
  * (c) Copyright 2000 by Carsten Paeth (calle@calle.de)
  *
  * Heavily based on devpts filesystem from H. Peter Anvin
- *
+ * 
  */
 
 #include <linux/version.h>
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/avmb1/capifs.h linux/drivers/isdn/avmb1/capifs.h
--- v2.4.5/linux/drivers/isdn/avmb1/capifs.h	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/capifs.h	Tue Jun 12 13:03:18 2001
@@ -1,23 +1,7 @@
 /*
- * $Id: capifs.h,v 1.2 2000/03/08 17:06:33 calle Exp $
+ * $Id: capifs.h,v 1.2.6.1 2001/05/17 20:41:51 kai Exp $
  * 
  * (c) Copyright 2000 by Carsten Paeth (calle@calle.de)
- *
- * $Log: capifs.h,v $
- * Revision 1.2  2000/03/08 17:06:33  calle
- * - changes for devfs and 2.3.49
- * - capifs now configurable (no need with devfs)
- * - New Middleware ioctl CAPI_NCCI_GETUNIT
- * - Middleware again tested with 2.2.14 and 2.3.49 (with and without devfs)
- *
- * Revision 1.1  2000/03/03 16:48:38  calle
- * - Added CAPI2.0 Middleware support (CONFIG_ISDN_CAPI)
- *   It is now possible to create a connection with a CAPI2.0 applikation
- *   and than to handle the data connection from /dev/capi/ (capifs) and also
- *   using async or sync PPP on this connection.
- *   The two major device number 190 and 191 are not confirmed yet,
- *   but I want to save the code in cvs, before I go on.
- *
  *
  */
 
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/avmb1/capiutil.h linux/drivers/isdn/avmb1/capiutil.h
--- v2.4.5/linux/drivers/isdn/avmb1/capiutil.h	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/capiutil.h	Tue Jun 12 13:03:18 2001
@@ -1,45 +1,10 @@
 /*
- * $Id: capiutil.h,v 1.5 2000/03/03 15:50:42 calle Exp $
+ * $Id: capiutil.h,v 1.5.6.1 2001/05/17 20:41:51 kai Exp $
  * 
  * CAPI 2.0 defines & types
  * 
  * From CAPI 2.0 Development Kit AVM 1995 (capi20.h)
  * Rewritten for Linux 1996 by Carsten Paeth (calle@calle.in-berlin.de)
- * 
- * $Log: capiutil.h,v $
- * Revision 1.5  2000/03/03 15:50:42  calle
- * - kernel CAPI:
- *   - Changed parameter "param" in capi_signal from __u32 to void *.
- *   - rewrote notifier handling in kcapi.c
- *   - new notifier NCCI_UP and NCCI_DOWN
- * - User CAPI:
- *   - /dev/capi20 is now a cloning device.
- *   - middleware extentions prepared.
- * - capidrv.c
- *   - locking of list operations and module count updates.
- *
- * Revision 1.4  1999/09/15 08:16:03  calle
- * Implementation of 64Bit extention complete.
- *
- * Revision 1.3  1999/09/07 09:02:53  calle
- * SETDATA removed. Now inside the kernel the datapart of DATA_B3_REQ and
- * DATA_B3_IND is always directly after the CAPI message. The "Data" member
- * ist never used inside the kernel.
- *
- * Revision 1.2  1997/05/18 09:24:19  calle
- * added verbose disconnect reason reporting to avmb1.
- * some fixes in capi20 interface.
- * changed info messages for B1-PCI
- *
- * Revision 1.1  1997/03/04 21:50:35  calle
- * Frirst version in isdn4linux
- *
- * Revision 2.2  1997/02/12 09:31:39  calle
- * new version
- *
- * Revision 1.1  1997/01/31 10:32:20  calle
- * Initial revision
- *
  * 
  */
 #ifndef __CAPIUTIL_H__
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/avmb1/kcapi.c linux/drivers/isdn/avmb1/kcapi.c
--- v2.4.5/linux/drivers/isdn/avmb1/kcapi.c	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/kcapi.c	Wed Jun 27 17:10:55 2001
@@ -1,128 +1,10 @@
 /*
- * $Id: kcapi.c,v 1.21.6.5 2001/03/21 08:52:21 kai Exp $
+ * $Id: kcapi.c,v 1.21.6.7 2001/06/09 15:14:15 kai Exp $
  * 
  * Kernel CAPI 2.0 Module
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
- * $Log: kcapi.c,v $
- * Revision 1.21.6.5  2001/03/21 08:52:21  kai
- * merge from main branch: fix buffer for revision string (calle)
- *
- * Revision 1.21.6.4  2001/03/15 15:11:24  kai
- * *** empty log message ***
- *
- * Revision 1.21.6.3  2001/03/13 16:17:08  kai
- * spelling fixes from 2.4.3-pre
- *
- * Revision 1.21.6.2  2001/02/13 11:43:29  kai
- * more compatility changes for 2.2.19
- *
- * Revision 1.21.6.1  2000/12/10 23:39:19  kai
- * in 2.4 we don't have tq_scheduler anymore.
- * also add one supported card to hfc_pci.c
- * (from main branch)
- *
- * Revision 1.21  2000/11/23 20:45:14  kai
- * fixed module_init/exit stuff
- * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
- *
- * Revision 1.20  2000/11/19 17:01:53  kai
- * compatibility cleanup - part 2
- *
- * Revision 1.19  2000/11/01 14:05:02  calle
- * - use module_init/module_exit from linux/init.h.
- * - all static struct variables are initialized with "membername:" now.
- * - avm_cs.c, let it work with newer pcmcia-cs.
- *
- * Revision 1.18  2000/07/20 10:22:27  calle
- * - Made procfs function cleaner and removed variable "begin".
- *
- * Revision 1.17  2000/04/21 13:00:56  calle
- * Bugfix: driver_proc_info was also wrong.
- *
- * Revision 1.16  2000/04/21 12:38:42  calle
- * Bugfix: error in proc_ functions, begin-off => off-begin
- *
- * Revision 1.15  2000/04/06 15:01:25  calle
- * Bugfix: crash in capidrv.c when reseting a capi controller.
- * - changed code order on remove of controller.
- * - using tq_schedule for notifier in kcapi.c.
- * - now using spin_lock_irqsave() and spin_unlock_irqrestore().
- * strange: sometimes even MP hang on unload of isdn.o ...
- *
- * Revision 1.14  2000/04/03 13:29:25  calle
- * make Tim Waugh happy (module unload races in 2.3.99-pre3).
- * no real problem there, but now it is much cleaner ...
- *
- * Revision 1.13  2000/03/03 15:50:42  calle
- * - kernel CAPI:
- *   - Changed parameter "param" in capi_signal from __u32 to void *.
- *   - rewrote notifier handling in kcapi.c
- *   - new notifier NCCI_UP and NCCI_DOWN
- * - User CAPI:
- *   - /dev/capi20 is now a cloning device.
- *   - middleware extentions prepared.
- * - capidrv.c
- *   - locking of list operations and module count updates.
- *
- * Revision 1.12  2000/01/28 16:45:39  calle
- * new manufacturer command KCAPI_CMD_ADDCARD (generic addcard),
- * will search named driver and call the add_card function if one exist.
- *
- * Revision 1.11  1999/11/23 13:29:29  calle
- * Bugfix: incoming capi message were never traced.
- *
- * Revision 1.10  1999/10/26 15:30:32  calle
- * Generate error message if user want to add card, but driver module is
- * not loaded.
- *
- * Revision 1.9  1999/10/11 22:04:12  keil
- * COMPAT_NEED_UACCESS (no include in isdn_compat.h)
- *
- * Revision 1.8  1999/09/10 17:24:18  calle
- * Changes for proposed standard for CAPI2.0:
- * - AK148 "Linux Exention"
- *
- * Revision 1.7  1999/09/04 06:20:05  keil
- * Changes from kernel set_current_state()
- *
- * Revision 1.6  1999/07/20 06:41:49  calle
- * Bugfix: After the redesign of the AVM B1 driver, the driver didn't even
- *         compile, if not selected as modules.
- *
- * Revision 1.5  1999/07/09 15:05:48  keil
- * compat.h is now isdn_compat.h
- *
- * Revision 1.4  1999/07/08 14:15:17  calle
- * Forgot to count down ncards in drivercb_detach_ctr.
- *
- * Revision 1.3  1999/07/06 07:42:02  calle
- * - changes in /proc interface
- * - check and changed calls to [dev_]kfree_skb and [dev_]alloc_skb.
- *
- * Revision 1.2  1999/07/05 15:09:52  calle
- * - renamed "appl_release" to "appl_released".
- * - version und profile data now cleared on controller reset
- * - extended /proc interface, to allow driver and controller specific
- *   informations to include by driver hackers.
- *
- * Revision 1.1  1999/07/01 15:26:42  calle
- * complete new version (I love it):
- * + new hardware independed "capi_driver" interface that will make it easy to:
- *   - support other controllers with CAPI-2.0 (i.e. USB Controller)
- *   - write a CAPI-2.0 for the passive cards
- *   - support serial link CAPI-2.0 boxes.
- * + wrote "capi_driver" for all supported cards.
- * + "capi_driver" (supported cards) now have to be configured with
- *   make menuconfig, in the past all supported cards where included
- *   at once.
- * + new and better informations in /proc/capi/
- * + new ioctl to switch trace of capi messages per controller
- *   using "avmcapictrl trace [contr] on|off|...."
- * + complete testcircle with all supported cards and also the
- *   PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done.
- *
  */
 #define CONFIG_AVMB1_COMPAT
 
@@ -148,7 +30,7 @@
 #include <linux/b1lli.h>
 #endif
 
-static char *revision = "$Revision: 1.21.6.6 $";
+static char *revision = "$Revision: 1.21.6.7 $";
 
 /* ------------------------------------------------------------- */
 
@@ -1247,14 +1129,12 @@
 
 static __u16 capi_release(__u16 applid)
 {
-	struct sk_buff *skb;
 	int i;
 
 	if (!VALID_APPLID(applid) || APPL(applid)->releasing)
 		return CAPI_ILLAPPNR;
 	APPL(applid)->releasing++;
-	while ((skb = skb_dequeue(&APPL(applid)->recv_queue)) != 0)
-		kfree_skb(skb);
+	skb_queue_purge(&APPL(applid)->recv_queue);
 	for (i = 0; i < CAPI_MAXCONTR; i++) {
 		if (cards[i].cardstate != CARD_RUNNING)
 			continue;
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/avmb1/t1isa.c linux/drivers/isdn/avmb1/t1isa.c
--- v2.4.5/linux/drivers/isdn/avmb1/t1isa.c	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/t1isa.c	Tue Jun 12 13:03:18 2001
@@ -1,104 +1,10 @@
 /*
- * $Id: t1isa.c,v 1.16.6.4 2001/03/21 08:52:21 kai Exp $
+ * $Id: t1isa.c,v 1.16.6.6 2001/05/17 21:15:33 kai Exp $
  * 
  * Module for AVM T1 HEMA-card.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
- * $Log: t1isa.c,v $
- * Revision 1.16.6.4  2001/03/21 08:52:21  kai
- * merge from main branch: fix buffer for revision string (calle)
- *
- * Revision 1.16.6.3  2001/03/15 15:11:24  kai
- * *** empty log message ***
- *
- * Revision 1.16.6.2  2001/02/16 16:43:24  kai
- * Changes from -ac16, little bug fixes, typos and the like
- *
- * Revision 1.16.6.1  2001/02/13 11:43:29  kai
- * more compatility changes for 2.2.19
- *
- * Revision 1.16  2000/11/23 20:45:14  kai
- * fixed module_init/exit stuff
- * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
- *
- * Revision 1.15  2000/11/01 14:05:02  calle
- * - use module_init/module_exit from linux/init.h.
- * - all static struct variables are initialized with "membername:" now.
- * - avm_cs.c, let it work with newer pcmcia-cs.
- *
- * Revision 1.14  2000/10/10 17:44:19  kai
- * changes from/for 2.2.18
- *
- * Revision 1.13  2000/08/04 15:36:31  calle
- * copied wrong from file to file :-(
- *
- * Revision 1.12  2000/08/04 12:20:08  calle
- * - Fix unsigned/signed warning in the right way ...
- *
- * Revision 1.11  2000/04/03 13:29:25  calle
- * make Tim Waugh happy (module unload races in 2.3.99-pre3).
- * no real problem there, but now it is much cleaner ...
- *
- * Revision 1.10  2000/02/02 18:36:04  calle
- * - Modules are now locked while init_module is running
- * - fixed problem with memory mapping if address is not aligned
- *
- * Revision 1.9  2000/01/25 14:37:39  calle
- * new message after successful detection including card revision and
- * used resources.
- *
- * Revision 1.8  1999/11/05 16:38:01  calle
- * Cleanups before kernel 2.4:
- * - Changed all messages to use card->name or driver->name instead of
- *   constant string.
- * - Moved some data from struct avmcard into new struct avmctrl_info.
- *   Changed all lowlevel capi driver to match the new structur.
- *
- * Revision 1.7  1999/09/15 08:16:03  calle
- * Implementation of 64Bit extention complete.
- *
- * Revision 1.6  1999/09/07 09:02:53  calle
- * SETDATA removed. Now inside the kernel the datapart of DATA_B3_REQ and
- * DATA_B3_IND is always directly after the CAPI message. The "Data" member
- * ist never used inside the kernel.
- *
- * Revision 1.5  1999/08/22 20:26:28  calle
- * backported changes from kernel 2.3.14:
- * - several #include "config.h" gone, others come.
- * - "struct device" changed to "struct net_device" in 2.3.14, added a
- *   define in isdn_compat.h for older kernel versions.
- *
- * Revision 1.4  1999/07/09 15:05:50  keil
- * compat.h is now isdn_compat.h
- *
- * Revision 1.3  1999/07/06 07:42:04  calle
- * - changes in /proc interface
- * - check and changed calls to [dev_]kfree_skb and [dev_]alloc_skb.
- *
- * Revision 1.2  1999/07/05 15:09:54  calle
- * - renamed "appl_release" to "appl_released".
- * - version und profile data now cleared on controller reset
- * - extended /proc interface, to allow driver and controller specific
- *   informations to include by driver hackers.
- *
- * Revision 1.1  1999/07/01 15:26:44  calle
- * complete new version (I love it):
- * + new hardware independed "capi_driver" interface that will make it easy to:
- *   - support other controllers with CAPI-2.0 (i.e. USB Controller)
- *   - write a CAPI-2.0 for the passive cards
- *   - support serial link CAPI-2.0 boxes.
- * + wrote "capi_driver" for all supported cards.
- * + "capi_driver" (supported cards) now have to be configured with
- *   make menuconfig, in the past all supported cards where included
- *   at once.
- * + new and better informations in /proc/capi/
- * + new ioctl to switch trace of capi messages per controller
- *   using "avmcapictrl trace [contr] on|off|...."
- * + complete testcircle with all supported cards and also the
- *   PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done.
- *
- *
  */
 
 #include <linux/module.h>
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/avmb1/t1pci.c linux/drivers/isdn/avmb1/t1pci.c
--- v2.4.5/linux/drivers/isdn/avmb1/t1pci.c	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/t1pci.c	Tue Jun 12 13:03:18 2001
@@ -1,80 +1,10 @@
 /*
- * $Id: t1pci.c,v 1.13.6.3 2001/03/21 08:52:21 kai Exp $
+ * $Id: t1pci.c,v 1.13.6.5 2001/05/17 20:41:51 kai Exp $
  * 
  * Module for AVM T1 PCI-card.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
- * $Log: t1pci.c,v $
- * Revision 1.13.6.3  2001/03/21 08:52:21  kai
- * merge from main branch: fix buffer for revision string (calle)
- *
- * Revision 1.13.6.2  2001/02/13 11:43:29  kai
- * more compatility changes for 2.2.19
- *
- * Revision 1.13.6.1  2000/11/28 12:02:45  kai
- * MODULE_DEVICE_TABLE for 2.4
- *
- * Revision 1.13.2.2  2000/11/26 17:47:53  kai
- * added PCI_DEV_TABLE for 2.4
- *
- * Revision 1.13.2.1  2000/11/26 17:14:19  kai
- * fix device ids
- * also needs patches to include/linux/pci_ids.h
- *
- * Revision 1.13  2000/11/23 20:45:14  kai
- * fixed module_init/exit stuff
- * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
- *
- * Revision 1.12  2000/11/01 14:05:02  calle
- * - use module_init/module_exit from linux/init.h.
- * - all static struct variables are initialized with "membername:" now.
- * - avm_cs.c, let it work with newer pcmcia-cs.
- *
- * Revision 1.11  2000/08/08 09:24:19  calle
- * calls to pci_enable_device surounded by #ifndef COMPAT_HAS_2_2_PCI
- *
- * Revision 1.10  2000/07/20 10:21:21  calle
- * Bugfix: driver will not be unregistered, if not cards were detected.
- *         this result in an oops in kcapi.c
- *
- * Revision 1.9  2000/05/19 15:43:22  calle
- * added calls to pci_device_start().
- *
- * Revision 1.8  2000/05/06 00:52:36  kai
- * merged changes from kernel tree
- * fixed timer and net_device->name breakage
- *
- * Revision 1.7  2000/04/07 15:26:55  calle
- * better error message if cabel not connected or T1 has no power.
- *
- * Revision 1.6  2000/04/03 13:29:25  calle
- * make Tim Waugh happy (module unload races in 2.3.99-pre3).
- * no real problem there, but now it is much cleaner ...
- *
- * Revision 1.5  2000/02/02 18:36:04  calle
- * - Modules are now locked while init_module is running
- * - fixed problem with memory mapping if address is not aligned
- *
- * Revision 1.4  2000/01/25 14:33:38  calle
- * - Added Support AVM B1 PCI V4.0 (tested with prototype)
- *   - splitted up t1pci.c into b1dma.c for common function with b1pciv4
- *   - support for revision register
- *
- * Revision 1.3  1999/11/13 21:27:16  keil
- * remove KERNELVERSION
- *
- * Revision 1.2  1999/11/05 16:38:02  calle
- * Cleanups before kernel 2.4:
- * - Changed all messages to use card->name or driver->name instead of
- *   constant string.
- * - Moved some data from struct avmcard into new struct avmctrl_info.
- *   Changed all lowlevel capi driver to match the new structur.
- *
- * Revision 1.1  1999/10/26 15:31:42  calle
- * Added driver for T1-PCI card.
- *
- *
  */
 
 #include <linux/config.h>
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/eicon/common.c linux/drivers/isdn/eicon/common.c
--- v2.4.5/linux/drivers/isdn/eicon/common.c	Sat May 19 17:43:06 2001
+++ linux/drivers/isdn/eicon/common.c	Wed Jun 27 17:10:55 2001
@@ -857,7 +857,7 @@
 {
 	int i;
 
-	bzero(card_list, sizeof(dia_card_list_t));
+	memset(card_list, 0, sizeof(dia_card_list_t));
 
 	for(i = 0; i < DivasCardNext; i++)
 	{
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/eicon/linchr.c linux/drivers/isdn/eicon/linchr.c
--- v2.4.5/linux/drivers/isdn/eicon/linchr.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/linchr.c	Wed Jun 27 17:10:55 2001
@@ -46,161 +46,110 @@
 int do_ioctl(struct inode *pDivasInode, struct file *pDivasFile, 
 			 unsigned int command, unsigned long arg)
 {
-	dia_load_t *pDivaLoad;
-	dia_start_t *pDivaStart;
-	dia_config_t *pDivaConfig;
-	dia_log_t *pDivaLog;
 	byte *pUserCards, card_i;
 	word wCardNum;
-	mem_block_t *mem_block;
 
 	switch (command)
 	{
 		case DIA_IOCTL_CONFIG:
-			pDivaConfig = (dia_config_t *) arg;
-			
-			if (!verify_area(VERIFY_READ, pDivaConfig, sizeof(dia_config_t)))
-			{
-				DivasCardConfig(pDivaConfig);
-			}
-			else
-			{
-				printk(KERN_WARNING "Divas: Unable to complete CONFIG ioctl (verify area failed)\n");
-				return -1;
-			}
-				return 0;
+		{
+			dia_config_t DivaConfig;
+			if (copy_from_user(&DivaConfig, (void *)arg, sizeof(dia_config_t)))
+				return -EFAULT;
+			DivasCardConfig(&DivaConfig);
+			return 0;
+		}
 
 		case DIA_IOCTL_DETECT:
 			pUserCards = (byte *) arg;
 
 			if (!verify_area(VERIFY_WRITE, pUserCards, 20))
 			{
-				put_user(DivasCardNext, pUserCards++);
+				if(__put_user(DivasCardNext, pUserCards++))
+					return -EFAULT;
 
 				for (card_i=1; card_i < 20; card_i++)
 				{
-					put_user((byte) DivasCards[card_i - 1].cfg.card_type, pUserCards++);
+					if(__put_user((byte) DivasCards[card_i - 1].cfg.card_type, pUserCards++))
+						return -EFAULT;
 				}
 			}
-			else
-			{
-				printk(KERN_WARNING "Divas: Unable to complete DETECT ioctl (verify area failed)\n");
-				return -1;
-			}
+			else return -EFAULT;
+
 			return 0;
 
 		case DIA_IOCTL_START:
-			pDivaStart = (dia_start_t *) arg;
-			
-			if (!verify_area(VERIFY_READ, pDivaStart, sizeof(dia_start_t)))
-			{
-				return DivasCardStart(pDivaStart->card_id);
-			}
-			else
-			{
-				printk(KERN_WARNING "Divas: Unable to complete START ioctl (verify area failed)\n");
-				return -1;
-			}
-
+		{
+			dia_start_t DivaStart;
+			if (copy_from_user(&DivaStart, (void *)arg, sizeof(dia_start_t)))
+				return -EFAULT;
+			return DivasCardStart(DivaStart.card_id);
+		}
 
 		case DIA_IOCTL_FLAVOUR:
 			return 0;
 
 		case DIA_IOCTL_LOAD:
-			pDivaLoad = (dia_load_t *) arg;
-			if (!verify_area(VERIFY_READ, pDivaLoad->code,pDivaLoad->length))
+		{
+			dia_load_t DivaLoad;
+			if(copy_from_user(&DivaLoad, (void *)arg, sizeof(dia_load_t)))
+				return -EFAULT;
+			if (!verify_area(VERIFY_READ, DivaLoad.code,DivaLoad.length))
 			{
-				if (DivasCardLoad(pDivaLoad))
+				if (DivasCardLoad(&DivaLoad))
 				{
 					printk(KERN_WARNING "Divas: Error loading DIVA Server adapter\n");
 					return -EINVAL;
 				}
+				return 0;
 			}
-			else
-			{
-				printk(KERN_WARNING "Divas: Error in LOAD parameters (verify failed)\n");
-				return -EINVAL;
-			}
-			return 0;
-
+			return -EFAULT;
+		}
 		case DIA_IOCTL_LOG:
-			pDivaLog = (dia_log_t *) arg;
-			
-			if (!verify_area(VERIFY_READ, pDivaLog, sizeof(dia_log_t)))
-			{
-				DivasLog(pDivaLog);
-			}
-			else
-			{
-				printk(KERN_WARNING "Divas: Unable to complete LOG ioctl (verify area failed)\n");
-				return -1;
-			}
+		{
+			dia_log_t DivaLog;
+			if (copy_from_user(&DivaLog, (void *) arg, sizeof(dia_log_t)))
+				return -EFAULT;
+			DivasLog(&DivaLog);
 			return 0;
+		}
 
 		case DIA_IOCTL_XLOG_REQ:
-			
-			if (!verify_area(VERIFY_READ, (void *)arg, sizeof(word)))
-			{
-				wCardNum = * (word *) arg;
-				DivasXlogReq(wCardNum);
-			}
-			else
-			{
-				printk(KERN_WARNING "Divas: Unable to complete XLOG_REQ ioctl (verify area failed)\n");
-				return -1;
-			}
+			if(get_user(wCardNum, (word *) arg))
+				return -EFAULT;
+			DivasXlogReq(wCardNum);
 			return 0;
 
 		case DIA_IOCTL_GET_NUM:
-			
-			if (!verify_area(VERIFY_WRITE, (void *)arg, sizeof(int)))
-			{
-				* (int *) arg = DivasCardNext;
-			}
-			else
-			{
-				printk(KERN_WARNING "Divas: Unable to complete GET_NUM ioctl (verify area failed)\n");
-				return -1;
-			}
+			if(put_user(DivasCardNext, (int *)arg))
+				return -EFAULT;
 			return 0;
 
 		case DIA_IOCTL_GET_LIST:
+		{
+			dia_card_list_t cards;
 			DPRINTF(("divas: DIA_IOCTL_GET_LIST"));
-			
-			if (!verify_area(VERIFY_WRITE, (void *)arg, sizeof(dia_card_list_t)))
-			{
-				DivasGetList((dia_card_list_t *)arg);
-			}
-			else
-			{
-				printk(KERN_WARNING "Divas: Unable to complete GET_LIST ioctl (verify area failed)\n");
-				return -1;
-			}
+			DivasGetList(&cards);
+			if(copy_to_user((void *)arg, &cards, sizeof(cards)))
+				return -EFAULT;
 			return 0;
-
+		}
 		case DIA_IOCTL_GET_MEM:
-			mem_block = (mem_block_t *) arg;
-			
-			if (!verify_area(VERIFY_WRITE, mem_block, sizeof(mem_block_t)))
-			{
-				DivasGetMem(mem_block);
-			}
-			else
-			{
-				printk(KERN_WARNING "Divas: Unable to complete GET_MEM ioctl (verify area failed)\n");
-				return -1;
-			}
+		{
+			mem_block_t mem_block;
+			if (copy_from_user(&mem_block, (void *)arg, sizeof(mem_block_t)))
+				return -EFAULT;
+			DivasGetMem(&mem_block);
 			return 0;
+		}
 
 		case DIA_IOCTL_UNLOCK:
 			UnlockDivas();
 			return 0;
 
 		default:
-			printk(KERN_WARNING "Divas: Unknown IOCTL Received by DIVA Server Driver(%d)\n", command);
 			return -EINVAL;
 	}
-	
 	return -EINVAL;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/hisax/callc.c linux/drivers/isdn/hisax/callc.c
--- v2.4.5/linux/drivers/isdn/hisax/callc.c	Mon Mar 26 15:38:19 2001
+++ linux/drivers/isdn/hisax/callc.c	Tue Jun 12 10:34:48 2001
@@ -1,4 +1,4 @@
-/* $Id: callc.c,v 2.51.6.2 2001/03/13 16:17:08 kai Exp $
+/* $Id: callc.c,v 2.51.6.3 2001/05/26 15:19:57 kai Exp $
  *
  * Author       Karsten Keil (keil@isdn4linux.de)
  *              based on the teles driver from Jan den Ouden
@@ -20,7 +20,7 @@
 #define MOD_USE_COUNT ( GET_USE_COUNT (&__this_module))
 #endif	/* MODULE */
 
-const char *lli_revision = "$Revision: 2.51.6.2 $";
+const char *lli_revision = "$Revision: 2.51.6.3 $";
 
 extern struct IsdnCard cards[];
 extern int nrcards;
@@ -850,14 +850,14 @@
 
 #define FNCOUNT (sizeof(fnlist)/sizeof(struct FsmNode))
 
-void __init
+int __init
 CallcNew(void)
 {
 	callcfsm.state_count = STATE_COUNT;
 	callcfsm.event_count = EVENT_COUNT;
 	callcfsm.strEvent = strEvent;
 	callcfsm.strState = strState;
-	FsmNew(&callcfsm, fnlist, FNCOUNT);
+	return FsmNew(&callcfsm, fnlist, FNCOUNT);
 }
 
 void
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/hisax/config.c linux/drivers/isdn/hisax/config.c
--- v2.4.5/linux/drivers/isdn/hisax/config.c	Wed Apr 18 11:49:13 2001
+++ linux/drivers/isdn/hisax/config.c	Tue Jun 12 10:34:48 2001
@@ -1,4 +1,4 @@
-/* $Id: config.c,v 2.57.6.13 2001/04/08 19:41:28 kai Exp $
+/* $Id: config.c,v 2.57.6.14 2001/05/26 15:19:57 kai Exp $
  *
  * Author       Karsten Keil (keil@isdn4linux.de)
  *              based on the teles driver from Jan den Ouden
@@ -1332,15 +1332,28 @@
 
 static int __init HiSax_init(void)
 {
-	int i,j;
+	int i, retval;
+#ifdef MODULE
+	int j;
 	int nzproto = 0;
+#endif
 
 	HiSaxVersion();
-	CallcNew();
-	Isdnl3New();
-	Isdnl2New();
-	TeiNew();
-	Isdnl1New();
+	retval = CallcNew();
+	if (retval)
+		goto out;
+	retval = Isdnl3New();
+	if (retval)
+		goto out_callc;
+	retval = Isdnl2New();
+	if (retval)
+		goto out_isdnl3;
+	retval = TeiNew();
+	if (retval)
+		goto out_isdnl2;
+	retval = Isdnl1New();
+	if (retval)
+		goto out_tei;
 
 #ifdef MODULE
 	if (!type[0]) {
@@ -1487,17 +1500,26 @@
 	printk(KERN_DEBUG "HiSax: Total %d card%s defined\n",
 	       nrcards, (nrcards > 1) ? "s" : "");
 
-	if (HiSax_inithardware(NULL)) {
-		/* Install only, if at least one card found */
-		return (0);
-	} else {
-		Isdnl1Free();
-		TeiFree();
-		Isdnl2Free();
-		Isdnl3Free();
-		CallcFree();
-		return -EIO;
+	/* Install only, if at least one card found */
+	if (!HiSax_inithardware(NULL)) {
+		retval = -EIO;
+		goto out_isdnl1;
 	}
+
+	return 0;
+
+ out_isdnl1:
+	Isdnl1Free();
+ out_tei:
+	TeiFree();
+ out_isdnl2:
+	Isdnl2Free();
+ out_isdnl3:
+	Isdnl3Free();
+ out_callc:
+	CallcFree();
+ out:
+	return retval;
 }
 
 static void __exit HiSax_exit(void)
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/hisax/fsm.c linux/drivers/isdn/hisax/fsm.c
--- v2.4.5/linux/drivers/isdn/hisax/fsm.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/fsm.c	Tue Jun 12 10:34:48 2001
@@ -1,4 +1,4 @@
-/* $Id: fsm.c,v 1.14.6.1 2001/02/16 16:43:26 kai Exp $
+/* $Id: fsm.c,v 1.14.6.2 2001/05/26 15:19:57 kai Exp $
  *
  * Author       Karsten Keil (keil@isdn4linux.de)
  *              based on the teles driver from Jan den Ouden
@@ -15,13 +15,16 @@
 
 #define FSM_TIMER_DEBUG 0
 
-void __init
+int __init
 FsmNew(struct Fsm *fsm, struct FsmNode *fnlist, int fncount)
 {
 	int i;
 
 	fsm->jumpmatrix = (FSMFNPTR *)
 		kmalloc(sizeof (FSMFNPTR) * fsm->state_count * fsm->event_count, GFP_KERNEL);
+	if (!fsm->jumpmatrix)
+		return -ENOMEM;
+
 	memset(fsm->jumpmatrix, 0, sizeof (FSMFNPTR) * fsm->state_count * fsm->event_count);
 
 	for (i = 0; i < fncount; i++) 
@@ -32,6 +35,7 @@
 		} else		
 			fsm->jumpmatrix[fsm->state_count * fnlist[i].event +
 				fnlist[i].state] = (FSMFNPTR) fnlist[i].routine;
+	return 0;
 }
 
 void
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/hisax/gazel.c linux/drivers/isdn/hisax/gazel.c
--- v2.4.5/linux/drivers/isdn/hisax/gazel.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/gazel.c	Tue Jun 12 10:34:48 2001
@@ -1,4 +1,4 @@
-/* $Id: gazel.c,v 2.11.6.4 2001/02/16 16:43:26 kai Exp $
+/* $Id: gazel.c,v 2.11.6.6 2001/06/08 08:48:46 kai Exp $
  *
  * gazel.c     low level stuff for Gazel isdn cards
  *
@@ -19,7 +19,7 @@
 #include <linux/pci.h>
 
 extern const char *CardType[];
-const char *gazel_revision = "$Revision: 2.11.6.4 $";
+const char *gazel_revision = "$Revision: 2.11.6.6 $";
 
 #define R647      1
 #define R685      2
@@ -439,10 +439,6 @@
 reserve_regions(struct IsdnCard *card, struct IsdnCardState *cs)
 {
 	unsigned int i, base = 0, adr = 0, len = 0;
-	long flags;
-
-	save_flags(flags);
-	cli();
 
 	switch (cs->subtyp) {
 		case R647:
@@ -487,17 +483,15 @@
 			break;
 	}
 
-	restore_flags(flags);
 	return 0;
 
       error:
-	restore_flags(flags);
 	printk(KERN_WARNING "Gazel: %s io ports 0x%x-0x%x already in use\n",
 	       CardType[cs->typ], adr, adr + len);
 	return 1;
 }
 
-static int
+static int __init
 setup_gazelisa(struct IsdnCard *card, struct IsdnCardState *cs)
 {
 	printk(KERN_INFO "Gazel: ISA PnP card automatic recognition\n");
@@ -546,7 +540,7 @@
 
 static struct pci_dev *dev_tel __initdata = NULL;
 
-static int
+static int __init
 setup_gazelpci(struct IsdnCardState *cs)
 {
 	u_int pci_ioaddr0 = 0, pci_ioaddr1 = 0;
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/hisax/hisax.h linux/drivers/isdn/hisax/hisax.h
--- v2.4.5/linux/drivers/isdn/hisax/hisax.h	Wed Apr 18 11:49:14 2001
+++ linux/drivers/isdn/hisax/hisax.h	Tue Jun 12 10:34:48 2001
@@ -1,4 +1,4 @@
-/* $Id: hisax.h,v 2.52.6.4 2001/04/08 19:32:26 kai Exp $
+/* $Id: hisax.h,v 2.52.6.5 2001/05/26 15:19:57 kai Exp $
  *
  *   Basic declarations, defines and prototypes
  *
@@ -1304,7 +1304,7 @@
 int getcallref(u_char * p);
 int newcallref(void);
 
-void FsmNew(struct Fsm *fsm, struct FsmNode *fnlist, int fncount);
+int FsmNew(struct Fsm *fsm, struct FsmNode *fnlist, int fncount);
 void FsmFree(struct Fsm *fsm);
 int FsmEvent(struct FsmInst *fi, int event, void *arg);
 void FsmChangeState(struct FsmInst *fi, int newstate);
@@ -1335,19 +1335,19 @@
 
 int ll_run(struct IsdnCardState *cs, int addfeatures);
 void ll_stop(struct IsdnCardState *cs);
-void CallcNew(void);
+int CallcNew(void);
 void CallcFree(void);
 int CallcNewChan(struct IsdnCardState *cs);
 void CallcFreeChan(struct IsdnCardState *cs);
-void Isdnl1New(void);
+int Isdnl1New(void);
 void Isdnl1Free(void);
-void Isdnl2New(void);
+int Isdnl2New(void);
 void Isdnl2Free(void);
-void Isdnl3New(void);
+int Isdnl3New(void);
 void Isdnl3Free(void);
 void init_tei(struct IsdnCardState *cs, int protocol);
 void release_tei(struct IsdnCardState *cs);
 char *HiSax_getrev(const char *revision);
-void TeiNew(void);
+int TeiNew(void);
 void TeiFree(void);
 int certification_check(int output);
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/hisax/isdnl1.c linux/drivers/isdn/hisax/isdnl1.c
--- v2.4.5/linux/drivers/isdn/hisax/isdnl1.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/isdnl1.c	Tue Jun 12 10:36:21 2001
@@ -1,4 +1,4 @@
-/* $Id: isdnl1.c,v 2.41.6.2 2001/02/16 16:43:27 kai Exp $
+/* $Id: isdnl1.c,v 2.41.6.3 2001/05/26 15:19:57 kai Exp $
  *
  * isdnl1.c     common low level stuff for Siemens Chipsetbased isdn cards
  *              based on the teles driver from Jan den Ouden
@@ -15,7 +15,7 @@
  *
  */
 
-const char *l1_revision = "$Revision: 2.41.6.2 $";
+const char *l1_revision = "$Revision: 2.41.6.3 $";
 
 #define __NO_VERSION__
 #include <linux/init.h>
@@ -736,26 +736,41 @@
 
 #define L1B_FN_COUNT (sizeof(L1BFnList)/sizeof(struct FsmNode))
 
-void __init 
+int __init
 Isdnl1New(void)
 {
-#ifdef HISAX_UINTERFACE
-	l1fsm_u.state_count = L1U_STATE_COUNT;
-	l1fsm_u.event_count = L1_EVENT_COUNT;
-	l1fsm_u.strEvent = strL1Event;
-	l1fsm_u.strState = strL1UState;
-	FsmNew(&l1fsm_u, L1UFnList, L1U_FN_COUNT);
-#endif
+	int retval;
+
 	l1fsm_s.state_count = L1S_STATE_COUNT;
 	l1fsm_s.event_count = L1_EVENT_COUNT;
 	l1fsm_s.strEvent = strL1Event;
 	l1fsm_s.strState = strL1SState;
-	FsmNew(&l1fsm_s, L1SFnList, L1S_FN_COUNT);
+	retval = FsmNew(&l1fsm_s, L1SFnList, L1S_FN_COUNT);
+	if (retval)
+		return retval;
+
 	l1fsm_b.state_count = L1B_STATE_COUNT;
 	l1fsm_b.event_count = L1_EVENT_COUNT;
 	l1fsm_b.strEvent = strL1Event;
 	l1fsm_b.strState = strL1BState;
-	FsmNew(&l1fsm_b, L1BFnList, L1B_FN_COUNT);
+	retval = FsmNew(&l1fsm_b, L1BFnList, L1B_FN_COUNT);
+	if (retval) {
+		FsmFree(&l1fsm_s);
+		return retval;
+	}
+#ifdef HISAX_UINTERFACE
+	l1fsm_u.state_count = L1U_STATE_COUNT;
+	l1fsm_u.event_count = L1_EVENT_COUNT;
+	l1fsm_u.strEvent = strL1Event;
+	l1fsm_u.strState = strL1UState;
+	retval = FsmNew(&l1fsm_u, L1UFnList, L1U_FN_COUNT);
+	if (retval) {
+		FsmFree(&l1fsm_s);
+		FsmFree(&l1fsm_b);
+		return retval;
+	}
+#endif
+	return 0;
 }
 
 void Isdnl1Free(void)
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/hisax/isdnl2.c linux/drivers/isdn/hisax/isdnl2.c
--- v2.4.5/linux/drivers/isdn/hisax/isdnl2.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/isdnl2.c	Tue Jun 12 10:34:48 2001
@@ -1,4 +1,4 @@
-/* $Id: isdnl2.c,v 2.25.6.1 2001/02/16 16:43:27 kai Exp $
+/* $Id: isdnl2.c,v 2.25.6.2 2001/05/26 15:19:57 kai Exp $
  *
  * Author       Karsten Keil (keil@isdn4linux.de)
  *              based on the teles driver from Jan den Ouden
@@ -16,7 +16,7 @@
 #include "hisax.h"
 #include "isdnl2.h"
 
-const char *l2_revision = "$Revision: 2.25.6.1 $";
+const char *l2_revision = "$Revision: 2.25.6.2 $";
 
 static void l2m_debug(struct FsmInst *fi, char *fmt, ...);
 
@@ -1831,14 +1831,14 @@
 {
 }
 
-void __init
+int __init
 Isdnl2New(void)
 {
 	l2fsm.state_count = L2_STATE_COUNT;
 	l2fsm.event_count = L2_EVENT_COUNT;
 	l2fsm.strEvent = strL2Event;
 	l2fsm.strState = strL2State;
-	FsmNew(&l2fsm, L2FnList, L2_FN_COUNT);
+	return FsmNew(&l2fsm, L2FnList, L2_FN_COUNT);
 }
 
 void
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/hisax/isdnl3.c linux/drivers/isdn/hisax/isdnl3.c
--- v2.4.5/linux/drivers/isdn/hisax/isdnl3.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/isdnl3.c	Tue Jun 12 10:34:48 2001
@@ -1,4 +1,4 @@
-/* $Id: isdnl3.c,v 2.17.6.2 2001/02/16 16:43:27 kai Exp $
+/* $Id: isdnl3.c,v 2.17.6.3 2001/05/26 15:19:57 kai Exp $
  *
  * Author       Karsten Keil (keil@isdn4linux.de)
  *              based on the teles driver from Jan den Ouden
@@ -18,7 +18,7 @@
 #include "isdnl3.h"
 #include <linux/config.h>
 
-const char *l3_revision = "$Revision: 2.17.6.2 $";
+const char *l3_revision = "$Revision: 2.17.6.3 $";
 
 static struct Fsm l3fsm;
 
@@ -591,14 +591,14 @@
 	}
 }
 
-void __init
+int __init
 Isdnl3New(void)
 {
 	l3fsm.state_count = L3_STATE_COUNT;
 	l3fsm.event_count = L3_EVENT_COUNT;
 	l3fsm.strEvent = strL3Event;
 	l3fsm.strState = strL3State;
-	FsmNew(&l3fsm, L3FnList, L3_FN_COUNT);
+	return FsmNew(&l3fsm, L3FnList, L3_FN_COUNT);
 }
 
 void
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/hisax/md5sums.asc linux/drivers/isdn/hisax/md5sums.asc
--- v2.4.5/linux/drivers/isdn/hisax/md5sums.asc	Thu Apr 19 22:30:09 2001
+++ linux/drivers/isdn/hisax/md5sums.asc	Tue Jun 12 10:34:48 2001
@@ -8,11 +8,11 @@
 # Read ../../../Documentation/isdn/HiSax.cert for more informations.
 # 
 9663cc9f4374c361197d394f6d27c459  isac.c
-9666c672c0fa0e65d5cc5b322f10a18c  isdnl1.c
-9250f15b932dfc36855aa120b896ed0b  isdnl2.c
-0cc2ef892bdb4a2be473e00eb1398950  isdnl3.c
-cac9c32fff889c57ff50d59823053019  tei.c
-665044a72334336533ac79da1a831b17  callc.c
+13c3eed869f5139f44c563e3a8fea1f5  isdnl1.c
+64dcc220ae42fe9e4bbc664c9525bd0a  isdnl2.c
+700aa997e04f5e7e0d32f0d60c8e7fa9  isdnl3.c
+51c603829b6cc4f8421f744ad657ceff  tei.c
+144d646162d83bb5b99095917d131865  callc.c
 e592db58630c1f1029cc064110108156  cert.c
 fadeb3b85bb23bc1ac48470c0848d6fa  l3dss1.c
 cf7dec9fac6283716904d26b99188476  l3_1tr6.c
@@ -22,12 +22,12 @@
 # end of md5sums
 
 -----BEGIN PGP SIGNATURE-----
-Version: 2.6.3i
+Version: 2.6.3in
 Charset: noconv
 
-iQCVAwUBOt+j/jpxHvX/mS9tAQGXwAP/U4voKzXAcTfo9CqJhHN92GRxunj6mlvn
-H+1pxSe0GdtC7BlrPhrokB5dNSwewk89Z5t7kTD76kx2FFuTcXBJxbgH7LZVF3ga
-JX92bOWQekHMH7Hk12Qc7zpeTmPzY02pvVc37Eo614BCvJMCk02cpQyo8a5wWRKH
-8vpQkQKiSyY=
-=FFLG
+iQCVAwUBOxFX6zpxHvX/mS9tAQE+bgP7B5FFxU+RQ3l8fBvZoMbu/Mslo9+XgtLg
+gK8Xwnp4Ij909fa2i6i2bvFPkzHULMqp2PRdtxBTn9CdhwSZyRByhCvZvDHitsv2
+ZEIRn2Bd1jhhgWcr5KCbjKUaIwcFY7RdSQJw/yCyGsodg1fLI+g+QrnMkICI/RTa
+AtYLLWgwEqo=
+=3IMV
 -----END PGP SIGNATURE-----
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/hisax/tei.c linux/drivers/isdn/hisax/tei.c
--- v2.4.5/linux/drivers/isdn/hisax/tei.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/tei.c	Tue Jun 12 10:34:48 2001
@@ -1,4 +1,4 @@
-/* $Id: tei.c,v 2.17.6.1 2001/02/16 16:43:29 kai Exp $
+/* $Id: tei.c,v 2.17.6.2 2001/05/26 15:19:57 kai Exp $
  *
  * Author       Karsten Keil (keil@isdn4linux.de)
  *              based on the teles driver from Jan den Ouden
@@ -17,7 +17,7 @@
 #include <linux/init.h>
 #include <linux/random.h>
 
-const char *tei_revision = "$Revision: 2.17.6.1 $";
+const char *tei_revision = "$Revision: 2.17.6.2 $";
 
 #define ID_REQUEST	1
 #define ID_ASSIGNED	2
@@ -446,14 +446,14 @@
 
 #define TEI_FN_COUNT (sizeof(TeiFnList)/sizeof(struct FsmNode))
 
-void __init
+int __init
 TeiNew(void)
 {
 	teifsm.state_count = TEI_STATE_COUNT;
 	teifsm.event_count = TEI_EVENT_COUNT;
 	teifsm.strEvent = strTeiEvent;
 	teifsm.strState = strTeiState;
-	FsmNew(&teifsm, TeiFnList, TEI_FN_COUNT);
+	return FsmNew(&teifsm, TeiFnList, TEI_FN_COUNT);
 }
 
 void
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/hysdn/hycapi.c linux/drivers/isdn/hysdn/hycapi.c
--- v2.4.5/linux/drivers/isdn/hysdn/hycapi.c	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/hysdn/hycapi.c	Tue Jun 12 10:34:48 2001
@@ -1,4 +1,4 @@
-/* $Id: hycapi.c,v 1.8.6.2 2001/04/20 02:42:00 keil Exp $
+/* $Id: hycapi.c,v 1.8.6.3 2001/05/26 15:19:58 kai Exp $
  *
  * Linux driver for HYSDN cards, CAPI2.0-Interface.
  * written by Ulrich Albrecht (u.albrecht@hypercope.de) for Hypercope GmbH
@@ -41,7 +41,7 @@
 #include "hysdn_defs.h"
 #include <linux/kernelcapi.h>
 
-static char hycapi_revision[]="$Revision: 1.8.6.2 $";
+static char hycapi_revision[]="$Revision: 1.8.6.3 $";
 
 unsigned int hycapi_enable = 0xffffffff; 
 MODULE_PARM(hycapi_enable, "i");
@@ -734,7 +734,7 @@
 	struct capi_driver *driver;
 	driver = &hycapi_driver;
 	if (!hy_di) {
-		printk(KERN_ERR "HYSDN: no capi-driver to detach (???)\n");
+		printk(KERN_ERR "HYSDN: no capi-driver to detach (?)\n");
 		return;
 	}
 	printk(KERN_NOTICE "HYSDN: Detaching capi-driver\n");
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/hysdn/hysdn_net.c linux/drivers/isdn/hysdn/hysdn_net.c
--- v2.4.5/linux/drivers/isdn/hysdn/hysdn_net.c	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/hysdn/hysdn_net.c	Tue Jun 12 10:34:48 2001
@@ -1,4 +1,4 @@
-/* $Id: hysdn_net.c,v 1.8.6.2 2001/04/20 02:42:00 keil Exp $
+/* $Id: hysdn_net.c,v 1.8.6.3 2001/06/05 19:45:37 kai Exp $
 
  * Linux driver for HYSDN cards, net (ethernet type) handling routines.
  *
@@ -41,7 +41,7 @@
 MODULE_PARM(hynet_enable, "i");
 
 /* store the actual version for log reporting */
-char *hysdn_net_revision = "$Revision: 1.8.6.2 $";
+char *hysdn_net_revision = "$Revision: 1.8.6.3 $";
 
 #define MAX_SKB_BUFFERS 20	/* number of buffers for keeping TX-data */
 
@@ -304,8 +304,7 @@
 	hysdn_net_release(card);	/* release an existing net device */
 	if ((dev = kmalloc(sizeof(struct net_local), GFP_KERNEL)) == NULL) {
 		printk(KERN_WARNING "HYSDN: unable to allocate mem\n");
-		if (card->debug_flags & LOG_NET_INIT)
-			return (-ENOMEM);
+		return (-ENOMEM);
 	}
 	memset(dev, 0, sizeof(struct net_local));	/* clean the structure */
 
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/hysdn/hysdn_proclog.c linux/drivers/isdn/hysdn/hysdn_proclog.c
--- v2.4.5/linux/drivers/isdn/hysdn/hysdn_proclog.c	Mon Nov 27 16:53:43 2000
+++ linux/drivers/isdn/hysdn/hysdn_proclog.c	Tue Jun 12 10:34:48 2001
@@ -1,4 +1,4 @@
-/* $Id: hysdn_proclog.c,v 1.9 2000/11/25 17:01:01 kai Exp $
+/* $Id: hysdn_proclog.c,v 1.9.6.1 2001/05/26 15:19:58 kai Exp $
 
  * Linux driver for HYSDN cards, /proc/net filesystem log functions.
  * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
@@ -228,7 +228,7 @@
 	struct log_data *inf;
 	int len;
 	word ino;
-	struct procdata *pd;
+	struct procdata *pd = NULL;
 	hysdn_card *card;
 
 	if (!*((struct log_data **) file->private_data)) {
@@ -271,7 +271,7 @@
 hysdn_log_open(struct inode *ino, struct file *filep)
 {
 	hysdn_card *card;
-	struct procdata *pd;
+	struct procdata *pd = NULL;
 	ulong flags;
 
 	lock_kernel();
@@ -381,7 +381,7 @@
 	unsigned int mask = 0;
 	word ino;
 	hysdn_card *card;
-	struct procdata *pd;
+	struct procdata *pd = NULL;
 
 	if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE)
 		return (mask);	/* no polling for write supported */
diff -u --recursive --new-file v2.4.5/linux/drivers/isdn/isdn_ppp.c linux/drivers/isdn/isdn_ppp.c
--- v2.4.5/linux/drivers/isdn/isdn_ppp.c	Tue May 22 10:23:16 2001
+++ linux/drivers/isdn/isdn_ppp.c	Tue Jun 12 10:35:44 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_ppp.c,v 1.85.6.4 2001/04/08 18:53:07 kai Exp $
+/* $Id: isdn_ppp.c,v 1.85.6.5 2001/05/26 15:19:56 kai Exp $
  *
  * Linux ISDN subsystem, functions for synchronous PPP (linklevel).
  *
@@ -83,7 +83,7 @@
 static int isdn_ppp_bundle(struct ippp_struct *, int unit);
 #endif	/* CONFIG_ISDN_MPP */
   
-char *isdn_ppp_revision = "$Revision: 1.85.6.4 $";
+char *isdn_ppp_revision = "$Revision: 1.85.6.5 $";
 
 static struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS];
 
@@ -785,7 +785,10 @@
 			}
 			skb_reserve(skb, hl);
 			if (copy_from_user(skb_put(skb, count), buf, count))
+			{
+				kfree_skb(skb);
 				return -EFAULT;
+			}
 			if (is->debug & 0x40) {
 				printk(KERN_DEBUG "ppp xmit: len %d\n", (int) skb->len);
 				isdn_ppp_frame_log("xmit", skb->data, skb->len, 32,is->unit,lp->ppp_slot);
diff -u --recursive --new-file v2.4.5/linux/drivers/macintosh/mac_hid.c linux/drivers/macintosh/mac_hid.c
--- v2.4.5/linux/drivers/macintosh/mac_hid.c	Sun Sep 17 09:48:05 2000
+++ linux/drivers/macintosh/mac_hid.c	Wed Jun 27 13:37:35 2001
@@ -15,6 +15,7 @@
 #include <linux/proc_fs.h>
 #include <linux/sysctl.h>
 #include <linux/input.h>
+#include <linux/module.h>
 
 #ifdef CONFIG_MAC_ADBKEYCODES
 #include <linux/keyboard.h>
@@ -401,6 +402,8 @@
 	return keyboard_sends_linux_keycodes;
 }
 
+EXPORT_SYMBOL(mac_hid_keyboard_sends_linux_keycodes);
+
 static int __init mac_hid_setup(char *str)
 {
 	int ints[2];
@@ -448,6 +451,8 @@
 	return 0;
 }
 
+EXPORT_SYMBOL(mac_hid_mouse_emulate_buttons);
+
 static void emumousebtn_input_register(void)
 {
 	emumousebtn.name = "Macintosh mouse button emulation";
@@ -473,9 +478,19 @@
 #ifdef CONFIG_MAC_ADBKEYCODES
 	memcpy(pc_key_maps_save, key_maps, sizeof(key_maps));
 
-	if (!keyboard_sends_linux_keycodes)
+	if (!keyboard_sends_linux_keycodes) {
+#ifdef CONFIG_MAGIC_SYSRQ
+		ppc_md.ppc_kbd_sysrq_xlate   = mac_hid_kbd_sysrq_xlate;
+		SYSRQ_KEY                = 0x69;
+#endif
 		memcpy(key_maps, mac_key_maps_save, sizeof(key_maps));
+	} else {
+#ifdef CONFIG_MAGIC_SYSRQ
+		ppc_md.ppc_kbd_sysrq_xlate   = pckbd_sysrq_xlate;
+		SYSRQ_KEY                = 0x54;
 #endif
+	}
+#endif /* CONFIG_MAC_ADBKEYCODES */
 
 #ifdef CONFIG_MAC_EMUMOUSEBTN
 	emumousebtn_input_register();
diff -u --recursive --new-file v2.4.5/linux/drivers/macintosh/mac_keyb.c linux/drivers/macintosh/mac_keyb.c
--- v2.4.5/linux/drivers/macintosh/mac_keyb.c	Sun Dec  3 17:48:19 2000
+++ linux/drivers/macintosh/mac_keyb.c	Wed Jun 27 13:37:35 2001
@@ -305,7 +305,7 @@
 	return 1;
 }
 
-int mackbd_unexpected_up(unsigned char keycode)
+char mackbd_unexpected_up(unsigned char keycode)
 {
 	return 0x80;
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/macintosh/macserial.c linux/drivers/macintosh/macserial.c
--- v2.4.5/linux/drivers/macintosh/macserial.c	Sun Feb  4 10:21:25 2001
+++ linux/drivers/macintosh/macserial.c	Wed Jun 27 13:37:35 2001
@@ -448,7 +448,7 @@
 		goto out;
 	info->tx_active = 0;
 
-	if (info->x_char) {
+	if (info->x_char && !info->power_wait) {
 		/* Send next char */
 		write_zsdata(info->zs_channel, info->x_char);
 		info->x_char = 0;
@@ -456,7 +456,8 @@
 		goto out;
 	}
 
-	if ((info->xmit_cnt <= 0) || info->tty->stopped || info->tx_stopped) {
+	if ((info->xmit_cnt <= 0) || info->tty->stopped || info->tx_stopped
+	    || info->power_wait) {
 		write_zsreg(info->zs_channel, 0, RES_Tx_P);
 		goto out;
 	}
@@ -474,6 +475,14 @@
 	restore_flags(flags);
 }
 
+static void powerup_done(unsigned long data)
+{
+	struct mac_serial *info = (struct mac_serial *) data;
+
+	info->power_wait = 0;
+	transmit_chars(info);
+}
+
 static _INLINE_ void status_handle(struct mac_serial *info)
 {
 	unsigned char status;
@@ -730,7 +739,7 @@
 	}
 }
 
-static int startup(struct mac_serial * info, int can_sleep)
+static int startup(struct mac_serial * info)
 {
 	int delay;
 
@@ -753,6 +762,18 @@
 
 	setup_scc(info);
 
+	if (delay) {
+		unsigned long flags;
+
+		/* delay is in ms */
+		save_flags(flags);
+		cli();
+		info->power_wait = 1;
+		mod_timer(&info->powerup_timer,
+			  jiffies + (delay * HZ + 999) / 1000);
+		restore_flags(flags);
+	}
+
 	OPNDBG("enabling IRQ on ttyS%d (irq %d)...\n", info->line, info->irq);
 
 	info->flags |= ZILOG_INITIALIZED;
@@ -761,15 +782,6 @@
 		enable_irq(info->rx_dma_irq);
 	}
 
-	if (delay) {
-		if (can_sleep) {
-			/* we need to wait a bit before using the port */
-			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(delay * HZ / 1000);
-		} else
-			mdelay(delay);
-	}
-
 	return 0;
 }
 
@@ -863,7 +875,7 @@
 		queue_task(&tty->flip.tqueue, &tq_timer);
 }
 
-static void poll_rxdma(void *private_)
+static void poll_rxdma(unsigned long private_)
 {
 	struct mac_serial	*info = (struct mac_serial *) private_;
 	unsigned long flags;
@@ -2325,7 +2337,7 @@
 	 * Start up serial port
 	 */
 
-	retval = startup(info, 1);
+	retval = startup(info);
 	if (retval)
 		return retval;
 
@@ -2426,6 +2438,10 @@
 		zss->rx_dma_irq = ch->intrs[2].line;
 		spin_lock_init(&zss->rx_dma_lock);
 	}
+
+	init_timer(&zss->powerup_timer);
+	zss->powerup_timer.function = powerup_done;
+	zss->powerup_timer.data = (unsigned long) zss;
 }
 
 /* Ask the PROM how many Z8530s we have and initialize their zs_channels */
@@ -2680,14 +2696,7 @@
 	return 0;
 }
 
-#ifdef MODULE
-int init_module(void)
-{
-	macserial_init();
-	return 0;
-}
-
-void cleanup_module(void)
+void macserial_cleanup(void)
 {
 	int i;
 	unsigned long flags;
@@ -2717,7 +2726,9 @@
 		pmu_unregister_sleep_notifier(&serial_sleep_notifier);
 #endif /* CONFIG_PMAC_PBOOK */
 }
-#endif /* MODULE */
+
+module_init(macserial_init);
+module_exit(macserial_cleanup);
 
 #if 0
 /*
@@ -3119,7 +3130,7 @@
 			struct mac_serial *info = &zs_soft[i];
 			if (info->flags & ZILOG_SLEEPING) {
 				info->flags &= ~ZILOG_SLEEPING;
-				startup(info, 0);
+				startup(info);
 			}
 		}
 		break;
diff -u --recursive --new-file v2.4.5/linux/drivers/macintosh/macserial.h linux/drivers/macintosh/macserial.h
--- v2.4.5/linux/drivers/macintosh/macserial.h	Sun Feb  4 10:21:25 2001
+++ linux/drivers/macintosh/macserial.h	Wed Jun 27 13:37:35 2001
@@ -115,6 +115,7 @@
 	char is_irda;		/* is connected to an IrDA codec */
 	unsigned char tx_active; /* character is being xmitted */
 	unsigned char tx_stopped; /* output is suspended */
+	unsigned char power_wait; /* waiting for power-up delay to expire */
 
 	/* We need to know the current clock divisor
 	 * to read the bps rate the chip has currently
@@ -186,6 +187,8 @@
 	void			*dma_priv;
 	struct timer_list	poll_dma_timer;
 #define RX_DMA_TIMER	(jiffies + 10*HZ/1000)
+
+	struct timer_list	powerup_timer;
 };
 
 
diff -u --recursive --new-file v2.4.5/linux/drivers/md/md.c linux/drivers/md/md.c
--- v2.4.5/linux/drivers/md/md.c	Fri May 25 09:48:49 2001
+++ linux/drivers/md/md.c	Wed Jun 20 20:55:08 2001
@@ -634,7 +634,7 @@
 	md_list_add(&rdev->same_set, &mddev->disks);
 	rdev->mddev = mddev;
 	mddev->nb_dev++;
-	printk("bind<%s,%d>\n", partition_name(rdev->dev), mddev->nb_dev);
+	printk("md: bind<%s,%d>\n", partition_name(rdev->dev), mddev->nb_dev);
 }
 
 static void unbind_rdev_from_array (mdk_rdev_t * rdev)
@@ -646,7 +646,7 @@
 	md_list_del(&rdev->same_set);
 	MD_INIT_LIST_HEAD(&rdev->same_set);
 	rdev->mddev->nb_dev--;
-	printk("unbind<%s,%d>\n", partition_name(rdev->dev),
+	printk("md: unbind<%s,%d>\n", partition_name(rdev->dev),
 						 rdev->mddev->nb_dev);
 	rdev->mddev = NULL;
 }
@@ -686,7 +686,7 @@
 
 static void export_rdev (mdk_rdev_t * rdev)
 {
-	printk("export_rdev(%s)\n",partition_name(rdev->dev));
+	printk("md: export_rdev(%s)\n",partition_name(rdev->dev));
 	if (rdev->mddev)
 		MD_BUG();
 	unlock_rdev(rdev);
@@ -694,7 +694,7 @@
 	md_list_del(&rdev->all);
 	MD_INIT_LIST_HEAD(&rdev->all);
 	if (rdev->pending.next != &rdev->pending) {
-		printk("(%s was pending)\n",partition_name(rdev->dev));
+		printk("md: (%s was pending)\n",partition_name(rdev->dev));
 		md_list_del(&rdev->pending);
 		MD_INIT_LIST_HEAD(&rdev->pending);
 	}
@@ -777,14 +777,14 @@
 {
 	int i;
 
-	printk("  SB: (V:%d.%d.%d) ID:<%08x.%08x.%08x.%08x> CT:%08x\n",
+	printk("md:  SB: (V:%d.%d.%d) ID:<%08x.%08x.%08x.%08x> CT:%08x\n",
 		sb->major_version, sb->minor_version, sb->patch_version,
 		sb->set_uuid0, sb->set_uuid1, sb->set_uuid2, sb->set_uuid3,
 		sb->ctime);
-	printk("     L%d S%08d ND:%d RD:%d md%d LO:%d CS:%d\n", sb->level,
+	printk("md:     L%d S%08d ND:%d RD:%d md%d LO:%d CS:%d\n", sb->level,
 		sb->size, sb->nr_disks, sb->raid_disks, sb->md_minor,
 		sb->layout, sb->chunk_size);
-	printk("     UT:%08x ST:%d AD:%d WD:%d FD:%d SD:%d CSUM:%08x E:%08lx\n",
+	printk("md:     UT:%08x ST:%d AD:%d WD:%d FD:%d SD:%d CSUM:%08x E:%08lx\n",
 		sb->utime, sb->state, sb->active_disks, sb->working_disks,
 		sb->failed_disks, sb->spare_disks,
 		sb->sb_csum, (unsigned long)sb->events_lo);
@@ -793,24 +793,24 @@
 		mdp_disk_t *desc;
 
 		desc = sb->disks + i;
-		printk("     D %2d: ", i);
+		printk("md:     D %2d: ", i);
 		print_desc(desc);
 	}
-	printk("     THIS: ");
+	printk("md:     THIS: ");
 	print_desc(&sb->this_disk);
 
 }
 
 static void print_rdev(mdk_rdev_t *rdev)
 {
-	printk(" rdev %s: O:%s, SZ:%08ld F:%d DN:%d ",
+	printk("md: rdev %s: O:%s, SZ:%08ld F:%d DN:%d ",
 		partition_name(rdev->dev), partition_name(rdev->old_dev),
 		rdev->size, rdev->faulty, rdev->desc_nr);
 	if (rdev->sb) {
-		printk("rdev superblock:\n");
+		printk("md: rdev superblock:\n");
 		print_sb(rdev->sb);
 	} else
-		printk("no rdev superblock!\n");
+		printk("md: no rdev superblock!\n");
 }
 
 void md_print_devices (void)
@@ -820,9 +820,9 @@
 	mddev_t *mddev;
 
 	printk("\n");
-	printk("	**********************************\n");
-	printk("	* <COMPLETE RAID STATE PRINTOUT> *\n");
-	printk("	**********************************\n");
+	printk("md:	**********************************\n");
+	printk("md:	* <COMPLETE RAID STATE PRINTOUT> *\n");
+	printk("md:	**********************************\n");
 	ITERATE_MDDEV(mddev,tmp) {
 		printk("md%d: ", mdidx(mddev));
 
@@ -838,7 +838,7 @@
 		ITERATE_RDEV(mddev,rdev,tmp2)
 			print_rdev(rdev);
 	}
-	printk("	**********************************\n");
+	printk("md:	**********************************\n");
 	printk("\n");
 }
 
@@ -917,15 +917,15 @@
 
 	if (!rdev->sb) {
 		MD_BUG();
-		return -1;
+		return 1;
 	}
 	if (rdev->faulty) {
 		MD_BUG();
-		return -1;
+		return 1;
 	}
 	if (rdev->sb->md_magic != MD_SB_MAGIC) {
 		MD_BUG();
-		return -1;
+		return 1;
 	}
 
 	dev = rdev->dev;
@@ -1014,7 +1014,7 @@
 
 int md_update_sb(mddev_t * mddev)
 {
-	int first, err, count = 100;
+	int err, count = 100;
 	struct md_list_head *tmp;
 	mdk_rdev_t *rdev;
 
@@ -1044,13 +1044,9 @@
 	printk(KERN_INFO "md: updating md%d RAID superblock on device\n",
 					mdidx(mddev));
 
-	first = 1;
 	err = 0;
 	ITERATE_RDEV(mddev,rdev,tmp) {
-		if (!first) {
-			first = 0;
-			printk(", ");
-		}
+		printk("md: ");
 		if (rdev->faulty)
 			printk("(skipping faulty ");
 		printk("%s ", partition_name(rdev->dev));
@@ -1061,12 +1057,12 @@
 		} else
 			printk(")\n");
 	}
-	printk(".\n");
 	if (err) {
-		printk("errors occurred during superblock update, repeating\n");
-		if (--count)
+		if (--count) {
+			printk("md: errors occurred during superblock update, repeating\n");
 			goto repeat;
-		printk("excessive errors occurred during superblock update, exiting\n");
+		}
+		printk("md: excessive errors occurred during superblock update, exiting\n");
 	}
 	return 0;
 }
@@ -1092,7 +1088,7 @@
 
 	rdev = (mdk_rdev_t *) kmalloc(sizeof(*rdev), GFP_KERNEL);
 	if (!rdev) {
-		printk("could not alloc mem for %s!\n", partition_name(newdev));
+		printk("md: could not alloc mem for %s!\n", partition_name(newdev));
 		return -ENOMEM;
 	}
 	memset(rdev, 0, sizeof(*rdev));
@@ -1244,7 +1240,7 @@
 					rdev->sb->events_hi--;
 		}
 
-		printk("%s's event counter: %08lx\n", partition_name(rdev->dev),
+		printk("md: %s's event counter: %08lx\n", partition_name(rdev->dev),
 			(unsigned long)rdev->sb->events_lo);
 		if (!freshest) {
 			freshest = rdev;
@@ -1263,7 +1259,7 @@
 	}
 	if (out_of_date) {
 		printk(OUT_OF_DATE);
-		printk("freshest: %s\n", partition_name(freshest->dev));
+		printk("md: freshest: %s\n", partition_name(freshest->dev));
 	}
 	memcpy (sb, freshest->sb, sizeof(*sb));
 
@@ -1489,7 +1485,7 @@
 		rdev->size = calc_dev_size(rdev->dev, mddev, persistent);
 		if (rdev->size < sb->chunk_size / 1024) {
 			printk (KERN_WARNING
-				"Dev %s smaller than chunk_size: %ldk < %dk\n",
+				"md: Dev %s smaller than chunk_size: %ldk < %dk\n",
 				partition_name(rdev->dev),
 				rdev->size, sb->chunk_size / 1024);
 			return -EINVAL;
@@ -1663,7 +1659,7 @@
 
 	err = mddev->pers->run(mddev);
 	if (err) {
-		printk("pers->run() failed ...\n");
+		printk("md: pers->run() failed ...\n");
 		mddev->pers = NULL;
 		return -EINVAL;
 	}
@@ -1705,7 +1701,7 @@
 		set_device_ro(mddev_to_kdev(mddev), 0);
 
 		printk (KERN_INFO
-			"md%d switched to read-write mode.\n", mdidx(mddev));
+			"md: md%d switched to read-write mode.\n", mdidx(mddev));
 		/*
 		 * Kick recovery or resync if necessary
 		 */
@@ -1793,7 +1789,7 @@
 			 * interrupted.
 			 */
 			if (!mddev->recovery_running && !resync_interrupted) {
-				printk("marking sb clean...\n");
+				printk("md: marking sb clean...\n");
 				mddev->sb->state |= 1 << MD_SB_CLEAN;
 			}
 			md_update_sb(mddev);
@@ -1806,12 +1802,12 @@
 	 * Free resources if final stop
 	 */
 	if (!ro) {
-		printk (KERN_INFO "md%d stopped.\n", mdidx(mddev));
+		printk (KERN_INFO "md: md%d stopped.\n", mdidx(mddev));
 		free_mddev(mddev);
 
 	} else
 		printk (KERN_INFO
-			"md%d switched to read-only mode.\n", mdidx(mddev));
+			"md: md%d switched to read-only mode.\n", mdidx(mddev));
 out:
 	return err;
 }
@@ -1843,16 +1839,16 @@
 		return;
 	}
 
-	printk("running: ");
+	printk("md: running: ");
 
 	ITERATE_RDEV(mddev,rdev,tmp) {
 		printk("<%s>", partition_name(rdev->dev));
 	}
-	printk("\nnow!\n");
+	printk("\nmd: now!\n");
 
 	err = do_md_run (mddev);
 	if (err) {
-		printk("do_md_run() returned %d\n", err);
+		printk("md :do_md_run() returned %d\n", err);
 		/*
 		 * prevent the writeback of an unrunnable array
 		 */
@@ -1882,20 +1878,20 @@
 	kdev_t md_kdev;
 
 
-	printk("autorun ...\n");
+	printk("md: autorun ...\n");
 	while (pending_raid_disks.next != &pending_raid_disks) {
 		rdev0 = md_list_entry(pending_raid_disks.next,
 					 mdk_rdev_t, pending);
 
-		printk("considering %s ...\n", partition_name(rdev0->dev));
+		printk("md: considering %s ...\n", partition_name(rdev0->dev));
 		MD_INIT_LIST_HEAD(&candidates);
 		ITERATE_RDEV_PENDING(rdev,tmp) {
 			if (uuid_equal(rdev0, rdev)) {
 				if (!sb_equal(rdev0->sb, rdev->sb)) {
-					printk("%s has same UUID as %s, but superblocks differ ...\n", partition_name(rdev->dev), partition_name(rdev0->dev));
+					printk("md: %s has same UUID as %s, but superblocks differ ...\n", partition_name(rdev->dev), partition_name(rdev0->dev));
 					continue;
 				}
-				printk("  adding %s ...\n", partition_name(rdev->dev));
+				printk("md:  adding %s ...\n", partition_name(rdev->dev));
 				md_list_del(&rdev->pending);
 				md_list_add(&rdev->pending, &candidates);
 			}
@@ -1908,7 +1904,7 @@
 		md_kdev = MKDEV(MD_MAJOR, rdev0->sb->md_minor);
 		mddev = kdev_to_mddev(md_kdev);
 		if (mddev) {
-			printk("md%d already running, cannot run %s\n",
+			printk("md: md%d already running, cannot run %s\n",
 				 mdidx(mddev), partition_name(rdev0->dev));
 			ITERATE_RDEV_GENERIC(candidates,pending,rdev,tmp)
 				export_rdev(rdev);
@@ -1921,7 +1917,7 @@
  		}
  		if (md_kdev == countdev)
  			atomic_inc(&mddev->active);
-		printk("created md%d\n", mdidx(mddev));
+		printk("md: created md%d\n", mdidx(mddev));
 		ITERATE_RDEV_GENERIC(candidates,pending,rdev,tmp) {
 			bind_rdev_to_array(rdev, mddev);
 			md_list_del(&rdev->pending);
@@ -1929,7 +1925,7 @@
 		}
 		autorun_array(mddev);
 	}
-	printk("... autorun DONE.\n");
+	printk("md: ... autorun DONE.\n");
 }
 
 /*
@@ -1971,7 +1967,7 @@
 	mdk_rdev_t *start_rdev = NULL, *rdev;
 
 	if (md_import_device(startdev, 1)) {
-		printk("could not import %s!\n", partition_name(startdev));
+		printk("md: could not import %s!\n", partition_name(startdev));
 		goto abort;
 	}
 
@@ -1981,7 +1977,7 @@
 		goto abort;
 	}
 	if (start_rdev->faulty) {
-		printk("can not autostart based on faulty %s!\n",
+		printk("md: can not autostart based on faulty %s!\n",
 						partition_name(startdev));
 		goto abort;
 	}
@@ -1991,7 +1987,7 @@
 
 	err = detect_old_array(sb);
 	if (err) {
-		printk("array version is too old to be autostarted, use raidtools 0.90 mkraid --upgrade\nto upgrade the array without data loss!\n");
+		printk("md: array version is too old to be autostarted, use raidtools 0.90 mkraid --upgrade\nto upgrade the array without data loss!\n");
 		goto abort;
 	}
 
@@ -2007,7 +2003,7 @@
 		if (dev == startdev)
 			continue;
 		if (md_import_device(dev, 1)) {
-			printk("could not import %s, trying to run array nevertheless.\n", partition_name(dev));
+			printk("md: could not import %s, trying to run array nevertheless.\n", partition_name(dev));
 			continue;
 		}
 		rdev = find_rdev_all(dev);
@@ -2129,7 +2125,7 @@
 	dev = MKDEV(info->major,info->minor);
 
 	if (find_rdev_all(dev)) {
-		printk("device %s already used in a RAID array!\n",
+		printk("md: device %s already used in a RAID array!\n",
 				partition_name(dev));
 		return -EBUSY;
 	}
@@ -2137,7 +2133,7 @@
 		/* expecting a device which has a superblock */
 		err = md_import_device(dev, 1);
 		if (err) {
-			printk("md error, md_import_device returned %d\n", err);
+			printk("md: md_import_device returned %d\n", err);
 			return -EINVAL;
 		}
 		rdev = find_rdev_all(dev);
@@ -2192,9 +2188,9 @@
 
 		persistent = !mddev->sb->not_persistent;
 		if (!persistent)
-			printk("nonpersistent superblock ...\n");
+			printk("md: nonpersistent superblock ...\n");
 		if (!mddev->sb->chunk_size)
-			printk("no chunksize?\n");
+			printk("md: no chunksize?\n");
 
 		size = calc_dev_size(dev, mddev, persistent);
 		rdev->sb_offset = calc_dev_sboffset(dev, mddev, persistent);
@@ -2221,7 +2217,7 @@
 	if (!mddev->pers)
 		return -ENODEV;
 
-	printk("trying to remove %s from md%d ... \n",
+	printk("md: trying to remove %s from md%d ... \n",
 		partition_name(dev), mdidx(mddev));
 
 	if (!mddev->pers->diskop) {
@@ -2261,7 +2257,7 @@
 
 	return 0;
 busy:
-	printk("cannot remove active disk %s from md%d ... \n",
+	printk("md: cannot remove active disk %s from md%d ... \n",
 		partition_name(dev), mdidx(mddev));
 	return -EBUSY;
 }
@@ -2276,7 +2272,7 @@
 	if (!mddev->pers)
 		return -ENODEV;
 
-	printk("trying to hot-add %s to md%d ... \n",
+	printk("md: trying to hot-add %s to md%d ... \n",
 		partition_name(dev), mdidx(mddev));
 
 	if (!mddev->pers->diskop) {
@@ -2431,31 +2427,31 @@
 
 static int set_disk_info (mddev_t * mddev, void * arg)
 {
-	printk("not yet");
+	printk("md: not yet");
 	return -EINVAL;
 }
 
 static int clear_array (mddev_t * mddev)
 {
-	printk("not yet");
+	printk("md: not yet");
 	return -EINVAL;
 }
 
 static int write_raid_info (mddev_t * mddev)
 {
-	printk("not yet");
+	printk("md: not yet");
 	return -EINVAL;
 }
 
 static int protect_array (mddev_t * mddev)
 {
-	printk("not yet");
+	printk("md: not yet");
 	return -EINVAL;
 }
 
 static int unprotect_array (mddev_t * mddev)
 {
-	printk("not yet");
+	printk("md: not yet");
 	return -EINVAL;
 }
 
@@ -2551,7 +2547,7 @@
 		case SET_ARRAY_INFO:
 		case START_ARRAY:
 			if (mddev) {
-				printk("array md%d already exists!\n",
+				printk("md: array md%d already exists!\n",
 								mdidx(mddev));
 				err = -EEXIST;
 				goto abort;
@@ -2573,12 +2569,12 @@
 			 */
 			err = lock_mddev(mddev);
 			if (err) {
-				printk("ioctl, reason %d, cmd %d\n", err, cmd);
+				printk("md: ioctl, reason %d, cmd %d\n", err, cmd);
 				goto abort;
 			}
 
 			if (mddev->sb) {
-				printk("array md%d already has a superblock!\n",
+				printk("md: array md%d already has a superblock!\n",
 				       mdidx(mddev));
 				err = -EBUSY;
 				goto abort_unlock;
@@ -2591,7 +2587,7 @@
 				}
 				err = set_array_info(mddev, &info);
 				if (err) {
-					printk("couldnt set array info. %d\n", err);
+					printk("md: couldnt set array info. %d\n", err);
 					goto abort_unlock;
 				}
 			}
@@ -2603,7 +2599,7 @@
 			 */
 			err = autostart_array((kdev_t)arg, dev);
 			if (err) {
-				printk("autostart %s failed!\n",
+				printk("md: autostart %s failed!\n",
 					partition_name((kdev_t)arg));
 				goto abort;
 			}
@@ -2622,7 +2618,7 @@
 	}
 	err = lock_mddev(mddev);
 	if (err) {
-		printk("ioctl lock interrupted, reason %d, cmd %d\n",err, cmd);
+		printk("md: ioctl lock interrupted, reason %d, cmd %d\n",err, cmd);
 		goto abort;
 	}
 	/* if we don't have a superblock yet, only ADD_NEW_DISK or STOP_ARRAY is allowed */
@@ -2760,7 +2756,7 @@
 		}
 
 		default:
-			printk(KERN_WARNING "%s(pid %d) used obsolete MD ioctl, upgrade your software to use new ictls.\n", current->comm, current->pid);
+			printk(KERN_WARNING "md: %s(pid %d) used obsolete MD ioctl, upgrade your software to use new ictls.\n", current->comm, current->pid);
 			err = -EINVAL;
 			goto abort_unlock;
 	}
@@ -2773,7 +2769,7 @@
 	return err;
 done:
 	if (err)
-		printk("huh12?\n");
+		printk("md: huh12?\n");
 abort:
 	return err;
 }
@@ -2835,7 +2831,7 @@
 	 */
 	current->policy = SCHED_OTHER;
 	current->nice = -20;
-//	md_unlock_kernel();
+	md_unlock_kernel();
 
 	up(thread->sem);
 
@@ -2845,9 +2841,9 @@
 		add_wait_queue(&thread->wqueue, &wait);
 		set_task_state(current, TASK_INTERRUPTIBLE);
 		if (!test_bit(THREAD_WAKEUP, &thread->flags)) {
-			dprintk("thread %p went to sleep.\n", thread);
+			dprintk("md: thread %p went to sleep.\n", thread);
 			schedule();
-			dprintk("thread %p woke up.\n", thread);
+			dprintk("md: thread %p woke up.\n", thread);
 		}
 		current->state = TASK_RUNNING;
 		remove_wait_queue(&thread->wqueue, &wait);
@@ -2859,7 +2855,7 @@
 		} else
 			break;
 		if (md_signal_pending(current)) {
-			printk("%8s(%d) flushing signals.\n", current->comm,
+			printk("md: %8s(%d) flushing signals.\n", current->comm,
 				current->pid);
 			md_flush_signals();
 		}
@@ -2870,7 +2866,7 @@
 
 void md_wakeup_thread(mdk_thread_t *thread)
 {
-	dprintk("waking up MD thread %p.\n", thread);
+	dprintk("md: waking up MD thread %p.\n", thread);
 	set_bit(THREAD_WAKEUP, &thread->flags);
 	wake_up(&thread->wqueue);
 }
@@ -2909,7 +2905,7 @@
 		MD_BUG();
 		return;
 	}
-	printk("interrupting MD-thread pid %d\n", thread->tsk->pid);
+	printk("md: interrupting MD-thread pid %d\n", thread->tsk->pid);
 	send_sig(SIGKILL, thread->tsk, 1);
 }
 
@@ -3132,7 +3128,7 @@
 		return -EBUSY;
 
 	pers[pnum] = p;
-	printk(KERN_INFO "%s personality registered\n", p->name);
+	printk(KERN_INFO "md: %s personality registered\n", p->name);
 	return 0;
 }
 
@@ -3141,7 +3137,7 @@
 	if (pnum >= MAX_PERSONALITY)
 		return -EINVAL;
 
-	printk(KERN_INFO "%s personality unregistered\n", pers[pnum]->name);
+	printk(KERN_INFO "md: %s personality unregistered\n", pers[pnum]->name);
 	pers[pnum] = NULL;
 	return 0;
 }
@@ -3203,9 +3199,9 @@
 		curr_events = kstat.dk_drive_rblk[major][idx] +
 						kstat.dk_drive_wblk[major][idx] ;
 		curr_events -= sync_io[major][idx];
-//		printk("events(major: %d, idx: %d): %ld\n", major, idx, curr_events);
-		if (curr_events != rdev->last_events) {
-//			printk("!I(%ld)", curr_events - rdev->last_events);
+//		printk("md: events(major: %d, idx: %d): %ld\n", major, idx, curr_events);
+		if ((curr_events - rdev->last_events) > 32) {
+//			printk("!I(%ld)%x", curr_events - rdev->last_events, rdev->dev);
 			rdev->last_events = curr_events;
 			idle = 0;
 		}
@@ -3332,7 +3328,7 @@
 			 * got a signal, exit.
 			 */
 			mddev->curr_resync = 0;
-			printk("md_do_sync() got signal ... exiting\n");
+			printk("md: md_do_sync() got signal ... exiting\n");
 			md_flush_signals();
 			err = -EINTR;
 			goto out;
@@ -3481,7 +3477,7 @@
 	if ((code == MD_SYS_DOWN) || (code == MD_SYS_HALT)
 				  || (code == MD_SYS_POWER_OFF)) {
 
-		printk(KERN_INFO "stopping all md devices.\n");
+		printk(KERN_INFO "md: stopping all md devices.\n");
 
 		ITERATE_MDDEV(mddev,tmp)
 			do_md_stop (mddev, 1);
@@ -3518,7 +3514,7 @@
 	max_readahead[MAJOR_NR] = md_maxreadahead;
 	hardsect_size[MAJOR_NR] = md_hardsect_sizes;
 
-	printk("md.c: sizeof(mdp_super_t) = %d\n", (int)sizeof(mdp_super_t));
+	dprintk("md: sizeof(mdp_super_t) = %d\n", (int)sizeof(mdp_super_t));
 
 #ifdef CONFIG_PROC_FS
 	create_proc_read_entry("mdstat", 0, NULL, md_status_read_proc, NULL);
@@ -3530,13 +3526,13 @@
 	static char * name = "mdrecoveryd";
 	int minor;
 	
-	printk (KERN_INFO "md driver %d.%d.%d MAX_MD_DEVS=%d, MD_SB_DISKS=%d\n",
+	printk (KERN_INFO "md: md driver %d.%d.%d MAX_MD_DEVS=%d, MD_SB_DISKS=%d\n",
 			MD_MAJOR_VERSION, MD_MINOR_VERSION,
 			MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS);
 
 	if (devfs_register_blkdev (MAJOR_NR, "md", &md_fops))
 	{
-		printk (KERN_ALERT "Unable to get major %d for md\n", MAJOR_NR);
+		printk (KERN_ALERT "md: Unable to get major %d for md\n", MAJOR_NR);
 		return (-1);
 	}
 	devfs_handle = devfs_mk_dir (NULL, "md", NULL);
@@ -3560,7 +3556,7 @@
 
 	md_recovery_thread = md_register_thread(md_do_recovery, NULL, name);
 	if (!md_recovery_thread)
-		printk(KERN_ALERT "bug: couldn't allocate md_recovery_thread\n");
+		printk(KERN_ALERT "md: bug: couldn't allocate md_recovery_thread\n");
 
 	md_register_reboot_notifier(&md_notifier);
 	raid_table_header = register_sysctl_table(raid_root_table, 1);
@@ -3605,13 +3601,13 @@
 	mdk_rdev_t *rdev;
 	int i;
 
-	printk(KERN_INFO "autodetecting RAID arrays\n");
+	printk(KERN_INFO "md: Autodetecting RAID arrays.\n");
 
 	for (i = 0; i < dev_cnt; i++) {
 		kdev_t dev = detected_devices[i];
 
 		if (md_import_device(dev,1)) {
-			printk(KERN_ALERT "could not import %s!\n",
+			printk(KERN_ALERT "md: could not import %s!\n",
 			       partition_name(dev));
 			continue;
 		}
@@ -3638,7 +3634,7 @@
 	char device_set [MAX_MD_DEVS];
 	int pers[MAX_MD_DEVS];
 	int chunk[MAX_MD_DEVS];
-	kdev_t devices[MAX_MD_DEVS][MD_SB_DISKS];
+	char *device_names[MAX_MD_DEVS];
 } md_setup_args md__initdata;
 
 /*
@@ -3657,25 +3653,25 @@
  *             md=n,device-list      reads a RAID superblock from the devices
  *             elements in device-list are read by name_to_kdev_t so can be
  *             a hex number or something like /dev/hda1 /dev/sdb
+ * 2001-06-03: Dave Cinege <dcinege@psychosis.com>
+ *		Shifted name_to_kdev_t() and related operations to md_set_drive()
+ *		for later execution. Rewrote section to make devfs compatible.
  */
-#ifndef MODULE
-extern kdev_t name_to_kdev_t(char *line) md__init;
 static int md__init md_setup(char *str)
 {
-	int minor, level, factor, fault, i=0;
-	kdev_t device;
-	char *devnames, *pername = "";
+	int minor, level, factor, fault;
+	char *pername = "";
+	char *str1 = str;
 
 	if (get_option(&str, &minor) != 2) {	/* MD Number */
 		printk("md: Too few arguments supplied to md=.\n");
 		return 0;
 	}
 	if (minor >= MAX_MD_DEVS) {
-		printk ("md: Minor device number too high.\n");
+		printk ("md: md=%d, Minor device number too high.\n", minor);
 		return 0;
-	} else if (md_setup_args.device_set[minor]) {
-		printk ("md: Warning - md=%d,... has been specified twice;\n"
-			"    will discard the first definition.\n", minor);
+	} else if (md_setup_args.device_names[minor]) {
+		printk ("md: md=%d, Specified more then once. Replacing previous definition.\n", minor);
 	}
 	switch (get_option(&str, &level)) {	/* RAID Personality */
 	case 2: /* could be 0 or -1.. */
@@ -3706,53 +3702,72 @@
 		}
 		/* FALL THROUGH */
 	case 1: /* the first device is numeric */
-		md_setup_args.devices[minor][i++] = level;
+		str = str1;
 		/* FALL THROUGH */
 	case 0:
 		md_setup_args.pers[minor] = 0;
 		pername="super-block";
 	}
-	devnames = str;
-	for (; i<MD_SB_DISKS && str; i++) {
-		if ((device = name_to_kdev_t(str))) {
-			md_setup_args.devices[minor][i] = device;
-		} else {
-			printk ("md: Unknown device name, %s.\n", str);
-			return 0;
-		}
-		if ((str = strchr(str, ',')) != NULL)
-			str++;
-	}
-	if (!i) {
-		printk ("md: No devices specified for md%d?\n", minor);
-		return 0;
-	}
-
+	
 	printk ("md: Will configure md%d (%s) from %s, below.\n",
-		minor, pername, devnames);
-	md_setup_args.devices[minor][i] = (kdev_t) 0;
-	md_setup_args.device_set[minor] = 1;
+		minor, pername, str);
+	md_setup_args.device_names[minor] = str;
+			
 	return 1;
 }
-#endif /* !MODULE */
 
+extern kdev_t name_to_kdev_t(char *line) md__init;
 void md__init md_setup_drive(void)
 {
 	int minor, i;
 	kdev_t dev;
 	mddev_t*mddev;
+	kdev_t devices[MD_SB_DISKS+1];
 
 	for (minor = 0; minor < MAX_MD_DEVS; minor++) {
+		int err = 0;
+		char *devname;
 		mdu_disk_info_t dinfo;
 
-		int err = 0;
-		if (!md_setup_args.device_set[minor])
+		if ((devname = md_setup_args.device_names[minor]) == 0)	continue;
+	
+		for (i = 0; i < MD_SB_DISKS && devname != 0; i++) {
+
+			char *p;
+			void *handle;
+	
+			if ((p = strchr(devname, ',')) != NULL)
+				*p++ = 0;
+
+			dev = name_to_kdev_t(devname);
+			handle = devfs_find_handle(NULL, devname, MAJOR (dev), MINOR (dev),
+						    DEVFS_SPECIAL_BLK, 1);
+			if (handle != 0) {
+				unsigned major, minor;
+				devfs_get_maj_min(handle, &major, &minor);
+				dev = MKDEV(major, minor);
+			}
+			if (dev == 0) {
+				printk ("md: Unknown device name: %s\n", devname);
+				break;
+			}
+			
+			devices[i] = dev;
+			md_setup_args.device_set[minor] = 1;
+			
+			devname = p;
+		}
+		devices[i] = 0;
+		
+		if (md_setup_args.device_set[minor] == 0)
 			continue;
-		printk("md: Loading md%d.\n", minor);
+		
 		if (mddev_map[minor].mddev) {
-			printk(".. md%d already autodetected - use raid=noautodetect\n", minor);
+			printk("md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n", minor);
 			continue;
 		}
+		printk("md: Loading md%d: %s\n", minor, md_setup_args.device_names[minor]);
+		
 		mddev = alloc_mddev(MKDEV(MD_MAJOR,minor));
 		if (mddev == NULL) {
 			printk("md: kmalloc failed - cannot start array %d\n", minor);
@@ -3776,7 +3791,7 @@
 			ainfo.layout = 0;
 			ainfo.chunk_size = md_setup_args.chunk[minor];
 			err = set_array_info(mddev, &ainfo);
-			for (i = 0; !err && (dev = md_setup_args.devices[minor][i]); i++) {
+			for (i = 0; !err && (dev = devices[i]); i++) {
 				dinfo.number = i;
 				dinfo.raid_disk = i;
 				dinfo.state = (1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC);
@@ -3790,7 +3805,7 @@
 			}
 		} else {
 			/* persistent */
-			for (i = 0; (dev = md_setup_args.devices[minor][i]); i++) {
+			for (i = 0; (dev = devices[i]); i++) {
 				dinfo.major = MAJOR(dev);
 				dinfo.minor = MINOR(dev);
 				add_new_disk (mddev, &dinfo);
@@ -3831,7 +3846,7 @@
 int md__init md_run_setup(void)
 {
 	if (raid_setup_args.noautodetect)
-		printk(KERN_INFO "skipping autodetection of RAID arrays\n");
+		printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
 	else
 		autostart_arrays();
 	md_setup_drive();
diff -u --recursive --new-file v2.4.5/linux/drivers/md/raid0.c linux/drivers/md/raid0.c
--- v2.4.5/linux/drivers/md/raid0.c	Mon Dec 11 13:19:35 2000
+++ linux/drivers/md/raid0.c	Wed Jun 20 20:55:08 2001
@@ -80,14 +80,14 @@
 	{
 		struct strip_zone *zone = conf->strip_zone + i;
 
-		printk("zone %d\n", i);
+		printk("raid0: zone %d\n", i);
 		zone->dev_offset = current_offset;
 		smallest = NULL;
 		c = 0;
 
 		ITERATE_RDEV_ORDERED(mddev,rdev,j) {
 
-			printk(" checking %s ...", partition_name(rdev->dev));
+			printk("raid0: checking %s ...", partition_name(rdev->dev));
 			if (rdev->size > current_offset)
 			{
 				printk(" contained as device %d\n", c);
@@ -103,7 +103,7 @@
 
 		zone->nb_dev = c;
 		zone->size = (smallest->size - current_offset) * c;
-		printk(" zone->nb_dev: %d, size: %ld\n",zone->nb_dev,zone->size);
+		printk("raid0: zone->nb_dev: %d, size: %ld\n",zone->nb_dev,zone->size);
 
 		if (!conf->smallest || (zone->size < conf->smallest->size))
 			conf->smallest = zone;
@@ -112,9 +112,9 @@
 		curr_zone_offset += zone->size;
 
 		current_offset = smallest->size;
-		printk("current zone offset: %ld\n", current_offset);
+		printk("raid0: current zone offset: %ld\n", current_offset);
 	}
-	printk("done.\n");
+	printk("raid0: done.\n");
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/md/raid1.c linux/drivers/md/raid1.c
--- v2.4.5/linux/drivers/md/raid1.c	Thu May 24 15:40:59 2001
+++ linux/drivers/md/raid1.c	Wed Jun 20 20:55:08 2001
@@ -82,7 +82,7 @@
 			bh = t;
 			cnt--;
 		} else {
-			PRINTK("waiting for %d bh\n", cnt);
+			PRINTK("raid1: waiting for %d bh\n", cnt);
 			wait_event(conf->wait_buffer, conf->freebh_cnt >= cnt);
 		}
 	}
@@ -1123,7 +1123,7 @@
 
 		mddev = r1_bh->mddev;
 		if (mddev->sb_dirty) {
-			printk(KERN_INFO "dirty sb detected, updating.\n");
+			printk(KERN_INFO "raid1: dirty sb detected, updating.\n");
 			mddev->sb_dirty = 0;
 			md_update_sb(mddev);
 		}
diff -u --recursive --new-file v2.4.5/linux/drivers/md/raid5.c linux/drivers/md/raid5.c
--- v2.4.5/linux/drivers/md/raid5.c	Thu May 24 15:40:59 2001
+++ linux/drivers/md/raid5.c	Wed Jun 20 20:55:08 2001
@@ -31,6 +31,7 @@
  */
 
 #define NR_STRIPES		256
+#define	IO_THRESHOLD		1
 #define HASH_PAGES		1
 #define HASH_PAGES_ORDER	0
 #define NR_HASH			(HASH_PAGES * PAGE_SIZE / sizeof(struct stripe_head *))
@@ -65,24 +66,33 @@
 			BUG();
 		if (atomic_read(&conf->active_stripes)==0)
 			BUG();
-		if (test_bit(STRIPE_HANDLE, &sh->state)) {
+		if (test_bit(STRIPE_DELAYED, &sh->state))
+			list_add_tail(&sh->lru, &conf->delayed_list);
+		else if (test_bit(STRIPE_HANDLE, &sh->state)) {
 			list_add_tail(&sh->lru, &conf->handle_list);
 			md_wakeup_thread(conf->thread);
-		}
-		else {
+		} else {
+			if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) {
+				atomic_dec(&conf->preread_active_stripes);
+				if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD)
+					md_wakeup_thread(conf->thread);
+			}
 			list_add_tail(&sh->lru, &conf->inactive_list);
 			atomic_dec(&conf->active_stripes);
-			wake_up(&conf->wait_for_stripe);
+			if (!conf->inactive_blocked ||
+			    atomic_read(&conf->active_stripes) < (NR_STRIPES*3/4))
+				wake_up(&conf->wait_for_stripe);
 		}
 	}
 }
 static void release_stripe(struct stripe_head *sh)
 {
 	raid5_conf_t *conf = sh->raid_conf;
-
-	spin_lock_irq(&conf->device_lock);
+	unsigned long flags;
+	
+	spin_lock_irqsave(&conf->device_lock, flags);
 	__release_stripe(conf, sh);
-	spin_unlock_irq(&conf->device_lock);
+	spin_unlock_irqrestore(&conf->device_lock, flags);
 }
 
 static void remove_hash(struct stripe_head *sh)
@@ -284,13 +294,18 @@
 
 		sh = __find_stripe(conf, sector);
 		if (!sh) {
-			sh = get_free_stripe(conf);
+			if (!conf->inactive_blocked)
+				sh = get_free_stripe(conf);
 			if (noblock && sh == NULL)
 				break;
 			if (!sh) {
+				conf->inactive_blocked = 1;
 				wait_event_lock_irq(conf->wait_for_stripe,
-						    !list_empty(&conf->inactive_list),
+						    !list_empty(&conf->inactive_list) &&
+						    (atomic_read(&conf->active_stripes) < (NR_STRIPES *3/4)
+						     || !conf->inactive_blocked),
 						    conf->device_lock);
+				conf->inactive_blocked = 0;
 			} else
 				init_stripe(sh, sector);
 		} else {
@@ -359,23 +374,12 @@
 }
 
 
-static inline void raid5_end_buffer_read(struct buffer_head *blist, struct buffer_head *bh)
-{
-	while (blist) {
-		struct buffer_head *new = blist;
-		blist = new->b_reqnext;
-		memcpy(new->b_data, bh->b_data, bh->b_size);
-		new->b_end_io(new, 1);
-	}
-}
-
 static void raid5_end_read_request (struct buffer_head * bh, int uptodate)
 {
  	struct stripe_head *sh = bh->b_private;
 	raid5_conf_t *conf = sh->raid_conf;
 	int disks = conf->raid_disks, i;
 	unsigned long flags;
-	struct buffer_head *buffers = NULL;
 
 	for (i=0 ; i<disks; i++)
 		if (bh == sh->bh_cache[i])
@@ -387,38 +391,45 @@
 		return;
 	}
 
-	md_spin_lock_irqsave(&conf->device_lock, flags);
 	if (uptodate) {
-#ifdef CONFIG_HIGHMEM
-		/* cannot map highmem bufferheads from irq,
-		 * so leave it for stripe_handle if there might
-		 * be a problem
+		struct buffer_head *buffer;
+		spin_lock_irqsave(&conf->device_lock, flags);
+		/* we can return a buffer if we bypassed the cache or
+		 * if the top buffer is not in highmem.  If there are
+		 * multiple buffers, leave the extra work to
+		 * handle_stripe
 		 */
-		if (sh->bh_read[i] &&
-		    sh->bh_read[i]->b_reqnext == NULL &&
-		    !PageHighMem(sh->bh_read[i]->b_page)) {
-			/* it's safe */
-			buffers = sh->bh_read[i];
-			sh->bh_read[i] = NULL;
-		}
-#else
-		buffers = sh->bh_read[i];
-		sh->bh_read[i] = NULL;
-#endif
-		set_bit(BH_Uptodate, &bh->b_state);
-		if (buffers) {
-			spin_unlock_irqrestore(&conf->device_lock, flags);
-			raid5_end_buffer_read(buffers, bh);
-			spin_lock_irqsave(&conf->device_lock, flags);
+		buffer = sh->bh_read[i];
+		if (buffer &&
+		    (!PageHighMem(buffer->b_page)
+		     || buffer->b_page == bh->b_page )
+			) {
+			sh->bh_read[i] = buffer->b_reqnext;
+			buffer->b_reqnext = NULL;
+		} else
+			buffer = NULL;
+		spin_unlock_irqrestore(&conf->device_lock, flags);
+		if (sh->bh_page[i]==NULL)
+			set_bit(BH_Uptodate, &bh->b_state);
+		if (buffer) {
+			if (buffer->b_page != bh->b_page)
+				memcpy(buffer->b_data, bh->b_data, bh->b_size);
+			buffer->b_end_io(buffer, 1);
 		}
 	} else {
 		md_error(conf->mddev, bh->b_dev);
 		clear_bit(BH_Uptodate, &bh->b_state);
 	}
+	/* must restore b_page before unlocking buffer... */
+	if (sh->bh_page[i]) {
+		bh->b_page = sh->bh_page[i];
+		bh->b_data = page_address(bh->b_page);
+		sh->bh_page[i] = NULL;
+		clear_bit(BH_Uptodate, &bh->b_state);
+	}
 	clear_bit(BH_Lock, &bh->b_state);
 	set_bit(STRIPE_HANDLE, &sh->state);
-	__release_stripe(conf, sh);
-	md_spin_unlock_irqrestore(&conf->device_lock, flags);
+	release_stripe(sh);
 }
 
 static void raid5_end_write_request (struct buffer_head *bh, int uptodate)
@@ -819,6 +830,7 @@
 
 	spin_lock(&sh->lock);
 	clear_bit(STRIPE_HANDLE, &sh->state);
+	clear_bit(STRIPE_DELAYED, &sh->state);
 
 	syncing = test_bit(STRIPE_SYNCING, &sh->state);
 	/* Now to look around and see what can be done */
@@ -939,6 +951,15 @@
 				} else if (conf->disks[i].operational) {
 					set_bit(BH_Lock, &bh->b_state);
 					action[i] = READ+1;
+					/* if I am just reading this block and we don't have
+					   a failed drive, or any pending writes then sidestep the cache */
+					if (sh->bh_page[i]) BUG();
+					if (sh->bh_read[i] && !sh->bh_read[i]->b_reqnext &&
+					    ! syncing && !failed && !to_write) {
+						sh->bh_page[i] = sh->bh_cache[i]->b_page;
+						sh->bh_cache[i]->b_page =  sh->bh_read[i]->b_page;
+						sh->bh_cache[i]->b_data =  sh->bh_read[i]->b_data;
+					}
 					locked++;
 					PRINTK("Reading block %d (sync=%d)\n", i, syncing);
 					if (syncing)
@@ -956,7 +977,8 @@
 			/* would I have to read this buffer for read_modify_write */
 			bh = sh->bh_cache[i];
 			if ((sh->bh_write[i] || i == sh->pd_idx) &&
-			    !buffer_locked(bh) && !buffer_uptodate(bh)) {
+			    (!buffer_locked(bh) || sh->bh_page[i]) &&
+			    !buffer_uptodate(bh)) {
 				if (conf->disks[i].operational 
 /*				    && !(conf->resync_parity && i == sh->pd_idx) */
 					)
@@ -965,7 +987,8 @@
 			}
 			/* Would I have to read this buffer for reconstruct_write */
 			if (!sh->bh_write[i] && i != sh->pd_idx &&
-			    !buffer_locked(bh) && !buffer_uptodate(bh)) {
+			    (!buffer_locked(bh) || sh->bh_page[i]) &&
+			    !buffer_uptodate(bh)) {
 				if (conf->disks[i].operational) rcw++;
 				else rcw += 2*disks;
 			}
@@ -979,10 +1002,16 @@
 				if ((sh->bh_write[i] || i == sh->pd_idx) &&
 				    !buffer_locked(bh) && !buffer_uptodate(bh) &&
 				    conf->disks[i].operational) {
-					PRINTK("Read_old block %d for r-m-w\n", i);
-					set_bit(BH_Lock, &bh->b_state);
-					action[i] = READ+1;
-					locked++;
+					if (test_bit(STRIPE_PREREAD_ACTIVE, &sh->state))
+					{
+						PRINTK("Read_old block %d for r-m-w\n", i);
+						set_bit(BH_Lock, &bh->b_state);
+						action[i] = READ+1;
+						locked++;
+					} else {
+						set_bit(STRIPE_DELAYED, &sh->state);
+						set_bit(STRIPE_HANDLE, &sh->state);
+					}
 				}
 			}
 		if (rcw <= rmw && rcw > 0)
@@ -992,10 +1021,16 @@
 				if (!sh->bh_write[i]  && i != sh->pd_idx &&
 				    !buffer_locked(bh) && !buffer_uptodate(bh) &&
 				    conf->disks[i].operational) {
-					PRINTK("Read_old block %d for Reconstruct\n", i);
-					set_bit(BH_Lock, &bh->b_state);
-					action[i] = READ+1;
-					locked++;
+					if (test_bit(STRIPE_PREREAD_ACTIVE, &sh->state))
+					{
+						PRINTK("Read_old block %d for Reconstruct\n", i);
+						set_bit(BH_Lock, &bh->b_state);
+						action[i] = READ+1;
+						locked++;
+					} else {
+						set_bit(STRIPE_DELAYED, &sh->state);
+						set_bit(STRIPE_HANDLE, &sh->state);
+					}
 				}
 			}
 		/* now if nothing is locked, and if we have enough data, we can start a write request */
@@ -1012,6 +1047,11 @@
 					    || (i==sh->pd_idx && failed == 0))
 						set_bit(STRIPE_INSYNC, &sh->state);
 				}
+			if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) {
+				atomic_dec(&conf->preread_active_stripes);
+				if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD)
+					md_wakeup_thread(conf->thread);
+			}
 		}
 	}
 
@@ -1103,6 +1143,47 @@
 		}
 }
 
+static inline void raid5_activate_delayed(raid5_conf_t *conf)
+{
+	if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD) {
+		while (!list_empty(&conf->delayed_list)) {
+			struct list_head *l = conf->delayed_list.next;
+			struct stripe_head *sh;
+			sh = list_entry(l, struct stripe_head, lru);
+			list_del_init(l);
+			clear_bit(STRIPE_DELAYED, &sh->state);
+			if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state))
+				atomic_inc(&conf->preread_active_stripes);
+			list_add_tail(&sh->lru, &conf->handle_list);
+		}
+	}
+}
+static void raid5_unplug_device(void *data)
+{
+	raid5_conf_t *conf = (raid5_conf_t *)data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&conf->device_lock, flags);
+
+	raid5_activate_delayed(conf);
+	
+	if (conf->plugged) {
+		conf->plugged = 0;
+		md_wakeup_thread(conf->thread);
+	}	
+	spin_unlock_irqrestore(&conf->device_lock, flags);
+}
+
+static inline void raid5_plug_device(raid5_conf_t *conf)
+{
+	spin_lock_irq(&conf->device_lock);
+	if (list_empty(&conf->delayed_list))
+		if (!conf->plugged) {
+			conf->plugged = 1;
+			queue_task(&conf->plug_tq, &tq_disk);
+		}
+	spin_unlock_irq(&conf->device_lock);
+}
 
 static int raid5_make_request (mddev_t *mddev, int rw, struct buffer_head * bh)
 {
@@ -1129,6 +1210,8 @@
 		sh->pd_idx = pd_idx;
 
 		add_stripe_bh(sh, bh, dd_idx, rw);
+
+		raid5_plug_device(conf);
 		handle_stripe(sh);
 		release_stripe(sh);
 	} else
@@ -1208,8 +1291,19 @@
 		md_update_sb(mddev);
 	}
 	md_spin_lock_irq(&conf->device_lock);
-	while (!list_empty(&conf->handle_list)) {
-		struct list_head *first = conf->handle_list.next;
+	while (1) {
+		struct list_head *first;
+
+		if (list_empty(&conf->handle_list) &&
+		    atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD &&
+		    !conf->plugged &&
+		    !list_empty(&conf->delayed_list))
+			raid5_activate_delayed(conf);
+
+		if (list_empty(&conf->handle_list))
+			break;
+
+		first = conf->handle_list.next;
 		sh = list_entry(first, struct stripe_head, lru);
 
 		list_del_init(first);
@@ -1288,9 +1382,16 @@
 	conf->device_lock = MD_SPIN_LOCK_UNLOCKED;
 	md_init_waitqueue_head(&conf->wait_for_stripe);
 	INIT_LIST_HEAD(&conf->handle_list);
+	INIT_LIST_HEAD(&conf->delayed_list);
 	INIT_LIST_HEAD(&conf->inactive_list);
 	atomic_set(&conf->active_stripes, 0);
+	atomic_set(&conf->preread_active_stripes, 0);
 	conf->buffer_size = PAGE_SIZE; /* good default for rebuild */
+
+	conf->plugged = 0;
+	conf->plug_tq.sync = 0;
+	conf->plug_tq.routine = &raid5_unplug_device;
+	conf->plug_tq.data = conf;
 
 	PRINTK("raid5_run(md%d) called.\n", mdidx(mddev));
 
diff -u --recursive --new-file v2.4.5/linux/drivers/media/radio/Config.in linux/drivers/media/radio/Config.in
--- v2.4.5/linux/drivers/media/radio/Config.in	Fri Apr 13 20:26:07 2001
+++ linux/drivers/media/radio/Config.in	Tue Jun 12 10:56:11 2001
@@ -24,6 +24,7 @@
 dep_tristate '  Guillemot MAXI Radio FM 2000 radio' CONFIG_RADIO_MAXIRADIO $CONFIG_VIDEO_DEV
 dep_tristate '  Maestro on board radio' CONFIG_RADIO_MAESTRO $CONFIG_VIDEO_DEV
 dep_tristate '  miroSOUND PCM20 radio' CONFIG_RADIO_MIROPCM20 $CONFIG_VIDEO_DEV $CONFIG_SOUND_ACI_MIXER
+dep_tristate '    miroSOUND PCM20 radio RDS user interface (EXPERIMENTAL)' CONFIG_RADIO_MIROPCM20_RDS $CONFIG_RADIO_MIROPCM20 $CONFIG_EXPERIMENTAL
 dep_tristate '  SF16FMI Radio' CONFIG_RADIO_SF16FMI $CONFIG_VIDEO_DEV
 if [ "$CONFIG_RADIO_SF16FMI" = "y" ]; then
    hex '    SF16FMI I/O port (0x284 or 0x384)' CONFIG_RADIO_SF16FMI_PORT 284
diff -u --recursive --new-file v2.4.5/linux/drivers/media/radio/Makefile linux/drivers/media/radio/Makefile
--- v2.4.5/linux/drivers/media/radio/Makefile	Fri Apr 13 20:26:07 2001
+++ linux/drivers/media/radio/Makefile	Tue Jun 12 10:56:11 2001
@@ -21,11 +21,11 @@
 # All of the (potential) objects that export symbols.
 # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
 
-export-objs     :=	
+export-objs     := miropcm20-rds-core.o
 
 list-multi	:= miropcm20.o
 
-miropcm20-objs	:= radio-miropcm20.o rds-miropcm20.o
+miropcm20-objs	:= miropcm20-rds-core.o miropcm20-radio.o
 
 obj-$(CONFIG_RADIO_AZTECH) += radio-aztech.o
 obj-$(CONFIG_RADIO_RTRACK2) += radio-rtrack2.o
@@ -37,6 +37,7 @@
 obj-$(CONFIG_RADIO_RTRACK) += radio-aimslab.o
 obj-$(CONFIG_RADIO_ZOLTRIX) += radio-zoltrix.o
 obj-$(CONFIG_RADIO_MIROPCM20) += miropcm20.o
+obj-$(CONFIG_RADIO_MIROPCM20_RDS) += miropcm20-rds.o
 obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o
 obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
 obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o
diff -u --recursive --new-file v2.4.5/linux/drivers/media/radio/miropcm20-radio.c linux/drivers/media/radio/miropcm20-radio.c
--- v2.4.5/linux/drivers/media/radio/miropcm20-radio.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/media/radio/miropcm20-radio.c	Tue Jun 12 10:56:11 2001
@@ -0,0 +1,286 @@
+/* Miro PCM20 radio driver for Linux radio support
+ * (c) 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
+ * Thanks to Norberto Pellici for the ACI device interface specification
+ * The API part is based on the radiotrack driver by M. Kirkwood
+ * This driver relies on the aci mixer (drivers/sound/aci.c)
+ * Look there for further info...
+ */
+
+/* Revision history:
+ *
+ *   1998        Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
+ *   2000-09-05  Robert Siemer <Robert.Siemer@gmx.de>
+ *        removed unfinished volume control (maybe adding it later again)
+ *        use OSS-mixer; added stereo control
+ */
+
+/* What ever you think about the ACI, version 0x07 is not very well!
+ * I cant get frequency, 'tuner status', 'tuner flags' or mute/mono
+ * conditions...                Robert 
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/videodev.h>
+#include "../../sound/aci.h"
+#include "miropcm20-rds-core.h"
+
+static int users = 0;
+static int radio_nr = -1;
+MODULE_PARM(radio_nr, "i");
+
+struct pcm20_device {
+	unsigned long freq;
+	int muted;
+	int stereo;
+};
+
+
+static int pcm20_mute(struct pcm20_device *dev, unsigned char mute)
+{
+	dev->muted = mute;
+	return aci_write_cmd(ACI_SET_TUNERMUTE, mute);
+}
+
+static int pcm20_stereo(struct pcm20_device *dev, unsigned char stereo)
+{
+	dev->stereo = stereo;
+	return aci_write_cmd(ACI_SET_TUNERMONO, !stereo);
+}
+
+static int pcm20_setfreq(struct pcm20_device *dev, unsigned long freq)
+{
+	unsigned char freql;
+	unsigned char freqh;
+
+	dev->freq=freq;
+
+	freq /= 160;
+	if (!(aci_version==0x07 || aci_version>=0xb0))
+		freq /= 10;  /* I don't know exactly which version
+			      * needs this hack */
+	freql = freq & 0xff;
+	freqh = freq >> 8;
+
+	aci_rds_cmd(RDS_RESET, 0, 0);
+	pcm20_stereo(dev, 1);
+
+	return aci_rw_cmd(ACI_WRITE_TUNE, freql, freqh);
+}
+
+static int pcm20_getflags(struct pcm20_device *dev, __u32 *flags, __u16 *signal)
+{
+	/* okay, check for signal, stereo and rds here... */
+	int i;
+	unsigned char buf;
+
+	if ((i=aci_rw_cmd(ACI_READ_TUNERSTATION, -1, -1))<0)
+		return i;
+#if DEBUG
+	printk("check_sig: 0x%x\n", i);
+#endif
+	if (i & 0x80) {
+		/* no signal from tuner */
+		*flags=0;
+		*signal=0;
+		return 0;
+	} else
+		*signal=0xffff;
+
+	if ((i=aci_rw_cmd(ACI_READ_TUNERSTEREO, -1, -1))<0)
+		return i;
+	if (i & 0x40) {
+		*flags=0;
+	} else {
+		/* stereo */
+		*flags=VIDEO_TUNER_STEREO_ON;
+		/* I cant see stereo, when forced to mono */
+		dev->stereo=1;
+	}
+
+	if ((i=aci_rds_cmd(RDS_STATUS, &buf, 1))<0)
+		return i;
+	if (buf & 1)
+		/* RDS available */
+		*flags|=VIDEO_TUNER_RDS_ON;
+	else
+		return 0;
+
+	if ((i=aci_rds_cmd(RDS_RXVALUE, &buf, 1))<0)
+		return i;
+#if DEBUG
+	printk("rds-signal: %d\n", buf);
+#endif
+	if (buf > 15) {
+		printk("miropcm20-radio: RX strengths unexpected high...\n");
+		buf=15;
+	}
+	/* refine signal */
+	if ((*signal=SCALE(15, 0xffff, buf))==0)
+		*signal = 1;
+
+	return 0;
+}
+
+static int pcm20_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+{
+	struct pcm20_device *pcm20=dev->priv;
+	int i;
+	
+	switch(cmd)
+	{
+		case VIDIOCGCAP:
+		{
+			struct video_capability v;
+			v.type=VID_TYPE_TUNER;
+			strcpy(v.name, "Miro PCM20");
+			v.channels=1;
+			v.audios=1;
+			/* No we don't do pictures */
+			v.maxwidth=0;
+			v.maxheight=0;
+			v.minwidth=0;
+			v.minheight=0;
+			if(copy_to_user(arg,&v,sizeof(v)))
+				return -EFAULT;
+			return 0;
+		}
+		case VIDIOCGTUNER:
+		{
+			struct video_tuner v;
+			if(copy_from_user(&v, arg,sizeof(v))!=0) 
+				return -EFAULT;
+			if(v.tuner)	/* Only 1 tuner */ 
+				return -EINVAL;
+			v.rangelow=87*16000;
+			v.rangehigh=108*16000;
+			pcm20_getflags(pcm20, &v.flags, &v.signal);
+			v.flags|=VIDEO_TUNER_LOW;
+			v.mode=VIDEO_MODE_AUTO;
+			strcpy(v.name, "FM");
+			if(copy_to_user(arg,&v, sizeof(v)))
+				return -EFAULT;
+			return 0;
+		}
+		case VIDIOCSTUNER:
+		{
+			struct video_tuner v;
+			if(copy_from_user(&v, arg, sizeof(v)))
+				return -EFAULT;
+			if(v.tuner!=0)
+				return -EINVAL;
+			/* Only 1 tuner so no setting needed ! */
+			return 0;
+		}
+		case VIDIOCGFREQ:
+			if(copy_to_user(arg, &pcm20->freq, sizeof(pcm20->freq)))
+				return -EFAULT;
+			return 0;
+		case VIDIOCSFREQ:
+			if(copy_from_user(&pcm20->freq, arg, sizeof(pcm20->freq)))
+				return -EFAULT;
+			i=pcm20_setfreq(pcm20, pcm20->freq);
+#if DEBUG
+			printk("First view (setfreq): 0x%x\n", i);
+#endif
+			return i;
+		case VIDIOCGAUDIO:
+		{	
+			struct video_audio v;
+			memset(&v,0, sizeof(v));
+			v.flags=VIDEO_AUDIO_MUTABLE;
+			if (pcm20->muted)
+				v.flags|=VIDEO_AUDIO_MUTE;
+			v.mode=VIDEO_SOUND_STEREO;
+			if (pcm20->stereo)
+				v.mode|=VIDEO_SOUND_MONO;
+			/* v.step=2048; */
+			strcpy(v.name, "Radio");
+			if(copy_to_user(arg,&v, sizeof(v)))
+				return -EFAULT;
+			return 0;			
+		}
+		case VIDIOCSAUDIO:
+		{
+			struct video_audio v;
+			if(copy_from_user(&v, arg, sizeof(v))) 
+				return -EFAULT;
+			if(v.audio) 
+				return -EINVAL;
+
+			pcm20_mute(pcm20, !!(v.flags&VIDEO_AUDIO_MUTE));
+			if(v.flags&VIDEO_SOUND_MONO)
+				pcm20_stereo(pcm20, 0);
+			if(v.flags&VIDEO_SOUND_STEREO)
+				pcm20_stereo(pcm20, 1);
+
+			return 0;
+		}
+		default:
+			return -ENOIOCTLCMD;
+	}
+}
+
+static int pcm20_open(struct video_device *dev, int flags)
+{
+	if(users)
+		return -EBUSY;
+	users++;
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static void pcm20_close(struct video_device *dev)
+{
+	users--;
+	MOD_DEC_USE_COUNT;
+}
+
+static struct pcm20_device pcm20_unit = {
+	freq:   87*16000,
+	muted:  1,
+	stereo: 0
+};
+
+static struct video_device pcm20_radio = {
+	owner:		THIS_MODULE,
+	name:		"Miro PCM 20 radio",
+	type:		VID_TYPE_TUNER,
+	hardware:	VID_HARDWARE_RTRACK,
+	open:		pcm20_open,
+	close:		pcm20_close,
+	ioctl:		pcm20_ioctl,
+	priv:		&pcm20_unit
+};
+
+static int __init pcm20_init(void)
+{
+	if(video_register_device(&pcm20_radio, VFL_TYPE_RADIO, radio_nr)==-1)
+		goto video_register_device;
+		
+	if(attach_aci_rds()<0)
+		goto attach_aci_rds;
+
+	printk(KERN_INFO "Miro PCM20 radio card driver.\n");
+
+	return 0;
+
+ attach_aci_rds:
+	video_unregister_device(&pcm20_radio);
+ video_register_device:
+	return -EINVAL;
+}
+
+MODULE_AUTHOR("Ruurd Reitsma");
+MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card.");
+
+EXPORT_NO_SYMBOLS;
+
+static void __exit pcm20_cleanup(void)
+{
+	unload_aci_rds();
+	video_unregister_device(&pcm20_radio);
+}
+
+module_init(pcm20_init);
+module_exit(pcm20_cleanup);
diff -u --recursive --new-file v2.4.5/linux/drivers/media/radio/miropcm20-rds-core.c linux/drivers/media/radio/miropcm20-rds-core.c
--- v2.4.5/linux/drivers/media/radio/miropcm20-rds-core.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/media/radio/miropcm20-rds-core.c	Tue Jun 12 10:56:11 2001
@@ -0,0 +1,210 @@
+/*
+ *  Many thanks to Fred Seidel <seidel@metabox.de>, the
+ *  designer of the RDS decoder hardware. With his help
+ *  I was able to code this driver.
+ *  Thanks also to Norberto Pellicci, Dominic Mounteney
+ *  <DMounteney@pinnaclesys.com> and www.teleauskunft.de
+ *  for good hints on finding Fred. It was somewhat hard
+ *  to locate him here in Germany... [:
+ *
+ * Revision history:
+ *
+ *   2000-08-09  Robert Siemer <Robert.Siemer@gmx.de>
+ *        RDS support for MiroSound PCM20 radio
+ */
+
+#define _NO_VERSION_
+
+/* #include <linux/kernel.h> */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <asm/semaphore.h>
+#include <asm/io.h>
+#include "../../sound/aci.h"
+#include "miropcm20-rds-core.h"
+
+#define DEBUG 0
+
+static struct semaphore aci_rds_sem;
+
+#define RDS_DATASHIFT          2   /* Bit 2 */
+#define RDS_DATAMASK        (1 << RDS_DATASHIFT)
+#define RDS_BUSYMASK        0x10   /* Bit 4 */
+#define RDS_CLOCKMASK       0x08   /* Bit 3 */
+
+#define RDS_DATA(x)         (((x) >> RDS_DATASHIFT) & 1) 
+
+
+#if DEBUG
+static void print_matrix(char array[], unsigned int length)
+{
+        int i, j;
+
+        for (i=0; i<length; i++) {
+                printk(KERN_DEBUG "aci-rds: ");
+                for (j=7; j>=0; j--) {
+                        printk("%d", (array[i] >> j) & 0x1);
+                }
+                if (i%8 == 0)
+                        printk(" byte-border\n");
+                else
+                        printk("\n");
+        }
+}
+#endif /* DEBUG */
+
+static int byte2trans(unsigned char byte, unsigned char sendbuffer[], int size)
+{
+	int i;
+
+	if (size != 8)
+		return -1;
+	for (i = 7; i >= 0; i--)
+		sendbuffer[7-i] = (byte & (1 << i)) ? RDS_DATAMASK : 0;
+	sendbuffer[0] |= RDS_CLOCKMASK;
+
+	return 0;
+}
+
+static int rds_waitread(void)
+{
+	unsigned char byte;
+	int i=2000;
+
+	do {
+		byte=inb(RDS_REGISTER);
+		i--;
+	}
+	while ((byte & RDS_BUSYMASK) && i);
+
+	if (i) {
+		#if DEBUG
+		printk(KERN_DEBUG "rds_waitread()");
+		print_matrix(&byte, 1);
+		#endif
+		return (byte);
+	} else {
+		printk(KERN_WARNING "aci-rds: rds_waitread() timeout...\n");
+		return -1;
+	}
+}
+
+/* dont use any ..._nowait() function if you are not sure what you do... */
+
+static inline void rds_rawwrite_nowait(unsigned char byte)
+{
+	#if DEBUG
+	printk(KERN_DEBUG "rds_rawwrite()");
+	print_matrix(&byte, 1);
+	#endif
+	outb(byte, RDS_REGISTER);
+}
+
+static int rds_rawwrite(unsigned char byte)
+{
+	if (rds_waitread() >= 0) {
+		rds_rawwrite_nowait(byte);
+		return 0;
+	} else
+		return -1;
+}
+
+static int rds_write(unsigned char cmd)
+{
+	unsigned char sendbuffer[8];
+	int i;
+	
+	if (byte2trans(cmd, sendbuffer, 8) != 0){
+		return -1;
+	} else {
+		for (i=0; i<8; i++) {
+			rds_rawwrite(sendbuffer[i]);
+		}
+	}
+	return 0;
+}
+
+static int rds_readcycle_nowait(void)
+{
+	rds_rawwrite_nowait(0);
+	return rds_waitread();
+}
+
+static int rds_readcycle(void)
+{
+	if (rds_rawwrite(0) < 0)
+		return -1;
+	return rds_waitread();
+}
+
+static int rds_read(unsigned char databuffer[], int datasize)
+{
+	#define READSIZE (8*datasize)
+
+	int i,j;
+
+	if (datasize < 1)  /* nothing to read */
+		return 0;
+
+	/* to be able to use rds_readcycle_nowait()
+	   I have to waitread() here */
+	if (rds_waitread() < 0)
+		return -1;
+	
+	memset(databuffer, 0, datasize);
+
+	for (i=0; i< READSIZE; i++)
+		if((j=rds_readcycle_nowait()) < 0) {
+			return -1;
+		} else {
+			databuffer[i/8]|=(RDS_DATA(j) << (7-(i%8)));
+		}
+
+	return 0;
+}
+
+static int rds_ack(void)
+{
+	int i=rds_readcycle();
+
+	if (i < 0)
+		return -1;
+	if (i & RDS_DATAMASK) {
+		return 0;  /* ACK  */
+	} else {
+		printk(KERN_DEBUG "aci-rds: NACK\n");
+		return 1;  /* NACK */
+	}
+}
+
+int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize)
+{
+	int ret;
+
+	if (down_interruptible(&aci_rds_sem))
+		return -EINTR;
+
+	rds_write(cmd);
+
+	/* RDS_RESET doesn't need further processing */
+	if (cmd!=RDS_RESET && (rds_ack() || rds_read(databuffer, datasize)))
+		ret = -1;
+	else
+		ret = 0;
+
+	up(&aci_rds_sem);
+	
+	return ret;
+}
+EXPORT_SYMBOL(aci_rds_cmd);
+
+int __init attach_aci_rds(void)
+{
+	init_MUTEX(&aci_rds_sem);
+	return 0;
+}
+
+void __exit unload_aci_rds(void)
+{
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/media/radio/miropcm20-rds-core.h linux/drivers/media/radio/miropcm20-rds-core.h
--- v2.4.5/linux/drivers/media/radio/miropcm20-rds-core.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/media/radio/miropcm20-rds-core.h	Tue Jun 12 10:56:11 2001
@@ -0,0 +1,19 @@
+#ifndef _MIROPCM20_RDS_CORE_H_
+#define _MIROPCM20_RDS_CORE_H_
+
+extern int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize);
+
+#define RDS_STATUS      0x01
+#define RDS_STATIONNAME 0x02
+#define RDS_TEXT        0x03
+#define RDS_ALTFREQ     0x04
+#define RDS_TIMEDATE    0x05
+#define RDS_PI_CODE     0x06
+#define RDS_PTYTATP     0x07
+#define RDS_RESET       0x08
+#define RDS_RXVALUE     0x09
+
+extern void __exit unload_aci_rds(void);
+extern int __init attach_aci_rds(void);
+
+#endif /* _MIROPCM20_RDS_CORE_H_ */
diff -u --recursive --new-file v2.4.5/linux/drivers/media/radio/miropcm20-rds.c linux/drivers/media/radio/miropcm20-rds.c
--- v2.4.5/linux/drivers/media/radio/miropcm20-rds.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/media/radio/miropcm20-rds.c	Tue Jun 12 10:56:11 2001
@@ -0,0 +1,140 @@
+/* MiroSOUND PCM20 radio rds interface driver
+ * (c) 2001 Robert Siemer <Robert.Siemer@gmx.de>
+ * Thanks to Fred Seidel. See miropcm20-rds-core.c for further information.
+ */
+
+/* Revision history:
+ *
+ *   2001-04-18  Robert Siemer <Robert.Siemer@gmx.de>
+ *        separate file for user interface driver
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <asm/uaccess.h>
+#include <linux/devfs_fs_kernel.h>
+#include "miropcm20-rds-core.h"
+
+devfs_handle_t dfsh;
+char * text_buffer;
+static int rds_users = 0;
+
+
+static int rds_f_open(struct inode *in, struct file *fi)
+{
+	if(rds_users)
+		return -EBUSY;
+
+	if ((text_buffer=kmalloc(66, GFP_KERNEL)) == 0) {
+		printk(KERN_NOTICE "aci-rds: Out of memory by open()...\n");
+		return -ENOMEM;
+	}
+
+	rds_users++;
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static int rds_f_release(struct inode *in, struct file *fi)
+{
+	kfree(text_buffer);
+
+	rds_users--;
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static void print_matrix(char *ch, char out[])
+{
+        int j;
+
+	for (j=7; j>=0; j--) {
+		 out[7-j] = ((*ch >> j) & 0x1) + '0';
+	}
+}
+
+static ssize_t rds_f_read(struct file *file, char *buffer, size_t length, loff_t *offset)
+{
+//	i = sprintf(text_buffer, "length: %d, offset: %d\n", length, *offset);
+
+	char c;
+	char bits[8];
+
+	current->state=TASK_UNINTERRUPTIBLE;
+	schedule_timeout(2*HZ);
+	aci_rds_cmd(RDS_STATUS, &c, 1);
+	print_matrix(&c, bits);
+	if (copy_to_user(buffer, bits, 8))
+		return -EFAULT;
+
+/*	if ((c >> 3) & 1) {
+		aci_rds_cmd(RDS_STATIONNAME, text_buffer+1, 8);
+		text_buffer[0]  = ' ' ;
+		text_buffer[9]  = '\n';
+		return copy_to_user(buffer+8, text_buffer, 10) ? -EFAULT: 18;
+	}
+*/
+/*	if ((c >> 6) & 1) {
+		aci_rds_cmd(RDS_PTYTATP, &c, 1);
+		if ( c & 1)
+			sprintf(text_buffer, " M");
+		else
+			sprintf(text_buffer, " S");
+		if ((c >> 1) & 1)
+			sprintf(text_buffer+2, " TA");
+		else
+			sprintf(text_buffer+2, " --");
+		if ((c >> 7) & 1)
+			sprintf(text_buffer+5, " TP");
+		else
+			sprintf(text_buffer+5, " --");
+		sprintf(text_buffer+8, " %2d\n", (c >> 2) & 0x1f);
+		return copy_to_user(buffer+8, text_buffer, 12) ? -EFAULT: 20;
+	}
+*/
+
+	if ((c >> 4) & 1) {
+		aci_rds_cmd(RDS_TEXT, text_buffer, 65);
+		text_buffer[0]  = ' ' ;
+		text_buffer[65] = '\n';
+		return copy_to_user(buffer+8, text_buffer,66) ? -EFAULT : 66+8;
+	} else {
+		put_user('\n', buffer+8);
+		return 9;
+	}
+}
+
+static struct file_operations rds_f_ops = {
+	read:    rds_f_read,
+	open:    rds_f_open,
+	release: rds_f_release
+};
+
+
+static int __init miropcm20_rds_init(void)
+{
+	if ((dfsh = devfs_register(NULL, "v4l/rds/radiotext", 
+				   DEVFS_FL_DEFAULT | DEVFS_FL_AUTO_DEVNUM,
+				   0, 0, S_IRUGO | S_IFCHR, &rds_f_ops, NULL))
+	    == NULL)
+		goto devfs_register;
+
+	printk("miropcm20-rds: userinterface driver loaded.\n");
+#if DEBUG
+	printk("v4l-name: %s\n", devfs_get_name(pcm20_radio.devfs_handle, 0));
+#endif
+
+	return 0;
+
+ devfs_register:
+	return -EINVAL;
+}
+
+static void __exit miropcm20_rds_cleanup(void)
+{
+	devfs_unregister(dfsh);
+}
+
+module_init(miropcm20_rds_init);
+module_exit(miropcm20_rds_cleanup);
diff -u --recursive --new-file v2.4.5/linux/drivers/media/radio/radio-miropcm20.c linux/drivers/media/radio/radio-miropcm20.c
--- v2.4.5/linux/drivers/media/radio/radio-miropcm20.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-miropcm20.c	Wed Dec 31 16:00:00 1969
@@ -1,290 +0,0 @@
-/* Miro PCM20 radio driver for Linux radio support
- * (c) 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
- * Thanks to Norberto Pellici for the ACI device interface specification
- * The API part is based on the radiotrack driver by M. Kirkwood
- * This driver relies on the aci mixer (drivers/sound/aci.c)
- * Look there for further info...
- */
-
-/* Revision history:
- *
- *   1998        Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
- *   2000-09-05  Robert Siemer <Robert.Siemer@gmx.de>
- *        removed unfinished volume control (maybe adding it later again)
- *        use OSS-mixer; added stereo control
- */
-
-/* What ever you think about the ACI, version 0x07 is not very well!
- * I cant get frequency, 'tuner status', 'tuner flags' or mute/mono
- * conditions...                Robert 
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/videodev.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/uaccess.h>
-
-char * aci_radio_name;
-
-#include "../../sound/aci.h"
-
-static int users = 0;
-static int radio_nr = -1;
-MODULE_PARM(radio_nr, "i");
-
-struct pcm20_device
-{
-	unsigned long freq;
-	int muted;
-	int stereo;
-};
-
-
-static int pcm20_mute(struct pcm20_device *dev, unsigned char mute)
-{
-	dev->muted = mute;
-	return aci_write_cmd(0xa3, mute);
-}
-
-static int pcm20_stereo(struct pcm20_device *dev, unsigned char stereo)
-{
-	dev->stereo = stereo;
-	return aci_write_cmd(0xa4, !stereo);
-}
-
-static int pcm20_setfreq(struct pcm20_device *dev, unsigned long freq)
-{
-	unsigned char freql;
-	unsigned char freqh;
-
-	dev->freq=freq;
-
-	freq /= 160;
-	if (!(aci_version==0x07 || aci_version>=0xb0))
-		freq /= 10;  /* I don't know exactly which version
-			      * needs this hack */
-	freql = freq & 0xff;
-	freqh = freq >> 8;
-
-	aci_rds_cmd(RDS_RESET, 0, 0);
-	pcm20_stereo(dev, 1);
-
-	return aci_rw_cmd(0xa7, freql, freqh);	/*  Tune to frequency	*/
-}
-
-static int pcm20_getflags(struct pcm20_device *dev, __u32 *flags, __u16 *signal)
-{
-	/* okay, check for signal, stereo and rds here... */
-	int i;
-	unsigned char buf;
-
-	if ((i=aci_rw_cmd(0xa9, -1, -1))<0)
-		return i;
-#if DEBUG
-	printk("check_sig: 0x%x\n", i);
-#endif
-	if (i & 0x80) {
-		/* no signal from tuner */
-		*flags=0;
-		*signal=0;
-		return 0;
-	} else
-		*signal=0xffff;
-
-	if ((i=aci_rw_cmd(0xa8, -1, -1))<0)
-		return i;
-	if (i & 0x40) {
-		*flags=0;
-	} else {
-		/* stereo */
-		*flags=VIDEO_TUNER_STEREO_ON;
-		/* I cant see stereo, when forced to mono */
-		dev->stereo=1;
-	}
-
-	if ((i=aci_rds_cmd(RDS_STATUS, &buf, 1))<0)
-		return i;
-	if (buf & 1)
-		/* RDS available */
-		*flags|=VIDEO_TUNER_RDS_ON;
-	else
-		return 0;
-
-	if ((i=aci_rds_cmd(RDS_RXVALUE, &buf, 1))<0)
-		return i;
-#if DEBUG
-	printk("rds-signal: %d\n", buf);
-#endif
-	if (buf > 15) {
-		printk("rds-miropcm20: RX strengths unexpected high...\n");
-		buf=15;
-	}
-	/* refine signal */
-	if ((*signal=SCALE(15, 0xffff, buf))==0)
-		*signal = 1;
-
-	return 0;
-}
-
-static int pcm20_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
-	struct pcm20_device *pcm20=dev->priv;
-	int i;
-	
-	switch(cmd)
-	{
-		case VIDIOCGCAP:
-		{
-			struct video_capability v;
-			v.type=VID_TYPE_TUNER;
-			strcpy(v.name, "Miro PCM20");
-			v.channels=1;
-			v.audios=1;
-			/* No we don't do pictures */
-			v.maxwidth=0;
-			v.maxheight=0;
-			v.minwidth=0;
-			v.minheight=0;
-			if(copy_to_user(arg,&v,sizeof(v)))
-				return -EFAULT;
-			return 0;
-		}
-		case VIDIOCGTUNER:
-		{
-			struct video_tuner v;
-			if(copy_from_user(&v, arg,sizeof(v))!=0) 
-				return -EFAULT;
-			if(v.tuner)	/* Only 1 tuner */ 
-				return -EINVAL;
-			v.rangelow=87*16000;
-			v.rangehigh=108*16000;
-			pcm20_getflags(pcm20, &v.flags, &v.signal);
-			v.flags|=VIDEO_TUNER_LOW;
-			v.mode=VIDEO_MODE_AUTO;
-			strcpy(v.name, "FM");
-			if(copy_to_user(arg,&v, sizeof(v)))
-				return -EFAULT;
-			return 0;
-		}
-		case VIDIOCSTUNER:
-		{
-			struct video_tuner v;
-			if(copy_from_user(&v, arg, sizeof(v)))
-				return -EFAULT;
-			if(v.tuner!=0)
-				return -EINVAL;
-			/* Only 1 tuner so no setting needed ! */
-			return 0;
-		}
-		case VIDIOCGFREQ:
-			if(copy_to_user(arg, &pcm20->freq, sizeof(pcm20->freq)))
-				return -EFAULT;
-			return 0;
-		case VIDIOCSFREQ:
-			if(copy_from_user(&pcm20->freq, arg, sizeof(pcm20->freq)))
-				return -EFAULT;
-			i=pcm20_setfreq(pcm20, pcm20->freq);
-#if DEBUG
-			printk("First view (setfreq): 0x%x\n", i);
-#endif
-			return i;
-		case VIDIOCGAUDIO:
-		{	
-			struct video_audio v;
-			memset(&v,0, sizeof(v));
-			v.flags=VIDEO_AUDIO_MUTABLE;
-			if (pcm20->muted)
-				v.flags|=VIDEO_AUDIO_MUTE;
-			v.mode=VIDEO_SOUND_STEREO;
-			if (pcm20->stereo)
-				v.mode|=VIDEO_SOUND_MONO;
-			/* v.step=2048; */
-			strcpy(v.name, "Radio");
-			if(copy_to_user(arg,&v, sizeof(v)))
-				return -EFAULT;
-			return 0;			
-		}
-		case VIDIOCSAUDIO:
-		{
-			struct video_audio v;
-			if(copy_from_user(&v, arg, sizeof(v))) 
-				return -EFAULT;
-			if(v.audio) 
-				return -EINVAL;
-
-			pcm20_mute(pcm20, !!(v.flags&VIDEO_AUDIO_MUTE));
-			if(v.flags&VIDEO_SOUND_MONO)
-				pcm20_stereo(pcm20, 0);
-			if(v.flags&VIDEO_SOUND_STEREO)
-				pcm20_stereo(pcm20, 1);
-
-			return 0;
-		}
-		default:
-			return -ENOIOCTLCMD;
-	}
-}
-
-static int pcm20_open(struct video_device *dev, int flags)
-{
-	if(users)
-		return -EBUSY;
-	users++;
-	return 0;
-}
-
-static void pcm20_close(struct video_device *dev)
-{
-	users--;
-}
-
-static struct pcm20_device pcm20_unit=
-{
-	freq:   87*16000,
-	muted:  1,
-	stereo: 0
-};
-
-static struct video_device pcm20_radio=
-{
-	owner:		THIS_MODULE,
-	name:		"Miro PCM 20 radio",
-	type:		VID_TYPE_TUNER,
-	hardware:	VID_HARDWARE_RTRACK,
-	open:		pcm20_open,
-	close:		pcm20_close,
-	ioctl:		pcm20_ioctl,
-	priv:		&pcm20_unit
-};
-
-static int __init pcm20_init(void)
-{
-	if(video_register_device(&pcm20_radio, VFL_TYPE_RADIO, radio_nr)==-1)
-		return -EINVAL;
-		
-	if(attach_aci_rds()<0) {
-		video_unregister_device(&pcm20_radio);
-		return -EINVAL;
-	}
-#if DEBUG
-	printk("v4l-name: %s\n", devfs_get_name(pcm20_radio.devfs_handle, 0));
-#endif
-	printk(KERN_INFO "Miro PCM20 radio card driver.\n");
-
-	return 0;
-}
-
-MODULE_AUTHOR("Ruurd Reitsma");
-MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card.");
-
-EXPORT_NO_SYMBOLS;
-
-static void __exit pcm20_cleanup(void)
-{
-	unload_aci_rds();
-	video_unregister_device(&pcm20_radio);
-}
-
-module_init(pcm20_init);
-module_exit(pcm20_cleanup);
diff -u --recursive --new-file v2.4.5/linux/drivers/media/radio/rds-miropcm20.c linux/drivers/media/radio/rds-miropcm20.c
--- v2.4.5/linux/drivers/media/radio/rds-miropcm20.c	Fri Apr 13 20:26:07 2001
+++ linux/drivers/media/radio/rds-miropcm20.c	Wed Dec 31 16:00:00 1969
@@ -1,249 +0,0 @@
-/*
- *  Many thanks to Fred Seidel <seidel@metabox.de>, the
- *  designer of the RDS decoder hardware. With his help
- *  I was able to code this driver.
- *  Thanks also to Norberto Pellicci, Dominic Mounteney
- *  <DMounteney@pinnaclesys.com> and www.teleauskunft.de
- *  for good hints on finding Fred. It was somewhat hard
- *  to locate him here in Germany... [:
- *
- * Revision history:
- *
- *   2000-08-09  Robert Siemer <Robert.Siemer@gmx.de>
- *        RDS support for MiroSound PCM20 radio
- */
-
-#define _NO_VERSION_
-
-/* #include <linux/kernel.h> */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <asm/semaphore.h>
-#include <asm/io.h>
-#include "../../sound/aci.h"
-
-#define WATCHMASK       0352 /* 11101010 */
-
-#define DEBUG 0
-
-static struct semaphore aci_rds_sem;
-
-
-#define RDS_BUSYMASK        0x10   /* Bit 4 */
-#define RDS_CLOCKMASK       0x08   /* Bit 3 */
-#define RDS_DATAMASK        0x04   /* Bit 2 */
-
-
-static void print_matrix(char array[], unsigned int length)
-{
-        int i, j;
-
-        for (i=0; i<length; i++) {
-                printk("aci-rds: ");
-                for (j=7; j>=0; j--) {
-                        printk("%d", (array[i] >> j) & 0x1);
-                }
-                if (i%8 == 0)
-                        printk(" byte-border\n");
-                else
-                        printk("\n");
-        }
-}
-
-static int byte2trans(unsigned char byte, unsigned char sendbuffer[], int size)
-{
-	int i;
-
-	if (size != 8)
-		return -1;
-	for (i = 7; i >= 0; i--)
-		sendbuffer[7-i] = (byte & (1 << i)) ? RDS_DATAMASK : 0;
-	sendbuffer[0] |= RDS_CLOCKMASK;
-
-	return 0;
-}
-
-static int trans2byte(unsigned char buffer[], int size)
-{
-	int i;
-	unsigned char byte=0;
-
-	if (size != 8)
-		return -1;
-	for (i = 7; i >= 0; i--)
-		byte |= ((buffer[7-i] & RDS_DATAMASK) ? 1 : 0) << i;
-
-	return byte;
-}
-
-static int trans2data(unsigned char readbuffer[], int readsize, unsigned char data[], int datasize)
-{
-	int i,j;
-
-	if (readsize != datasize*8)
-		return -1;
-	for (i = 0; i < datasize; i++)
-		if ((j=trans2byte(&readbuffer[i*8], 8)) < 0)
-			return -1;
-		else
-			data[i]=j;
-	return 0;
-}
-
-static int rds_waitread(void)
-{
-	unsigned char byte;
-	int i=2000;
-
-	do {
-		byte=inb(RDS_REGISTER);
-		if ((byte & WATCHMASK) != WATCHMASK)
-			printk("aci-rds: Hidden information discoverd!\n");
-		i--;
-	}
-	while ((byte & RDS_BUSYMASK) && i);
-
-	if (i) {
-#if DEBUG
-		printk("rds_waitread()");
-		print_matrix(&byte, 1);
-#endif
-		return (byte);
-	} else {
-		printk("aci-rds: rds_waitread() timeout...\n");
-		return -1;
-	}
-}
-
-/* dont use any ..._nowait() function if you are not sure what you do... */
-
-static inline void rds_rawwrite_nowait(unsigned char byte)
-{
-#if DEBUG
-	printk("rds_rawwrite()");
-	print_matrix(&byte, 1);
-#endif
-	outb(byte, RDS_REGISTER);
-}
-
-static int rds_rawwrite(unsigned char byte)
-{
-	if (rds_waitread() >= 0) {
-		rds_rawwrite_nowait(byte);
-		return 0;
-	} else
-		return -1;
-}
-
-static int rds_write(unsigned char cmd)
-{
-	unsigned char sendbuffer[8];
-	int i;
-	
-	if (byte2trans(cmd, sendbuffer, 8) != 0){
-		return -1;
-	} else {
-		for (i=0; i<8; i++) {
-			rds_rawwrite(sendbuffer[i]);
-		}
-	}
-	return 0;
-}
-
-static int rds_readcycle_nowait(void)
-{
-	rds_rawwrite_nowait(0);
-	return rds_waitread();
-}
-
-static int rds_readcycle(void)
-{
-	if (rds_rawwrite(0) < 0)
-		return -1;
-	return rds_waitread();
-}
-
-static int rds_read(unsigned char databuffer[], int datasize)
-{
-
-#define READSIZE (8*datasize)
-
-	int i,j;
-	unsigned char* readbuffer;
-
-	if (!datasize)  /* nothing to read */
-		return 0;
-
-	/* to be able to use rds_readcycle_nowait()
-	   I have to readwait() here */
-	if (rds_waitread() < 0)
-		return -1;
-	
-	if ((readbuffer=kmalloc(READSIZE, GFP_KERNEL)) == 0) {
-		printk("aci-rds: Out of memory...\n");
-		return -ENOMEM;
-	} else {
-		if (signal_pending(current)) {
-			kfree(readbuffer);
-			return -EINTR;
-		}
-	}
-	
-	for (i=0; i< READSIZE; i++)
-		if((j=rds_readcycle_nowait()) < 0) {
-			kfree(readbuffer);
-			return -1;
-		} else
-			readbuffer[i]=j;
-	if (trans2data(readbuffer, READSIZE, databuffer, datasize) < 0) {
-		kfree(readbuffer);
-		return -1;
-	}
-	kfree(readbuffer);
-	return 0;
-}
-
-static int rds_ack(void)
-{
-	int i=rds_readcycle();
-
-	if (i < 0)
-		return -1;
-	if (i & RDS_DATAMASK) {
-		return 0;  /* ACK  */
-	} else {
-		return 1;  /* NACK */
-	}
-}
-
-int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize)
-{
-	int ret;
-
-	if (down_interruptible(&aci_rds_sem))
-		return -EINTR;
-
-	if (rds_write(cmd))
-		ret = -2;
-
-	/* RDS_RESET doesn't need further processing */
-	if (cmd!=RDS_RESET && (rds_ack() || rds_read(databuffer, datasize)))
-		ret = -1;
-	else
-		ret = 0;
-
-	up(&aci_rds_sem);
-	
-	return ret;
-}
-
-int __init attach_aci_rds(void)
-{
-	init_MUTEX(&aci_rds_sem);
-	return 0;
-}
-
-void __exit unload_aci_rds(void)
-{
-}
diff -u --recursive --new-file v2.4.5/linux/drivers/media/video/bttv-driver.c linux/drivers/media/video/bttv-driver.c
--- v2.4.5/linux/drivers/media/video/bttv-driver.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/video/bttv-driver.c	Wed Jun 20 11:10:27 2001
@@ -2812,8 +2812,7 @@
 
         /* disable PCI bus-mastering */
         pci_read_config_byte(btv->dev, PCI_COMMAND, &command);
-        /* Should this be &=~ ?? */
-        command&=~PCI_COMMAND_MASTER;
+        command &= ~PCI_COMMAND_MASTER;
         pci_write_config_byte(btv->dev, PCI_COMMAND, command);
 
         /* unmap and free memory */
diff -u --recursive --new-file v2.4.5/linux/drivers/media/video/i2c-parport.c linux/drivers/media/video/i2c-parport.c
--- v2.4.5/linux/drivers/media/video/i2c-parport.c	Wed Jul 12 16:24:33 2000
+++ linux/drivers/media/video/i2c-parport.c	Wed Jun 27 17:10:55 2001
@@ -74,6 +74,10 @@
 {
   struct parport_i2c_bus *b = kmalloc(sizeof(struct parport_i2c_bus), 
 				      GFP_KERNEL);
+  if (!b) {
+	  printk(KERN_ERR "i2c_parport: Memory allocation failed. Not attaching.\n");
+	  return;
+  }
   b->i2c = parport_i2c_bus_template;
   b->i2c.data = parport_get_port (port);
   strncpy(b->i2c.name, port->name, 32);
diff -u --recursive --new-file v2.4.5/linux/drivers/media/video/planb.c linux/drivers/media/video/planb.c
--- v2.4.5/linux/drivers/media/video/planb.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/video/planb.c	Wed Jun 27 17:10:55 2001
@@ -50,6 +50,7 @@
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <asm/irq.h>
+#include <asm/semaphore.h>
 
 #include "planb.h"
 #include "saa7196.h"
@@ -326,41 +327,14 @@
 /* misc. supporting functions */
 /******************************/
 
-static void __planb_wait(struct planb *pb)
-{
-	DECLARE_WAITQUEUE(wait, current);
-
-	add_wait_queue(&pb->lockq, &wait);
-repeat:
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	if (pb->lock) {
-		schedule();
-		goto repeat;
-	}
-	remove_wait_queue(&pb->lockq, &wait);
-	current->state = TASK_RUNNING;
-}
-
-static inline void planb_wait(struct planb *pb)
-{
-	DEBUG("PlanB: planb_wait\n");
-	if(pb->lock)
-		__planb_wait(pb);
-}
-
 static inline void planb_lock(struct planb *pb)
 {
-	DEBUG("PlanB: planb_lock\n");
-	if(pb->lock)
-		__planb_wait(pb);
-	pb->lock = 1;
+	down(&pb->lock);
 }
 
 static inline void planb_unlock(struct planb *pb)
 {
-	DEBUG("PlanB: planb_unlock\n");
-	pb->lock = 0;
-	wake_up(&pb->lockq);
+	up(&pb->lock);
 }
 
 /***************/
@@ -2098,7 +2072,7 @@
 	pb->tab_size = PLANB_MAXLINES + 40;
 	pb->suspend = 0;
 	pb->lock = 0;
-	init_waitqueue_head(&pb->lockq);
+	init_MUTEX(&pb->lock);
 	pb->ch1_cmd = 0;
 	pb->ch2_cmd = 0;
 	pb->mask = 0;
diff -u --recursive --new-file v2.4.5/linux/drivers/media/video/planb.h linux/drivers/media/video/planb.h
--- v2.4.5/linux/drivers/media/video/planb.h	Wed Apr 12 09:38:53 2000
+++ linux/drivers/media/video/planb.h	Wed Jun 27 17:10:55 2001
@@ -174,8 +174,7 @@
 	int	user;
 	unsigned int tab_size;
 	int     maxlines;
-	int lock;
-	wait_queue_head_t lockq;
+	struct semaphore lock;
 	unsigned int	irq;			/* interrupt number */
 	volatile unsigned int intr_mask;
 
diff -u --recursive --new-file v2.4.5/linux/drivers/media/video/tuner.c linux/drivers/media/video/tuner.c
--- v2.4.5/linux/drivers/media/video/tuner.c	Mon Feb 19 14:43:36 2001
+++ linux/drivers/media/video/tuner.c	Tue Jun 12 11:06:54 2001
@@ -558,6 +558,7 @@
 #endif
 	default:
 		/* nothing */
+		break;
 	}
 	
 	return 0;
diff -u --recursive --new-file v2.4.5/linux/drivers/media/video/videodev.c linux/drivers/media/video/videodev.c
--- v2.4.5/linux/drivers/media/video/videodev.c	Sat May 19 18:13:15 2001
+++ linux/drivers/media/video/videodev.c	Wed Jun 27 17:10:55 2001
@@ -373,6 +373,8 @@
 		return;
 
 	p = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, video_dev_proc_entry);
+	if (!p)
+		return;
 	p->data = vfd;
 	p->read_proc = videodev_proc_read;
 
diff -u --recursive --new-file v2.4.5/linux/drivers/media/video/zr36120.c linux/drivers/media/video/zr36120.c
--- v2.4.5/linux/drivers/media/video/zr36120.c	Mon May 21 17:06:00 2001
+++ linux/drivers/media/video/zr36120.c	Wed Jun 27 17:10:55 2001
@@ -1025,7 +1025,7 @@
 		v.norm=VIDEO_MODE_PAL;
 #endif
 		/* too many inputs? no decoder -> no channels */
-		if (!ztv->have_decoder || v.channel >= ztv->card->video_inputs)
+		if (!ztv->have_decoder || v.channel < 0 ||  v.channel >= ztv->card->video_inputs)
 			return -EINVAL;
 
 		/* now determine the name of the channel */
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/Config.in linux/drivers/mtd/Config.in
--- v2.4.5/linux/drivers/mtd/Config.in	Mon Dec 11 14:57:58 2000
+++ linux/drivers/mtd/Config.in	Wed Jun 27 14:06:00 2001
@@ -1,5 +1,5 @@
 
-# $Id: No. :) $
+# $Id: Config.in,v 1.66 2001/05/07 21:00:43 dwmw2 Exp $
 
 mainmenu_option next_comment
 comment 'Memory Technology Devices (MTD)'
@@ -11,72 +11,30 @@
    if [ "$CONFIG_MTD_DEBUG" = "y" ]; then
       int '  Debugging verbosity (0 = quiet, 3 = noisy)' CONFIG_MTD_DEBUG_VERBOSE 0
    fi
-
-comment 'Disk-On-Chip Device Drivers'
-   dep_tristate '  M-Systems Disk-On-Chip 1000' CONFIG_MTD_DOC1000 $CONFIG_MTD
-   dep_tristate '  M-Systems Disk-On-Chip 2000 and Millennium' CONFIG_MTD_DOC2000 $CONFIG_MTD
-   dep_tristate '  M-Systems Disk-On-Chip Millennium-only alternative driver' CONFIG_MTD_DOC2001 $CONFIG_MTD
-   if [ "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" ]; then
-      define_tristate CONFIG_MTD_DOCPROBE y
-   else
-      if [ "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" ]; then
-	 define_tristate CONFIG_MTD_DOCPROBE m
-      else
-	 define_tristate CONFIG_MTD_DOCPROBE n
-      fi
-   fi
-   if [ "$CONFIG_MTD_DOCPROBE" = "y" -o "$CONFIG_MTD_DOCPROBE" = "m" ]; then
-      hex  '    Physical address of DiskOnChip' CONFIG_MTD_DOCPROBE_ADDRESS 0x0000
-      bool '    Probe high addresses' CONFIG_MTD_DOCPROBE_HIGH
-      bool '    Probe for 0x55 0xAA BIOS Extension Signature' CONFIG_MTD_DOCPROBE_55AA
-   fi
-
-comment 'RAM/ROM Device Drivers'
-   dep_tristate '  Use extra onboard system memory as MTD device' CONFIG_MTD_SLRAM $CONFIG_MTD
-   dep_tristate '  Ramix PMC551 PCI Mezzanine ram card support' CONFIG_MTD_PMC551 $CONFIG_MTD $CONFIG_PCI
-   if [ "$CONFIG_MTD_PMC551" != "n" ]; then
-      bool '    PMC551 256M DRAM Bugfix' CONFIG_MTD_PMC551_BUGFIX
-      bool '    PMC551 Debugging' CONFIG_MTD_PMC551_DEBUG
-   fi
-   dep_tristate '  Debugging RAM test driver' CONFIG_MTD_MTDRAM $CONFIG_MTD
-   if [ "$CONFIG_MTD_MTDRAM" != "n" ]; then
-      int 'Device size in kB' CONFIG_MTDRAM_TOTAL_SIZE 4096
-      int 'Size of the erase sectors in kB' CONFIG_MTDRAM_ERASE_SIZE 128
-   fi
-
-comment 'Linearly Mapped Flash Device Drivers'
-   dep_tristate '  Common Flash Interface (CFI) support' CONFIG_MTD_CFI $CONFIG_MTD
-   dep_tristate '    CFI support for Intel/Sharp Extended Command Set chips' CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_CFI
-   dep_tristate '    CFI support for AMD/Fujitsu Standard Command Set chips' CONFIG_MTD_CFI_AMDSTD $CONFIG_MTD_CFI
-   dep_tristate '  Support for RAM chips in bus mapping' CONFIG_MTD_RAM $CONFIG_MTD
-   dep_tristate '  Support for ROM chips in bus mapping' CONFIG_MTD_ROM $CONFIG_MTD
-
-# These will later become config-options
-define_bool CONFIG_MTD_JEDEC n
-
-   dep_tristate '  Flash chip mapping in physical memory' CONFIG_MTD_PHYSMAP $CONFIG_MTD_CFI
-   if [ "$CONFIG_MTD_PHYSMAP" = "y" -o "$CONFIG_MTD_PHYSMAP" = "m" ]; then
-      hex '    Physical start location of flash chip mapping' CONFIG_MTD_PHYSMAP_START 0x8000000
-      hex '    Physical length of flash chip mapping' CONFIG_MTD_PHYSMAP_LEN 0x4000000
-      int '    Bus width in octets' CONFIG_MTD_PHYSMAP_BUSWIDTH 2
+   dep_tristate '  MTD partitioning support' CONFIG_MTD_PARTITIONS $CONFIG_MTD
+   dep_tristate '  RedBoot partition table parsing' CONFIG_MTD_REDBOOT_PARTS $CONFIG_MTD_PARTITIONS
+   dep_tristate '  Compaq bootldr partition table parsing' CONFIG_MTD_BOOTLDR_PARTS $CONFIG_MTD_PARTITIONS
+
+comment 'User Modules And Translation Layers'
+   dep_tristate '  Direct char device access to MTD devices' CONFIG_MTD_CHAR $CONFIG_MTD
+   dep_tristate '  Caching block device access to MTD devices' CONFIG_MTD_BLOCK $CONFIG_MTD
+   if [ "$CONFIG_MTD_BLOCK" = "n" -o "$CONFIG_MTD_BLOCK" = "m" ]; then
+   	dep_tristate '  Readonly block device access to MTD devices' CONFIG_MTD_BLOCK_RO $CONFIG_MTD
    fi
-
-comment 'Drivers for chip mappings'
-   dep_tristate '  Flash chip mapping on Mixcom piggyback card' CONFIG_MTD_MIXMEM $CONFIG_MTD_JEDEC
-   dep_tristate '  Flash chip mapping on Nora' CONFIG_MTD_NORA $CONFIG_MTD_CFI
-   dep_tristate '  Flash chip mapping on Octagon 5066 SBC' CONFIG_MTD_OCTAGON $CONFIG_MTD_JEDEC
-   dep_tristate '  Flash chip mapping on Photron PNC-2000' CONFIG_MTD_PNC2000 $CONFIG_MTD_CFI
-   dep_tristate '  Flash chip mapping on RPXLite PPC board' CONFIG_MTD_RPXLITE $CONFIG_MTD_CFI
-   dep_tristate '  Flash chip mapping on Tempustech VMAX SBC301' CONFIG_MTD_VMAX $CONFIG_MTD_JEDEC
-
-comment 'User modules and translation layers for MTD devices'
-   dep_tristate '  Direct chardevice access to MTD devices' CONFIG_MTD_CHAR $CONFIG_MTD
-   dep_tristate '  Caching blockdevice access to MTD devices' CONFIG_MTD_BLOCK $CONFIG_MTD
    dep_tristate '  FTL (Flash Translation Layer) support' CONFIG_FTL $CONFIG_MTD
    dep_tristate '  NFTL (NAND Flash Translation Layer) support' CONFIG_NFTL $CONFIG_MTD
    if [ "$CONFIG_NFTL" = "y" -o "$CONFIG_NFTL" = "m" ]; then
       bool '    Write support for NFTL (BETA)' CONFIG_NFTL_RW
    fi
+
+   source drivers/mtd/chips/Config.in
+
+   source drivers/mtd/maps/Config.in
+
+   source drivers/mtd/devices/Config.in
+
+   source drivers/mtd/nand/Config.in
+
 fi
 
 endmenu
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/Makefile linux/drivers/mtd/Makefile
--- v2.4.5/linux/drivers/mtd/Makefile	Fri Dec 29 14:07:22 2000
+++ linux/drivers/mtd/Makefile	Tue Jun 12 10:30:27 2001
@@ -8,54 +8,57 @@
 # Note 2! The CFLAGS definitions are now inherited from the
 # parent makes..
 #
-# $Id: Makefile,v 1.22 2000/07/14 08:10:52 dwmw2 Exp $
+# $Id: Makefile,v 1.60 2001/05/31 20:43:18 dwmw2 Exp $
 
-# Object file lists.
 
-obj-y           :=
+obj-y           += chips/chipslink.o maps/mapslink.o \
+			devices/devlink.o nand/nandlink.o
 obj-m           :=
 obj-n           :=
 obj-            :=
 
 O_TARGET	:= mtdlink.o
-SUB_DIRS	:=
-ALL_SUB_DIRS 	:=
-MOD_SUB_DIRS	:=
 
-export-objs	:=	mtdcore.o mtdpart.o jedec.o
-list-multi	:=
+export-objs	:= mtdcore.o mtdpart.o redboot.o bootldr.o
+list-multi	:= nftl.o
 
-# MTD devices
+mod-subdirs	:= 
+subdir-y	:= chips maps devices nand
+subdir-m	:= $(subdir-y)
+
+#                       *** BIG UGLY NOTE ***
+#
+# The shiny new inter_module_xxx has introduced yet another ugly link
+# order dependency, which I'd previously taken great care to avoid.
+# We now have to ensure that the chip drivers are initialised before the
+# map drivers, and that the doc200[01] drivers are initialised before
+# docprobe.
+#
+# We'll hopefully merge the doc200[01] drivers and docprobe back into
+# a single driver some time soon, but the CFI drivers are going to have
+# to stay like that.
+#
+# Urgh.
+# 
+# dwmw2 21/11/0
+
+# Core functionality.
 obj-$(CONFIG_MTD)		+= mtdcore.o
-obj-$(CONFIG_MTD_DOC1000)	+= doc1000.o
-obj-$(CONFIG_MTD_DOC2000)	+= doc2000.o
-obj-$(CONFIG_MTD_DOC2001)	+= doc2001.o
-obj-$(CONFIG_MTD_DOCPROBE)	+= docprobe.o docecc.o
-obj-$(CONFIG_MTD_SLRAM)		+= slram.o
-obj-$(CONFIG_MTD_PMC551)	+= pmc551.o
-obj-$(CONFIG_MTD_MTDRAM)	+= mtdram.o
-
-# Chip drivers
-obj-$(CONFIG_MTD_JEDEC)		+= jedec.o
-obj-$(CONFIG_MTD_RAM)		+= map_ram.o
-obj-$(CONFIG_MTD_ROM)		+= map_rom.o
-obj-$(CONFIG_MTD_CFI)		+= cfi_probe.o
-obj-$(CONFIG_MTD_CFI_INTELEXT)	+= cfi_cmdset_0001.o
-obj-$(CONFIG_MTD_CFI_AMDSTD)	+= cfi_cmdset_0002.o
-
-# Chip mappings
-obj-$(CONFIG_MTD_PHYSMAP)	+= physmap.o
-obj-$(CONFIG_MTD_MIXMEM)	+= mixmem.o
-obj-$(CONFIG_MTD_NORA)		+= nora.o
-obj-$(CONFIG_MTD_OCTAGON)	+= octagon-5066.o
-obj-$(CONFIG_MTD_PNC2000)	+= pnc2000.o mtdpart.o
-obj-$(CONFIG_MTD_RPXLITE)	+= rpxlite.o
-obj-$(CONFIG_MTD_VMAX)		+= vmax301.o
+obj-$(CONFIG_MTD_PARTITIONS)	+= mtdpart.o
+obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
+obj-$(CONFIG_MTD_BOOTLDR_PARTS) += bootldr.o
 
-# Users
+# 'Users' - code which presents functionality to userspace.
 obj-$(CONFIG_MTD_CHAR)		+= mtdchar.o
 obj-$(CONFIG_MTD_BLOCK)		+= mtdblock.o
+obj-$(CONFIG_MTD_BLOCK_RO)	+= mtdblock_ro.o
 obj-$(CONFIG_FTL)		+= ftl.o
-obj-$(CONFIG_NFTL)		+= nftl.o nftlmount.o
+obj-$(CONFIG_NFTL)		+= nftl.o
+
+nftl-objs	:= nftlcore.o nftlmount.o
 
 include $(TOPDIR)/Rules.make
+
+nftl.o: $(nftl-objs)
+	$(LD) -r -o $@ $(nftl-objs)
+
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/bootldr.c linux/drivers/mtd/bootldr.c
--- v2.4.5/linux/drivers/mtd/bootldr.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/bootldr.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,149 @@
+/*
+ * Read flash partition table from Compaq Bootloader
+ *
+ * Copyright 2001 Compaq Computer Corporation.
+ *
+ * $Id: bootldr.c,v 1.4 2001/06/02 18:24:27 nico Exp $
+ *
+ * Use consistent with the GNU GPL is permitted,
+ * provided that this copyright notice is
+ * preserved in its entirety in all copies and derived works.
+ *
+ * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
+ * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
+ * FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ */
+
+/*
+ * Maintainer: Jamey Hicks (jamey.hicks@compaq.com)
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#define FLASH_PARTITION_NAMELEN 32
+enum LFR_FLAGS {
+   LFR_SIZE_PREFIX = 1,		/* prefix data with 4-byte size */
+   LFR_PATCH_BOOTLDR = 2,	/* patch bootloader's 0th instruction */
+   LFR_KERNEL = 4,		/* add BOOTIMG_MAGIC, imgsize and VKERNEL_BASE to head of programmed region (see bootldr.c) */
+   LFR_EXPAND = 8               /* expand partition size to fit rest of flash */
+};
+
+typedef struct FlashRegion {
+   char name[FLASH_PARTITION_NAMELEN];
+   unsigned long base;
+   unsigned long size;
+   enum LFR_FLAGS flags;
+} FlashRegion;
+
+typedef struct BootldrFlashPartitionTable {
+  int magic; /* should be filled with 0x646c7470 (btlp) BOOTLDR_PARTITION_MAGIC */
+  int npartitions;
+  struct FlashRegion partition[0];
+} BootldrFlashPartitionTable;
+
+#define BOOTLDR_MAGIC      0x646c7462        /* btld: marks a valid bootldr image */
+#define BOOTLDR_PARTITION_MAGIC  0x646c7470  /* btlp: marks a valid bootldr partition table in params sector */
+
+#define BOOTLDR_MAGIC_OFFSET 0x20 /* offset 0x20 into the bootldr */
+#define BOOTCAP_OFFSET 0X30 /* offset 0x30 into the bootldr */
+
+#define BOOTCAP_WAKEUP	(1<<0)
+#define BOOTCAP_PARTITIONS (1<<1) /* partition table stored in params sector */
+#define BOOTCAP_PARAMS_AFTER_BOOTLDR (1<<2) /* params sector right after bootldr sector(s), else in last sector */
+
+int parse_bootldr_partitions(struct mtd_info *master, struct mtd_partition **pparts)
+{
+	struct mtd_partition *parts;
+	int ret, retlen, i;
+	int npartitions = 0;
+	long partition_table_offset;
+	long bootmagic = 0;
+	long bootcap = 0;
+	int namelen = 0;
+	struct BootldrFlashPartitionTable *partition_table = NULL; 
+	char *names; 
+
+	/* verify bootldr magic */
+	ret = master->read(master, BOOTLDR_MAGIC_OFFSET, sizeof(long), &retlen, (void *)&bootmagic);
+	if (ret) 
+		goto out;
+        if (bootmagic != BOOTLDR_MAGIC)
+                goto out;
+	/* see if bootldr supports partition tables and where to find the partition table */
+	ret = master->read(master, BOOTCAP_OFFSET, sizeof(long), &retlen, (void *)&bootcap);
+	if (ret) 
+		goto out;
+
+	if (!(bootcap & BOOTCAP_PARTITIONS))
+		goto out;
+	if (bootcap & BOOTCAP_PARAMS_AFTER_BOOTLDR)
+		partition_table_offset = master->erasesize;
+	else
+		partition_table_offset = master->size - master->erasesize;
+
+	printk(__FUNCTION__ ": partition_table_offset=%#lx\n", partition_table_offset);
+
+	/* Read the partition table */
+	partition_table = (struct BootldrFlashPartitionTable *)kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!partition_table)
+		return -ENOMEM;
+	ret = master->read(master, partition_table_offset,
+			   PAGE_SIZE, &retlen, (void *)partition_table);
+	if (ret)
+		goto out;
+
+	printk(__FUNCTION__ ": magic=%#x\n", partition_table->magic);
+
+	/* check for partition table magic number */
+	if (partition_table->magic != BOOTLDR_PARTITION_MAGIC) 
+		goto out;
+	npartitions = partition_table->npartitions;
+
+	printk(__FUNCTION__ ": npartitions=%#x\n", npartitions);
+
+	for (i = 0; i < npartitions; i++) {
+		namelen += strlen(partition_table->partition[i].name) + 1;
+	}
+
+	parts = kmalloc(sizeof(*parts)*npartitions + namelen, GFP_KERNEL);
+	if (!parts) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	names = (char *)&parts[npartitions];
+	memset(parts, 0, sizeof(*parts)*npartitions + namelen);
+
+	for (i = 0; i < npartitions; i++) {
+                struct FlashRegion *partition = &partition_table->partition[i];
+		const char *name = partition->name;
+		parts[i].name = names;
+		names += strlen(name) + 1;
+		strcpy(parts[i].name, name);
+
+                if (partition->flags & LFR_EXPAND)
+                        parts[i].size = MTDPART_SIZ_FULL;
+                else
+                        parts[i].size = partition->size;
+		parts[i].offset = partition->base;
+		parts[i].mask_flags = 0;
+		
+		printk("        partition %s o=%x s=%x\n", 
+		       parts[i].name, parts[i].offset, parts[i].size);
+
+	}
+
+	ret = npartitions;
+	*pparts = parts;
+
+ out:
+	if (partition_table)
+		kfree(partition_table);
+	return ret;
+}
+
+EXPORT_SYMBOL(parse_bootldr_partitions);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/cfi_cmdset_0001.c linux/drivers/mtd/cfi_cmdset_0001.c
--- v2.4.5/linux/drivers/mtd/cfi_cmdset_0001.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/cfi_cmdset_0001.c	Wed Dec 31 16:00:00 1969
@@ -1,891 +0,0 @@
-/*
- * Common Flash Interface support:
- *   Intel Extended Vendor Command Set (ID 0x0001)
- *
- * (C) 2000 Red Hat. GPL'd
- *
- * $Id: cfi_cmdset_0001.c,v 1.21 2000/07/13 10:36:14 dwmw2 Exp $
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <asm/io.h>
-#include <asm/byteorder.h>
-
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/cfi.h>
-
-#if LINUX_VERSION_CODE < 0x20300
-#define set_current_state(x) current->state = (x);
-#endif
-static int cfi_intelext_read_1_by_16 (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
-static int cfi_intelext_write_1_by_16(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
-static int cfi_intelext_erase_1_by_16 (struct mtd_info *, struct erase_info *);
-static void cfi_intelext_sync (struct mtd_info *);
-static int cfi_intelext_suspend (struct mtd_info *);
-static void cfi_intelext_resume (struct mtd_info *);
-
-static void cfi_intelext_destroy(struct mtd_info *);
-
-static void cfi_cmdset_0001(struct map_info *, int, unsigned long);
-
-static struct mtd_info *cfi_intelext_setup (struct map_info *);
-
-static const char im_name[] = "cfi_cmdset_0001";
-
-/* This routine is made available to other mtd code via
- * inter_module_register.  It must only be accessed through
- * inter_module_get which will bump the use count of this module.  The
- * addresses passed back in cfi are valid as long as the use count of
- * this module is non-zero, i.e. between inter_module_get and
- * inter_module_put.  Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
- */
-static void cfi_cmdset_0001(struct map_info *map, int primary, unsigned long base)
-{
-	struct cfi_private *cfi = map->fldrv_priv;
-	int i;
-	struct cfi_pri_intelext *extp;
-
-	__u16 adr = primary?cfi->cfiq.P_ADR:cfi->cfiq.A_ADR;
-
-	printk(" Intel/Sharp Extended Query Table at 0x%4.4X\n", adr);
-
-	if (!adr)
-		return;
-
-	/* Switch it into Query Mode */
-	switch(map->buswidth) {
-	case 1:
-		map->write8(map, 0x98, 0x55);
-		break;
-	case 2:
-		map->write16(map, 0x9898, 0xaa);
-		break;
-	case 4:
-		map->write32(map, 0x98989898, 0x154);
-		break;
-	}
-
-	extp = kmalloc(sizeof(*extp), GFP_KERNEL);
-	if (!extp) {
-		printk("Failed to allocate memory\n");
-		return;
-	}
-
-	/* Read in the Extended Query Table */
-	for (i=0; i<sizeof(*extp); i++) {
-		((unsigned char *)extp)[i] = 
-			map->read8(map, (base+((adr+i)*map->buswidth)));
-	}
-
-	if (extp->MajorVersion != '1' || 
-	    (extp->MinorVersion < '0' || extp->MinorVersion > '2')) {
-		printk("  Unknown IntelExt Extended Query version %c.%c.\n",
-		       extp->MajorVersion, extp->MinorVersion);
-		kfree(extp);
-		return;
-	}
-
-	/* Do some byteswapping if necessary */
-	extp->FeatureSupport = le32_to_cpu(extp->FeatureSupport);
-	extp->BlkStatusRegMask = le32_to_cpu(extp->BlkStatusRegMask);
-
-	
-	/* Tell the user about it in lots of lovely detail */
-#if 0  
-	printk("  Feature/Command Support: %4.4X\n", extp->FeatureSupport);
-	printk("     - Chip Erase:         %s\n", extp->FeatureSupport&1?"supported":"unsupported");
-	printk("     - Suspend Erase:      %s\n", extp->FeatureSupport&2?"supported":"unsupported");
-	printk("     - Suspend Program:    %s\n", extp->FeatureSupport&4?"supported":"unsupported");
-	printk("     - Legacy Lock/Unlock: %s\n", extp->FeatureSupport&8?"supported":"unsupported");
-	printk("     - Queued Erase:       %s\n", extp->FeatureSupport&16?"supported":"unsupported");
-	printk("     - Instant block lock: %s\n", extp->FeatureSupport&32?"supported":"unsupported");
-	printk("     - Protection Bits:    %s\n", extp->FeatureSupport&64?"supported":"unsupported");
-	printk("     - Page-mode read:     %s\n", extp->FeatureSupport&128?"supported":"unsupported");
-	printk("     - Synchronous read:   %s\n", extp->FeatureSupport&256?"supported":"unsupported");
-	for (i=9; i<32; i++) {
-		if (extp->FeatureSupport & (1<<i)) 
-			printk("     - Unknown Bit %X:      supported\n", i);
-	}
-	
-	printk("  Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport);
-	printk("     - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported");
-	for (i=1; i<8; i++) {
-		if (extp->SuspendCmdSupport & (1<<i))
-			printk("     - Unknown Bit %X:               supported\n", i);
-	}
-	
-	printk("  Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask);
-	printk("     - Lock Bit Active:      %s\n", extp->BlkStatusRegMask&1?"yes":"no");
-	printk("     - Valid Bit Active:     %s\n", extp->BlkStatusRegMask&2?"yes":"no");
-	for (i=2; i<16; i++) {
-		if (extp->BlkStatusRegMask & (1<<i))
-			printk("     - Unknown Bit %X Active: yes\n",i);
-	}
-	
-	printk("  Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", 
-	       extp->VccOptimal >> 8, extp->VccOptimal & 0xf);
-	if (extp->VppOptimal)
-		printk("  Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", 
-		       extp->VppOptimal >> 8, extp->VppOptimal & 0xf);
-#endif	
-	/* OK. We like it. Take over the control of it. */
-
-	/* Switch it into Read Mode */
-	switch(map->buswidth) {
-	case 1:
-		map->write8(map, 0xff, 0x55);
-		break;
-	case 2:
-		map->write16(map, 0xffff, 0xaa);
-		break;
-	case 4:
-		map->write32(map, 0xffffffff, 0x154);
-		break;
-	}
-
-
-	/* If there was an old setup function, decrease its use count */
-	if (cfi->cmdset_setup)
-		inter_module_put(cfi->im_name);
-	if (cfi->cmdset_priv)
-		kfree(cfi->cmdset_priv);
-
-	for (i=0; i< cfi->numchips; i++) {
-		cfi->chips[i].word_write_time = 128;
-		cfi->chips[i].buffer_write_time = 128;
-		cfi->chips[i].erase_time = 1024;
-	}		
-		
-
-	cfi->cmdset_setup = cfi_intelext_setup;
-	cfi->im_name = im_name;
-	cfi->cmdset_priv = extp;
-	
-	return;
-}
-
-static struct mtd_info *cfi_intelext_setup(struct map_info *map)
-{
-	struct cfi_private *cfi = map->fldrv_priv;
-	struct mtd_info *mtd;
-
-	mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
-	printk("number of CFI chips: %d\n", cfi->numchips);
-
-	if (!mtd) {
-	  printk("Failed to allocate memory for MTD device\n");
-	  kfree(cfi->cmdset_priv);
-	  return NULL;
-	}
-
-	memset(mtd, 0, sizeof(*mtd));
-	mtd->priv = map;
-	mtd->type = MTD_NORFLASH;
-	mtd->erasesize = 0x20000; /* FIXME */
-	/* Also select the correct geometry setup too */ 
-	mtd->size = (1 << cfi->cfiq.DevSize) * cfi->numchips;
-	mtd->erase = cfi_intelext_erase_1_by_16;
-	mtd->read = cfi_intelext_read_1_by_16;
-	mtd->write = cfi_intelext_write_1_by_16;
-	mtd->sync = cfi_intelext_sync;
-	mtd->suspend = cfi_intelext_suspend;
-	mtd->resume = cfi_intelext_resume;
-	mtd->flags = MTD_CAP_NORFLASH;
-	map->fldrv_destroy = cfi_intelext_destroy;
-	mtd->name = map->name;
-	return mtd;
-}
-
-static inline int do_read_1_by_16_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
-{
-	__u16 status;
-	unsigned long timeo = jiffies + HZ;
-	DECLARE_WAITQUEUE(wait, current);
-
-	adr += chip->start;
-
- retry:
-	spin_lock_bh(chip->mutex);
-
-	/* Check that the chip's ready to talk to us.
-	 * Later, we can actually think about interrupting it
-	 * if it's in FL_ERASING or FL_WRITING state.
-	 * Not just yet, though.
-	 */
-	switch (chip->state) {
-#if 0
-	case FL_ERASING:
-	case FL_WRITING:
-		/* Suspend the operation, set state to FL_xxx_SUSPENDED */
-#endif
-
-	case FL_CFI_QUERY:
-	case FL_JEDEC_QUERY:
-	case FL_READY:
-		map->write16(map, cpu_to_le16(0x0070), adr);
-		chip->state = FL_STATUS;
-
-	case FL_STATUS:
-		status = le16_to_cpu(map->read16(map, adr));
-
-		if (!(status & (1<<7))) {
-			static int z=0;
-			/* Urgh. Chip not yet ready to talk to us. */
-			if (time_after(jiffies, timeo)) {
-				spin_unlock_bh(chip->mutex);
-				printk("waiting for chip to be ready timed out in read");
-				return -EIO;
-			}
-
-			/* Latency issues. Drop the lock, wait a while and retry */
-			spin_unlock_bh(chip->mutex);
-
-			z++;
-			if ( 0 && !(z % 100 )) 
-				printk("chip not ready yet before read. looping\n");
-
-			udelay(1);
-
-			goto retry;
-		}
-		break;
-
-	default:
-		printk("Waiting for chip, status = %d\n", chip->state);
-
-		/* Stick ourselves on a wait queue to be woken when
-		   someone changes the status */
-
-		set_current_state(TASK_INTERRUPTIBLE);
-		add_wait_queue(&chip->wq, &wait);
-		
-		spin_unlock_bh(chip->mutex);
-
-		schedule();
-		remove_wait_queue(&chip->wq, &wait);
-
-		if(signal_pending(current))
-			return -EINTR;
-
-
-		timeo = jiffies + HZ;
-
-		goto retry;
-	}
-
-	map->write16(map, cpu_to_le16(0x00ff), adr);
-	chip->state = FL_READY;
-
-	map->copy_from(map, buf, adr, len);
-
-	if (chip->state == FL_ERASE_SUSPENDED || 
-	    chip->state == FL_WRITE_SUSPENDED) {
-		printk("Who in hell suspended the pending operation? I didn't write that code yet!\n");
-		/* Restart it and set the state accordingly */
-	}
-
-	wake_up(&chip->wq);
-	spin_unlock_bh(chip->mutex);
-
-	return 0;
-}
-
-static int cfi_intelext_read_1_by_16 (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
-{
-	struct map_info *map = mtd->priv;
-	struct cfi_private *cfi = map->fldrv_priv;
-	unsigned long ofs;
-	int chipnum;
-	int ret = 0;
-
-	/* ofs: offset within the first chip that the first read should start */
-	chipnum = (from >> cfi->chipshift);
-	ofs = from - (chipnum <<  cfi->chipshift);
-
-	*retlen = 0;
-
-	while (len) {
-		unsigned long thislen;
-
-		if (chipnum >= cfi->numchips)
-			break;
-
-		if ((len + ofs -1) >> cfi->chipshift)
-			thislen = (1<<cfi->chipshift) - ofs;
-		else
-			thislen = len;
-
-		ret = do_read_1_by_16_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf);
-		if (ret)
-			break;
-
-		*retlen += thislen;
-		len -= thislen;
-		buf += thislen;
-		
-		ofs = 0;
-		chipnum++;
-	}
-	return ret;
-}
-
-static inline int do_write_1_by_16_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, __u16 datum)
-{
-	__u16 status;
-	unsigned long timeo = jiffies + HZ;
-	DECLARE_WAITQUEUE(wait, current);
-	int z = 0;
-	adr += chip->start;
-
- retry:
-	spin_lock_bh(chip->mutex);
-
-	/* Check that the chip's ready to talk to us.
-	 * Later, we can actually think about interrupting it
-	 * if it's in FL_ERASING state.
-	 * Not just yet, though.
-	 */
-	switch (chip->state) {
-	case FL_CFI_QUERY:
-	case FL_JEDEC_QUERY:
-	case FL_READY:
-		map->write16(map, cpu_to_le16(0x0070), adr);
-		chip->state = FL_STATUS;
-		timeo = jiffies + HZ;
-
-	case FL_STATUS:
-		status = le16_to_cpu(map->read16(map, adr));
-
-		if (!(status & (1<<7))) {
-
-			/* Urgh. Chip not yet ready to talk to us. */
-			if (time_after(jiffies, timeo)) {
-				spin_unlock_bh(chip->mutex);
-				printk("waiting for chip to be ready timed out in read");
-				return -EIO;
-			}
-
-			/* Latency issues. Drop the lock, wait a while and retry */
-			spin_unlock_bh(chip->mutex);
-
-			z++;
-			if ( 0 && !(z % 100 ))
-				printk("chip not ready yet before write. looping\n");
-			
-			udelay(1);
-
-			goto retry;
-		}
-		break;
-
-	default:
-		printk("Waiting for chip, status = %d\n", chip->state);
-
-		/* Stick ourselves on a wait queue to be woken when
-		   someone changes the status */
-
-		set_current_state(TASK_INTERRUPTIBLE);
-		add_wait_queue(&chip->wq, &wait);
-		
-		spin_unlock_bh(chip->mutex);
-
-		schedule();
-		remove_wait_queue(&chip->wq, &wait);
-
-		if(signal_pending(current))
-			return -EINTR;
-
-		timeo = jiffies + HZ;
-
-		goto retry;
-	}
-	
-	map->write16(map, cpu_to_le16(0x0040), adr);
-	map->write16(map, datum, adr);
-	chip->state = FL_WRITING;
-
-	timeo = jiffies + (HZ/2);
-
-	spin_unlock_bh(chip->mutex);
-	udelay(chip->word_write_time);
-	spin_lock_bh(chip->mutex);
-
-	z = 0;
-	while ( !( (status = le16_to_cpu(map->read16(map, adr)))  & 0x80 ) ) {
-
-		if (chip->state != FL_WRITING) {
-			/* Someone's suspended the write. Sleep */
-			set_current_state(TASK_INTERRUPTIBLE);
-			add_wait_queue(&chip->wq, &wait);
-			
-			spin_unlock_bh(chip->mutex);
-			
-			schedule();
-			remove_wait_queue(&chip->wq, &wait);
-			
-			if (signal_pending(current))
-				return -EINTR;
-			
-			timeo = jiffies + (HZ / 2); /* FIXME */
-
-			spin_lock_bh(chip->mutex);
-			continue;
-		}
-
-		/* OK Still waiting */
-		if (time_after(jiffies, timeo)) {
-			chip->state = FL_STATUS;
-			spin_unlock_bh(chip->mutex);
-			printk("waiting for chip to be ready timed out in read");
-			return -EIO;
-		}
-		
-		/* Latency issues. Drop the lock, wait a while and retry */
-		spin_unlock_bh(chip->mutex);
-		
-		z++;
-		if ( 0 && !(z % 100 )) 
-		  printk("chip not ready yet after write. looping\n");
-		
-		udelay(1);
-		
-		spin_lock_bh(chip->mutex);
-		continue;
-	}
-	if (!z) {
-		chip->word_write_time--;
-		if (!chip->word_write_time)
-			chip->word_write_time++;
-	}
-	if (z > 1) 
-		chip->word_write_time++;
-
-	/* Done and happy. */
-	chip->state = FL_STATUS;
-	wake_up(&chip->wq);
-	spin_unlock_bh(chip->mutex);
-	//	printk("write ret OK at %lx\n", adr);
-	return 0;
-}
-
-
-/* This version only uses the 'word write' instruction. We should update it
- * to write using 'buffer write' if it's available 
- */
-static int cfi_intelext_write_1_by_16 (struct mtd_info *mtd, loff_t to , size_t len, size_t *retlen, const u_char *buf)
-{
-	struct map_info *map = mtd->priv;
-	struct cfi_private *cfi = map->fldrv_priv;
-	int ret = 0;
-	int chipnum;
-	unsigned long ofs;
-
-	*retlen = 0;
-	chipnum = to >> cfi->chipshift;
-	ofs = to  - (chipnum << cfi->chipshift);
-
-	/* If it's not word-aligned, do the first byte write */
-	if (ofs & 1) {
-#if defined(__LITTLE_ENDIAN)
-		ret = do_write_1_by_16_oneword(map, &cfi->chips[chipnum],
-					       ofs, 0xFF | (*buf << 8));
-#elif defined(__BIG_ENDIAN) 
-		ret = do_write_1_by_16_oneword(map, &cfi->chips[chipnum],
-					       ofs, 0xFF00 | (*buf));
-#else
-#error define a sensible endianness
-#endif
-		if (ret) 
-			return ret;
-		
-		ofs++;
-		buf++;
-		(*retlen)++;
-		len--;
-
-		if (ofs >> cfi->chipshift) {
-			chipnum ++; 
-			ofs = 0;
-			if (chipnum == cfi->numchips)
-				return 0;
-		}
-	}
-	
-	while(len > 1) {
-		ret = do_write_1_by_16_oneword(map, &cfi->chips[chipnum],
-					       ofs, *(__u16 *)buf);
-		if (ret)
-			return ret;
-
-		ofs += 2;
-		buf += 2;
-		(*retlen) += 2;
-		len -= 2;
-
-		if (ofs >> cfi->chipshift) {
-			chipnum ++; 
-			ofs = 0;
-			if (chipnum == cfi->numchips)
-				return 0;
-		}
-	}
-
-	if (len) {
-		/* Final byte to write */
-#if defined(__LITTLE_ENDIAN)
-		ret = do_write_1_by_16_oneword(map, &cfi->chips[chipnum],
-					       ofs, 0xFF00 | (*buf));
-#elif defined(__BIG_ENDIAN) 
-		ret = do_write_1_by_16_oneword(map, &cfi->chips[chipnum],
-					       ofs, 0xFF | (*buf << 8));
-#else
-#error define a sensible endianness
-#endif
-		if (ret) 
-			return ret;
-		
-		(*retlen)++;
-	}
-
-	return 0;
-}
-
-
-static inline int do_erase_1_by_16_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
-{
-	__u16 status;
-	unsigned long timeo = jiffies + HZ;
-	DECLARE_WAITQUEUE(wait, current);
-
-	adr += chip->start;
-
- retry:
-	spin_lock_bh(chip->mutex);
-
-	/* Check that the chip's ready to talk to us. */
-	switch (chip->state) {
-	case FL_CFI_QUERY:
-	case FL_JEDEC_QUERY:
-	case FL_READY:
-		map->write16(map, cpu_to_le16(0x0070), adr);
-		chip->state = FL_STATUS;
-		timeo = jiffies + HZ;
-
-	case FL_STATUS:
-		status = le16_to_cpu(map->read16(map, adr));
-
-		if (!(status & (1<<7))) {
-			static int z=0;
-			/* Urgh. Chip not yet ready to talk to us. */
-			if (time_after(jiffies, timeo)) {
-				spin_unlock_bh(chip->mutex);
-				printk("waiting for chip to be ready timed out in erase");
-				return -EIO;
-			}
-
-			/* Latency issues. Drop the lock, wait a while and retry */
-			spin_unlock_bh(chip->mutex);
-
-			z++;
-			if ( 0 && !(z % 100 )) 
-				printk("chip not ready yet before erase. looping\n");
-
-			udelay(1);
-
-			goto retry;
-		}
-		break;
-
-	default:
-		printk("Waiting for chip, status = %d\n", chip->state);
-
-		/* Stick ourselves on a wait queue to be woken when
-		   someone changes the status */
-
-		set_current_state(TASK_INTERRUPTIBLE);
-		add_wait_queue(&chip->wq, &wait);
-		
-		spin_unlock_bh(chip->mutex);
-
-		schedule();
-		remove_wait_queue(&chip->wq, &wait);
-
-		if(signal_pending(current))
-			return -EINTR;
-
-		timeo = jiffies + HZ;
-
-		goto retry;
-	}
-	
-	map->write16(map, cpu_to_le16(0x0020), adr);
-	map->write16(map, cpu_to_le16(0x00D0), adr);
-
-	chip->state = FL_ERASING;
-	
-	timeo = jiffies + (HZ*2);
-	spin_unlock_bh(chip->mutex);
-	schedule_timeout(HZ);
-	spin_lock_bh(chip->mutex);
-
-	/* FIXME. Use a timer to check this, and return immediately. */
-	/* Once the state machine's known to be working I'll do that */
-
-	while ( !( (status = le16_to_cpu(map->read16(map, adr)))  & 0x80 ) ) {
-		static int z=0;
-
-		if (chip->state != FL_ERASING) {
-			/* Someone's suspended the erase. Sleep */
-			set_current_state(TASK_INTERRUPTIBLE);
-			add_wait_queue(&chip->wq, &wait);
-			
-			spin_unlock_bh(chip->mutex);
-			printk("erase suspended. Sleeping\n");
-			
-			schedule();
-			remove_wait_queue(&chip->wq, &wait);
-			
-			if (signal_pending(current))
-				return -EINTR;
-			
-			timeo = jiffies + (HZ*2); /* FIXME */
-			spin_lock_bh(chip->mutex);
-			continue;
-		}
-
-		/* OK Still waiting */
-		if (time_after(jiffies, timeo)) {
-			chip->state = FL_STATUS;
-			spin_unlock_bh(chip->mutex);
-			printk("waiting for erase to complete timed out.");
-			return -EIO;
-		}
-		
-		/* Latency issues. Drop the lock, wait a while and retry */
-		spin_unlock_bh(chip->mutex);
-
-		z++;
-		if ( 0 && !(z % 100 )) 
-			printk("chip not ready yet after erase. looping\n");
-
-		udelay(1);
-		
-		spin_lock_bh(chip->mutex);
-		continue;
-	}
-	
-	/* Done and happy. */
-	chip->state = FL_STATUS;
-	wake_up(&chip->wq);
-	spin_unlock_bh(chip->mutex);
-	//printk("erase ret OK\n");
-	return 0;
-}
-
-static int cfi_intelext_erase_1_by_16 (struct mtd_info *mtd, struct erase_info *instr)
-{
-	struct map_info *map = mtd->priv;
-	struct cfi_private *cfi = map->fldrv_priv;
-	unsigned long adr, len;
-	int chipnum, ret = 0;
-
-	if (instr->addr & (mtd->erasesize - 1))
-		return -EINVAL;
-
-	if (instr->len & (mtd->erasesize -1))
-		return -EINVAL;
-
-	if ((instr->len + instr->addr) > mtd->size)
-		return -EINVAL;
-
-	chipnum = instr->addr >> cfi->chipshift;
-	adr = instr->addr - (chipnum << cfi->chipshift);
-	len = instr->len;
-
-	while(len) {
-		ret = do_erase_1_by_16_oneblock(map, &cfi->chips[chipnum], adr);
-		
-		if (ret)
-			return ret;
-
-		adr += mtd->erasesize;
-		len -= mtd->erasesize;
-
-		if (adr >> cfi->chipshift) {
-			adr = 0;
-			chipnum++;
-			
-			if (chipnum >= cfi->numchips)
-			break;
-		}
-	}
-		
-	if (instr->callback)
-		instr->callback(instr);
-	
-	return 0;
-}
-
-
-
-static void cfi_intelext_sync (struct mtd_info *mtd)
-{
-	struct map_info *map = mtd->priv;
-	struct cfi_private *cfi = map->fldrv_priv;
-	int i;
-	struct flchip *chip;
-	int ret = 0;
-	DECLARE_WAITQUEUE(wait, current);
-
-	for (i=0; !ret && i<cfi->numchips; i++) {
-		chip = &cfi->chips[i];
-
-	retry:
-		spin_lock_bh(chip->mutex);
-
-		switch(chip->state) {
-		case FL_READY:
-		case FL_STATUS:
-		case FL_CFI_QUERY:
-		case FL_JEDEC_QUERY:
-			chip->oldstate = chip->state;
-			chip->state = FL_SYNCING;
-			/* No need to wake_up() on this state change - 
-			 * as the whole point is that nobody can do anything
-			 * with the chip now anyway.
-			 */
-			spin_unlock_bh(chip->mutex);
-			break;
-
-		default:
-			/* Not an idle state */
-			add_wait_queue(&chip->wq, &wait);
-			
-			spin_unlock_bh(chip->mutex);
-			schedule();
-			
-			remove_wait_queue(&chip->wq, &wait);
-
-			goto retry;
-		}
-	}
-
-	/* Unlock the chips again */
-
-	for (i--; i >=0; i--) {
-		chip = &cfi->chips[i];
-
-		spin_lock_bh(chip->mutex);
-		
-		if (chip->state == FL_SYNCING) {
-			chip->state = chip->oldstate;
-			wake_up(&chip->wq);
-		}
-		spin_unlock_bh(chip->mutex);
-	}
-}
-
-
-static int cfi_intelext_suspend(struct mtd_info *mtd)
-{
-	struct map_info *map = mtd->priv;
-	struct cfi_private *cfi = map->fldrv_priv;
-	int i;
-	struct flchip *chip;
-	int ret = 0;
-
-	for (i=0; !ret && i<cfi->numchips; i++) {
-		chip = &cfi->chips[i];
-
-		spin_lock_bh(chip->mutex);
-
-		switch(chip->state) {
-		case FL_READY:
-		case FL_STATUS:
-		case FL_CFI_QUERY:
-		case FL_JEDEC_QUERY:
-			chip->oldstate = chip->state;
-			chip->state = FL_PM_SUSPENDED;
-			/* No need to wake_up() on this state change - 
-			 * as the whole point is that nobody can do anything
-			 * with the chip now anyway.
-			 */
-			break;
-
-		default:
-			ret = -EAGAIN;
-			break;
-		}
-		spin_unlock_bh(chip->mutex);
-	}
-
-	/* Unlock the chips again */
-
-	for (i--; i >=0; i--) {
-		chip = &cfi->chips[i];
-
-		spin_lock_bh(chip->mutex);
-		
-		if (chip->state == FL_PM_SUSPENDED) {
-			chip->state = chip->oldstate;
-			wake_up(&chip->wq);
-		}
-		spin_unlock_bh(chip->mutex);
-	}
-	
-	return ret;
-}
-
-static void cfi_intelext_resume(struct mtd_info *mtd)
-{
-	struct map_info *map = mtd->priv;
-	struct cfi_private *cfi = map->fldrv_priv;
-	int i;
-	struct flchip *chip;
-
-	for (i=0; i<cfi->numchips; i++) {
-	
-		chip = &cfi->chips[i];
-
-		spin_lock_bh(chip->mutex);
-		
-		if (chip->state == FL_PM_SUSPENDED) {
-			chip->state = chip->oldstate;
-			wake_up(&chip->wq);
-		}
-		else
-			printk("Argh. Chip not in PM_SUSPENDED state upon resume()\n");
-
-		spin_unlock_bh(chip->mutex);
-	}
-}
-
-static void cfi_intelext_destroy(struct mtd_info *mtd)
-{
-	struct map_info *map = mtd->priv;
-	struct cfi_private *cfi = map->fldrv_priv;
-	kfree(cfi->cmdset_priv);
-	inter_module_put(cfi->im_name);
-	kfree(cfi);
-}
-
-
-static int __init cfi_intelext_init(void)
-{
-	inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0001);
-	return 0;
-}
-
-static void __exit cfi_intelext_exit(void)
-{
-	inter_module_unregister(im_name);
-}
-
-module_init(cfi_intelext_init);
-module_exit(cfi_intelext_exit);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/cfi_cmdset_0002.c linux/drivers/mtd/cfi_cmdset_0002.c
--- v2.4.5/linux/drivers/mtd/cfi_cmdset_0002.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/cfi_cmdset_0002.c	Wed Dec 31 16:00:00 1969
@@ -1,628 +0,0 @@
-/*
- * Common Flash Interface support:
- *   AMD & Fujitsu Extended Vendor Command Set (ID 0x0002)
- *
- * Copyright (C) 2000 Crossnet Co. <info@crossnet.co.jp>
- *
- * This code is GPL
- *
- * $Id: cfi_cmdset_0002.c,v 1.1 2000/07/11 12:32:09 dwmw2 Exp $
- *
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <asm/io.h>
-#include <asm/byteorder.h>
-
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/cfi.h>
-
-#if LINUX_VERSION_CODE < 0x20300
-#define set_current_state(x) current->state = (x);
-#endif
-
-static int cfi_amdext_read_2_by_16 (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
-static int cfi_amdext_write_2_by_16(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
-static int cfi_amdext_erase_2_by_16 (struct mtd_info *, struct erase_info *);
-static void cfi_amdext_sync (struct mtd_info *);
-static int cfi_amdext_suspend (struct mtd_info *);
-static void cfi_amdext_resume (struct mtd_info *);
-
-static void cfi_amdext_destroy(struct mtd_info *);
-
-static void cfi_cmdset_0002(struct map_info *, int, unsigned long);
-
-static struct mtd_info *cfi_amdext_setup (struct map_info *);
-
-static const char im_name[] = "cfi_cmdset_0002";
-
-static void cfi_cmdset_0002(struct map_info *map, int primary, unsigned long base)
-{
-	struct cfi_private *cfi = map->fldrv_priv;
-	int i;
-//	struct cfi_pri_intelext *extp;
-
-	__u16 adr = primary?cfi->cfiq.P_ADR:cfi->cfiq.A_ADR;
-
-	printk(" Amd/Fujitsu Extended Query Table at 0x%4.4X\n", adr);
-
-
-	/* If there was an old setup function, decrease its use count */
-	if (cfi->cmdset_setup)
-		inter_module_put(cfi->im_name);
-	if (cfi->cmdset_priv)
-		kfree(cfi->cmdset_priv);
-
-	for (i=0; i< cfi->numchips; i++) {
-		cfi->chips[i].word_write_time = 128;
-		cfi->chips[i].buffer_write_time = 128;
-		cfi->chips[i].erase_time = 1024;
-	}		
-		
-
-	cfi->cmdset_setup = cfi_amdext_setup;
-	cfi->im_name = im_name;
-//	cfi->cmdset_priv = extp;
-	
-	return;
-}
-
-static struct mtd_info *cfi_amdext_setup(struct map_info *map)
-{
-	struct cfi_private *cfi = map->fldrv_priv;
-	struct mtd_info *mtd;
-
-	mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
-	printk("number of CFI chips: %d\n", cfi->numchips);
-
-	if (!mtd) {
-	  printk("Failed to allocate memory for MTD device\n");
-	  kfree(cfi->cmdset_priv);
-	  return NULL;
-	}
-
-	memset(mtd, 0, sizeof(*mtd));
-	mtd->priv = map;
-	mtd->type = MTD_NORFLASH;
-	mtd->erasesize = 0x20000; /* FIXME */
-	/* Also select the correct geometry setup too */ 
-	mtd->size = (1 << cfi->cfiq.DevSize) * cfi->numchips * cfi->interleave;
-	mtd->erase = cfi_amdext_erase_2_by_16;
-	mtd->read = cfi_amdext_read_2_by_16;
-	mtd->write = cfi_amdext_write_2_by_16;
-	mtd->sync = cfi_amdext_sync;
-	mtd->suspend = cfi_amdext_suspend;
-	mtd->resume = cfi_amdext_resume;
-	mtd->flags = MTD_CAP_NORFLASH;
-	map->fldrv_destroy = cfi_amdext_destroy;
-	mtd->name = map->name;
-	return mtd;
-}
-
-static inline int do_read_2_by_16_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long timeo = jiffies + HZ;
-
- retry:
-	spin_lock_bh(chip->mutex);
-
-	if (chip->state != FL_READY){
-printk("Waiting for chip to read, status = %d\n", chip->state);
-		set_current_state(TASK_INTERRUPTIBLE);
-		add_wait_queue(&chip->wq, &wait);
-                
-		spin_unlock_bh(chip->mutex);
-
-		schedule();
-		remove_wait_queue(&chip->wq, &wait);
-
-		if(signal_pending(current))
-			return -EINTR;
-
-		timeo = jiffies + HZ;
-
-		goto retry;
-	}	
-
-	adr += chip->start;
-
-//     	map->write32(map, cpu_to_le32(0x00F000F0), adr);
-
-	chip->state = FL_READY;
-
-	map->copy_from(map, buf, adr, len);
-
-	wake_up(&chip->wq);
-	spin_unlock_bh(chip->mutex);
-
-	return 0;
-}
-
-static int cfi_amdext_read_2_by_16 (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
-{
-	struct map_info *map = mtd->priv;
-	struct cfi_private *cfi = map->fldrv_priv;
-	unsigned long ofs;
-	int chipnum;
-	int ret = 0;
-
-	/* ofs: offset within the first chip that the first read should start */
-
-	chipnum = (from >> cfi->chipshift);
-	chipnum /= (cfi->interleave);
-	ofs = from - (chipnum <<  cfi->chipshift) * (cfi->interleave);
-
-	*retlen = 0;
-
-	while (len) {
-		unsigned long thislen;
-
-		if (chipnum >= cfi->numchips)
-			break;
-
-		if (((len + ofs -1) >> cfi->chipshift) / (cfi->interleave))
-			thislen = (1<<cfi->chipshift) * (cfi->interleave) - ofs;
-		else
-			thislen = len;
-
-		ret = do_read_2_by_16_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf);
-		if (ret)
-			break;
-
-		*retlen += thislen;
-		len -= thislen;
-		buf += thislen;
-
-		ofs = 0;
-		chipnum++;
-	}
-	return ret;
-}
-
-static inline int do_write_2_by_16_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, __u32 datum)
-{
-	unsigned long timeo = jiffies + HZ;
-	unsigned int Last[4];
-	unsigned long Count = 0;
-	DECLARE_WAITQUEUE(wait, current);
-	int ret = 0;
-
- retry:
-	spin_lock_bh(chip->mutex);
-
-	if (chip->state != FL_READY){
-printk("Waiting for chip to write, status = %d\n", chip->state);
-		set_current_state(TASK_INTERRUPTIBLE);
-		add_wait_queue(&chip->wq, &wait);
-                
-		spin_unlock_bh(chip->mutex);
-
-		schedule();
-		remove_wait_queue(&chip->wq, &wait);
-printk("Wake up to write:\n");
-		if(signal_pending(current))
-			return -EINTR;
-
-		timeo = jiffies + HZ;
-
-		goto retry;
-	}	
-
-	chip->state = FL_WRITING;
-
-	adr += chip->start;
-
-	map->write32(map, cpu_to_le32(0x00AA00AA), 0x555 *4);
-	map->write32(map, cpu_to_le32(0x00550055), 0x2AA *4);
-	map->write32(map, cpu_to_le32(0x00A000A0), 0x555 *4);
-	map->write32(map, cpu_to_le32(datum), adr);
-
-	spin_unlock_bh(chip->mutex);
-	udelay(chip->word_write_time);
-	spin_lock_bh(chip->mutex);
-
-	Last[0] = map->read32(map, adr);
-	Last[1] = map->read32(map, adr);
-	Last[2] = map->read32(map, adr);
-
-	for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] && Count < 10000; Count++){
-		udelay(10);
-
-		Last[Count % 4] = map->read32(map, adr);
-	}
-
-	if (Last[(Count - 1) % 4] != datum){
-	     	map->write32(map, cpu_to_le32(0x00F000F0), adr);
-		ret = -EIO;
-	}       
-
-	chip->state = FL_READY;
-	wake_up(&chip->wq);
-	spin_unlock_bh(chip->mutex);
-
-	return ret;
-}
-
-
-static int cfi_amdext_write_2_by_16 (struct mtd_info *mtd, loff_t to , size_t len, size_t *retlen, const u_char *buf)
-{
-	struct map_info *map = mtd->priv;
-	struct cfi_private *cfi = map->fldrv_priv;
-	int ret = 0;
-	int chipnum;
-	unsigned long ofs;
-
-	*retlen = 0;
-
-	chipnum = (to >> cfi->chipshift);
-	chipnum /= cfi->interleave;
-	ofs = to  - (chipnum << cfi->chipshift) * cfi->interleave;
-
-	while(len > 3) {
-
-		ret = do_write_2_by_16_oneword(map, &cfi->chips[chipnum],
-					       ofs, *(__u32 *)buf);
-		if (ret)
-			return ret;
-
-		ofs += 4;
-		buf += 4;
-		(*retlen) += 4;
-		len -= 4;
-
-		if ((ofs >> cfi->chipshift) / cfi->interleave) {
-			chipnum ++; 
-			ofs = 0;
-			if (chipnum == cfi->numchips)
-				return 0;
-		}
-	}
-
-	if (len) {
-		unsigned int tmp;
-
-		/* Final byte to write */
-#if defined(__LITTLE_ENDIAN)
-		tmp = map->read32(map, ofs);
-
-		tmp = 0xffffffff >> (len*8);
-		tmp = tmp << (len*8);
-
-		tmp |= *(__u32 *)(buf);
-
-		ret = do_write_2_by_16_oneword(map, &cfi->chips[chipnum],
-					       ofs, tmp);
-
-#elif defined(__BIG_ENDIAN) 
-#error not support big endian yet
-#else
-#error define a sensible endianness
-#endif
-
-		if (ret) 
-			return ret;
-		
-		(*retlen)+=len;
-	}
-
-	return 0;
-}
-
-
-static inline int do_erase_2_by_16_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
-{
-	unsigned int status;
-	unsigned long timeo = jiffies + HZ;
-	DECLARE_WAITQUEUE(wait, current);
-
- retry:
-	spin_lock_bh(chip->mutex);
-
-	if (chip->state != FL_READY){
-		set_current_state(TASK_INTERRUPTIBLE);
-		add_wait_queue(&chip->wq, &wait);
-                
-		spin_unlock_bh(chip->mutex);
-
-		schedule();
-		remove_wait_queue(&chip->wq, &wait);
-
-		if(signal_pending(current))
-			return -EINTR;
-
-		timeo = jiffies + HZ;
-
-		goto retry;
-	}	
-
-	chip->state = FL_ERASING;
-
-	adr += chip->start;
-
-	map->write32(map, cpu_to_le32(0x00AA00AA), 0x555 *4);
-	map->write32(map, cpu_to_le32(0x00550055), 0x2AA *4);
-	map->write32(map, cpu_to_le32(0x00800080), 0x555 *4);
-	map->write32(map, cpu_to_le32(0x00AA00AA), 0x555 *4);
-	map->write32(map, cpu_to_le32(0x00550055), 0x2AA *4);
-	map->write32(map, cpu_to_le32(0x00300030), adr);
-
-	
-	timeo = jiffies + (HZ*20);
-
-	spin_unlock_bh(chip->mutex);
-	schedule_timeout(HZ);
-	spin_lock_bh(chip->mutex);
-
-	/* FIXME. Use a timer to check this, and return immediately. */
-	/* Once the state machine's known to be working I'll do that */
-
-	while ( ( (status = le32_to_cpu(map->read32(map, 0x00))) & 0x80808080 ) != 0x80808080 ) {
-		static int z=0;
-
-		if (chip->state != FL_ERASING) {
-			/* Someone's suspended the erase. Sleep */
-			set_current_state(TASK_INTERRUPTIBLE);
-			add_wait_queue(&chip->wq, &wait);
-			
-			spin_unlock_bh(chip->mutex);
-			printk("erase suspended. Sleeping\n");
-			
-			schedule();
-			remove_wait_queue(&chip->wq, &wait);
-			
-			if (signal_pending(current))
-				return -EINTR;
-			
-			timeo = jiffies + (HZ*2); /* FIXME */
-			spin_lock_bh(chip->mutex);
-			continue;
-		}
-
-		/* OK Still waiting */
-		if (time_after(jiffies, timeo)) {
-			chip->state = FL_READY;
-			spin_unlock_bh(chip->mutex);
-			printk("waiting for erase to complete timed out.");
-			return -EIO;
-		}
-		
-		/* Latency issues. Drop the lock, wait a while and retry */
-		spin_unlock_bh(chip->mutex);
-
-		z++;
-		if ( 0 && !(z % 100 )) 
-			printk("chip not ready yet after erase. looping\n");
-
-		udelay(1);
-		
-		spin_lock_bh(chip->mutex);
-		continue;
-	}
-	
-	/* Done and happy. */
-	chip->state = FL_READY;
-	wake_up(&chip->wq);
-	spin_unlock_bh(chip->mutex);
-	printk("erase ret OK\n");
-	return 0;
-}
-
-static int cfi_amdext_erase_2_by_16 (struct mtd_info *mtd, struct erase_info *instr)
-{
-	struct map_info *map = mtd->priv;
-	struct cfi_private *cfi = map->fldrv_priv;
-	unsigned long adr, len;
-	int chipnum, ret = 0;
-
-//printk("erase : 0x%x 0x%x 0x%x\n", instr->addr, instr->len, mtd->size);
-
-	if (instr->addr & (mtd->erasesize - 1))
-		return -EINVAL;
-
-	if (instr->len & (mtd->erasesize -1))
-		return -EINVAL;
-
-	if ((instr->len + instr->addr) > mtd->size)
-		return -EINVAL;
-
-	chipnum = instr->addr >> cfi->chipshift;
-	chipnum /= cfi->interleave;
-	adr = instr->addr - (chipnum << cfi->chipshift) * (cfi->interleave);
-	len = instr->len;
-
-	printk("erase : 0x%lx 0x%lx 0x%x 0x%lx\n", adr, len, chipnum, mtd->size);
-
-	while(len) {
-//printk("erase : 0x%x 0x%x 0x%x 0x%x\n", chipnum, adr, len, cfi->chipshift);
-		ret = do_erase_2_by_16_oneblock(map, &cfi->chips[chipnum], adr);
-
-		if (ret)
-			return ret;
-
-		adr += mtd->erasesize;
-		len -= mtd->erasesize;
-
-		if ((adr >> cfi->chipshift) / (cfi->interleave)) {
-			adr = 0;
-			chipnum++;
-			
-			if (chipnum >= cfi->numchips)
-			break;
-		}
-	}
-		
-	if (instr->callback)
-		instr->callback(instr);
-	
-	return 0;
-}
-
-
-
-static void cfi_amdext_sync (struct mtd_info *mtd)
-{
-	struct map_info *map = mtd->priv;
-	struct cfi_private *cfi = map->fldrv_priv;
-	int i;
-	struct flchip *chip;
-	int ret = 0;
-	DECLARE_WAITQUEUE(wait, current);
-printk("sync\n");
-
-	for (i=0; !ret && i<cfi->numchips; i++) {
-		chip = &cfi->chips[i];
-
-	retry:
-		spin_lock_bh(chip->mutex);
-
-		switch(chip->state) {
-		case FL_READY:
-		case FL_STATUS:
-		case FL_CFI_QUERY:
-		case FL_JEDEC_QUERY:
-			chip->oldstate = chip->state;
-			chip->state = FL_SYNCING;
-			/* No need to wake_up() on this state change - 
-			 * as the whole point is that nobody can do anything
-			 * with the chip now anyway.
-			 */
-			spin_unlock_bh(chip->mutex);
-			break;
-
-		default:
-			/* Not an idle state */
-			add_wait_queue(&chip->wq, &wait);
-			
-			spin_unlock_bh(chip->mutex);
-
-			schedule();
-			
-			remove_wait_queue(&chip->wq, &wait);
-
-			goto retry;
-		}
-	}
-
-	/* Unlock the chips again */
-
-	for (i--; i >=0; i--) {
-		chip = &cfi->chips[i];
-
-		spin_lock_bh(chip->mutex);
-		
-		if (chip->state == FL_SYNCING) {
-			chip->state = chip->oldstate;
-			wake_up(&chip->wq);
-		}
-		spin_unlock_bh(chip->mutex);
-	}
-printk("sync end\n");
-}
-
-
-static int cfi_amdext_suspend(struct mtd_info *mtd)
-{
-	struct map_info *map = mtd->priv;
-	struct cfi_private *cfi = map->fldrv_priv;
-	int i;
-	struct flchip *chip;
-	int ret = 0;
-//printk("suspend\n");
-
-	for (i=0; !ret && i<cfi->numchips; i++) {
-		chip = &cfi->chips[i];
-
-		spin_lock_bh(chip->mutex);
-
-		switch(chip->state) {
-		case FL_READY:
-		case FL_STATUS:
-		case FL_CFI_QUERY:
-		case FL_JEDEC_QUERY:
-			chip->oldstate = chip->state;
-			chip->state = FL_PM_SUSPENDED;
-			/* No need to wake_up() on this state change - 
-			 * as the whole point is that nobody can do anything
-			 * with the chip now anyway.
-			 */
-			break;
-
-		default:
-			ret = -EAGAIN;
-			break;
-		}
-		spin_unlock_bh(chip->mutex);
-	}
-
-	/* Unlock the chips again */
-
-	for (i--; i >=0; i--) {
-		chip = &cfi->chips[i];
-
-		spin_lock_bh(chip->mutex);
-		
-		if (chip->state == FL_PM_SUSPENDED) {
-			chip->state = chip->oldstate;
-			wake_up(&chip->wq);
-		}
-		spin_unlock_bh(chip->mutex);
-	}
-	
-	return ret;
-}
-
-static void cfi_amdext_resume(struct mtd_info *mtd)
-{
-	struct map_info *map = mtd->priv;
-	struct cfi_private *cfi = map->fldrv_priv;
-	int i;
-	struct flchip *chip;
-//printk("resume\n");
-
-	for (i=0; i<cfi->numchips; i++) {
-	
-		chip = &cfi->chips[i];
-
-		spin_lock_bh(chip->mutex);
-		
-		if (chip->state == FL_PM_SUSPENDED) {
-			chip->state = chip->oldstate;
-			wake_up(&chip->wq);
-		}
-		else
-			printk("Argh. Chip not in PM_SUSPENDED state upon resume()\n");
-
-		spin_unlock_bh(chip->mutex);
-	}
-}
-
-static void cfi_amdext_destroy(struct mtd_info *mtd)
-{
-	struct map_info *map = mtd->priv;
-	struct cfi_private *cfi = map->fldrv_priv;
-	kfree(cfi->cmdset_priv);
-	inter_module_put(cfi->im_name);
-	kfree(cfi);
-}
-
-
-static int __init cfi_amdext_init(void)
-{
-	inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0002);
-	return 0;
-}
-
-static void __exit cfi_amdext_exit(void)
-{
-	inter_module_unregister(im_name);
-}
-
-module_init(cfi_amdext_init);
-module_exit(cfi_amdext_exit);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/cfi_probe.c linux/drivers/mtd/cfi_probe.c
--- v2.4.5/linux/drivers/mtd/cfi_probe.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/cfi_probe.c	Wed Dec 31 16:00:00 1969
@@ -1,517 +0,0 @@
-/* 
-   Common Flash Interface probe code.
-   (C) 2000 Red Hat. GPL'd.
-   $Id: cfi_probe.c,v 1.12 2000/07/03 13:29:16 dwmw2 Exp $
-*/
-
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <asm/io.h>
-#include <asm/byteorder.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-
-#include <linux/mtd/map.h>
-#include <linux/mtd/cfi.h>
-
-
-struct mtd_info *cfi_probe(struct map_info *);
-
-static void print_cfi_ident(struct cfi_ident *);
-static void check_cmd_set(struct map_info *, int, unsigned long);
-static struct cfi_private *cfi_cfi_probe(struct map_info *);
-
-static const char im_name[] = "cfi_probe";
-
-/* This routine is made available to other mtd code via
- * inter_module_register.  It must only be accessed through
- * inter_module_get which will bump the use count of this module.  The
- * addresses passed back in mtd are valid as long as the use count of
- * this module is non-zero, i.e. between inter_module_get and
- * inter_module_put.  Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
- */
-struct mtd_info *cfi_probe(struct map_info *map)
-{
-	struct mtd_info *mtd = NULL;
-	struct cfi_private *cfi;
-	/* First probe the map to see if we have CFI stuff there. */
-	cfi = cfi_cfi_probe(map);
-	
-	if (!cfi)
-		return NULL;
-
-	map->fldrv_priv = cfi;
-	map->im_name = im_name;
-
-	/* OK we liked it. Now find a driver for the command set it talks */
-
-	check_cmd_set(map, 1, cfi->chips[0].start); /* First the primary cmdset */
-	check_cmd_set(map, 0, cfi->chips[0].start); /* Then the secondary */
-	
-	/* check_cmd_set() will have used inter_module_get to increase
-	   the use count of the module which provides the command set 
-	   driver. If we're quitting, we have to decrease it again.
-	*/
-
-	if(cfi->cmdset_setup) {
-		mtd = cfi->cmdset_setup(map);
-		
-		if (mtd)
-			return mtd;
-		inter_module_put(cfi->im_name);
-	}
-	printk("No supported Vendor Command Set found\n");
-	
-	kfree(cfi);
-	map->fldrv_priv = NULL;
-	return NULL;
-
-}
-
-static int cfi_probe_new_chip(struct map_info *map, unsigned long base,
-			      struct flchip *chips, struct cfi_private *cfi)
-{
-	switch (map->buswidth) {
-		
-	case 1: {
-		unsigned char tmp = map->read8(map, base + 0x55);
-
-		/* If there's a device there, put it in Query Mode */
-		map->write8(map, 0x98, base+0x55);
-		
-		if (map->read8(map,base+0x10) == 'Q' &&
-		    map->read8(map,base+0x11) == 'R' &&
-		    map->read8(map,base+0x12) == 'Y') {
-			printk("%s: Found a CFI device at 0x%lx in 8 bit mode\n", map->name, base);
-			if (chips) {
-				/* Check previous chips for aliases */
-				printk("FIXME: Do alias check at line %d of cfi_probe.c\n", __LINE__);
-				/* Put it back into Read Mode */
-				map->write8(map, 0x98, base+0x55);
-			}
-			return 1;
-		} else {
-			if (map->read8(map, base + 0x55) == 0x98) {
-				/* It looks like RAM. Put back the stuff we overwrote */
-				map->write8(map, tmp, base+0x55);
-			}
-			return 0;
-		}
-	}
-	
-	case 2: {
-		__u16 tmp = map->read16(map, base + 0xaa);
-		
-		/* If there's a device there, put it into Query Mode */
-		map->write16(map, 0x9898, base+0xAA);
-		
-		if (map->read16(map, base+0x20) == cpu_to_le16(0x0051) &&
-		    map->read16(map, base+0x22) == cpu_to_le16(0x0052) &&
-		    map->read16(map, base+0x24) == cpu_to_le16(0x0059)) {
-			printk("%s: Found a CFI device at 0x%lx in 16 bit mode\n", map->name, base);
-			if (chips) {
-				/* Check previous chips for aliases */
-				int i;
-
-				for (i=0; i < cfi->numchips; i++) {
-					/* This chip should be in read mode if it's one 
-					   we've already touched. */
-					if (map->read16(map, chips[i].start+0x20) == cpu_to_le16(0x0051) &&
-					    map->read16(map, chips[i].start+0x22) == cpu_to_le16(0x0052) &&
-					    map->read16(map, chips[i].start+0x24) == cpu_to_le16(0x0059)){
-						/* Either the old chip has got 'Q''R''Y' in a most
-						   unfortunate place, or it's an alias of the new
-						   chip. Double-check that it's in read mode, and check. */
-						map->write16(map, 0xffff, chips[i].start+0x20);
-						if (map->read16(map, chips[i].start+0x20) == cpu_to_le16(0x0051) &&
-						    map->read16(map, chips[i].start+0x22) == cpu_to_le16(0x0052) &&
-						    map->read16(map, chips[i].start+0x24) == cpu_to_le16(0x0059)) {
-							/* Yes it's got QRY for data. Most unfortunate. 
-							   Stick the old one in read mode too. */
-							map->write16(map, 0xffff, base);
-							if (map->read16(map, base+0x20) == cpu_to_le16(0x0051) &&
-							    map->read16(map, base+0x22) == cpu_to_le16(0x0052) &&
-							    map->read16(map, base+0x24) == cpu_to_le16(0x0059)) {
-								/* OK, so has the new one. Assume it's an alias */
-								printk("T'was probably an alias for the chip at 0x%lx\n", chips[i].start);
-								return 1;
-							} /* else no, they're different, fall through. */
-						} else {
-							/* No the old one hasn't got QRY for data. Therefore,
-							   it's an alias of the new one. */
-							map->write16(map, 0xffff, base+0xaa);
-							/* Just to be paranoid. */
-							map->write16(map, 0xffff, chips[i].start+0xaa);
-							printk("T'was an alias for the chip at 0x%lx\n", chips[i].start);
-							return 1;
-						}
-					} 
-					/* No, the old one didn't look like it's in query mode. Next. */
-				}
-				
-				/* OK, if we got to here, then none of the previous chips appear to
-				   be aliases for the current one. */
-				if (cfi->numchips == MAX_CFI_CHIPS) {
-					printk("%s: Too many flash chips detected. Increase MAX_CFI_CHIPS from %d.\n", map->name, MAX_CFI_CHIPS);
-					/* Doesn't matter about resetting it to Read Mode - we're not going to talk to it anyway */
-					return 1;
-				}
-				printk("Not an alias. Adding\n");
-				chips[cfi->numchips].start = base;
-				chips[cfi->numchips].state = FL_READY;
-				chips[cfi->numchips].mutex = &chips[cfi->numchips]._spinlock;
-				cfi->numchips++;
-
-				/* Put it back into Read Mode */
-				map->write16(map, 0xffff, base+0xaa);
-			}
-			
-			return 1;
-		}	
-		else if (map->read16(map, base+0x20) == 0x5151 &&
-			 map->read16(map, base+0x22) == 0x5252 &&
-			 map->read16(map, base+0x24) == 0x5959) {
-			printk("%s: Found a coupled pair of CFI devices at %lx in 8 bit mode\n",
-			       map->name, base);
-			if (chips) {
-				/* Check previous chips for aliases */
-				printk("FIXME: Do alias check at line %d of cfi_probe.c\n", __LINE__);
-
-				/* Put it back into Read Mode */
-				map->write16(map, 0xffff, base+0xaa);
-			}
-
-			return 2;
-		} else {
-			if (map->read16(map, base+0xaa) == 0x9898) {
-				/* It looks like RAM. Put back the stuff we overwrote */
-				map->write16(map, tmp, base+0xaa);
-			}
-			return 0;
-		}
-	}
-
-		
-	case 4: {
-		__u32 tmp = map->read32(map, base+0x154);
-		
-		/* If there's a device there, put it into Query Mode */
-		map->write32(map, 0x98989898, base+0x154);
-		
-		if (map->read32(map, base+0x40) == cpu_to_le32(0x00000051) &&
-		    map->read32(map, base+0x44) == cpu_to_le32(0x00000052) &&
-		    map->read32(map, base+0x48) == cpu_to_le32(0x00000059)) {
-				/* This isn't actually in the CFI spec - only x8 and x16 are. */
-			printk("%s: Found a CFI device at %lx in 32 bit mode\n", map->name, base);
-			if (chips) {
-				/* Check previous chips for aliases */
-				printk("FIXME: Do alias check at line %d of cfi_probe.c\n", __LINE__);
-
-				/* Put it back into read mode */
-				map->write32(map, 0xffffffff, base+0x154);
-			}
-			return 1;
-		} 
-		else if (map->read32(map, base+0x40) == cpu_to_le32(0x00510051) &&
-			 map->read32(map, base+0x44) == cpu_to_le32(0x00520052) &&
-			 map->read32(map, base+0x48) == cpu_to_le32(0x00590059)) {
-			printk("%s: Found a coupled pair of CFI devices at location %lx in 16 bit mode\n", map->name, base);
-			if (chips) {
-				/* Check previous chips for aliases */
-				printk("FIXME: Do alias check at line %d of cfi_probe.c\n", __LINE__);
-
-				/* Put it back into read mode */
-				map->write32(map, 0xffffffff, base+0x154);
-			}
-			return 2;
-		}
-		else if (map->read32(map, base+0x40) == 0x51515151 &&
-			 map->read32(map, base+0x44) == 0x52525252 &&
-			 map->read32(map, base+0x48) == 0x59595959) {
-			printk("%s: Found four side-by-side CFI devices at location %lx in 8 bit mode\n", map->name, base);
-			if (chips) {
-				/* Check previous chips for aliases */
-				printk("FIXME: Do alias check at line %d of cfi_probe.c\n", __LINE__);
-
-				/* Put it back into read mode */
-				map->write32(map, 0xffffffff, base+0x154);
-			}
-			return 4;
-		} else {
-			if (map->read32(map, base+0x154) == 0x98989898) {
-				/* It looks like RAM. Put back the stuff we overwrote */
-				map->write32(map, tmp, base+0x154);
-			}
-			return 0;
-		}
-	}	
-	default:
-		printk(KERN_WARNING "cfi_probe called with strange buswidth %d\n", map->buswidth);
-		return 0;
-	}
-}
-
-static struct cfi_private *cfi_cfi_probe(struct map_info *map)
-{
-	unsigned long base=0;
-	struct cfi_private cfi;
-	struct cfi_private *retcfi;
-	struct flchip chip[MAX_CFI_CHIPS];
-	int i;
-
-	memset(&cfi, 0, sizeof(cfi));
-
-	/* The first invocation (with chips == NULL) leaves the device in Query Mode */
-	cfi.interleave = cfi_probe_new_chip(map, 0, NULL, NULL);
-
-	if (!cfi.interleave) {
-		printk("%s: Found no CFI device at location zero\n", map->name);
-		/* Doesn't appear to be CFI-compliant at all */
-		return NULL;
-	}
-
-	/* Read the Basic Query Structure from the device */
-
-	for (i=0; i<sizeof(struct cfi_ident); i++) {
-		((unsigned char *)&cfi.cfiq)[i] = map->read8(map,base + ((0x10 + i)*map->buswidth));
-	}
-
-	/* Do any necessary byteswapping */
-	cfi.cfiq.P_ID = le16_to_cpu(cfi.cfiq.P_ID);
-	cfi.cfiq.P_ADR = le16_to_cpu(cfi.cfiq.P_ADR);
-	cfi.cfiq.A_ID = le16_to_cpu(cfi.cfiq.A_ID);
-	cfi.cfiq.A_ADR = le16_to_cpu(cfi.cfiq.A_ADR);
-	cfi.cfiq.InterfaceDesc = le16_to_cpu(cfi.cfiq.InterfaceDesc);
-	cfi.cfiq.MaxBufWriteSize = le16_to_cpu(cfi.cfiq.MaxBufWriteSize);
-	
-#if 1
-	/* Dump the information therein */
-	print_cfi_ident(&cfi.cfiq);
-
-	for (i=0; i<cfi.cfiq.NumEraseRegions; i++) {
-		__u16 EraseRegionInfoNum = (map->read8(map,base + ((0x2d + (4*i))*map->buswidth))) + 
-			(((map->read8(map,(0x2e + (4*i))*map->buswidth)) << 8));
-		__u16 EraseRegionInfoSize = (map->read8(map, base + ((0x2f + (4*i))*map->buswidth))) + 
-			(map->read8(map, base + ((0x30 + (4*i))*map->buswidth)) << 8);
-		
-		printk("  Erase Region #%d: BlockSize 0x%4.4X bytes, %d blocks\n",
-		       i, EraseRegionInfoSize * 256, EraseRegionInfoNum+1);
-	}
-	
-	printk("\n");
-#endif	
-
-	/* Switch the chip back into Read Mode, to make the alias detection work */
-	switch(map->buswidth) {
-	case 1:
-		map->write8(map, 0xff, 0x55);
-		break;
-	case 2:
-		map->write16(map, 0xffff, 0xaa);
-		break;
-	case 4:
-		map->write32(map, 0xffffffff, 0x154);
-		break;
-	}
-
-	/* OK. We've worked out what it is and we're happy with it. Now see if there are others */
-
-	chip[0].start = 0;
-	chip[0].state = FL_READY;
-	chip[0].mutex = &chip[0]._spinlock;
-
-	cfi.chipshift =  cfi.cfiq.DevSize;
-	cfi.numchips = 1;
-
-	if (!cfi.chipshift) {
-		printk("cfi.chipsize is zero. This is bad. cfi.cfiq.DevSize is %d\n", cfi.cfiq.DevSize);
-		return NULL;
-	}
-
-	for (base = (1<<cfi.chipshift); base < map->size; base += (1<<cfi.chipshift))
-		cfi_probe_new_chip(map, base, &chip[0], &cfi);
-
-	retcfi = kmalloc(sizeof(struct cfi_private) + cfi.numchips * sizeof(struct flchip), GFP_KERNEL);
-
-	if (!retcfi)
-		return NULL;
-
-	memcpy(retcfi, &cfi, sizeof(cfi));
-	memcpy(&retcfi->chips[0], chip, sizeof(struct flchip) * cfi.numchips);
-	for (i=0; i< retcfi->numchips; i++) {
-		init_waitqueue_head(&retcfi->chips[i].wq);
-		spin_lock_init(&retcfi->chips[i]._spinlock);
-	}
-	return retcfi;
-}
-
-static char *vendorname(__u16 vendor) 
-{
-	switch (vendor) {
-	case P_ID_NONE:
-		return "None";
-		
-	case P_ID_INTEL_EXT:
-		return "Intel/Sharp Extended";
-		
-	case P_ID_AMD_STD:
-		return "AMD/Fujitsu Standard";
-		
-	case P_ID_INTEL_STD:
-		return "Intel/Sharp Standard";
-		
-	case P_ID_AMD_EXT:
-		return "AMD/Fujitsu Extended";
-		
-	case P_ID_MITSUBISHI_STD:
-		return "Mitsubishi Standard";
-		
-	case P_ID_MITSUBISHI_EXT:
-		return "Mitsubishi Extended";
-		
-	case P_ID_RESERVED:
-		return "Not Allowed / Reserved for Future Use";
-		
-	default:
-		return "Unknown";
-	}
-}
-
-		
-static void print_cfi_ident(struct cfi_ident *cfip)
-{
-	if (cfip->qry[0] != 'Q' || cfip->qry[1] != 'R' || cfip->qry[2] != 'Y') {
-		printk("Invalid CFI ident structure.\n");
-		return;
-	}	
-		
-	printk("Primary Vendor Command Set: %4.4X (%s)\n", cfip->P_ID, vendorname(cfip->P_ID));
-	if (cfip->P_ADR)
-		printk("Primary Algorithm Table at %4.4X\n", cfip->P_ADR);
-	else
-		printk("No Primary Algorithm Table\n");
-	
-	printk("Alternative Vendor Command Set: %4.4X (%s)\n", cfip->A_ID, vendorname(cfip->A_ID));
-	if (cfip->A_ADR)
-		printk("Alternate Algorithm Table at %4.4X\n", cfip->A_ADR);
-	else
-		printk("No Alternate Algorithm Table\n");
-		
-		
-	printk("Vcc Minimum: %x.%x V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf);
-	printk("Vcc Maximum: %x.%x V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf);
-	if (cfip->VppMin) {
-		printk("Vpp Minimum: %x.%x V\n", cfip->VppMin >> 4, cfip->VppMin & 0xf);
-		printk("Vpp Maximum: %x.%x V\n", cfip->VppMax >> 4, cfip->VppMax & 0xf);
-	}
-	else
-		printk("No Vpp line\n");
-	
-	printk("Typical byte/word write timeout: %d µs\n", 1<<cfip->WordWriteTimeoutTyp);
-	printk("Maximum byte/word write timeout: %d µs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp));
-	
-	if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) {
-		printk("Typical full buffer write timeout: %d µs\n", 1<<cfip->BufWriteTimeoutTyp);
-		printk("Maximum full buffer write timeout: %d µs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp));
-	}
-	else
-		printk("Full buffer write not supported\n");
-	
-	printk("Typical block erase timeout: %d µs\n", 1<<cfip->BlockEraseTimeoutTyp);
-	printk("Maximum block erase timeout: %d µs\n", (1<<cfip->BlockEraseTimeoutMax) * (1<<cfip->BlockEraseTimeoutTyp));
-	if (cfip->ChipEraseTimeoutTyp || cfip->ChipEraseTimeoutMax) {
-		printk("Typical chip erase timeout: %d µs\n", 1<<cfip->ChipEraseTimeoutTyp); 
-		printk("Maximum chip erase timeout: %d µs\n", (1<<cfip->ChipEraseTimeoutMax) * (1<<cfip->ChipEraseTimeoutTyp));
-	}
-	else
-		printk("Chip erase not supported\n");
-	
-	printk("Device size: 0x%X bytes (%d Mb)\n", 1 << cfip->DevSize, 1<< (cfip->DevSize - 20));
-	printk("Flash Device Interface description: 0x%4.4X\n", cfip->InterfaceDesc);
-	switch(cfip->InterfaceDesc) {
-	case 0:
-		printk("  - x8-only asynchronous interface\n");
-		break;
-		
-	case 1:
-		printk("  - x16-only asynchronous interface\n");
-		break;
-		
-	case 2:
-		printk("  - supports x8 and x16 via BYTE# with asynchronous interface\n");
-		break;
-		
-	case 3:
-		printk("  - x32-only asynchronous interface\n");
-		break;
-		
-	case 65535:
-		printk("  - Not Allowed / Reserved\n");
-		break;
-		
-	default:
-		printk("  - Unknown\n");
-		break;
-	}
-	
-	printk("Max. bytes in buffer write: 0x%x\n", 1<< cfip->MaxBufWriteSize);
-	printk("Number of Erase Block Regions: %d\n", cfip->NumEraseRegions);
-	
-}
-
-static void check_cmd_set(struct map_info *map, int primary, unsigned long base)
-{
-	__u16 adr;
-	struct cfi_private *cfi = map->fldrv_priv;
-	__u16 type = primary?cfi->cfiq.P_ID:cfi->cfiq.A_ID;
-	char probename[32];
-	void (*probe_function)(struct map_info *, int, unsigned long);
-	
-	if (type == P_ID_NONE || type == P_ID_RESERVED)
-		return;
-	
-	sprintf(probename, "cfi_cmdset_%4.4X", type);
-	
-	probe_function = inter_module_get_request(probename, probename);
-	if (probe_function) {
-		(*probe_function)(map, primary, base);
-		return;
-	}
-
-	/* This was a command set we don't know about. Print only the basic info */
-	adr = primary?cfi->cfiq.P_ADR:cfi->cfiq.A_ADR;
-	
-	if (!adr) {
-		printk(" No Extended Query Table\n");
-	}
-	else if (map->read8(map,base+(adr*map->buswidth)) != (primary?'P':'A') ||
-		 map->read8(map,base+((adr+1)*map->buswidth)) != (primary?'R':'L') ||
-		 map->read8(map,base+((adr+2)*map->buswidth)) != (primary?'I':'T')) {
-		printk ("Invalid Extended Query Table at %4.4X: %2.2X %2.2X %2.2X\n",
-			adr,
-			map->read8(map,base+(adr*map->buswidth)),
-			map->read8(map,base+((adr+1)*map->buswidth)),
-			map->read8(map,base+((adr+2)*map->buswidth)));
-	}
-	else {
-		printk(" Extended Query Table version %c.%c\n",
-		       map->read8(map,base+((adr+3)*map->buswidth)), 
-		       map->read8(map,base+((adr+4)*map->buswidth)));
-	}
-}
-
-static int __init cfi_probe_init(void)
-{
-	inter_module_register(im_name, THIS_MODULE, &cfi_probe);
-	return 0;
-}
-
-static void __exit cfi_probe_exit(void)
-{
-	inter_module_unregister(im_name);
-}
-
-module_init(cfi_probe_init);
-module_exit(cfi_probe_exit);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/chips/Config.in linux/drivers/mtd/chips/Config.in
--- v2.4.5/linux/drivers/mtd/chips/Config.in	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/chips/Config.in	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,42 @@
+# drivers/mtd/chips/Config.in
+
+# $Id: Config.in,v 1.4 2001/05/14 09:48:12 dwmw2 Exp $
+
+mainmenu_option next_comment
+
+comment 'RAM/ROM/Flash chip drivers'
+
+dep_tristate '  Common Flash Interface (CFI) support' CONFIG_MTD_CFI $CONFIG_MTD
+if [ "$CONFIG_MTD_CFI" = "y" -o "$CONFIG_MTD_CFI" = "m" ]; then
+   bool '  CFI Virtual erase regions (EXPERIMENTAL)' CONFIG_MTD_CFI_VIRTUAL_ER 
+   bool '  CFI Advanced configuration options' CONFIG_MTD_CFI_ADV_OPTIONS
+   if [ "$CONFIG_MTD_CFI_ADV_OPTIONS" = "y" ]; then
+     choice 'Flash cmd/query data swapping'			\
+	"NO			CONFIG_MTD_CFI_NOSWAP		\
+	 BIG_ENDIAN_BYTE	CONFIG_MTD_CFI_BE_BYTE_SWAP	\
+	 LITTLE_ENDIAN_BYTE	CONFIG_MTD_CFI_LE_BYTE_SWAP	\
+	 LART_ENDIAN_BYTE	CONFIG_MTD_CFI_LART_BIT_SWAP"	NO
+     bool '  Specific CFI Flash geometry selection' CONFIG_MTD_CFI_GEOMETRY
+     if [ "$CONFIG_MTD_CFI_GEOMETRY" = "y" ]; then
+       bool '    Support  8-bit buswidth' CONFIG_MTD_CFI_B1
+       bool '    Support 16-bit buswidth' CONFIG_MTD_CFI_B2
+       bool '    Support 32-bit buswidth' CONFIG_MTD_CFI_B4
+	 if [ "$CONFIG_MTD_CFI_B1" = "y" ]; then
+	   define_bool CONFIG_MTD_CFI_I1 y
+         else
+           bool '    Support 1-chip flash interleave' CONFIG_MTD_CFI_I1
+	 fi
+       bool '    Support 2-chip flash interleave' CONFIG_MTD_CFI_I2
+       bool '    Support 4-chip flash interleave' CONFIG_MTD_CFI_I4
+     fi
+  fi
+fi
+dep_tristate '    CFI support for Intel/Sharp Basic/Extended Commands' CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_CFI
+dep_tristate '    CFI support for AMD/Fujitsu Standard Commands' CONFIG_MTD_CFI_AMDSTD $CONFIG_MTD_CFI
+dep_tristate '  AMD compatible flash chip support (non-CFI)' CONFIG_MTD_AMDSTD $CONFIG_MTD
+dep_tristate '  pre-CFI Sharp chip support' CONFIG_MTD_SHARP $CONFIG_MTD
+dep_tristate '  Support for RAM chips in bus mapping' CONFIG_MTD_RAM $CONFIG_MTD
+dep_tristate '  Support for ROM chips in bus mapping' CONFIG_MTD_ROM $CONFIG_MTD
+dep_tristate '  JEDEC device support' CONFIG_MTD_JEDEC $CONFIG_MTD
+
+endmenu
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/chips/Makefile linux/drivers/mtd/chips/Makefile
--- v2.4.5/linux/drivers/mtd/chips/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/chips/Makefile	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,27 @@
+#
+# linux/drivers/chips/Makefile
+#
+# $Id: Makefile,v 1.4 2001/06/09 19:57:57 dwmw2 Exp $
+
+O_TARGET	:= chipslink.o
+
+export-objs	:= chipreg.o
+
+#                       *** BIG UGLY NOTE ***
+#
+# The removal of get_module_symbol() and replacement with
+# inter_module_register() et al has introduced a link order dependency
+# here where previously there was none.  We now have to ensure that
+# the CFI command set drivers are linked before cfi_probe.o
+
+obj-$(CONFIG_MTD)		+= chipreg.o
+obj-$(CONFIG_MTD_AMDSTD)	+= amd_flash.o 
+obj-$(CONFIG_MTD_CFI)		+= cfi_probe.o cfi_jedec.o
+obj-$(CONFIG_MTD_CFI_AMDSTD)	+= cfi_cmdset_0002.o
+obj-$(CONFIG_MTD_CFI_INTELEXT)	+= cfi_cmdset_0001.o
+obj-$(CONFIG_MTD_JEDEC)		+= jedec.o
+obj-$(CONFIG_MTD_RAM)		+= map_ram.o
+obj-$(CONFIG_MTD_ROM)		+= map_rom.o
+obj-$(CONFIG_MTD_SHARP)		+= sharp.o
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/chips/amd_flash.c linux/drivers/mtd/chips/amd_flash.c
--- v2.4.5/linux/drivers/mtd/chips/amd_flash.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/chips/amd_flash.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,1251 @@
+/*
+ * MTD map driver for AMD compatible flash chips (non-CFI)
+ *
+ * Author: Jonas Holmberg <jonas.holmberg@axis.com>
+ *
+ * $Id: amd_flash.c,v 1.8 2001/06/02 14:47:16 dwmw2 Exp $
+ *
+ * Copyright (c) 2001 Axis Communications AB
+ *
+ * This file is under GPL.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/flashchip.h>
+
+/* There's no limit. It exists only to avoid realloc. */
+#define MAX_AMD_CHIPS 8
+
+#define DEVICE_TYPE_X8	(8 / 8)
+#define DEVICE_TYPE_X16	(16 / 8)
+#define DEVICE_TYPE_X32	(32 / 8)
+
+/* Addresses */
+#define ADDR_MANUFACTURER		0x0000
+#define ADDR_DEVICE_ID			0x0001
+#define ADDR_UNLOCK_1			0x0555
+#define ADDR_UNLOCK_2			0x02AA
+
+/* Commands */
+#define CMD_UNLOCK_DATA_1		0x00AA
+#define CMD_UNLOCK_DATA_2		0x0055
+#define CMD_MANUFACTURER_UNLOCK_DATA	0x0090
+#define CMD_UNLOCK_BYPASS_MODE		0x0020
+#define CMD_PROGRAM_UNLOCK_DATA		0x00A0
+#define CMD_RESET_DATA			0x00F0
+#define CMD_SECTOR_ERASE_UNLOCK_DATA	0x0080
+#define CMD_SECTOR_ERASE_UNLOCK_DATA_2	0x0030
+
+/* Manufacturers */
+#define MANUFACTURER_AMD	0x0001
+#define MANUFACTURER_FUJITSU	0x0004
+#define MANUFACTURER_ST		0x0020
+#define MANUFACTURER_SST	0x00BF
+#define MANUFACTURER_TOSHIBA	0x0098
+
+/* AMD */
+#define AM29F800BB	0x2258
+#define AM29F800BT	0x22D6
+#define AM29LV800BB	0x225B
+#define AM29LV800BT	0x22DA
+#define AM29LV160DT	0x22C4
+#define AM29LV160DB	0x2249
+
+/* Fujitsu */
+#define MBM29LV160TE	0x22C4
+#define MBM29LV160BE	0x2249
+
+/* ST - www.st.com */
+#define M29W800T	0x00D7
+#define M29W160DT	0x22C4
+#define M29W160DB	0x2249
+
+/* SST */
+#define SST39LF800	0x2781
+#define SST39LF160	0x2782
+
+/* Toshiba */
+#define TC58FVT160	0x00C2
+#define TC58FVB160	0x0043
+
+#define D6_MASK	0x40
+
+struct amd_flash_private {
+	int device_type;	
+	int interleave;	
+	int numchips;	
+	unsigned long chipshift;
+//	const char *im_name;
+	struct flchip chips[0];
+};
+
+struct amd_flash_info {
+	const __u16 mfr_id;
+	const __u16 dev_id;
+	const char *name;
+	const u_long size;
+	const int numeraseregions;
+	const struct mtd_erase_region_info regions[4];
+};
+
+
+
+static int amd_flash_read(struct mtd_info *, loff_t, size_t, size_t *,
+			  u_char *);
+static int amd_flash_write(struct mtd_info *, loff_t, size_t, size_t *,
+			   const u_char *);
+static int amd_flash_erase(struct mtd_info *, struct erase_info *);
+static void amd_flash_sync(struct mtd_info *);
+static int amd_flash_suspend(struct mtd_info *);
+static void amd_flash_resume(struct mtd_info *);
+static void amd_flash_destroy(struct mtd_info *);
+static struct mtd_info *amd_flash_probe(struct map_info *map);
+
+
+static struct mtd_chip_driver amd_flash_chipdrv = {
+	probe: amd_flash_probe,
+	destroy: amd_flash_destroy,
+	name: "amd_flash",
+	module: THIS_MODULE
+};
+
+
+
+static const char im_name[] = "amd_flash";
+
+
+
+static inline __u32 wide_read(struct map_info *map, __u32 addr)
+{
+	if (map->buswidth == 1) {
+		return map->read8(map, addr);
+	} else if (map->buswidth == 2) {
+		return map->read16(map, addr);
+	} else if (map->buswidth == 4) {
+		return map->read32(map, addr);
+        }
+
+	return 0;
+}
+
+static inline void wide_write(struct map_info *map, __u32 val, __u32 addr)
+{
+	if (map->buswidth == 1) {
+		map->write8(map, val, addr);
+	} else if (map->buswidth == 2) {
+		map->write16(map, val, addr);
+	} else if (map->buswidth == 4) {
+		map->write32(map, val, addr);
+	}
+}
+
+static inline __u32 make_cmd(struct map_info *map, __u32 cmd)
+{
+	const struct amd_flash_private *private = map->fldrv_priv;
+	if ((private->interleave == 2) &&
+	    (private->device_type == DEVICE_TYPE_X16)) {
+		cmd |= (cmd << 16);
+	}
+
+	return cmd;
+}
+
+static inline void send_unlock(struct map_info *map, unsigned long base)
+{
+	wide_write(map, (CMD_UNLOCK_DATA_1 << 16) | CMD_UNLOCK_DATA_1,
+		   base + (map->buswidth * ADDR_UNLOCK_1));
+	wide_write(map, (CMD_UNLOCK_DATA_2 << 16) | CMD_UNLOCK_DATA_2,
+		   base + (map->buswidth * ADDR_UNLOCK_2));
+}
+
+static inline void send_cmd(struct map_info *map, unsigned long base, __u32 cmd)
+{
+	send_unlock(map, base);
+	wide_write(map, make_cmd(map, cmd),
+		   base + (map->buswidth * ADDR_UNLOCK_1));
+}
+
+static inline void send_cmd_to_addr(struct map_info *map, unsigned long base,
+				    __u32 cmd, unsigned long addr)
+{
+	send_unlock(map, base);
+	wide_write(map, make_cmd(map, cmd), addr);
+}
+
+static inline int flash_is_busy(struct map_info *map, unsigned long addr,
+				int interleave)
+{
+
+	if ((interleave == 2) && (map->buswidth == 4)) {
+		__u32 read1, read2;
+
+		read1 = wide_read(map, addr);
+		read2 = wide_read(map, addr);
+
+		return (((read1 >> 16) & D6_MASK) !=
+			((read2 >> 16) & D6_MASK)) ||
+		       (((read1 & 0xffff) & D6_MASK) !=
+			((read2 & 0xffff) & D6_MASK));
+	}
+
+	return ((wide_read(map, addr) & D6_MASK) !=
+		(wide_read(map, addr) & D6_MASK));
+}
+
+
+
+/*
+ * Reads JEDEC manufacturer ID and device ID and returns the index of the first
+ * matching table entry (-1 if not found or alias for already found chip).
+ */ 
+static int probe_new_chip(struct mtd_info *mtd, __u32 base,
+			  struct flchip *chips,
+			  struct amd_flash_private *private,
+			  const struct amd_flash_info *table, int table_size)
+{
+	__u32 mfr_id, dev_id;
+	struct map_info *map = mtd->priv;
+	struct amd_flash_private temp;
+	int i;
+
+	temp.device_type = DEVICE_TYPE_X16;	// Assume X16 (FIXME)
+	temp.interleave = 2;
+	map->fldrv_priv = &temp;
+
+	/* Enter autoselect mode. */
+	send_cmd(map, base, CMD_RESET_DATA);
+	send_cmd(map, base, CMD_MANUFACTURER_UNLOCK_DATA);
+
+	mfr_id = wide_read(map, base + (map->buswidth * ADDR_MANUFACTURER));
+	dev_id = wide_read(map, base + (map->buswidth * ADDR_DEVICE_ID));
+
+	if ((map->buswidth == 4) && ((mfr_id >> 16) == (mfr_id & 0xffff)) &&
+	    ((dev_id >> 16) == (dev_id & 0xffff))) {
+		mfr_id = mfr_id & 0xffff;
+		dev_id = dev_id & 0xffff;
+	} else {
+		temp.interleave = 1;
+	}
+
+	for (i = 0; i < table_size; i++) {
+		if ((mfr_id == table[i].mfr_id) &&
+		    (dev_id == table[i].dev_id)) {
+			if (chips) {
+				int j;
+
+				/* Is this an alias for an already found chip?
+				 * In that case that chip should be in
+				 * autoselect mode now.
+				 */
+				for (j = 0; j < private->numchips; j++) {
+					if ((wide_read(map, chips[j].start +
+							    (map->buswidth *
+							     ADDR_MANUFACTURER))
+					     == mfr_id)
+					    &&
+					    (wide_read(map, chips[j].start +
+					    		    (map->buswidth *
+							     ADDR_DEVICE_ID))
+					     == dev_id)) {
+
+						/* Exit autoselect mode. */
+						send_cmd(map, base,
+							 CMD_RESET_DATA);
+
+						return -1;
+					}
+				}
+
+				if (private->numchips == MAX_AMD_CHIPS) {
+					printk(KERN_WARNING
+					       "%s: Too many flash chips "
+					       "detected. Increase "
+					       "MAX_AMD_CHIPS from %d.\n",
+					       map->name, MAX_AMD_CHIPS);
+
+					return -1;
+				}
+
+				chips[private->numchips].start = base;
+				chips[private->numchips].state = FL_READY;
+				chips[private->numchips].mutex =
+					&chips[private->numchips]._spinlock;
+				private->numchips++;
+			}
+
+			printk("%s: Found %d x %ldMiB %s at 0x%x\n", map->name,
+			       temp.interleave, (table[i].size)/(1024*1024),
+			       table[i].name, base);
+
+			mtd->size += table[i].size * temp.interleave;
+			mtd->numeraseregions += table[i].numeraseregions;
+
+			break;
+		}
+	}
+
+	/* Exit autoselect mode. */
+	send_cmd(map, base, CMD_RESET_DATA);
+
+	if (i == table_size) {
+		printk(KERN_DEBUG "%s: unknown flash device at 0x%x, "
+		       "mfr id 0x%x, dev id 0x%x\n", map->name,
+		       base, mfr_id, dev_id);
+		map->fldrv_priv = NULL;
+
+		return -1;
+	}
+
+	private->device_type = temp.device_type;
+	private->interleave = temp.interleave;
+
+	return i;
+}
+
+
+
+static struct mtd_info *amd_flash_probe(struct map_info *map)
+{
+	/* Keep this table on the stack so that it gets deallocated after the
+	 * probe is done.
+	 */
+	const struct amd_flash_info table[] = {
+	{
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV160DT,
+		name: "AMD AM29LV160DT",
+		size: 0x00200000,
+		numeraseregions: 4,
+		regions: {
+			{ offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
+			{ offset: 0x1F0000, erasesize: 0x08000, numblocks:  1 },
+			{ offset: 0x1F8000, erasesize: 0x02000, numblocks:  2 },
+			{ offset: 0x1FC000, erasesize: 0x04000, numblocks:  1 }
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV160DB,
+		name: "AMD AM29LV160DB",
+		size: 0x00200000,
+		numeraseregions: 4,
+		regions: {
+			{ offset: 0x000000, erasesize: 0x04000, numblocks:  1 },
+			{ offset: 0x004000, erasesize: 0x02000, numblocks:  2 },
+			{ offset: 0x008000, erasesize: 0x08000, numblocks:  1 },
+			{ offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
+		}
+	}, {
+		mfr_id: MANUFACTURER_TOSHIBA,
+		dev_id: TC58FVT160,
+		name: "Toshiba TC58FVT160",
+		size: 0x00200000,
+		numeraseregions: 4,
+		regions: {
+			{ offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
+			{ offset: 0x1F0000, erasesize: 0x08000, numblocks:  1 },
+			{ offset: 0x1F8000, erasesize: 0x02000, numblocks:  2 },
+			{ offset: 0x1FC000, erasesize: 0x04000, numblocks:  1 }
+		}
+	}, {
+		mfr_id: MANUFACTURER_FUJITSU,
+		dev_id: MBM29LV160TE,
+		name: "Fujitsu MBM29LV160TE",
+		size: 0x00200000,
+		numeraseregions: 4,
+		regions: {
+			{ offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
+			{ offset: 0x1F0000, erasesize: 0x08000, numblocks:  1 },
+			{ offset: 0x1F8000, erasesize: 0x02000, numblocks:  2 },
+			{ offset: 0x1FC000, erasesize: 0x04000, numblocks:  1 }
+		}
+	}, {
+		mfr_id: MANUFACTURER_TOSHIBA,
+		dev_id: TC58FVB160,
+		name: "Toshiba TC58FVB160",
+		size: 0x00200000,
+		numeraseregions: 4,
+		regions: {
+			{ offset: 0x000000, erasesize: 0x04000, numblocks:  1 },
+			{ offset: 0x004000, erasesize: 0x02000, numblocks:  2 },
+			{ offset: 0x008000, erasesize: 0x08000, numblocks:  1 },
+			{ offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
+		}
+	}, {
+		mfr_id: MANUFACTURER_FUJITSU,
+		dev_id: MBM29LV160BE,
+		name: "Fujitsu MBM29LV160BE",
+		size: 0x00200000,
+		numeraseregions: 4,
+		regions: {
+			{ offset: 0x000000, erasesize: 0x04000, numblocks:  1 },
+			{ offset: 0x004000, erasesize: 0x02000, numblocks:  2 },
+			{ offset: 0x008000, erasesize: 0x08000, numblocks:  1 },
+			{ offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV800BB,
+		name: "AMD AM29LV800BB",
+		size: 0x00100000,
+		numeraseregions: 4,
+		regions: {
+			{ offset: 0x000000, erasesize: 0x04000, numblocks:  1 },
+			{ offset: 0x004000, erasesize: 0x02000, numblocks:  2 },
+			{ offset: 0x008000, erasesize: 0x08000, numblocks:  1 },
+			{ offset: 0x010000, erasesize: 0x10000, numblocks: 15 }
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29F800BB,
+		name: "AMD AM29F800BB",
+		size: 0x00100000,
+		numeraseregions: 4,
+		regions: {
+			{ offset: 0x000000, erasesize: 0x04000, numblocks:  1 },
+			{ offset: 0x004000, erasesize: 0x02000, numblocks:  2 },
+			{ offset: 0x008000, erasesize: 0x08000, numblocks:  1 },
+			{ offset: 0x010000, erasesize: 0x10000, numblocks: 15 }
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV800BT,
+		name: "AMD AM29LV800BT",
+		size: 0x00100000,
+		numeraseregions: 4,
+		regions: {
+			{ offset: 0x000000, erasesize: 0x10000, numblocks: 15 },
+			{ offset: 0x0F0000, erasesize: 0x08000, numblocks:  1 },
+			{ offset: 0x0F8000, erasesize: 0x02000, numblocks:  2 },
+			{ offset: 0x0FC000, erasesize: 0x04000, numblocks:  1 }
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29F800BT,
+		name: "AMD AM29F800BT",
+		size: 0x00100000,
+		numeraseregions: 4,
+		regions: {
+			{ offset: 0x000000, erasesize: 0x10000, numblocks: 15 },
+			{ offset: 0x0F0000, erasesize: 0x08000, numblocks:  1 },
+			{ offset: 0x0F8000, erasesize: 0x02000, numblocks:  2 },
+			{ offset: 0x0FC000, erasesize: 0x04000, numblocks:  1 }
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV800BB,
+		name: "AMD AM29LV800BB",
+		size: 0x00100000,
+		numeraseregions: 4,
+		regions: {
+			{ offset: 0x000000, erasesize: 0x10000, numblocks: 15 },
+			{ offset: 0x0F0000, erasesize: 0x08000, numblocks:  1 },
+			{ offset: 0x0F8000, erasesize: 0x02000, numblocks:  2 },
+			{ offset: 0x0FC000, erasesize: 0x04000, numblocks:  1 }
+		}
+	}, {
+		mfr_id: MANUFACTURER_ST,
+		dev_id: M29W800T,
+		name: "ST M29W800T",
+		size: 0x00100000,
+		numeraseregions: 4,
+		regions: {
+			{ offset: 0x000000, erasesize: 0x10000, numblocks: 15 },
+			{ offset: 0x0F0000, erasesize: 0x08000, numblocks:  1 },
+			{ offset: 0x0F8000, erasesize: 0x02000, numblocks:  2 },
+			{ offset: 0x0FC000, erasesize: 0x04000, numblocks:  1 }
+		}
+	}, {
+		mfr_id: MANUFACTURER_ST,
+		dev_id: M29W160DT,
+		name: "ST M29W160DT",
+		size: 0x00200000,
+		numeraseregions: 4,
+		regions: {
+			{ offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
+			{ offset: 0x1F0000, erasesize: 0x08000, numblocks:  1 },
+			{ offset: 0x1F8000, erasesize: 0x02000, numblocks:  2 },
+			{ offset: 0x1FC000, erasesize: 0x04000, numblocks:  1 }
+		}
+	}, {
+		mfr_id: MANUFACTURER_ST,
+		dev_id: M29W160DB,
+		name: "ST M29W160DB",
+		size: 0x00200000,
+		numeraseregions: 4,
+		regions: {
+			{ offset: 0x000000, erasesize: 0x04000, numblocks:  1 },
+			{ offset: 0x004000, erasesize: 0x02000, numblocks:  2 },
+			{ offset: 0x008000, erasesize: 0x08000, numblocks:  1 },
+			{ offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
+		}
+	} 
+	};
+
+	struct mtd_info *mtd;
+	struct flchip chips[MAX_AMD_CHIPS];
+	int table_pos[MAX_AMD_CHIPS];
+	struct amd_flash_private temp;
+	struct amd_flash_private *private;
+	u_long size;
+	unsigned long base;
+	int i;
+	int reg_idx;
+	int offset;
+
+	mtd = (struct mtd_info*)kmalloc(sizeof(*mtd), GFP_KERNEL);
+	if (!mtd) {
+		printk(KERN_WARNING
+		       "%s: kmalloc failed for info structure\n", map->name);
+		return NULL;
+	}
+	memset(mtd, 0, sizeof(*mtd));
+	mtd->priv = map;
+
+	memset(&temp, 0, sizeof(temp));
+
+	printk("%s: Probing for AMD compatible flash...\n", map->name);
+
+	if ((table_pos[0] = probe_new_chip(mtd, 0, NULL, &temp, table,
+					   sizeof(table)/sizeof(table[0])))
+	    == -1) {
+		printk(KERN_WARNING
+		       "%s: Found no AMD compatible device at location zero\n",
+		       map->name);
+		kfree(mtd);
+
+		return NULL;
+	}
+
+	chips[0].start = 0;
+	chips[0].state = FL_READY;
+	chips[0].mutex = &chips[0]._spinlock;
+	temp.numchips = 1;
+	for (size = mtd->size; size > 1; size >>= 1) {
+		temp.chipshift++;
+	}
+	switch (temp.interleave) {
+		case 2:
+			temp.chipshift += 1;
+			break;
+		case 4:
+			temp.chipshift += 2;
+			break;
+	}
+
+	/* Find out if there are any more chips in the map. */
+	for (base = (1 << temp.chipshift);
+	     base < map->size;
+	     base += (1 << temp.chipshift)) {
+	     	int numchips = temp.numchips;
+		table_pos[numchips] = probe_new_chip(mtd, base, chips,
+			&temp, table, sizeof(table)/sizeof(table[0]));
+	}
+
+	mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) *
+				    mtd->numeraseregions, GFP_KERNEL);
+	if (!mtd->eraseregions) { 
+		printk(KERN_WARNING "%s: Failed to allocate "
+		       "memory for MTD erase region info\n", map->name);
+		kfree(mtd);
+		map->fldrv_priv = NULL;
+		return 0;
+	}
+
+	reg_idx = 0;
+	offset = 0;
+	for (i = 0; i < temp.numchips; i++) {
+		int dev_size;
+		int j;
+
+		dev_size = 0;
+		for (j = 0; j < table[table_pos[i]].numeraseregions; j++) {
+			mtd->eraseregions[reg_idx].offset = offset +
+				(table[table_pos[i]].regions[j].offset *
+				 temp.interleave);
+			mtd->eraseregions[reg_idx].erasesize =
+				table[table_pos[i]].regions[j].erasesize *
+				temp.interleave;
+			mtd->eraseregions[reg_idx].numblocks =
+				table[table_pos[i]].regions[j].numblocks;
+			if (mtd->erasesize <
+			    mtd->eraseregions[reg_idx].erasesize) {
+				mtd->erasesize =
+					mtd->eraseregions[reg_idx].erasesize;
+			}
+			dev_size += mtd->eraseregions[reg_idx].erasesize *
+				    mtd->eraseregions[reg_idx].numblocks;
+			reg_idx++;
+		}
+		offset += dev_size;
+	}
+	mtd->type = MTD_NORFLASH;
+	mtd->flags = MTD_CAP_NORFLASH;
+	mtd->name = map->name;
+	mtd->erase = amd_flash_erase;	
+	mtd->read = amd_flash_read;	
+	mtd->write = amd_flash_write;	
+	mtd->sync = amd_flash_sync;	
+	mtd->suspend = amd_flash_suspend;	
+	mtd->resume = amd_flash_resume;	
+
+	private = kmalloc(sizeof(*private) + (sizeof(struct flchip) *
+					      temp.numchips), GFP_KERNEL);
+	if (!private) {
+		printk(KERN_WARNING
+		       "%s: kmalloc failed for private structure\n", map->name);
+		kfree(mtd);
+		map->fldrv_priv = NULL;
+		return NULL;
+	}
+	memcpy(private, &temp, sizeof(temp));
+	memcpy(private->chips, chips,
+	       sizeof(struct flchip) * private->numchips);
+	for (i = 0; i < private->numchips; i++) {
+		init_waitqueue_head(&private->chips[i].wq);
+		spin_lock_init(&private->chips[i]._spinlock);
+	}
+
+	map->fldrv_priv = private;
+
+	map->fldrv = &amd_flash_chipdrv;
+	MOD_INC_USE_COUNT;
+
+	return mtd;
+}
+
+
+
+static inline int read_one_chip(struct map_info *map, struct flchip *chip,
+			       loff_t adr, size_t len, u_char *buf)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	unsigned long timeo = jiffies + HZ;
+
+retry:
+	spin_lock_bh(chip->mutex);
+
+	if (chip->state != FL_READY){
+		printk(KERN_INFO "%s: waiting for chip to read, state = %d\n",
+		       map->name, chip->state);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&chip->wq, &wait);
+                
+		spin_unlock_bh(chip->mutex);
+
+		schedule();
+		remove_wait_queue(&chip->wq, &wait);
+
+		if(signal_pending(current)) {
+			return -EINTR;
+		}
+
+		timeo = jiffies + HZ;
+
+		goto retry;
+	}	
+
+	adr += chip->start;
+
+	chip->state = FL_READY;
+
+	map->copy_from(map, buf, adr, len);
+
+	wake_up(&chip->wq);
+	spin_unlock_bh(chip->mutex);
+
+	return 0;
+}
+
+
+
+static int amd_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
+			  size_t *retlen, u_char *buf)
+{
+	struct map_info *map = mtd->priv;
+	struct amd_flash_private *private = map->fldrv_priv;
+	unsigned long ofs;
+	int chipnum;
+	int ret = 0;
+
+	if ((from + len) > mtd->size) {
+		printk(KERN_WARNING "%s: read request past end of device "
+		       "(0x%lx)\n", map->name, (unsigned long)from + len);
+
+		return -EINVAL;
+	}
+
+	/* Offset within the first chip that the first read should start. */
+	chipnum = (from >> private->chipshift);
+	ofs = from - (chipnum <<  private->chipshift);
+
+	*retlen = 0;
+
+	while (len) {
+		unsigned long this_len;
+
+		if (chipnum >= private->numchips) {
+			break;
+		}
+
+		if ((len + ofs - 1) >> private->chipshift) {
+			this_len = (1 << private->chipshift) - ofs;
+		} else {
+			this_len = len;
+		}
+
+		ret = read_one_chip(map, &private->chips[chipnum], ofs,
+				    this_len, buf);
+		if (ret) {
+			break;
+		}
+
+		*retlen += this_len;
+		len -= this_len;
+		buf += this_len;
+
+		ofs = 0;
+		chipnum++;
+	}
+
+	return ret;
+}
+
+
+
+static int write_one_word(struct map_info *map, struct flchip *chip,
+			  unsigned long adr, __u32 datum)
+{
+	unsigned long timeo = jiffies + HZ;
+	struct amd_flash_private *private = map->fldrv_priv;
+	DECLARE_WAITQUEUE(wait, current);
+	int ret = 0;
+	int times_left;
+
+retry:
+	spin_lock_bh(chip->mutex);
+
+	if (chip->state != FL_READY){
+		printk("%s: waiting for chip to write, state = %d\n",
+		       map->name, chip->state);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&chip->wq, &wait);
+                
+		spin_unlock_bh(chip->mutex);
+
+		schedule();
+		remove_wait_queue(&chip->wq, &wait);
+		printk(KERN_INFO "%s: woke up to write\n", map->name);
+		if(signal_pending(current))
+			return -EINTR;
+
+		timeo = jiffies + HZ;
+
+		goto retry;
+	}	
+
+	chip->state = FL_WRITING;
+
+	adr += chip->start;
+	ENABLE_VPP(map);
+	send_cmd(map, chip->start, CMD_PROGRAM_UNLOCK_DATA);
+	wide_write(map, datum, adr);
+
+	times_left = 500000;
+	while (times_left-- && flash_is_busy(map, chip->start,
+					     private->interleave)) {
+		if (current->need_resched) {
+			spin_unlock_bh(chip->mutex);
+			schedule();
+			spin_lock_bh(chip->mutex);
+		}
+	}
+
+	if (!times_left) {
+		printk(KERN_WARNING "%s: write to 0x%lx timed out!\n",
+		       map->name, adr);
+		ret = -EIO;
+	} else {
+		__u32 verify;
+		if ((verify = wide_read(map, adr)) != datum) {
+			printk(KERN_WARNING "%s: write to 0x%lx failed. "
+			       "datum = %x, verify = %x\n",
+			       map->name, adr, datum, verify);
+			ret = -EIO;
+		}
+	}
+
+	DISABLE_VPP(map);
+	chip->state = FL_READY;
+	wake_up(&chip->wq);
+	spin_unlock_bh(chip->mutex);
+
+	return ret;
+}
+
+
+
+static int amd_flash_write(struct mtd_info *mtd, loff_t to , size_t len,
+			   size_t *retlen, const u_char *buf)
+{
+	struct map_info *map = mtd->priv;
+	struct amd_flash_private *private = map->fldrv_priv;
+	int ret = 0;
+	int chipnum;
+	unsigned long ofs;
+	unsigned long chipstart;
+
+	*retlen = 0;
+	if (!len) {
+		return 0;
+	}
+
+	chipnum = to >> private->chipshift;
+	ofs = to  - (chipnum << private->chipshift);
+	chipstart = private->chips[chipnum].start;
+
+	/* If it's not bus-aligned, do the first byte write. */
+	if (ofs & (map->buswidth - 1)) {
+		unsigned long bus_ofs = ofs & ~(map->buswidth - 1);
+		int i = ofs - bus_ofs;
+		int n = 0;
+		u_char tmp_buf[4];
+		__u32 datum;
+
+		map->copy_from(map, tmp_buf,
+			       bus_ofs + private->chips[chipnum].start,
+			       map->buswidth);
+		while (len && i < map->buswidth)
+			tmp_buf[i++] = buf[n++], len--;
+
+		if (map->buswidth == 2) {
+			datum = *(__u16*)tmp_buf;
+		} else if (map->buswidth == 4) {
+			datum = *(__u32*)tmp_buf;
+		} else {
+			return -EINVAL;  /* should never happen, but be safe */
+		}
+
+		ret = write_one_word(map, &private->chips[chipnum], bus_ofs,
+				     datum);
+		if (ret) {
+			return ret;
+		}
+		
+		ofs += n;
+		buf += n;
+		(*retlen) += n;
+
+		if (ofs >> private->chipshift) {
+			chipnum++;
+			ofs = 0;
+			if (chipnum == private->numchips) {
+				return 0;
+			}
+		}
+	}
+	
+	/* We are now aligned, write as much as possible. */
+	while(len >= map->buswidth) {
+		__u32 datum;
+
+		if (map->buswidth == 1) {
+			datum = *(__u8*)buf;
+		} else if (map->buswidth == 2) {
+			datum = *(__u16*)buf;
+		} else if (map->buswidth == 4) {
+			datum = *(__u32*)buf;
+		} else {
+			return -EINVAL;
+		}
+
+		ret = write_one_word(map, &private->chips[chipnum], ofs, datum);
+
+		if (ret) {
+			return ret;
+		}
+
+		ofs += map->buswidth;
+		buf += map->buswidth;
+		(*retlen) += map->buswidth;
+		len -= map->buswidth;
+
+		if (ofs >> private->chipshift) {
+			chipnum++;
+			ofs = 0;
+			if (chipnum == private->numchips) {
+				return 0;
+			}
+			chipstart = private->chips[chipnum].start;
+		}
+	}
+
+	if (len & (map->buswidth - 1)) {
+		int i = 0, n = 0;
+		u_char tmp_buf[2];
+		__u32 datum;
+
+		map->copy_from(map, tmp_buf,
+			       ofs + private->chips[chipnum].start,
+			       map->buswidth);
+		while (len--) {
+			tmp_buf[i++] = buf[n++];
+		}
+
+		if (map->buswidth == 2) {
+			datum = *(__u16*)tmp_buf;
+		} else if (map->buswidth == 4) {
+			datum = *(__u32*)tmp_buf;
+		} else {
+			return -EINVAL;  /* should never happen, but be safe */
+		}
+
+		ret = write_one_word(map, &private->chips[chipnum], ofs, datum);
+
+		if (ret) {
+			return ret;
+		}
+		
+		(*retlen) += n;
+	}
+
+	return 0;
+}
+
+
+
+static inline int erase_one_block(struct map_info *map, struct flchip *chip,
+				  unsigned long adr, u_long size)
+{
+	unsigned long timeo = jiffies + HZ;
+	struct amd_flash_private *private = map->fldrv_priv;
+	DECLARE_WAITQUEUE(wait, current);
+
+retry:
+	spin_lock_bh(chip->mutex);
+
+	if (chip->state != FL_READY){
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&chip->wq, &wait);
+                
+		spin_unlock_bh(chip->mutex);
+
+		schedule();
+		remove_wait_queue(&chip->wq, &wait);
+
+		if (signal_pending(current)) {
+			return -EINTR;
+		}
+
+		timeo = jiffies + HZ;
+
+		goto retry;
+	}	
+
+	chip->state = FL_ERASING;
+
+	adr += chip->start;
+	ENABLE_VPP(map);
+	send_cmd(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA);
+	send_cmd_to_addr(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA_2, adr);
+	
+	timeo = jiffies + (HZ * 20);
+
+	spin_unlock_bh(chip->mutex);
+	schedule_timeout(HZ);
+	spin_lock_bh(chip->mutex);
+	
+	while (flash_is_busy(map, chip->start, private->interleave)) {
+
+		if (chip->state != FL_ERASING) {
+			/* Someone's suspended the erase. Sleep */
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			add_wait_queue(&chip->wq, &wait);
+			
+			spin_unlock_bh(chip->mutex);
+			printk(KERN_INFO "%s: erase suspended. Sleeping\n",
+			       map->name);
+			schedule();
+			remove_wait_queue(&chip->wq, &wait);
+			
+			if (signal_pending(current)) {
+				return -EINTR;
+			}
+			
+			timeo = jiffies + (HZ*2); /* FIXME */
+			spin_lock_bh(chip->mutex);
+			continue;
+		}
+
+		/* OK Still waiting */
+		if (time_after(jiffies, timeo)) {
+			chip->state = FL_READY;
+			spin_unlock_bh(chip->mutex);
+			printk(KERN_WARNING "%s: waiting for erase to complete "
+			       "timed out.\n", map->name);
+			DISABLE_VPP(map);
+
+			return -EIO;
+		}
+		
+		/* Latency issues. Drop the lock, wait a while and retry */
+		spin_unlock_bh(chip->mutex);
+
+		if (current->need_resched)
+			schedule();
+		else
+			udelay(1);
+		
+		spin_lock_bh(chip->mutex);
+	}
+
+	/* Verify every single word */
+	{
+		int address;
+		int error = 0;
+		__u8 verify;
+
+		for (address = adr; address < (adr + size); address++) {
+			if ((verify = map->read8(map, address)) != 0xFF) {
+				error = 1;
+				break;
+			}
+		}
+		if (error) {
+			chip->state = FL_READY;
+			spin_unlock_bh(chip->mutex);
+			printk(KERN_WARNING
+			       "%s: verify error at 0x%x, size %ld.\n",
+			       map->name, address, size);
+			DISABLE_VPP(map);
+
+			return -EIO;
+		}
+	}
+	
+	DISABLE_VPP(map);
+	chip->state = FL_READY;
+	wake_up(&chip->wq);
+	spin_unlock_bh(chip->mutex);
+
+	return 0;
+}
+
+
+
+static int amd_flash_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+	struct map_info *map = mtd->priv;
+	struct amd_flash_private *private = map->fldrv_priv;
+	unsigned long adr, len;
+	int chipnum;
+	int ret = 0;
+	int i;
+	int first;
+	struct mtd_erase_region_info *regions = mtd->eraseregions;
+
+	if (instr->addr > mtd->size) {
+		return -EINVAL;
+	}
+
+	if ((instr->len + instr->addr) > mtd->size) {
+		return -EINVAL;
+	}
+
+	/* Check that both start and end of the requested erase are
+	 * aligned with the erasesize at the appropriate addresses.
+	 */
+
+	i = 0;
+
+        /* Skip all erase regions which are ended before the start of
+           the requested erase. Actually, to save on the calculations,
+           we skip to the first erase region which starts after the
+           start of the requested erase, and then go back one.
+        */
+
+        while ((i < mtd->numeraseregions) &&
+	       (instr->addr >= regions[i].offset)) {
+               i++;
+	}
+        i--;
+
+	/* OK, now i is pointing at the erase region in which this
+	 * erase request starts. Check the start of the requested
+	 * erase range is aligned with the erase size which is in
+	 * effect here.
+	 */
+
+	if (instr->addr & (regions[i].erasesize-1)) {
+		return -EINVAL;
+	}
+
+	/* Remember the erase region we start on. */
+
+	first = i;
+
+	/* Next, check that the end of the requested erase is aligned
+	 * with the erase region at that address.
+	 */
+
+	while ((i < mtd->numeraseregions) && 
+	       ((instr->addr + instr->len) >= regions[i].offset)) {
+                i++;
+	}
+
+	/* As before, drop back one to point at the region in which
+	 * the address actually falls.
+	 */
+
+	i--;
+
+	if ((instr->addr + instr->len) & (regions[i].erasesize-1)) {
+                return -EINVAL;
+	}
+
+	chipnum = instr->addr >> private->chipshift;
+	adr = instr->addr - (chipnum << private->chipshift);
+	len = instr->len;
+
+	i = first;
+
+	while (len) {
+		ret = erase_one_block(map, &private->chips[chipnum], adr,
+				      regions[i].erasesize);
+
+		if (ret) {
+			return ret;
+		}
+
+		adr += regions[i].erasesize;
+		len -= regions[i].erasesize;
+
+		if ((adr % (1 << private->chipshift)) ==
+		    ((regions[i].offset + (regions[i].erasesize *
+		    			   regions[i].numblocks))
+		     % (1 << private->chipshift))) {
+			i++;
+		}
+
+		if (adr >> private->chipshift) {
+			adr = 0;
+			chipnum++;
+			if (chipnum >= private->numchips) {
+				break;
+			}
+		}
+	}
+		
+	instr->state = MTD_ERASE_DONE;
+	if (instr->callback) {
+		instr->callback(instr);
+	}
+	
+	return 0;
+}
+
+
+
+static void amd_flash_sync(struct mtd_info *mtd)
+{
+	struct map_info *map = mtd->priv;
+	struct amd_flash_private *private = map->fldrv_priv;
+	int i;
+	struct flchip *chip;
+	int ret = 0;
+	DECLARE_WAITQUEUE(wait, current);
+
+	for (i = 0; !ret && (i < private->numchips); i++) {
+		chip = &private->chips[i];
+
+	retry:
+		spin_lock_bh(chip->mutex);
+
+		switch(chip->state) {
+		case FL_READY:
+		case FL_STATUS:
+		case FL_CFI_QUERY:
+		case FL_JEDEC_QUERY:
+			chip->oldstate = chip->state;
+			chip->state = FL_SYNCING;
+			/* No need to wake_up() on this state change - 
+			 * as the whole point is that nobody can do anything
+			 * with the chip now anyway.
+			 */
+		case FL_SYNCING:
+			spin_unlock_bh(chip->mutex);
+			break;
+
+		default:
+			/* Not an idle state */
+			add_wait_queue(&chip->wq, &wait);
+			
+			spin_unlock_bh(chip->mutex);
+
+			schedule();
+
+		        remove_wait_queue(&chip->wq, &wait);
+			
+			goto retry;
+		}
+	}
+
+	/* Unlock the chips again */
+	for (i--; i >= 0; i--) {
+		chip = &private->chips[i];
+
+		spin_lock_bh(chip->mutex);
+		
+		if (chip->state == FL_SYNCING) {
+			chip->state = chip->oldstate;
+			wake_up(&chip->wq);
+		}
+		spin_unlock_bh(chip->mutex);
+	}
+}
+
+
+
+static int amd_flash_suspend(struct mtd_info *mtd)
+{
+printk("amd_flash_suspend(): not implemented!\n");
+	return -EINVAL;
+}
+
+
+
+static void amd_flash_resume(struct mtd_info *mtd)
+{
+printk("amd_flash_resume(): not implemented!\n");
+}
+
+
+
+static void amd_flash_destroy(struct mtd_info *mtd)
+{
+	struct map_info *map = mtd->priv;
+	struct amd_flash_private *private = map->fldrv_priv;
+	kfree(private);
+}
+
+int __init amd_flash_init(void)
+{
+	register_mtd_chip_driver(&amd_flash_chipdrv);
+	return 0;
+}
+
+void __exit amd_flash_exit(void)
+{
+	unregister_mtd_chip_driver(&amd_flash_chipdrv);
+}
+
+module_init(amd_flash_init);
+module_exit(amd_flash_exit);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/chips/cfi_cmdset_0001.c linux/drivers/mtd/chips/cfi_cmdset_0001.c
--- v2.4.5/linux/drivers/mtd/chips/cfi_cmdset_0001.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/chips/cfi_cmdset_0001.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,1636 @@
+/*
+ * Common Flash Interface support:
+ *   Intel Extended Vendor Command Set (ID 0x0001)
+ *
+ * (C) 2000 Red Hat. GPL'd
+ *
+ * $Id: cfi_cmdset_0001.c,v 1.80 2001/06/03 01:32:57 nico Exp $
+ *
+ * 
+ * 10/10/2000	Nicolas Pitre <nico@cam.org>
+ * 	- completely revamped method functions so they are aware and
+ * 	  independent of the flash geometry (buswidth, interleave, etc.)
+ * 	- scalability vs code size is completely set at compile-time
+ * 	  (see include/linux/mtd/cfi.h for selection)
+ *	- optimized write buffer method
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/cfi.h>
+#include <linux/mtd/compatmac.h>
+
+static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
+static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
+static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
+static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *);
+static void cfi_intelext_sync (struct mtd_info *);
+static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len);
+static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len);
+static int cfi_intelext_suspend (struct mtd_info *);
+static void cfi_intelext_resume (struct mtd_info *);
+
+static void cfi_intelext_destroy(struct mtd_info *);
+
+void cfi_cmdset_0001(struct map_info *, int, unsigned long);
+
+static struct mtd_info *cfi_intelext_setup (struct map_info *);
+
+static struct mtd_chip_driver cfi_intelext_chipdrv = {
+	probe: cfi_intelext_setup,
+	destroy: cfi_intelext_destroy,
+	name: "cfi_intel",
+	module: THIS_MODULE
+};
+
+/* #define DEBUG_LOCK_BITS */
+
+/* This routine is made available to other mtd code via
+ * inter_module_register.  It must only be accessed through
+ * inter_module_get which will bump the use count of this module.  The
+ * addresses passed back in cfi are valid as long as the use count of
+ * this module is non-zero, i.e. between inter_module_get and
+ * inter_module_put.  Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
+ */
+void cfi_cmdset_0001(struct map_info *map, int primary, unsigned long base)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
+	int i;
+	struct cfi_pri_intelext *extp;
+	int ofs_factor = cfi->interleave * cfi->device_type;
+
+	__u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
+
+	//printk(" Intel/Sharp Extended Query Table at 0x%4.4X\n", adr);
+
+	if (!adr)
+		return;
+
+	/* Switch it into Query Mode */
+	switch(CFIDEV_BUSWIDTH) {
+	case 1:
+		map->write8(map, 0x98, 0x55);
+		break;
+	case 2:
+		map->write16(map, 0x9898, 0xaa);
+		break;
+	case 4:
+		map->write32(map, 0x98989898, 0x154);
+		break;
+	}
+
+	extp = kmalloc(sizeof(*extp), GFP_KERNEL);
+	if (!extp) {
+		printk("Failed to allocate memory\n");
+		return;
+	}
+
+	/* Read in the Extended Query Table */
+	for (i=0; i<sizeof(*extp); i++) {
+		((unsigned char *)extp)[i] = 
+		    cfi_read_query(map, (base+((adr+i)*cfi->interleave*cfi->device_type)));
+	}
+
+	if (extp->MajorVersion != '1' || 
+	    (extp->MinorVersion < '0' || extp->MinorVersion > '2')) {
+		printk("  Unknown IntelExt Extended Query version %c.%c.\n",
+		       extp->MajorVersion, extp->MinorVersion);
+		kfree(extp);
+		return;
+	}
+
+	/* Do some byteswapping if necessary */
+	extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport);
+	extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask);
+
+	
+	/* Tell the user about it in lots of lovely detail */
+#if 0  
+	printk("  Feature/Command Support: %4.4X\n", extp->FeatureSupport);
+	printk("     - Chip Erase:         %s\n", extp->FeatureSupport&1?"supported":"unsupported");
+	printk("     - Suspend Erase:      %s\n", extp->FeatureSupport&2?"supported":"unsupported");
+	printk("     - Suspend Program:    %s\n", extp->FeatureSupport&4?"supported":"unsupported");
+	printk("     - Legacy Lock/Unlock: %s\n", extp->FeatureSupport&8?"supported":"unsupported");
+	printk("     - Queued Erase:       %s\n", extp->FeatureSupport&16?"supported":"unsupported");
+	printk("     - Instant block lock: %s\n", extp->FeatureSupport&32?"supported":"unsupported");
+	printk("     - Protection Bits:    %s\n", extp->FeatureSupport&64?"supported":"unsupported");
+	printk("     - Page-mode read:     %s\n", extp->FeatureSupport&128?"supported":"unsupported");
+	printk("     - Synchronous read:   %s\n", extp->FeatureSupport&256?"supported":"unsupported");
+	for (i=9; i<32; i++) {
+		if (extp->FeatureSupport & (1<<i)) 
+			printk("     - Unknown Bit %X:      supported\n", i);
+	}
+	
+	printk("  Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport);
+	printk("     - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported");
+	for (i=1; i<8; i++) {
+		if (extp->SuspendCmdSupport & (1<<i))
+			printk("     - Unknown Bit %X:               supported\n", i);
+	}
+	
+	printk("  Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask);
+	printk("     - Lock Bit Active:      %s\n", extp->BlkStatusRegMask&1?"yes":"no");
+	printk("     - Valid Bit Active:     %s\n", extp->BlkStatusRegMask&2?"yes":"no");
+	for (i=2; i<16; i++) {
+		if (extp->BlkStatusRegMask & (1<<i))
+			printk("     - Unknown Bit %X Active: yes\n",i);
+	}
+	
+	printk("  Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", 
+	       extp->VccOptimal >> 8, extp->VccOptimal & 0xf);
+	if (extp->VppOptimal)
+		printk("  Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", 
+		       extp->VppOptimal >> 8, extp->VppOptimal & 0xf);
+#endif	
+	/* OK. We like it. Take over the control of it. */
+
+	/* Switch it into Read Mode */
+	switch(CFIDEV_BUSWIDTH) {
+	case 1:
+		map->write8(map, 0xff, 0x55);
+		break;
+	case 2:
+		map->write16(map, 0xffff, 0xaa);
+		break;
+	case 4:
+		map->write32(map, 0xffffffff, 0x154);
+		break;
+	}
+
+
+	/* If there was an old setup function, decrease its use count */
+	if (map->fldrv)
+	  if(map->fldrv->module)
+	    __MOD_DEC_USE_COUNT(map->fldrv->module);
+	
+	if (cfi->cmdset_priv)
+		kfree(cfi->cmdset_priv);
+
+	for (i=0; i< cfi->numchips; i++) {
+		cfi->chips[i].word_write_time = 128;
+		cfi->chips[i].buffer_write_time = 128;
+		cfi->chips[i].erase_time = 1024;
+	}		
+		
+
+	map->fldrv = &cfi_intelext_chipdrv;
+	MOD_INC_USE_COUNT;
+
+	cfi->cmdset_priv = extp;
+
+#if 1 /* Does this work? */
+	cfi_send_gen_cmd(0x90, 0x55, base, map, cfi, cfi->device_type, NULL);
+
+	cfi->mfr = cfi_read_query(map, base);
+	cfi->id = cfi_read_query(map, base + ofs_factor);
+
+	printk("JEDEC ID: %2.2X %2.2X\n", cfi->mfr, cfi->id);
+#endif
+
+        cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
+	return;
+}
+
+static struct mtd_info *cfi_intelext_setup(struct map_info *map)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
+	struct mtd_info *mtd;
+	unsigned long offset = 0;
+	int i,j;
+	unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave;
+
+	mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
+	//printk("number of CFI chips: %d\n", cfi->numchips);
+
+	if (!mtd) {
+	  printk("Failed to allocate memory for MTD device\n");
+	  kfree(cfi->cmdset_priv);
+	  return NULL;
+	}
+
+	memset(mtd, 0, sizeof(*mtd));
+	mtd->priv = map;
+	mtd->type = MTD_NORFLASH;
+	mtd->size = devsize * cfi->numchips;
+
+	mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
+	mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) 
+			* mtd->numeraseregions, GFP_KERNEL);
+	if (!mtd->eraseregions) { 
+			printk("Failed to allocate memory for MTD erase region info\n");
+			kfree(cfi->cmdset_priv);
+			return NULL;
+	}
+	
+	for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
+		unsigned long ernum, ersize;
+		ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
+		ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1;
+
+		if (mtd->erasesize < ersize) {
+			mtd->erasesize = ersize;
+		}
+		for (j=0; j<cfi->numchips; j++) {
+			mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset;
+			mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize;
+			mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum;
+		}
+		offset += (ersize * ernum);
+		}
+
+		if (offset != devsize) {
+			/* Argh */
+			printk("Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize);
+			kfree(mtd->eraseregions);
+			kfree(cfi->cmdset_priv);
+			return NULL;
+		}
+
+		for (i=0; i<mtd->numeraseregions;i++){
+			printk("%d: offset=0x%x,size=0x%x,blocks=%d\n",
+			       i,mtd->eraseregions[i].offset,
+			       mtd->eraseregions[i].erasesize,
+			       mtd->eraseregions[i].numblocks);
+		}
+
+	/* Also select the correct geometry setup too */ 
+		mtd->erase = cfi_intelext_erase_varsize;
+	mtd->read = cfi_intelext_read;
+	if ( cfi->cfiq->BufWriteTimeoutTyp ) {
+		//printk( KERN_INFO"Using buffer write method\n" );
+		mtd->write = cfi_intelext_write_buffers;
+	} else {
+		//printk( KERN_INFO"Using word write method\n" );
+		mtd->write = cfi_intelext_write_words;
+	}
+	mtd->sync = cfi_intelext_sync;
+	mtd->lock = cfi_intelext_lock;
+	mtd->unlock = cfi_intelext_unlock;
+	mtd->suspend = cfi_intelext_suspend;
+	mtd->resume = cfi_intelext_resume;
+	mtd->flags = MTD_CAP_NORFLASH;
+	map->fldrv = &cfi_intelext_chipdrv;
+	MOD_INC_USE_COUNT;
+	mtd->name = map->name;
+	return mtd;
+}
+
+
+static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
+{
+	__u32 status, status_OK;
+	unsigned long timeo;
+	DECLARE_WAITQUEUE(wait, current);
+	int suspended = 0;
+	unsigned long cmd_addr;
+	struct cfi_private *cfi = map->fldrv_priv;
+
+	adr += chip->start;
+
+	/* Ensure cmd read/writes are aligned. */ 
+	cmd_addr = adr & ~(CFIDEV_BUSWIDTH-1); 
+
+	/* Let's determine this according to the interleave only once */
+	status_OK = CMD(0x80);
+
+	timeo = jiffies + HZ;
+ retry:
+	spin_lock_bh(chip->mutex);
+
+	/* Check that the chip's ready to talk to us.
+	 * If it's in FL_ERASING state, suspend it and make it talk now.
+	 */
+	switch (chip->state) {
+	case FL_ERASING:
+		cfi_write (map, CMD(0xb0), cmd_addr);
+		chip->oldstate = FL_ERASING;
+		chip->state = FL_ERASE_SUSPENDING;
+//		printk("Erase suspending at 0x%lx\n", cmd_addr);
+		for (;;) {
+			status = cfi_read(map, cmd_addr);
+			if ((status & status_OK) == status_OK)
+				break;
+			
+			if (time_after(jiffies, timeo)) {
+				/* Urgh */
+				cfi_write(map, CMD(0xd0), cmd_addr);
+				chip->state = FL_ERASING;
+				spin_unlock_bh(chip->mutex);
+				printk("Chip not ready after erase suspended\n");
+				return -EIO;
+			}
+
+			spin_unlock_bh(chip->mutex);
+			cfi_udelay(1);
+			spin_lock_bh(chip->mutex);
+		}
+
+		suspended = 1;
+		cfi_write(map, CMD(0xff), cmd_addr);
+		chip->state = FL_READY;
+		break;
+
+#if 0
+	case FL_WRITING:
+		/* Not quite yet */
+#endif
+
+	case FL_READY:
+		break;
+
+	case FL_CFI_QUERY:
+	case FL_JEDEC_QUERY:
+		cfi_write(map, CMD(0x70), cmd_addr);
+		chip->state = FL_STATUS;
+
+	case FL_STATUS:
+		status = cfi_read(map, cmd_addr);
+		if ((status & status_OK) == status_OK) {
+			cfi_write(map, CMD(0xff), cmd_addr);
+			chip->state = FL_READY;
+			break;
+		}
+		
+		/* Urgh. Chip not yet ready to talk to us. */
+		if (time_after(jiffies, timeo)) {
+			spin_unlock_bh(chip->mutex);
+			printk("waiting for chip to be ready timed out in read. WSM status = %x\n", status);
+			return -EIO;
+		}
+
+		/* Latency issues. Drop the lock, wait a while and retry */
+		spin_unlock_bh(chip->mutex);
+		cfi_udelay(1);
+		goto retry;
+
+	default:
+		/* Stick ourselves on a wait queue to be woken when
+		   someone changes the status */
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&chip->wq, &wait);
+		spin_unlock_bh(chip->mutex);
+		schedule();
+		remove_wait_queue(&chip->wq, &wait);
+		timeo = jiffies + HZ;
+		goto retry;
+	}
+
+	map->copy_from(map, buf, adr, len);
+
+	if (suspended) {
+		chip->state = chip->oldstate;
+		/* What if one interleaved chip has finished and the 
+		   other hasn't? The old code would leave the finished
+		   one in READY mode. That's bad, and caused -EROFS 
+		   errors to be returned from do_erase_oneblock because
+		   that's the only bit it checked for at the time.
+		   As the state machine appears to explicitly allow 
+		   sending the 0x70 (Read Status) command to an erasing
+		   chip and expecting it to be ignored, that's what we 
+		   do. */
+		cfi_write(map, CMD(0xd0), cmd_addr);
+		cfi_write(map, CMD(0x70), cmd_addr);		
+	}
+
+	wake_up(&chip->wq);
+	spin_unlock_bh(chip->mutex);
+	return 0;
+}
+
+static int cfi_intelext_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	unsigned long ofs;
+	int chipnum;
+	int ret = 0;
+
+	/* ofs: offset within the first chip that the first read should start */
+	chipnum = (from >> cfi->chipshift);
+	ofs = from - (chipnum <<  cfi->chipshift);
+
+	*retlen = 0;
+
+	while (len) {
+		unsigned long thislen;
+
+		if (chipnum >= cfi->numchips)
+			break;
+
+		if ((len + ofs -1) >> cfi->chipshift)
+			thislen = (1<<cfi->chipshift) - ofs;
+		else
+			thislen = len;
+
+		ret = do_read_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf);
+		if (ret)
+			break;
+
+		*retlen += thislen;
+		len -= thislen;
+		buf += thislen;
+		
+		ofs = 0;
+		chipnum++;
+	}
+	return ret;
+}
+
+static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, __u32 datum)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
+	__u32 status, status_OK;
+	unsigned long timeo;
+	DECLARE_WAITQUEUE(wait, current);
+	int z;
+
+	adr += chip->start;
+
+	/* Let's determine this according to the interleave only once */
+	status_OK = CMD(0x80);
+
+	timeo = jiffies + HZ;
+ retry:
+	spin_lock_bh(chip->mutex);
+
+	/* Check that the chip's ready to talk to us.
+	 * Later, we can actually think about interrupting it
+	 * if it's in FL_ERASING state.
+	 * Not just yet, though.
+	 */
+	switch (chip->state) {
+	case FL_READY:
+		break;
+		
+	case FL_CFI_QUERY:
+	case FL_JEDEC_QUERY:
+		cfi_write(map, CMD(0x70), adr);
+		chip->state = FL_STATUS;
+
+	case FL_STATUS:
+		status = cfi_read(map, adr);
+		if ((status & status_OK) == status_OK)
+			break;
+		
+		/* Urgh. Chip not yet ready to talk to us. */
+		if (time_after(jiffies, timeo)) {
+			spin_unlock_bh(chip->mutex);
+			printk("waiting for chip to be ready timed out in read\n");
+			return -EIO;
+		}
+
+		/* Latency issues. Drop the lock, wait a while and retry */
+		spin_unlock_bh(chip->mutex);
+		cfi_udelay(1);
+		goto retry;
+
+	default:
+		/* Stick ourselves on a wait queue to be woken when
+		   someone changes the status */
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&chip->wq, &wait);
+		spin_unlock_bh(chip->mutex);
+		schedule();
+		remove_wait_queue(&chip->wq, &wait);
+		timeo = jiffies + HZ;
+		goto retry;
+	}
+
+	ENABLE_VPP(map);
+	cfi_write(map, CMD(0x40), adr);
+	cfi_write(map, datum, adr);
+	chip->state = FL_WRITING;
+
+	spin_unlock_bh(chip->mutex);
+	cfi_udelay(chip->word_write_time);
+	spin_lock_bh(chip->mutex);
+
+	timeo = jiffies + (HZ/2);
+	z = 0;
+	for (;;) {
+		if (chip->state != FL_WRITING) {
+			/* Someone's suspended the write. Sleep */
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			add_wait_queue(&chip->wq, &wait);
+			spin_unlock_bh(chip->mutex);
+			schedule();
+			remove_wait_queue(&chip->wq, &wait);
+			timeo = jiffies + (HZ / 2); /* FIXME */
+			spin_lock_bh(chip->mutex);
+			continue;
+		}
+
+		status = cfi_read(map, adr);
+		if ((status & status_OK) == status_OK)
+			break;
+		
+		/* OK Still waiting */
+		if (time_after(jiffies, timeo)) {
+			chip->state = FL_STATUS;
+			DISABLE_VPP(map);
+			spin_unlock_bh(chip->mutex);
+			printk("waiting for chip to be ready timed out in word write\n");
+			return -EIO;
+		}
+
+		/* Latency issues. Drop the lock, wait a while and retry */
+		spin_unlock_bh(chip->mutex);
+		z++;
+		cfi_udelay(1);
+		spin_lock_bh(chip->mutex);
+	}
+	if (!z) {
+		chip->word_write_time--;
+		if (!chip->word_write_time)
+			chip->word_write_time++;
+	}
+	if (z > 1) 
+		chip->word_write_time++;
+
+	/* Done and happy. */
+	DISABLE_VPP(map);
+	chip->state = FL_STATUS;
+	/* check for lock bit */
+	if (status & CMD(0x02)) {
+		/* clear status */
+		cfi_write(map, CMD(0x50), adr);
+		/* put back into read status register mode */
+		cfi_write(map, CMD(0x70), adr);
+		wake_up(&chip->wq);
+		spin_unlock_bh(chip->mutex);
+		return -EROFS;
+	}
+	wake_up(&chip->wq);
+	spin_unlock_bh(chip->mutex);
+	return 0;
+}
+
+
+static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t len, size_t *retlen, const u_char *buf)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	int ret = 0;
+	int chipnum;
+	unsigned long ofs;
+
+	*retlen = 0;
+	if (!len)
+		return 0;
+
+	chipnum = to >> cfi->chipshift;
+	ofs = to  - (chipnum << cfi->chipshift);
+
+	/* If it's not bus-aligned, do the first byte write */
+	if (ofs & (CFIDEV_BUSWIDTH-1)) {
+		unsigned long bus_ofs = ofs & ~(CFIDEV_BUSWIDTH-1);
+		int gap = ofs - bus_ofs;
+		int i = 0, n = 0;
+		u_char tmp_buf[4];
+		__u32 datum;
+
+		while (gap--)
+			tmp_buf[i++] = 0xff;
+		while (len && i < CFIDEV_BUSWIDTH)
+			tmp_buf[i++] = buf[n++], len--;
+		while (i < CFIDEV_BUSWIDTH)
+			tmp_buf[i++] = 0xff;
+
+		if (cfi_buswidth_is_2()) {
+			datum = *(__u16*)tmp_buf;
+		} else if (cfi_buswidth_is_4()) {
+			datum = *(__u32*)tmp_buf;
+		} else {
+			return -EINVAL;  /* should never happen, but be safe */
+		}
+
+		ret = do_write_oneword(map, &cfi->chips[chipnum],
+					       bus_ofs, datum);
+		if (ret) 
+			return ret;
+		
+		ofs += n;
+		buf += n;
+		(*retlen) += n;
+
+		if (ofs >> cfi->chipshift) {
+			chipnum ++; 
+			ofs = 0;
+			if (chipnum == cfi->numchips)
+				return 0;
+		}
+	}
+	
+	while(len >= CFIDEV_BUSWIDTH) {
+		__u32 datum;
+
+		if (cfi_buswidth_is_1()) {
+			datum = *(__u8*)buf;
+		} else if (cfi_buswidth_is_2()) {
+			datum = *(__u16*)buf;
+		} else if (cfi_buswidth_is_4()) {
+			datum = *(__u32*)buf;
+		} else {
+			return -EINVAL;
+		}
+
+		ret = do_write_oneword(map, &cfi->chips[chipnum],
+				ofs, datum);
+		if (ret)
+			return ret;
+
+		ofs += CFIDEV_BUSWIDTH;
+		buf += CFIDEV_BUSWIDTH;
+		(*retlen) += CFIDEV_BUSWIDTH;
+		len -= CFIDEV_BUSWIDTH;
+
+		if (ofs >> cfi->chipshift) {
+			chipnum ++; 
+			ofs = 0;
+			if (chipnum == cfi->numchips)
+				return 0;
+		}
+	}
+
+	if (len & (CFIDEV_BUSWIDTH-1)) {
+		int i = 0, n = 0;
+		u_char tmp_buf[4];
+		__u32 datum;
+
+		while (len--)
+			tmp_buf[i++] = buf[n++];
+		while (i < CFIDEV_BUSWIDTH)
+			tmp_buf[i++] = 0xff;
+
+		if (cfi_buswidth_is_2()) {
+			datum = *(__u16*)tmp_buf;
+		} else if (cfi_buswidth_is_4()) {
+			datum = *(__u32*)tmp_buf;
+		} else {
+			return -EINVAL;  /* should never happen, but be safe */
+		}
+
+		ret = do_write_oneword(map, &cfi->chips[chipnum],
+					       ofs, datum);
+		if (ret) 
+			return ret;
+		
+		(*retlen) += n;
+	}
+
+	return 0;
+}
+
+
+static inline int do_write_buffer(struct map_info *map, struct flchip *chip, 
+				  unsigned long adr, const u_char *buf, int len)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
+	__u32 status, status_OK;
+	unsigned long cmd_adr, timeo;
+	DECLARE_WAITQUEUE(wait, current);
+	int wbufsize, z;
+
+	wbufsize = CFIDEV_INTERLEAVE << cfi->cfiq->MaxBufWriteSize;
+	adr += chip->start;
+	cmd_adr = adr & ~(wbufsize-1);
+	
+	/* Let's determine this according to the interleave only once */
+	status_OK = CMD(0x80);
+
+	timeo = jiffies + HZ;
+ retry:
+	spin_lock_bh(chip->mutex);
+
+	/* Check that the chip's ready to talk to us.
+	 * Later, we can actually think about interrupting it
+	 * if it's in FL_ERASING state.
+	 * Not just yet, though.
+	 */
+	switch (chip->state) {
+	case FL_READY:
+		break;
+		
+	case FL_CFI_QUERY:
+	case FL_JEDEC_QUERY:
+		cfi_write(map, CMD(0x70), cmd_adr);
+		chip->state = FL_STATUS;
+
+	case FL_STATUS:
+		status = cfi_read(map, cmd_adr);
+		if ((status & status_OK) == status_OK)
+			break;
+		/* Urgh. Chip not yet ready to talk to us. */
+		if (time_after(jiffies, timeo)) {
+			spin_unlock_bh(chip->mutex);
+			printk("waiting for chip to be ready timed out in buffer write\n");
+			return -EIO;
+		}
+
+		/* Latency issues. Drop the lock, wait a while and retry */
+		spin_unlock_bh(chip->mutex);
+		cfi_udelay(1);
+		goto retry;
+
+	default:
+		/* Stick ourselves on a wait queue to be woken when
+		   someone changes the status */
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&chip->wq, &wait);
+		spin_unlock_bh(chip->mutex);
+		schedule();
+		remove_wait_queue(&chip->wq, &wait);
+		timeo = jiffies + HZ;
+		goto retry;
+	}
+
+	ENABLE_VPP(map);
+	cfi_write(map, CMD(0xe8), cmd_adr);
+	chip->state = FL_WRITING_TO_BUFFER;
+
+	z = 0;
+	for (;;) {
+		status = cfi_read(map, cmd_adr);
+		if ((status & status_OK) == status_OK)
+			break;
+
+		spin_unlock_bh(chip->mutex);
+		cfi_udelay(1);
+		spin_lock_bh(chip->mutex);
+
+		if (++z > 20) {
+			/* Argh. Not ready for write to buffer */
+			cfi_write(map, CMD(0x70), cmd_adr);
+			chip->state = FL_STATUS;
+			DISABLE_VPP(map);
+			spin_unlock_bh(chip->mutex);
+			printk("Chip not ready for buffer write. Xstatus = %x, status = %x\n", status, cfi_read(map, cmd_adr));
+			return -EIO;
+		}
+	}
+
+	/* Write length of data to come */
+	cfi_write(map, CMD(len/CFIDEV_BUSWIDTH-1), cmd_adr );
+
+	/* Write data */
+	for (z = 0; z < len; z += CFIDEV_BUSWIDTH) {
+		if (cfi_buswidth_is_1()) {
+			map->write8 (map, *((__u8*)buf)++, adr+z);
+		} else if (cfi_buswidth_is_2()) {
+			map->write16 (map, *((__u16*)buf)++, adr+z);
+		} else if (cfi_buswidth_is_4()) {
+			map->write32 (map, *((__u32*)buf)++, adr+z);
+		} else {
+			DISABLE_VPP(map);
+			return -EINVAL;
+		}
+	}
+	/* GO GO GO */
+	cfi_write(map, CMD(0xd0), cmd_adr);
+	chip->state = FL_WRITING;
+
+	spin_unlock_bh(chip->mutex);
+	cfi_udelay(chip->buffer_write_time);
+	spin_lock_bh(chip->mutex);
+
+	timeo = jiffies + (HZ/2);
+	z = 0;
+	for (;;) {
+		if (chip->state != FL_WRITING) {
+			/* Someone's suspended the write. Sleep */
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			add_wait_queue(&chip->wq, &wait);
+			spin_unlock_bh(chip->mutex);
+			schedule();
+			remove_wait_queue(&chip->wq, &wait);
+			timeo = jiffies + (HZ / 2); /* FIXME */
+			spin_lock_bh(chip->mutex);
+			continue;
+		}
+
+		status = cfi_read(map, cmd_adr);
+		if ((status & status_OK) == status_OK)
+			break;
+
+		/* OK Still waiting */
+		if (time_after(jiffies, timeo)) {
+			chip->state = FL_STATUS;
+			DISABLE_VPP(map);
+			spin_unlock_bh(chip->mutex);
+			printk("waiting for chip to be ready timed out in bufwrite\n");
+			return -EIO;
+		}
+		
+		/* Latency issues. Drop the lock, wait a while and retry */
+		spin_unlock_bh(chip->mutex);
+		cfi_udelay(1);
+		z++;
+		spin_lock_bh(chip->mutex);
+	}
+	if (!z) {
+		chip->buffer_write_time--;
+		if (!chip->buffer_write_time)
+			chip->buffer_write_time++;
+	}
+	if (z > 1) 
+		chip->buffer_write_time++;
+
+	/* Done and happy. */
+	DISABLE_VPP(map);
+	chip->state = FL_STATUS;
+	/* check for lock bit */
+	if (status & CMD(0x02)) {
+		/* clear status */
+		cfi_write(map, CMD(0x50), cmd_adr);
+		/* put back into read status register mode */
+		cfi_write(map, CMD(0x70), adr);
+		wake_up(&chip->wq);
+		spin_unlock_bh(chip->mutex);
+		return -EROFS;
+	}
+	wake_up(&chip->wq);
+	spin_unlock_bh(chip->mutex);
+	return 0;
+}
+
+static int cfi_intelext_write_buffers (struct mtd_info *mtd, loff_t to, 
+				       size_t len, size_t *retlen, const u_char *buf)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	int wbufsize = CFIDEV_INTERLEAVE << cfi->cfiq->MaxBufWriteSize;
+	int ret = 0;
+	int chipnum;
+	unsigned long ofs;
+
+	*retlen = 0;
+	if (!len)
+		return 0;
+
+	chipnum = to >> cfi->chipshift;
+	ofs = to  - (chipnum << cfi->chipshift);
+
+	/* If it's not bus-aligned, do the first word write */
+	if (ofs & (CFIDEV_BUSWIDTH-1)) {
+		size_t local_len = (-ofs)&(CFIDEV_BUSWIDTH-1);
+		if (local_len > len)
+			local_len = len;
+		ret = cfi_intelext_write_words(mtd, to, local_len,
+					       retlen, buf);
+		if (ret)
+			return ret;
+		ofs += local_len;
+		buf += local_len;
+		len -= local_len;
+
+		if (ofs >> cfi->chipshift) {
+			chipnum ++;
+			ofs = 0;
+			if (chipnum == cfi->numchips)
+				return 0;
+		}
+	}
+
+	/* Write buffer is worth it only if more than one word to write... */
+	while(len > CFIDEV_BUSWIDTH) {
+		/* We must not cross write block boundaries */
+		int size = wbufsize - (ofs & (wbufsize-1));
+
+		if (size > len)
+			size = len & ~(CFIDEV_BUSWIDTH-1);
+		ret = do_write_buffer(map, &cfi->chips[chipnum], 
+				      ofs, buf, size);
+		if (ret)
+			return ret;
+
+		ofs += size;
+		buf += size;
+		(*retlen) += size;
+		len -= size;
+
+		if (ofs >> cfi->chipshift) {
+			chipnum ++; 
+			ofs = 0;
+			if (chipnum == cfi->numchips)
+				return 0;
+		}
+	}
+
+	/* ... and write the remaining bytes */
+	if (len > 0) {
+		size_t local_retlen;
+		ret = cfi_intelext_write_words(mtd, ofs + (chipnum << cfi->chipshift),
+					       len, &local_retlen, buf);
+		if (ret)
+			return ret;
+		(*retlen) += local_retlen;
+	}
+
+	return 0;
+}
+
+
+static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
+	__u32 status, status_OK;
+	unsigned long timeo;
+	int retries = 3;
+	DECLARE_WAITQUEUE(wait, current);
+	int ret = 0;
+
+	adr += chip->start;
+
+	/* Let's determine this according to the interleave only once */
+	status_OK = CMD(0x80);
+
+	timeo = jiffies + HZ;
+retry:
+	spin_lock_bh(chip->mutex);
+
+	/* Check that the chip's ready to talk to us. */
+	switch (chip->state) {
+	case FL_CFI_QUERY:
+	case FL_JEDEC_QUERY:
+	case FL_READY:
+		cfi_write(map, CMD(0x70), adr);
+		chip->state = FL_STATUS;
+
+	case FL_STATUS:
+		status = cfi_read(map, adr);
+		if ((status & status_OK) == status_OK)
+			break;
+		
+		/* Urgh. Chip not yet ready to talk to us. */
+		if (time_after(jiffies, timeo)) {
+			spin_unlock_bh(chip->mutex);
+			printk("waiting for chip to be ready timed out in erase\n");
+			return -EIO;
+		}
+
+		/* Latency issues. Drop the lock, wait a while and retry */
+		spin_unlock_bh(chip->mutex);
+		cfi_udelay(1);
+		goto retry;
+
+	default:
+		/* Stick ourselves on a wait queue to be woken when
+		   someone changes the status */
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&chip->wq, &wait);
+		spin_unlock_bh(chip->mutex);
+		schedule();
+		remove_wait_queue(&chip->wq, &wait);
+		timeo = jiffies + HZ;
+		goto retry;
+	}
+
+	ENABLE_VPP(map);
+	/* Clear the status register first */
+	cfi_write(map, CMD(0x50), adr);
+
+	/* Now erase */
+	cfi_write(map, CMD(0x20), adr);
+	cfi_write(map, CMD(0xD0), adr);
+	chip->state = FL_ERASING;
+	
+	spin_unlock_bh(chip->mutex);
+	schedule_timeout(HZ);
+	spin_lock_bh(chip->mutex);
+
+	/* FIXME. Use a timer to check this, and return immediately. */
+	/* Once the state machine's known to be working I'll do that */
+
+	timeo = jiffies + (HZ*20);
+	for (;;) {
+		if (chip->state != FL_ERASING) {
+			/* Someone's suspended the erase. Sleep */
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			add_wait_queue(&chip->wq, &wait);
+			spin_unlock_bh(chip->mutex);
+			schedule();
+			remove_wait_queue(&chip->wq, &wait);
+			timeo = jiffies + (HZ*2); /* FIXME */
+			spin_lock_bh(chip->mutex);
+			continue;
+		}
+
+		status = cfi_read(map, adr);
+		if ((status & status_OK) == status_OK)
+			break;
+		
+		/* OK Still waiting */
+		if (time_after(jiffies, timeo)) {
+			cfi_write(map, CMD(0x70), adr);
+			chip->state = FL_STATUS;
+			printk("waiting for erase to complete timed out. Xstatus = %x, status = %x.\n", status, cfi_read(map, adr));
+			DISABLE_VPP(map);
+			spin_unlock_bh(chip->mutex);
+			return -EIO;
+		}
+		
+		/* Latency issues. Drop the lock, wait a while and retry */
+		spin_unlock_bh(chip->mutex);
+		cfi_udelay(1);
+		spin_lock_bh(chip->mutex);
+	}
+	
+	DISABLE_VPP(map);
+	ret = 0;
+
+	/* We've broken this before. It doesn't hurt to be safe */
+	cfi_write(map, CMD(0x70), adr);
+	chip->state = FL_STATUS;
+	status = cfi_read(map, adr);
+
+	/* check for lock bit */
+	if (status & CMD(0x3a)) {
+		unsigned char chipstatus = status;
+		if (status != CMD(status & 0xff)) {
+			int i;
+			for (i = 1; i<CFIDEV_INTERLEAVE; i++) {
+				      chipstatus |= status >> (cfi->device_type * 8);
+			}
+			printk(KERN_WARNING "Status is not identical for all chips: 0x%x. Merging to give 0x%02x\n", status, chipstatus);
+		}
+		/* Reset the error bits */
+		cfi_write(map, CMD(0x50), adr);
+		cfi_write(map, CMD(0x70), adr);
+		
+		if ((chipstatus & 0x30) == 0x30) {
+			printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", status);
+			ret = -EIO;
+		} else if (chipstatus & 0x02) {
+			/* Protection bit set */
+			ret = -EROFS;
+		} else if (chipstatus & 0x8) {
+			/* Voltage */
+			printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%x\n", status);
+			ret = -EIO;
+		} else if (chipstatus & 0x20) {
+			if (retries--) {
+				printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x. Retrying...\n", adr, status);
+				timeo = jiffies + HZ;
+				chip->state = FL_STATUS;
+				spin_unlock_bh(chip->mutex);
+				goto retry;
+			}
+			printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x\n", adr, status);
+			ret = -EIO;
+		}
+	}
+
+	wake_up(&chip->wq);
+	spin_unlock_bh(chip->mutex);
+	return ret;
+}
+
+int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
+{	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	unsigned long adr, len;
+	int chipnum, ret = 0;
+	int i, first;
+	struct mtd_erase_region_info *regions = mtd->eraseregions;
+
+	if (instr->addr > mtd->size)
+		return -EINVAL;
+
+	if ((instr->len + instr->addr) > mtd->size)
+		return -EINVAL;
+
+	/* Check that both start and end of the requested erase are
+	 * aligned with the erasesize at the appropriate addresses.
+	 */
+
+	i = 0;
+
+	/* Skip all erase regions which are ended before the start of 
+	   the requested erase. Actually, to save on the calculations,
+	   we skip to the first erase region which starts after the
+	   start of the requested erase, and then go back one.
+	*/
+	
+	while (i < mtd->numeraseregions && instr->addr >= regions[i].offset)
+	       i++;
+	i--;
+
+	/* OK, now i is pointing at the erase region in which this 
+	   erase request starts. Check the start of the requested
+	   erase range is aligned with the erase size which is in
+	   effect here.
+	*/
+
+	if (instr->addr & (regions[i].erasesize-1))
+		return -EINVAL;
+
+	/* Remember the erase region we start on */
+	first = i;
+
+	/* Next, check that the end of the requested erase is aligned
+	 * with the erase region at that address.
+	 */
+
+	while (i<mtd->numeraseregions && (instr->addr + instr->len) >= regions[i].offset)
+		i++;
+
+	/* As before, drop back one to point at the region in which
+	   the address actually falls
+	*/
+	i--;
+	
+	if ((instr->addr + instr->len) & (regions[i].erasesize-1))
+		return -EINVAL;
+
+	chipnum = instr->addr >> cfi->chipshift;
+	adr = instr->addr - (chipnum << cfi->chipshift);
+	len = instr->len;
+
+	i=first;
+
+	while(len) {
+		ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
+		
+		if (ret)
+			return ret;
+
+		adr += regions[i].erasesize;
+		len -= regions[i].erasesize;
+
+		if (adr % (1<< cfi->chipshift) == ((regions[i].offset + (regions[i].erasesize * regions[i].numblocks)) %( 1<< cfi->chipshift)))
+			i++;
+
+		if (adr >> cfi->chipshift) {
+			adr = 0;
+			chipnum++;
+			
+			if (chipnum >= cfi->numchips)
+			break;
+		}
+	}
+		
+	instr->state = MTD_ERASE_DONE;
+	if (instr->callback)
+		instr->callback(instr);
+	
+	return 0;
+}
+
+static void cfi_intelext_sync (struct mtd_info *mtd)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	int i;
+	struct flchip *chip;
+	int ret = 0;
+	DECLARE_WAITQUEUE(wait, current);
+
+	for (i=0; !ret && i<cfi->numchips; i++) {
+		chip = &cfi->chips[i];
+
+	retry:
+		spin_lock_bh(chip->mutex);
+
+		switch(chip->state) {
+		case FL_READY:
+		case FL_STATUS:
+		case FL_CFI_QUERY:
+		case FL_JEDEC_QUERY:
+			chip->oldstate = chip->state;
+			chip->state = FL_SYNCING;
+			/* No need to wake_up() on this state change - 
+			 * as the whole point is that nobody can do anything
+			 * with the chip now anyway.
+			 */
+		case FL_SYNCING:
+			spin_unlock_bh(chip->mutex);
+			break;
+
+		default:
+			/* Not an idle state */
+			add_wait_queue(&chip->wq, &wait);
+			
+			spin_unlock_bh(chip->mutex);
+			schedule();
+		        remove_wait_queue(&chip->wq, &wait);
+			
+			goto retry;
+		}
+	}
+
+	/* Unlock the chips again */
+
+	for (i--; i >=0; i--) {
+		chip = &cfi->chips[i];
+
+		spin_lock_bh(chip->mutex);
+		
+		if (chip->state == FL_SYNCING) {
+			chip->state = chip->oldstate;
+			wake_up(&chip->wq);
+		}
+		spin_unlock_bh(chip->mutex);
+	}
+}
+
+static inline int do_lock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
+	__u32 status, status_OK;
+	unsigned long timeo = jiffies + HZ;
+	DECLARE_WAITQUEUE(wait, current);
+
+	adr += chip->start;
+
+	/* Let's determine this according to the interleave only once */
+	status_OK = CMD(0x80);
+
+	timeo = jiffies + HZ;
+retry:
+	spin_lock_bh(chip->mutex);
+
+	/* Check that the chip's ready to talk to us. */
+	switch (chip->state) {
+	case FL_CFI_QUERY:
+	case FL_JEDEC_QUERY:
+	case FL_READY:
+		cfi_write(map, CMD(0x70), adr);
+		chip->state = FL_STATUS;
+
+	case FL_STATUS:
+		status = cfi_read(map, adr);
+		if ((status & status_OK) == status_OK) 
+			break;
+		
+		/* Urgh. Chip not yet ready to talk to us. */
+		if (time_after(jiffies, timeo)) {
+			spin_unlock_bh(chip->mutex);
+			printk("waiting for chip to be ready timed out in lock\n");
+			return -EIO;
+		}
+
+		/* Latency issues. Drop the lock, wait a while and retry */
+		spin_unlock_bh(chip->mutex);
+		cfi_udelay(1);
+		goto retry;
+
+	default:
+		/* Stick ourselves on a wait queue to be woken when
+		   someone changes the status */
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&chip->wq, &wait);
+		spin_unlock_bh(chip->mutex);
+		schedule();
+		remove_wait_queue(&chip->wq, &wait);
+		timeo = jiffies + HZ;
+		goto retry;
+	}
+
+	ENABLE_VPP(map);
+	cfi_write(map, CMD(0x60), adr);
+	cfi_write(map, CMD(0x01), adr);
+	chip->state = FL_LOCKING;
+	
+	spin_unlock_bh(chip->mutex);
+	schedule_timeout(HZ);
+	spin_lock_bh(chip->mutex);
+
+	/* FIXME. Use a timer to check this, and return immediately. */
+	/* Once the state machine's known to be working I'll do that */
+
+	timeo = jiffies + (HZ*2);
+	for (;;) {
+
+		status = cfi_read(map, adr);
+		if ((status & status_OK) == status_OK)
+			break;
+		
+		/* OK Still waiting */
+		if (time_after(jiffies, timeo)) {
+			cfi_write(map, CMD(0x70), adr);
+			chip->state = FL_STATUS;
+			printk("waiting for lock to complete timed out. Xstatus = %x, status = %x.\n", status, cfi_read(map, adr));
+			DISABLE_VPP(map);
+			spin_unlock_bh(chip->mutex);
+			return -EIO;
+		}
+		
+		/* Latency issues. Drop the lock, wait a while and retry */
+		spin_unlock_bh(chip->mutex);
+		cfi_udelay(1);
+		spin_lock_bh(chip->mutex);
+	}
+	
+	/* Done and happy. */
+	chip->state = FL_STATUS;
+	DISABLE_VPP(map);
+	wake_up(&chip->wq);
+	spin_unlock_bh(chip->mutex);
+	return 0;
+}
+static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	unsigned long adr;
+	int chipnum, ret = 0;
+#ifdef DEBUG_LOCK_BITS
+	int ofs_factor = cfi->interleave * cfi->device_type;
+#endif
+
+	if (ofs & (mtd->erasesize - 1))
+		return -EINVAL;
+
+	if (len & (mtd->erasesize -1))
+		return -EINVAL;
+
+	if ((len + ofs) > mtd->size)
+		return -EINVAL;
+
+	chipnum = ofs >> cfi->chipshift;
+	adr = ofs - (chipnum << cfi->chipshift);
+
+	while(len) {
+
+#ifdef DEBUG_LOCK_BITS
+		cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
+		printk("before lock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor)));
+		cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
+#endif
+
+		ret = do_lock_oneblock(map, &cfi->chips[chipnum], adr);
+
+#ifdef DEBUG_LOCK_BITS
+		cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
+		printk("after lock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor)));
+		cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
+#endif	
+		
+		if (ret)
+			return ret;
+
+		adr += mtd->erasesize;
+		len -= mtd->erasesize;
+
+		if (adr >> cfi->chipshift) {
+			adr = 0;
+			chipnum++;
+			
+			if (chipnum >= cfi->numchips)
+			break;
+		}
+	}
+	return 0;
+}
+static inline int do_unlock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
+	__u32 status, status_OK;
+	unsigned long timeo = jiffies + HZ;
+	DECLARE_WAITQUEUE(wait, current);
+
+	adr += chip->start;
+
+	/* Let's determine this according to the interleave only once */
+	status_OK = CMD(0x80);
+
+	timeo = jiffies + HZ;
+retry:
+	spin_lock_bh(chip->mutex);
+
+	/* Check that the chip's ready to talk to us. */
+	switch (chip->state) {
+	case FL_CFI_QUERY:
+	case FL_JEDEC_QUERY:
+	case FL_READY:
+		cfi_write(map, CMD(0x70), adr);
+		chip->state = FL_STATUS;
+
+	case FL_STATUS:
+		status = cfi_read(map, adr);
+		if ((status & status_OK) == status_OK)
+			break;
+		
+		/* Urgh. Chip not yet ready to talk to us. */
+		if (time_after(jiffies, timeo)) {
+			spin_unlock_bh(chip->mutex);
+			printk("waiting for chip to be ready timed out in unlock\n");
+			return -EIO;
+		}
+
+		/* Latency issues. Drop the lock, wait a while and retry */
+		spin_unlock_bh(chip->mutex);
+		cfi_udelay(1);
+		goto retry;
+
+	default:
+		/* Stick ourselves on a wait queue to be woken when
+		   someone changes the status */
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&chip->wq, &wait);
+		spin_unlock_bh(chip->mutex);
+		schedule();
+		remove_wait_queue(&chip->wq, &wait);
+		timeo = jiffies + HZ;
+		goto retry;
+	}
+
+	ENABLE_VPP(map);
+	cfi_write(map, CMD(0x60), adr);
+	cfi_write(map, CMD(0xD0), adr);
+	chip->state = FL_UNLOCKING;
+	
+	spin_unlock_bh(chip->mutex);
+	schedule_timeout(HZ);
+	spin_lock_bh(chip->mutex);
+
+	/* FIXME. Use a timer to check this, and return immediately. */
+	/* Once the state machine's known to be working I'll do that */
+
+	timeo = jiffies + (HZ*2);
+	for (;;) {
+
+		status = cfi_read(map, adr);
+		if ((status & status_OK) == status_OK)
+			break;
+		
+		/* OK Still waiting */
+		if (time_after(jiffies, timeo)) {
+			cfi_write(map, CMD(0x70), adr);
+			chip->state = FL_STATUS;
+			printk("waiting for unlock to complete timed out. Xstatus = %x, status = %x.\n", status, cfi_read(map, adr));
+			DISABLE_VPP(map);
+			spin_unlock_bh(chip->mutex);
+			return -EIO;
+		}
+		
+		/* Latency issues. Drop the unlock, wait a while and retry */
+		spin_unlock_bh(chip->mutex);
+		cfi_udelay(1);
+		spin_lock_bh(chip->mutex);
+	}
+	
+	/* Done and happy. */
+	chip->state = FL_STATUS;
+	DISABLE_VPP(map);
+	wake_up(&chip->wq);
+	spin_unlock_bh(chip->mutex);
+	return 0;
+}
+static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	unsigned long adr;
+	int chipnum, ret = 0;
+#ifdef DEBUG_LOCK_BITS
+	int ofs_factor = cfi->interleave * cfi->device_type;
+#endif
+
+	chipnum = ofs >> cfi->chipshift;
+	adr = ofs - (chipnum << cfi->chipshift);
+
+#ifdef DEBUG_LOCK_BITS
+	{
+		unsigned long temp_adr = adr;
+		unsigned long temp_len = len;
+                 
+		cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
+                while (temp_len) {
+			printk("before unlock %x: block status register is %x\n",temp_adr,cfi_read_query(map, temp_adr+(2*ofs_factor)));
+			temp_adr += mtd->erasesize;
+			temp_len -= mtd->erasesize;
+		}
+		cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
+	}
+#endif
+
+	ret = do_unlock_oneblock(map, &cfi->chips[chipnum], adr);
+
+#ifdef DEBUG_LOCK_BITS
+	cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
+	printk("after unlock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor)));
+	cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
+#endif
+	
+	return ret;
+}
+
+static int cfi_intelext_suspend(struct mtd_info *mtd)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	int i;
+	struct flchip *chip;
+	int ret = 0;
+
+	for (i=0; !ret && i<cfi->numchips; i++) {
+		chip = &cfi->chips[i];
+
+		spin_lock_bh(chip->mutex);
+
+		switch(chip->state) {
+		case FL_READY:
+		case FL_STATUS:
+		case FL_CFI_QUERY:
+		case FL_JEDEC_QUERY:
+			chip->oldstate = chip->state;
+			chip->state = FL_PM_SUSPENDED;
+			/* No need to wake_up() on this state change - 
+			 * as the whole point is that nobody can do anything
+			 * with the chip now anyway.
+			 */
+		case FL_PM_SUSPENDED:
+			break;
+
+		default:
+			ret = -EAGAIN;
+			break;
+		}
+		spin_unlock_bh(chip->mutex);
+	}
+
+	/* Unlock the chips again */
+
+	if (ret) {
+		for (i--; i >=0; i--) {
+			chip = &cfi->chips[i];
+			
+			spin_lock_bh(chip->mutex);
+			
+			if (chip->state == FL_PM_SUSPENDED) {
+				chip->state = chip->oldstate;
+				wake_up(&chip->wq);
+			}
+			spin_unlock_bh(chip->mutex);
+		}
+	} 
+	
+	return ret;
+}
+
+static void cfi_intelext_resume(struct mtd_info *mtd)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	int i;
+	struct flchip *chip;
+
+	for (i=0; i<cfi->numchips; i++) {
+	
+		chip = &cfi->chips[i];
+
+		spin_lock_bh(chip->mutex);
+		
+		if (chip->state == FL_PM_SUSPENDED) {
+			/* We need to force it back to a known state. */
+			cfi_write(map, CMD(0xff), 0);
+			chip->state = FL_READY;
+			wake_up(&chip->wq);
+		}
+
+		spin_unlock_bh(chip->mutex);
+	}
+}
+
+static void cfi_intelext_destroy(struct mtd_info *mtd)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	kfree(cfi->cmdset_priv);
+	kfree(cfi);
+}
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define cfi_intelext_init init_module
+#define cfi_intelext_exit cleanup_module
+#endif
+
+static char im_name_1[]="cfi_cmdset_0001";
+static char im_name_3[]="cfi_cmdset_0003";
+
+
+mod_init_t cfi_intelext_init(void)
+{
+	inter_module_register(im_name_1, THIS_MODULE, &cfi_cmdset_0001);
+	inter_module_register(im_name_3, THIS_MODULE, &cfi_cmdset_0001);
+	return 0;
+}
+
+mod_exit_t cfi_intelext_exit(void)
+{
+	inter_module_unregister(im_name_1);
+	inter_module_unregister(im_name_3);
+}
+
+module_init(cfi_intelext_init);
+module_exit(cfi_intelext_exit);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/chips/cfi_cmdset_0002.c linux/drivers/mtd/chips/cfi_cmdset_0002.c
--- v2.4.5/linux/drivers/mtd/chips/cfi_cmdset_0002.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/chips/cfi_cmdset_0002.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,936 @@
+/*
+ * Common Flash Interface support:
+ *   AMD & Fujitsu Standard Vendor Command Set (ID 0x0002)
+ *
+ * Copyright (C) 2000 Crossnet Co. <info@crossnet.co.jp>
+ *
+ * 2_by_8 routines added by Simon Munton
+ *
+ * This code is GPL
+ *
+ * $Id: cfi_cmdset_0002.c,v 1.48 2001/06/03 01:32:57 nico Exp $
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/cfi.h>
+
+#define AMD_BOOTLOC_BUG
+
+static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
+static int cfi_amdstd_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
+static int cfi_amdstd_erase_onesize(struct mtd_info *, struct erase_info *);
+static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *);
+static void cfi_amdstd_sync (struct mtd_info *);
+static int cfi_amdstd_suspend (struct mtd_info *);
+static void cfi_amdstd_resume (struct mtd_info *);
+
+static void cfi_amdstd_destroy(struct mtd_info *);
+
+void cfi_cmdset_0002(struct map_info *, int, unsigned long);
+static struct mtd_info *cfi_amdstd_setup (struct map_info *);
+
+
+static struct mtd_chip_driver cfi_amdstd_chipdrv = {
+	probe: cfi_amdstd_setup,
+	destroy: cfi_amdstd_destroy,
+	name: "cfi_cmdset_0002",
+	module: THIS_MODULE
+};
+
+void cfi_cmdset_0002(struct map_info *map, int primary, unsigned long base)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
+	unsigned char bootloc;
+	int ofs_factor = cfi->interleave * cfi->device_type;
+	int i;
+	__u8 major, minor;
+//	struct cfi_pri_intelext *extp;
+
+    if (cfi->cfi_mode==0){
+	__u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
+
+	cfi_send_gen_cmd(0x98, 0x55, 0, map, cfi, cfi->device_type, NULL);
+
+	major = cfi_read_query(map, (adr+3)*ofs_factor);
+	minor = cfi_read_query(map, (adr+4)*ofs_factor);
+
+	printk(" Amd/Fujitsu Extended Query Table v%c.%c at 0x%4.4X\n",
+	       major, minor, adr);
+
+	cfi_send_gen_cmd(0xf0, 0x55, 0, map, cfi, cfi->device_type, NULL);
+
+	cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
+	cfi->mfr = cfi_read_query(map, base);
+	cfi->id = cfi_read_query(map, base + ofs_factor);
+
+	/* Wheee. Bring me the head of someone at AMD. */
+#ifdef AMD_BOOTLOC_BUG
+	if (((major << 8) | minor) < 0x3131) {
+		/* CFI version 1.0 => don't trust bootloc */
+		if (cfi->id & 0x80) {
+			printk(KERN_WARNING "%s: JEDEC Device ID is 0x%02X. Assuming broken CFI table.\n", map->name, cfi->id);
+			bootloc = 3;	/* top boot */
+		} else {
+			bootloc = 2;	/* bottom boot */
+		}
+	} else
+#endif
+	{
+		cfi_send_gen_cmd(0x98, 0x55, 0, map, cfi, cfi->device_type, NULL);
+		bootloc = cfi_read_query(map, (adr+15)*ofs_factor);
+	}
+	if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) {
+		printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n", map->name);
+
+		for (i=0; i<cfi->cfiq->NumEraseRegions / 2; i++) {
+			int j = (cfi->cfiq->NumEraseRegions-1)-i;
+			__u32 swap;
+
+			swap = cfi->cfiq->EraseRegionInfo[i];
+			cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j];
+			cfi->cfiq->EraseRegionInfo[j] = swap;
+		}
+	}
+    }
+
+    /* If there was an old setup function, decrease its use count */
+    if (map->fldrv)
+      if(map->fldrv->module)
+	__MOD_DEC_USE_COUNT(map->fldrv->module);
+    
+    if (cfi->cmdset_priv)
+		kfree(cfi->cmdset_priv);
+
+    for (i=0; i< cfi->numchips; i++) {
+		cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
+		cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
+		cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
+    }		
+
+    map->fldrv = &cfi_amdstd_chipdrv;
+    MOD_INC_USE_COUNT;
+    cfi_send_gen_cmd(0xf0, 0x55, 0, map, cfi, cfi->device_type, NULL);
+    return;
+}
+
+static struct mtd_info *cfi_amdstd_setup(struct map_info *map)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
+	struct mtd_info *mtd;
+	unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave;
+
+	mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
+	printk("number of %s chips: %d\n", (cfi->cfi_mode)?"JEDEC":"CFI",cfi->numchips);
+
+	if (!mtd) {
+	  printk("Failed to allocate memory for MTD device\n");
+	  kfree(cfi->cmdset_priv);
+	  return NULL;
+	}
+
+	memset(mtd, 0, sizeof(*mtd));
+	mtd->priv = map;
+	mtd->type = MTD_NORFLASH;
+	/* Also select the correct geometry setup too */ 
+	mtd->size = devsize * cfi->numchips;
+	
+	if (cfi->cfiq->NumEraseRegions == 1) {
+		/* No need to muck about with multiple erase sizes */
+		mtd->erasesize = ((cfi->cfiq->EraseRegionInfo[0] >> 8) & ~0xff) * cfi->interleave;
+	} else {
+		unsigned long offset = 0;
+		int i,j;
+
+		mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
+		mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * mtd->numeraseregions, GFP_KERNEL);
+		if (!mtd->eraseregions) { 
+			printk("Failed to allocate memory for MTD erase region info\n");
+			kfree(cfi->cmdset_priv);
+			return NULL;
+		}
+			
+		for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
+			unsigned long ernum, ersize;
+			ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
+			ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1;
+			
+			if (mtd->erasesize < ersize) {
+				mtd->erasesize = ersize;
+			}
+			for (j=0; j<cfi->numchips; j++) {
+				mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset;
+				mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize;
+				mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum;
+			}
+			offset += (ersize * ernum);
+		}
+		if (offset != devsize) {
+			/* Argh */
+			printk("Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize);
+			kfree(mtd->eraseregions);
+			kfree(cfi->cmdset_priv);
+			return NULL;
+		}
+		// debug
+		for (i=0; i<mtd->numeraseregions;i++){
+			printk("%d: offset=0x%x,size=0x%x,blocks=%d\n",
+			       i,mtd->eraseregions[i].offset,
+			       mtd->eraseregions[i].erasesize,
+			       mtd->eraseregions[i].numblocks);
+		}
+	}
+
+	switch (CFIDEV_BUSWIDTH)
+	{
+	case 1:
+	case 2:
+	case 4:
+#if 1
+		if (mtd->numeraseregions > 1)
+			mtd->erase = cfi_amdstd_erase_varsize;
+		else
+#endif
+			mtd->erase = cfi_amdstd_erase_onesize;
+		mtd->read = cfi_amdstd_read;
+		mtd->write = cfi_amdstd_write;
+		break;
+
+	default:
+	        printk("Unsupported buswidth\n");
+		kfree(mtd);
+		kfree(cfi->cmdset_priv);
+		return NULL;
+		break;
+	}
+	mtd->sync = cfi_amdstd_sync;
+	mtd->suspend = cfi_amdstd_suspend;
+	mtd->resume = cfi_amdstd_resume;
+	mtd->flags = MTD_CAP_NORFLASH;
+	map->fldrv = &cfi_amdstd_chipdrv;
+	mtd->name = map->name;
+	MOD_INC_USE_COUNT;
+	return mtd;
+}
+
+static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	unsigned long timeo = jiffies + HZ;
+
+ retry:
+	cfi_spin_lock(chip->mutex);
+
+	if (chip->state != FL_READY){
+	        printk("Waiting for chip to read, status = %d\n", chip->state);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&chip->wq, &wait);
+                
+		cfi_spin_unlock(chip->mutex);
+
+		schedule();
+		remove_wait_queue(&chip->wq, &wait);
+#if 0
+		if(signal_pending(current))
+			return -EINTR;
+#endif
+		timeo = jiffies + HZ;
+
+		goto retry;
+	}	
+
+	adr += chip->start;
+
+	chip->state = FL_READY;
+
+	map->copy_from(map, buf, adr, len);
+
+	wake_up(&chip->wq);
+	cfi_spin_unlock(chip->mutex);
+
+	return 0;
+}
+
+static int cfi_amdstd_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	unsigned long ofs;
+	int chipnum;
+	int ret = 0;
+
+	/* ofs: offset within the first chip that the first read should start */
+
+	chipnum = (from >> cfi->chipshift);
+	ofs = from - (chipnum <<  cfi->chipshift);
+
+
+	*retlen = 0;
+
+	while (len) {
+		unsigned long thislen;
+
+		if (chipnum >= cfi->numchips)
+			break;
+
+		if ((len + ofs -1) >> cfi->chipshift)
+			thislen = (1<<cfi->chipshift) - ofs;
+		else
+			thislen = len;
+
+		ret = do_read_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf);
+		if (ret)
+			break;
+
+		*retlen += thislen;
+		len -= thislen;
+		buf += thislen;
+
+		ofs = 0;
+		chipnum++;
+	}
+	return ret;
+}
+
+static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, __u32 datum, int fast)
+{
+	unsigned long timeo = jiffies + HZ;
+	unsigned int Last[4];
+	unsigned long Count = 0;
+	struct cfi_private *cfi = map->fldrv_priv;
+	DECLARE_WAITQUEUE(wait, current);
+	int ret = 0;
+
+ retry:
+	cfi_spin_lock(chip->mutex);
+
+	if (chip->state != FL_READY){
+	        printk("Waiting for chip to write, status = %d\n", chip->state);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&chip->wq, &wait);
+                
+		cfi_spin_unlock(chip->mutex);
+
+		schedule();
+		remove_wait_queue(&chip->wq, &wait);
+		printk("Wake up to write:\n");
+#if 0
+		if(signal_pending(current))
+			return -EINTR;
+#endif
+		timeo = jiffies + HZ;
+
+		goto retry;
+	}	
+
+	chip->state = FL_WRITING;
+
+	adr += chip->start;
+	ENABLE_VPP(map);
+	if (fast) { /* Unlock bypass */
+		cfi_send_gen_cmd(0xA0, 0, chip->start, map, cfi, cfi->device_type, NULL);
+	}
+	else {
+	        cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	        cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	        cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	}
+
+	cfi_write(map, datum, adr);
+
+	cfi_spin_unlock(chip->mutex);
+	cfi_udelay(chip->word_write_time);
+	cfi_spin_lock(chip->mutex);
+
+	Last[0] = cfi_read(map, adr);
+	//	printk("Last[0] is %x\n", Last[0]);
+	Last[1] = cfi_read(map, adr);
+	//	printk("Last[1] is %x\n", Last[1]);
+	Last[2] = cfi_read(map, adr);
+	//	printk("Last[2] is %x\n", Last[2]);
+
+	for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] && Count < 10000; Count++){
+		cfi_spin_unlock(chip->mutex);
+		cfi_udelay(10);
+		cfi_spin_lock(chip->mutex);
+		
+	        Last[Count % 4] = cfi_read(map, adr);
+		//		printk("Last[%d%%4] is %x\n", Count, Last[Count%4]);
+	}
+	
+	if (Last[(Count - 1) % 4] != datum){
+		printk("Last[%ld] is %x, datum is %x\n",(Count - 1) % 4,Last[(Count - 1) % 4],datum);
+	        cfi_send_gen_cmd(0xF0, 0, chip->start, map, cfi, cfi->device_type, NULL);
+		DISABLE_VPP(map);
+		ret = -EIO;
+	}       
+	DISABLE_VPP(map);
+	chip->state = FL_READY;
+	wake_up(&chip->wq);
+	cfi_spin_unlock(chip->mutex);
+	
+	return ret;
+}
+
+static int cfi_amdstd_write (struct mtd_info *mtd, loff_t to , size_t len, size_t *retlen, const u_char *buf)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	int ret = 0;
+	int chipnum;
+	unsigned long ofs, chipstart;
+
+	*retlen = 0;
+	if (!len)
+		return 0;
+
+	chipnum = to >> cfi->chipshift;
+	ofs = to  - (chipnum << cfi->chipshift);
+	chipstart = cfi->chips[chipnum].start;
+
+	/* If it's not bus-aligned, do the first byte write */
+	if (ofs & (CFIDEV_BUSWIDTH-1)) {
+		unsigned long bus_ofs = ofs & ~(CFIDEV_BUSWIDTH-1);
+		int i = ofs - bus_ofs;
+		int n = 0;
+		u_char tmp_buf[4];
+		__u32 datum;
+
+		map->copy_from(map, tmp_buf, bus_ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
+		while (len && i < CFIDEV_BUSWIDTH)
+			tmp_buf[i++] = buf[n++], len--;
+
+		if (cfi_buswidth_is_2()) {
+			datum = *(__u16*)tmp_buf;
+		} else if (cfi_buswidth_is_4()) {
+			datum = *(__u32*)tmp_buf;
+		} else {
+			return -EINVAL;  /* should never happen, but be safe */
+		}
+
+		ret = do_write_oneword(map, &cfi->chips[chipnum], 
+				bus_ofs, datum, 0);
+		if (ret) 
+			return ret;
+		
+		ofs += n;
+		buf += n;
+		(*retlen) += n;
+
+		if (ofs >> cfi->chipshift) {
+			chipnum ++; 
+			ofs = 0;
+			if (chipnum == cfi->numchips)
+				return 0;
+		}
+	}
+	
+	/* Go into unlock bypass mode */
+	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	cfi_send_gen_cmd(0x20, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
+
+	/* We are now aligned, write as much as possible */
+	while(len >= CFIDEV_BUSWIDTH) {
+		__u32 datum;
+
+		if (cfi_buswidth_is_1()) {
+			datum = *(__u8*)buf;
+		} else if (cfi_buswidth_is_2()) {
+			datum = *(__u16*)buf;
+		} else if (cfi_buswidth_is_4()) {
+			datum = *(__u32*)buf;
+		} else {
+			return -EINVAL;
+		}
+		ret = do_write_oneword(map, &cfi->chips[chipnum],
+				       ofs, datum, cfi->fast_prog);
+		if (ret) {
+			if (cfi->fast_prog){
+				/* Get out of unlock bypass mode */
+				cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi, cfi->device_type, NULL);
+				cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi, cfi->device_type, NULL);
+			}
+			return ret;
+		}
+
+		ofs += CFIDEV_BUSWIDTH;
+		buf += CFIDEV_BUSWIDTH;
+		(*retlen) += CFIDEV_BUSWIDTH;
+		len -= CFIDEV_BUSWIDTH;
+
+		if (ofs >> cfi->chipshift) {
+			if (cfi->fast_prog){
+				/* Get out of unlock bypass mode */
+				cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi, cfi->device_type, NULL);
+				cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi, cfi->device_type, NULL);
+			}
+
+			chipnum ++; 
+			ofs = 0;
+			if (chipnum == cfi->numchips)
+				return 0;
+			chipstart = cfi->chips[chipnum].start;
+			if (cfi->fast_prog){
+				/* Go into unlock bypass mode for next set of chips */
+				cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
+				cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
+				cfi_send_gen_cmd(0x20, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
+			}
+		}
+	}
+
+	if (cfi->fast_prog){
+		/* Get out of unlock bypass mode */
+		cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi, cfi->device_type, NULL);
+		cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi, cfi->device_type, NULL);
+	}
+
+	if (len & (CFIDEV_BUSWIDTH-1)) {
+		int i = 0, n = 0;
+		u_char tmp_buf[4];
+		__u32 datum;
+
+		map->copy_from(map, tmp_buf, ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
+		while (len--)
+			tmp_buf[i++] = buf[n++];
+
+		if (cfi_buswidth_is_2()) {
+			datum = *(__u16*)tmp_buf;
+		} else if (cfi_buswidth_is_4()) {
+			datum = *(__u32*)tmp_buf;
+		} else {
+			return -EINVAL;  /* should never happen, but be safe */
+		}
+
+		ret = do_write_oneword(map, &cfi->chips[chipnum], 
+				ofs, datum, 0);
+		if (ret) 
+			return ret;
+		
+		(*retlen) += n;
+	}
+
+	return 0;
+}
+
+static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
+{
+	unsigned int status;
+	unsigned long timeo = jiffies + HZ;
+	struct cfi_private *cfi = map->fldrv_priv;
+	unsigned int rdy_mask;
+	DECLARE_WAITQUEUE(wait, current);
+
+ retry:
+	cfi_spin_lock(chip->mutex);
+
+	if (chip->state != FL_READY){
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&chip->wq, &wait);
+                
+		cfi_spin_unlock(chip->mutex);
+
+		schedule();
+		remove_wait_queue(&chip->wq, &wait);
+#if 0
+		if(signal_pending(current))
+			return -EINTR;
+#endif
+		timeo = jiffies + HZ;
+
+		goto retry;
+	}	
+
+	chip->state = FL_ERASING;
+
+	adr += chip->start;
+	ENABLE_VPP(map);
+	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	cfi_write(map, CMD(0x30), adr);
+	
+	timeo = jiffies + (HZ*20);
+
+	cfi_spin_unlock(chip->mutex);
+	schedule_timeout(HZ);
+	cfi_spin_lock(chip->mutex);
+	
+	rdy_mask = CMD(0x80);
+
+	/* FIXME. Use a timer to check this, and return immediately. */
+	/* Once the state machine's known to be working I'll do that */
+
+	while ( ( (status = cfi_read(map,adr)) & rdy_mask ) != rdy_mask ) {
+		static int z=0;
+
+		if (chip->state != FL_ERASING) {
+			/* Someone's suspended the erase. Sleep */
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			add_wait_queue(&chip->wq, &wait);
+			
+			cfi_spin_unlock(chip->mutex);
+			printk("erase suspended. Sleeping\n");
+			
+			schedule();
+			remove_wait_queue(&chip->wq, &wait);
+#if 0			
+			if (signal_pending(current))
+				return -EINTR;
+#endif			
+			timeo = jiffies + (HZ*2); /* FIXME */
+			cfi_spin_lock(chip->mutex);
+			continue;
+		}
+
+		/* OK Still waiting */
+		if (time_after(jiffies, timeo)) {
+			chip->state = FL_READY;
+			cfi_spin_unlock(chip->mutex);
+			printk("waiting for erase to complete timed out.");
+			DISABLE_VPP(map);
+			return -EIO;
+		}
+		
+		/* Latency issues. Drop the lock, wait a while and retry */
+		cfi_spin_unlock(chip->mutex);
+
+		z++;
+		if ( 0 && !(z % 100 )) 
+			printk("chip not ready yet after erase. looping\n");
+
+		cfi_udelay(1);
+		
+		cfi_spin_lock(chip->mutex);
+		continue;
+	}
+	
+	/* Done and happy. */
+	DISABLE_VPP(map);
+	chip->state = FL_READY;
+	wake_up(&chip->wq);
+	cfi_spin_unlock(chip->mutex);
+	return 0;
+}
+
+static int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	unsigned long adr, len;
+	int chipnum, ret = 0;
+	int i, first;
+	struct mtd_erase_region_info *regions = mtd->eraseregions;
+
+	if (instr->addr > mtd->size)
+		return -EINVAL;
+
+	if ((instr->len + instr->addr) > mtd->size)
+		return -EINVAL;
+
+	/* Check that both start and end of the requested erase are
+	 * aligned with the erasesize at the appropriate addresses.
+	 */
+
+	i = 0;
+
+	/* Skip all erase regions which are ended before the start of 
+	   the requested erase. Actually, to save on the calculations,
+	   we skip to the first erase region which starts after the
+	   start of the requested erase, and then go back one.
+	*/
+	
+	while (i < mtd->numeraseregions && instr->addr >= regions[i].offset)
+	       i++;
+	i--;
+
+	/* OK, now i is pointing at the erase region in which this 
+	   erase request starts. Check the start of the requested
+	   erase range is aligned with the erase size which is in
+	   effect here.
+	*/
+
+	if (instr->addr & (regions[i].erasesize-1))
+		return -EINVAL;
+
+	/* Remember the erase region we start on */
+	first = i;
+
+	/* Next, check that the end of the requested erase is aligned
+	 * with the erase region at that address.
+	 */
+
+	while (i<mtd->numeraseregions && (instr->addr + instr->len) >= regions[i].offset)
+		i++;
+
+	/* As before, drop back one to point at the region in which
+	   the address actually falls
+	*/
+	i--;
+	
+	if ((instr->addr + instr->len) & (regions[i].erasesize-1))
+		return -EINVAL;
+	
+	chipnum = instr->addr >> cfi->chipshift;
+	adr = instr->addr - (chipnum << cfi->chipshift);
+	len = instr->len;
+
+	i=first;
+
+	while(len) {
+		ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
+
+		if (ret)
+			return ret;
+
+		adr += regions[i].erasesize;
+		len -= regions[i].erasesize;
+
+		if (adr % (1<< cfi->chipshift) == ((regions[i].offset + (regions[i].erasesize * regions[i].numblocks)) %( 1<< cfi->chipshift)))
+			i++;
+
+		if (adr >> cfi->chipshift) {
+			adr = 0;
+			chipnum++;
+			
+			if (chipnum >= cfi->numchips)
+			break;
+		}
+	}
+
+	instr->state = MTD_ERASE_DONE;
+	if (instr->callback)
+		instr->callback(instr);
+	
+	return 0;
+}
+
+static int cfi_amdstd_erase_onesize(struct mtd_info *mtd, struct erase_info *instr)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	unsigned long adr, len;
+	int chipnum, ret = 0;
+
+	if (instr->addr & (mtd->erasesize - 1))
+		return -EINVAL;
+
+	if (instr->len & (mtd->erasesize -1))
+		return -EINVAL;
+
+	if ((instr->len + instr->addr) > mtd->size)
+		return -EINVAL;
+
+	chipnum = instr->addr >> cfi->chipshift;
+	adr = instr->addr - (chipnum << cfi->chipshift);
+	len = instr->len;
+
+	while(len) {
+		ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
+
+		if (ret)
+			return ret;
+
+		adr += mtd->erasesize;
+		len -= mtd->erasesize;
+
+		if (adr >> cfi->chipshift) {
+			adr = 0;
+			chipnum++;
+			
+			if (chipnum >= cfi->numchips)
+			break;
+		}
+	}
+		
+	instr->state = MTD_ERASE_DONE;
+	if (instr->callback)
+		instr->callback(instr);
+	
+	return 0;
+}
+
+static void cfi_amdstd_sync (struct mtd_info *mtd)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	int i;
+	struct flchip *chip;
+	int ret = 0;
+	DECLARE_WAITQUEUE(wait, current);
+
+	for (i=0; !ret && i<cfi->numchips; i++) {
+		chip = &cfi->chips[i];
+
+	retry:
+		cfi_spin_lock(chip->mutex);
+
+		switch(chip->state) {
+		case FL_READY:
+		case FL_STATUS:
+		case FL_CFI_QUERY:
+		case FL_JEDEC_QUERY:
+			chip->oldstate = chip->state;
+			chip->state = FL_SYNCING;
+			/* No need to wake_up() on this state change - 
+			 * as the whole point is that nobody can do anything
+			 * with the chip now anyway.
+			 */
+		case FL_SYNCING:
+			cfi_spin_unlock(chip->mutex);
+			break;
+
+		default:
+			/* Not an idle state */
+			add_wait_queue(&chip->wq, &wait);
+			
+			cfi_spin_unlock(chip->mutex);
+
+			schedule();
+
+		        remove_wait_queue(&chip->wq, &wait);
+			
+			goto retry;
+		}
+	}
+
+	/* Unlock the chips again */
+
+	for (i--; i >=0; i--) {
+		chip = &cfi->chips[i];
+
+		cfi_spin_lock(chip->mutex);
+		
+		if (chip->state == FL_SYNCING) {
+			chip->state = chip->oldstate;
+			wake_up(&chip->wq);
+		}
+		cfi_spin_unlock(chip->mutex);
+	}
+}
+
+
+static int cfi_amdstd_suspend(struct mtd_info *mtd)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	int i;
+	struct flchip *chip;
+	int ret = 0;
+//printk("suspend\n");
+
+	for (i=0; !ret && i<cfi->numchips; i++) {
+		chip = &cfi->chips[i];
+
+		cfi_spin_lock(chip->mutex);
+
+		switch(chip->state) {
+		case FL_READY:
+		case FL_STATUS:
+		case FL_CFI_QUERY:
+		case FL_JEDEC_QUERY:
+			chip->oldstate = chip->state;
+			chip->state = FL_PM_SUSPENDED;
+			/* No need to wake_up() on this state change - 
+			 * as the whole point is that nobody can do anything
+			 * with the chip now anyway.
+			 */
+		case FL_PM_SUSPENDED:
+			break;
+
+		default:
+			ret = -EAGAIN;
+			break;
+		}
+		cfi_spin_unlock(chip->mutex);
+	}
+
+	/* Unlock the chips again */
+
+	if (ret) {
+    		for (i--; i >=0; i--) {
+			chip = &cfi->chips[i];
+
+			cfi_spin_lock(chip->mutex);
+		
+			if (chip->state == FL_PM_SUSPENDED) {
+				chip->state = chip->oldstate;
+				wake_up(&chip->wq);
+			}
+			cfi_spin_unlock(chip->mutex);
+		}
+	}
+	
+	return ret;
+}
+
+static void cfi_amdstd_resume(struct mtd_info *mtd)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	int i;
+	struct flchip *chip;
+//printk("resume\n");
+
+	for (i=0; i<cfi->numchips; i++) {
+	
+		chip = &cfi->chips[i];
+
+		cfi_spin_lock(chip->mutex);
+		
+		if (chip->state == FL_PM_SUSPENDED) {
+			chip->state = FL_READY;
+			cfi_write(map, CMD(0xF0), chip->start);
+			wake_up(&chip->wq);
+		}
+		else
+			printk("Argh. Chip not in PM_SUSPENDED state upon resume()\n");
+
+		cfi_spin_unlock(chip->mutex);
+	}
+}
+
+static void cfi_amdstd_destroy(struct mtd_info *mtd)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	kfree(cfi->cmdset_priv);
+	kfree(cfi);
+}
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define cfi_amdstd_init init_module
+#define cfi_amdstd_exit cleanup_module
+#endif
+
+static char im_name[]="cfi_cmdset_0002";
+
+mod_init_t cfi_amdstd_init(void)
+{
+	inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0002);
+	return 0;
+}
+
+mod_exit_t cfi_amdstd_exit(void)
+{
+	inter_module_unregister(im_name);
+}
+
+module_init(cfi_amdstd_init);
+module_exit(cfi_amdstd_exit);
+
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/chips/cfi_jedec.c linux/drivers/mtd/chips/cfi_jedec.c
--- v2.4.5/linux/drivers/mtd/chips/cfi_jedec.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/chips/cfi_jedec.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,289 @@
+/* $Id: cfi_jedec.c,v 1.5 2001/06/02 14:52:23 dwmw2 Exp $ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+#include <linux/mtd/map.h>
+#include <linux/mtd/cfi.h>
+
+/* Manufacturers */
+#define MANUFACTURER_AMD	0x0001
+#define MANUFACTURER_FUJITSU	0x0004
+#define MANUFACTURER_ATMEL	0x001f
+#define MANUFACTURER_ST		0x0020
+#define MANUFACTURER_SST	0x00BF
+#define MANUFACTURER_TOSHIBA	0x0098
+
+/* AMD */
+#define AM29F800BB	0x2258
+#define AM29F800BT	0x22D6
+#define AM29LV800BB	0x225B
+#define AM29LV800BT	0x22DA
+#define AM29LV160DT	0x22C4
+#define AM29LV160DB	0x2249
+
+/* Atmel */
+#define AT49BV16X4	0x00c0
+#define AT49BV16X4T	0x00c2
+
+/* Fujitsu */
+#define MBM29LV160TE	0x22C4
+#define MBM29LV160BE	0x2249
+
+/* ST - www.st.com */
+#define M29W800T	0x00D7
+#define M29W160DT	0x22C4
+#define M29W160DB	0x2249
+
+/* SST */
+#define SST39LF800	0x2781
+#define SST39LF160	0x2782
+
+/* Toshiba */
+#define TC58FVT160	0x00C2
+#define TC58FVB160	0x0043
+
+
+struct amd_flash_info {
+	const __u16 mfr_id;
+	const __u16 dev_id;
+	const char *name;
+	const int DevSize;
+	const int InterfaceDesc;
+	const int NumEraseRegions;
+	const ulong regions[4];
+};
+
+#define ERASEINFO(size,blocks) (size<<8)|(blocks-1)
+
+#define SIZE_1MiB 20
+#define SIZE_2MiB 21
+#define SIZE_4MiB 22
+
+static const struct amd_flash_info jedec_table[] = {
+	{
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV160DT,
+		name: "AMD AM29LV160DT",
+		DevSize: SIZE_2MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x10000,31),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x04000,1)
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV160DB,
+		name: "AMD AM29LV160DB",
+		DevSize: SIZE_2MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x04000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x10000,31)
+		}
+	}, {
+		mfr_id: MANUFACTURER_TOSHIBA,
+		dev_id: TC58FVT160,
+		name: "Toshiba TC58FVT160",
+		DevSize: SIZE_2MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x10000,31),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x04000,1)
+		}
+	}, {
+		mfr_id: MANUFACTURER_FUJITSU,
+		dev_id: MBM29LV160TE,
+		name: "Fujitsu MBM29LV160TE",
+		DevSize: SIZE_2MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x10000,31),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x04000,1)
+		}
+	}, {
+		mfr_id: MANUFACTURER_TOSHIBA,
+		dev_id: TC58FVB160,
+		name: "Toshiba TC58FVB160",
+		DevSize: SIZE_2MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x04000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x10000,31)
+		}
+	}, {
+		mfr_id: MANUFACTURER_FUJITSU,
+		dev_id: MBM29LV160BE,
+		name: "Fujitsu MBM29LV160BE",
+		DevSize: SIZE_2MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x04000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x10000,31)
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV800BB,
+		name: "AMD AM29LV800BB",
+		DevSize: SIZE_1MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x04000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x10000,15),
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29F800BB,
+		name: "AMD AM29F800BB",
+		DevSize: SIZE_1MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x04000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x10000,15),
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV800BT,
+		name: "AMD AM29LV800BT",
+		DevSize: SIZE_1MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x10000,15),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x04000,1)
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29F800BT,
+		name: "AMD AM29F800BT",
+		DevSize: SIZE_1MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x10000,15),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x04000,1)
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV800BB,
+		name: "AMD AM29LV800BB",
+		DevSize: SIZE_1MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x10000,15),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x04000,1)
+		}
+	}, {
+		mfr_id: MANUFACTURER_ST,
+		dev_id: M29W800T,
+		name: "ST M29W800T",
+		DevSize: SIZE_1MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x10000,15),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x04000,1)
+		}
+	}, {
+		mfr_id: MANUFACTURER_ST,
+		dev_id: M29W160DT,
+		name: "ST M29W160DT",
+		DevSize: SIZE_2MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x10000,31),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x04000,1)
+		}
+	}, {
+		mfr_id: MANUFACTURER_ST,
+		dev_id: M29W160DB,
+		name: "ST M29W160DB",
+		DevSize: SIZE_2MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x04000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x10000,31)
+		}
+	}, {
+		mfr_id: MANUFACTURER_ATMEL,
+		dev_id: AT49BV16X4,
+		name: "Atmel AT49BV16X4",
+		DevSize: SIZE_2MiB,
+		NumEraseRegions: 3,
+		regions: {ERASEINFO(0x02000,8),
+			  ERASEINFO(0x08000,2),
+			  ERASEINFO(0x10000,30)
+		}
+	}, {
+                mfr_id: MANUFACTURER_ATMEL,
+                dev_id: AT49BV16X4T,
+                name: "Atmel AT49BV16X4T",
+                DevSize: SIZE_2MiB,
+                NumEraseRegions: 3,
+                regions: {ERASEINFO(0x10000,30),
+                          ERASEINFO(0x08000,2),
+			  ERASEINFO(0x02000,8)
+                }
+        }, {
+		0
+	} 
+};
+
+int cfi_jedec_lookup(int index, int mfr_id, int dev_id)
+{
+  	if (index>=0){
+		if (jedec_table[index].mfr_id == mfr_id &&
+		    jedec_table[index].dev_id == dev_id) return index;
+  	}
+  	else{
+		for (index=0; jedec_table[index].mfr_id; index++){
+		    if (jedec_table[index].mfr_id == mfr_id &&
+		        jedec_table[index].dev_id == dev_id) return index;
+		}
+  	}
+	return -1;
+}
+
+int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
+{
+int i,num_erase_regions;
+
+	printk("Found: %s\n",jedec_table[index].name);
+
+	num_erase_regions = jedec_table[index].NumEraseRegions;
+	
+	p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
+	if (!p_cfi->cfiq) {
+		//xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
+		return -1;
+	}
+
+	memset(p_cfi->cfiq,0,sizeof(struct cfi_ident));	
+	
+	p_cfi->cfiq->P_ID = P_ID_AMD_STD;
+	p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions;
+	p_cfi->cfiq->DevSize = jedec_table[index].DevSize;
+
+	for (i=0; i<num_erase_regions; i++){
+		p_cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i];
+	}	
+	return 0; 	/* ok */
+}
+
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/chips/cfi_probe.c linux/drivers/mtd/chips/cfi_probe.c
--- v2.4.5/linux/drivers/mtd/chips/cfi_probe.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/chips/cfi_probe.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,671 @@
+/* 
+   Common Flash Interface probe code.
+   (C) 2000 Red Hat. GPL'd.
+   $Id: cfi_probe.c,v 1.60 2001/06/03 01:32:57 nico Exp $
+*/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+#include <linux/mtd/map.h>
+#include <linux/mtd/cfi.h>
+
+/* #define DEBUG_CFI */
+
+#ifdef DEBUG_CFI
+static void print_cfi_ident(struct cfi_ident *);
+#endif
+
+int cfi_jedec_setup(struct cfi_private *p_cfi, int index);
+int cfi_jedec_lookup(int index, int mfr_id, int dev_id);
+
+static void check_cmd_set(struct map_info *, int, unsigned long);
+static struct cfi_private *cfi_cfi_probe(struct map_info *);
+struct mtd_info *cfi_probe(struct map_info *map);
+
+
+static struct mtd_chip_driver cfi_chipdrv = {
+	probe: cfi_probe,
+	name: "cfi",
+	module: THIS_MODULE
+};
+
+
+struct mtd_info *cfi_probe(struct map_info *map)
+{
+	struct mtd_info *mtd = NULL;
+	struct cfi_private *cfi;
+
+	/* First probe the map to see if we have CFI stuff there. */
+	cfi = cfi_cfi_probe(map);
+	
+	if (!cfi)
+		return NULL;
+
+	map->fldrv_priv = cfi;
+	/* OK we liked it. Now find a driver for the command set it talks */
+
+	check_cmd_set(map, 1, cfi->chips[0].start); /* First the primary cmdset */
+	if (!map->fldrv)
+		check_cmd_set(map, 0, cfi->chips[0].start); /* Then the secondary */
+	
+	/* check_cmd_set() will have used inter_module_get to increase
+	   the use count of the module which provides the command set 
+	   driver. If we're quitting, we have to decrease it again.
+	*/
+
+	if(map->fldrv) {
+		mtd = map->fldrv->probe(map);
+		/* Undo the use count we held onto from inter_module_get */
+#ifdef MODULE
+		if(map->fldrv->module)
+		  __MOD_DEC_USE_COUNT(map->fldrv->module);
+#endif
+		if (mtd)
+			return mtd;
+	}
+	printk(KERN_WARNING"cfi_probe: No supported Vendor Command Set found\n");
+	
+	kfree(cfi->cfiq);
+	kfree(cfi);
+	map->fldrv_priv = NULL;
+	return NULL;
+}
+
+static __u32 cfi_send_cmd(u_char cmd, __u32 base, struct map_info *map, struct cfi_private *cfi)
+{
+	return cfi_send_gen_cmd(cmd, 0x55, base, map, cfi, cfi->device_type, NULL);
+}
+
+/* check for QRY, or search for jedec id.
+   in: interleave,type,mode
+   ret: table index, <0 for error
+ */
+static int cfi_check_qry_or_id(struct map_info *map, __u32 base, int index,
+				struct cfi_private *cfi)
+{
+	__u32 manufacturer_id, device_id;
+	int osf = cfi->interleave * cfi->device_type;	// scale factor
+
+	//printk("cfi_check_qry_or_id: base=0x%08lx interl=%d type=%d index=%d\n",base,cfi->interleave,cfi->device_type,index);
+
+	switch(cfi->cfi_mode){
+	case 0:
+		if (cfi_read(map,base+osf*0x10)==cfi_build_cmd('Q',map,cfi) &&
+		    cfi_read(map,base+osf*0x11)==cfi_build_cmd('R',map,cfi) &&
+		    cfi_read(map,base+osf*0x12)==cfi_build_cmd('Y',map,cfi))
+			return 0;	// ok !
+		break;
+		
+	case 1:
+		manufacturer_id = cfi_read(map,base+0*osf);
+		device_id 	= cfi_read(map,base+1*osf);
+		//printk("cfi_check_qry_or_id: man=0x%lx,id=0x%lx\n",manufacturer_id, device_id);
+		
+		return cfi_jedec_lookup(index,manufacturer_id,device_id);	
+	}
+	
+	return -1; 	// nothing found
+}
+
+static void cfi_qry_mode(struct map_info *map, __u32 base, struct cfi_private *cfi)
+{
+	switch(cfi->cfi_mode){
+	case 0:
+		/* Query */
+		cfi_send_cmd(0x98, base, map, cfi);
+		break;
+		
+	case 1:
+		
+		/* Autoselect */
+		cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
+		cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
+		cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
+		break;
+	}
+}
+
+static int cfi_probe_chip_1(struct map_info *map, __u32 base,
+			  struct flchip *chips, struct cfi_private *cfi)
+{
+	int index;
+	__u32 tmp,ofs;
+	
+	ofs = cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, &tmp);
+	
+	cfi_qry_mode(map,base,cfi);
+	
+	index=cfi_check_qry_or_id(map,base,-1,cfi);
+	if (index<0) return -1;
+	
+	if (chips){
+		int i;
+
+		for (i=0; i<cfi->numchips; i++){
+			/* This chip should be in read mode if it's one
+			   we've already touched. */
+			if (cfi_check_qry_or_id(map,chips[i].start,index,cfi) >= 0){
+				cfi_send_gen_cmd(0xF0, 0, chips[i].start, map, cfi, cfi->device_type, NULL);
+				if (cfi_check_qry_or_id(map,chips[i].start,index,cfi) >= 0){
+					/* Yes it's got QRY for data. Most unfortunate.
+					   Stick the old one in read mode too. */
+					cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
+					if (cfi_check_qry_or_id(map,base,index,cfi) >= 0){
+						/* OK, so has the new one. Assume it's an alias */
+						printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
+						       map->name, base, chips[i].start);
+						return -1;
+					}
+				} else {
+					/* 
+					 * FIXME: Is this supposed to work?
+					 * The third argument is already
+					 * multiplied as this within the
+					 * function definition. (Nicolas Pitre)
+					 */
+					cfi_send_gen_cmd(0xF0, 0, base+0xaa*cfi->interleave * cfi->device_type, map, cfi, cfi->device_type, NULL);
+					cfi_send_gen_cmd(0xF0, 0, chips[i].start+0xaa*cfi->interleave * cfi->device_type, map, cfi, cfi->device_type, NULL);
+					return -1;
+				}
+			}
+		} /* for i */
+		
+		/* OK, if we got to here, then none of the previous chips appear to
+		   be aliases for the current one. */
+		if (cfi->numchips == MAX_CFI_CHIPS) {
+			printk(KERN_WARNING"%s: Too many flash chips detected. Increase MAX_CFI_CHIPS from %d.\n", map->name, MAX_CFI_CHIPS);
+			/* Doesn't matter about resetting it to Read Mode - we're not going to talk to it anyway */
+			return -1;
+		}
+		chips[cfi->numchips].start = base;
+		chips[cfi->numchips].state = FL_READY;
+		chips[cfi->numchips].mutex = &chips[cfi->numchips]._spinlock;
+		cfi->numchips++;
+		
+		/* Put it back into Read Mode */
+		cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
+	}
+	printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit mode\n", map->name, 
+	       cfi->interleave, cfi->device_type*8, base, map->buswidth*8);
+	
+	return index;
+}
+
+/*  put dev into qry mode, and try cfi and jedec modes for the given type/interleave
+ */
+static int cfi_probe_chip(struct map_info *map, __u32 base,
+			  struct flchip *chips, struct cfi_private *cfi)
+{
+	int index;
+	cfi->cfi_mode=0;	/* cfi mode */
+	
+	switch (cfi->device_type) {
+	case CFI_DEVICETYPE_X8:
+		cfi->addr_unlock1 = 0x555; 
+		cfi->addr_unlock2 = 0x2aa; 
+		break;
+	case CFI_DEVICETYPE_X16:
+		cfi->addr_unlock1 = 0xaaa;
+		if (map->buswidth == cfi->interleave) {
+			/* X16 chip(s) in X8 mode */
+			cfi->addr_unlock2 = 0x555;
+		} else {
+			cfi->addr_unlock2 = 0x554;
+		}
+		break;
+	case CFI_DEVICETYPE_X32:
+		cfi->addr_unlock1 = 0x1555; 
+		cfi->addr_unlock2 = 0xaaa; 
+		break;
+	default:
+		return 0;
+	}
+	index = cfi_probe_chip_1(map,base,chips,cfi);
+	if (index>=0) return index;
+	
+	cfi->cfi_mode=1;	/* jedec mode */
+	index = cfi_probe_chip_1(map,base,chips,cfi);
+	if (index>=0) return index;
+	
+	cfi->addr_unlock1 = 0x5555;
+	cfi->addr_unlock2 = 0x2aaa; 
+	index = cfi_probe_chip_1(map,base,chips,cfi);
+	
+	return index;
+}
+
+/*
+ * Since probeing for CFI chips requires writing to the device problems may
+ * occur if the flash is not present and RAM is accessed instead.  For now we
+ * assume that the flash is present so we don't check for RAM or replace
+ * possibly overwritten data.
+ */
+static int cfi_probe_new_chip(struct map_info *map, unsigned long base,
+			      struct flchip *chips, struct cfi_private *cfi)
+{
+int index;
+	switch (map->buswidth) {
+#ifdef CFIDEV_BUSWIDTH_1		
+	case CFIDEV_BUSWIDTH_1:
+		cfi->interleave = CFIDEV_INTERLEAVE_1;
+		cfi->device_type = CFI_DEVICETYPE_X8;
+		index = cfi_probe_chip(map,base,chips,cfi);
+		if (index>=0) return index;
+
+		cfi->device_type = CFI_DEVICETYPE_X16;
+		index = cfi_probe_chip(map,base,chips,cfi);
+		if (index>=0) return index;
+		break;			
+#endif
+
+#ifdef CFIDEV_BUSWIDTH_2		
+	case CFIDEV_BUSWIDTH_2:
+#ifdef CFIDEV_INTERLEAVE_1
+		cfi->interleave = CFIDEV_INTERLEAVE_1;
+		cfi->device_type = CFI_DEVICETYPE_X16;
+		index = cfi_probe_chip(map,base,chips,cfi);
+		if (index>=0) return index;
+#endif
+#ifdef CFIDEV_INTERLEAVE_2
+		cfi->interleave = CFIDEV_INTERLEAVE_2;
+		cfi->device_type = CFI_DEVICETYPE_X8;
+		index = cfi_probe_chip(map,base,chips,cfi);
+		if (index>=0) return index;
+
+		cfi->device_type = CFI_DEVICETYPE_X16;
+		index = cfi_probe_chip(map,base,chips,cfi);
+		if (index>=0) return index;
+
+#endif
+		break;			
+#endif
+
+#ifdef CFIDEV_BUSWIDTH_4
+	case CFIDEV_BUSWIDTH_4:
+#ifdef CFIDEV_INTERLEAVE_4
+		cfi->interleave = CFIDEV_INTERLEAVE_4;
+		cfi->device_type = CFI_DEVICETYPE_X16;
+		index = cfi_probe_chip(map,base,chips,cfi);
+		if (index>=0) return index;
+
+		cfi->device_type = CFI_DEVICETYPE_X32;
+		index = cfi_probe_chip(map,base,chips,cfi);
+		if (index>=0) return index;
+
+		cfi->device_type = CFI_DEVICETYPE_X8;
+		index = cfi_probe_chip(map,base,chips,cfi);
+		if (index>=0) return index;
+#endif
+#ifdef CFIDEV_INTERLEAVE_2
+		cfi->interleave = CFIDEV_INTERLEAVE_2;
+		cfi->device_type = CFI_DEVICETYPE_X16;
+		index = cfi_probe_chip(map,base,chips,cfi);
+		if (index>=0) return index;
+#endif
+#ifdef CFIDEV_INTERLEAVE_1
+                cfi->interleave = CFIDEV_INTERLEAVE_1;
+                cfi->device_type = CFI_DEVICETYPE_X32;
+                index = cfi_probe_chip(map,base,chips,cfi);
+                if (index>=0) return index;
+#endif
+		break;
+#endif
+	default:
+		printk(KERN_WARNING "cfi_probe called with unsupported buswidth %d\n", map->buswidth);
+		return -1;
+	} // switch
+	return -1;
+}
+
+static struct cfi_private *cfi_cfi_probe(struct map_info *map)
+{
+	unsigned long base=0;
+	struct cfi_private cfi;
+	struct cfi_private *retcfi;
+	struct flchip chip[MAX_CFI_CHIPS];
+	int i,index; 
+	char num_erase_regions;
+ 	int ofs_factor;
+
+	memset(&cfi, 0, sizeof(cfi));
+
+	/* The first invocation (with chips == NULL) leaves the device in Query Mode */
+	index = cfi_probe_new_chip(map, 0, NULL, &cfi);
+
+	if (index<0) {
+		printk(KERN_WARNING"%s: Found no CFI device at location zero\n", map->name);
+		/* Doesn't appear to be CFI-compliant at all */
+		return NULL;
+	}
+
+	/* Read the Basic Query Structure from the device */
+
+ 	ofs_factor = cfi.interleave*cfi.device_type;
+
+	/* First, work out the amount of space to allocate */
+	if (cfi.cfi_mode==0){
+		num_erase_regions = cfi_read_query(map, base + (0x10 + 28)*ofs_factor);
+
+#ifdef DEBUG_CFI
+		printk("Number of erase regions: %d\n", num_erase_regions);
+#endif
+
+		cfi.cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
+		if (!cfi.cfiq) {
+			printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
+			return NULL;
+		}
+
+		memset(cfi.cfiq,0,sizeof(struct cfi_ident));	
+
+		cfi.fast_prog=1;		/* CFI supports fast programming */
+
+			/* CFI flash */
+		for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++) {
+			((unsigned char *)cfi.cfiq)[i] = cfi_read_query(map,base + (0x10 + i)*ofs_factor);
+		}
+
+		/* Do any necessary byteswapping */
+		cfi.cfiq->P_ID = le16_to_cpu(cfi.cfiq->P_ID);
+
+		cfi.cfiq->P_ADR = le16_to_cpu(cfi.cfiq->P_ADR);
+		cfi.cfiq->A_ID = le16_to_cpu(cfi.cfiq->A_ID);
+		cfi.cfiq->A_ADR = le16_to_cpu(cfi.cfiq->A_ADR);
+		cfi.cfiq->InterfaceDesc = le16_to_cpu(cfi.cfiq->InterfaceDesc);
+		cfi.cfiq->MaxBufWriteSize = le16_to_cpu(cfi.cfiq->MaxBufWriteSize);
+
+		for (i=0; i<cfi.cfiq->NumEraseRegions; i++) {
+			cfi.cfiq->EraseRegionInfo[i] = le32_to_cpu(cfi.cfiq->EraseRegionInfo[i]);
+
+#ifdef DEBUG_CFI		
+			printk("  Erase Region #%d: BlockSize 0x%4.4X bytes, %d blocks\n",
+		       		i, (cfi.cfiq->EraseRegionInfo[i] >> 8) & ~0xff, 
+		       		(cfi.cfiq->EraseRegionInfo[i] & 0xffff) + 1);
+#endif
+		}
+	}
+	else{
+		/* JEDEC flash */
+		if (cfi_jedec_setup(&cfi,index)<0){
+			printk(KERN_WARNING "cfi_jedec_setup failed\n");
+			return NULL;
+		}
+	}
+
+	if (cfi.cfiq->NumEraseRegions == 0) {
+		printk(KERN_WARNING "Number of erase regions is zero\n");
+		kfree(cfi.cfiq);
+		return NULL;
+	}
+
+#ifdef DEBUG_CFI
+	/* Dump the information therein */
+	print_cfi_ident(cfi.cfiq);
+#endif
+
+	cfi_send_cmd(0xFF, base, map, &cfi);
+
+	/* OK. We've worked out what it is and we're happy with it. Now see if there are others */
+
+	chip[0].start = 0;
+	chip[0].state = FL_READY;
+	chip[0].mutex = &chip[0]._spinlock;
+
+	cfi.chipshift = cfi.cfiq->DevSize;
+	cfi.numchips = 1;
+
+	if (!cfi.chipshift) {
+		printk(KERN_ERR"cfi.chipsize is zero. This is bad. cfi.cfiq->DevSize is %d\n", cfi.cfiq->DevSize);
+		kfree(cfi.cfiq);
+		return NULL;
+	}
+	switch (cfi.interleave) {
+	    case 2: cfi.chipshift += 1; break;
+	    case 4: cfi.chipshift += 2; break;
+	}
+
+	for (base = (1<<cfi.chipshift); base < map->size; base += (1<<cfi.chipshift))
+		cfi_probe_chip_1(map, base, &chip[0], &cfi);
+
+	retcfi = kmalloc(sizeof(struct cfi_private) + cfi.numchips * sizeof(struct flchip), GFP_KERNEL);
+
+	if (!retcfi) {
+		printk(KERN_WARNING "%s: kmalloc failed for CFI private structure\n", map->name);
+		kfree(cfi.cfiq);
+		return NULL;
+	}
+	memcpy(retcfi, &cfi, sizeof(cfi));
+	memcpy(&retcfi->chips[0], chip, sizeof(struct flchip) * cfi.numchips);
+	for (i=0; i< retcfi->numchips; i++) {
+		init_waitqueue_head(&retcfi->chips[i].wq);
+		spin_lock_init(&retcfi->chips[i]._spinlock);
+		retcfi->chips[i].mutex = &retcfi->chips[i]._spinlock;
+	}
+	return retcfi;
+}
+
+#ifdef DEBUG_CFI
+static char *vendorname(__u16 vendor) 
+{
+	switch (vendor) {
+	case P_ID_NONE:
+		return "None";
+		
+	case P_ID_INTEL_EXT:
+		return "Intel/Sharp Extended";
+		
+	case P_ID_AMD_STD:
+		return "AMD/Fujitsu Standard";
+		
+	case P_ID_INTEL_STD:
+		return "Intel/Sharp Standard";
+		
+	case P_ID_AMD_EXT:
+		return "AMD/Fujitsu Extended";
+		
+	case P_ID_MITSUBISHI_STD:
+		return "Mitsubishi Standard";
+		
+	case P_ID_MITSUBISHI_EXT:
+		return "Mitsubishi Extended";
+		
+	case P_ID_RESERVED:
+		return "Not Allowed / Reserved for Future Use";
+		
+	default:
+		return "Unknown";
+	}
+}
+
+
+static void print_cfi_ident(struct cfi_ident *cfip)
+{
+#if 0
+	if (cfip->qry[0] != 'Q' || cfip->qry[1] != 'R' || cfip->qry[2] != 'Y') {
+		printk("Invalid CFI ident structure.\n");
+		return;
+	}	
+#endif		
+	printk("Primary Vendor Command Set: %4.4X (%s)\n", cfip->P_ID, vendorname(cfip->P_ID));
+	if (cfip->P_ADR)
+		printk("Primary Algorithm Table at %4.4X\n", cfip->P_ADR);
+	else
+		printk("No Primary Algorithm Table\n");
+	
+	printk("Alternative Vendor Command Set: %4.4X (%s)\n", cfip->A_ID, vendorname(cfip->A_ID));
+	if (cfip->A_ADR)
+		printk("Alternate Algorithm Table at %4.4X\n", cfip->A_ADR);
+	else
+		printk("No Alternate Algorithm Table\n");
+		
+		
+	printk("Vcc Minimum: %x.%x V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf);
+	printk("Vcc Maximum: %x.%x V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf);
+	if (cfip->VppMin) {
+		printk("Vpp Minimum: %x.%x V\n", cfip->VppMin >> 4, cfip->VppMin & 0xf);
+		printk("Vpp Maximum: %x.%x V\n", cfip->VppMax >> 4, cfip->VppMax & 0xf);
+	}
+	else
+		printk("No Vpp line\n");
+	
+	printk("Typical byte/word write timeout: %d µs\n", 1<<cfip->WordWriteTimeoutTyp);
+	printk("Maximum byte/word write timeout: %d µs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp));
+	
+	if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) {
+		printk("Typical full buffer write timeout: %d µs\n", 1<<cfip->BufWriteTimeoutTyp);
+		printk("Maximum full buffer write timeout: %d µs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp));
+	}
+	else
+		printk("Full buffer write not supported\n");
+	
+	printk("Typical block erase timeout: %d µs\n", 1<<cfip->BlockEraseTimeoutTyp);
+	printk("Maximum block erase timeout: %d µs\n", (1<<cfip->BlockEraseTimeoutMax) * (1<<cfip->BlockEraseTimeoutTyp));
+	if (cfip->ChipEraseTimeoutTyp || cfip->ChipEraseTimeoutMax) {
+		printk("Typical chip erase timeout: %d µs\n", 1<<cfip->ChipEraseTimeoutTyp); 
+		printk("Maximum chip erase timeout: %d µs\n", (1<<cfip->ChipEraseTimeoutMax) * (1<<cfip->ChipEraseTimeoutTyp));
+	}
+	else
+		printk("Chip erase not supported\n");
+	
+	printk("Device size: 0x%X bytes (%d MiB)\n", 1 << cfip->DevSize, 1<< (cfip->DevSize - 20));
+	printk("Flash Device Interface description: 0x%4.4X\n", cfip->InterfaceDesc);
+	switch(cfip->InterfaceDesc) {
+	case 0:
+		printk("  - x8-only asynchronous interface\n");
+		break;
+		
+	case 1:
+		printk("  - x16-only asynchronous interface\n");
+		break;
+		
+	case 2:
+		printk("  - supports x8 and x16 via BYTE# with asynchronous interface\n");
+		break;
+		
+	case 3:
+		printk("  - x32-only asynchronous interface\n");
+		break;
+		
+	case 65535:
+		printk("  - Not Allowed / Reserved\n");
+		break;
+		
+	default:
+		printk("  - Unknown\n");
+		break;
+	}
+	
+	printk("Max. bytes in buffer write: 0x%x\n", 1<< cfip->MaxBufWriteSize);
+	printk("Number of Erase Block Regions: %d\n", cfip->NumEraseRegions);
+	
+}
+#endif /* DEBUG_CFI */
+
+typedef void cfi_cmdset_fn_t(struct map_info *, int, unsigned long);
+
+extern cfi_cmdset_fn_t cfi_cmdset_0001;
+extern cfi_cmdset_fn_t cfi_cmdset_0002;
+
+static void cfi_cmdset_unknown(struct map_info *map, int primary, unsigned long base)
+{
+	__u16 adr;
+	struct cfi_private *cfi = map->fldrv_priv;
+	__u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID;
+#ifdef HAVE_INTER_MODULE
+	char probename[32];
+	cfi_cmdset_fn_t *probe_function;
+
+	sprintf(probename, "cfi_cmdset_%4.4X", type);
+		
+	probe_function = inter_module_get_request(probename, probename);
+
+	if (probe_function) {
+		(*probe_function)(map, primary, base);
+		return;
+	}	
+#endif
+	printk(KERN_NOTICE "Support for command set %04X not present\n", type);
+	/* This was a command set we don't know about. Print only the basic info */
+	adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
+	
+	if (!adr) {
+		printk(" No Extended Query Table\n");
+	}
+	else {
+ 		int ofs_factor = cfi->interleave * cfi->device_type;
+
+		if (cfi_read_query(map,base + adr*ofs_factor) != (primary?'P':'A') ||
+		    cfi_read_query(map,base + (adr+1)*ofs_factor) != (primary?'R':'L') ||
+		    cfi_read_query(map,base + (adr+2)*ofs_factor) != (primary?'I':'T')) {
+			printk ("Invalid Extended Query Table at %4.4X: %2.2X %2.2X %2.2X\n",
+				adr,
+				cfi_read_query(map,base + adr*ofs_factor),
+				cfi_read_query(map,base + (adr+1)*ofs_factor),
+				cfi_read_query(map,base + (adr+2)*ofs_factor));
+		}
+		else {
+			printk(" Extended Query Table version %c.%c\n",
+			       cfi_read_query(map,base + (adr+3)*ofs_factor), 
+			       cfi_read_query(map,base + (adr+4)*ofs_factor));
+		}
+	}
+	cfi_send_cmd(0xff, base, map, cfi);
+}
+
+static void check_cmd_set(struct map_info *map, int primary, unsigned long base)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
+	__u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID;
+	
+	if (type == P_ID_NONE || type == P_ID_RESERVED)
+		return;
+	/* Put it in query mode */
+	cfi_qry_mode(map,base,cfi);
+
+	switch(type){
+		/* Urgh. Ifdefs. The version with weak symbols was
+		 * _much_ nicer. Shame it didn't seem to work on
+		 * anything but x86, really.
+		 * But we can't rely in inter_module_get() because
+		 * that'd mean we depend on link order.
+		 */
+#ifdef CONFIG_MTD_CFI_INTELEXT
+	case 0x0001:
+	case 0x0003:
+		return cfi_cmdset_0001(map, primary, base);
+#endif
+#ifdef CONFIG_MTD_CFI_AMDSTD
+	case 0x0002:
+		return cfi_cmdset_0002(map, primary, base);
+#endif
+	}
+
+	return cfi_cmdset_unknown(map, primary, base);
+}
+
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define cfi_probe_init init_module
+#define cfi_probe_exit cleanup_module
+#endif
+
+mod_init_t cfi_probe_init(void)
+{
+	register_mtd_chip_driver(&cfi_chipdrv);
+	return 0;
+}
+
+mod_exit_t cfi_probe_exit(void)
+{
+	unregister_mtd_chip_driver(&cfi_chipdrv);
+}
+
+module_init(cfi_probe_init);
+module_exit(cfi_probe_exit);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/chips/chipreg.c linux/drivers/mtd/chips/chipreg.c
--- v2.4.5/linux/drivers/mtd/chips/chipreg.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/chips/chipreg.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,92 @@
+/*
+ * $Id: chipreg.c,v 1.8 2001/06/09 19:58:19 dwmw2 Exp $
+ *
+ * Registration for chip drivers
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/kmod.h>
+#include <linux/spinlock.h>
+#include <linux/mtd/compatmac.h>
+#include <linux/mtd/map.h>
+
+spinlock_t chip_drvs_lock = SPIN_LOCK_UNLOCKED;
+static LIST_HEAD(chip_drvs_list);
+
+void register_mtd_chip_driver(struct mtd_chip_driver *drv)
+{
+	spin_lock(&chip_drvs_lock);
+	list_add(&drv->list, &chip_drvs_list);
+	spin_unlock(&chip_drvs_lock);
+}
+
+void unregister_mtd_chip_driver(struct mtd_chip_driver *drv)
+{
+	spin_lock(&chip_drvs_lock);
+	list_del(&drv->list);
+	spin_unlock(&chip_drvs_lock);
+}
+
+static struct mtd_chip_driver *get_mtd_chip_driver (char *name)
+{
+	struct list_head *pos;
+	struct mtd_chip_driver *ret = NULL, *this;
+
+	spin_lock(&chip_drvs_lock);
+
+	list_for_each(pos, &chip_drvs_list) {
+		this = list_entry(pos, typeof(*this), list);
+		
+		if (!strcmp(this->name, name)) {
+			ret = this;
+			break;
+		}
+	}
+	if (ret && !try_inc_mod_count(ret->module)) {
+		/* Eep. Failed. */
+		ret = NULL;
+	}
+
+	spin_unlock(&chip_drvs_lock);
+
+	return ret;
+}
+
+	/* Hide all the horrid details, like some silly person taking
+	   get_module_symbol() away from us, from the caller. */
+
+struct mtd_info *do_map_probe(char *name, struct map_info *map)
+{
+	struct mtd_chip_driver *drv;
+	struct mtd_info *ret;
+
+	drv = get_mtd_chip_driver(name);
+
+	if (!drv && !request_module(name))
+		drv = get_mtd_chip_driver(name);
+
+	if (!drv)
+		return NULL;
+
+	ret = drv->probe(map);
+#ifdef CONFIG_MODULES
+	/* We decrease the use count here. It may have been a 
+	   probe-only module, which is no longer required from this
+	   point, having given us a handle on (and increased the use
+	   count of) the actual driver code.
+	*/
+	if(drv->module)
+		__MOD_DEC_USE_COUNT(drv->module);
+#endif
+
+	if (ret)
+		return ret;
+	
+	return NULL;
+}
+
+EXPORT_SYMBOL(register_mtd_chip_driver);
+EXPORT_SYMBOL(unregister_mtd_chip_driver);
+EXPORT_SYMBOL(do_map_probe);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/chips/jedec.c linux/drivers/mtd/chips/jedec.c
--- v2.4.5/linux/drivers/mtd/chips/jedec.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/chips/jedec.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,880 @@
+
+/* JEDEC Flash Interface.
+ * This is an older type of interface for self programming flash. It is 
+ * commonly use in older AMD chips and is obsolete compared with CFI.
+ * It is called JEDEC because the JEDEC association distributes the ID codes
+ * for the chips.
+ *
+ * See the AMD flash databook for information on how to operate the interface.
+ *
+ * This code does not support anything wider than 8 bit flash chips, I am
+ * not going to guess how to send commands to them, plus I expect they will
+ * all speak CFI..
+ *
+ * $Id: jedec.c,v 1.8 2001/06/09 23:56:57 dwmw2 Exp $
+ */
+
+#include <linux/mtd/jedec.h>
+
+struct mtd_info *jedec_probe(struct map_info *);
+int jedec_probe8(struct map_info *map,unsigned long base,
+		  struct jedec_private *priv);
+int jedec_probe16(struct map_info *map,unsigned long base,
+		  struct jedec_private *priv);
+int jedec_probe32(struct map_info *map,unsigned long base,
+		  struct jedec_private *priv);
+static void jedec_flash_chip_scan(struct jedec_private *priv,unsigned long start,
+			    unsigned long len);
+static int flash_erase(struct mtd_info *mtd, struct erase_info *instr);
+static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
+		       size_t *retlen, const u_char *buf);
+
+static unsigned long my_bank_size;
+
+/* Listing of parts and sizes. We need this table to learn the sector
+   size of the chip and the total length */
+static const struct JEDECTable JEDEC_table[] = 
+  {{0x013D,"AMD Am29F017D",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
+   {0x01AD,"AMD Am29F016",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
+   {0x01D5,"AMD Am29F080",1*1024*1024,64*1024,MTD_CAP_NORFLASH},
+   {0x01A4,"AMD Am29F040",512*1024,64*1024,MTD_CAP_NORFLASH},
+   {0x20E3,"AMD Am29W040B",512*1024,64*1024,MTD_CAP_NORFLASH},
+   {0xC2AD,"Macronix MX29F016",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
+   {}};
+
+static void jedec_sync(struct mtd_info *mtd) {};
+static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len, 
+		      size_t *retlen, u_char *buf);
+static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len, 
+			     size_t *retlen, u_char *buf);
+
+struct mtd_info *jedec_probe(struct map_info *map);
+
+
+
+static struct mtd_chip_driver jedec_chipdrv = {
+	probe: jedec_probe,
+	name: "jedec",
+	module: THIS_MODULE
+};
+
+/* Probe entry point */
+struct jedec_private priv;
+struct mtd_info __MTD;
+struct mtd_info *jedec_probe(struct map_info *map)
+{
+   struct mtd_info *MTD = &__MTD;
+   unsigned long Base;
+   unsigned long SectorSize;
+   unsigned count;
+   unsigned I,Uniq;
+   char Part[200];
+   memset(&priv,0,sizeof(priv));
+   
+   my_bank_size = map->size;
+
+   if (map->size/my_bank_size > MAX_JEDEC_CHIPS)
+   {
+      printk("mtd: Increase MAX_JEDEC_CHIPS, too many banks.\n");
+      return 0;
+   }
+   
+   for (Base = 0; Base < map->size; Base += my_bank_size)
+   {
+      // Perhaps zero could designate all tests?
+      if (map->buswidth == 0)
+	 map->buswidth = 1;
+      
+      if (map->buswidth == 1){
+	 if (jedec_probe8(map,Base,&priv) == 0) {
+		 printk("did recognize jedec chip\n");
+	         return 0;
+	 }
+      }
+      if (map->buswidth == 2)
+	 jedec_probe16(map,Base,&priv);
+      if (map->buswidth == 4)
+	 jedec_probe32(map,Base,&priv);
+   }
+   
+   // Get the biggest sector size
+   SectorSize = 0;
+   for (I = 0; priv.chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
+   {
+	   //	   printk("priv.chips[%d].jedec is %x\n",I,priv.chips[I].jedec);
+	   //	   printk("priv.chips[%d].sectorsize is %lx\n",I,priv.chips[I].sectorsize);
+      if (priv.chips[I].sectorsize > SectorSize)
+	 SectorSize = priv.chips[I].sectorsize;
+   }
+   
+   // Quickly ensure that the other sector sizes are factors of the largest
+   for (I = 0; priv.chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
+   {
+      if ((SectorSize/priv.chips[I].sectorsize)*priv.chips[I].sectorsize != SectorSize)
+      {
+	 printk("mtd: Failed. Device has incompatible mixed sector sizes\n");
+	 return 0;
+      }      
+   }
+   
+   /* Generate a part name that includes the number of different chips and
+      other configuration information */
+   count = 1;
+   strncpy(Part,map->name,sizeof(Part)-10);
+   Part[sizeof(Part)-11] = 0;
+   strcat(Part," ");
+   Uniq = 0;
+   for (I = 0; priv.chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
+   {
+      const struct JEDECTable *JEDEC;
+      
+      if (priv.chips[I+1].jedec == priv.chips[I].jedec)
+      {
+	 count++;
+	 continue;
+      }
+      
+      // Locate the chip in the jedec table
+      JEDEC = jedec_idtoinf(priv.chips[I].jedec >> 8,priv.chips[I].jedec);
+      if (JEDEC == 0)
+      {
+	 printk("mtd: Internal Error, JEDEC not set\n");
+	 return 0;
+      }
+      
+      if (Uniq != 0)
+	 strcat(Part,",");
+      Uniq++;
+      
+      if (count != 1)
+	 sprintf(Part+strlen(Part),"%x*[%s]",count,JEDEC->name);
+      else
+	 sprintf(Part+strlen(Part),"%s",JEDEC->name);
+      if (strlen(Part) > sizeof(Part)*2/3)
+	 break;
+      count = 1;
+   }   
+
+   /* Determine if the chips are organized in a linear fashion, or if there
+      are empty banks. Note, the last bank does not count here, only the
+      first banks are important. Holes on non-bank boundaries can not exist
+      due to the way the detection algorithm works. */
+   if (priv.size < my_bank_size)
+      my_bank_size = priv.size;
+   priv.is_banked = 0;
+   //printk("priv.size is %x, my_bank_size is %x\n",priv.size,my_bank_size);
+   //printk("priv.bank_fill[0] is %x\n",priv.bank_fill[0]);
+   if (!priv.size) {
+	   printk("priv.size is zero\n");
+	   return 0;
+   }
+   if (priv.size/my_bank_size) {
+	   if (priv.size/my_bank_size == 1) {
+		   priv.size = my_bank_size;
+	   }
+	   else {
+		   for (I = 0; I != priv.size/my_bank_size - 1; I++)
+		   {
+		      if (priv.bank_fill[I] != my_bank_size)
+			 priv.is_banked = 1;
+		      
+		      /* This even could be eliminated, but new de-optimized read/write
+			 functions have to be written */
+		      printk("priv.bank_fill[%d] is %lx, priv.bank_fill[0] is %lx\n",I,priv.bank_fill[I],priv.bank_fill[0]);
+		      if (priv.bank_fill[I] != priv.bank_fill[0])
+		      {
+			 printk("mtd: Failed. Cannot handle unsymetric banking\n");
+			 return 0;
+		      }      
+		   }
+	   }
+   }
+   if (priv.is_banked == 1)
+      strcat(Part,", banked");
+
+   //   printk("Part: '%s'\n",Part);
+   
+   memset(MTD,0,sizeof(*MTD));
+  // strncpy(MTD->name,Part,sizeof(MTD->name));
+  // MTD->name[sizeof(MTD->name)-1] = 0;
+   MTD->name = map->name;
+   MTD->type = MTD_NORFLASH;
+   MTD->flags = MTD_CAP_NORFLASH;
+   MTD->erasesize = SectorSize*(map->buswidth);
+   //   printk("MTD->erasesize is %x\n",(unsigned int)MTD->erasesize);
+   MTD->size = priv.size;
+   //   printk("MTD->size is %x\n",(unsigned int)MTD->size);
+   //MTD->module = THIS_MODULE; // ? Maybe this should be the low level module?
+   MTD->erase = flash_erase;
+   if (priv.is_banked == 1)
+      MTD->read = jedec_read_banked;
+   else
+      MTD->read = jedec_read;
+   MTD->write = flash_write;
+   MTD->sync = jedec_sync;
+   MTD->priv = map;
+   map->fldrv_priv = &priv;
+   map->fldrv = &jedec_chipdrv;
+   MOD_INC_USE_COUNT;
+   return MTD;
+}
+
+/* Helper for the JEDEC function, JEDEC numbers all have odd parity */
+static int checkparity(u_char C)
+{
+   u_char parity = 0;
+   while (C != 0)
+   {
+      parity ^= C & 1;
+      C >>= 1;
+   }
+
+   return parity == 1;
+}
+
+
+/* Take an array of JEDEC numbers that represent interleved flash chips
+   and process them. Check to make sure they are good JEDEC numbers, look
+   them up and then add them to the chip list */   
+int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
+		  unsigned long base,struct jedec_private *priv)
+{
+   unsigned I,J;
+   unsigned long Size;
+   unsigned long SectorSize;
+   const struct JEDECTable *JEDEC;
+
+   // Test #2 JEDEC numbers exhibit odd parity
+   for (I = 0; I != Count; I++)
+   {
+      if (checkparity(Mfg[I]) == 0 || checkparity(Id[I]) == 0)
+	 return 0;
+   }
+   
+   // Finally, just make sure all the chip sizes are the same
+   JEDEC = jedec_idtoinf(Mfg[0],Id[0]);
+   
+   if (JEDEC == 0)
+   {
+      printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]);
+      return 0;
+   }
+   
+   Size = JEDEC->size;
+   SectorSize = JEDEC->sectorsize;
+   for (I = 0; I != Count; I++)
+   {
+      JEDEC = jedec_idtoinf(Mfg[0],Id[0]);
+      if (JEDEC == 0)
+      {
+	 printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]);
+	 return 0;
+      }
+
+      if (Size != JEDEC->size || SectorSize != JEDEC->sectorsize)
+      {
+	 printk("mtd: Failed. Interleved flash does not have matching characteristics\n");
+	 return 0;
+      }      
+   }
+
+   // Load the Chips
+   for (I = 0; I != MAX_JEDEC_CHIPS; I++)
+   {
+      if (priv->chips[I].jedec == 0)
+	 break;
+   }
+
+   if (I + Count > MAX_JEDEC_CHIPS)
+   {
+      printk("mtd: Device has too many chips. Increase MAX_JEDEC_CHIPS\n");
+      return 0;
+   }      
+   
+   // Add them to the table
+   for (J = 0; J != Count; J++)
+   {
+      unsigned long Bank;
+	 
+      JEDEC = jedec_idtoinf(Mfg[J],Id[J]);
+      priv->chips[I].jedec = (Mfg[J] << 8) | Id[J];
+      priv->chips[I].size = JEDEC->size;
+      priv->chips[I].sectorsize = JEDEC->sectorsize;
+      priv->chips[I].base = base + J;
+      priv->chips[I].datashift = J*8;
+      priv->chips[I].capabilities = JEDEC->capabilities;
+      priv->chips[I].offset = priv->size + J;
+
+      // log2 n :|
+      priv->chips[I].addrshift = 0;
+      for (Bank = Count; Bank != 1; Bank >>= 1, priv->chips[I].addrshift++);
+      
+      // Determine how filled this bank is.
+      Bank = base & (~(my_bank_size-1));
+      if (priv->bank_fill[Bank/my_bank_size] < base + 
+	  (JEDEC->size << priv->chips[I].addrshift) - Bank)
+	 priv->bank_fill[Bank/my_bank_size] =  base + (JEDEC->size << priv->chips[I].addrshift) - Bank;
+      I++;
+   }
+
+   priv->size += priv->chips[I-1].size*Count;
+	 
+   return priv->chips[I-1].size;
+}
+
+/* Lookup the chip information from the JEDEC ID table. */
+const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id)
+{
+   __u16 Id = (mfr << 8) | id;
+   unsigned long I = 0;
+   for (I = 0; JEDEC_table[I].jedec != 0; I++)
+      if (JEDEC_table[I].jedec == Id)
+	 return JEDEC_table + I;
+   return 0;
+}
+
+// Look for flash using an 8 bit bus interface
+int jedec_probe8(struct map_info *map,unsigned long base,
+		  struct jedec_private *priv)
+{ 
+   #define flread(x) map->read8(map,base+x)
+   #define flwrite(v,x) map->write8(map,v,base+x)
+
+   const unsigned long AutoSel1 = 0xAA;
+   const unsigned long AutoSel2 = 0x55;
+   const unsigned long AutoSel3 = 0x90;
+   const unsigned long Reset = 0xF0;
+   __u32 OldVal;
+   __u8 Mfg[1];
+   __u8 Id[1];
+   unsigned I;
+   unsigned long Size;
+
+   // Wait for any write/erase operation to settle
+   OldVal = flread(base);
+   for (I = 0; OldVal != flread(base) && I < 10000; I++)
+      OldVal = flread(base);
+   
+   // Reset the chip
+   flwrite(Reset,0x555); 
+   
+   // Send the sequence
+   flwrite(AutoSel1,0x555);
+   flwrite(AutoSel2,0x2AA);
+   flwrite(AutoSel3,0x555);
+   
+   //  Get the JEDEC numbers
+   Mfg[0] = flread(0);
+   Id[0] = flread(1);
+   //   printk("Mfg is %x, Id is %x\n",Mfg[0],Id[0]);
+      
+   Size = handle_jedecs(map,Mfg,Id,1,base,priv);
+   //   printk("handle_jedecs Size is %x\n",(unsigned int)Size);
+   if (Size == 0)
+   {
+      flwrite(Reset,0x555);
+      return 0;
+   }
+   
+
+   // Reset.
+   flwrite(Reset,0x555);
+   
+   return 1;
+   
+   #undef flread
+   #undef flwrite
+}
+
+// Look for flash using a 16 bit bus interface (ie 2 8-bit chips)
+int jedec_probe16(struct map_info *map,unsigned long base,
+		  struct jedec_private *priv)
+{
+   return 0;
+}
+
+// Look for flash using a 32 bit bus interface (ie 4 8-bit chips)
+int jedec_probe32(struct map_info *map,unsigned long base,
+		  struct jedec_private *priv)
+{
+   #define flread(x) map->read32(map,base+((x)<<2))
+   #define flwrite(v,x) map->write32(map,v,base+((x)<<2))
+
+   const unsigned long AutoSel1 = 0xAAAAAAAA;
+   const unsigned long AutoSel2 = 0x55555555;
+   const unsigned long AutoSel3 = 0x90909090;
+   const unsigned long Reset = 0xF0F0F0F0;
+   __u32 OldVal;
+   __u8 Mfg[4];
+   __u8 Id[4];
+   unsigned I;
+   unsigned long Size;
+
+   // Wait for any write/erase operation to settle
+   OldVal = flread(base);
+   for (I = 0; OldVal != flread(base) && I < 10000; I++)
+      OldVal = flread(base);
+   
+   // Reset the chip
+   flwrite(Reset,0x555); 
+   
+   // Send the sequence
+   flwrite(AutoSel1,0x555);
+   flwrite(AutoSel2,0x2AA);
+   flwrite(AutoSel3,0x555);
+   
+   // Test #1, JEDEC numbers are readable from 0x??00/0x??01
+   if (flread(0) != flread(0x100) || 
+       flread(1) != flread(0x101))
+   {
+      flwrite(Reset,0x555);
+      return 0;
+   }
+
+   // Split up the JEDEC numbers
+   OldVal = flread(0);
+   for (I = 0; I != 4; I++)
+      Mfg[I] = (OldVal >> (I*8));
+   OldVal = flread(1);
+   for (I = 0; I != 4; I++)
+      Id[I] = (OldVal >> (I*8));
+      
+   Size = handle_jedecs(map,Mfg,Id,4,base,priv);
+   if (Size == 0)
+   {
+      flwrite(Reset,0x555);
+      return 0;
+   }
+   
+   /* Check if there is address wrap around within a single bank, if this
+      returns JEDEC numbers then we assume that it is wrap around. Notice
+      we call this routine with the JEDEC return still enabled, if two or
+      more flashes have a truncated address space the probe test will still
+      work */
+   if (base + Size+0x555 < map->size &&
+       base + Size+0x555 < (base & (~(my_bank_size-1))) + my_bank_size)
+   {
+      if (flread(base+Size) != flread(base+Size + 0x100) ||
+	  flread(base+Size + 1) != flread(base+Size + 0x101))
+      {
+	 jedec_probe32(map,base+Size,priv);
+      }
+   }
+
+   // Reset.
+   flwrite(0xF0F0F0F0,0x555);
+   
+   return 1;
+   
+   #undef flread
+   #undef flwrite
+}
+
+/* Linear read. */
+static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len, 
+		      size_t *retlen, u_char *buf)
+{
+   struct map_info *map = (struct map_info *)mtd->priv;
+   
+   map->copy_from(map, buf, from, len);
+   *retlen = len;
+   return 0;   
+}
+
+/* Banked read. Take special care to jump past the holes in the bank
+   mapping. This version assumes symetry in the holes.. */
+static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len, 
+			     size_t *retlen, u_char *buf)
+{
+   struct map_info *map = (struct map_info *)mtd->priv;
+   struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv;
+
+   *retlen = 0;
+   while (len > 0)
+   {
+      // Determine what bank and offset into that bank the first byte is
+      unsigned long bank = from & (~(priv->bank_fill[0]-1));
+      unsigned long offset = from & (priv->bank_fill[0]-1);
+      unsigned long get = len;
+      if (priv->bank_fill[0] - offset < len)
+	 get = priv->bank_fill[0] - offset;
+
+      bank /= priv->bank_fill[0];      
+      map->copy_from(map,buf + *retlen,bank*my_bank_size + offset,get);
+      
+      len -= get;
+      *retlen += get;
+      from += get;
+   }   
+   return 0;   
+}
+
+/* Pass the flags value that the flash return before it re-entered read 
+   mode. */
+static void jedec_flash_failed(unsigned char code)
+{
+   /* Bit 5 being high indicates that there was an internal device
+      failure, erasure time limits exceeded or something */
+   if ((code & (1 << 5)) != 0)
+   {
+      printk("mtd: Internal Flash failure\n");
+      return;
+   }
+   printk("mtd: Programming didn't take\n");
+}
+
+/* This uses the erasure function described in the AMD Flash Handbook, 
+   it will work for flashes with a fixed sector size only. Flashes with
+   a selection of sector sizes (ie the AMD Am29F800B) will need a different
+   routine. This routine tries to parallize erasing multiple chips/sectors 
+   where possible */
+static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+   // Does IO to the currently selected chip
+   #define flread(x) map->read8(map,chip->base+((x)<<chip->addrshift))
+   #define flwrite(v,x) map->write8(map,v,chip->base+((x)<<chip->addrshift))
+   
+   unsigned long Time = 0;
+   unsigned long NoTime = 0;
+   unsigned long start = instr->addr, len = instr->len;
+   unsigned int I;
+   struct map_info *map = (struct map_info *)mtd->priv;
+   struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv;
+
+   // Verify the arguments..
+   if (start + len > mtd->size ||
+       (start % mtd->erasesize) != 0 ||
+       (len % mtd->erasesize) != 0 ||
+       (len/mtd->erasesize) == 0)
+      return -EINVAL;
+   
+   jedec_flash_chip_scan(priv,start,len);
+
+   // Start the erase sequence on each chip
+   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
+   {
+      unsigned long off;
+      struct jedec_flash_chip *chip = priv->chips + I;
+      
+      if (chip->length == 0)
+	 continue;
+      
+      if (chip->start + chip->length > chip->size)
+      {
+	 printk("DIE\n");
+	 return -EIO;
+      }     
+      
+      flwrite(0xF0,chip->start + 0x555);
+      flwrite(0xAA,chip->start + 0x555);
+      flwrite(0x55,chip->start + 0x2AA);
+      flwrite(0x80,chip->start + 0x555);
+      flwrite(0xAA,chip->start + 0x555);
+      flwrite(0x55,chip->start + 0x2AA);
+
+      /* Once we start selecting the erase sectors the delay between each 
+         command must not exceed 50us or it will immediately start erasing 
+         and ignore the other sectors */
+      for (off = 0; off < len; off += chip->sectorsize)
+      {
+	 // Check to make sure we didn't timeout
+	 flwrite(0x30,chip->start + off);
+	 if (off == 0)
+	    continue;
+	 if ((flread(chip->start + off) & (1 << 3)) != 0)
+	 {
+	    printk("mtd: Ack! We timed out the erase timer!\n");
+	    return -EIO;
+	 }       	 
+      }
+   }   
+
+   /* We could split this into a timer routine and return early, performing
+      background erasure.. Maybe later if the need warrents */
+
+   /* Poll the flash for erasure completion, specs say this can take as long
+      as 480 seconds to do all the sectors (for a 2 meg flash). 
+      Erasure time is dependant on chip age, temp and wear.. */
+   
+   /* This being a generic routine assumes a 32 bit bus. It does read32s
+      and bundles interleved chips into the same grouping. This will work 
+      for all bus widths */
+   Time = 0;
+   NoTime = 0;
+   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
+   {
+      struct jedec_flash_chip *chip = priv->chips + I;
+      unsigned long off = 0;
+      unsigned todo[4] = {0,0,0,0};
+      unsigned todo_left = 0;
+      unsigned J;
+      
+      if (chip->length == 0)
+	 continue;
+
+      /* Find all chips in this data line, realistically this is all 
+         or nothing up to the interleve count */
+      for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++)
+      {
+	 if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) == 
+	     (chip->base & (~((1<<chip->addrshift)-1))))
+	 {
+	    todo_left++;
+	    todo[priv->chips[J].base & ((1<<chip->addrshift)-1)] = 1;
+	 }	 
+      }
+
+      /*      printk("todo: %x %x %x %x\n",(short)todo[0],(short)todo[1],
+	      (short)todo[2],(short)todo[3]);
+      */
+      while (1)
+      {
+	 __u32 Last[4];
+	 unsigned long Count = 0;
+	 
+	 /* During erase bit 7 is held low and bit 6 toggles, we watch this,
+	    should it stop toggling or go high then the erase is completed,
+  	    or this is not really flash ;> */
+	 switch (map->buswidth) {
+	 case 1:
+	    Last[0] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off);
+	    Last[1] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off);
+	    Last[2] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off);
+	    break;
+	 case 2:
+	    Last[0] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off);
+	    Last[1] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off);
+	    Last[2] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off);
+	    break;
+	 case 3:
+	    Last[0] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
+	    Last[1] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
+	    Last[2] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
+	    break;
+	 }
+	 Count = 3;
+	 while (todo_left != 0)
+	 {
+	    for (J = 0; J != 4; J++)
+	    {
+	       __u8 Byte1 = (Last[(Count-1)%4] >> (J*8)) & 0xFF;
+	       __u8 Byte2 = (Last[(Count-2)%4] >> (J*8)) & 0xFF;
+	       __u8 Byte3 = (Last[(Count-3)%4] >> (J*8)) & 0xFF;
+	       if (todo[J] == 0)
+		  continue;
+	       
+	       if ((Byte1 & (1 << 7)) == 0 && Byte1 != Byte2)
+	       {
+//		  printk("Check %x %x %x\n",(short)J,(short)Byte1,(short)Byte2);
+		  continue;
+	       }
+	       
+	       if (Byte1 == Byte2)
+	       {
+		  jedec_flash_failed(Byte3);
+		  return -EIO;
+	       }
+	       
+	       todo[J] = 0;
+	       todo_left--;
+	    }
+	    
+/*	    if (NoTime == 0)
+	       Time += HZ/10 - schedule_timeout(HZ/10);*/
+	    NoTime = 0;
+
+	    switch (map->buswidth) {
+	    case 1:
+	       Last[Count % 4] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off);
+	      break;
+	    case 2:
+	       Last[Count % 4] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off);
+	      break;
+	    case 4:
+	       Last[Count % 4] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
+	      break;
+	    }
+	    Count++;
+	    
+/*	    // Count time, max of 15s per sector (according to AMD)
+	    if (Time > 15*len/mtd->erasesize*HZ)
+	    {
+	       printk("mtd: Flash Erase Timed out\n");
+	       return -EIO;
+	    }	    */
+	 }
+	 	 
+	 // Skip to the next chip if we used chip erase
+	 if (chip->length == chip->size)
+	    off = chip->size;
+	 else
+	    off += chip->sectorsize;
+	 
+	 if (off >= chip->length)
+	    break;
+	 NoTime = 1;
+      }
+      
+      for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++)
+      {
+	 if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
+	     (chip->base & (~((1<<chip->addrshift)-1))))
+	    priv->chips[J].length = 0;
+      }      
+   }
+       	    
+   //printk("done\n");
+   if (instr->callback)
+	instr->callback(instr);
+   return 0;
+   
+   #undef flread
+   #undef flwrite
+}
+
+/* This is the simple flash writing function. It writes to every byte, in
+   sequence. It takes care of how to properly address the flash if
+   the flash is interleved. It can only be used if all the chips in the 
+   array are identical!*/
+static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
+		       size_t *retlen, const u_char *buf)
+{
+   /* Does IO to the currently selected chip. It takes the bank addressing
+      base (which is divisable by the chip size) adds the necesary lower bits
+      of addrshift (interleve index) and then adds the control register index. */
+   #define flread(x) map->read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
+   #define flwrite(v,x) map->write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
+   
+   struct map_info *map = (struct map_info *)mtd->priv;
+   struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv;
+   unsigned long base;
+   unsigned long off;
+   size_t save_len = len;
+   
+   if (start + len > mtd->size)
+      return -EIO;
+   
+   //printk("Here");
+   
+   //printk("flash_write: start is %x, len is %x\n",start,(unsigned long)len);
+   while (len != 0)
+   {
+      struct jedec_flash_chip *chip = priv->chips;
+      unsigned long bank;
+      unsigned long boffset;
+	 
+      // Compute the base of the flash.
+      off = ((unsigned long)start) % (chip->size << chip->addrshift);
+      base = start - off;
+
+      // Perform banked addressing translation.
+      bank = base & (~(priv->bank_fill[0]-1));
+      boffset = base & (priv->bank_fill[0]-1);
+      bank = (bank/priv->bank_fill[0])*my_bank_size;
+      base = bank + boffset;
+      
+    //  printk("Flasing %X %X %X\n",base,chip->size,len);
+     // printk("off is %x, compare with %x\n",off,chip->size << chip->addrshift);
+      
+      // Loop over this page
+      for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++)
+      {
+	 unsigned char oldbyte = map->read8(map,base+off);
+	 unsigned char Last[4];
+	 unsigned long Count = 0;
+
+	 if (oldbyte == *buf) {
+	//	 printk("oldbyte and *buf is %x,len is %x\n",oldbyte,len);
+	    continue;
+	 }
+	 if (((~oldbyte) & *buf) != 0)
+	    printk("mtd: warn: Trying to set a 0 to a 1\n");
+	     
+	 // Write
+	 flwrite(0xAA,0x555);
+	 flwrite(0x55,0x2AA);
+	 flwrite(0xA0,0x555);
+	 map->write8(map,*buf,base + off);
+	 Last[0] = map->read8(map,base + off);
+	 Last[1] = map->read8(map,base + off);
+	 Last[2] = map->read8(map,base + off);
+	 
+	 /* Wait for the flash to finish the operation. We store the last 4
+	    status bytes that have been retrieved so we can determine why
+	    it failed. The toggle bits keep toggling when there is a 
+	    failure */
+	 for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] &&
+	      Count < 10000; Count++)
+	    Last[Count % 4] = map->read8(map,base + off);
+	 if (Last[(Count - 1) % 4] != *buf)
+	 {
+	    jedec_flash_failed(Last[(Count - 3) % 4]);
+	    return -EIO;
+	 }	 
+      }
+   }
+   *retlen = save_len;
+   return 0;
+}
+
+/* This is used to enhance the speed of the erase routine,
+   when things are being done to multiple chips it is possible to
+   parallize the operations, particularly full memory erases of multi
+   chip memories benifit */
+static void jedec_flash_chip_scan(struct jedec_private *priv,unsigned long start,
+		     unsigned long len)
+{
+   unsigned int I;
+
+   // Zero the records
+   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
+      priv->chips[I].start = priv->chips[I].length = 0;
+   
+   // Intersect the region with each chip
+   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
+   {
+      struct jedec_flash_chip *chip = priv->chips + I;
+      unsigned long ByteStart;
+      unsigned long ChipEndByte = chip->offset + (chip->size << chip->addrshift);
+      
+      // End is before this chip or the start is after it
+      if (start+len < chip->offset ||
+	  ChipEndByte - (1 << chip->addrshift) < start)
+	 continue;
+      
+      if (start < chip->offset)
+      {
+	 ByteStart = chip->offset;
+	 chip->start = 0;
+      }      
+      else
+      {
+	 chip->start = (start - chip->offset + (1 << chip->addrshift)-1) >> chip->addrshift;
+	 ByteStart = start;
+      }
+
+      if (start + len >= ChipEndByte)
+	 chip->length = (ChipEndByte - ByteStart) >> chip->addrshift;
+      else
+	 chip->length = (start + len - ByteStart + (1 << chip->addrshift)-1) >> chip->addrshift;
+   }
+}
+									/*}}}*/
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define jedec_probe_init init_module
+#define jedec_probe_exit cleanup_module
+#endif
+
+int __init jedec_probe_init(void)
+{
+	register_mtd_chip_driver(&jedec_chipdrv);
+	return 0;
+}
+
+static void __exit jedec_probe_exit(void)
+{
+	unregister_mtd_chip_driver(&jedec_chipdrv);
+}
+
+module_init(jedec_probe_init);
+module_exit(jedec_probe_exit);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/chips/map_ram.c linux/drivers/mtd/chips/map_ram.c
--- v2.4.5/linux/drivers/mtd/chips/map_ram.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/chips/map_ram.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,136 @@
+/*
+ * Common code to handle map devices which are simple RAM
+ * (C) 2000 Red Hat. GPL'd.
+ * $Id: map_ram.c,v 1.11 2001/06/08 15:34:04 dwmw2 Exp $
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+#include <linux/mtd/map.h>
+
+
+static int mapram_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
+static int mapram_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
+static int mapram_erase (struct mtd_info *, struct erase_info *);
+static void mapram_nop (struct mtd_info *);
+static struct mtd_info *map_ram_probe(struct map_info *map);
+
+
+static struct mtd_chip_driver mapram_chipdrv = {
+	probe: map_ram_probe,
+	name: "ram",
+	module: THIS_MODULE
+};
+
+static struct mtd_info *map_ram_probe(struct map_info *map)
+{
+	struct mtd_info *mtd;
+
+	/* Check the first byte is RAM */
+#if 0
+	map->write8(map, 0x55, 0);
+	if (map->read8(map, 0) != 0x55)
+		return NULL;
+
+	map->write8(map, 0xAA, 0);
+	if (map->read8(map, 0) != 0xAA)
+		return NULL;
+
+	/* Check the last byte is RAM */
+	map->write8(map, 0x55, map->size-1);
+	if (map->read8(map, map->size-1) != 0x55)
+		return NULL;
+
+	map->write8(map, 0xAA, map->size-1);
+	if (map->read8(map, map->size-1) != 0xAA)
+		return NULL;
+#endif
+	/* OK. It seems to be RAM. */
+
+	mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
+	if (!mtd)
+		return NULL;
+
+	memset(mtd, 0, sizeof(*mtd));
+
+	map->fldrv = &mapram_chipdrv;
+	mtd->priv = map;
+	mtd->name = map->name;
+	mtd->type = MTD_RAM;
+	mtd->erasesize = 0x10000;
+	mtd->size = map->size;
+	mtd->erase = mapram_erase;
+	mtd->read = mapram_read;
+	mtd->write = mapram_write;
+	mtd->sync = mapram_nop;
+	mtd->flags = MTD_CAP_RAM | MTD_VOLATILE;
+	mtd->erasesize = PAGE_SIZE;
+
+	MOD_INC_USE_COUNT;
+	return mtd;
+}
+
+
+static int mapram_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
+{
+	struct map_info *map = (struct map_info *)mtd->priv;
+
+	map->copy_from(map, buf, from, len);
+	*retlen = len;
+	return 0;
+}
+
+static int mapram_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
+{
+	struct map_info *map = (struct map_info *)mtd->priv;
+
+	map->copy_to(map, to, buf, len);
+	*retlen = len;
+	return 0;
+}
+
+static int mapram_erase (struct mtd_info *mtd, struct erase_info *instr)
+{
+	/* Yeah, it's inefficient. Who cares? It's faster than a _real_
+	   flash erase. */
+	struct map_info *map = (struct map_info *)mtd->priv;
+	unsigned long i;
+
+	for (i=0; i<instr->len; i++)
+		map->write8(map, 0xFF, instr->addr + i);
+
+	if (instr->callback)
+		instr->callback(instr);
+
+	return 0;
+}
+
+static void mapram_nop(struct mtd_info *mtd)
+{
+	/* Nothing to see here */
+}
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define map_ram_init init_module
+#define map_ram_exit cleanup_module
+#endif
+
+static int __init map_ram_init(void)
+{
+	register_mtd_chip_driver(&mapram_chipdrv);
+	return 0;
+}
+
+static void __exit map_ram_exit(void)
+{
+	unregister_mtd_chip_driver(&mapram_chipdrv);
+}
+
+module_init(map_ram_init);
+module_exit(map_ram_exit);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/chips/map_rom.c linux/drivers/mtd/chips/map_rom.c
--- v2.4.5/linux/drivers/mtd/chips/map_rom.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/chips/map_rom.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,91 @@
+/*
+ * Common code to handle map devices which are simple ROM
+ * (C) 2000 Red Hat. GPL'd.
+ * $Id: map_rom.c,v 1.14 2001/06/02 14:30:43 dwmw2 Exp $
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+#include <linux/mtd/map.h>
+
+static int maprom_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
+static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
+static void maprom_nop (struct mtd_info *);
+struct mtd_info *map_rom_probe(struct map_info *map);
+
+static struct mtd_chip_driver maprom_chipdrv = {
+	probe: map_rom_probe,
+	name: "rom",
+	module: THIS_MODULE
+};
+
+struct mtd_info *map_rom_probe(struct map_info *map)
+{
+	struct mtd_info *mtd;
+
+	mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
+	if (!mtd)
+		return NULL;
+
+	memset(mtd, 0, sizeof(*mtd));
+
+	map->fldrv = &maprom_chipdrv;
+	mtd->priv = map;
+	mtd->name = map->name;
+	mtd->type = MTD_ROM;
+	mtd->size = map->size;
+	mtd->read = maprom_read;
+	mtd->write = maprom_write;
+	mtd->sync = maprom_nop;
+	mtd->flags = MTD_CAP_ROM;
+	mtd->erasesize = 131072;
+
+	MOD_INC_USE_COUNT;
+	return mtd;
+}
+
+
+static int maprom_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
+{
+	struct map_info *map = (struct map_info *)mtd->priv;
+
+	map->copy_from(map, buf, from, len);
+	*retlen = len;
+	return 0;
+}
+
+static void maprom_nop(struct mtd_info *mtd)
+{
+	/* Nothing to see here */
+}
+
+static int maprom_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
+{
+	printk(KERN_NOTICE "maprom_write called\n");
+	return -EIO;
+}
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define map_rom_init init_module
+#define map_rom_exit cleanup_module
+#endif
+
+mod_init_t map_rom_init(void)
+{
+	register_mtd_chip_driver(&maprom_chipdrv);
+	return 0;
+}
+
+mod_exit_t map_rom_exit(void)
+{
+	unregister_mtd_chip_driver(&maprom_chipdrv);
+}
+
+module_init(map_rom_init);
+module_exit(map_rom_exit);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/chips/sharp.c linux/drivers/mtd/chips/sharp.c
--- v2.4.5/linux/drivers/mtd/chips/sharp.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/chips/sharp.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,593 @@
+/*
+ * MTD chip driver for pre-CFI Sharp flash chips
+ *
+ * Copyright 2000,2001 David A. Schleef <ds@schleef.org>
+ *           2000,2001 Lineo, Inc.
+ *
+ * $Id: sharp.c,v 1.4 2001/04/29 16:21:17 dwmw2 Exp $
+ *
+ * Devices supported:
+ *   LH28F016SCT Symmetrical block flash memory, 2Mx8
+ *   LH28F008SCT Symmetrical block flash memory, 1Mx8
+ *
+ * Documentation:
+ *   http://www.sharpmeg.com/datasheets/memic/flashcmp/
+ *   http://www.sharpmeg.com/datasheets/memic/flashcmp/01symf/16m/016sctl9.pdf
+ *   016sctl9.pdf
+ *
+ * Limitations:
+ *   This driver only supports 4x1 arrangement of chips.
+ *   Not tested on anything but PowerPC.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/cfi.h>
+#include <linux/delay.h>
+
+#define CMD_RESET		0xffffffff
+#define CMD_READ_ID		0x90909090
+#define CMD_READ_STATUS		0x70707070
+#define CMD_CLEAR_STATUS	0x50505050
+#define CMD_BLOCK_ERASE_1	0x20202020
+#define CMD_BLOCK_ERASE_2	0xd0d0d0d0
+#define CMD_BYTE_WRITE		0x40404040
+#define CMD_SUSPEND		0xb0b0b0b0
+#define CMD_RESUME		0xd0d0d0d0
+#define CMD_SET_BLOCK_LOCK_1	0x60606060
+#define CMD_SET_BLOCK_LOCK_2	0x01010101
+#define CMD_SET_MASTER_LOCK_1	0x60606060
+#define CMD_SET_MASTER_LOCK_2	0xf1f1f1f1
+#define CMD_CLEAR_BLOCK_LOCKS_1	0x60606060
+#define CMD_CLEAR_BLOCK_LOCKS_2	0xd0d0d0d0
+
+#define SR_READY		0x80808080 // 1 = ready
+#define SR_ERASE_SUSPEND	0x40404040 // 1 = block erase suspended
+#define SR_ERROR_ERASE		0x20202020 // 1 = error in block erase or clear lock bits
+#define SR_ERROR_WRITE		0x10101010 // 1 = error in byte write or set lock bit
+#define	SR_VPP			0x08080808 // 1 = Vpp is low
+#define SR_WRITE_SUSPEND	0x04040404 // 1 = byte write suspended
+#define SR_PROTECT		0x02020202 // 1 = lock bit set
+#define SR_RESERVED		0x01010101
+
+#define SR_ERRORS (SR_ERROR_ERASE|SR_ERROR_WRITE|SR_VPP|SR_PROTECT)
+
+/* Configuration options */
+
+#undef AUTOUNLOCK  /* automatically unlocks blocks before erasing */
+
+struct mtd_info *sharp_probe(struct map_info *);
+
+static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd);
+
+static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len,
+	size_t *retlen, u_char *buf);
+static int sharp_write(struct mtd_info *mtd, loff_t from, size_t len,
+	size_t *retlen, const u_char *buf);
+static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr);
+static void sharp_sync(struct mtd_info *mtd);
+static int sharp_suspend(struct mtd_info *mtd);
+static void sharp_resume(struct mtd_info *mtd);
+static void sharp_destroy(struct mtd_info *mtd);
+
+static int sharp_write_oneword(struct map_info *map, struct flchip *chip,
+	unsigned long adr, __u32 datum);
+static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip,
+	unsigned long adr);
+#ifdef AUTOUNLOCK
+static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip,
+	unsigned long adr);
+#endif
+
+
+struct sharp_info{
+	struct flchip *chip;
+	int bogus;
+	int chipshift;
+	int numchips;
+	struct flchip chips[1];
+};
+
+struct mtd_info *sharp_probe(struct map_info *map);
+static void sharp_destroy(struct mtd_info *mtd);
+
+static struct mtd_chip_driver sharp_chipdrv = {
+	probe: sharp_probe,
+	destroy: sharp_destroy,
+	name: "sharp",
+	module: THIS_MODULE
+};
+
+
+struct mtd_info *sharp_probe(struct map_info *map)
+{
+	struct mtd_info *mtd = NULL;
+	struct sharp_info *sharp = NULL;
+	int width;
+
+	mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
+	if(!mtd)
+		return NULL;
+
+	sharp = kmalloc(sizeof(*sharp), GFP_KERNEL);
+	if(!sharp)
+		return NULL;
+
+	memset(mtd, 0, sizeof(*mtd));
+
+	width = sharp_probe_map(map,mtd);
+	if(!width){
+		kfree(mtd);
+		kfree(sharp);
+		return NULL;
+	}
+
+	mtd->priv = map;
+	mtd->type = MTD_NORFLASH;
+	mtd->erase = sharp_erase;
+	mtd->read = sharp_read;
+	mtd->write = sharp_write;
+	mtd->sync = sharp_sync;
+	mtd->suspend = sharp_suspend;
+	mtd->resume = sharp_resume;
+	mtd->flags = MTD_CAP_NORFLASH;
+	mtd->name = map->name;
+
+	memset(sharp, 0, sizeof(*sharp));
+	sharp->chipshift = 23;
+	sharp->numchips = 1;
+	sharp->chips[0].start = 0;
+	sharp->chips[0].state = FL_READY;
+	sharp->chips[0].mutex = &sharp->chips[0]._spinlock;
+	sharp->chips[0].word_write_time = 0;
+	init_waitqueue_head(&sharp->chips[0].wq);
+	spin_lock_init(&sharp->chips[0]._spinlock);
+
+	map->fldrv = &sharp_chipdrv;
+	map->fldrv_priv = sharp;
+
+	MOD_INC_USE_COUNT;
+	return mtd;
+}
+
+static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd)
+{
+	unsigned long tmp;
+	unsigned long base = 0;
+	u32 read0, read4;
+	int width = 4;
+
+	tmp = map->read32(map, base+0);
+
+	map->write32(map, CMD_READ_ID, base+0);
+
+	read0=map->read32(map, base+0);
+	read4=map->read32(map, base+4);
+	if(read0 == 0x89898989){
+		printk("Looks like sharp flash\n");
+		switch(read4){
+		case 0xaaaaaaaa:
+		case 0xa0a0a0a0:
+			/* aa - LH28F016SCT-L95 2Mx8, 32 64k blocks*/
+			/* a0 - LH28F016SCT-Z4  2Mx8, 32 64k blocks*/
+			mtd->erasesize = 0x10000 * width;
+			mtd->size = 0x200000 * width;
+			return width;
+		case 0xa6a6a6a6:
+			/* a6 - LH28F008SCT-L12 1Mx8, 16 64k blocks*/
+			/* a6 - LH28F008SCR-L85 1Mx8, 16 64k blocks*/
+			mtd->erasesize = 0x10000 * width;
+			mtd->size = 0x100000 * width;
+			return width;
+#if 0
+		case 0x00000000: /* unknown */
+			/* XX - LH28F004SCT 512kx8, 8 64k blocks*/
+			mtd->erasesize = 0x10000 * width;
+			mtd->size = 0x80000 * width;
+			return width;
+#endif
+		default:
+			printk("Sort-of looks like sharp flash, 0x%08x 0x%08x\n",
+				read0,read4);
+		}
+	}else if((map->read32(map, base+0) == CMD_READ_ID)){
+		/* RAM, probably */
+		printk("Looks like RAM\n");
+		map->write32(map, tmp, base+0);
+	}else{
+		printk("Doesn't look like sharp flash, 0x%08x 0x%08x\n",
+			read0,read4);
+	}
+
+	return 0;
+}
+
+/* This function returns with the chip->mutex lock held. */
+static int sharp_wait(struct map_info *map, struct flchip *chip)
+{
+	__u16 status;
+	unsigned long timeo = jiffies + HZ;
+	DECLARE_WAITQUEUE(wait, current);
+	int adr = 0;
+
+retry:
+	spin_lock_bh(chip->mutex);
+
+	switch(chip->state){
+	case FL_READY:
+		map->write32(map,CMD_READ_STATUS,adr);
+		chip->state = FL_STATUS;
+	case FL_STATUS:
+		status = map->read32(map,adr);
+//printk("status=%08x\n",status);
+
+		udelay(100);
+		if((status & SR_READY)!=SR_READY){
+//printk(".status=%08x\n",status);
+			udelay(100);
+		}
+		break;
+	default:
+		printk("Waiting for chip\n");
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		add_wait_queue(&chip->wq, &wait);
+
+		spin_unlock_bh(chip->mutex);
+
+		schedule();
+		remove_wait_queue(&chip->wq, &wait);
+
+		if(signal_pending(current))
+			return -EINTR;
+
+		timeo = jiffies + HZ;
+
+		goto retry;
+	}
+
+	map->write32(map,CMD_RESET, adr);
+
+	chip->state = FL_READY;
+
+	return 0;
+}
+
+static void sharp_release(struct flchip *chip)
+{
+	wake_up(&chip->wq);
+	spin_unlock_bh(chip->mutex);
+}
+
+static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len,
+	size_t *retlen, u_char *buf)
+{
+	struct map_info *map = mtd->priv;
+	struct sharp_info *sharp = map->fldrv_priv;
+	int chipnum;
+	int ret = 0;
+	int ofs = 0;
+
+	chipnum = (from >> sharp->chipshift);
+	ofs = from & ((1 << sharp->chipshift)-1);
+
+	*retlen = 0;
+
+	while(len){
+		unsigned long thislen;
+
+		if(chipnum>=sharp->numchips)
+			break;
+
+		thislen = len;
+		if(ofs+thislen >= (1<<sharp->chipshift))
+			thislen = (1<<sharp->chipshift) - ofs;
+
+		ret = sharp_wait(map,&sharp->chips[chipnum]);
+		if(ret<0)
+			break;
+
+		map->copy_from(map,buf,ofs,thislen);
+
+		sharp_release(&sharp->chips[chipnum]);
+
+		*retlen += thislen;
+		len -= thislen;
+		buf += thislen;
+
+		ofs = 0;
+		chipnum++;
+	}
+	return ret;
+}
+
+static int sharp_write(struct mtd_info *mtd, loff_t to, size_t len,
+	size_t *retlen, const u_char *buf)
+{
+	struct map_info *map = mtd->priv;
+	struct sharp_info *sharp = map->fldrv_priv;
+	int ret = 0;
+	int i,j;
+	int chipnum;
+	unsigned long ofs;
+	union { u32 l; unsigned char uc[4]; } tbuf;
+
+	*retlen = 0;
+
+	while(len){
+		tbuf.l = 0xffffffff;
+		chipnum = to >> sharp->chipshift;
+		ofs = to & ((1<<sharp->chipshift)-1);
+
+		j=0;
+		for(i=ofs&3;i<4 && len;i++){
+			tbuf.uc[i] = *buf;
+			buf++;
+			to++;
+			len--;
+			j++;
+		}
+		sharp_write_oneword(map, &sharp->chips[chipnum], ofs&~3, tbuf.l);
+		if(ret<0)
+			return ret;
+		(*retlen)+=j;
+	}
+
+	return 0;
+}
+
+static int sharp_write_oneword(struct map_info *map, struct flchip *chip,
+	unsigned long adr, __u32 datum)
+{
+	int ret;
+	int timeo;
+	int try;
+	int i;
+	int status = 0;
+
+	ret = sharp_wait(map,chip);
+
+	for(try=0;try<10;try++){
+		map->write32(map,CMD_BYTE_WRITE,adr);
+		/* cpu_to_le32 -> hack to fix the writel be->le conversion */
+		map->write32(map,cpu_to_le32(datum),adr);
+
+		chip->state = FL_WRITING;
+
+		timeo = jiffies + (HZ/2);
+
+		map->write32(map,CMD_READ_STATUS,adr);
+		for(i=0;i<100;i++){
+			status = map->read32(map,adr);
+			if((status & SR_READY)==SR_READY)
+				break;
+		}
+		if(i==100){
+			printk("sharp: timed out writing\n");
+		}
+
+		if(!(status&SR_ERRORS))
+			break;
+
+		printk("sharp: error writing byte at addr=%08lx status=%08x\n",adr,status);
+
+		map->write32(map,CMD_CLEAR_STATUS,adr);
+	}
+	map->write32(map,CMD_RESET,adr);
+	chip->state = FL_READY;
+
+	wake_up(&chip->wq);
+	spin_unlock_bh(chip->mutex);
+
+	return 0;
+}
+
+static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+	struct map_info *map = mtd->priv;
+	struct sharp_info *sharp = map->fldrv_priv;
+	unsigned long adr,len;
+	int chipnum, ret=0;
+
+//printk("sharp_erase()\n");
+	if(instr->addr & (mtd->erasesize - 1))
+		return -EINVAL;
+	if(instr->len & (mtd->erasesize - 1))
+		return -EINVAL;
+	if(instr->len + instr->addr > mtd->size)
+		return -EINVAL;
+
+	chipnum = instr->addr >> sharp->chipshift;
+	adr = instr->addr & ((1<<sharp->chipshift)-1);
+	len = instr->len;
+
+	while(len){
+		ret = sharp_erase_oneblock(map, &sharp->chips[chipnum], adr);
+		if(ret)return ret;
+
+		adr += mtd->erasesize;
+		len -= mtd->erasesize;
+		if(adr >> sharp->chipshift){
+			adr = 0;
+			chipnum++;
+			if(chipnum>=sharp->numchips)
+				break;
+		}
+	}
+
+	if(instr->callback)
+		instr->callback(instr);
+
+	return 0;
+}
+
+static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip,
+	unsigned long adr)
+{
+	int ret;
+	int timeo;
+	int status;
+	DECLARE_WAITQUEUE(wait, current);
+
+	map->write32(map,CMD_READ_STATUS,adr);
+	status = map->read32(map,adr);
+
+	timeo = jiffies + HZ;
+
+	while(jiffies<timeo){
+		map->write32(map,CMD_READ_STATUS,adr);
+		status = map->read32(map,adr);
+		if((status & SR_READY)==SR_READY){
+			ret = 0;
+			goto out;
+		}
+		set_current_state(TASK_INTERRUPTIBLE);
+		add_wait_queue(&chip->wq, &wait);
+
+		//spin_unlock_bh(chip->mutex);
+
+		schedule_timeout(1);
+		schedule();
+		remove_wait_queue(&chip->wq, &wait);
+
+		//spin_lock_bh(chip->mutex);
+		
+		if (signal_pending(current)){
+			ret = -EINTR;
+			goto out;
+		}
+		
+	}
+	ret = -ETIME;
+out:
+	return ret;
+}
+
+static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip,
+	unsigned long adr)
+{
+	int ret;
+	//int timeo;
+	int status;
+	//int i;
+
+//printk("sharp_erase_oneblock()\n");
+
+#ifdef AUTOUNLOCK
+	/* This seems like a good place to do an unlock */
+	sharp_unlock_oneblock(map,chip,adr);
+#endif
+
+	map->write32(map,CMD_BLOCK_ERASE_1,adr);
+	map->write32(map,CMD_BLOCK_ERASE_2,adr);
+
+	chip->state = FL_ERASING;
+
+	ret = sharp_do_wait_for_ready(map,chip,adr);
+	if(ret<0)return ret;
+
+	map->write32(map,CMD_READ_STATUS,adr);
+	status = map->read32(map,adr);
+
+	if(!(status&SR_ERRORS)){
+		map->write32(map,CMD_RESET,adr);
+		chip->state = FL_READY;
+		//spin_unlock_bh(chip->mutex);
+		return 0;
+	}
+
+	printk("sharp: error erasing block at addr=%08lx status=%08x\n",adr,status);
+	map->write32(map,CMD_CLEAR_STATUS,adr);
+
+	//spin_unlock_bh(chip->mutex);
+
+	return -EIO;
+}
+
+#ifdef AUTOUNLOCK
+static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip,
+	unsigned long adr)
+{
+	int i;
+	int status;
+
+	map->write32(map,CMD_CLEAR_BLOCK_LOCKS_1,adr);
+	map->write32(map,CMD_CLEAR_BLOCK_LOCKS_2,adr);
+
+	udelay(100);
+
+	status = map->read32(map,adr);
+	printk("status=%08x\n",status);
+
+	for(i=0;i<1000;i++){
+		//map->write32(map,CMD_READ_STATUS,adr);
+		status = map->read32(map,adr);
+		if((status & SR_READY)==SR_READY)
+			break;
+		udelay(100);
+	}
+	if(i==1000){
+		printk("sharp: timed out unlocking block\n");
+	}
+
+	if(!(status&SR_ERRORS)){
+		map->write32(map,CMD_RESET,adr);
+		chip->state = FL_READY;
+		return;
+	}
+
+	printk("sharp: error unlocking block at addr=%08lx status=%08x\n",adr,status);
+	map->write32(map,CMD_CLEAR_STATUS,adr);
+}
+#endif
+
+static void sharp_sync(struct mtd_info *mtd)
+{
+	//printk("sharp_sync()\n");
+}
+
+static int sharp_suspend(struct mtd_info *mtd)
+{
+	printk("sharp_suspend()\n");
+	return -EINVAL;
+}
+
+static void sharp_resume(struct mtd_info *mtd)
+{
+	printk("sharp_resume()\n");
+	
+}
+
+static void sharp_destroy(struct mtd_info *mtd)
+{
+	printk("sharp_destroy()\n");
+
+}
+
+#if LINUX_VERSION_CODE < 0x020212 && defined(MODULE)
+#define sharp_probe_init init_module
+#define sharp_probe_exit cleanup_module
+#endif
+
+int __init sharp_probe_init(void)
+{
+	printk("MTD Sharp chip driver <ds@lineo.com>\n");
+
+	register_mtd_chip_driver(&sharp_chipdrv);
+
+	return 0;
+}
+
+static void __exit sharp_probe_exit(void)
+{
+	unregister_mtd_chip_driver(&sharp_chipdrv);
+}
+
+module_init(sharp_probe_init);
+module_exit(sharp_probe_exit);
+
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/devices/Config.in linux/drivers/mtd/devices/Config.in
--- v2.4.5/linux/drivers/mtd/devices/Config.in	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/devices/Config.in	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,51 @@
+# drivers/mtd/maps/Config.in
+
+# $Id: Config.in,v 1.2 2001/04/29 16:24:34 dwmw2 Exp $
+
+mainmenu_option next_comment
+
+comment 'Self-contained MTD device drivers'
+dep_tristate '  Ramix PMC551 PCI Mezzanine RAM card support' CONFIG_MTD_PMC551 $CONFIG_MTD $CONFIG_PCI
+if [ "$CONFIG_MTD_PMC551" = "y" -o  "$CONFIG_MTD_PMC551" = "m" ]; then
+   bool '    PMC551 256M DRAM Bugfix' CONFIG_MTD_PMC551_BUGFIX
+   bool '    PMC551 Debugging' CONFIG_MTD_PMC551_DEBUG
+fi
+dep_tristate '  Uncached system RAM' CONFIG_MTD_SLRAM $CONFIG_MTD
+dep_tristate '  Test driver using RAM' CONFIG_MTD_MTDRAM $CONFIG_MTD
+if [ "$CONFIG_MTD_MTDRAM" = "y" -o "$CONFIG_MTD_MTDRAM" = "m" ]; then
+   int 'MTDRAM device size in KiB' CONFIG_MTDRAM_TOTAL_SIZE 4096
+   int 'MTDRAM erase block size in KiB' CONFIG_MTDRAM_ERASE_SIZE 128
+   if [ "$CONFIG_MTD_MTDRAM" = "y" ]; then #If not a module (I don't want to test it as a module)
+      hex 'SRAM Hexadecimal Absolute position or 0' CONFIG_MTDRAM_ABS_POS 0
+   fi
+fi
+
+comment 'Disk-On-Chip Device Drivers'
+   dep_tristate '  M-Systems Disk-On-Chip 1000' CONFIG_MTD_DOC1000 $CONFIG_MTD
+   dep_tristate '  M-Systems Disk-On-Chip 2000 and Millennium' CONFIG_MTD_DOC2000 $CONFIG_MTD
+   dep_tristate '  M-Systems Disk-On-Chip Millennium-only alternative driver (see help)' CONFIG_MTD_DOC2001 $CONFIG_MTD
+   if [ "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" ]; then
+      define_bool CONFIG_MTD_DOCPROBE y
+   else
+      if [ "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" ]; then
+	 define_bool CONFIG_MTD_DOCPROBE m
+      else
+	 define_bool CONFIG_MTD_DOCPROBE n
+      fi
+   fi
+
+   if [ "$CONFIG_MTD_DOCPROBE" = "y" -o "$CONFIG_MTD_DOCPROBE" = "m" ]; then
+      bool '    Advanced detection options for DiskOnChip' CONFIG_MTD_DOCPROBE_ADVANCED
+      if [ "$CONFIG_MTD_DOCPROBE_ADVANCED" = "n" ]; then
+         define_hex CONFIG_MTD_DOCPROBE_ADDRESS 0
+         define_bool CONFIG_MTD_DOCPROBE_HIGH n
+         define_bool CONFIG_MTD_DOCPROBE_55AA n
+      else
+         hex  '    Physical address of DiskOnChip' CONFIG_MTD_DOCPROBE_ADDRESS 0x0000
+         bool '    Probe high addresses' CONFIG_MTD_DOCPROBE_HIGH
+         bool '    Probe for 0x55 0xAA BIOS Extension Signature' CONFIG_MTD_DOCPROBE_55AA
+      fi
+   fi
+
+
+endmenu
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/devices/Makefile linux/drivers/mtd/devices/Makefile
--- v2.4.5/linux/drivers/mtd/devices/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/devices/Makefile	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,23 @@
+#
+# linux/drivers/devices/Makefile
+#
+# $Id: Makefile,v 1.2 2001/04/19 22:12:36 dwmw2 Exp $
+
+O_TARGET	:= devlink.o
+
+#                       *** BIG UGLY NOTE ***
+#
+# The removal of get_module_symbol() and replacement with
+# inter_module_register() et al has introduced a link order dependency
+# here where previously there was none.  We now have to ensure that
+# doc200[01].o are linked before docprobe.o
+
+obj-$(CONFIG_MTD_DOC1000)	+= doc1000.o
+obj-$(CONFIG_MTD_DOC2000)	+= doc2000.o
+obj-$(CONFIG_MTD_DOC2001)	+= doc2001.o
+obj-$(CONFIG_MTD_DOCPROBE)	+= docprobe.o docecc.o
+obj-$(CONFIG_MTD_SLRAM)		+= slram.o
+obj-$(CONFIG_MTD_PMC551)	+= pmc551.o
+obj-$(CONFIG_MTD_MTDRAM)	+= mtdram.o
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/devices/doc1000.c linux/drivers/mtd/devices/doc1000.c
--- v2.4.5/linux/drivers/mtd/devices/doc1000.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/devices/doc1000.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,597 @@
+/*======================================================================
+
+  $Id: doc1000.c,v 1.11 2000/11/24 13:43:16 dwmw2 Exp $
+
+======================================================================*/
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <linux/ioctl.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <stdarg.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/iflash.h>
+
+/* Parameters that can be set with 'insmod' */
+
+static u_long base              = 0xe0000;
+static int erase_timeout	= 10*HZ;	/* in ticks */
+static int retry_limit		= 4;		/* write retries */
+static u_long max_tries       	= 4096;		/* status polling */
+
+MODULE_PARM(base,"l");
+MODULE_PARM(erase_timeout, "i");
+MODULE_PARM(retry_limit, "i");
+MODULE_PARM(max_tries, "i");
+
+#define WINDOW_SIZE 0x2000
+#define WINDOW_MASK (WINDOW_SIZE - 1)
+#define PAGEREG_LO (WINDOW_SIZE)
+#define PAGEREG_HI (WINDOW_SIZE + 2)
+
+static struct mtd_info *mymtd;
+static struct timer_list flashcard_timer;
+
+#define MAX_CELLS		32
+#define MAX_FLASH_DEVICES       8
+
+/* A flash region is composed of one or more "cells", where we allow
+   simultaneous erases if they are in different cells */
+
+
+
+struct mypriv {
+	u_char *baseaddr;
+	u_short curpage;
+	u_char locked;
+	u_short numdevices;
+	u_char interleave;
+	struct erase_info *cur_erases;
+	wait_queue_head_t wq;
+	u_char devstat[MAX_FLASH_DEVICES];
+	u_long devshift;
+};
+
+
+static void flashcard_periodic(u_long data);
+static int flashcard_erase (struct mtd_info *mtd, struct erase_info *instr);
+static int flashcard_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
+static int flashcard_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
+static void flashcard_sync (struct mtd_info *mtd);
+
+static inline void resume_erase(volatile u_char *addr);
+static inline int suspend_erase(volatile u_char *addr);
+static inline int byte_write (volatile u_char *addr, u_char byte);
+static inline int word_write (volatile u_char *addr, __u16 word);
+static inline int check_write(volatile u_char *addr);
+static inline void block_erase (volatile u_char *addr);
+static inline int check_erase(volatile u_char *addr);
+
+#ifdef CONFIG_SMP
+#warning This is definitely not SMP safe. Lock the paging mechanism.
+#endif
+
+static u_char *pagein(struct mtd_info *mtd, u_long addr)
+{
+  struct mypriv *priv=mtd->priv;
+  u_short page = addr >> 13;
+
+  priv->baseaddr[PAGEREG_LO] = page & 0xff;
+  priv->baseaddr[PAGEREG_HI] = page >> 8;
+  priv->curpage = page;
+  
+  return &priv->baseaddr[addr & WINDOW_MASK];
+}
+
+
+void flashcard_sync (struct mtd_info *mtd)
+{
+	struct mypriv *priv=mtd->priv;
+
+	flashcard_periodic((u_long) mtd);
+	printk("sync...");
+	if (priv->cur_erases)
+		interruptible_sleep_on(&priv->wq);
+	printk("Done.\n");
+}
+
+int flashcard_erase (struct mtd_info *mtd, struct erase_info *instr)
+{
+	u_char *pageaddr;
+	struct mypriv *priv=mtd->priv;
+	struct erase_info **tmp=&priv->cur_erases;
+	
+	if (instr->len != mtd->erasesize)
+		return -EINVAL;
+	if (instr->addr + instr->len > mtd->size)
+		return -EINVAL;
+
+	pageaddr=pagein(mtd,instr->addr);
+	instr->mtd = mtd;
+	instr->dev = instr->addr >> priv->devshift;
+	instr->cell = (instr->addr - (instr->dev << priv->devshift)) / mtd->erasesize;
+	instr->next = NULL;
+	instr->state = MTD_ERASE_PENDING;
+	
+	while (*tmp)
+	{
+		tmp = &((*tmp) -> next);
+	}
+	
+	*tmp = instr;
+	flashcard_periodic((u_long)mtd);
+	return 0;
+}
+
+
+int flashcard_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
+{
+ 	u_char *pageaddr=pagein(mtd,from);
+	struct mypriv *priv=mtd->priv;
+	u_char device = from >> priv->devshift;
+	u_char cell = (int) (from - (device << priv->devshift)) / mtd->erasesize;
+	int ret = 0, timeron = 0;
+
+	if ((from & WINDOW_MASK) + len <= WINDOW_SIZE)
+		*retlen = len;
+	else
+		*retlen = WINDOW_SIZE - (from & WINDOW_MASK);
+
+	if (priv->devstat[device])
+	{
+		
+		/* There is an erase in progress or pending for this device. Stop it */
+		timeron = del_timer(&flashcard_timer);
+		
+		if (priv->cur_erases && priv->cur_erases->cell == cell) 
+			
+		{
+			/* The erase is on the current cell. Just return all 0xff */ 
+			add_timer(&flashcard_timer);
+			
+			
+			printk("Cell %d currently erasing. Setting to all 0xff\n",cell);
+			memset(buf, 0xff, *retlen);
+			return 0;
+		}
+		if (priv->devstat[device] == MTD_ERASING)
+		{
+			ret = suspend_erase(pageaddr);
+			priv->devstat[device] = MTD_ERASE_SUSPEND;
+		       
+			if (ret) 
+			{
+				printk("flashcard: failed to suspend erase\n");
+				add_timer (&flashcard_timer);
+				return ret;
+			}
+		}
+
+	}
+
+	writew(IF_READ_ARRAY, (u_long)pageaddr & ~1);
+	
+	ret = 0;
+	memcpy (buf, pageaddr, *retlen);
+	
+	writew(IF_READ_CSR, (u_long)pageaddr & ~1);
+	
+	
+	if (priv->devstat[device] & MTD_ERASE_SUSPEND)
+	{
+		resume_erase(pageaddr);
+		priv->devstat[device]=MTD_ERASING;
+	}
+
+
+	if (timeron) add_timer (&flashcard_timer);
+		
+	return ret;
+}
+
+
+int flashcard_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
+{
+	struct mypriv *priv = (struct mypriv *)mtd->priv;
+ 	u_char *endaddr, *startaddr;
+	register u_char *pageaddr;
+	u_char device = to >> priv->devshift;
+/*	jiffies_t oldj=jiffies;*/
+	int ret;
+
+	while (priv->devstat[device])
+	{
+		flashcard_sync(mtd);
+	}
+
+	if ((to & WINDOW_MASK) + len <= WINDOW_SIZE)
+		*retlen = len;
+	else
+		*retlen = WINDOW_SIZE - (to & WINDOW_MASK);
+	
+	pageaddr = pagein(mtd, to);
+	startaddr = (u_char *)((u_long) pageaddr & ~1);
+	endaddr = pageaddr+(*retlen);
+
+
+
+	/* Set up to read */
+	writew(IF_READ_CSR, startaddr);
+	
+	/* Make sure it's aligned by reading the first byte if necessary */
+	if (to & 1)
+	{
+		/* Unaligned access */
+
+		u_char cbuf;
+
+		cbuf = *buf;
+
+		if (!((u_long)pageaddr & 0xf))
+			schedule();
+			
+		ret = byte_write(pageaddr, cbuf);
+		if (ret) return ret;
+
+		pageaddr++; buf++;
+	}
+
+
+	for ( ; pageaddr + 1 < endaddr; buf += 2, pageaddr += 2)
+		{
+			/* if ((u_long)pageaddr & 0xf) schedule();*/
+			
+			ret = word_write(pageaddr, *(__u16 *)buf);
+			if (ret) 
+				return ret;
+		}
+	
+	if (pageaddr != endaddr)
+	{
+		/* One more byte to write at the end. */
+		u_char cbuf;
+
+		cbuf = *buf;
+
+		ret = byte_write(pageaddr, cbuf);
+
+		if (ret) return ret;
+	}
+
+	return check_write(startaddr);
+/*	printk("Time taken in flashcard_write: %lx jiffies\n",jiffies - oldj);*/
+}
+
+
+
+
+/*====================================================================*/
+
+static inline int byte_write (volatile u_char *addr, u_char byte)
+{
+	register u_char status;
+ 	register u_short i = 0;
+  	
+ 	do {
+		status = readb(addr);
+		if (status & CSR_WR_READY)
+		{
+			writeb(IF_WRITE & 0xff, addr);
+			writeb(byte, addr);
+			return 0;
+		}
+		i++;
+	} while(i < max_tries);
+
+		
+	printk(KERN_NOTICE "flashcard: byte_write timed out, status 0x%x\n",status);
+	return -EIO;
+}
+
+static inline int word_write (volatile u_char *addr, __u16 word)
+{
+	register u_short status;
+	register u_short i = 0;
+	
+	do {
+		status = readw(addr);
+		if ((status & CSR_WR_READY) == CSR_WR_READY)
+		{
+			writew(IF_WRITE, addr);
+			writew(word, addr);
+			return 0;
+		}
+		i++;
+	} while(i < max_tries);
+		
+	printk(KERN_NOTICE "flashcard: word_write timed out at %p, status 0x%x\n", addr, status);
+	return -EIO;
+}
+
+static inline void block_erase (volatile u_char *addr)
+{
+	writew(IF_BLOCK_ERASE, addr);
+	writew(IF_CONFIRM, addr);
+}
+
+
+static inline int check_erase(volatile u_char *addr)
+{
+	__u16 status;
+	
+/*	writew(IF_READ_CSR, addr);*/
+	status = readw(addr);
+	
+
+	if ((status & CSR_WR_READY) != CSR_WR_READY)
+		return -EBUSY;
+	
+	if (status & (CSR_ERA_ERR | CSR_VPP_LOW | CSR_WR_ERR)) 
+	{
+		printk(KERN_NOTICE "flashcard: erase failed, status 0x%x\n",
+		       status);
+		return -EIO;
+	}
+	
+	return 0;
+}
+
+static inline int suspend_erase(volatile u_char *addr)
+{
+	__u16 status;
+	u_long i = 0;
+	
+	writew(IF_ERASE_SUSPEND, addr);
+	writew(IF_READ_CSR, addr);
+	
+	do {
+		status = readw(addr);
+		if ((status & CSR_WR_READY) == CSR_WR_READY)
+			return 0;
+		i++;
+	} while(i < max_tries);
+
+	printk(KERN_NOTICE "flashcard: suspend_erase timed out, status 0x%x\n", status);
+	return -EIO;
+
+}
+
+static inline void resume_erase(volatile u_char *addr)
+{
+	__u16 status;
+	
+	writew(IF_READ_CSR, addr);
+	status = readw(addr);
+	
+	/* Only give resume signal if the erase is really suspended */
+	if (status & CSR_ERA_SUSPEND)
+		writew(IF_CONFIRM, addr);
+}
+
+static inline void reset_block(volatile u_char *addr)
+{
+	u_short i;
+	__u16 status;
+
+	writew(IF_CLEAR_CSR, addr);
+
+	for (i = 0; i < 100; i++) {
+		writew(IF_READ_CSR, addr);
+		status = readw(addr);
+		if (status != 0xffff) break;
+		udelay(1000);
+	}
+
+	writew(IF_READ_CSR, addr);
+}
+
+static inline int check_write(volatile u_char *addr)
+{
+	u_short status, i = 0;
+	
+	writew(IF_READ_CSR, addr);
+	
+	do {
+		status = readw(addr);
+		if (status & (CSR_WR_ERR | CSR_VPP_LOW))
+		{
+			printk(KERN_NOTICE "flashcard: write failure at %p, status 0x%x\n", addr, status);
+			reset_block(addr);
+			return -EIO;
+		}
+		if ((status & CSR_WR_READY) == CSR_WR_READY)
+			return 0;
+		i++;
+	} while (i < max_tries);
+
+	printk(KERN_NOTICE "flashcard: write timed out at %p, status 0x%x\n", addr, status);
+	return -EIO;
+}
+
+
+/*====================================================================*/
+
+
+
+static void flashcard_periodic(unsigned long data)
+{
+	register struct mtd_info *mtd = (struct mtd_info *)data;
+	register struct mypriv *priv = mtd->priv;
+	struct erase_info *erase = priv->cur_erases;
+	u_char *pageaddr;
+
+	del_timer (&flashcard_timer);
+
+	if (!erase)
+		return;
+
+	pageaddr = pagein(mtd, erase->addr);
+	
+	if (erase->state == MTD_ERASE_PENDING)
+	{
+		block_erase(pageaddr);
+		priv->devstat[erase->dev] = erase->state = MTD_ERASING;
+		erase->time = jiffies;
+		erase->retries = 0;
+	}
+	else if (erase->state == MTD_ERASING)
+	{
+		/* It's trying to erase. Check whether it's finished */
+
+		int ret = check_erase(pageaddr);
+
+		if (!ret)
+		{
+			/* It's finished OK */
+			priv->devstat[erase->dev] = 0;
+			priv->cur_erases = erase->next;
+			erase->state = MTD_ERASE_DONE;
+			if (erase->callback)
+				(*(erase->callback))(erase);
+			else
+				kfree(erase);
+		}
+		else if (ret == -EIO)
+		{
+			if (++erase->retries > retry_limit)
+			{
+				printk("Failed too many times. Giving up\n");
+				priv->cur_erases = erase->next;
+				priv->devstat[erase->dev] = 0;
+				erase->state = MTD_ERASE_FAILED;
+				if (erase->callback)
+					(*(erase->callback))(erase);
+				else
+					kfree(erase);
+			}
+			else
+				priv->devstat[erase->dev] = erase->state = MTD_ERASE_PENDING;
+		}
+		else if (erase->time + erase_timeout < jiffies)
+		{
+			printk("Flash erase timed out. The world is broken.\n");
+
+			/* Just ignore and hope it goes away. For a while, read ops will give the CSR
+			   and writes won't work. */
+
+			priv->cur_erases = erase->next;
+			priv->devstat[erase->dev] = 0;
+			erase->state = MTD_ERASE_FAILED;
+			if (erase->callback)
+					(*(erase->callback))(erase);
+				else
+					kfree(erase);
+		}
+	}
+
+	if (priv->cur_erases)
+	{
+		flashcard_timer.expires = jiffies + HZ;
+		add_timer (&flashcard_timer);
+	}
+	else 
+		wake_up_interruptible(&priv->wq);
+
+}
+
+#if defined (MODULE) && LINUX_VERSION_CODE < 0x20211
+#define init_doc1000 init_module
+#define cleanup_doc1000 cleanup_module
+#endif
+
+int __init init_doc1000(void)
+{
+	struct mypriv *priv;
+
+	if (!base)
+	{
+		printk(KERN_NOTICE "flashcard: No start address for memory device.\n");
+		return -EINVAL;
+	}
+
+	mymtd  = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
+
+	if (!mymtd)
+	{
+		printk(KERN_NOTICE "physmem: Cannot allocate memory for new MTD device.\n");
+		return -ENOMEM;
+	}
+
+	memset(mymtd,0,sizeof(struct mtd_info));
+
+	mymtd->priv = (void *) kmalloc (sizeof(struct mypriv), GFP_KERNEL);
+	if (!mymtd->priv)
+	  {
+	    kfree(mymtd);
+	    printk(KERN_NOTICE "physmem: Cannot allocate memory for new MTD device's private data.\n");
+	    return -ENOMEM;
+	  }
+	
+
+
+
+	priv=mymtd->priv;
+	init_waitqueue_head(&priv->wq);
+
+	memset (priv,0,sizeof(struct mypriv));
+
+	priv->baseaddr = phys_to_virt(base);
+	priv->numdevices = 4;
+	
+	mymtd->name = "M-Systems DiskOnChip 1000";
+
+	mymtd->size = 0x100000;
+	mymtd->flags = MTD_CLEAR_BITS | MTD_ERASEABLE;
+        mymtd->erase = flashcard_erase;
+	mymtd->point = NULL;
+	mymtd->unpoint = NULL;
+	mymtd->read = flashcard_read;
+	mymtd->write = flashcard_write;
+
+	mymtd->sync = flashcard_sync;
+	mymtd->erasesize = 0x10000;
+	//	mymtd->interleave = 2;
+	priv->devshift =  24;
+	mymtd->type = MTD_NORFLASH;
+	
+	if (add_mtd_device(mymtd))
+	{
+		printk(KERN_NOTICE "MTD device registration failed!\n");
+		kfree(mymtd->priv);
+		kfree(mymtd);
+		return -EAGAIN;
+	}
+	
+	init_timer(&flashcard_timer);
+	flashcard_timer.function = flashcard_periodic;
+	flashcard_timer.data = (u_long)mymtd;
+	return 0;
+}
+
+static void __init cleanup_doc1000(void)
+{
+	kfree (mymtd->priv);
+	del_mtd_device(mymtd);
+	kfree(mymtd);
+}
+
+#if LINUX_VERSION_CODE >= 0x20211
+module_init(init_doc1000);
+module_exit(cleanup_doc1000);
+#endif
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/devices/doc2000.c linux/drivers/mtd/devices/doc2000.c
--- v2.4.5/linux/drivers/mtd/devices/doc2000.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/devices/doc2000.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,1121 @@
+
+/*
+ * Linux driver for Disk-On-Chip 2000 and Millennium
+ * (c) 1999 Machine Vision Holdings, Inc.
+ * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
+ *
+ * $Id: doc2000.c,v 1.43 2001/06/02 14:30:43 dwmw2 Exp $
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ids.h>
+#include <linux/mtd/doc2000.h>
+
+#define DOC_SUPPORT_2000
+#define DOC_SUPPORT_MILLENNIUM
+
+#ifdef DOC_SUPPORT_2000
+#define DoC_is_2000(doc) (doc->ChipID == DOC_ChipID_Doc2k)
+#else
+#define DoC_is_2000(doc) (0)
+#endif
+
+#ifdef DOC_SUPPORT_MILLENNIUM
+#define DoC_is_Millennium(doc) (doc->ChipID == DOC_ChipID_DocMil)
+#else
+#define DoC_is_Millennium(doc) (0)
+#endif
+
+/* #define ECC_DEBUG */
+
+/* I have no idea why some DoC chips can not use memcpy_from|to_io().
+ * This may be due to the different revisions of the ASIC controller built-in or
+ * simplily a QA/Bug issue. Who knows ?? If you have trouble, please uncomment
+ * this:
+ #undef USE_MEMCPY
+*/
+
+static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
+		    size_t *retlen, u_char *buf);
+static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
+		     size_t *retlen, const u_char *buf);
+static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
+			size_t *retlen, u_char *buf, u_char *eccbuf);
+static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
+			 size_t *retlen, const u_char *buf, u_char *eccbuf);
+static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
+			size_t *retlen, u_char *buf);
+static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
+			 size_t *retlen, const u_char *buf);
+static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);
+
+static struct mtd_info *doc2klist = NULL;
+
+/* Perform the required delay cycles by reading from the appropriate register */
+static void DoC_Delay(struct DiskOnChip *doc, unsigned short cycles)
+{
+	volatile char dummy;
+	int i;
+	
+	for (i = 0; i < cycles; i++) {
+		if (DoC_is_Millennium(doc))
+			dummy = ReadDOC(doc->virtadr, NOP);
+		else
+			dummy = ReadDOC(doc->virtadr, DOCStatus);
+	}
+	
+}
+
+/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
+static int _DoC_WaitReady(struct DiskOnChip *doc)
+{
+	unsigned long docptr = doc->virtadr;
+	unsigned short c = 0xffff;
+
+	DEBUG(MTD_DEBUG_LEVEL3,
+	      "_DoC_WaitReady called for out-of-line wait\n");
+
+	/* Out-of-line routine to wait for chip response */
+	while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B) && --c)
+		;
+
+	if (c == 0)
+		DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
+
+	return (c == 0);
+}
+
+static inline int DoC_WaitReady(struct DiskOnChip *doc)
+{
+	unsigned long docptr = doc->virtadr;
+	/* This is inline, to optimise the common case, where it's ready instantly */
+	int ret = 0;
+
+	/* 4 read form NOP register should be issued in prior to the read from CDSNControl
+	   see Software Requirement 11.4 item 2. */
+	DoC_Delay(doc, 4);
+
+	if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
+		/* Call the out-of-line routine to wait */
+		ret = _DoC_WaitReady(doc);
+
+	/* issue 2 read from NOP register after reading from CDSNControl register
+	   see Software Requirement 11.4 item 2. */
+	DoC_Delay(doc, 2);
+
+	return ret;
+}
+
+/* DoC_Command: Send a flash command to the flash chip through the CDSN Slow IO register to
+   bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
+   required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
+
+static inline int DoC_Command(struct DiskOnChip *doc, unsigned char command,
+			      unsigned char xtraflags)
+{
+	unsigned long docptr = doc->virtadr;
+
+	if (DoC_is_2000(doc))
+		xtraflags |= CDSN_CTRL_FLASH_IO;
+
+	/* Assert the CLE (Command Latch Enable) line to the flash chip */
+	WriteDOC(xtraflags | CDSN_CTRL_CLE | CDSN_CTRL_CE, docptr, CDSNControl);
+	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */
+
+	if (DoC_is_Millennium(doc))
+		WriteDOC(command, docptr, CDSNSlowIO);
+
+	/* Send the command */
+	WriteDOC_(command, docptr, doc->ioreg);
+
+	/* Lower the CLE line */
+	WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl);
+	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */
+
+	/* Wait for the chip to respond - Software requirement 11.4.1 (extended for any command) */
+	return DoC_WaitReady(doc);
+}
+
+/* DoC_Address: Set the current address for the flash chip through the CDSN Slow IO register to
+   bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
+   required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
+
+static int DoC_Address(struct DiskOnChip *doc, int numbytes, unsigned long ofs,
+		       unsigned char xtraflags1, unsigned char xtraflags2)
+{
+	unsigned long docptr;
+	int i;
+
+	docptr = doc->virtadr;
+
+	if (DoC_is_2000(doc))
+		xtraflags1 |= CDSN_CTRL_FLASH_IO;
+
+	/* Assert the ALE (Address Latch Enable) line to the flash chip */
+	WriteDOC(xtraflags1 | CDSN_CTRL_ALE | CDSN_CTRL_CE, docptr, CDSNControl);
+
+	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */
+
+	/* Send the address */
+	/* Devices with 256-byte page are addressed as:
+	   Column (bits 0-7), Page (bits 8-15, 16-23, 24-31)
+	   * there is no device on the market with page256
+	   and more than 24 bits.
+	   Devices with 512-byte page are addressed as:
+	   Column (bits 0-7), Page (bits 9-16, 17-24, 25-31)
+	   * 25-31 is sent only if the chip support it.
+	   * bit 8 changes the read command to be sent
+	   (NAND_CMD_READ0 or NAND_CMD_READ1).
+	 */
+
+	if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE) {
+		if (DoC_is_Millennium(doc))
+			WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
+		WriteDOC_(ofs & 0xff, docptr, doc->ioreg);
+	}
+
+	if (doc->page256) {
+		ofs = ofs >> 8;
+	} else {
+		ofs = ofs >> 9;
+	}
+
+	if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) {
+		for (i = 0; i < doc->pageadrlen; i++, ofs = ofs >> 8) {
+			if (DoC_is_Millennium(doc))
+				WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
+			WriteDOC_(ofs & 0xff, docptr, doc->ioreg);
+		}
+	}
+
+	DoC_Delay(doc, 2);	/* Needed for some slow flash chips. mf. */
+	
+	/* FIXME: The SlowIO's for millennium could be replaced by 
+	   a single WritePipeTerm here. mf. */
+
+	/* Lower the ALE line */
+	WriteDOC(xtraflags1 | xtraflags2 | CDSN_CTRL_CE, docptr,
+		 CDSNControl);
+
+	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */
+
+	/* Wait for the chip to respond - Software requirement 11.4.1 */
+	return DoC_WaitReady(doc);
+}
+
+/* Read a buffer from DoC, taking care of Millennium odditys */
+static void DoC_ReadBuf(struct DiskOnChip *doc, u_char * buf, int len)
+{
+	int dummy;
+	int modulus = 0xffff;
+	unsigned long docptr;
+	int i;
+
+	docptr = doc->virtadr;
+
+	if (len <= 0)
+		return;
+
+	if (DoC_is_Millennium(doc)) {
+		/* Read the data via the internal pipeline through CDSN IO register,
+		   see Pipelined Read Operations 11.3 */
+		dummy = ReadDOC(docptr, ReadPipeInit);
+
+		/* Millennium should use the LastDataRead register - Pipeline Reads */
+		len--;
+
+		/* This is needed for correctly ECC calculation */
+		modulus = 0xff;
+	}
+
+	for (i = 0; i < len; i++)
+		buf[i] = ReadDOC_(docptr, doc->ioreg + (i & modulus));
+
+	if (DoC_is_Millennium(doc)) {
+		buf[i] = ReadDOC(docptr, LastDataRead);
+	}
+}
+
+/* Write a buffer to DoC, taking care of Millennium odditys */
+static void DoC_WriteBuf(struct DiskOnChip *doc, const u_char * buf, int len)
+{
+	unsigned long docptr;
+	int i;
+
+	docptr = doc->virtadr;
+
+	if (len <= 0)
+		return;
+
+	for (i = 0; i < len; i++)
+		WriteDOC_(buf[i], docptr, doc->ioreg + i);
+
+	if (DoC_is_Millennium(doc)) {
+		WriteDOC(0x00, docptr, WritePipeTerm);
+	}
+}
+
+
+/* DoC_SelectChip: Select a given flash chip within the current floor */
+
+static inline int DoC_SelectChip(struct DiskOnChip *doc, int chip)
+{
+	unsigned long docptr = doc->virtadr;
+
+	/* Software requirement 11.4.4 before writing DeviceSelect */
+	/* Deassert the CE line to eliminate glitches on the FCE# outputs */
+	WriteDOC(CDSN_CTRL_WP, docptr, CDSNControl);
+	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */
+
+	/* Select the individual flash chip requested */
+	WriteDOC(chip, docptr, CDSNDeviceSelect);
+	DoC_Delay(doc, 4);
+
+	/* Reassert the CE line */
+	WriteDOC(CDSN_CTRL_CE | CDSN_CTRL_FLASH_IO | CDSN_CTRL_WP, docptr,
+		 CDSNControl);
+	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */
+
+	/* Wait for it to be ready */
+	return DoC_WaitReady(doc);
+}
+
+/* DoC_SelectFloor: Select a given floor (bank of flash chips) */
+
+static inline int DoC_SelectFloor(struct DiskOnChip *doc, int floor)
+{
+	unsigned long docptr = doc->virtadr;
+
+	/* Select the floor (bank) of chips required */
+	WriteDOC(floor, docptr, FloorSelect);
+
+	/* Wait for the chip to be ready */
+	return DoC_WaitReady(doc);
+}
+
+/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
+
+static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
+{
+	int mfr, id, i;
+	volatile char dummy;
+
+	/* Page in the required floor/chip */
+	DoC_SelectFloor(doc, floor);
+	DoC_SelectChip(doc, chip);
+
+	/* Reset the chip */
+	if (DoC_Command(doc, NAND_CMD_RESET, CDSN_CTRL_WP)) {
+		DEBUG(MTD_DEBUG_LEVEL2,
+		      "DoC_Command (reset) for %d,%d returned true\n",
+		      floor, chip);
+		return 0;
+	}
+
+
+	/* Read the NAND chip ID: 1. Send ReadID command */
+	if (DoC_Command(doc, NAND_CMD_READID, CDSN_CTRL_WP)) {
+		DEBUG(MTD_DEBUG_LEVEL2,
+		      "DoC_Command (ReadID) for %d,%d returned true\n",
+		      floor, chip);
+		return 0;
+	}
+
+	/* Read the NAND chip ID: 2. Send address byte zero */
+	DoC_Address(doc, ADDR_COLUMN, 0, CDSN_CTRL_WP, 0);
+
+	/* Read the manufacturer and device id codes from the device */
+
+	/* CDSN Slow IO register see Software Requirement 11.4 item 5. */
+	dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
+	DoC_Delay(doc, 2);
+	mfr = ReadDOC_(doc->virtadr, doc->ioreg);
+
+	/* CDSN Slow IO register see Software Requirement 11.4 item 5. */
+	dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
+	DoC_Delay(doc, 2);
+	id = ReadDOC_(doc->virtadr, doc->ioreg);
+
+	/* No response - return failure */
+	if (mfr == 0xff || mfr == 0)
+		return 0;
+
+	/* Check it's the same as the first chip we identified. 
+	 * M-Systems say that any given DiskOnChip device should only
+	 * contain _one_ type of flash part, although that's not a 
+	 * hardware restriction. */
+	if (doc->mfr) {
+		if (doc->mfr == mfr && doc->id == id)
+			return 1;	/* This is another the same the first */
+		else
+			printk(KERN_WARNING
+			       "Flash chip at floor %d, chip %d is different:\n",
+			       floor, chip);
+	}
+
+	/* Print and store the manufacturer and ID codes. */
+	for (i = 0; nand_flash_ids[i].name != NULL; i++) {
+		if (mfr == nand_flash_ids[i].manufacture_id &&
+		    id == nand_flash_ids[i].model_id) {
+			printk(KERN_INFO
+			       "Flash chip found: Manufacturer ID: %2.2X, "
+			       "Chip ID: %2.2X (%s)\n", mfr, id,
+			       nand_flash_ids[i].name);
+			if (!doc->mfr) {
+				doc->mfr = mfr;
+				doc->id = id;
+				doc->chipshift =
+				    nand_flash_ids[i].chipshift;
+				doc->page256 = nand_flash_ids[i].page256;
+				doc->pageadrlen =
+				    nand_flash_ids[i].pageadrlen;
+				doc->erasesize =
+				    nand_flash_ids[i].erasesize;
+				return 1;
+			}
+			return 0;
+		}
+	}
+
+
+	/* We haven't fully identified the chip. Print as much as we know. */
+	printk(KERN_WARNING "Unknown flash chip found: %2.2X %2.2X\n",
+	       id, mfr);
+
+	printk(KERN_WARNING "Please report to dwmw2@infradead.org\n");
+	return 0;
+}
+
+/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
+
+static void DoC_ScanChips(struct DiskOnChip *this)
+{
+	int floor, chip;
+	int numchips[MAX_FLOORS];
+	int maxchips = MAX_CHIPS;
+	int ret = 1;
+
+	this->numchips = 0;
+	this->mfr = 0;
+	this->id = 0;
+
+	if (DoC_is_Millennium(this))
+		maxchips = MAX_CHIPS_MIL;
+
+	/* For each floor, find the number of valid chips it contains */
+	for (floor = 0; floor < MAX_FLOORS; floor++) {
+		ret = 1;
+		numchips[floor] = 0;
+		for (chip = 0; chip < maxchips && ret != 0; chip++) {
+
+			ret = DoC_IdentChip(this, floor, chip);
+			if (ret) {
+				numchips[floor]++;
+				this->numchips++;
+			}
+		}
+	}
+
+	/* If there are none at all that we recognise, bail */
+	if (!this->numchips) {
+		printk("No flash chips recognised.\n");
+		return;
+	}
+
+	/* Allocate an array to hold the information for each chip */
+	this->chips = kmalloc(sizeof(struct Nand) * this->numchips, GFP_KERNEL);
+	if (!this->chips) {
+		printk("No memory for allocating chip info structures\n");
+		return;
+	}
+
+	ret = 0;
+
+	/* Fill out the chip array with {floor, chipno} for each 
+	 * detected chip in the device. */
+	for (floor = 0; floor < MAX_FLOORS; floor++) {
+		for (chip = 0; chip < numchips[floor]; chip++) {
+			this->chips[ret].floor = floor;
+			this->chips[ret].chip = chip;
+			this->chips[ret].curadr = 0;
+			this->chips[ret].curmode = 0x50;
+			ret++;
+		}
+	}
+
+	/* Calculate and print the total size of the device */
+	this->totlen = this->numchips * (1 << this->chipshift);
+
+	printk(KERN_INFO "%d flash chips found. Total DiskOnChip size: %ld MiB\n",
+	       this->numchips, this->totlen >> 20);
+}
+
+static int DoC2k_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
+{
+	int tmp1, tmp2, retval;
+	if (doc1->physadr == doc2->physadr)
+		return 1;
+
+	/* Use the alias resolution register which was set aside for this
+	 * purpose. If it's value is the same on both chips, they might
+	 * be the same chip, and we write to one and check for a change in
+	 * the other. It's unclear if this register is usuable in the
+	 * DoC 2000 (it's in the Millennium docs), but it seems to work. */
+	tmp1 = ReadDOC(doc1->virtadr, AliasResolution);
+	tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
+	if (tmp1 != tmp2)
+		return 0;
+
+	WriteDOC((tmp1 + 1) % 0xff, doc1->virtadr, AliasResolution);
+	tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
+	if (tmp2 == (tmp1 + 1) % 0xff)
+		retval = 1;
+	else
+		retval = 0;
+
+	/* Restore register contents.  May not be necessary, but do it just to
+	 * be safe. */
+	WriteDOC(tmp1, doc1->virtadr, AliasResolution);
+
+	return retval;
+}
+
+static const char im_name[] = "DoC2k_init";
+
+/* This routine is made available to other mtd code via
+ * inter_module_register.  It must only be accessed through
+ * inter_module_get which will bump the use count of this module.  The
+ * addresses passed back in mtd are valid as long as the use count of
+ * this module is non-zero, i.e. between inter_module_get and
+ * inter_module_put.  Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
+ */
+static void DoC2k_init(struct mtd_info *mtd)
+{
+	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
+	struct DiskOnChip *old = NULL;
+
+	/* We must avoid being called twice for the same device. */
+
+	if (doc2klist)
+		old = (struct DiskOnChip *) doc2klist->priv;
+
+	while (old) {
+		if (DoC2k_is_alias(old, this)) {
+			printk(KERN_NOTICE
+			       "Ignoring DiskOnChip 2000 at 0x%lX - already configured\n",
+			       this->physadr);
+			iounmap((void *) this->virtadr);
+			kfree(mtd);
+			return;
+		}
+		if (old->nextdoc)
+			old = (struct DiskOnChip *) old->nextdoc->priv;
+		else
+			old = NULL;
+	}
+
+
+	switch (this->ChipID) {
+	case DOC_ChipID_Doc2k:
+		mtd->name = "DiskOnChip 2000";
+		this->ioreg = DoC_2k_CDSN_IO;
+		break;
+	case DOC_ChipID_DocMil:
+		mtd->name = "DiskOnChip Millennium";
+		this->ioreg = DoC_Mil_CDSN_IO;
+		break;
+	}
+
+	printk(KERN_NOTICE "%s found at address 0x%lX\n", mtd->name,
+	       this->physadr);
+
+	mtd->type = MTD_NANDFLASH;
+	mtd->flags = MTD_CAP_NANDFLASH;
+	mtd->size = 0;
+	mtd->erasesize = 0;
+	mtd->oobblock = 512;
+	mtd->oobsize = 16;
+	mtd->module = THIS_MODULE;
+	mtd->erase = doc_erase;
+	mtd->point = NULL;
+	mtd->unpoint = NULL;
+	mtd->read = doc_read;
+	mtd->write = doc_write;
+	mtd->read_ecc = doc_read_ecc;
+	mtd->write_ecc = doc_write_ecc;
+	mtd->read_oob = doc_read_oob;
+	mtd->write_oob = doc_write_oob;
+	mtd->sync = NULL;
+
+	this->totlen = 0;
+	this->numchips = 0;
+
+	this->curfloor = -1;
+	this->curchip = -1;
+
+	/* Ident all the chips present. */
+	DoC_ScanChips(this);
+
+	if (!this->totlen) {
+		kfree(mtd);
+		iounmap((void *) this->virtadr);
+	} else {
+		this->nextdoc = doc2klist;
+		doc2klist = mtd;
+		mtd->size = this->totlen;
+		mtd->erasesize = this->erasesize;
+		add_mtd_device(mtd);
+		return;
+	}
+}
+
+static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
+		    size_t * retlen, u_char * buf)
+{
+	/* Just a special case of doc_read_ecc */
+	return doc_read_ecc(mtd, from, len, retlen, buf, NULL);
+}
+
+static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
+			size_t * retlen, u_char * buf, u_char * eccbuf)
+{
+	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
+	unsigned long docptr;
+	struct Nand *mychip;
+	unsigned char syndrome[6];
+	volatile char dummy;
+	int i, len256 = 0, ret=0;
+
+	docptr = this->virtadr;
+
+	/* Don't allow read past end of device */
+	if (from >= this->totlen)
+		return -EINVAL;
+
+	/* Don't allow a single read to cross a 512-byte block boundary */
+	if (from + len > ((from | 0x1ff) + 1))
+		len = ((from | 0x1ff) + 1) - from;
+
+	/* The ECC will not be calculated correctly if less than 512 is read */
+	if (len != 0x200 && eccbuf)
+		printk(KERN_WARNING
+		       "ECC needs a full sector read (adr: %lx size %lx)\n",
+		       (long) from, (long) len);
+
+	/* printk("DoC_Read (adr: %lx size %lx)\n", (long) from, (long) len); */
+
+
+	/* Find the chip which is to be used and select it */
+	mychip = &this->chips[from >> (this->chipshift)];
+
+	if (this->curfloor != mychip->floor) {
+		DoC_SelectFloor(this, mychip->floor);
+		DoC_SelectChip(this, mychip->chip);
+	} else if (this->curchip != mychip->chip) {
+		DoC_SelectChip(this, mychip->chip);
+	}
+
+	this->curfloor = mychip->floor;
+	this->curchip = mychip->chip;
+
+	DoC_Command(this,
+		    (!this->page256
+		     && (from & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0,
+		    CDSN_CTRL_WP);
+	DoC_Address(this, ADDR_COLUMN_PAGE, from, CDSN_CTRL_WP,
+		    CDSN_CTRL_ECC_IO);
+
+	if (eccbuf) {
+		/* Prime the ECC engine */
+		WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
+		WriteDOC(DOC_ECC_EN, docptr, ECCConf);
+	} else {
+		/* disable the ECC engine */
+		WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
+		WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
+	}
+
+	/* treat crossing 256-byte sector for 2M x 8bits devices */
+	if (this->page256 && from + len > (from | 0xff) + 1) {
+		len256 = (from | 0xff) + 1 - from;
+		DoC_ReadBuf(this, buf, len256);
+
+		DoC_Command(this, NAND_CMD_READ0, CDSN_CTRL_WP);
+		DoC_Address(this, ADDR_COLUMN_PAGE, from + len256,
+			    CDSN_CTRL_WP, CDSN_CTRL_ECC_IO);
+	}
+
+	DoC_ReadBuf(this, &buf[len256], len - len256);
+
+	/* Let the caller know we completed it */
+	*retlen = len;
+
+	if (eccbuf) {
+		/* Read the ECC data through the DiskOnChip ECC logic */
+		/* Note: this will work even with 2M x 8bit devices as   */
+		/*       they have 8 bytes of OOB per 256 page. mf.      */
+		DoC_ReadBuf(this, eccbuf, 6);
+
+		/* Flush the pipeline */
+		if (DoC_is_Millennium(this)) {
+			dummy = ReadDOC(docptr, ECCConf);
+			dummy = ReadDOC(docptr, ECCConf);
+			i = ReadDOC(docptr, ECCConf);
+		} else {
+			dummy = ReadDOC(docptr, 2k_ECCStatus);
+			dummy = ReadDOC(docptr, 2k_ECCStatus);
+			i = ReadDOC(docptr, 2k_ECCStatus);
+		}
+
+		/* Check the ECC Status */
+		if (i & 0x80) {
+			int nb_errors;
+			/* There was an ECC error */
+#ifdef ECC_DEBUG
+			printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
+#endif
+			/* Read the ECC syndrom through the DiskOnChip ECC logic.
+			   These syndrome will be all ZERO when there is no error */
+			for (i = 0; i < 6; i++) {
+				syndrome[i] =
+				    ReadDOC(docptr, ECCSyndrome0 + i);
+			}
+                        nb_errors = doc_decode_ecc(buf, syndrome);
+
+#ifdef ECC_DEBUG
+			printk("Errors corrected: %x\n", nb_errors);
+#endif
+                        if (nb_errors < 0) {
+				/* We return error, but have actually done the read. Not that
+				   this can be told to user-space, via sys_read(), but at least
+				   MTD-aware stuff can know about it by checking *retlen */
+				ret = -EIO;
+                        }
+		}
+
+#ifdef PSYCHO_DEBUG
+		printk("ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
+			     (long)from, eccbuf[0], eccbuf[1], eccbuf[2],
+			     eccbuf[3], eccbuf[4], eccbuf[5]);
+#endif
+		
+		/* disable the ECC engine */
+		WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
+	}
+
+	/* according to 11.4.1, we need to wait for the busy line 
+         * drop if we read to the end of the page.  */
+	if(0 == ((from + *retlen) & 0x1ff))
+	{
+	    DoC_WaitReady(this);
+	}
+
+	return ret;
+}
+
+static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
+		     size_t * retlen, const u_char * buf)
+{
+	char eccbuf[6];
+	return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf);
+}
+
+static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
+			 size_t * retlen, const u_char * buf,
+			 u_char * eccbuf)
+{
+	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
+	int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */
+	unsigned long docptr;
+	volatile char dummy;
+	int len256 = 0;
+	struct Nand *mychip;
+
+	docptr = this->virtadr;
+
+	/* Don't allow write past end of device */
+	if (to >= this->totlen)
+		return -EINVAL;
+
+	/* Don't allow a single write to cross a 512-byte block boundary */
+	if (to + len > ((to | 0x1ff) + 1))
+		len = ((to | 0x1ff) + 1) - to;
+
+	/* The ECC will not be calculated correctly if less than 512 is written */
+	if (len != 0x200 && eccbuf)
+		printk(KERN_WARNING
+		       "ECC needs a full sector write (adr: %lx size %lx)\n",
+		       (long) to, (long) len);
+
+	/* printk("DoC_Write (adr: %lx size %lx)\n", (long) to, (long) len); */
+
+	/* Find the chip which is to be used and select it */
+	mychip = &this->chips[to >> (this->chipshift)];
+
+	if (this->curfloor != mychip->floor) {
+		DoC_SelectFloor(this, mychip->floor);
+		DoC_SelectChip(this, mychip->chip);
+	} else if (this->curchip != mychip->chip) {
+		DoC_SelectChip(this, mychip->chip);
+	}
+
+	this->curfloor = mychip->floor;
+	this->curchip = mychip->chip;
+
+	/* Set device to main plane of flash */
+	DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP);
+	DoC_Command(this,
+		    (!this->page256
+		     && (to & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0,
+		    CDSN_CTRL_WP);
+
+	DoC_Command(this, NAND_CMD_SEQIN, 0);
+	DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO);
+
+	if (eccbuf) {
+		/* Prime the ECC engine */
+		WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
+		WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
+	} else {
+		/* disable the ECC engine */
+		WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
+		WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
+	}
+
+	/* treat crossing 256-byte sector for 2M x 8bits devices */
+	if (this->page256 && to + len > (to | 0xff) + 1) {
+		len256 = (to | 0xff) + 1 - to;
+		DoC_WriteBuf(this, buf, len256);
+
+		DoC_Command(this, NAND_CMD_PAGEPROG, 0);
+
+		DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
+		/* There's an implicit DoC_WaitReady() in DoC_Command */
+
+		dummy = ReadDOC(docptr, CDSNSlowIO);
+		DoC_Delay(this, 2);
+
+		if (ReadDOC_(docptr, this->ioreg) & 1) {
+			printk("Error programming flash\n");
+			/* Error in programming */
+			*retlen = 0;
+			return -EIO;
+		}
+
+		DoC_Command(this, NAND_CMD_SEQIN, 0);
+		DoC_Address(this, ADDR_COLUMN_PAGE, to + len256, 0,
+			    CDSN_CTRL_ECC_IO);
+	}
+
+	DoC_WriteBuf(this, &buf[len256], len - len256);
+
+	if (eccbuf) {
+		WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr,
+			 CDSNControl);
+
+		if (DoC_is_Millennium(this)) {
+			WriteDOC(0, docptr, NOP);
+			WriteDOC(0, docptr, NOP);
+			WriteDOC(0, docptr, NOP);
+		} else {
+			WriteDOC_(0, docptr, this->ioreg);
+			WriteDOC_(0, docptr, this->ioreg);
+			WriteDOC_(0, docptr, this->ioreg);
+		}
+
+		/* Read the ECC data through the DiskOnChip ECC logic */
+		for (di = 0; di < 6; di++) {
+			eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di);
+		}
+
+		/* Reset the ECC engine */
+		WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
+
+#ifdef PSYCHO_DEBUG
+		printk
+		    ("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
+		     (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
+		     eccbuf[4], eccbuf[5]);
+#endif
+	}
+
+	DoC_Command(this, NAND_CMD_PAGEPROG, 0);
+
+	DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
+	/* There's an implicit DoC_WaitReady() in DoC_Command */
+
+	dummy = ReadDOC(docptr, CDSNSlowIO);
+	DoC_Delay(this, 2);
+
+	if (ReadDOC_(docptr, this->ioreg) & 1) {
+		printk("Error programming flash\n");
+		/* Error in programming */
+		*retlen = 0;
+		return -EIO;
+	}
+
+	/* Let the caller know we completed it */
+	*retlen = len;
+		
+	if (eccbuf) {
+		unsigned char x[8];
+		size_t dummy;
+
+		/* Write the ECC data to flash */
+		for (di=0; di<6; di++)
+			x[di] = eccbuf[di];
+		
+		x[6]=0x55;
+		x[7]=0x55;
+		
+		return doc_write_oob(mtd, to, 8, &dummy, x);
+	}
+
+	return 0;
+}
+
+static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
+			size_t * retlen, u_char * buf)
+{
+	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
+	int len256 = 0;
+	unsigned long docptr;
+	struct Nand *mychip;
+
+	docptr = this->virtadr;
+
+	mychip = &this->chips[ofs >> this->chipshift];
+
+	if (this->curfloor != mychip->floor) {
+		DoC_SelectFloor(this, mychip->floor);
+		DoC_SelectChip(this, mychip->chip);
+	} else if (this->curchip != mychip->chip) {
+		DoC_SelectChip(this, mychip->chip);
+	}
+	this->curfloor = mychip->floor;
+	this->curchip = mychip->chip;
+
+	/* update address for 2M x 8bit devices. OOB starts on the second */
+	/* page to maintain compatibility with doc_read_ecc. */
+	if (this->page256) {
+		if (!(ofs & 0x8))
+			ofs += 0x100;
+		else
+			ofs -= 0x8;
+	}
+
+	DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
+	DoC_Address(this, ADDR_COLUMN_PAGE, ofs, CDSN_CTRL_WP, 0);
+
+	/* treat crossing 8-byte OOB data for 2M x 8bit devices */
+	/* Note: datasheet says it should automaticaly wrap to the */
+	/*       next OOB block, but it didn't work here. mf.      */
+	if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
+		len256 = (ofs | 0x7) + 1 - ofs;
+		DoC_ReadBuf(this, buf, len256);
+
+		DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
+		DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff),
+			    CDSN_CTRL_WP, 0);
+	}
+
+	DoC_ReadBuf(this, &buf[len256], len - len256);
+
+	*retlen = len;
+	/* Reading the full OOB data drops us off of the end of the page,
+         * causing the flash device to go into busy mode, so we need
+         * to wait until ready 11.4.1 and Toshiba TC58256FT docs */
+	return DoC_WaitReady(this);
+
+}
+
+static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
+			 size_t * retlen, const u_char * buf)
+{
+	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
+	int len256 = 0;
+	unsigned long docptr = this->virtadr;
+	struct Nand *mychip = &this->chips[ofs >> this->chipshift];
+	int dummy;
+
+	//      printk("doc_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",(long)ofs, len,
+	//   buf[0], buf[1], buf[2], buf[3], buf[8], buf[9], buf[14],buf[15]);
+
+	/* Find the chip which is to be used and select it */
+	if (this->curfloor != mychip->floor) {
+		DoC_SelectFloor(this, mychip->floor);
+		DoC_SelectChip(this, mychip->chip);
+	} else if (this->curchip != mychip->chip) {
+		DoC_SelectChip(this, mychip->chip);
+	}
+	this->curfloor = mychip->floor;
+	this->curchip = mychip->chip;
+
+	/* disable the ECC engine */
+	WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
+	WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
+
+	/* Reset the chip, see Software Requirement 11.4 item 1. */
+	DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP);
+
+	/* issue the Read2 command to set the pointer to the Spare Data Area. */
+	DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
+
+	/* update address for 2M x 8bit devices. OOB starts on the second */
+	/* page to maintain compatibility with doc_read_ecc. */
+	if (this->page256) {
+		if (!(ofs & 0x8))
+			ofs += 0x100;
+		else
+			ofs -= 0x8;
+	}
+
+	/* issue the Serial Data In command to initial the Page Program process */
+	DoC_Command(this, NAND_CMD_SEQIN, 0);
+	DoC_Address(this, ADDR_COLUMN_PAGE, ofs, 0, 0);
+
+	/* treat crossing 8-byte OOB data for 2M x 8bit devices */
+	/* Note: datasheet says it should automaticaly wrap to the */
+	/*       next OOB block, but it didn't work here. mf.      */
+	if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
+		len256 = (ofs | 0x7) + 1 - ofs;
+		DoC_WriteBuf(this, buf, len256);
+
+		DoC_Command(this, NAND_CMD_PAGEPROG, 0);
+		DoC_Command(this, NAND_CMD_STATUS, 0);
+		/* DoC_WaitReady() is implicit in DoC_Command */
+
+		dummy = ReadDOC(docptr, CDSNSlowIO);
+		DoC_Delay(this, 2);
+
+		if (ReadDOC_(docptr, this->ioreg) & 1) {
+			printk("Error programming oob data\n");
+			/* There was an error */
+			*retlen = 0;
+			return -EIO;
+		}
+		DoC_Command(this, NAND_CMD_SEQIN, 0);
+		DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff), 0, 0);
+	}
+
+	DoC_WriteBuf(this, &buf[len256], len - len256);
+
+	DoC_Command(this, NAND_CMD_PAGEPROG, 0);
+	DoC_Command(this, NAND_CMD_STATUS, 0);
+	/* DoC_WaitReady() is implicit in DoC_Command */
+
+	dummy = ReadDOC(docptr, CDSNSlowIO);
+	DoC_Delay(this, 2);
+
+	if (ReadDOC_(docptr, this->ioreg) & 1) {
+		printk("Error programming oob data\n");
+		/* There was an error */
+		*retlen = 0;
+		return -EIO;
+	}
+
+	*retlen = len;
+	return 0;
+
+}
+
+int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
+	__u32 ofs = instr->addr;
+	__u32 len = instr->len;
+	unsigned long docptr;
+	struct Nand *mychip;
+
+	if (len != mtd->erasesize)
+		printk(KERN_WARNING "Erase not right size (%x != %x)n",
+		       len, mtd->erasesize);
+
+	docptr = this->virtadr;
+
+	mychip = &this->chips[ofs >> this->chipshift];
+
+	if (this->curfloor != mychip->floor) {
+		DoC_SelectFloor(this, mychip->floor);
+		DoC_SelectChip(this, mychip->chip);
+	} else if (this->curchip != mychip->chip) {
+		DoC_SelectChip(this, mychip->chip);
+	}
+	this->curfloor = mychip->floor;
+	this->curchip = mychip->chip;
+
+	instr->state = MTD_ERASE_PENDING;
+
+	DoC_Command(this, NAND_CMD_ERASE1, 0);
+	DoC_Address(this, ADDR_PAGE, ofs, 0, 0);
+	DoC_Command(this, NAND_CMD_ERASE2, 0);
+
+	instr->state = MTD_ERASING;
+
+	DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
+
+	if (ReadDOC_(docptr, this->ioreg) & 1) {
+		printk("Error writing\n");
+		/* There was an error */
+		instr->state = MTD_ERASE_FAILED;
+	} else
+		instr->state = MTD_ERASE_DONE;
+
+	if (instr->callback)
+		instr->callback(instr);
+
+	return 0;
+}
+
+
+/****************************************************************************
+ *
+ * Module stuff
+ *
+ ****************************************************************************/
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define cleanup_doc2000 cleanup_module
+#define init_doc2000 init_module
+#endif
+
+int __init init_doc2000(void)
+{
+       inter_module_register(im_name, THIS_MODULE, &DoC2k_init);
+       return 0;
+}
+
+static void __exit cleanup_doc2000(void)
+{
+	struct mtd_info *mtd;
+	struct DiskOnChip *this;
+
+	while ((mtd = doc2klist)) {
+		this = (struct DiskOnChip *) mtd->priv;
+		doc2klist = this->nextdoc;
+
+		del_mtd_device(mtd);
+
+		iounmap((void *) this->virtadr);
+		kfree(this->chips);
+		kfree(mtd);
+	}
+	inter_module_unregister(im_name);
+}
+
+module_exit(cleanup_doc2000);
+module_init(init_doc2000);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/devices/doc2001.c linux/drivers/mtd/devices/doc2001.c
--- v2.4.5/linux/drivers/mtd/devices/doc2001.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/devices/doc2001.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,883 @@
+
+/*
+ * Linux driver for Disk-On-Chip Millennium
+ * (c) 1999 Machine Vision Holdings, Inc.
+ * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
+ *
+ * $Id: doc2001.c,v 1.34 2001/06/02 14:30:43 dwmw2 Exp $
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ids.h>
+#include <linux/mtd/doc2000.h>
+
+/* #define ECC_DEBUG */
+
+/* I have no idea why some DoC chips can not use memcop_form|to_io().
+ * This may be due to the different revisions of the ASIC controller built-in or
+ * simplily a QA/Bug issue. Who knows ?? If you have trouble, please uncomment
+ * this:*/
+#undef USE_MEMCPY
+
+static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
+		    size_t *retlen, u_char *buf);
+static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
+		     size_t *retlen, const u_char *buf);
+static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
+			size_t *retlen, u_char *buf, u_char *eccbuf);
+static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
+			 size_t *retlen, const u_char *buf, u_char *eccbuf);
+static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
+			size_t *retlen, u_char *buf);
+static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
+			 size_t *retlen, const u_char *buf);
+static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);
+
+static struct mtd_info *docmillist = NULL;
+
+/* Perform the required delay cycles by reading from the NOP register */
+static void DoC_Delay(unsigned long docptr, unsigned short cycles)
+{
+	volatile char dummy;
+	int i;
+
+	for (i = 0; i < cycles; i++)
+		dummy = ReadDOC(docptr, NOP);
+}
+
+/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
+static int _DoC_WaitReady(unsigned long docptr)
+{
+	unsigned short c = 0xffff;
+
+	DEBUG(MTD_DEBUG_LEVEL3,
+	      "_DoC_WaitReady called for out-of-line wait\n");
+
+	/* Out-of-line routine to wait for chip response */
+	while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B) && --c)
+		;
+
+	if (c == 0)
+		DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
+
+	return (c == 0);
+}
+
+static inline int DoC_WaitReady(unsigned long docptr)
+{
+	/* This is inline, to optimise the common case, where it's ready instantly */
+	int ret = 0;
+
+	/* 4 read form NOP register should be issued in prior to the read from CDSNControl
+	   see Software Requirement 11.4 item 2. */
+	DoC_Delay(docptr, 4);
+
+	if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
+		/* Call the out-of-line routine to wait */
+		ret = _DoC_WaitReady(docptr);
+
+	/* issue 2 read from NOP register after reading from CDSNControl register
+	   see Software Requirement 11.4 item 2. */
+	DoC_Delay(docptr, 2);
+
+	return ret;
+}
+
+/* DoC_Command: Send a flash command to the flash chip through the CDSN IO register
+   with the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
+   required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
+
+static inline void DoC_Command(unsigned long docptr, unsigned char command,
+			       unsigned char xtraflags)
+{
+	/* Assert the CLE (Command Latch Enable) line to the flash chip */
+	WriteDOC(xtraflags | CDSN_CTRL_CLE | CDSN_CTRL_CE, docptr, CDSNControl);
+	DoC_Delay(docptr, 4);
+
+	/* Send the command */
+	WriteDOC(command, docptr, Mil_CDSN_IO);
+	WriteDOC(0x00, docptr, WritePipeTerm);
+
+	/* Lower the CLE line */
+	WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl);
+	DoC_Delay(docptr, 4);
+}
+
+/* DoC_Address: Set the current address for the flash chip through the CDSN IO register
+   with the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
+   required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
+
+static inline void DoC_Address(unsigned long docptr, int numbytes, unsigned long ofs,
+			       unsigned char xtraflags1, unsigned char xtraflags2)
+{
+	/* Assert the ALE (Address Latch Enable) line to the flash chip */
+	WriteDOC(xtraflags1 | CDSN_CTRL_ALE | CDSN_CTRL_CE, docptr, CDSNControl);
+	DoC_Delay(docptr, 4);
+
+	/* Send the address */
+	switch (numbytes)
+	    {
+	    case 1:
+		    /* Send single byte, bits 0-7. */
+		    WriteDOC(ofs & 0xff, docptr, Mil_CDSN_IO);
+		    WriteDOC(0x00, docptr, WritePipeTerm);
+		    break;
+	    case 2:
+		    /* Send bits 9-16 followed by 17-23 */
+		    WriteDOC((ofs >> 9)  & 0xff, docptr, Mil_CDSN_IO);
+		    WriteDOC((ofs >> 17) & 0xff, docptr, Mil_CDSN_IO);
+		    WriteDOC(0x00, docptr, WritePipeTerm);
+		break;
+	    case 3:
+		    /* Send 0-7, 9-16, then 17-23 */
+		    WriteDOC(ofs & 0xff, docptr, Mil_CDSN_IO);
+		    WriteDOC((ofs >> 9)  & 0xff, docptr, Mil_CDSN_IO);
+		    WriteDOC((ofs >> 17) & 0xff, docptr, Mil_CDSN_IO);
+		    WriteDOC(0x00, docptr, WritePipeTerm);
+		break;
+	    default:
+		return;
+	    }
+
+	/* Lower the ALE line */
+	WriteDOC(xtraflags1 | xtraflags2 | CDSN_CTRL_CE, docptr, CDSNControl);
+	DoC_Delay(docptr, 4);
+}
+
+/* DoC_SelectChip: Select a given flash chip within the current floor */
+static int DoC_SelectChip(unsigned long docptr, int chip)
+{
+	/* Select the individual flash chip requested */
+	WriteDOC(chip, docptr, CDSNDeviceSelect);
+	DoC_Delay(docptr, 4);
+
+	/* Wait for it to be ready */
+	return DoC_WaitReady(docptr);
+}
+
+/* DoC_SelectFloor: Select a given floor (bank of flash chips) */
+static int DoC_SelectFloor(unsigned long docptr, int floor)
+{
+	/* Select the floor (bank) of chips required */
+	WriteDOC(floor, docptr, FloorSelect);
+
+	/* Wait for the chip to be ready */
+	return DoC_WaitReady(docptr);
+}
+
+/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
+static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
+{
+	int mfr, id, i;
+	volatile char dummy;
+
+	/* Page in the required floor/chip
+	   FIXME: is this supported by Millennium ?? */
+	DoC_SelectFloor(doc->virtadr, floor);
+	DoC_SelectChip(doc->virtadr, chip);
+
+	/* Reset the chip, see Software Requirement 11.4 item 1. */
+	DoC_Command(doc->virtadr, NAND_CMD_RESET, CDSN_CTRL_WP);
+	DoC_WaitReady(doc->virtadr);
+
+	/* Read the NAND chip ID: 1. Send ReadID command */ 
+	DoC_Command(doc->virtadr, NAND_CMD_READID, CDSN_CTRL_WP);
+
+	/* Read the NAND chip ID: 2. Send address byte zero */ 
+	DoC_Address(doc->virtadr, 1, 0x00, CDSN_CTRL_WP, 0x00);
+
+	/* Read the manufacturer and device id codes of the flash device through
+	   CDSN IO register see Software Requirement 11.4 item 5.*/
+	dummy = ReadDOC(doc->virtadr, ReadPipeInit);
+	DoC_Delay(doc->virtadr, 2);
+	mfr = ReadDOC(doc->virtadr, Mil_CDSN_IO);
+
+	DoC_Delay(doc->virtadr, 2);
+	id  = ReadDOC(doc->virtadr, Mil_CDSN_IO);
+	dummy = ReadDOC(doc->virtadr, LastDataRead);
+
+	/* No response - return failure */
+	if (mfr == 0xff || mfr == 0)
+		return 0;
+
+	/* FIXME: to deal with multi-flash on multi-Millennium case more carefully */
+	for (i = 0; nand_flash_ids[i].name != NULL; i++) {
+		if (mfr == nand_flash_ids[i].manufacture_id &&
+		    id == nand_flash_ids[i].model_id) {
+			printk(KERN_INFO "Flash chip found: Manufacturer ID: %2.2X, "
+			       "Chip ID: %2.2X (%s)\n",
+			       mfr, id, nand_flash_ids[i].name);
+			doc->mfr = mfr;
+			doc->id = id;
+			doc->chipshift = nand_flash_ids[i].chipshift;
+			break;
+		}
+	}
+
+	if (nand_flash_ids[i].name == NULL)
+		return 0;
+	else
+		return 1;
+}
+
+/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
+static void DoC_ScanChips(struct DiskOnChip *this)
+{
+	int floor, chip;
+	int numchips[MAX_FLOORS_MIL];
+	int ret;
+
+	this->numchips = 0;
+	this->mfr = 0;
+	this->id = 0;
+
+	/* For each floor, find the number of valid chips it contains */
+	for (floor = 0,ret = 1; floor < MAX_FLOORS_MIL; floor++) {
+		numchips[floor] = 0;
+		for (chip = 0; chip < MAX_CHIPS_MIL && ret != 0; chip++) {
+			ret = DoC_IdentChip(this, floor, chip);
+			if (ret) {
+				numchips[floor]++;
+				this->numchips++;
+			}
+		}
+	}
+	/* If there are none at all that we recognise, bail */
+	if (!this->numchips) {
+		printk("No flash chips recognised.\n");
+		return;
+	}
+
+	/* Allocate an array to hold the information for each chip */
+	this->chips = kmalloc(sizeof(struct Nand) * this->numchips, GFP_KERNEL);
+	if (!this->chips){
+		printk("No memory for allocating chip info structures\n");
+		return;
+	}
+
+	/* Fill out the chip array with {floor, chipno} for each 
+	 * detected chip in the device. */
+	for (floor = 0, ret = 0; floor < MAX_FLOORS_MIL; floor++) {
+		for (chip = 0 ; chip < numchips[floor] ; chip++) {
+			this->chips[ret].floor = floor;
+			this->chips[ret].chip = chip;
+			this->chips[ret].curadr = 0;
+			this->chips[ret].curmode = 0x50;
+			ret++;
+		}
+	}
+
+	/* Calculate and print the total size of the device */
+	this->totlen = this->numchips * (1 << this->chipshift);
+	printk(KERN_INFO "%d flash chips found. Total DiskOnChip size: %ld MiB\n",
+	       this->numchips ,this->totlen >> 20);
+}
+
+static int DoCMil_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
+{
+	int tmp1, tmp2, retval;
+
+	if (doc1->physadr == doc2->physadr)
+		return 1;
+
+	/* Use the alias resolution register which was set aside for this
+	 * purpose. If it's value is the same on both chips, they might
+	 * be the same chip, and we write to one and check for a change in
+	 * the other. It's unclear if this register is usuable in the
+	 * DoC 2000 (it's in the Millenium docs), but it seems to work. */
+	tmp1 = ReadDOC(doc1->virtadr, AliasResolution);
+	tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
+	if (tmp1 != tmp2)
+		return 0;
+	
+	WriteDOC((tmp1+1) % 0xff, doc1->virtadr, AliasResolution);
+	tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
+	if (tmp2 == (tmp1+1) % 0xff)
+		retval = 1;
+	else
+		retval = 0;
+
+	/* Restore register contents.  May not be necessary, but do it just to
+	 * be safe. */
+	WriteDOC(tmp1, doc1->virtadr, AliasResolution);
+
+	return retval;
+}
+
+static const char im_name[] = "DoCMil_init";
+
+/* This routine is made available to other mtd code via
+ * inter_module_register.  It must only be accessed through
+ * inter_module_get which will bump the use count of this module.  The
+ * addresses passed back in mtd are valid as long as the use count of
+ * this module is non-zero, i.e. between inter_module_get and
+ * inter_module_put.  Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
+ */
+static void DoCMil_init(struct mtd_info *mtd)
+{
+	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	struct DiskOnChip *old = NULL;
+
+	/* We must avoid being called twice for the same device. */
+	if (docmillist)
+		old = (struct DiskOnChip *)docmillist->priv;
+
+	while (old) {
+		if (DoCMil_is_alias(this, old)) {
+			printk(KERN_NOTICE "Ignoring DiskOnChip Millennium at "
+			       "0x%lX - already configured\n", this->physadr);
+			iounmap((void *)this->virtadr);
+			kfree(mtd);
+			return;
+		}
+		if (old->nextdoc)
+			old = (struct DiskOnChip *)old->nextdoc->priv;
+		else
+			old = NULL;
+	}
+
+	mtd->name = "DiskOnChip Millennium";
+	printk(KERN_NOTICE "DiskOnChip Millennium found at address 0x%lX\n",
+	       this->physadr);
+
+	mtd->type = MTD_NANDFLASH;
+	mtd->flags = MTD_CAP_NANDFLASH;
+	mtd->size = 0;
+
+	/* FIXME: erase size is not always 8kB */
+	mtd->erasesize = 0x2000;
+
+	mtd->oobblock = 512;
+	mtd->oobsize = 16;
+	mtd->module = THIS_MODULE;
+	mtd->erase = doc_erase;
+	mtd->point = NULL;
+	mtd->unpoint = NULL;
+	mtd->read = doc_read;
+	mtd->write = doc_write;
+	mtd->read_ecc = doc_read_ecc;
+	mtd->write_ecc = doc_write_ecc;
+	mtd->read_oob = doc_read_oob;
+	mtd->write_oob = doc_write_oob;
+	mtd->sync = NULL;
+
+	this->totlen = 0;
+	this->numchips = 0;
+	this->curfloor = -1;
+	this->curchip = -1;
+
+	/* Ident all the chips present. */
+	DoC_ScanChips(this);
+
+	if (!this->totlen) {
+		kfree(mtd);
+		iounmap((void *)this->virtadr);
+	} else {
+		this->nextdoc = docmillist;
+		docmillist = mtd;
+		mtd->size  = this->totlen;
+		add_mtd_device(mtd);
+		return;
+	}
+}
+
+static int doc_read (struct mtd_info *mtd, loff_t from, size_t len,
+		     size_t *retlen, u_char *buf)
+{
+	/* Just a special case of doc_read_ecc */
+	return doc_read_ecc(mtd, from, len, retlen, buf, NULL);
+}
+
+static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
+			 size_t *retlen, u_char *buf, u_char *eccbuf)
+{
+	int i, ret;
+	volatile char dummy;
+	unsigned char syndrome[6];
+	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	unsigned long docptr = this->virtadr;
+	struct Nand *mychip = &this->chips[from >> (this->chipshift)];
+
+	/* Don't allow read past end of device */
+	if (from >= this->totlen)
+		return -EINVAL;
+
+	/* Don't allow a single read to cross a 512-byte block boundary */
+	if (from + len > ((from | 0x1ff) + 1)) 
+		len = ((from | 0x1ff) + 1) - from;
+
+	/* Find the chip which is to be used and select it */
+	if (this->curfloor != mychip->floor) {
+		DoC_SelectFloor(docptr, mychip->floor);
+		DoC_SelectChip(docptr, mychip->chip);
+	} else if (this->curchip != mychip->chip) {
+		DoC_SelectChip(docptr, mychip->chip);
+	}
+	this->curfloor = mychip->floor;
+	this->curchip = mychip->chip;
+
+	/* issue the Read0 or Read1 command depend on which half of the page
+	   we are accessing. Polling the Flash Ready bit after issue 3 bytes
+	   address in Sequence Read Mode, see Software Requirement 11.4 item 1.*/
+	DoC_Command(docptr, (from >> 8) & 1, CDSN_CTRL_WP);
+	DoC_Address(docptr, 3, from, CDSN_CTRL_WP, 0x00);
+	DoC_WaitReady(docptr);
+
+	if (eccbuf) {
+		/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
+		WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
+		WriteDOC (DOC_ECC_EN, docptr, ECCConf);
+	} else {
+		/* disable the ECC engine */
+		WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
+		WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
+	}
+
+	/* Read the data via the internal pipeline through CDSN IO register,
+	   see Pipelined Read Operations 11.3 */
+	dummy = ReadDOC(docptr, ReadPipeInit);
+#ifndef USE_MEMCPY
+	for (i = 0; i < len-1; i++) {
+		/* N.B. you have to increase the source address in this way or the
+		   ECC logic will not work properly */
+		buf[i] = ReadDOC(docptr, Mil_CDSN_IO + (i & 0xff));
+	}
+#else
+	memcpy_fromio(buf, docptr + DoC_Mil_CDSN_IO, len - 1);
+#endif
+	buf[len - 1] = ReadDOC(docptr, LastDataRead);
+
+	/* Let the caller know we completed it */
+	*retlen = len;
+        ret = 0;
+
+	if (eccbuf) {
+		/* Read the ECC data from Spare Data Area,
+		   see Reed-Solomon EDC/ECC 11.1 */
+		dummy = ReadDOC(docptr, ReadPipeInit);
+#ifndef USE_MEMCPY
+		for (i = 0; i < 5; i++) {
+			/* N.B. you have to increase the source address in this way or the
+			   ECC logic will not work properly */
+			eccbuf[i] = ReadDOC(docptr, Mil_CDSN_IO + i);
+		}
+#else
+		memcpy_fromio(eccbuf, docptr + DoC_Mil_CDSN_IO, 5);
+#endif
+		eccbuf[5] = ReadDOC(docptr, LastDataRead);
+
+		/* Flush the pipeline */
+		dummy = ReadDOC(docptr, ECCConf);
+		dummy = ReadDOC(docptr, ECCConf);
+
+		/* Check the ECC Status */
+		if (ReadDOC(docptr, ECCConf) & 0x80) {
+                        int nb_errors;
+			/* There was an ECC error */
+#ifdef ECC_DEBUG
+			printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
+#endif
+			/* Read the ECC syndrom through the DiskOnChip ECC logic.
+			   These syndrome will be all ZERO when there is no error */
+			for (i = 0; i < 6; i++) {
+				syndrome[i] = ReadDOC(docptr, ECCSyndrome0 + i);
+			}
+                        nb_errors = doc_decode_ecc(buf, syndrome);
+#ifdef ECC_DEBUG
+			printk("ECC Errors corrected: %x\n", nb_errors);
+#endif
+                        if (nb_errors < 0) {
+				/* We return error, but have actually done the read. Not that
+				   this can be told to user-space, via sys_read(), but at least
+				   MTD-aware stuff can know about it by checking *retlen */
+				ret = -EIO;
+                        }
+		}
+
+#ifdef PSYCHO_DEBUG
+		printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
+		       (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
+		       eccbuf[4], eccbuf[5]);
+#endif
+
+		/* disable the ECC engine */
+		WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
+	}
+
+	return ret;
+}
+
+static int doc_write (struct mtd_info *mtd, loff_t to, size_t len,
+		      size_t *retlen, const u_char *buf)
+{
+	char eccbuf[6];
+	return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf);
+}
+
+static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
+			  size_t *retlen, const u_char *buf, u_char *eccbuf)
+{
+	int i,ret = 0;
+	volatile char dummy;
+	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	unsigned long docptr = this->virtadr;
+	struct Nand *mychip = &this->chips[to >> (this->chipshift)];
+
+	/* Don't allow write past end of device */
+	if (to >= this->totlen)
+		return -EINVAL;
+
+#if 0
+	/* Don't allow a single write to cross a 512-byte block boundary */
+	if (to + len > ( (to | 0x1ff) + 1)) 
+		len = ((to | 0x1ff) + 1) - to;
+#else
+	/* Don't allow writes which aren't exactly one block */
+	if (to & 0x1ff || len != 0x200)
+		return -EINVAL;
+#endif
+
+	/* Find the chip which is to be used and select it */
+	if (this->curfloor != mychip->floor) {
+		DoC_SelectFloor(docptr, mychip->floor);
+		DoC_SelectChip(docptr, mychip->chip);
+	} else if (this->curchip != mychip->chip) {
+		DoC_SelectChip(docptr, mychip->chip);
+	}
+	this->curfloor = mychip->floor;
+	this->curchip = mychip->chip;
+
+	/* Reset the chip, see Software Requirement 11.4 item 1. */
+	DoC_Command(docptr, NAND_CMD_RESET, 0x00);
+	DoC_WaitReady(docptr);
+	/* Set device to main plane of flash */
+	DoC_Command(docptr, NAND_CMD_READ0, 0x00);
+
+	/* issue the Serial Data In command to initial the Page Program process */
+	DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
+	DoC_Address(docptr, 3, to, 0x00, 0x00);
+	DoC_WaitReady(docptr);
+
+	if (eccbuf) {
+		/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
+		WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
+		WriteDOC (DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
+	} else {
+		/* disable the ECC engine */
+		WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
+		WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
+	}
+
+	/* Write the data via the internal pipeline through CDSN IO register,
+	   see Pipelined Write Operations 11.2 */
+#ifndef USE_MEMCPY
+	for (i = 0; i < len; i++) {
+		/* N.B. you have to increase the source address in this way or the
+		   ECC logic will not work properly */
+		WriteDOC(buf[i], docptr, Mil_CDSN_IO + i);
+	}
+#else
+	memcpy_toio(docptr + DoC_Mil_CDSN_IO, buf, len);
+#endif
+	WriteDOC(0x00, docptr, WritePipeTerm);
+
+	if (eccbuf) {
+		/* Write ECC data to flash, the ECC info is generated by the DiskOnChip ECC logic
+		   see Reed-Solomon EDC/ECC 11.1 */
+		WriteDOC(0, docptr, NOP);
+		WriteDOC(0, docptr, NOP);
+		WriteDOC(0, docptr, NOP);
+
+		/* Read the ECC data through the DiskOnChip ECC logic */
+		for (i = 0; i < 6; i++) {
+			eccbuf[i] = ReadDOC(docptr, ECCSyndrome0 + i);
+		}
+
+		/* ignore the ECC engine */
+		WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
+
+#ifndef USE_MEMCPY
+		/* Write the ECC data to flash */
+		for (i = 0; i < 6; i++) {
+			/* N.B. you have to increase the source address in this way or the
+			   ECC logic will not work properly */
+			WriteDOC(eccbuf[i], docptr, Mil_CDSN_IO + i);
+		}
+#else
+		memcpy_toio(docptr + DoC_Mil_CDSN_IO, eccbuf, 6);
+#endif
+
+		/* write the block status BLOCK_USED (0x5555) at the end of ECC data
+		   FIXME: this is only a hack for programming the IPL area for LinuxBIOS
+		   and should be replace with proper codes in user space utilities */ 
+		WriteDOC(0x55, docptr, Mil_CDSN_IO);
+		WriteDOC(0x55, docptr, Mil_CDSN_IO + 1);
+
+		WriteDOC(0x00, docptr, WritePipeTerm);
+
+#ifdef PSYCHO_DEBUG
+		printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
+		       (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
+		       eccbuf[4], eccbuf[5]);
+#endif
+	}
+
+	/* Commit the Page Program command and wait for ready
+	   see Software Requirement 11.4 item 1.*/
+	DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
+	DoC_WaitReady(docptr);
+
+	/* Read the status of the flash device through CDSN IO register
+	   see Software Requirement 11.4 item 5.*/
+	DoC_Command(docptr, NAND_CMD_STATUS, CDSN_CTRL_WP);
+	dummy = ReadDOC(docptr, ReadPipeInit);
+	DoC_Delay(docptr, 2);
+	if (ReadDOC(docptr, Mil_CDSN_IO) & 1) {
+		printk("Error programming flash\n");
+		/* Error in programming
+		   FIXME: implement Bad Block Replacement (in nftl.c ??) */
+		*retlen = 0;
+		ret = -EIO;
+	}
+	dummy = ReadDOC(docptr, LastDataRead);
+
+	/* Let the caller know we completed it */
+	*retlen = len;
+
+	return ret;
+}
+
+static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
+			size_t *retlen, u_char *buf)
+{
+#ifndef USE_MEMCPY
+	int i;
+#endif
+	volatile char dummy;
+	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	unsigned long docptr = this->virtadr;
+	struct Nand *mychip = &this->chips[ofs >> this->chipshift];
+
+	/* Find the chip which is to be used and select it */
+	if (this->curfloor != mychip->floor) {
+		DoC_SelectFloor(docptr, mychip->floor);
+		DoC_SelectChip(docptr, mychip->chip);
+	} else if (this->curchip != mychip->chip) {
+		DoC_SelectChip(docptr, mychip->chip);
+	}
+	this->curfloor = mychip->floor;
+	this->curchip = mychip->chip;
+
+	/* disable the ECC engine */
+	WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
+	WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
+
+	/* issue the Read2 command to set the pointer to the Spare Data Area.
+	   Polling the Flash Ready bit after issue 3 bytes address in
+	   Sequence Read Mode, see Software Requirement 11.4 item 1.*/
+	DoC_Command(docptr, NAND_CMD_READOOB, CDSN_CTRL_WP);
+	DoC_Address(docptr, 3, ofs, CDSN_CTRL_WP, 0x00);
+	DoC_WaitReady(docptr);
+
+	/* Read the data out via the internal pipeline through CDSN IO register,
+	   see Pipelined Read Operations 11.3 */
+	dummy = ReadDOC(docptr, ReadPipeInit);
+#ifndef USE_MEMCPY
+	for (i = 0; i < len-1; i++) {
+		/* N.B. you have to increase the source address in this way or the
+		   ECC logic will not work properly */
+		buf[i] = ReadDOC(docptr, Mil_CDSN_IO + i);
+	}
+#else
+	memcpy_fromio(buf, docptr + DoC_Mil_CDSN_IO, len - 1);
+#endif
+	buf[len - 1] = ReadDOC(docptr, LastDataRead);
+
+	*retlen = len;
+
+	return 0;
+}
+
+static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
+			 size_t *retlen, const u_char *buf)
+{
+#ifndef USE_MEMCPY
+	int i;
+#endif
+	volatile char dummy;
+	int ret = 0;
+	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	unsigned long docptr = this->virtadr;
+	struct Nand *mychip = &this->chips[ofs >> this->chipshift];
+
+	/* Find the chip which is to be used and select it */
+	if (this->curfloor != mychip->floor) {
+		DoC_SelectFloor(docptr, mychip->floor);
+		DoC_SelectChip(docptr, mychip->chip);
+	} else if (this->curchip != mychip->chip) {
+		DoC_SelectChip(docptr, mychip->chip);
+	}
+	this->curfloor = mychip->floor;
+	this->curchip = mychip->chip;
+
+	/* disable the ECC engine */
+	WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
+	WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
+
+	/* Reset the chip, see Software Requirement 11.4 item 1. */
+	DoC_Command(docptr, NAND_CMD_RESET, CDSN_CTRL_WP);
+	DoC_WaitReady(docptr);
+	/* issue the Read2 command to set the pointer to the Spare Data Area. */
+	DoC_Command(docptr, NAND_CMD_READOOB, CDSN_CTRL_WP);
+
+	/* issue the Serial Data In command to initial the Page Program process */
+	DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
+	DoC_Address(docptr, 3, ofs, 0x00, 0x00);
+
+	/* Write the data via the internal pipeline through CDSN IO register,
+	   see Pipelined Write Operations 11.2 */
+#ifndef USE_MEMCPY
+	for (i = 0; i < len; i++) {
+		/* N.B. you have to increase the source address in this way or the
+		   ECC logic will not work properly */
+		WriteDOC(buf[i], docptr, Mil_CDSN_IO + i);
+	}
+#else
+	memcpy_toio(docptr + DoC_Mil_CDSN_IO, buf, len);
+#endif
+	WriteDOC(0x00, docptr, WritePipeTerm);
+
+	/* Commit the Page Program command and wait for ready
+	   see Software Requirement 11.4 item 1.*/
+	DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
+	DoC_WaitReady(docptr);
+
+	/* Read the status of the flash device through CDSN IO register
+	   see Software Requirement 11.4 item 5.*/
+	DoC_Command(docptr, NAND_CMD_STATUS, 0x00);
+	dummy = ReadDOC(docptr, ReadPipeInit);
+	DoC_Delay(docptr, 2);
+	if (ReadDOC(docptr, Mil_CDSN_IO) & 1) {
+		printk("Error programming oob data\n");
+		/* FIXME: implement Bad Block Replacement (in nftl.c ??) */
+		*retlen = 0;
+		ret = -EIO;
+	}
+	dummy = ReadDOC(docptr, LastDataRead);
+
+	*retlen = len;
+
+	return ret;
+}
+
+int doc_erase (struct mtd_info *mtd, struct erase_info *instr)
+{
+	volatile char dummy;
+	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	__u32 ofs = instr->addr;
+	__u32 len = instr->len;
+	unsigned long docptr = this->virtadr;
+	struct Nand *mychip = &this->chips[ofs >> this->chipshift];
+
+	if (len != mtd->erasesize) 
+		printk(KERN_WARNING "Erase not right size (%x != %x)n",
+		       len, mtd->erasesize);
+
+	/* Find the chip which is to be used and select it */
+	if (this->curfloor != mychip->floor) {
+		DoC_SelectFloor(docptr, mychip->floor);
+		DoC_SelectChip(docptr, mychip->chip);
+	} else if (this->curchip != mychip->chip) {
+		DoC_SelectChip(docptr, mychip->chip);
+	}
+	this->curfloor = mychip->floor;
+	this->curchip = mychip->chip;
+
+	instr->state = MTD_ERASE_PENDING;
+
+	/* issue the Erase Setup command */
+	DoC_Command(docptr, NAND_CMD_ERASE1, 0x00);
+	DoC_Address(docptr, 2, ofs, 0x00, 0x00);
+
+	/* Commit the Erase Start command and wait for ready
+	   see Software Requirement 11.4 item 1.*/
+	DoC_Command(docptr, NAND_CMD_ERASE2, 0x00);
+	DoC_WaitReady(docptr);
+
+	instr->state = MTD_ERASING;
+
+	/* Read the status of the flash device through CDSN IO register
+	   see Software Requirement 11.4 item 5.
+	   FIXME: it seems that we are not wait long enough, some blocks are not
+	   erased fully */
+	DoC_Command(docptr, NAND_CMD_STATUS, CDSN_CTRL_WP);
+	dummy = ReadDOC(docptr, ReadPipeInit);
+	DoC_Delay(docptr, 2);
+	if (ReadDOC(docptr, Mil_CDSN_IO) & 1) {
+		printk("Error Erasing at 0x%x\n", ofs);
+		/* There was an error
+		   FIXME: implement Bad Block Replacement (in nftl.c ??) */
+		instr->state = MTD_ERASE_FAILED;
+	} else
+		instr->state = MTD_ERASE_DONE;
+	dummy = ReadDOC(docptr, LastDataRead);
+
+	if (instr->callback) 
+		instr->callback(instr);
+
+	return 0;
+}
+
+/****************************************************************************
+ *
+ * Module stuff
+ *
+ ****************************************************************************/
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define cleanup_doc2001 cleanup_module
+#define init_doc2001 init_module
+#endif
+
+int __init init_doc2001(void)
+{
+	inter_module_register(im_name, THIS_MODULE, &DoCMil_init);
+	return 0;
+}
+
+static void __exit cleanup_doc2001(void)
+{
+	struct mtd_info *mtd;
+	struct DiskOnChip *this;
+
+	while ((mtd=docmillist)) {
+		this = (struct DiskOnChip *)mtd->priv;
+		docmillist = this->nextdoc;
+			
+		del_mtd_device(mtd);
+			
+		iounmap((void *)this->virtadr);
+		kfree(this->chips);
+		kfree(mtd);
+	}
+	inter_module_unregister(im_name);
+}
+
+module_exit(cleanup_doc2001);
+module_init(init_doc2001);
+
+
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/devices/docecc.c linux/drivers/mtd/devices/docecc.c
--- v2.4.5/linux/drivers/mtd/devices/docecc.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/devices/docecc.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,522 @@
+/*
+ * ECC algorithm for M-systems disk on chip. We use the excellent Reed
+ * Solmon code of Phil Karn (karn@ka9q.ampr.org) available under the
+ * GNU GPL License. The rest is simply to convert the disk on chip
+ * syndrom into a standard syndom.
+ *
+ * Author: Fabrice Bellard (fabrice.bellard@netgem.com) 
+ * Copyright (C) 2000 Netgem S.A.
+ *
+ * $Id: docecc.c,v 1.1 2000/11/03 12:43:43 dwmw2 Exp $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/doc2000.h>
+
+/* need to undef it (from asm/termbits.h) */
+#undef B0
+
+#define MM 10 /* Symbol size in bits */
+#define KK (1023-4) /* Number of data symbols per block */
+#define B0 510 /* First root of generator polynomial, alpha form */
+#define PRIM 1 /* power of alpha used to generate roots of generator poly */
+#define	NN ((1 << MM) - 1)
+
+typedef unsigned short dtype;
+
+/* 1+x^3+x^10 */
+static const int Pp[MM+1] = { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
+
+/* This defines the type used to store an element of the Galois Field
+ * used by the code. Make sure this is something larger than a char if
+ * if anything larger than GF(256) is used.
+ *
+ * Note: unsigned char will work up to GF(256) but int seems to run
+ * faster on the Pentium.
+ */
+typedef int gf;
+
+/* No legal value in index form represents zero, so
+ * we need a special value for this purpose
+ */
+#define A0	(NN)
+
+/* Compute x % NN, where NN is 2**MM - 1,
+ * without a slow divide
+ */
+static inline gf
+modnn(int x)
+{
+  while (x >= NN) {
+    x -= NN;
+    x = (x >> MM) + (x & NN);
+  }
+  return x;
+}
+
+#define	min(a,b)	((a) < (b) ? (a) : (b))
+
+#define	CLEAR(a,n) {\
+int ci;\
+for(ci=(n)-1;ci >=0;ci--)\
+(a)[ci] = 0;\
+}
+
+#define	COPY(a,b,n) {\
+int ci;\
+for(ci=(n)-1;ci >=0;ci--)\
+(a)[ci] = (b)[ci];\
+}
+
+#define	COPYDOWN(a,b,n) {\
+int ci;\
+for(ci=(n)-1;ci >=0;ci--)\
+(a)[ci] = (b)[ci];\
+}
+
+#define Ldec 1
+
+/* generate GF(2**m) from the irreducible polynomial p(X) in Pp[0]..Pp[m]
+   lookup tables:  index->polynomial form   alpha_to[] contains j=alpha**i;
+                   polynomial form -> index form  index_of[j=alpha**i] = i
+   alpha=2 is the primitive element of GF(2**m)
+   HARI's COMMENT: (4/13/94) alpha_to[] can be used as follows:
+        Let @ represent the primitive element commonly called "alpha" that
+   is the root of the primitive polynomial p(x). Then in GF(2^m), for any
+   0 <= i <= 2^m-2,
+        @^i = a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1)
+   where the binary vector (a(0),a(1),a(2),...,a(m-1)) is the representation
+   of the integer "alpha_to[i]" with a(0) being the LSB and a(m-1) the MSB. Thus for
+   example the polynomial representation of @^5 would be given by the binary
+   representation of the integer "alpha_to[5]".
+                   Similarily, index_of[] can be used as follows:
+        As above, let @ represent the primitive element of GF(2^m) that is
+   the root of the primitive polynomial p(x). In order to find the power
+   of @ (alpha) that has the polynomial representation
+        a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1)
+   we consider the integer "i" whose binary representation with a(0) being LSB
+   and a(m-1) MSB is (a(0),a(1),...,a(m-1)) and locate the entry
+   "index_of[i]". Now, @^index_of[i] is that element whose polynomial 
+    representation is (a(0),a(1),a(2),...,a(m-1)).
+   NOTE:
+        The element alpha_to[2^m-1] = 0 always signifying that the
+   representation of "@^infinity" = 0 is (0,0,0,...,0).
+        Similarily, the element index_of[0] = A0 always signifying
+   that the power of alpha which has the polynomial representation
+   (0,0,...,0) is "infinity".
+ 
+*/
+
+static void
+generate_gf(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1])
+{
+  register int i, mask;
+
+  mask = 1;
+  Alpha_to[MM] = 0;
+  for (i = 0; i < MM; i++) {
+    Alpha_to[i] = mask;
+    Index_of[Alpha_to[i]] = i;
+    /* If Pp[i] == 1 then, term @^i occurs in poly-repr of @^MM */
+    if (Pp[i] != 0)
+      Alpha_to[MM] ^= mask;	/* Bit-wise EXOR operation */
+    mask <<= 1;	/* single left-shift */
+  }
+  Index_of[Alpha_to[MM]] = MM;
+  /*
+   * Have obtained poly-repr of @^MM. Poly-repr of @^(i+1) is given by
+   * poly-repr of @^i shifted left one-bit and accounting for any @^MM
+   * term that may occur when poly-repr of @^i is shifted.
+   */
+  mask >>= 1;
+  for (i = MM + 1; i < NN; i++) {
+    if (Alpha_to[i - 1] >= mask)
+      Alpha_to[i] = Alpha_to[MM] ^ ((Alpha_to[i - 1] ^ mask) << 1);
+    else
+      Alpha_to[i] = Alpha_to[i - 1] << 1;
+    Index_of[Alpha_to[i]] = i;
+  }
+  Index_of[0] = A0;
+  Alpha_to[NN] = 0;
+}
+
+/*
+ * Performs ERRORS+ERASURES decoding of RS codes. bb[] is the content
+ * of the feedback shift register after having processed the data and
+ * the ECC.
+ *
+ * Return number of symbols corrected, or -1 if codeword is illegal
+ * or uncorrectable. If eras_pos is non-null, the detected error locations
+ * are written back. NOTE! This array must be at least NN-KK elements long.
+ * The corrected data are written in eras_val[]. They must be xor with the data
+ * to retrieve the correct data : data[erase_pos[i]] ^= erase_val[i] .
+ * 
+ * First "no_eras" erasures are declared by the calling program. Then, the
+ * maximum # of errors correctable is t_after_eras = floor((NN-KK-no_eras)/2).
+ * If the number of channel errors is not greater than "t_after_eras" the
+ * transmitted codeword will be recovered. Details of algorithm can be found
+ * in R. Blahut's "Theory ... of Error-Correcting Codes".
+
+ * Warning: the eras_pos[] array must not contain duplicate entries; decoder failure
+ * will result. The decoder *could* check for this condition, but it would involve
+ * extra time on every decoding operation.
+ * */
+static int
+eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
+            gf bb[NN - KK + 1], gf eras_val[NN-KK], int eras_pos[NN-KK], 
+            int no_eras)
+{
+  int deg_lambda, el, deg_omega;
+  int i, j, r,k;
+  gf u,q,tmp,num1,num2,den,discr_r;
+  gf lambda[NN-KK + 1], s[NN-KK + 1];	/* Err+Eras Locator poly
+					 * and syndrome poly */
+  gf b[NN-KK + 1], t[NN-KK + 1], omega[NN-KK + 1];
+  gf root[NN-KK], reg[NN-KK + 1], loc[NN-KK];
+  int syn_error, count;
+
+  syn_error = 0;
+  for(i=0;i<NN-KK;i++)
+      syn_error |= bb[i];
+
+  if (!syn_error) {
+    /* if remainder is zero, data[] is a codeword and there are no
+     * errors to correct. So return data[] unmodified
+     */
+    count = 0;
+    goto finish;
+  }
+  
+  for(i=1;i<=NN-KK;i++){
+    s[i] = bb[0];
+  }
+  for(j=1;j<NN-KK;j++){
+    if(bb[j] == 0)
+      continue;
+    tmp = Index_of[bb[j]];
+    
+    for(i=1;i<=NN-KK;i++)
+      s[i] ^= Alpha_to[modnn(tmp + (B0+i-1)*PRIM*j)];
+  }
+
+  /* undo the feedback register implicit multiplication and convert
+     syndromes to index form */
+
+  for(i=1;i<=NN-KK;i++) {
+      tmp = Index_of[s[i]];
+      if (tmp != A0)
+          tmp = modnn(tmp + 2 * KK * (B0+i-1)*PRIM);
+      s[i] = tmp;
+  }
+  
+  CLEAR(&lambda[1],NN-KK);
+  lambda[0] = 1;
+
+  if (no_eras > 0) {
+    /* Init lambda to be the erasure locator polynomial */
+    lambda[1] = Alpha_to[modnn(PRIM * eras_pos[0])];
+    for (i = 1; i < no_eras; i++) {
+      u = modnn(PRIM*eras_pos[i]);
+      for (j = i+1; j > 0; j--) {
+	tmp = Index_of[lambda[j - 1]];
+	if(tmp != A0)
+	  lambda[j] ^= Alpha_to[modnn(u + tmp)];
+      }
+    }
+#if DEBUG >= 1
+    /* Test code that verifies the erasure locator polynomial just constructed
+       Needed only for decoder debugging. */
+    
+    /* find roots of the erasure location polynomial */
+    for(i=1;i<=no_eras;i++)
+      reg[i] = Index_of[lambda[i]];
+    count = 0;
+    for (i = 1,k=NN-Ldec; i <= NN; i++,k = modnn(NN+k-Ldec)) {
+      q = 1;
+      for (j = 1; j <= no_eras; j++)
+	if (reg[j] != A0) {
+	  reg[j] = modnn(reg[j] + j);
+	  q ^= Alpha_to[reg[j]];
+	}
+      if (q != 0)
+	continue;
+      /* store root and error location number indices */
+      root[count] = i;
+      loc[count] = k;
+      count++;
+    }
+    if (count != no_eras) {
+      printf("\n lambda(x) is WRONG\n");
+      count = -1;
+      goto finish;
+    }
+#if DEBUG >= 2
+    printf("\n Erasure positions as determined by roots of Eras Loc Poly:\n");
+    for (i = 0; i < count; i++)
+      printf("%d ", loc[i]);
+    printf("\n");
+#endif
+#endif
+  }
+  for(i=0;i<NN-KK+1;i++)
+    b[i] = Index_of[lambda[i]];
+  
+  /*
+   * Begin Berlekamp-Massey algorithm to determine error+erasure
+   * locator polynomial
+   */
+  r = no_eras;
+  el = no_eras;
+  while (++r <= NN-KK) {	/* r is the step number */
+    /* Compute discrepancy at the r-th step in poly-form */
+    discr_r = 0;
+    for (i = 0; i < r; i++){
+      if ((lambda[i] != 0) && (s[r - i] != A0)) {
+	discr_r ^= Alpha_to[modnn(Index_of[lambda[i]] + s[r - i])];
+      }
+    }
+    discr_r = Index_of[discr_r];	/* Index form */
+    if (discr_r == A0) {
+      /* 2 lines below: B(x) <-- x*B(x) */
+      COPYDOWN(&b[1],b,NN-KK);
+      b[0] = A0;
+    } else {
+      /* 7 lines below: T(x) <-- lambda(x) - discr_r*x*b(x) */
+      t[0] = lambda[0];
+      for (i = 0 ; i < NN-KK; i++) {
+	if(b[i] != A0)
+	  t[i+1] = lambda[i+1] ^ Alpha_to[modnn(discr_r + b[i])];
+	else
+	  t[i+1] = lambda[i+1];
+      }
+      if (2 * el <= r + no_eras - 1) {
+	el = r + no_eras - el;
+	/*
+	 * 2 lines below: B(x) <-- inv(discr_r) *
+	 * lambda(x)
+	 */
+	for (i = 0; i <= NN-KK; i++)
+	  b[i] = (lambda[i] == 0) ? A0 : modnn(Index_of[lambda[i]] - discr_r + NN);
+      } else {
+	/* 2 lines below: B(x) <-- x*B(x) */
+	COPYDOWN(&b[1],b,NN-KK);
+	b[0] = A0;
+      }
+      COPY(lambda,t,NN-KK+1);
+    }
+  }
+
+  /* Convert lambda to index form and compute deg(lambda(x)) */
+  deg_lambda = 0;
+  for(i=0;i<NN-KK+1;i++){
+    lambda[i] = Index_of[lambda[i]];
+    if(lambda[i] != A0)
+      deg_lambda = i;
+  }
+  /*
+   * Find roots of the error+erasure locator polynomial by Chien
+   * Search
+   */
+  COPY(&reg[1],&lambda[1],NN-KK);
+  count = 0;		/* Number of roots of lambda(x) */
+  for (i = 1,k=NN-Ldec; i <= NN; i++,k = modnn(NN+k-Ldec)) {
+    q = 1;
+    for (j = deg_lambda; j > 0; j--){
+      if (reg[j] != A0) {
+	reg[j] = modnn(reg[j] + j);
+	q ^= Alpha_to[reg[j]];
+      }
+    }
+    if (q != 0)
+      continue;
+    /* store root (index-form) and error location number */
+    root[count] = i;
+    loc[count] = k;
+    /* If we've already found max possible roots,
+     * abort the search to save time
+     */
+    if(++count == deg_lambda)
+      break;
+  }
+  if (deg_lambda != count) {
+    /*
+     * deg(lambda) unequal to number of roots => uncorrectable
+     * error detected
+     */
+    count = -1;
+    goto finish;
+  }
+  /*
+   * Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo
+   * x**(NN-KK)). in index form. Also find deg(omega).
+   */
+  deg_omega = 0;
+  for (i = 0; i < NN-KK;i++){
+    tmp = 0;
+    j = (deg_lambda < i) ? deg_lambda : i;
+    for(;j >= 0; j--){
+      if ((s[i + 1 - j] != A0) && (lambda[j] != A0))
+	tmp ^= Alpha_to[modnn(s[i + 1 - j] + lambda[j])];
+    }
+    if(tmp != 0)
+      deg_omega = i;
+    omega[i] = Index_of[tmp];
+  }
+  omega[NN-KK] = A0;
+  
+  /*
+   * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 =
+   * inv(X(l))**(B0-1) and den = lambda_pr(inv(X(l))) all in poly-form
+   */
+  for (j = count-1; j >=0; j--) {
+    num1 = 0;
+    for (i = deg_omega; i >= 0; i--) {
+      if (omega[i] != A0)
+	num1  ^= Alpha_to[modnn(omega[i] + i * root[j])];
+    }
+    num2 = Alpha_to[modnn(root[j] * (B0 - 1) + NN)];
+    den = 0;
+    
+    /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
+    for (i = min(deg_lambda,NN-KK-1) & ~1; i >= 0; i -=2) {
+      if(lambda[i+1] != A0)
+	den ^= Alpha_to[modnn(lambda[i+1] + i * root[j])];
+    }
+    if (den == 0) {
+#if DEBUG >= 1
+      printf("\n ERROR: denominator = 0\n");
+#endif
+      /* Convert to dual- basis */
+      count = -1;
+      goto finish;
+    }
+    /* Apply error to data */
+    if (num1 != 0) {
+        eras_val[j] = Alpha_to[modnn(Index_of[num1] + Index_of[num2] + NN - Index_of[den])];
+    } else {
+        eras_val[j] = 0;
+    }
+  }
+ finish:
+  for(i=0;i<count;i++)
+      eras_pos[i] = loc[i];
+  return count;
+}
+
+/***************************************************************************/
+/* The DOC specific code begins here */
+
+#define SECTOR_SIZE 512
+/* The sector bytes are packed into NB_DATA MM bits words */
+#define NB_DATA (((SECTOR_SIZE + 1) * 8 + 6) / MM)
+
+/* 
+ * Correct the errors in 'sector[]' by using 'ecc1[]' which is the
+ * content of the feedback shift register applyied to the sector and
+ * the ECC. Return the number of errors corrected (and correct them in
+ * sector), or -1 if error 
+ */
+int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
+{
+    int parity, i, nb_errors;
+    gf bb[NN - KK + 1];
+    gf error_val[NN-KK];
+    int error_pos[NN-KK], pos, bitpos, index, val;
+    dtype *Alpha_to, *Index_of;
+
+    /* init log and exp tables here to save memory. However, it is slower */
+    Alpha_to = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL);
+    if (!Alpha_to)
+        return -1;
+    
+    Index_of = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL);
+    if (!Index_of) {
+        kfree(Alpha_to);
+        return -1;
+    }
+
+    generate_gf(Alpha_to, Index_of);
+
+    parity = ecc1[1];
+
+    bb[0] =  (ecc1[4] & 0xff) | ((ecc1[5] & 0x03) << 8);
+    bb[1] = ((ecc1[5] & 0xfc) >> 2) | ((ecc1[2] & 0x0f) << 6);
+    bb[2] = ((ecc1[2] & 0xf0) >> 4) | ((ecc1[3] & 0x3f) << 4);
+    bb[3] = ((ecc1[3] & 0xc0) >> 6) | ((ecc1[0] & 0xff) << 2);
+
+    nb_errors = eras_dec_rs(Alpha_to, Index_of, bb, 
+                            error_val, error_pos, 0);
+    if (nb_errors <= 0)
+        goto the_end;
+
+    /* correct the errors */
+    for(i=0;i<nb_errors;i++) {
+        pos = error_pos[i];
+        if (pos >= NB_DATA && pos < KK) {
+            nb_errors = -1;
+            goto the_end;
+        }
+        if (pos < NB_DATA) {
+            /* extract bit position (MSB first) */
+            pos = 10 * (NB_DATA - 1 - pos) - 6;
+            /* now correct the following 10 bits. At most two bytes
+               can be modified since pos is even */
+            index = (pos >> 3) ^ 1;
+            bitpos = pos & 7;
+            if ((index >= 0 && index < SECTOR_SIZE) || 
+                index == (SECTOR_SIZE + 1)) {
+                val = error_val[i] >> (2 + bitpos);
+                parity ^= val;
+                if (index < SECTOR_SIZE)
+                    sector[index] ^= val;
+            }
+            index = ((pos >> 3) + 1) ^ 1;
+            bitpos = (bitpos + 10) & 7;
+            if (bitpos == 0)
+                bitpos = 8;
+            if ((index >= 0 && index < SECTOR_SIZE) || 
+                index == (SECTOR_SIZE + 1)) {
+                val = error_val[i] << (8 - bitpos);
+                parity ^= val;
+                if (index < SECTOR_SIZE)
+                    sector[index] ^= val;
+            }
+        }
+    }
+    
+    /* use parity to test extra errors */
+    if ((parity & 0xff) != 0)
+        nb_errors = -1;
+
+ the_end:
+    kfree(Alpha_to);
+    kfree(Index_of);
+    return nb_errors;
+}
+
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/devices/docprobe.c linux/drivers/mtd/devices/docprobe.c
--- v2.4.5/linux/drivers/mtd/devices/docprobe.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/devices/docprobe.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,285 @@
+
+/* Linux driver for Disk-On-Chip devices			*/
+/* Probe routines common to all DoC devices			*/
+/* (c) 1999 Machine Vision Holdings, Inc.			*/
+/* Author: David Woodhouse <dwmw2@infradead.org>		*/
+/* $Id: docprobe.c,v 1.27 2001/06/03 19:06:09 dwmw2 Exp $	*/
+
+
+
+/* DOC_PASSIVE_PROBE:
+   In order to ensure that the BIOS checksum is correct at boot time, and 
+   hence that the onboard BIOS extension gets executed, the DiskOnChip 
+   goes into reset mode when it is read sequentially: all registers 
+   return 0xff until the chip is woken up again by writing to the 
+   DOCControl register. 
+
+   Unfortunately, this means that the probe for the DiskOnChip is unsafe, 
+   because one of the first things it does is write to where it thinks 
+   the DOCControl register should be - which may well be shared memory 
+   for another device. I've had machines which lock up when this is 
+   attempted. Hence the possibility to do a passive probe, which will fail 
+   to detect a chip in reset mode, but is at least guaranteed not to lock
+   the machine.
+
+   If you have this problem, uncomment the following line:
+#define DOC_PASSIVE_PROBE
+*/
+
+
+/* DOC_SINGLE_DRIVER:
+   Millennium driver has been merged into DOC2000 driver.
+
+   The newly-merged driver doesn't appear to work for writing. It's the
+   same with the DiskOnChip 2000 and the Millennium. If you have a 
+   Millennium and you want write support to work, remove the definition
+   of DOC_SINGLE_DRIVER below to use the old doc2001-specific driver.
+
+   Otherwise, it's left on in the hope that it'll annoy someone with
+   a Millennium enough that they go through and work out what the 
+   difference is :)
+*/
+#define DOC_SINGLE_DRIVER
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/doc2000.h>
+
+/* Where to look for the devices? */
+#ifndef CONFIG_MTD_DOCPROBE_ADDRESS
+#define CONFIG_MTD_DOCPROBE_ADDRESS 0
+#endif
+
+
+static unsigned long doc_config_location = CONFIG_MTD_DOCPROBE_ADDRESS;
+MODULE_PARM(doc_config_location, "l");
+
+
+static unsigned long __initdata doc_locations[] = {
+#if defined (__alpha__) || defined(__i386__)
+#ifdef CONFIG_MTD_DOCPROBE_HIGH
+	0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000, 
+	0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
+	0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000, 
+	0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000, 
+	0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000,
+#else /*  CONFIG_MTD_DOCPROBE_HIGH */
+	0xc8000, 0xca000, 0xcc000, 0xce000, 
+	0xd0000, 0xd2000, 0xd4000, 0xd6000,
+	0xd8000, 0xda000, 0xdc000, 0xde000, 
+	0xe0000, 0xe2000, 0xe4000, 0xe6000, 
+	0xe8000, 0xea000, 0xec000, 0xee000,
+#endif /*  CONFIG_MTD_DOCPROBE_HIGH */
+#elif defined(__ppc__)
+	0xe4000000,
+#elif defined(CONFIG_MOMENCO_OCELOT)
+	0x2f000000,
+#else
+#warning Unknown architecture for DiskOnChip. No default probe locations defined
+#endif
+	0 };
+
+/* doccheck: Probe a given memory window to see if there's a DiskOnChip present */
+
+static inline int __init doccheck(unsigned long potential, unsigned long physadr)
+{
+	unsigned long window=potential;
+	unsigned char tmp, ChipID;
+#ifndef DOC_PASSIVE_PROBE
+	unsigned char tmp2;
+#endif
+
+	/* Routine copied from the Linux DOC driver */
+
+#ifdef CONFIG_MTD_DOCPROBE_55AA
+	/* Check for 0x55 0xAA signature at beginning of window,
+	   this is no longer true once we remove the IPL (for Millennium */
+	if (ReadDOC(window, Sig1) != 0x55 || ReadDOC(window, Sig2) != 0xaa)
+		return 0;
+#endif /* CONFIG_MTD_DOCPROBE_55AA */
+
+#ifndef DOC_PASSIVE_PROBE	
+	/* It's not possible to cleanly detect the DiskOnChip - the
+	 * bootup procedure will put the device into reset mode, and
+	 * it's not possible to talk to it without actually writing
+	 * to the DOCControl register. So we store the current contents
+	 * of the DOCControl register's location, in case we later decide
+	 * that it's not a DiskOnChip, and want to put it back how we
+	 * found it. 
+	 */
+	tmp2 = ReadDOC(window, DOCControl);
+	
+	/* Reset the DiskOnChip ASIC */
+	WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, 
+		 window, DOCControl);
+	WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, 
+		 window, DOCControl);
+	
+	/* Enable the DiskOnChip ASIC */
+	WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, 
+		 window, DOCControl);
+	WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, 
+		 window, DOCControl);
+#endif /* !DOC_PASSIVE_PROBE */	
+
+	ChipID = ReadDOC(window, ChipID);
+  
+	switch (ChipID) {
+	case DOC_ChipID_Doc2k:
+		/* Check the TOGGLE bit in the ECC register */
+		tmp = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT;
+		if ((ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT) != tmp)
+				return ChipID;
+		break;
+		
+	case DOC_ChipID_DocMil:
+		/* Check the TOGGLE bit in the ECC register */
+		tmp = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
+		if ((ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT) != tmp)
+				return ChipID;
+		break;
+		
+	default:
+#ifndef CONFIG_MTD_DOCPROBE_55AA
+		printk(KERN_WARNING "Possible DiskOnChip with unknown ChipID %2.2X found at 0x%lx\n",
+		       ChipID, physadr);
+#endif
+#ifndef DOC_PASSIVE_PROBE
+		/* Put back the contents of the DOCControl register, in case it's not
+		 * actually a DiskOnChip.
+		 */
+		WriteDOC(tmp2, window, DOCControl);
+#endif
+		return 0;
+	}
+
+	printk(KERN_WARNING "DiskOnChip failed TOGGLE test, dropping.\n");
+
+#ifndef DOC_PASSIVE_PROBE
+	/* Put back the contents of the DOCControl register: it's not a DiskOnChip */
+	WriteDOC(tmp2, window, DOCControl);
+#endif
+	return 0;
+}   
+
+
+static void __init DoC_Probe(unsigned long physadr)
+{
+	unsigned long docptr;
+	struct DiskOnChip *this;
+	struct mtd_info *mtd;
+	int ChipID;
+	char namebuf[15];
+	char *name = namebuf;
+	char *im_funcname = NULL;
+	char *im_modname = NULL;
+	void (*initroutine)(struct mtd_info *) = NULL;
+
+	docptr = (unsigned long)ioremap(physadr, DOC_IOREMAP_LEN);
+	
+	if (!docptr)
+		return;
+	
+	if ((ChipID = doccheck(docptr, physadr))) {
+		
+		mtd = kmalloc(sizeof(struct DiskOnChip) + sizeof(struct mtd_info), GFP_KERNEL);
+
+		if (!mtd) {
+			printk("Cannot allocate memory for data structures. Dropping.\n");
+			iounmap((void *)docptr);
+			return;
+		}
+		
+		this = (struct DiskOnChip *)(&mtd[1]);
+		
+		memset((char *)mtd,0, sizeof(struct mtd_info));
+		memset((char *)this, 0, sizeof(struct DiskOnChip));
+
+		mtd->priv = this;
+		this->virtadr = docptr;
+		this->physadr = physadr;
+		this->ChipID = ChipID;
+		sprintf(namebuf, "with ChipID %2.2X", ChipID);
+
+		switch(ChipID) {
+		case DOC_ChipID_Doc2k:
+			name="2000";
+			im_funcname = "DoC2k_init";
+			im_modname = "doc2000";
+			break;
+			
+		case DOC_ChipID_DocMil:
+			name="Millennium";
+#ifdef DOC_SINGLE_DRIVER
+			im_funcname = "DoC2k_init";
+			im_modname = "doc2000";
+#else
+			im_funcname = "DoCMil_init";
+			im_modname = "doc2001";
+#endif /* DOC_SINGLE_DRIVER */
+			break;
+		}
+
+		if (im_funcname)
+			initroutine = inter_module_get_request(im_funcname, im_modname);
+
+		if (initroutine) {
+			(*initroutine)(mtd);
+			inter_module_put(im_funcname);
+			return;
+		}
+		printk("Cannot find driver for DiskOnChip %s at 0x%lX\n", name, physadr);
+	}
+	iounmap((void *)docptr);
+}
+
+
+/****************************************************************************
+ *
+ * Module stuff
+ *
+ ****************************************************************************/
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_doc init_module
+#endif
+
+int __init init_doc(void)
+{
+	int i;
+	
+	printk(KERN_NOTICE "M-Systems DiskOnChip driver. (C) 1999 Machine Vision Holdings, Inc.\n");
+#ifdef PRERELEASE
+	printk(KERN_INFO "$Id: docprobe.c,v 1.27 2001/06/03 19:06:09 dwmw2 Exp $\n");
+#endif
+	if (doc_config_location) {
+		printk("Using configured probe address 0x%lx\n", doc_config_location);
+		DoC_Probe(doc_config_location);
+	} else {
+		for (i=0; doc_locations[i]; i++) {
+			DoC_Probe(doc_locations[i]);
+		}
+	}
+	/* So it looks like we've been used and we get unloaded */
+	MOD_INC_USE_COUNT;
+	MOD_DEC_USE_COUNT;
+	return 0;
+	
+}
+
+module_init(init_doc);
+
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/devices/mtdram.c linux/drivers/mtd/devices/mtdram.c
--- v2.4.5/linux/drivers/mtd/devices/mtdram.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/devices/mtdram.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,178 @@
+/*
+ * mtdram - a test mtd device
+ * $Id: mtdram.c,v 1.24 2001/06/09 23:09:23 dwmw2 Exp $
+ * Author: Alexander Larsson <alex@cendio.se>
+ *
+ * Copyright (c) 1999 Alexander Larsson <alex@cendio.se>
+ *
+ * This code is GPL
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/mtd/compatmac.h>
+#include <linux/mtd/mtd.h>
+
+#ifndef CONFIG_MTDRAM_ABS_POS
+  #define CONFIG_MTDRAM_ABS_POS 0
+#endif
+
+#if CONFIG_MTDRAM_ABS_POS > 0
+  #include <asm/io.h>
+#endif
+
+#ifdef MODULE
+static unsigned long total_size = CONFIG_MTDRAM_TOTAL_SIZE;
+static unsigned long erase_size = CONFIG_MTDRAM_ERASE_SIZE;
+MODULE_PARM(total_size,"l");
+MODULE_PARM(erase_size,"l");
+#define MTDRAM_TOTAL_SIZE (total_size * 1024)
+#define MTDRAM_ERASE_SIZE (erase_size * 1024)
+#else
+#define MTDRAM_TOTAL_SIZE (CONFIG_MTDRAM_TOTAL_SIZE * 1024)
+#define MTDRAM_ERASE_SIZE (CONFIG_MTDRAM_ERASE_SIZE * 1024)
+#endif
+
+
+// We could store these in the mtd structure, but we only support 1 device..
+static struct mtd_info *mtd_info;
+
+
+static int
+ram_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+  DEBUG(MTD_DEBUG_LEVEL2, "ram_erase(pos:%ld, len:%ld)\n", (long)instr->addr, (long)instr->len);
+  if (instr->addr + instr->len > mtd->size) {
+    DEBUG(MTD_DEBUG_LEVEL1, "ram_erase() out of bounds (%ld > %ld)\n", (long)(instr->addr + instr->len), (long)mtd->size);
+    return -EINVAL;
+  }
+	
+  memset((char *)mtd->priv + instr->addr, 0xff, instr->len);
+	
+  instr->state = MTD_ERASE_DONE;
+
+  if (instr->callback)
+    (*(instr->callback))(instr);
+  return 0;
+}
+
+static int ram_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf)
+{
+  if (from + len > mtd->size)
+    return -EINVAL;
+	
+  *mtdbuf = mtd->priv + from;
+  *retlen = len;
+  return 0;
+}
+
+static void ram_unpoint (struct mtd_info *mtd, u_char *addr)
+{
+  DEBUG(MTD_DEBUG_LEVEL2, "ram_unpoint\n");
+}
+
+static int ram_read(struct mtd_info *mtd, loff_t from, size_t len,
+	     size_t *retlen, u_char *buf)
+{
+  DEBUG(MTD_DEBUG_LEVEL2, "ram_read(pos:%ld, len:%ld)\n", (long)from, (long)len);
+  if (from + len > mtd->size) {
+    DEBUG(MTD_DEBUG_LEVEL1, "ram_read() out of bounds (%ld > %ld)\n", (long)(from + len), (long)mtd->size);
+    return -EINVAL;
+  }
+
+  memcpy(buf, mtd->priv + from, len);
+
+  *retlen=len;
+  return 0;
+}
+
+static int ram_write(struct mtd_info *mtd, loff_t to, size_t len,
+	      size_t *retlen, const u_char *buf)
+{
+  DEBUG(MTD_DEBUG_LEVEL2, "ram_write(pos:%ld, len:%ld)\n", (long)to, (long)len);
+  if (to + len > mtd->size) {
+    DEBUG(MTD_DEBUG_LEVEL1, "ram_write() out of bounds (%ld > %ld)\n", (long)(to + len), (long)mtd->size);
+    return -EINVAL;
+  }
+
+  memcpy ((char *)mtd->priv + to, buf, len);
+
+  *retlen=len;
+  return 0;
+}
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_mtdram init_module
+#define cleanup_mtdram cleanup_module
+#endif
+
+//static void __exit cleanup_mtdram(void)
+mod_exit_t cleanup_mtdram(void)
+{
+  if (mtd_info) {
+    del_mtd_device(mtd_info);
+    if (mtd_info->priv)
+#if CONFIG_MTDRAM_ABS_POS > 0
+      iounmap(mtd_info->priv);
+#else
+      vfree(mtd_info->priv);
+#endif	
+    kfree(mtd_info);
+  }
+}
+
+mod_init_t init_mtdram(void)
+{
+   // Allocate some memory
+   mtd_info = (struct mtd_info *)kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
+   if (!mtd_info)
+      return 0;
+   
+   memset(mtd_info, 0, sizeof(*mtd_info));
+
+   // Setup the MTD structure
+   mtd_info->name = "mtdram test device";
+   mtd_info->type = MTD_RAM;
+   mtd_info->flags = MTD_CAP_RAM;
+   mtd_info->size = MTDRAM_TOTAL_SIZE;
+   mtd_info->erasesize = MTDRAM_ERASE_SIZE;
+#if CONFIG_MTDRAM_ABS_POS > 0
+   mtd_info->priv = ioremap(CONFIG_MTDRAM_ABS_POS, MTDRAM_TOTAL_SIZE);
+#else
+   mtd_info->priv = vmalloc(MTDRAM_TOTAL_SIZE);
+#endif
+
+   if (!mtd_info->priv) {
+     DEBUG(MTD_DEBUG_LEVEL1, "Failed to vmalloc(/ioremap) memory region of size %ld (ABS_POS:%ld)\n", (long)MTDRAM_TOTAL_SIZE, (long)CONFIG_MTDRAM_ABS_POS);
+     kfree(mtd_info);
+     mtd_info = NULL;
+     return -ENOMEM;
+   }
+   memset(mtd_info->priv, 0xff, MTDRAM_TOTAL_SIZE);
+
+   mtd_info->module = THIS_MODULE;			
+   mtd_info->erase = ram_erase;
+   mtd_info->point = ram_point;
+   mtd_info->unpoint = ram_unpoint;
+   mtd_info->read = ram_read;
+   mtd_info->write = ram_write;
+
+   if (add_mtd_device(mtd_info)) {
+#if CONFIG_MTDRAM_ABS_POS > 0
+     iounmap(mtd_info->priv);
+#else
+     vfree(mtd_info->priv);
+#endif	
+     kfree(mtd_info);
+     mtd_info = NULL;
+     return -EIO;
+   }
+   
+   return 0;
+}
+
+module_init(init_mtdram);
+module_exit(cleanup_mtdram);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/devices/pmc551.c linux/drivers/mtd/devices/pmc551.c
--- v2.4.5/linux/drivers/mtd/devices/pmc551.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/devices/pmc551.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,872 @@
+/*
+ * $Id: pmc551.c,v 1.17 2001/05/22 13:56:46 dwmw2 Exp $
+ *
+ * PMC551 PCI Mezzanine Ram Device
+ *
+ * Author:
+ *       Mark Ferrell <mferrell@mvista.com>
+ *       Copyright 1999,2000 Nortel Networks
+ *
+ * License:
+ *	 As part of this driver was derived from the slram.c driver it
+ *	 falls under the same license, which is GNU General Public
+ *	 License v2
+ *
+ * Description:
+ *	 This driver is intended to support the PMC551 PCI Ram device
+ *	 from Ramix Inc.  The PMC551 is a PMC Mezzanine module for
+ *	 cPCI embedded systems.  The device contains a single SROM
+ *	 that initially programs the V370PDC chipset onboard the
+ *	 device, and various banks of DRAM/SDRAM onboard.  This driver
+ *	 implements this PCI Ram device as an MTD (Memory Technology
+ *	 Device) so that it can be used to hold a file system, or for
+ *	 added swap space in embedded systems.  Since the memory on
+ *	 this board isn't as fast as main memory we do not try to hook
+ *	 it into main memory as that would simply reduce performance
+ *	 on the system.  Using it as a block device allows us to use
+ *	 it as high speed swap or for a high speed disk device of some
+ *	 sort.  Which becomes very useful on diskless systems in the
+ *	 embedded market I might add.
+ *	 
+ * Notes:
+ *	 Due to what I assume is more buggy SROM, the 64M PMC551 I
+ *	 have available claims that all 4 of it's DRAM banks have 64M
+ *	 of ram configured (making a grand total of 256M onboard).
+ *	 This is slightly annoying since the BAR0 size reflects the
+ *	 aperture size, not the dram size, and the V370PDC supplies no
+ *	 other method for memory size discovery.  This problem is
+ *	 mostly only relevant when compiled as a module, as the
+ *	 unloading of the module with an aperture size smaller then
+ *	 the ram will cause the driver to detect the onboard memory
+ *	 size to be equal to the aperture size when the module is
+ *	 reloaded.  Soooo, to help, the module supports an msize
+ *	 option to allow the specification of the onboard memory, and
+ *	 an asize option, to allow the specification of the aperture
+ *	 size.  The aperture must be equal to or less then the memory
+ *	 size, the driver will correct this if you screw it up.  This
+ *	 problem is not relevant for compiled in drivers as compiled
+ *	 in drivers only init once.
+ *
+ * Credits:
+ *       Saeed Karamooz <saeed@ramix.com> of Ramix INC. for the
+ *       initial example code of how to initialize this device and for
+ *       help with questions I had concerning operation of the device.
+ *
+ *       Most of the MTD code for this driver was originally written
+ *       for the slram.o module in the MTD drivers package which
+ *       allows the mapping of system memory into an MTD device.
+ *       Since the PMC551 memory module is accessed in the same
+ *       fashion as system memory, the slram.c code became a very nice
+ *       fit to the needs of this driver.  All we added was PCI
+ *       detection/initialization to the driver and automatically figure
+ *       out the size via the PCI detection.o, later changes by Corey
+ *       Minyard set up the card to utilize a 1M sliding apature.
+ *
+ *	 Corey Minyard <minyard@nortelnetworks.com>
+ *       * Modified driver to utilize a sliding aperture instead of 
+ *         mapping all memory into kernel space which turned out to
+ *         be very wasteful.
+ *       * Located a bug in the SROM's initialization sequence that 
+ *         made the memory unusable, added a fix to code to touch up
+ *         the DRAM some.
+ *
+ * Bugs/FIXME's:
+ *       * MUST fix the init function to not spin on a register
+ *       waiting for it to set .. this does not safely handle busted
+ *       devices that never reset the register correctly which will
+ *       cause the system to hang w/ a reboot being the only chance at
+ *       recover.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <linux/ioctl.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <stdarg.h>
+#include <linux/pci.h>
+
+#ifndef CONFIG_PCI
+#error Enable PCI in your kernel config
+#endif
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/pmc551.h>
+#include <linux/mtd/compatmac.h>
+
+#if LINUX_VERSION_CODE > 0x20300
+#define PCI_BASE_ADDRESS(dev) (dev->resource[0].start)
+#else
+#define PCI_BASE_ADDRESS(dev) (dev->base_address[0])
+#endif
+
+static struct mtd_info *pmc551list;
+
+static int pmc551_erase (struct mtd_info *mtd, struct erase_info *instr)
+{
+        struct mypriv *priv = mtd->priv;
+        u32 start_addr_highbits;
+        u32 end_addr_highbits;
+        u32 start_addr_lowbits;
+        u32 end_addr_lowbits;
+        unsigned long end;
+
+        end = instr->addr + instr->len;
+
+        /* Is it too much memory?  The second check find if we wrap around
+           past the end of a u32. */
+        if ((end > mtd->size) || (end < instr->addr)) {
+                return -EINVAL;
+        }
+
+        start_addr_highbits = instr->addr & PMC551_ADDR_HIGH_MASK;
+        end_addr_highbits = end & PMC551_ADDR_HIGH_MASK;
+        start_addr_lowbits = instr->addr & PMC551_ADDR_LOW_MASK;
+        end_addr_lowbits = end & PMC551_ADDR_LOW_MASK;
+
+        pci_write_config_dword ( priv->dev,
+                                 PMC551_PCI_MEM_MAP0,
+                                 (priv->mem_map0_base_val
+                                  | start_addr_highbits));
+        if (start_addr_highbits == end_addr_highbits) {
+                /* The whole thing fits within one access, so just one shot
+                   will do it. */
+                memset(priv->start + start_addr_lowbits,
+                       0xff,
+                       instr->len);
+        } else {
+                /* We have to do multiple writes to get all the data
+                   written. */
+                memset(priv->start + start_addr_lowbits,
+                       0xff,
+                       priv->aperture_size - start_addr_lowbits);
+                start_addr_highbits += priv->aperture_size;
+                while (start_addr_highbits != end_addr_highbits) {
+                        pci_write_config_dword ( priv->dev,
+                                                 PMC551_PCI_MEM_MAP0,
+                                                 (priv->mem_map0_base_val
+                                                  | start_addr_highbits));
+                        memset(priv->start,
+                               0xff,
+                               priv->aperture_size);
+                        start_addr_highbits += priv->aperture_size;
+                }
+                priv->curr_mem_map0_val = (priv->mem_map0_base_val
+                                           | start_addr_highbits);
+                pci_write_config_dword ( priv->dev,
+                                         PMC551_PCI_MEM_MAP0,
+                                         priv->curr_mem_map0_val);
+                memset(priv->start,
+                       0xff,
+                       end_addr_lowbits);
+        }
+
+	instr->state = MTD_ERASE_DONE;
+
+        if (instr->callback) {
+                (*(instr->callback))(instr);
+	}
+
+        return 0;
+}
+
+
+static void pmc551_unpoint (struct mtd_info *mtd, u_char *addr)
+{}
+
+
+static int pmc551_read (struct mtd_info *mtd,
+                        loff_t from,
+                        size_t len,
+                        size_t *retlen,
+                        u_char *buf)
+{
+        struct mypriv *priv = (struct mypriv *)mtd->priv;
+        u32 start_addr_highbits;
+        u32 end_addr_highbits;
+        u32 start_addr_lowbits;
+        u32 end_addr_lowbits;
+        unsigned long end;
+        u_char *copyto = buf;
+
+
+        /* Is it past the end? */
+        if (from > mtd->size) {
+                return -EINVAL;
+        }
+
+        end = from + len;
+        start_addr_highbits = from & PMC551_ADDR_HIGH_MASK;
+        end_addr_highbits = end & PMC551_ADDR_HIGH_MASK;
+        start_addr_lowbits = from & PMC551_ADDR_LOW_MASK;
+        end_addr_lowbits = end & PMC551_ADDR_LOW_MASK;
+
+
+        /* Only rewrite the first value if it doesn't match our current
+           values.  Most operations are on the same page as the previous
+           value, so this is a pretty good optimization. */
+        if (priv->curr_mem_map0_val !=
+                        (priv->mem_map0_base_val | start_addr_highbits)) {
+                priv->curr_mem_map0_val = (priv->mem_map0_base_val
+                                           | start_addr_highbits);
+                pci_write_config_dword ( priv->dev,
+                                         PMC551_PCI_MEM_MAP0,
+                                         priv->curr_mem_map0_val);
+        }
+
+        if (start_addr_highbits == end_addr_highbits) {
+                /* The whole thing fits within one access, so just one shot
+                   will do it. */
+                memcpy(copyto,
+                       priv->start + start_addr_lowbits,
+                       len);
+                copyto += len;
+        } else {
+                /* We have to do multiple writes to get all the data
+                   written. */
+                memcpy(copyto,
+                       priv->start + start_addr_lowbits,
+                       priv->aperture_size - start_addr_lowbits);
+                copyto += priv->aperture_size - start_addr_lowbits;
+                start_addr_highbits += priv->aperture_size;
+                while (start_addr_highbits != end_addr_highbits) {
+                        pci_write_config_dword ( priv->dev,
+                                                 PMC551_PCI_MEM_MAP0,
+                                                 (priv->mem_map0_base_val
+                                                  | start_addr_highbits));
+                        memcpy(copyto,
+                               priv->start,
+                               priv->aperture_size);
+                        copyto += priv->aperture_size;
+                        start_addr_highbits += priv->aperture_size;
+                        if (start_addr_highbits >= mtd->size) {
+                                /* Make sure we have the right value here. */
+                                priv->curr_mem_map0_val
+                                = (priv->mem_map0_base_val
+                                   | start_addr_highbits);
+                                goto out;
+                        }
+                }
+                priv->curr_mem_map0_val = (priv->mem_map0_base_val
+                                           | start_addr_highbits);
+                pci_write_config_dword ( priv->dev,
+                                         PMC551_PCI_MEM_MAP0,
+                                         priv->curr_mem_map0_val);
+                memcpy(copyto,
+                       priv->start,
+                       end_addr_lowbits);
+                copyto += end_addr_lowbits;
+        }
+
+out:
+        *retlen = copyto - buf;
+        return 0;
+}
+
+static int pmc551_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
+{
+        struct mypriv *priv = (struct mypriv *)mtd->priv;
+        u32 start_addr_highbits;
+        u32 end_addr_highbits;
+        u32 start_addr_lowbits;
+        u32 end_addr_lowbits;
+        unsigned long end;
+        const u_char *copyfrom = buf;
+
+
+        /* Is it past the end? */
+        if (to > mtd->size) {
+                return -EINVAL;
+        }
+
+        end = to + len;
+        start_addr_highbits = to & PMC551_ADDR_HIGH_MASK;
+        end_addr_highbits = end & PMC551_ADDR_HIGH_MASK;
+        start_addr_lowbits = to & PMC551_ADDR_LOW_MASK;
+        end_addr_lowbits = end & PMC551_ADDR_LOW_MASK;
+
+
+        /* Only rewrite the first value if it doesn't match our current
+           values.  Most operations are on the same page as the previous
+           value, so this is a pretty good optimization. */
+        if (priv->curr_mem_map0_val !=
+                        (priv->mem_map0_base_val | start_addr_highbits)) {
+                priv->curr_mem_map0_val = (priv->mem_map0_base_val
+                                           | start_addr_highbits);
+                pci_write_config_dword ( priv->dev,
+                                         PMC551_PCI_MEM_MAP0,
+                                         priv->curr_mem_map0_val);
+        }
+
+        if (start_addr_highbits == end_addr_highbits) {
+                /* The whole thing fits within one access, so just one shot
+                   will do it. */
+                memcpy(priv->start + start_addr_lowbits,
+                       copyfrom,
+                       len);
+                copyfrom += len;
+        } else {
+                /* We have to do multiple writes to get all the data
+                   written. */
+                memcpy(priv->start + start_addr_lowbits,
+                       copyfrom,
+                       priv->aperture_size - start_addr_lowbits);
+                copyfrom += priv->aperture_size - start_addr_lowbits;
+                start_addr_highbits += priv->aperture_size;
+                while (start_addr_highbits != end_addr_highbits) {
+                        pci_write_config_dword ( priv->dev,
+                                                 PMC551_PCI_MEM_MAP0,
+                                                 (priv->mem_map0_base_val
+                                                  | start_addr_highbits));
+                        memcpy(priv->start,
+                               copyfrom,
+                               priv->aperture_size);
+                        copyfrom += priv->aperture_size;
+                        start_addr_highbits += priv->aperture_size;
+                        if (start_addr_highbits >= mtd->size) {
+                                /* Make sure we have the right value here. */
+                                priv->curr_mem_map0_val
+                                = (priv->mem_map0_base_val
+                                   | start_addr_highbits);
+                                goto out;
+                        }
+                }
+                priv->curr_mem_map0_val = (priv->mem_map0_base_val
+                                           | start_addr_highbits);
+                pci_write_config_dword ( priv->dev,
+                                         PMC551_PCI_MEM_MAP0,
+                                         priv->curr_mem_map0_val);
+                memcpy(priv->start,
+                       copyfrom,
+                       end_addr_lowbits);
+                copyfrom += end_addr_lowbits;
+        }
+
+out:
+        *retlen = copyfrom - buf;
+        return 0;
+}
+
+/*
+ * Fixup routines for the V370PDC
+ * PCI device ID 0x020011b0
+ *
+ * This function basicly kick starts the DRAM oboard the card and gets it
+ * ready to be used.  Before this is done the device reads VERY erratic, so
+ * much that it can crash the Linux 2.2.x series kernels when a user cat's
+ * /proc/pci .. though that is mainly a kernel bug in handling the PCI DEVSEL
+ * register.  FIXME: stop spinning on registers .. must implement a timeout
+ * mechanism
+ * returns the size of the memory region found.
+ */
+static u32 fixup_pmc551 (struct pci_dev *dev)
+{
+#ifdef CONFIG_MTD_PMC551_BUGFIX
+        u32 dram_data;
+#endif
+        u32 size, dcmd, cfg, dtmp;
+        u16 cmd, tmp, i;
+	u8 bcmd, counter;
+
+        /* Sanity Check */
+        if(!dev) {
+                return -ENODEV;
+        }
+
+	/*
+	 * Attempt to reset the card
+	 * FIXME: Stop Spinning registers
+	 */
+	counter=0;
+	/* unlock registers */
+	pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, 0xA5 );
+	/* read in old data */
+	pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd );
+	/* bang the reset line up and down for a few */
+	for(i=0;i<10;i++) {
+		counter=0;
+		bcmd &= ~0x80;
+		while(counter++ < 100) {
+			pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd);
+		}
+		counter=0;
+		bcmd |= 0x80;
+		while(counter++ < 100) {
+			pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd);
+		}
+	}
+	bcmd |= (0x40|0x20);
+	pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd);
+
+        /* 
+	 * Take care and turn off the memory on the device while we
+	 * tweak the configurations
+	 */
+        pci_read_config_word(dev, PCI_COMMAND, &cmd);
+        tmp = cmd & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY);
+        pci_write_config_word(dev, PCI_COMMAND, tmp);
+
+	/*
+	 * Disable existing aperture before probing memory size
+	 */
+	pci_read_config_dword(dev, PMC551_PCI_MEM_MAP0, &dcmd);
+        dtmp=(dcmd|PMC551_PCI_MEM_MAP_ENABLE|PMC551_PCI_MEM_MAP_REG_EN);
+	pci_write_config_dword(dev, PMC551_PCI_MEM_MAP0, dtmp);
+	/*
+	 * Grab old BAR0 config so that we can figure out memory size
+	 * This is another bit of kludge going on.  The reason for the
+	 * redundancy is I am hoping to retain the original configuration
+	 * previously assigned to the card by the BIOS or some previous 
+	 * fixup routine in the kernel.  So we read the old config into cfg,
+	 * then write all 1's to the memory space, read back the result into
+	 * "size", and then write back all the old config.
+	 */
+	pci_read_config_dword( dev, PCI_BASE_ADDRESS_0, &cfg );
+#ifndef CONFIG_MTD_PMC551_BUGFIX
+	pci_write_config_dword( dev, PCI_BASE_ADDRESS_0, ~0 );
+	pci_read_config_dword( dev, PCI_BASE_ADDRESS_0, &size );
+	pci_write_config_dword( dev, PCI_BASE_ADDRESS_0, cfg );
+	size=~(size&PCI_BASE_ADDRESS_MEM_MASK)+1;
+#else
+        /*
+         * Get the size of the memory by reading all the DRAM size values
+         * and adding them up.
+         *
+         * KLUDGE ALERT: the boards we are using have invalid column and
+         * row mux values.  We fix them here, but this will break other
+         * memory configurations.
+         */
+        pci_read_config_dword(dev, PMC551_DRAM_BLK0, &dram_data);
+        size = PMC551_DRAM_BLK_GET_SIZE(dram_data);
+        dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
+        dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
+        pci_write_config_dword(dev, PMC551_DRAM_BLK0, dram_data);
+
+        pci_read_config_dword(dev, PMC551_DRAM_BLK1, &dram_data);
+        size += PMC551_DRAM_BLK_GET_SIZE(dram_data);
+        dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
+        dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
+        pci_write_config_dword(dev, PMC551_DRAM_BLK1, dram_data);
+
+        pci_read_config_dword(dev, PMC551_DRAM_BLK2, &dram_data);
+        size += PMC551_DRAM_BLK_GET_SIZE(dram_data);
+        dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
+        dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
+        pci_write_config_dword(dev, PMC551_DRAM_BLK2, dram_data);
+
+        pci_read_config_dword(dev, PMC551_DRAM_BLK3, &dram_data);
+        size += PMC551_DRAM_BLK_GET_SIZE(dram_data);
+        dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
+        dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
+        pci_write_config_dword(dev, PMC551_DRAM_BLK3, dram_data);
+
+        /*
+         * Oops .. something went wrong
+         */
+        if( (size &= PCI_BASE_ADDRESS_MEM_MASK) == 0) {
+                return -ENODEV;
+        }
+#endif /* CONFIG_MTD_PMC551_BUGFIX */
+
+	if ((cfg&PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY) {
+                return -ENODEV;
+	}
+
+        /*
+         * Precharge Dram
+         */
+        pci_write_config_word( dev, PMC551_SDRAM_MA, 0x0400 );
+        pci_write_config_word( dev, PMC551_SDRAM_CMD, 0x00bf );
+
+        /*
+         * Wait until command has gone through
+         * FIXME: register spinning issue
+         */
+        do {	pci_read_config_word( dev, PMC551_SDRAM_CMD, &cmd );
+		if(counter++ > 100)break;
+        } while ( (PCI_COMMAND_IO) & cmd );
+
+        /*
+	 * Turn on auto refresh 
+	 * The loop is taken directly from Ramix's example code.  I assume that
+	 * this must be held high for some duration of time, but I can find no
+	 * documentation refrencing the reasons why.
+	 * 
+         */
+        for ( i = 1; i<=8 ; i++) {
+                pci_write_config_word (dev, PMC551_SDRAM_CMD, 0x0df);
+
+                /*
+                 * Make certain command has gone through
+                 * FIXME: register spinning issue
+                 */
+		counter=0;
+                do {	pci_read_config_word(dev, PMC551_SDRAM_CMD, &cmd);
+			if(counter++ > 100)break;
+                } while ( (PCI_COMMAND_IO) & cmd );
+        }
+
+        pci_write_config_word ( dev, PMC551_SDRAM_MA, 0x0020);
+        pci_write_config_word ( dev, PMC551_SDRAM_CMD, 0x0ff);
+
+        /*
+         * Wait until command completes
+         * FIXME: register spinning issue
+         */
+	counter=0;
+        do {	pci_read_config_word ( dev, PMC551_SDRAM_CMD, &cmd);
+		if(counter++ > 100)break;
+        } while ( (PCI_COMMAND_IO) & cmd );
+
+        pci_read_config_dword ( dev, PMC551_DRAM_CFG, &dcmd);
+        dcmd |= 0x02000000;
+        pci_write_config_dword ( dev, PMC551_DRAM_CFG, dcmd);
+
+        /*
+         * Check to make certain fast back-to-back, if not
+         * then set it so
+         */
+        pci_read_config_word( dev, PCI_STATUS, &cmd);
+        if((cmd&PCI_COMMAND_FAST_BACK) == 0) {
+                cmd |= PCI_COMMAND_FAST_BACK;
+                pci_write_config_word( dev, PCI_STATUS, cmd);
+        }
+
+        /*
+         * Check to make certain the DEVSEL is set correctly, this device
+         * has a tendancy to assert DEVSEL and TRDY when a write is performed
+         * to the memory when memory is read-only
+         */
+        if((cmd&PCI_STATUS_DEVSEL_MASK) != 0x0) {
+                cmd &= ~PCI_STATUS_DEVSEL_MASK;
+                pci_write_config_word( dev, PCI_STATUS, cmd );
+        }
+        /*
+         * Set to be prefetchable and put everything back based on old cfg.
+	 * it's possible that the reset of the V370PDC nuked the original
+	 * setup
+         */
+        cfg |= PCI_BASE_ADDRESS_MEM_PREFETCH;
+	pci_write_config_dword( dev, PCI_BASE_ADDRESS_0, cfg );
+
+        /*
+         * Turn PCI memory and I/O bus access back on
+         */
+        pci_write_config_word( dev, PCI_COMMAND,
+                               PCI_COMMAND_MEMORY | PCI_COMMAND_IO );
+#ifdef CONFIG_MTD_PMC551_DEBUG
+        /*
+         * Some screen fun
+         */
+        printk(KERN_DEBUG "pmc551: %d%c (0x%x) of %sprefetchable memory at 0x%lx\n",
+	       (size<1024)?size:(size<1048576)?size/1024:size/1024/1024,
+               (size<1024)?'B':(size<1048576)?'K':'M',
+	       size, ((dcmd&(0x1<<3)) == 0)?"non-":"",
+               PCI_BASE_ADDRESS(dev)&PCI_BASE_ADDRESS_MEM_MASK );
+
+        /*
+         * Check to see the state of the memory
+         */
+        pci_read_config_dword( dev, PMC551_DRAM_BLK0, &dcmd );
+        printk(KERN_DEBUG "pmc551: DRAM_BLK0 Flags: %s,%s\n"
+			  "pmc551: DRAM_BLK0 Size: %d at %d\n"
+			  "pmc551: DRAM_BLK0 Row MUX: %d, Col MUX: %d\n",
+               (((0x1<<1)&dcmd) == 0)?"RW":"RO",
+               (((0x1<<0)&dcmd) == 0)?"Off":"On",
+	       PMC551_DRAM_BLK_GET_SIZE(dcmd),
+	       ((dcmd>>20)&0x7FF), ((dcmd>>13)&0x7), ((dcmd>>9)&0xF) );
+
+        pci_read_config_dword( dev, PMC551_DRAM_BLK1, &dcmd );
+        printk(KERN_DEBUG "pmc551: DRAM_BLK1 Flags: %s,%s\n"
+			  "pmc551: DRAM_BLK1 Size: %d at %d\n"
+			  "pmc551: DRAM_BLK1 Row MUX: %d, Col MUX: %d\n",
+               (((0x1<<1)&dcmd) == 0)?"RW":"RO",
+               (((0x1<<0)&dcmd) == 0)?"Off":"On",
+	       PMC551_DRAM_BLK_GET_SIZE(dcmd),
+	       ((dcmd>>20)&0x7FF), ((dcmd>>13)&0x7), ((dcmd>>9)&0xF) );
+
+        pci_read_config_dword( dev, PMC551_DRAM_BLK2, &dcmd );
+        printk(KERN_DEBUG "pmc551: DRAM_BLK2 Flags: %s,%s\n"
+			  "pmc551: DRAM_BLK2 Size: %d at %d\n"
+			  "pmc551: DRAM_BLK2 Row MUX: %d, Col MUX: %d\n",
+               (((0x1<<1)&dcmd) == 0)?"RW":"RO",
+               (((0x1<<0)&dcmd) == 0)?"Off":"On",
+	       PMC551_DRAM_BLK_GET_SIZE(dcmd),
+	       ((dcmd>>20)&0x7FF), ((dcmd>>13)&0x7), ((dcmd>>9)&0xF) );
+
+        pci_read_config_dword( dev, PMC551_DRAM_BLK3, &dcmd );
+        printk(KERN_DEBUG "pmc551: DRAM_BLK3 Flags: %s,%s\n"
+			  "pmc551: DRAM_BLK3 Size: %d at %d\n"
+			  "pmc551: DRAM_BLK3 Row MUX: %d, Col MUX: %d\n",
+               (((0x1<<1)&dcmd) == 0)?"RW":"RO",
+               (((0x1<<0)&dcmd) == 0)?"Off":"On",
+	       PMC551_DRAM_BLK_GET_SIZE(dcmd),
+	       ((dcmd>>20)&0x7FF), ((dcmd>>13)&0x7), ((dcmd>>9)&0xF) );
+
+        pci_read_config_word( dev, PCI_COMMAND, &cmd );
+        printk( KERN_DEBUG "pmc551: Memory Access %s\n",
+                (((0x1<<1)&cmd) == 0)?"off":"on" );
+        printk( KERN_DEBUG "pmc551: I/O Access %s\n",
+                (((0x1<<0)&cmd) == 0)?"off":"on" );
+
+        pci_read_config_word( dev, PCI_STATUS, &cmd );
+        printk( KERN_DEBUG "pmc551: Devsel %s\n",
+                ((PCI_STATUS_DEVSEL_MASK&cmd)==0x000)?"Fast":
+                ((PCI_STATUS_DEVSEL_MASK&cmd)==0x200)?"Medium":
+                ((PCI_STATUS_DEVSEL_MASK&cmd)==0x400)?"Slow":"Invalid" );
+
+        printk( KERN_DEBUG "pmc551: %sFast Back-to-Back\n",
+                ((PCI_COMMAND_FAST_BACK&cmd) == 0)?"Not ":"" );
+
+	pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd );
+	printk( KERN_DEBUG "pmc551: EEPROM is under %s control\n"
+			   "pmc551: System Control Register is %slocked to PCI access\n"
+			   "pmc551: System Control Register is %slocked to EEPROM access\n", 
+		(bcmd&0x1)?"software":"hardware",
+		(bcmd&0x20)?"":"un", (bcmd&0x40)?"":"un");
+#endif
+        return size;
+}
+
+/*
+ * Kernel version specific module stuffages
+ */
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_pmc551 init_module
+#define cleanup_pmc551 cleanup_module
+#endif
+
+#if defined(MODULE)
+MODULE_AUTHOR("Mark Ferrell <mferrell@mvista.com>");
+MODULE_DESCRIPTION(PMC551_VERSION);
+MODULE_PARM(msize, "i");
+MODULE_PARM_DESC(msize, "memory size, 6=32M, 7=64M, 8=128M, etc.. [32M-1024M]");
+MODULE_PARM(asize, "i");
+MODULE_PARM_DESC(asize, "aperture size, must be <= memsize [1M-1024M]");
+#endif
+/*
+ * Stuff these outside the ifdef so as to not bust compiled in driver support
+ */
+static int msize=0;
+#if defined(CONFIG_MTD_PMC551_APERTURE_SIZE)
+static int asize=CONFIG_MTD_PMC551_APERTURE_SIZE
+#else
+static int asize=0;
+#endif
+
+/*
+ * PMC551 Card Initialization
+ */
+int __init init_pmc551(void)
+{
+        struct pci_dev *PCI_Device = NULL;
+        struct mypriv *priv;
+        int count, found=0;
+        struct mtd_info *mtd;
+        u32 length = 0;
+
+	if(msize) {
+		if (msize < 6 || msize > 11 ) {
+			printk(KERN_NOTICE "pmc551: Invalid memory size\n");
+			return -ENODEV;
+		}
+		msize = (512*1024)<<msize;
+	}
+
+	if(asize) {
+		if (asize < 1 || asize > 11 ) {
+			printk(KERN_NOTICE "pmc551: Invalid aperture size\n");
+			return -ENODEV;
+		}
+		asize = (512*1024)<<asize;
+	}
+
+        printk(KERN_INFO PMC551_VERSION);
+
+        if(!pci_present()) {
+                printk(KERN_NOTICE "pmc551: PCI not enabled.\n");
+                return -ENODEV;
+        }
+
+        /*
+         * PCU-bus chipset probe.
+         */
+        for( count = 0; count < MAX_MTD_DEVICES; count++ ) {
+
+                if ( (PCI_Device = pci_find_device( PCI_VENDOR_ID_V3_SEMI,
+                                                    PCI_DEVICE_ID_V3_SEMI_V370PDC, PCI_Device ) ) == NULL) {
+                        break;
+                }
+
+                printk(KERN_NOTICE "pmc551: Found PCI V370PDC IRQ:%d\n",
+                       PCI_Device->irq);
+
+                /*
+                 * The PMC551 device acts VERY weird if you don't init it
+                 * first.  i.e. it will not correctly report devsel.  If for
+                 * some reason the sdram is in a wrote-protected state the
+                 * device will DEVSEL when it is written to causing problems
+                 * with the oldproc.c driver in
+                 * some kernels (2.2.*)
+                 */
+                if((length = fixup_pmc551(PCI_Device)) <= 0) {
+                        printk(KERN_NOTICE "pmc551: Cannot init SDRAM\n");
+                        break;
+                }
+		if(msize) {
+			length = msize;
+			printk(KERN_NOTICE "pmc551: Using specified memory size 0x%x\n", length);
+		}
+
+                mtd = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
+                if (!mtd) {
+                        printk(KERN_NOTICE "pmc551: Cannot allocate new MTD device.\n");
+                        break;
+                }
+
+                memset(mtd, 0, sizeof(struct mtd_info));
+
+                priv = kmalloc (sizeof(struct mypriv), GFP_KERNEL);
+                if (!priv) {
+                        printk(KERN_NOTICE "pmc551: Cannot allocate new MTD device.\n");
+                        kfree(mtd);
+                        break;
+                }
+                memset(priv, 0, sizeof(*priv));
+                mtd->priv = priv;
+
+                priv->dev = PCI_Device;
+		if(asize) {
+			if(asize > length) {
+				asize=length;
+				printk(KERN_NOTICE "pmc551: reducing aperture size to fit memory [0x%x]\n",asize);
+			} else {
+				printk(KERN_NOTICE "pmc551: Using specified aperture size 0x%x\n", asize);
+			}
+			priv->aperture_size = asize;
+		} else {
+                	priv->aperture_size = length;
+		}
+                priv->start = ioremap((PCI_BASE_ADDRESS(PCI_Device)
+                                       & PCI_BASE_ADDRESS_MEM_MASK),
+                                      priv->aperture_size);
+		
+		if (!priv->start) {
+                        kfree(mtd->priv);
+                        kfree(mtd);
+			break;
+		}
+		/*
+		 * Due to the dynamic nature of the code, we need to figure
+		 * this out in order to stuff the register to set the proper
+		 * aperture size.  If you know of an easier way to do this then
+		 * PLEASE help yourself.
+		 *
+		 * Not with bloody floating point, you don't. Consider yourself
+		 * duly LARTed. dwmw2.
+		 */
+		{
+			u32 size;
+			u16 bits;
+			size = priv->aperture_size>>20;
+			for(bits=0;!(size&0x01)&&size>0;bits++,size=size>>1);
+			//size=((u32)((log10(priv->aperture_size)/.30103)-19)<<4);
+                	priv->mem_map0_base_val = (PMC551_PCI_MEM_MAP_REG_EN
+						| PMC551_PCI_MEM_MAP_ENABLE
+						| size);
+#ifdef CONFIG_MTD_PMC551_DEBUG
+			printk(KERN_NOTICE "pmc551: aperture set to %d[%d]\n", 
+					size, size>>4);
+#endif
+		}
+                priv->curr_mem_map0_val = priv->mem_map0_base_val;
+
+                pci_write_config_dword ( priv->dev,
+                                         PMC551_PCI_MEM_MAP0,
+                                         priv->curr_mem_map0_val);
+
+                mtd->size 		= length;
+                mtd->flags 		= (MTD_CLEAR_BITS
+                                | MTD_SET_BITS
+                                | MTD_WRITEB_WRITEABLE
+                                | MTD_VOLATILE);
+                mtd->erase 		= pmc551_erase;
+                mtd->point 		= NULL;
+                mtd->unpoint 		= pmc551_unpoint;
+                mtd->read 		= pmc551_read;
+                mtd->write 		= pmc551_write;
+                mtd->module 		= THIS_MODULE;
+                mtd->type 		= MTD_RAM;
+                mtd->name 		= "PMC551 RAM board";
+                mtd->erasesize 		= 0x10000;
+
+                if (add_mtd_device(mtd)) {
+                        printk(KERN_NOTICE "pmc551: Failed to register new device\n");
+			iounmap(priv->start);
+                        kfree(mtd->priv);
+                        kfree(mtd);
+                        break;
+                }
+                printk(KERN_NOTICE "Registered pmc551 memory device.\n");
+                printk(KERN_NOTICE "Mapped %dM of memory from 0x%p to 0x%p\n",
+                       priv->aperture_size/1024/1024,
+                       priv->start,
+                       priv->start + priv->aperture_size);
+                printk(KERN_NOTICE "Total memory is %d%c\n",
+	       		(length<1024)?length:
+				(length<1048576)?length/1024:length/1024/1024,
+               		(length<1024)?'B':(length<1048576)?'K':'M');
+		priv->nextpmc551 = pmc551list;
+		pmc551list = mtd;
+		found++;
+        }
+
+        if( !pmc551list ) {
+                printk(KERN_NOTICE "pmc551: not detected,\n");
+                return -ENODEV;
+        } else {
+		printk(KERN_NOTICE "pmc551: %d pmc551 devices loaded\n", found);
+                return 0;
+	}
+}
+
+/*
+ * PMC551 Card Cleanup
+ */
+static void __exit cleanup_pmc551(void)
+{
+        int found=0;
+        struct mtd_info *mtd;
+	struct mypriv *priv;
+
+	while((mtd=pmc551list)) {
+		priv = (struct mypriv *)mtd->priv;
+		pmc551list = priv->nextpmc551;
+		
+		if(priv->start)
+			iounmap(priv->start);
+		
+		kfree (mtd->priv);
+		del_mtd_device(mtd);
+		kfree(mtd);
+		found++;
+	}
+
+	printk(KERN_NOTICE "pmc551: %d pmc551 devices unloaded\n", found);
+}
+
+module_init(init_pmc551);
+module_exit(cleanup_pmc551);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/devices/slram.c linux/drivers/mtd/devices/slram.c
--- v2.4.5/linux/drivers/mtd/devices/slram.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/devices/slram.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,341 @@
+/*======================================================================
+
+  $Id: slram.c,v 1.19 2001/06/02 20:33:20 dwmw2 Exp $
+
+======================================================================*/
+
+
+#include <linux/module.h>
+#include <asm/uaccess.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <linux/ioctl.h>
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <stdarg.h>
+
+#include <linux/mtd/mtd.h>
+
+#define SLRAM_MAX_DEVICES_PARAMS 6		/* 3 parameters / device */
+
+#define T(fmt, args...) printk(KERN_DEBUG fmt, ## args)
+#define E(fmt, args...) printk(KERN_NOTICE fmt, ## args)
+
+typedef struct slram_priv {
+	u_char *start;
+	u_char *end;
+} slram_priv_t;
+
+typedef struct slram_mtd_list {
+	struct mtd_info *mtdinfo;
+	struct slram_mtd_list *next;
+} slram_mtd_list_t;
+
+#ifdef MODULE
+static char *map[SLRAM_MAX_DEVICES_PARAMS];
+#else
+static char *map;
+#endif
+
+#ifdef MODULE
+#if LINUX_VERSION_CODE < 0x20212
+#define init_slram init_module
+#define cleanup_slram cleanup_module
+#endif
+
+MODULE_PARM(map, "3-" __MODULE_STRING(SLRAM_MAX_DEVICES_PARAMS) "s");
+MODULE_PARM_DESC(map, "List of memory regions to map. \"map=<name>, <start>, <length / end>\"");
+#endif
+
+static slram_mtd_list_t *slram_mtdlist = NULL;
+
+int slram_erase(struct mtd_info *, struct erase_info *);
+int slram_point(struct mtd_info *, loff_t, size_t, size_t *, u_char **);
+void slram_unpoint(struct mtd_info *, u_char *);
+int slram_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);
+int slram_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
+
+int slram_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+	slram_priv_t *priv = mtd->priv;
+
+	if (instr->addr + instr->len > mtd->size) {
+		return(-EINVAL);
+	}
+	
+	memset(priv->start + instr->addr, 0xff, instr->len);
+
+	/* This'll catch a few races. Free the thing before returning :) 
+	 * I don't feel at all ashamed. This kind of thing is possible anyway
+	 * with flash, but unlikely.
+	 */
+
+	instr->state = MTD_ERASE_DONE;
+
+	if (instr->callback) {
+		(*(instr->callback))(instr);
+	}
+	else {
+		kfree(instr);
+	}
+
+	return(0);
+}
+
+int slram_point(struct mtd_info *mtd, loff_t from, size_t len,
+		size_t *retlen, u_char **mtdbuf)
+{
+	slram_priv_t *priv = (slram_priv_t *)mtd->priv;
+
+	*mtdbuf = priv->start + from;
+	*retlen = len;
+	return(0);
+}
+
+void slram_unpoint(struct mtd_info *mtd, u_char *addr)
+{
+}
+
+int slram_read(struct mtd_info *mtd, loff_t from, size_t len,
+		size_t *retlen, u_char *buf)
+{
+	slram_priv_t *priv = (slram_priv_t *)mtd->priv;
+	
+	memcpy(buf, priv->start + from, len);
+
+	*retlen = len;
+	return(0);
+}
+
+int slram_write(struct mtd_info *mtd, loff_t to, size_t len,
+		size_t *retlen, const u_char *buf)
+{
+	slram_priv_t *priv = (slram_priv_t *)mtd->priv;
+
+	memcpy(priv->start + to, buf, len);
+
+	*retlen = len;
+	return(0);
+}
+
+/*====================================================================*/
+
+int register_device(char *name, long start, long length)
+{
+	slram_mtd_list_t **curmtd;
+
+	curmtd = &slram_mtdlist;
+	while (*curmtd) {
+		curmtd = &(*curmtd)->next;
+	}
+
+	*curmtd = kmalloc(sizeof(slram_mtd_list_t), GFP_KERNEL);
+	if (!curmtd) {
+		E("slram: Cannot allocate new MTD device.\n");
+		return(-ENOMEM);
+	}
+	(*curmtd)->mtdinfo = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
+	(*curmtd)->next = NULL;
+	
+	if ((*curmtd)->mtdinfo)	{
+		memset((char *)(*curmtd)->mtdinfo, 0, sizeof(struct mtd_info));
+		(*curmtd)->mtdinfo->priv =
+			(void *)kmalloc(sizeof(slram_priv_t), GFP_KERNEL);
+		
+		if (!(*curmtd)->mtdinfo->priv) {
+			kfree((*curmtd)->mtdinfo);
+			(*curmtd)->mtdinfo = NULL;
+		} else {
+			memset((*curmtd)->mtdinfo->priv,0,sizeof(slram_priv_t));
+		}
+	}
+
+	if (!(*curmtd)->mtdinfo) {
+		E("slram: Cannot allocate new MTD device.\n");
+		return(-ENOMEM);
+	}
+	
+	if (!(((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start =
+				ioremap(start, length))) {
+		E("slram: ioremap failed\n");
+		return -EIO;
+	}
+	((slram_priv_t *)(*curmtd)->mtdinfo->priv)->end =
+		((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start + length;
+
+
+	(*curmtd)->mtdinfo->name = name;
+	(*curmtd)->mtdinfo->size = length;
+	(*curmtd)->mtdinfo->flags = MTD_CLEAR_BITS | MTD_SET_BITS |
+					MTD_WRITEB_WRITEABLE | MTD_VOLATILE;
+        (*curmtd)->mtdinfo->erase = slram_erase;
+	(*curmtd)->mtdinfo->point = slram_point;
+	(*curmtd)->mtdinfo->unpoint = slram_unpoint;
+	(*curmtd)->mtdinfo->read = slram_read;
+	(*curmtd)->mtdinfo->write = slram_write;
+	(*curmtd)->mtdinfo->module = THIS_MODULE;
+	(*curmtd)->mtdinfo->type = MTD_RAM;
+	(*curmtd)->mtdinfo->erasesize = 0x10000;
+
+	if (add_mtd_device((*curmtd)->mtdinfo))	{
+		E("slram: Failed to register new device\n");
+		iounmap(((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start);
+		kfree((*curmtd)->mtdinfo->priv);
+		kfree((*curmtd)->mtdinfo);
+		return(-EAGAIN);
+	}
+	T("slram: Registered device %s from %dKiB to %dKiB\n", name,
+			(int)(start / 1024), (int)((start + length) / 1024));
+	T("slram: Mapped from 0x%p to 0x%p\n",
+			((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start,
+			((slram_priv_t *)(*curmtd)->mtdinfo->priv)->end);
+	return(0);	
+}
+
+void unregister_devices(void)
+{
+	slram_mtd_list_t *nextitem;
+
+	while (slram_mtdlist) {
+		nextitem = slram_mtdlist->next;
+		del_mtd_device(slram_mtdlist->mtdinfo);
+		iounmap(((slram_priv_t *)slram_mtdlist->mtdinfo->priv)->start);
+		kfree(slram_mtdlist->mtdinfo->priv);
+		kfree(slram_mtdlist->mtdinfo);
+		kfree(slram_mtdlist);
+		slram_mtdlist = nextitem;
+	}
+}
+
+int handle_unit(long value, char *unit)
+{
+	if ((*unit == 'M') || (*unit == 'm')) {
+		return(value * 1024 * 1024);
+	} else if ((*unit == 'K') || (*unit == 'k')) {
+		return(value * 1024);
+	}
+	return(value);
+}
+
+int parse_cmdline(char *devname, char *szstart, char *szlength)
+{
+	char *buffer;
+	long devstart;
+	long devlength;
+	
+	if ((!devname) || (!szstart) || (!szlength)) {
+		unregister_devices();
+		return(-EINVAL);
+	}
+
+	devstart = simple_strtoul(szstart, &buffer, 0);
+	devstart = handle_unit(devstart, buffer);
+	
+	if (*(szlength) != '+') {
+		devlength = simple_strtoul(szlength, &buffer, 0);
+		devlength = handle_unit(devlength, buffer) - devstart;
+	} else {
+		devlength = simple_strtoul(szlength + 1, &buffer, 0);
+		devlength = handle_unit(devlength, buffer);
+	}
+	T("slram: devname=%s, devstart=%li, devlength=%li\n",
+			devname, devstart, devlength);
+	if ((devstart < 0) || (devlength < 0)) {
+		E("slram: Illegal start / length parameter.\n");
+		return(-EINVAL);
+	}
+	
+	if ((devstart = register_device(devname, devstart, devlength))){
+		unregister_devices();
+		return((int)devstart);
+	}
+	return(0);
+}
+
+#ifndef MODULE
+
+static int __init mtd_slram_setup(char *str)
+{
+	map = str;
+	return(1);
+}
+
+__setup("slram=", mtd_slram_setup);
+
+#endif
+
+int init_slram(void)
+{
+	char *devname;
+	int i;
+
+#ifndef MODULE
+	char *devstart;
+	char *devlength;
+
+	i = 0;
+
+	if (!map) {
+		E("slram: not enough parameters.\n");
+		return(-EINVAL);
+	}
+	while (map) {
+		devname = devstart = devlength = NULL;
+
+		if (!(devname = strsep(&map, ","))) {
+			E("slram: No devicename specified.\n");
+			break;
+		}
+		T("slram: devname = %s\n", devname);
+		if ((!map) || (!(devstart = strsep(&map, ",")))) {
+			E("slram: No devicestart specified.\n");
+		}
+		T("slram: devstart = %s\n", devstart);
+		if ((!map) || (!(devlength = strsep(&map, ",")))) {
+			E("slram: No devicelength / -end specified.\n");
+		}
+		T("slram: devlength = %s\n", devlength);
+		if (parse_cmdline(devname, devstart, devlength) != 0) {
+			return(-EINVAL);
+		}
+	}
+#else
+	int count;
+	
+	for (count = 0; (map[count]) && (count < SLRAM_MAX_DEVICES_PARAMS);
+			count++) {
+	}
+
+	if ((count % 3 != 0) || (count == 0)) {
+		E("slram: not enough parameters.\n");
+		return(-EINVAL);
+	}
+	for (i = 0; i < (count / 3); i++) {
+		devname = map[i * 3];
+
+		if (parse_cmdline(devname, map[i * 3 + 1], map[i * 3 + 2])!=0) {
+			return(-EINVAL);
+		}
+		
+	}
+#endif /* !MODULE */
+	
+	return(0);
+}
+
+static void __exit cleanup_slram(void)
+{
+	unregister_devices();
+}
+
+module_init(init_slram);
+module_exit(cleanup_slram);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/doc1000.c linux/drivers/mtd/doc1000.c
--- v2.4.5/linux/drivers/mtd/doc1000.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/doc1000.c	Wed Dec 31 16:00:00 1969
@@ -1,597 +0,0 @@
-/*======================================================================
-
-  $Id: doc1000.c,v 1.11 2000/11/24 13:43:16 dwmw2 Exp $
-
-======================================================================*/
-
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <asm/uaccess.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/major.h>
-#include <linux/fs.h>
-#include <linux/ioctl.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/segment.h>
-#include <stdarg.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/iflash.h>
-
-/* Parameters that can be set with 'insmod' */
-
-static u_long base              = 0xe0000;
-static int erase_timeout	= 10*HZ;	/* in ticks */
-static int retry_limit		= 4;		/* write retries */
-static u_long max_tries       	= 4096;		/* status polling */
-
-MODULE_PARM(base,"l");
-MODULE_PARM(erase_timeout, "i");
-MODULE_PARM(retry_limit, "i");
-MODULE_PARM(max_tries, "i");
-
-#define WINDOW_SIZE 0x2000
-#define WINDOW_MASK (WINDOW_SIZE - 1)
-#define PAGEREG_LO (WINDOW_SIZE)
-#define PAGEREG_HI (WINDOW_SIZE + 2)
-
-static struct mtd_info *mymtd;
-static struct timer_list flashcard_timer;
-
-#define MAX_CELLS		32
-#define MAX_FLASH_DEVICES       8
-
-/* A flash region is composed of one or more "cells", where we allow
-   simultaneous erases if they are in different cells */
-
-
-
-struct mypriv {
-	u_char *baseaddr;
-	u_short curpage;
-	u_char locked;
-	u_short numdevices;
-	u_char interleave;
-	struct erase_info *cur_erases;
-	wait_queue_head_t wq;
-	u_char devstat[MAX_FLASH_DEVICES];
-	u_long devshift;
-};
-
-
-static void flashcard_periodic(u_long data);
-static int flashcard_erase (struct mtd_info *mtd, struct erase_info *instr);
-static int flashcard_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
-static int flashcard_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
-static void flashcard_sync (struct mtd_info *mtd);
-
-static inline void resume_erase(volatile u_char *addr);
-static inline int suspend_erase(volatile u_char *addr);
-static inline int byte_write (volatile u_char *addr, u_char byte);
-static inline int word_write (volatile u_char *addr, __u16 word);
-static inline int check_write(volatile u_char *addr);
-static inline void block_erase (volatile u_char *addr);
-static inline int check_erase(volatile u_char *addr);
-
-#ifdef CONFIG_SMP
-#warning This is definitely not SMP safe. Lock the paging mechanism.
-#endif
-
-static u_char *pagein(struct mtd_info *mtd, u_long addr)
-{
-  struct mypriv *priv=mtd->priv;
-  u_short page = addr >> 13;
-
-  priv->baseaddr[PAGEREG_LO] = page & 0xff;
-  priv->baseaddr[PAGEREG_HI] = page >> 8;
-  priv->curpage = page;
-  
-  return &priv->baseaddr[addr & WINDOW_MASK];
-}
-
-
-void flashcard_sync (struct mtd_info *mtd)
-{
-	struct mypriv *priv=mtd->priv;
-
-	flashcard_periodic((u_long) mtd);
-	printk("sync...");
-	if (priv->cur_erases)
-		interruptible_sleep_on(&priv->wq);
-	printk("Done.\n");
-}
-
-int flashcard_erase (struct mtd_info *mtd, struct erase_info *instr)
-{
-	u_char *pageaddr;
-	struct mypriv *priv=mtd->priv;
-	struct erase_info **tmp=&priv->cur_erases;
-	
-	if (instr->len != mtd->erasesize)
-		return -EINVAL;
-	if (instr->addr + instr->len > mtd->size)
-		return -EINVAL;
-
-	pageaddr=pagein(mtd,instr->addr);
-	instr->mtd = mtd;
-	instr->dev = instr->addr >> priv->devshift;
-	instr->cell = (instr->addr - (instr->dev << priv->devshift)) / mtd->erasesize;
-	instr->next = NULL;
-	instr->state = MTD_ERASE_PENDING;
-	
-	while (*tmp)
-	{
-		tmp = &((*tmp) -> next);
-	}
-	
-	*tmp = instr;
-	flashcard_periodic((u_long)mtd);
-	return 0;
-}
-
-
-int flashcard_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
-{
- 	u_char *pageaddr=pagein(mtd,from);
-	struct mypriv *priv=mtd->priv;
-	u_char device = from >> priv->devshift;
-	u_char cell = (int) (from - (device << priv->devshift)) / mtd->erasesize;
-	int ret = 0, timeron = 0;
-
-	if ((from & WINDOW_MASK) + len <= WINDOW_SIZE)
-		*retlen = len;
-	else
-		*retlen = WINDOW_SIZE - (from & WINDOW_MASK);
-
-	if (priv->devstat[device])
-	{
-		
-		/* There is an erase in progress or pending for this device. Stop it */
-		timeron = del_timer(&flashcard_timer);
-		
-		if (priv->cur_erases && priv->cur_erases->cell == cell) 
-			
-		{
-			/* The erase is on the current cell. Just return all 0xff */ 
-			add_timer(&flashcard_timer);
-			
-			
-			printk("Cell %d currently erasing. Setting to all 0xff\n",cell);
-			memset(buf, 0xff, *retlen);
-			return 0;
-		}
-		if (priv->devstat[device] == MTD_ERASING)
-		{
-			ret = suspend_erase(pageaddr);
-			priv->devstat[device] = MTD_ERASE_SUSPEND;
-		       
-			if (ret) 
-			{
-				printk("flashcard: failed to suspend erase\n");
-				add_timer (&flashcard_timer);
-				return ret;
-			}
-		}
-
-	}
-
-	writew(IF_READ_ARRAY, (u_long)pageaddr & ~1);
-	
-	ret = 0;
-	memcpy (buf, pageaddr, *retlen);
-	
-	writew(IF_READ_CSR, (u_long)pageaddr & ~1);
-	
-	
-	if (priv->devstat[device] & MTD_ERASE_SUSPEND)
-	{
-		resume_erase(pageaddr);
-		priv->devstat[device]=MTD_ERASING;
-	}
-
-
-	if (timeron) add_timer (&flashcard_timer);
-		
-	return ret;
-}
-
-
-int flashcard_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
-{
-	struct mypriv *priv = (struct mypriv *)mtd->priv;
- 	u_char *endaddr, *startaddr;
-	register u_char *pageaddr;
-	u_char device = to >> priv->devshift;
-/*	jiffies_t oldj=jiffies;*/
-	int ret;
-
-	while (priv->devstat[device])
-	{
-		flashcard_sync(mtd);
-	}
-
-	if ((to & WINDOW_MASK) + len <= WINDOW_SIZE)
-		*retlen = len;
-	else
-		*retlen = WINDOW_SIZE - (to & WINDOW_MASK);
-	
-	pageaddr = pagein(mtd, to);
-	startaddr = (u_char *)((u_long) pageaddr & ~1);
-	endaddr = pageaddr+(*retlen);
-
-
-
-	/* Set up to read */
-	writew(IF_READ_CSR, startaddr);
-	
-	/* Make sure it's aligned by reading the first byte if necessary */
-	if (to & 1)
-	{
-		/* Unaligned access */
-
-		u_char cbuf;
-
-		cbuf = *buf;
-
-		if (!((u_long)pageaddr & 0xf))
-			schedule();
-			
-		ret = byte_write(pageaddr, cbuf);
-		if (ret) return ret;
-
-		pageaddr++; buf++;
-	}
-
-
-	for ( ; pageaddr + 1 < endaddr; buf += 2, pageaddr += 2)
-		{
-			/* if ((u_long)pageaddr & 0xf) schedule();*/
-			
-			ret = word_write(pageaddr, *(__u16 *)buf);
-			if (ret) 
-				return ret;
-		}
-	
-	if (pageaddr != endaddr)
-	{
-		/* One more byte to write at the end. */
-		u_char cbuf;
-
-		cbuf = *buf;
-
-		ret = byte_write(pageaddr, cbuf);
-
-		if (ret) return ret;
-	}
-
-	return check_write(startaddr);
-/*	printk("Time taken in flashcard_write: %lx jiffies\n",jiffies - oldj);*/
-}
-
-
-
-
-/*====================================================================*/
-
-static inline int byte_write (volatile u_char *addr, u_char byte)
-{
-	register u_char status;
- 	register u_short i = 0;
-  	
- 	do {
-		status = readb(addr);
-		if (status & CSR_WR_READY)
-		{
-			writeb(IF_WRITE & 0xff, addr);
-			writeb(byte, addr);
-			return 0;
-		}
-		i++;
-	} while(i < max_tries);
-
-		
-	printk(KERN_NOTICE "flashcard: byte_write timed out, status 0x%x\n",status);
-	return -EIO;
-}
-
-static inline int word_write (volatile u_char *addr, __u16 word)
-{
-	register u_short status;
-	register u_short i = 0;
-	
-	do {
-		status = readw(addr);
-		if ((status & CSR_WR_READY) == CSR_WR_READY)
-		{
-			writew(IF_WRITE, addr);
-			writew(word, addr);
-			return 0;
-		}
-		i++;
-	} while(i < max_tries);
-		
-	printk(KERN_NOTICE "flashcard: word_write timed out at %p, status 0x%x\n", addr, status);
-	return -EIO;
-}
-
-static inline void block_erase (volatile u_char *addr)
-{
-	writew(IF_BLOCK_ERASE, addr);
-	writew(IF_CONFIRM, addr);
-}
-
-
-static inline int check_erase(volatile u_char *addr)
-{
-	__u16 status;
-	
-/*	writew(IF_READ_CSR, addr);*/
-	status = readw(addr);
-	
-
-	if ((status & CSR_WR_READY) != CSR_WR_READY)
-		return -EBUSY;
-	
-	if (status & (CSR_ERA_ERR | CSR_VPP_LOW | CSR_WR_ERR)) 
-	{
-		printk(KERN_NOTICE "flashcard: erase failed, status 0x%x\n",
-		       status);
-		return -EIO;
-	}
-	
-	return 0;
-}
-
-static inline int suspend_erase(volatile u_char *addr)
-{
-	__u16 status;
-	u_long i = 0;
-	
-	writew(IF_ERASE_SUSPEND, addr);
-	writew(IF_READ_CSR, addr);
-	
-	do {
-		status = readw(addr);
-		if ((status & CSR_WR_READY) == CSR_WR_READY)
-			return 0;
-		i++;
-	} while(i < max_tries);
-
-	printk(KERN_NOTICE "flashcard: suspend_erase timed out, status 0x%x\n", status);
-	return -EIO;
-
-}
-
-static inline void resume_erase(volatile u_char *addr)
-{
-	__u16 status;
-	
-	writew(IF_READ_CSR, addr);
-	status = readw(addr);
-	
-	/* Only give resume signal if the erase is really suspended */
-	if (status & CSR_ERA_SUSPEND)
-		writew(IF_CONFIRM, addr);
-}
-
-static inline void reset_block(volatile u_char *addr)
-{
-	u_short i;
-	__u16 status;
-
-	writew(IF_CLEAR_CSR, addr);
-
-	for (i = 0; i < 100; i++) {
-		writew(IF_READ_CSR, addr);
-		status = readw(addr);
-		if (status != 0xffff) break;
-		udelay(1000);
-	}
-
-	writew(IF_READ_CSR, addr);
-}
-
-static inline int check_write(volatile u_char *addr)
-{
-	u_short status, i = 0;
-	
-	writew(IF_READ_CSR, addr);
-	
-	do {
-		status = readw(addr);
-		if (status & (CSR_WR_ERR | CSR_VPP_LOW))
-		{
-			printk(KERN_NOTICE "flashcard: write failure at %p, status 0x%x\n", addr, status);
-			reset_block(addr);
-			return -EIO;
-		}
-		if ((status & CSR_WR_READY) == CSR_WR_READY)
-			return 0;
-		i++;
-	} while (i < max_tries);
-
-	printk(KERN_NOTICE "flashcard: write timed out at %p, status 0x%x\n", addr, status);
-	return -EIO;
-}
-
-
-/*====================================================================*/
-
-
-
-static void flashcard_periodic(unsigned long data)
-{
-	register struct mtd_info *mtd = (struct mtd_info *)data;
-	register struct mypriv *priv = mtd->priv;
-	struct erase_info *erase = priv->cur_erases;
-	u_char *pageaddr;
-
-	del_timer (&flashcard_timer);
-
-	if (!erase)
-		return;
-
-	pageaddr = pagein(mtd, erase->addr);
-	
-	if (erase->state == MTD_ERASE_PENDING)
-	{
-		block_erase(pageaddr);
-		priv->devstat[erase->dev] = erase->state = MTD_ERASING;
-		erase->time = jiffies;
-		erase->retries = 0;
-	}
-	else if (erase->state == MTD_ERASING)
-	{
-		/* It's trying to erase. Check whether it's finished */
-
-		int ret = check_erase(pageaddr);
-
-		if (!ret)
-		{
-			/* It's finished OK */
-			priv->devstat[erase->dev] = 0;
-			priv->cur_erases = erase->next;
-			erase->state = MTD_ERASE_DONE;
-			if (erase->callback)
-				(*(erase->callback))(erase);
-			else
-				kfree(erase);
-		}
-		else if (ret == -EIO)
-		{
-			if (++erase->retries > retry_limit)
-			{
-				printk("Failed too many times. Giving up\n");
-				priv->cur_erases = erase->next;
-				priv->devstat[erase->dev] = 0;
-				erase->state = MTD_ERASE_FAILED;
-				if (erase->callback)
-					(*(erase->callback))(erase);
-				else
-					kfree(erase);
-			}
-			else
-				priv->devstat[erase->dev] = erase->state = MTD_ERASE_PENDING;
-		}
-		else if (erase->time + erase_timeout < jiffies)
-		{
-			printk("Flash erase timed out. The world is broken.\n");
-
-			/* Just ignore and hope it goes away. For a while, read ops will give the CSR
-			   and writes won't work. */
-
-			priv->cur_erases = erase->next;
-			priv->devstat[erase->dev] = 0;
-			erase->state = MTD_ERASE_FAILED;
-			if (erase->callback)
-					(*(erase->callback))(erase);
-				else
-					kfree(erase);
-		}
-	}
-
-	if (priv->cur_erases)
-	{
-		flashcard_timer.expires = jiffies + HZ;
-		add_timer (&flashcard_timer);
-	}
-	else 
-		wake_up_interruptible(&priv->wq);
-
-}
-
-#if defined (MODULE) && LINUX_VERSION_CODE < 0x20211
-#define init_doc1000 init_module
-#define cleanup_doc1000 cleanup_module
-#endif
-
-int __init init_doc1000(void)
-{
-	struct mypriv *priv;
-
-	if (!base)
-	{
-		printk(KERN_NOTICE "flashcard: No start address for memory device.\n");
-		return -EINVAL;
-	}
-
-	mymtd  = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
-
-	if (!mymtd)
-	{
-		printk(KERN_NOTICE "physmem: Cannot allocate memory for new MTD device.\n");
-		return -ENOMEM;
-	}
-
-	memset(mymtd,0,sizeof(struct mtd_info));
-
-	mymtd->priv = (void *) kmalloc (sizeof(struct mypriv), GFP_KERNEL);
-	if (!mymtd->priv)
-	  {
-	    kfree(mymtd);
-	    printk(KERN_NOTICE "physmem: Cannot allocate memory for new MTD device's private data.\n");
-	    return -ENOMEM;
-	  }
-	
-
-
-
-	priv=mymtd->priv;
-	init_waitqueue_head(&priv->wq);
-
-	memset (priv,0,sizeof(struct mypriv));
-
-	priv->baseaddr = phys_to_virt(base);
-	priv->numdevices = 4;
-	
-	mymtd->name = "M-Systems DiskOnChip 1000";
-
-	mymtd->size = 0x100000;
-	mymtd->flags = MTD_CLEAR_BITS | MTD_ERASEABLE;
-        mymtd->erase = flashcard_erase;
-	mymtd->point = NULL;
-	mymtd->unpoint = NULL;
-	mymtd->read = flashcard_read;
-	mymtd->write = flashcard_write;
-
-	mymtd->sync = flashcard_sync;
-	mymtd->erasesize = 0x10000;
-	//	mymtd->interleave = 2;
-	priv->devshift =  24;
-	mymtd->type = MTD_NORFLASH;
-	
-	if (add_mtd_device(mymtd))
-	{
-		printk(KERN_NOTICE "MTD device registration failed!\n");
-		kfree(mymtd->priv);
-		kfree(mymtd);
-		return -EAGAIN;
-	}
-	
-	init_timer(&flashcard_timer);
-	flashcard_timer.function = flashcard_periodic;
-	flashcard_timer.data = (u_long)mymtd;
-	return 0;
-}
-
-static void __init cleanup_doc1000(void)
-{
-	kfree (mymtd->priv);
-	del_mtd_device(mymtd);
-	kfree(mymtd);
-}
-
-#if LINUX_VERSION_CODE >= 0x20211
-module_init(init_doc1000);
-module_exit(cleanup_doc1000);
-#endif
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/doc2000.c linux/drivers/mtd/doc2000.c
--- v2.4.5/linux/drivers/mtd/doc2000.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/doc2000.c	Wed Dec 31 16:00:00 1969
@@ -1,1113 +0,0 @@
-
-/*
- * Linux driver for Disk-On-Chip 2000 and Millennium
- * (c) 1999 Machine Vision Holdings, Inc.
- * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
- *
- * $Id: doc2000.c,v 1.39 2000/12/01 17:34:29 dwmw2 Exp $
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/types.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ids.h>
-#include <linux/mtd/doc2000.h>
-
-#define DOC_SUPPORT_2000
-#define DOC_SUPPORT_MILLENNIUM
-
-#ifdef DOC_SUPPORT_2000
-#define DoC_is_2000(doc) (doc->ChipID == DOC_ChipID_Doc2k)
-#else
-#define DoC_is_2000(doc) (0)
-#endif
-
-#ifdef DOC_SUPPORT_MILLENNIUM
-#define DoC_is_Millennium(doc) (doc->ChipID == DOC_ChipID_DocMil)
-#else
-#define DoC_is_Millennium(doc) (0)
-#endif
-
-/* #define ECC_DEBUG */
-
-/* I have no idea why some DoC chips can not use memcpy_from|to_io().
- * This may be due to the different revisions of the ASIC controller built-in or
- * simplily a QA/Bug issue. Who knows ?? If you have trouble, please uncomment
- * this:
- #undef USE_MEMCPY
-*/
-
-static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
-		    size_t *retlen, u_char *buf);
-static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
-		     size_t *retlen, const u_char *buf);
-static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
-			size_t *retlen, u_char *buf, u_char *eccbuf);
-static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
-			 size_t *retlen, const u_char *buf, u_char *eccbuf);
-static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
-			size_t *retlen, u_char *buf);
-static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
-			 size_t *retlen, const u_char *buf);
-static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);
-
-static struct mtd_info *doc2klist = NULL;
-
-/* Perform the required delay cycles by reading from the appropriate register */
-static void DoC_Delay(struct DiskOnChip *doc, unsigned short cycles)
-{
-	volatile char dummy;
-	int i;
-	
-	for (i = 0; i < cycles; i++) {
-		if (DoC_is_Millennium(doc))
-			dummy = ReadDOC(doc->virtadr, NOP);
-		else
-			dummy = ReadDOC(doc->virtadr, DOCStatus);
-	}
-	
-}
-
-/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
-static int _DoC_WaitReady(struct DiskOnChip *doc)
-{
-	unsigned long docptr = doc->virtadr;
-	unsigned short c = 0xffff;
-
-	DEBUG(MTD_DEBUG_LEVEL3,
-	      "_DoC_WaitReady called for out-of-line wait\n");
-
-	/* Out-of-line routine to wait for chip response */
-	while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B) && --c)
-		;
-
-	if (c == 0)
-		DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
-
-	return (c == 0);
-}
-
-static inline int DoC_WaitReady(struct DiskOnChip *doc)
-{
-	unsigned long docptr = doc->virtadr;
-	/* This is inline, to optimise the common case, where it's ready instantly */
-	int ret = 0;
-
-	/* 4 read form NOP register should be issued in prior to the read from CDSNControl
-	   see Software Requirement 11.4 item 2. */
-	DoC_Delay(doc, 4);
-
-	if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
-		/* Call the out-of-line routine to wait */
-		ret = _DoC_WaitReady(doc);
-
-	/* issue 2 read from NOP register after reading from CDSNControl register
-	   see Software Requirement 11.4 item 2. */
-	DoC_Delay(doc, 2);
-
-	return ret;
-}
-
-/* DoC_Command: Send a flash command to the flash chip through the CDSN Slow IO register to
-   bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
-   required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
-
-static inline int DoC_Command(struct DiskOnChip *doc, unsigned char command,
-			      unsigned char xtraflags)
-{
-	unsigned long docptr = doc->virtadr;
-
-	if (DoC_is_2000(doc))
-		xtraflags |= CDSN_CTRL_FLASH_IO;
-
-	/* Assert the CLE (Command Latch Enable) line to the flash chip */
-	WriteDOC(xtraflags | CDSN_CTRL_CLE | CDSN_CTRL_CE, docptr, CDSNControl);
-	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */
-
-	if (DoC_is_Millennium(doc))
-		WriteDOC(command, docptr, CDSNSlowIO);
-
-	/* Send the command */
-	WriteDOC_(command, docptr, doc->ioreg);
-
-	/* Lower the CLE line */
-	WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl);
-	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */
-
-	/* Wait for the chip to respond - Software requirement 11.4.1 (extended for any command) */
-	return DoC_WaitReady(doc);
-}
-
-/* DoC_Address: Set the current address for the flash chip through the CDSN Slow IO register to
-   bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
-   required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
-
-static int DoC_Address(struct DiskOnChip *doc, int numbytes, unsigned long ofs,
-		       unsigned char xtraflags1, unsigned char xtraflags2)
-{
-	unsigned long docptr;
-	int i;
-
-	docptr = doc->virtadr;
-
-	if (DoC_is_2000(doc))
-		xtraflags1 |= CDSN_CTRL_FLASH_IO;
-
-	/* Assert the ALE (Address Latch Enable) line to the flash chip */
-	WriteDOC(xtraflags1 | CDSN_CTRL_ALE | CDSN_CTRL_CE, docptr, CDSNControl);
-
-	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */
-
-	/* Send the address */
-	/* Devices with 256-byte page are addressed as:
-	   Column (bits 0-7), Page (bits 8-15, 16-23, 24-31)
-	   * there is no device on the market with page256
-	   and more than 24 bits.
-	   Devices with 512-byte page are addressed as:
-	   Column (bits 0-7), Page (bits 9-16, 17-24, 25-31)
-	   * 25-31 is sent only if the chip support it.
-	   * bit 8 changes the read command to be sent
-	   (NAND_CMD_READ0 or NAND_CMD_READ1).
-	 */
-
-	if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE) {
-		if (DoC_is_Millennium(doc))
-			WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
-		WriteDOC_(ofs & 0xff, docptr, doc->ioreg);
-	}
-
-	if (doc->page256) {
-		ofs = ofs >> 8;
-	} else {
-		ofs = ofs >> 9;
-	}
-
-	if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) {
-		for (i = 0; i < doc->pageadrlen; i++, ofs = ofs >> 8) {
-			if (DoC_is_Millennium(doc))
-				WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
-			WriteDOC_(ofs & 0xff, docptr, doc->ioreg);
-		}
-	}
-
-	DoC_Delay(doc, 2);	/* Needed for some slow flash chips. mf. */
-	
-	/* FIXME: The SlowIO's for millennium could be replaced by 
-	   a single WritePipeTerm here. mf. */
-
-	/* Lower the ALE line */
-	WriteDOC(xtraflags1 | xtraflags2 | CDSN_CTRL_CE, docptr,
-		 CDSNControl);
-
-	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */
-
-	/* Wait for the chip to respond - Software requirement 11.4.1 */
-	return DoC_WaitReady(doc);
-}
-
-/* Read a buffer from DoC, taking care of Millennium odditys */
-static void DoC_ReadBuf(struct DiskOnChip *doc, u_char * buf, int len)
-{
-	int dummy;
-	int modulus = 0xffff;
-	unsigned long docptr;
-	int i;
-
-	docptr = doc->virtadr;
-
-	if (len <= 0)
-		return;
-
-	if (DoC_is_Millennium(doc)) {
-		/* Read the data via the internal pipeline through CDSN IO register,
-		   see Pipelined Read Operations 11.3 */
-		dummy = ReadDOC(docptr, ReadPipeInit);
-
-		/* Millennium should use the LastDataRead register - Pipeline Reads */
-		len--;
-
-		/* This is needed for correctly ECC calculation */
-		modulus = 0xff;
-	}
-
-	for (i = 0; i < len; i++)
-		buf[i] = ReadDOC_(docptr, doc->ioreg + (i & modulus));
-
-	if (DoC_is_Millennium(doc)) {
-		buf[i] = ReadDOC(docptr, LastDataRead);
-	}
-}
-
-/* Write a buffer to DoC, taking care of Millennium odditys */
-static void DoC_WriteBuf(struct DiskOnChip *doc, const u_char * buf, int len)
-{
-	unsigned long docptr;
-	int i;
-
-	docptr = doc->virtadr;
-
-	if (len <= 0)
-		return;
-
-	for (i = 0; i < len; i++)
-		WriteDOC_(buf[i], docptr, doc->ioreg + i);
-
-	if (DoC_is_Millennium(doc)) {
-		WriteDOC(0x00, docptr, WritePipeTerm);
-	}
-}
-
-
-/* DoC_SelectChip: Select a given flash chip within the current floor */
-
-static inline int DoC_SelectChip(struct DiskOnChip *doc, int chip)
-{
-	unsigned long docptr = doc->virtadr;
-
-	/* Software requirement 11.4.4 before writing DeviceSelect */
-	/* Deassert the CE line to eliminate glitches on the FCE# outputs */
-	WriteDOC(CDSN_CTRL_WP, docptr, CDSNControl);
-	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */
-
-	/* Select the individual flash chip requested */
-	WriteDOC(chip, docptr, CDSNDeviceSelect);
-	DoC_Delay(doc, 4);
-
-	/* Reassert the CE line */
-	WriteDOC(CDSN_CTRL_CE | CDSN_CTRL_FLASH_IO | CDSN_CTRL_WP, docptr,
-		 CDSNControl);
-	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */
-
-	/* Wait for it to be ready */
-	return DoC_WaitReady(doc);
-}
-
-/* DoC_SelectFloor: Select a given floor (bank of flash chips) */
-
-static inline int DoC_SelectFloor(struct DiskOnChip *doc, int floor)
-{
-	unsigned long docptr = doc->virtadr;
-
-	/* Select the floor (bank) of chips required */
-	WriteDOC(floor, docptr, FloorSelect);
-
-	/* Wait for the chip to be ready */
-	return DoC_WaitReady(doc);
-}
-
-/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
-
-static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
-{
-	int mfr, id, i;
-	volatile char dummy;
-
-	/* Page in the required floor/chip */
-	DoC_SelectFloor(doc, floor);
-	DoC_SelectChip(doc, chip);
-
-	/* Reset the chip */
-	if (DoC_Command(doc, NAND_CMD_RESET, CDSN_CTRL_WP)) {
-		DEBUG(MTD_DEBUG_LEVEL2,
-		      "DoC_Command (reset) for %d,%d returned true\n",
-		      floor, chip);
-		return 0;
-	}
-
-
-	/* Read the NAND chip ID: 1. Send ReadID command */
-	if (DoC_Command(doc, NAND_CMD_READID, CDSN_CTRL_WP)) {
-		DEBUG(MTD_DEBUG_LEVEL2,
-		      "DoC_Command (ReadID) for %d,%d returned true\n",
-		      floor, chip);
-		return 0;
-	}
-
-	/* Read the NAND chip ID: 2. Send address byte zero */
-	DoC_Address(doc, ADDR_COLUMN, 0, CDSN_CTRL_WP, 0);
-
-	/* Read the manufacturer and device id codes from the device */
-
-	/* CDSN Slow IO register see Software Requirement 11.4 item 5. */
-	dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
-	DoC_Delay(doc, 2);
-	mfr = ReadDOC_(doc->virtadr, doc->ioreg);
-
-	/* CDSN Slow IO register see Software Requirement 11.4 item 5. */
-	dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
-	DoC_Delay(doc, 2);
-	id = ReadDOC_(doc->virtadr, doc->ioreg);
-
-	/* No response - return failure */
-	if (mfr == 0xff || mfr == 0)
-		return 0;
-
-	/* Check it's the same as the first chip we identified. 
-	 * M-Systems say that any given DiskOnChip device should only
-	 * contain _one_ type of flash part, although that's not a 
-	 * hardware restriction. */
-	if (doc->mfr) {
-		if (doc->mfr == mfr && doc->id == id)
-			return 1;	/* This is another the same the first */
-		else
-			printk(KERN_WARNING
-			       "Flash chip at floor %d, chip %d is different:\n",
-			       floor, chip);
-	}
-
-	/* Print and store the manufacturer and ID codes. */
-	for (i = 0; nand_flash_ids[i].name != NULL; i++) {
-		if (mfr == nand_flash_ids[i].manufacture_id &&
-		    id == nand_flash_ids[i].model_id) {
-			printk(KERN_INFO
-			       "Flash chip found: Manufacturer ID: %2.2X, "
-			       "Chip ID: %2.2X (%s)\n", mfr, id,
-			       nand_flash_ids[i].name);
-			if (!doc->mfr) {
-				doc->mfr = mfr;
-				doc->id = id;
-				doc->chipshift =
-				    nand_flash_ids[i].chipshift;
-				doc->page256 = nand_flash_ids[i].page256;
-				doc->pageadrlen =
-				    nand_flash_ids[i].pageadrlen;
-				doc->erasesize =
-				    nand_flash_ids[i].erasesize;
-				return 1;
-			}
-			return 0;
-		}
-	}
-
-
-	/* We haven't fully identified the chip. Print as much as we know. */
-	printk(KERN_WARNING "Unknown flash chip found: %2.2X %2.2X\n",
-	       id, mfr);
-
-	printk(KERN_WARNING "Please report to dwmw2@infradead.org\n");
-	return 0;
-}
-
-/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
-
-static void DoC_ScanChips(struct DiskOnChip *this)
-{
-	int floor, chip;
-	int numchips[MAX_FLOORS];
-	int maxchips = MAX_CHIPS;
-	int ret = 1;
-
-	this->numchips = 0;
-	this->mfr = 0;
-	this->id = 0;
-
-	if (DoC_is_Millennium(this))
-		maxchips = MAX_CHIPS_MIL;
-
-	/* For each floor, find the number of valid chips it contains */
-	for (floor = 0; floor < MAX_FLOORS; floor++) {
-		ret = 1;
-		numchips[floor] = 0;
-		for (chip = 0; chip < maxchips && ret != 0; chip++) {
-
-			ret = DoC_IdentChip(this, floor, chip);
-			if (ret) {
-				numchips[floor]++;
-				this->numchips++;
-			}
-		}
-	}
-
-	/* If there are none at all that we recognise, bail */
-	if (!this->numchips) {
-		printk("No flash chips recognised.\n");
-		return;
-	}
-
-	/* Allocate an array to hold the information for each chip */
-	this->chips = kmalloc(sizeof(struct Nand) * this->numchips, GFP_KERNEL);
-	if (!this->chips) {
-		printk("No memory for allocating chip info structures\n");
-		return;
-	}
-
-	ret = 0;
-
-	/* Fill out the chip array with {floor, chipno} for each 
-	 * detected chip in the device. */
-	for (floor = 0; floor < MAX_FLOORS; floor++) {
-		for (chip = 0; chip < numchips[floor]; chip++) {
-			this->chips[ret].floor = floor;
-			this->chips[ret].chip = chip;
-			this->chips[ret].curadr = 0;
-			this->chips[ret].curmode = 0x50;
-			ret++;
-		}
-	}
-
-	/* Calculate and print the total size of the device */
-	this->totlen = this->numchips * (1 << this->chipshift);
-
-	printk(KERN_INFO
-	       "%d flash chips found. Total DiskOnChip size: %ld Mb\n",
-	       this->numchips, this->totlen >> 20);
-}
-
-
-static int DoC2k_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
-{
-	int tmp1, tmp2, retval;
-	if (doc1->physadr == doc2->physadr)
-		return 1;
-
-	/* Use the alias resolution register which was set aside for this
-	 * purpose. If it's value is the same on both chips, they might
-	 * be the same chip, and we write to one and check for a change in
-	 * the other. It's unclear if this register is usuable in the
-	 * DoC 2000 (it's in the Millennium docs), but it seems to work. */
-	tmp1 = ReadDOC(doc1->virtadr, AliasResolution);
-	tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
-	if (tmp1 != tmp2)
-		return 0;
-
-	WriteDOC((tmp1 + 1) % 0xff, doc1->virtadr, AliasResolution);
-	tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
-	if (tmp2 == (tmp1 + 1) % 0xff)
-		retval = 1;
-	else
-		retval = 0;
-
-	/* Restore register contents.  May not be necessary, but do it just to
-	 * be safe. */
-	WriteDOC(tmp1, doc1->virtadr, AliasResolution);
-
-	return retval;
-}
-
-static const char im_name[] = "DoC2k_init";
-
-/* This routine is made available to other mtd code via
- * inter_module_register.  It must only be accessed through
- * inter_module_get which will bump the use count of this module.  The
- * addresses passed back in mtd are valid as long as the use count of
- * this module is non-zero, i.e. between inter_module_get and
- * inter_module_put.  Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
- */
-static void DoC2k_init(struct mtd_info *mtd)
-{
-	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
-	struct DiskOnChip *old = NULL;
-
-	/* We must avoid being called twice for the same device. */
-
-	if (doc2klist)
-		old = (struct DiskOnChip *) doc2klist->priv;
-
-	while (old) {
-		if (DoC2k_is_alias(old, this)) {
-			printk(KERN_NOTICE
-			       "Ignoring DiskOnChip 2000 at 0x%lX - already configured\n",
-			       this->physadr);
-			iounmap((void *) this->virtadr);
-			kfree(mtd);
-			return;
-		}
-		if (old->nextdoc)
-			old = (struct DiskOnChip *) old->nextdoc->priv;
-		else
-			old = NULL;
-	}
-
-
-	switch (this->ChipID) {
-	case DOC_ChipID_Doc2k:
-		mtd->name = "DiskOnChip 2000";
-		this->ioreg = DoC_2k_CDSN_IO;
-		break;
-	case DOC_ChipID_DocMil:
-		mtd->name = "DiskOnChip Millennium";
-		this->ioreg = DoC_Mil_CDSN_IO;
-		break;
-	}
-
-	printk(KERN_NOTICE "%s found at address 0x%lX\n", mtd->name,
-	       this->physadr);
-
-	mtd->type = MTD_NANDFLASH;
-	mtd->flags = MTD_CAP_NANDFLASH;
-	mtd->size = 0;
-	mtd->erasesize = 0;
-	mtd->oobblock = 512;
-	mtd->oobsize = 16;
-	mtd->module = THIS_MODULE;
-	mtd->erase = doc_erase;
-	mtd->point = NULL;
-	mtd->unpoint = NULL;
-	mtd->read = doc_read;
-	mtd->write = doc_write;
-	mtd->read_ecc = doc_read_ecc;
-	mtd->write_ecc = doc_write_ecc;
-	mtd->read_oob = doc_read_oob;
-	mtd->write_oob = doc_write_oob;
-	mtd->sync = NULL;
-
-	this->totlen = 0;
-	this->numchips = 0;
-
-	this->curfloor = -1;
-	this->curchip = -1;
-
-	/* Ident all the chips present. */
-	DoC_ScanChips(this);
-
-	if (!this->totlen) {
-		kfree(mtd);
-		iounmap((void *) this->virtadr);
-	} else {
-		this->nextdoc = doc2klist;
-		doc2klist = mtd;
-		mtd->size = this->totlen;
-		mtd->erasesize = this->erasesize;
-		add_mtd_device(mtd);
-		return;
-	}
-}
-
-static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
-		    size_t * retlen, u_char * buf)
-{
-	/* Just a special case of doc_read_ecc */
-	return doc_read_ecc(mtd, from, len, retlen, buf, NULL);
-}
-
-static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
-			size_t * retlen, u_char * buf, u_char * eccbuf)
-{
-	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
-	unsigned long docptr;
-	struct Nand *mychip;
-	unsigned char syndrome[6];
-	volatile char dummy;
-	int i, len256 = 0, ret=0;
-
-	docptr = this->virtadr;
-
-	/* Don't allow read past end of device */
-	if (from >= this->totlen)
-		return -EINVAL;
-
-	/* Don't allow a single read to cross a 512-byte block boundary */
-	if (from + len > ((from | 0x1ff) + 1))
-		len = ((from | 0x1ff) + 1) - from;
-
-	/* The ECC will not be calculated correctly if less than 512 is read */
-	if (len != 0x200 && eccbuf)
-		printk(KERN_WARNING
-		       "ECC needs a full sector read (adr: %lx size %lx)\n",
-		       (long) from, (long) len);
-
-	/* printk("DoC_Read (adr: %lx size %lx)\n", (long) from, (long) len); */
-
-
-	/* Find the chip which is to be used and select it */
-	mychip = &this->chips[from >> (this->chipshift)];
-
-	if (this->curfloor != mychip->floor) {
-		DoC_SelectFloor(this, mychip->floor);
-		DoC_SelectChip(this, mychip->chip);
-	} else if (this->curchip != mychip->chip) {
-		DoC_SelectChip(this, mychip->chip);
-	}
-
-	this->curfloor = mychip->floor;
-	this->curchip = mychip->chip;
-
-	DoC_Command(this,
-		    (!this->page256
-		     && (from & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0,
-		    CDSN_CTRL_WP);
-	DoC_Address(this, ADDR_COLUMN_PAGE, from, CDSN_CTRL_WP,
-		    CDSN_CTRL_ECC_IO);
-
-	if (eccbuf) {
-		/* Prime the ECC engine */
-		WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
-		WriteDOC(DOC_ECC_EN, docptr, ECCConf);
-	} else {
-		/* disable the ECC engine */
-		WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
-		WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
-	}
-
-	/* treat crossing 256-byte sector for 2M x 8bits devices */
-	if (this->page256 && from + len > (from | 0xff) + 1) {
-		len256 = (from | 0xff) + 1 - from;
-		DoC_ReadBuf(this, buf, len256);
-
-		DoC_Command(this, NAND_CMD_READ0, CDSN_CTRL_WP);
-		DoC_Address(this, ADDR_COLUMN_PAGE, from + len256,
-			    CDSN_CTRL_WP, CDSN_CTRL_ECC_IO);
-	}
-
-	DoC_ReadBuf(this, &buf[len256], len - len256);
-
-	/* Let the caller know we completed it */
-	*retlen = len;
-
-	if (eccbuf) {
-		/* Read the ECC data through the DiskOnChip ECC logic */
-		/* Note: this will work even with 2M x 8bit devices as   */
-		/*       they have 8 bytes of OOB per 256 page. mf.      */
-		DoC_ReadBuf(this, eccbuf, 6);
-
-		/* Flush the pipeline */
-		if (DoC_is_Millennium(this)) {
-			dummy = ReadDOC(docptr, ECCConf);
-			dummy = ReadDOC(docptr, ECCConf);
-			i = ReadDOC(docptr, ECCConf);
-		} else {
-			dummy = ReadDOC(docptr, 2k_ECCStatus);
-			dummy = ReadDOC(docptr, 2k_ECCStatus);
-			i = ReadDOC(docptr, 2k_ECCStatus);
-		}
-
-		/* Check the ECC Status */
-		if (i & 0x80) {
-			int nb_errors;
-			/* There was an ECC error */
-#ifdef ECC_DEBUG
-			printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
-#endif
-			/* Read the ECC syndrom through the DiskOnChip ECC logic.
-			   These syndrome will be all ZERO when there is no error */
-			for (i = 0; i < 6; i++) {
-				syndrome[i] =
-				    ReadDOC(docptr, ECCSyndrome0 + i);
-			}
-                        nb_errors = doc_decode_ecc(buf, syndrome);
-
-#ifdef ECC_DEBUG
-			printk("Errors corrected: %x\n", nb_errors);
-#endif
-                        if (nb_errors < 0) {
-				/* We return error, but have actually done the read. Not that
-				   this can be told to user-space, via sys_read(), but at least
-				   MTD-aware stuff can know about it by checking *retlen */
-				ret = -EIO;
-                        }
-		}
-
-#ifdef PSYCHO_DEBUG
-		printk("ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
-			     (long)from, eccbuf[0], eccbuf[1], eccbuf[2],
-			     eccbuf[3], eccbuf[4], eccbuf[5]);
-#endif
-		
-		/* disable the ECC engine */
-		WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
-	}
-
-	return ret;
-}
-
-static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
-		     size_t * retlen, const u_char * buf)
-{
-	char eccbuf[6];
-	return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf);
-}
-
-static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
-			 size_t * retlen, const u_char * buf,
-			 u_char * eccbuf)
-{
-	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
-	int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */
-	unsigned long docptr;
-	volatile char dummy;
-	int len256 = 0;
-	struct Nand *mychip;
-
-	docptr = this->virtadr;
-
-	/* Don't allow write past end of device */
-	if (to >= this->totlen)
-		return -EINVAL;
-
-	/* Don't allow a single write to cross a 512-byte block boundary */
-	if (to + len > ((to | 0x1ff) + 1))
-		len = ((to | 0x1ff) + 1) - to;
-
-	/* The ECC will not be calculated correctly if less than 512 is written */
-	if (len != 0x200 && eccbuf)
-		printk(KERN_WARNING
-		       "ECC needs a full sector write (adr: %lx size %lx)\n",
-		       (long) to, (long) len);
-
-	/* printk("DoC_Write (adr: %lx size %lx)\n", (long) to, (long) len); */
-
-	/* Find the chip which is to be used and select it */
-	mychip = &this->chips[to >> (this->chipshift)];
-
-	if (this->curfloor != mychip->floor) {
-		DoC_SelectFloor(this, mychip->floor);
-		DoC_SelectChip(this, mychip->chip);
-	} else if (this->curchip != mychip->chip) {
-		DoC_SelectChip(this, mychip->chip);
-	}
-
-	this->curfloor = mychip->floor;
-	this->curchip = mychip->chip;
-
-	/* Set device to main plane of flash */
-	DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP);
-	DoC_Command(this,
-		    (!this->page256
-		     && (to & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0,
-		    CDSN_CTRL_WP);
-
-	DoC_Command(this, NAND_CMD_SEQIN, 0);
-	DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO);
-
-	if (eccbuf) {
-		/* Prime the ECC engine */
-		WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
-		WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
-	} else {
-		/* disable the ECC engine */
-		WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
-		WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
-	}
-
-	/* treat crossing 256-byte sector for 2M x 8bits devices */
-	if (this->page256 && to + len > (to | 0xff) + 1) {
-		len256 = (to | 0xff) + 1 - to;
-		DoC_WriteBuf(this, buf, len256);
-
-		DoC_Command(this, NAND_CMD_PAGEPROG, 0);
-
-		DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
-		/* There's an implicit DoC_WaitReady() in DoC_Command */
-
-		dummy = ReadDOC(docptr, CDSNSlowIO);
-		DoC_Delay(this, 2);
-
-		if (ReadDOC_(docptr, this->ioreg) & 1) {
-			printk("Error programming flash\n");
-			/* Error in programming */
-			*retlen = 0;
-			return -EIO;
-		}
-
-		DoC_Command(this, NAND_CMD_SEQIN, 0);
-		DoC_Address(this, ADDR_COLUMN_PAGE, to + len256, 0,
-			    CDSN_CTRL_ECC_IO);
-	}
-
-	DoC_WriteBuf(this, &buf[len256], len - len256);
-
-	if (eccbuf) {
-		WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr,
-			 CDSNControl);
-
-		if (DoC_is_Millennium(this)) {
-			WriteDOC(0, docptr, NOP);
-			WriteDOC(0, docptr, NOP);
-			WriteDOC(0, docptr, NOP);
-		} else {
-			WriteDOC_(0, docptr, this->ioreg);
-			WriteDOC_(0, docptr, this->ioreg);
-			WriteDOC_(0, docptr, this->ioreg);
-		}
-
-		/* Read the ECC data through the DiskOnChip ECC logic */
-		for (di = 0; di < 6; di++) {
-			eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di);
-		}
-
-		/* Reset the ECC engine */
-		WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
-
-#ifdef PSYCHO_DEBUG
-		printk
-		    ("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
-		     (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
-		     eccbuf[4], eccbuf[5]);
-#endif
-	}
-
-	DoC_Command(this, NAND_CMD_PAGEPROG, 0);
-
-	DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
-	/* There's an implicit DoC_WaitReady() in DoC_Command */
-
-	dummy = ReadDOC(docptr, CDSNSlowIO);
-	DoC_Delay(this, 2);
-
-	if (ReadDOC_(docptr, this->ioreg) & 1) {
-		printk("Error programming flash\n");
-		/* Error in programming */
-		*retlen = 0;
-		return -EIO;
-	}
-
-	/* Let the caller know we completed it */
-	*retlen = len;
-		
-	if (eccbuf) {
-		unsigned char x[8];
-		size_t dummy;
-
-		/* Write the ECC data to flash */
-		for (di=0; di<6; di++)
-			x[di] = eccbuf[di];
-		
-		x[6]=0x55;
-		x[7]=0x55;
-		
-		return doc_write_oob(mtd, to, 8, &dummy, x);
-	}
-
-	return 0;
-}
-
-static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
-			size_t * retlen, u_char * buf)
-{
-	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
-	int len256 = 0;
-	unsigned long docptr;
-	struct Nand *mychip;
-
-	docptr = this->virtadr;
-
-	mychip = &this->chips[ofs >> this->chipshift];
-
-	if (this->curfloor != mychip->floor) {
-		DoC_SelectFloor(this, mychip->floor);
-		DoC_SelectChip(this, mychip->chip);
-	} else if (this->curchip != mychip->chip) {
-		DoC_SelectChip(this, mychip->chip);
-	}
-	this->curfloor = mychip->floor;
-	this->curchip = mychip->chip;
-
-	/* update address for 2M x 8bit devices. OOB starts on the second */
-	/* page to maintain compatibility with doc_read_ecc. */
-	if (this->page256) {
-		if (!(ofs & 0x8))
-			ofs += 0x100;
-		else
-			ofs -= 0x8;
-	}
-
-	DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
-	DoC_Address(this, ADDR_COLUMN_PAGE, ofs, CDSN_CTRL_WP, 0);
-
-	/* treat crossing 8-byte OOB data for 2M x 8bit devices */
-	/* Note: datasheet says it should automaticaly wrap to the */
-	/*       next OOB block, but it didn't work here. mf.      */
-	if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
-		len256 = (ofs | 0x7) + 1 - ofs;
-		DoC_ReadBuf(this, buf, len256);
-
-		DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
-		DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff),
-			    CDSN_CTRL_WP, 0);
-	}
-
-	DoC_ReadBuf(this, &buf[len256], len - len256);
-
-	*retlen = len;
-	return 0;
-
-}
-
-static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
-			 size_t * retlen, const u_char * buf)
-{
-	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
-	int len256 = 0;
-	unsigned long docptr = this->virtadr;
-	struct Nand *mychip = &this->chips[ofs >> this->chipshift];
-	int dummy;
-
-	//      printk("doc_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",(long)ofs, len,
-	//   buf[0], buf[1], buf[2], buf[3], buf[8], buf[9], buf[14],buf[15]);
-
-	/* Find the chip which is to be used and select it */
-	if (this->curfloor != mychip->floor) {
-		DoC_SelectFloor(this, mychip->floor);
-		DoC_SelectChip(this, mychip->chip);
-	} else if (this->curchip != mychip->chip) {
-		DoC_SelectChip(this, mychip->chip);
-	}
-	this->curfloor = mychip->floor;
-	this->curchip = mychip->chip;
-
-	/* disable the ECC engine */
-	WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
-	WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
-
-	/* Reset the chip, see Software Requirement 11.4 item 1. */
-	DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP);
-
-	/* issue the Read2 command to set the pointer to the Spare Data Area. */
-	DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
-
-	/* update address for 2M x 8bit devices. OOB starts on the second */
-	/* page to maintain compatibility with doc_read_ecc. */
-	if (this->page256) {
-		if (!(ofs & 0x8))
-			ofs += 0x100;
-		else
-			ofs -= 0x8;
-	}
-
-	/* issue the Serial Data In command to initial the Page Program process */
-	DoC_Command(this, NAND_CMD_SEQIN, 0);
-	DoC_Address(this, ADDR_COLUMN_PAGE, ofs, 0, 0);
-
-	/* treat crossing 8-byte OOB data for 2M x 8bit devices */
-	/* Note: datasheet says it should automaticaly wrap to the */
-	/*       next OOB block, but it didn't work here. mf.      */
-	if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
-		len256 = (ofs | 0x7) + 1 - ofs;
-		DoC_WriteBuf(this, buf, len256);
-
-		DoC_Command(this, NAND_CMD_PAGEPROG, 0);
-		DoC_Command(this, NAND_CMD_STATUS, 0);
-		/* DoC_WaitReady() is implicit in DoC_Command */
-
-		dummy = ReadDOC(docptr, CDSNSlowIO);
-		DoC_Delay(this, 2);
-
-		if (ReadDOC_(docptr, this->ioreg) & 1) {
-			printk("Error programming oob data\n");
-			/* There was an error */
-			*retlen = 0;
-			return -EIO;
-		}
-		DoC_Command(this, NAND_CMD_SEQIN, 0);
-		DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff), 0, 0);
-	}
-
-	DoC_WriteBuf(this, &buf[len256], len - len256);
-
-	DoC_Command(this, NAND_CMD_PAGEPROG, 0);
-	DoC_Command(this, NAND_CMD_STATUS, 0);
-	/* DoC_WaitReady() is implicit in DoC_Command */
-
-	dummy = ReadDOC(docptr, CDSNSlowIO);
-	DoC_Delay(this, 2);
-
-	if (ReadDOC_(docptr, this->ioreg) & 1) {
-		printk("Error programming oob data\n");
-		/* There was an error */
-		*retlen = 0;
-		return -EIO;
-	}
-
-	*retlen = len;
-	return 0;
-
-}
-
-int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
-{
-	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
-	unsigned long ofs = instr->addr;
-	unsigned long len = instr->len;
-	unsigned long docptr;
-	struct Nand *mychip;
-
-	if (len != mtd->erasesize)
-		printk(KERN_WARNING "Erase not right size (%lx != %lx)n",
-		       len, mtd->erasesize);
-
-	docptr = this->virtadr;
-
-	mychip = &this->chips[ofs >> this->chipshift];
-
-	if (this->curfloor != mychip->floor) {
-		DoC_SelectFloor(this, mychip->floor);
-		DoC_SelectChip(this, mychip->chip);
-	} else if (this->curchip != mychip->chip) {
-		DoC_SelectChip(this, mychip->chip);
-	}
-	this->curfloor = mychip->floor;
-	this->curchip = mychip->chip;
-
-	instr->state = MTD_ERASE_PENDING;
-
-	DoC_Command(this, NAND_CMD_ERASE1, 0);
-	DoC_Address(this, ADDR_PAGE, ofs, 0, 0);
-	DoC_Command(this, NAND_CMD_ERASE2, 0);
-
-	instr->state = MTD_ERASING;
-
-	DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
-
-	if (ReadDOC_(docptr, this->ioreg) & 1) {
-		printk("Error writing\n");
-		/* There was an error */
-		instr->state = MTD_ERASE_FAILED;
-	} else
-		instr->state = MTD_ERASE_DONE;
-
-	if (instr->callback)
-		instr->callback(instr);
-
-	return 0;
-}
-
-
-/****************************************************************************
- *
- * Module stuff
- *
- ****************************************************************************/
-
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define cleanup_doc2000 cleanup_module
-#define init_doc2000 init_module
-#endif
-
-int __init init_doc2000(void)
-{
-       inter_module_register(im_name, THIS_MODULE, &DoC2k_init);
-       return 0;
-}
-
-static void __exit cleanup_doc2000(void)
-{
-	struct mtd_info *mtd;
-	struct DiskOnChip *this;
-
-	while ((mtd = doc2klist)) {
-		this = (struct DiskOnChip *) mtd->priv;
-		doc2klist = this->nextdoc;
-
-		del_mtd_device(mtd);
-
-		iounmap((void *) this->virtadr);
-		kfree(this->chips);
-		kfree(mtd);
-	}
-	inter_module_unregister(im_name);
-}
-
-module_exit(cleanup_doc2000);
-module_init(init_doc2000);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/doc2001.c linux/drivers/mtd/doc2001.c
--- v2.4.5/linux/drivers/mtd/doc2001.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/doc2001.c	Wed Dec 31 16:00:00 1969
@@ -1,883 +0,0 @@
-
-/*
- * Linux driver for Disk-On-Chip Millennium
- * (c) 1999 Machine Vision Holdings, Inc.
- * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
- *
- * $Id: doc2001.c,v 1.24 2000/12/01 13:11:02 dwmw2 Exp $
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/types.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ids.h>
-#include <linux/mtd/doc2000.h>
-
-/* #define ECC_DEBUG */
-
-/* I have no idea why some DoC chips can not use memcop_form|to_io().
- * This may be due to the different revisions of the ASIC controller built-in or
- * simplily a QA/Bug issue. Who knows ?? If you have trouble, please uncomment
- * this:
- #undef USE_MEMCPY
-*/
-
-static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
-		    size_t *retlen, u_char *buf);
-static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
-		     size_t *retlen, const u_char *buf);
-static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
-			size_t *retlen, u_char *buf, u_char *eccbuf);
-static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
-			 size_t *retlen, const u_char *buf, u_char *eccbuf);
-static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
-			size_t *retlen, u_char *buf);
-static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
-			 size_t *retlen, const u_char *buf);
-static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);
-
-static struct mtd_info *docmillist = NULL;
-
-/* Perform the required delay cycles by reading from the NOP register */
-static void DoC_Delay(unsigned long docptr, unsigned short cycles)
-{
-	volatile char dummy;
-	int i;
-
-	for (i = 0; i < cycles; i++)
-		dummy = ReadDOC(docptr, NOP);
-}
-
-/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
-static int _DoC_WaitReady(unsigned long docptr)
-{
-	unsigned short c = 0xffff;
-
-	DEBUG(MTD_DEBUG_LEVEL3,
-	      "_DoC_WaitReady called for out-of-line wait\n");
-
-	/* Out-of-line routine to wait for chip response */
-	while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B) && --c)
-		;
-
-	if (c == 0)
-		DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
-
-	return (c == 0);
-}
-
-static inline int DoC_WaitReady(unsigned long docptr)
-{
-	/* This is inline, to optimise the common case, where it's ready instantly */
-	int ret = 0;
-
-	/* 4 read form NOP register should be issued in prior to the read from CDSNControl
-	   see Software Requirement 11.4 item 2. */
-	DoC_Delay(docptr, 4);
-
-	if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
-		/* Call the out-of-line routine to wait */
-		ret = _DoC_WaitReady(docptr);
-
-	/* issue 2 read from NOP register after reading from CDSNControl register
-	   see Software Requirement 11.4 item 2. */
-	DoC_Delay(docptr, 2);
-
-	return ret;
-}
-
-/* DoC_Command: Send a flash command to the flash chip through the CDSN Slow IO register to
-   bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
-   required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
-
-static inline void DoC_Command(unsigned long docptr, unsigned char command,
-			       unsigned char xtraflags)
-{
-	/* Assert the CLE (Command Latch Enable) line to the flash chip */
-	WriteDOC(xtraflags | CDSN_CTRL_CLE | CDSN_CTRL_CE, docptr, CDSNControl);
-	DoC_Delay(docptr, 4);
-
-	/* Send the command */
-	WriteDOC(command, docptr, CDSNSlowIO);
-	WriteDOC(command, docptr, Mil_CDSN_IO);
-
-	/* Lower the CLE line */
-	WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl);
-	DoC_Delay(docptr, 4);
-}
-
-/* DoC_Address: Set the current address for the flash chip through the CDSN Slow IO register to
-   bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
-   required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
-
-static inline void DoC_Address(unsigned long docptr, int numbytes, unsigned long ofs,
-			       unsigned char xtraflags1, unsigned char xtraflags2)
-{
-	/* Assert the ALE (Address Latch Enable) line to the flash chip */
-	WriteDOC(xtraflags1 | CDSN_CTRL_ALE | CDSN_CTRL_CE, docptr, CDSNControl);
-	DoC_Delay(docptr, 4);
-
-	/* Send the address */
-	switch (numbytes)
-	    {
-	    case 1:
-		/* Send single byte, bits 0-7. */
-		WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
-		WriteDOC(ofs & 0xff, docptr, Mil_CDSN_IO);
-		break;
-	    case 2:
-		/* Send bits 9-16 followed by 17-23 */
-		WriteDOC((ofs >> 9)  & 0xff, docptr, CDSNSlowIO);
-		WriteDOC((ofs >> 9)  & 0xff, docptr, Mil_CDSN_IO);
-		WriteDOC((ofs >> 17) & 0xff, docptr, CDSNSlowIO);
-		WriteDOC((ofs >> 17) & 0xff, docptr, Mil_CDSN_IO);
-		break;
-	    case 3:
-		/* Send 0-7, 9-16, then 17-23 */
-		WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
-		WriteDOC(ofs & 0xff, docptr, Mil_CDSN_IO);
-		WriteDOC((ofs >> 9)  & 0xff, docptr, CDSNSlowIO);
-		WriteDOC((ofs >> 9)  & 0xff, docptr, Mil_CDSN_IO);
-		WriteDOC((ofs >> 17) & 0xff, docptr, CDSNSlowIO);
-		WriteDOC((ofs >> 17) & 0xff, docptr, Mil_CDSN_IO);
-		break;
-	    default:
-		return;
-	    }
-
-	/* Lower the ALE line */
-	WriteDOC(xtraflags1 | xtraflags2 | CDSN_CTRL_CE, docptr, CDSNControl);
-	DoC_Delay(docptr, 4);
-}
-
-/* DoC_SelectChip: Select a given flash chip within the current floor */
-static int DoC_SelectChip(unsigned long docptr, int chip)
-{
-	/* Select the individual flash chip requested */
-	WriteDOC(chip, docptr, CDSNDeviceSelect);
-	DoC_Delay(docptr, 4);
-
-	/* Wait for it to be ready */
-	return DoC_WaitReady(docptr);
-}
-
-/* DoC_SelectFloor: Select a given floor (bank of flash chips) */
-static int DoC_SelectFloor(unsigned long docptr, int floor)
-{
-	/* Select the floor (bank) of chips required */
-	WriteDOC(floor, docptr, FloorSelect);
-
-	/* Wait for the chip to be ready */
-	return DoC_WaitReady(docptr);
-}
-
-/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
-static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
-{
-	int mfr, id, i;
-	volatile char dummy;
-
-	/* Page in the required floor/chip
-	   FIXME: is this supported by Millennium ?? */
-	DoC_SelectFloor(doc->virtadr, floor);
-	DoC_SelectChip(doc->virtadr, chip);
-
-	/* Reset the chip, see Software Requirement 11.4 item 1. */
-	DoC_Command(doc->virtadr, NAND_CMD_RESET, CDSN_CTRL_WP);
-	DoC_WaitReady(doc->virtadr);
-
-	/* Read the NAND chip ID: 1. Send ReadID command */ 
-	DoC_Command(doc->virtadr, NAND_CMD_READID, CDSN_CTRL_WP);
-
-	/* Read the NAND chip ID: 2. Send address byte zero */ 
-	DoC_Address(doc->virtadr, 1, 0x00, CDSN_CTRL_WP, 0x00);
-
-	/* Read the manufacturer and device id codes of the flash device through
-	   CDSN Slow IO register see Software Requirement 11.4 item 5.*/
-	dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
-	DoC_Delay(doc->virtadr, 2);
-	mfr = ReadDOC(doc->virtadr, Mil_CDSN_IO);
-
-	dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
-	DoC_Delay(doc->virtadr, 2);
-	id  = ReadDOC(doc->virtadr, Mil_CDSN_IO);
-
-	/* No response - return failure */
-	if (mfr == 0xff || mfr == 0)
-		return 0;
-
-	/* FIXME: to deal with multi-flash on multi-Millennium case more carefully */
-	for (i = 0; nand_flash_ids[i].name != NULL; i++) {
-		if (mfr == nand_flash_ids[i].manufacture_id &&
-		    id == nand_flash_ids[i].model_id) {
-			printk(KERN_INFO "Flash chip found: Manufacturer ID: %2.2X, "
-			       "Chip ID: %2.2X (%s)\n",
-			       mfr, id, nand_flash_ids[i].name);
-			doc->mfr = mfr;
-			doc->id = id;
-			doc->chipshift = nand_flash_ids[i].chipshift;
-			break;
-		}
-	}
-
-	if (nand_flash_ids[i].name == NULL)
-		return 0;
-	else
-		return 1;
-}
-
-/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
-static void DoC_ScanChips(struct DiskOnChip *this)
-{
-	int floor, chip;
-	int numchips[MAX_FLOORS_MIL];
-	int ret;
-
-	this->numchips = 0;
-	this->mfr = 0;
-	this->id = 0;
-
-	/* For each floor, find the number of valid chips it contains */
-	for (floor = 0,ret = 1; floor < MAX_FLOORS_MIL; floor++) {
-		numchips[floor] = 0;
-		for (chip = 0; chip < MAX_CHIPS_MIL && ret != 0; chip++) {
-			ret = DoC_IdentChip(this, floor, chip);
-			if (ret) {
-				numchips[floor]++;
-				this->numchips++;
-			}
-		}
-	}
-	/* If there are none at all that we recognise, bail */
-	if (!this->numchips) {
-		printk("No flash chips recognised.\n");
-		return;
-	}
-
-	/* Allocate an array to hold the information for each chip */
-	this->chips = kmalloc(sizeof(struct Nand) * this->numchips, GFP_KERNEL);
-	if (!this->chips){
-		printk("No memory for allocating chip info structures\n");
-		return;
-	}
-
-	/* Fill out the chip array with {floor, chipno} for each 
-	 * detected chip in the device. */
-	for (floor = 0, ret = 0; floor < MAX_FLOORS_MIL; floor++) {
-		for (chip = 0 ; chip < numchips[floor] ; chip++) {
-			this->chips[ret].floor = floor;
-			this->chips[ret].chip = chip;
-			this->chips[ret].curadr = 0;
-			this->chips[ret].curmode = 0x50;
-			ret++;
-		}
-	}
-
-	/* Calculate and print the total size of the device */
-	this->totlen = this->numchips * (1 << this->chipshift);
-	printk(KERN_NOTICE "%d flash chips found. Total DiskOnChip size: %ld Mbytes\n",
-	       this->numchips ,this->totlen >> 20);
-}
-
-static int DoCMil_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
-{
-	int tmp1, tmp2, retval;
-
-	if (doc1->physadr == doc2->physadr)
-		return 1;
-
-	/* Use the alias resolution register which was set aside for this
-	 * purpose. If it's value is the same on both chips, they might
-	 * be the same chip, and we write to one and check for a change in
-	 * the other. It's unclear if this register is usuable in the
-	 * DoC 2000 (it's in the Millenium docs), but it seems to work. */
-	tmp1 = ReadDOC(doc1->virtadr, AliasResolution);
-	tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
-	if (tmp1 != tmp2)
-		return 0;
-	
-	WriteDOC((tmp1+1) % 0xff, doc1->virtadr, AliasResolution);
-	tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
-	if (tmp2 == (tmp1+1) % 0xff)
-		retval = 1;
-	else
-		retval = 0;
-
-	/* Restore register contents.  May not be necessary, but do it just to
-	 * be safe. */
-	WriteDOC(tmp1, doc1->virtadr, AliasResolution);
-
-	return retval;
-}
-
-static const char im_name[] = "DoCMil_init";
-
-/* This routine is made available to other mtd code via
- * inter_module_register.  It must only be accessed through
- * inter_module_get which will bump the use count of this module.  The
- * addresses passed back in mtd are valid as long as the use count of
- * this module is non-zero, i.e. between inter_module_get and
- * inter_module_put.  Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
- */
-static void DoCMil_init(struct mtd_info *mtd)
-{
-	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-	struct DiskOnChip *old = NULL;
-
-	/* We must avoid being called twice for the same device. */
-	if (docmillist)
-		old = (struct DiskOnChip *)docmillist->priv;
-
-	while (old) {
-		if (DoCMil_is_alias(this, old)) {
-			printk(KERN_NOTICE "Ignoring DiskOnChip Millennium at "
-			       "0x%lX - already configured\n", this->physadr);
-			iounmap((void *)this->virtadr);
-			kfree(mtd);
-			return;
-		}
-		if (old->nextdoc)
-			old = (struct DiskOnChip *)old->nextdoc->priv;
-		else
-			old = NULL;
-	}
-
-	mtd->name = "DiskOnChip Millennium";
-	printk(KERN_NOTICE "DiskOnChip Millennium found at address 0x%lX\n",
-	       this->physadr);
-
-	mtd->type = MTD_NANDFLASH;
-	mtd->flags = MTD_CAP_NANDFLASH;
-	mtd->size = 0;
-
-	/* FIXME: erase size is not always 8kB */
-	mtd->erasesize = 0x2000;
-
-	mtd->oobblock = 512;
-	mtd->oobsize = 16;
-	mtd->module = THIS_MODULE;
-	mtd->erase = doc_erase;
-	mtd->point = NULL;
-	mtd->unpoint = NULL;
-	mtd->read = doc_read;
-	mtd->write = doc_write;
-	mtd->read_ecc = doc_read_ecc;
-	mtd->write_ecc = doc_write_ecc;
-	mtd->read_oob = doc_read_oob;
-	mtd->write_oob = doc_write_oob;
-	mtd->sync = NULL;
-
-	this->totlen = 0;
-	this->numchips = 0;
-	this->curfloor = -1;
-	this->curchip = -1;
-
-	/* Ident all the chips present. */
-	DoC_ScanChips(this);
-
-	if (!this->totlen) {
-		kfree(mtd);
-		iounmap((void *)this->virtadr);
-	} else {
-		this->nextdoc = docmillist;
-		docmillist = mtd;
-		mtd->size  = this->totlen;
-		add_mtd_device(mtd);
-		return;
-	}
-}
-
-static int doc_read (struct mtd_info *mtd, loff_t from, size_t len,
-		     size_t *retlen, u_char *buf)
-{
-	/* Just a special case of doc_read_ecc */
-	return doc_read_ecc(mtd, from, len, retlen, buf, NULL);
-}
-
-static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
-			 size_t *retlen, u_char *buf, u_char *eccbuf)
-{
-	int i, ret;
-	volatile char dummy;
-	unsigned char syndrome[6];
-	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-	unsigned long docptr = this->virtadr;
-	struct Nand *mychip = &this->chips[from >> (this->chipshift)];
-
-	/* Don't allow read past end of device */
-	if (from >= this->totlen)
-		return -EINVAL;
-
-	/* Don't allow a single read to cross a 512-byte block boundary */
-	if (from + len > ((from | 0x1ff) + 1)) 
-		len = ((from | 0x1ff) + 1) - from;
-
-	/* Find the chip which is to be used and select it */
-	if (this->curfloor != mychip->floor) {
-		DoC_SelectFloor(docptr, mychip->floor);
-		DoC_SelectChip(docptr, mychip->chip);
-	} else if (this->curchip != mychip->chip) {
-		DoC_SelectChip(docptr, mychip->chip);
-	}
-	this->curfloor = mychip->floor;
-	this->curchip = mychip->chip;
-
-	/* issue the Read0 or Read1 command depend on which half of the page
-	   we are accessing. Polling the Flash Ready bit after issue 3 bytes
-	   address in Sequence Read Mode, see Software Requirement 11.4 item 1.*/
-	DoC_Command(docptr, (from >> 8) & 1, CDSN_CTRL_WP);
-	DoC_Address(docptr, 3, from, CDSN_CTRL_WP, 0x00);
-	DoC_WaitReady(docptr);
-
-	if (eccbuf) {
-		/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
-		WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
-		WriteDOC (DOC_ECC_EN, docptr, ECCConf);
-	} else {
-		/* disable the ECC engine */
-		WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
-		WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
-	}
-
-	/* Read the data via the internal pipeline through CDSN IO register,
-	   see Pipelined Read Operations 11.3 */
-	dummy = ReadDOC(docptr, ReadPipeInit);
-#ifndef USE_MEMCPY
-	for (i = 0; i < len-1; i++) {
-		/* N.B. you have to increase the source address in this way or the
-		   ECC logic will not work properly */
-		buf[i] = ReadDOC(docptr, Mil_CDSN_IO + (i & 0xff));
-	}
-#else
-	memcpy_fromio(buf, docptr + DoC_Mil_CDSN_IO, len - 1);
-#endif
-	buf[len - 1] = ReadDOC(docptr, LastDataRead);
-
-	/* Let the caller know we completed it */
-	*retlen = len;
-        ret = 0;
-
-	if (eccbuf) {
-		/* Read the ECC data from Spare Data Area,
-		   see Reed-Solomon EDC/ECC 11.1 */
-		dummy = ReadDOC(docptr, ReadPipeInit);
-#ifndef USE_MEMCPY
-		for (i = 0; i < 5; i++) {
-			/* N.B. you have to increase the source address in this way or the
-			   ECC logic will not work properly */
-			eccbuf[i] = ReadDOC(docptr, Mil_CDSN_IO + i);
-		}
-#else
-		memcpy_fromio(eccbuf, docptr + DoC_Mil_CDSN_IO, 5);
-#endif
-		eccbuf[5] = ReadDOC(docptr, LastDataRead);
-
-		/* Flush the pipeline */
-		dummy = ReadDOC(docptr, ECCConf);
-		dummy = ReadDOC(docptr, ECCConf);
-
-		/* Check the ECC Status */
-		if (ReadDOC(docptr, ECCConf) & 0x80) {
-                        int nb_errors;
-			/* There was an ECC error */
-#ifdef ECC_DEBUG
-			printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
-#endif
-			/* Read the ECC syndrom through the DiskOnChip ECC logic.
-			   These syndrome will be all ZERO when there is no error */
-			for (i = 0; i < 6; i++) {
-				syndrome[i] = ReadDOC(docptr, ECCSyndrome0 + i);
-			}
-                        nb_errors = doc_decode_ecc(buf, syndrome);
-#ifdef ECC_DEBUG
-			printk("Errors corrected: %x\n", nb_errors);
-#endif
-                        if (nb_errors < 0) {
-				/* We return error, but have actually done the read. Not that
-				   this can be told to user-space, via sys_read(), but at least
-				   MTD-aware stuff can know about it by checking *retlen */
-				ret = -EIO;
-                        }
-		}
-
-#ifdef PSYCHO_DEBUG
-		printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
-		       (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
-		       eccbuf[4], eccbuf[5]);
-#endif
-		/* disable the ECC engine */
-		WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
-	}
-
-	return ret;
-}
-
-static int doc_write (struct mtd_info *mtd, loff_t to, size_t len,
-		      size_t *retlen, const u_char *buf)
-{
-	char eccbuf[6];
-	return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf);
-}
-
-static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
-			  size_t *retlen, const u_char *buf, u_char *eccbuf)
-{
-	int i;
-	volatile char dummy;
-	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-	unsigned long docptr = this->virtadr;
-	struct Nand *mychip = &this->chips[to >> (this->chipshift)];
-
-	/* Don't allow write past end of device */
-	if (to >= this->totlen)
-		return -EINVAL;
-
-#if 0
-	/* Don't allow a single write to cross a 512-byte block boundary */
-	if (to + len > ( (to | 0x1ff) + 1)) 
-		len = ((to | 0x1ff) + 1) - to;
-#else
-	/* Don't allow writes which aren't exactly one block */
-	if (to & 0x1ff || len != 0x200)
-		return -EINVAL;
-#endif
-
-	/* Find the chip which is to be used and select it */
-	if (this->curfloor != mychip->floor) {
-		DoC_SelectFloor(docptr, mychip->floor);
-		DoC_SelectChip(docptr, mychip->chip);
-	} else if (this->curchip != mychip->chip) {
-		DoC_SelectChip(docptr, mychip->chip);
-	}
-	this->curfloor = mychip->floor;
-	this->curchip = mychip->chip;
-
-	/* Reset the chip, see Software Requirement 11.4 item 1. */
-	DoC_Command(docptr, NAND_CMD_RESET, 0x00);
-	DoC_WaitReady(docptr);
-	/* Set device to main plane of flash */
-	DoC_Command(docptr, NAND_CMD_READ0, 0x00);
-
-	/* issue the Serial Data In command to initial the Page Program process */
-	DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
-	DoC_Address(docptr, 3, to, 0x00, 0x00);
-	DoC_WaitReady(docptr);
-
-	if (eccbuf) {
-		/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
-		WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
-		WriteDOC (DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
-	} else {
-		/* disable the ECC engine */
-		WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
-		WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
-	}
-
-	/* Write the data via the internal pipeline through CDSN IO register,
-	   see Pipelined Write Operations 11.2 */
-#ifndef USE_MEMCPY
-	for (i = 0; i < len; i++) {
-		/* N.B. you have to increase the source address in this way or the
-		   ECC logic will not work properly */
-		WriteDOC(buf[i], docptr, Mil_CDSN_IO + i);
-	}
-#else
-	memcpy_toio(docptr + DoC_Mil_CDSN_IO, buf, len);
-#endif
-	WriteDOC(0x00, docptr, WritePipeTerm);
-
-	if (eccbuf) {
-		/* Write ECC data to flash, the ECC info is generated by the DiskOnChip ECC logic
-		   see Reed-Solomon EDC/ECC 11.1 */
-		WriteDOC(0, docptr, NOP);
-		WriteDOC(0, docptr, NOP);
-		WriteDOC(0, docptr, NOP);
-
-		/* Read the ECC data through the DiskOnChip ECC logic */
-		for (i = 0; i < 6; i++) {
-			eccbuf[i] = ReadDOC(docptr, ECCSyndrome0 + i);
-		}
-
-		/* ignore the ECC engine */
-		WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
-
-#ifndef USE_MEMCPY
-		/* Write the ECC data to flash */
-		for (i = 0; i < 6; i++) {
-			/* N.B. you have to increase the source address in this way or the
-			   ECC logic will not work properly */
-			WriteDOC(eccbuf[i], docptr, Mil_CDSN_IO + i);
-		}
-#else
-		memcpy_toio(docptr + DoC_Mil_CDSN_IO, eccbuf, 6);
-#endif
-
-		/* write the block status BLOCK_USED (0x5555) at the end of ECC data
-		   FIXME: this is only a hack for programming the IPL area for LinuxBIOS
-		   and should be replace with proper codes in user space utilities */ 
-		WriteDOC(0x55, docptr, Mil_CDSN_IO);
-		WriteDOC(0x55, docptr, Mil_CDSN_IO + 1);
-
-		WriteDOC(0x00, docptr, WritePipeTerm);
-
-#ifdef PSYCHO_DEBUG
-		printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
-		       (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
-		       eccbuf[4], eccbuf[5]);
-#endif
-	}
-
-	/* Commit the Page Program command and wait for ready
-	   see Software Requirement 11.4 item 1.*/
-	DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
-	DoC_WaitReady(docptr);
-
-	/* Read the status of the flash device through CDSN Slow IO register
-	   see Software Requirement 11.4 item 5.*/
-	DoC_Command(docptr, NAND_CMD_STATUS, CDSN_CTRL_WP);
-	dummy = ReadDOC(docptr, CDSNSlowIO);
-	DoC_Delay(docptr, 2);
-	if (ReadDOC(docptr, Mil_CDSN_IO) & 1) {
-		printk("Error programming flash\n");
-		/* Error in programming
-		   FIXME: implement Bad Block Replacement (in nftl.c ??) */
-		*retlen = 0;
-		return -EIO;
-	}
-
-	/* Let the caller know we completed it */
-	*retlen = len;
-
-	return 0;
-}
-
-static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
-			size_t *retlen, u_char *buf)
-{
-#ifndef USE_MEMCPY
-	int i;
-#endif
-	volatile char dummy;
-	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-	unsigned long docptr = this->virtadr;
-	struct Nand *mychip = &this->chips[ofs >> this->chipshift];
-
-	/* Find the chip which is to be used and select it */
-	if (this->curfloor != mychip->floor) {
-		DoC_SelectFloor(docptr, mychip->floor);
-		DoC_SelectChip(docptr, mychip->chip);
-	} else if (this->curchip != mychip->chip) {
-		DoC_SelectChip(docptr, mychip->chip);
-	}
-	this->curfloor = mychip->floor;
-	this->curchip = mychip->chip;
-
-	/* disable the ECC engine */
-	WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
-	WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
-
-	/* issue the Read2 command to set the pointer to the Spare Data Area.
-	   Polling the Flash Ready bit after issue 3 bytes address in
-	   Sequence Read Mode, see Software Requirement 11.4 item 1.*/
-	DoC_Command(docptr, NAND_CMD_READOOB, CDSN_CTRL_WP);
-	DoC_Address(docptr, 3, ofs, CDSN_CTRL_WP, 0x00);
-	DoC_WaitReady(docptr);
-
-	/* Read the data out via the internal pipeline through CDSN IO register,
-	   see Pipelined Read Operations 11.3 */
-	dummy = ReadDOC(docptr, ReadPipeInit);
-#ifndef USE_MEMCPY
-	for (i = 0; i < len-1; i++) {
-		/* N.B. you have to increase the source address in this way or the
-		   ECC logic will not work properly */
-		buf[i] = ReadDOC(docptr, Mil_CDSN_IO + i);
-	}
-	buf[i] = ReadDOC(docptr, LastDataRead);
-#else
-	memcpy_fromio(buf, docptr + DoC_Mil_CDSN_IO, len - 1);
-#endif
-	buf[len - 1] = ReadDOC(docptr, LastDataRead);
-
-	*retlen = len;
-
-	return 0;
-}
-
-static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
-			 size_t *retlen, const u_char *buf)
-{
-#ifndef USE_MEMCPY
-	int i;
-#endif
-	volatile char dummy;
-	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-	unsigned long docptr = this->virtadr;
-	struct Nand *mychip = &this->chips[ofs >> this->chipshift];
-
-	/* Find the chip which is to be used and select it */
-	if (this->curfloor != mychip->floor) {
-		DoC_SelectFloor(docptr, mychip->floor);
-		DoC_SelectChip(docptr, mychip->chip);
-	} else if (this->curchip != mychip->chip) {
-		DoC_SelectChip(docptr, mychip->chip);
-	}
-	this->curfloor = mychip->floor;
-	this->curchip = mychip->chip;
-
-	/* disable the ECC engine */
-	WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
-	WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
-
-	/* Reset the chip, see Software Requirement 11.4 item 1. */
-	DoC_Command(docptr, NAND_CMD_RESET, CDSN_CTRL_WP);
-	DoC_WaitReady(docptr);
-	/* issue the Read2 command to set the pointer to the Spare Data Area. */
-	DoC_Command(docptr, NAND_CMD_READOOB, CDSN_CTRL_WP);
-
-	/* issue the Serial Data In command to initial the Page Program process */
-	DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
-	DoC_Address(docptr, 3, ofs, 0x00, 0x00);
-
-	/* Write the data via the internal pipeline through CDSN IO register,
-	   see Pipelined Write Operations 11.2 */
-#ifndef USE_MEMCPY
-	for (i = 0; i < len; i++) {
-		/* N.B. you have to increase the source address in this way or the
-		   ECC logic will not work properly */
-		WriteDOC(buf[i], docptr, Mil_CDSN_IO + i);
-	}
-#else
-	memcpy_toio(docptr + DoC_Mil_CDSN_IO, buf, len);
-#endif
-	WriteDOC(0x00, docptr, WritePipeTerm);
-
-	/* Commit the Page Program command and wait for ready
-	   see Software Requirement 11.4 item 1.*/
-	DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
-	DoC_WaitReady(docptr);
-
-	/* Read the status of the flash device through CDSN Slow IO register
-	   see Software Requirement 11.4 item 5.*/
-	DoC_Command(docptr, NAND_CMD_STATUS, 0x00);
-	dummy = ReadDOC(docptr, CDSNSlowIO);
-	DoC_Delay(docptr, 2);
-	if (ReadDOC(docptr, Mil_CDSN_IO) & 1) {
-		printk("Error programming oob data\n");
-		/* FIXME: implement Bad Block Replacement (in nftl.c ??) */
-		*retlen = 0;
-		return -EIO;
-	}
-
-	*retlen = len;
-
-	return 0;
-}
-
-int doc_erase (struct mtd_info *mtd, struct erase_info *instr)
-{
-	volatile char dummy;
-	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-	unsigned long ofs = instr->addr;
-	unsigned long len = instr->len;
-	unsigned long docptr = this->virtadr;
-	struct Nand *mychip = &this->chips[ofs >> this->chipshift];
-
-	if (len != mtd->erasesize) 
-		printk(KERN_WARNING "Erase not right size (%lx != %lx)n",
-		       len, mtd->erasesize);
-
-	/* Find the chip which is to be used and select it */
-	if (this->curfloor != mychip->floor) {
-		DoC_SelectFloor(docptr, mychip->floor);
-		DoC_SelectChip(docptr, mychip->chip);
-	} else if (this->curchip != mychip->chip) {
-		DoC_SelectChip(docptr, mychip->chip);
-	}
-	this->curfloor = mychip->floor;
-	this->curchip = mychip->chip;
-
-	instr->state = MTD_ERASE_PENDING;
-
-	/* issue the Erase Setup command */
-	DoC_Command(docptr, NAND_CMD_ERASE1, 0x00);
-	DoC_Address(docptr, 2, ofs, 0x00, 0x00);
-
-	/* Commit the Erase Start command and wait for ready
-	   see Software Requirement 11.4 item 1.*/
-	DoC_Command(docptr, NAND_CMD_ERASE2, 0x00);
-	DoC_WaitReady(docptr);
-
-	instr->state = MTD_ERASING;
-
-	/* Read the status of the flash device through CDSN Slow IO register
-	   see Software Requirement 11.4 item 5.
-	   FIXME: it seems that we are not wait long enough, some blocks are not
-	   erased fully */
-	DoC_Command(docptr, NAND_CMD_STATUS, CDSN_CTRL_WP);
-	dummy = ReadDOC(docptr, CDSNSlowIO);
-	DoC_Delay(docptr, 2);
-	if (ReadDOC(docptr, Mil_CDSN_IO) & 1) {
-		printk("Error Erasing at 0x%lx\n", ofs);
-		/* There was an error
-		   FIXME: implement Bad Block Replacement (in nftl.c ??) */
-		instr->state = MTD_ERASE_FAILED;
-	} else
-		instr->state = MTD_ERASE_DONE;
-
-	if (instr->callback) 
-		instr->callback(instr);
-
-	return 0;
-}
-
-/****************************************************************************
- *
- * Module stuff
- *
- ****************************************************************************/
-
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define cleanup_doc2001 cleanup_module
-#define init_doc2001 init_module
-#endif
-
-int __init init_doc2001(void)
-{
-	inter_module_register(im_name, THIS_MODULE, &DoCMil_init);
-	return 0;
-}
-
-static void __exit cleanup_doc2001(void)
-{
-	struct mtd_info *mtd;
-	struct DiskOnChip *this;
-
-	while((mtd=docmillist)) {
-		this = (struct DiskOnChip *)mtd->priv;
-		docmillist = this->nextdoc;
-			
-		del_mtd_device(mtd);
-			
-		iounmap((void *)this->virtadr);
-		kfree(this->chips);
-		kfree(mtd);
-	}
-	inter_module_unregister(im_name);
-}
-
-module_exit(cleanup_doc2001);
-module_init(init_doc2001);
-
-
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/docecc.c linux/drivers/mtd/docecc.c
--- v2.4.5/linux/drivers/mtd/docecc.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/docecc.c	Wed Dec 31 16:00:00 1969
@@ -1,522 +0,0 @@
-/*
- * ECC algorithm for M-systems disk on chip. We use the excellent Reed
- * Solmon code of Phil Karn (karn@ka9q.ampr.org) available under the
- * GNU GPL License. The rest is simply to convert the disk on chip
- * syndrom into a standard syndom.
- *
- * Author: Fabrice Bellard (fabrice.bellard@netgem.com) 
- * Copyright (C) 2000 Netgem S.A.
- *
- * $Id: docecc.c,v 1.1 2000/11/03 12:43:43 dwmw2 Exp $
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/types.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/doc2000.h>
-
-/* need to undef it (from asm/termbits.h) */
-#undef B0
-
-#define MM 10 /* Symbol size in bits */
-#define KK (1023-4) /* Number of data symbols per block */
-#define B0 510 /* First root of generator polynomial, alpha form */
-#define PRIM 1 /* power of alpha used to generate roots of generator poly */
-#define	NN ((1 << MM) - 1)
-
-typedef unsigned short dtype;
-
-/* 1+x^3+x^10 */
-static const int Pp[MM+1] = { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
-
-/* This defines the type used to store an element of the Galois Field
- * used by the code. Make sure this is something larger than a char if
- * if anything larger than GF(256) is used.
- *
- * Note: unsigned char will work up to GF(256) but int seems to run
- * faster on the Pentium.
- */
-typedef int gf;
-
-/* No legal value in index form represents zero, so
- * we need a special value for this purpose
- */
-#define A0	(NN)
-
-/* Compute x % NN, where NN is 2**MM - 1,
- * without a slow divide
- */
-static inline gf
-modnn(int x)
-{
-  while (x >= NN) {
-    x -= NN;
-    x = (x >> MM) + (x & NN);
-  }
-  return x;
-}
-
-#define	min(a,b)	((a) < (b) ? (a) : (b))
-
-#define	CLEAR(a,n) {\
-int ci;\
-for(ci=(n)-1;ci >=0;ci--)\
-(a)[ci] = 0;\
-}
-
-#define	COPY(a,b,n) {\
-int ci;\
-for(ci=(n)-1;ci >=0;ci--)\
-(a)[ci] = (b)[ci];\
-}
-
-#define	COPYDOWN(a,b,n) {\
-int ci;\
-for(ci=(n)-1;ci >=0;ci--)\
-(a)[ci] = (b)[ci];\
-}
-
-#define Ldec 1
-
-/* generate GF(2**m) from the irreducible polynomial p(X) in Pp[0]..Pp[m]
-   lookup tables:  index->polynomial form   alpha_to[] contains j=alpha**i;
-                   polynomial form -> index form  index_of[j=alpha**i] = i
-   alpha=2 is the primitive element of GF(2**m)
-   HARI's COMMENT: (4/13/94) alpha_to[] can be used as follows:
-        Let @ represent the primitive element commonly called "alpha" that
-   is the root of the primitive polynomial p(x). Then in GF(2^m), for any
-   0 <= i <= 2^m-2,
-        @^i = a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1)
-   where the binary vector (a(0),a(1),a(2),...,a(m-1)) is the representation
-   of the integer "alpha_to[i]" with a(0) being the LSB and a(m-1) the MSB. Thus for
-   example the polynomial representation of @^5 would be given by the binary
-   representation of the integer "alpha_to[5]".
-                   Similarily, index_of[] can be used as follows:
-        As above, let @ represent the primitive element of GF(2^m) that is
-   the root of the primitive polynomial p(x). In order to find the power
-   of @ (alpha) that has the polynomial representation
-        a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1)
-   we consider the integer "i" whose binary representation with a(0) being LSB
-   and a(m-1) MSB is (a(0),a(1),...,a(m-1)) and locate the entry
-   "index_of[i]". Now, @^index_of[i] is that element whose polynomial 
-    representation is (a(0),a(1),a(2),...,a(m-1)).
-   NOTE:
-        The element alpha_to[2^m-1] = 0 always signifying that the
-   representation of "@^infinity" = 0 is (0,0,0,...,0).
-        Similarily, the element index_of[0] = A0 always signifying
-   that the power of alpha which has the polynomial representation
-   (0,0,...,0) is "infinity".
- 
-*/
-
-static void
-generate_gf(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1])
-{
-  register int i, mask;
-
-  mask = 1;
-  Alpha_to[MM] = 0;
-  for (i = 0; i < MM; i++) {
-    Alpha_to[i] = mask;
-    Index_of[Alpha_to[i]] = i;
-    /* If Pp[i] == 1 then, term @^i occurs in poly-repr of @^MM */
-    if (Pp[i] != 0)
-      Alpha_to[MM] ^= mask;	/* Bit-wise EXOR operation */
-    mask <<= 1;	/* single left-shift */
-  }
-  Index_of[Alpha_to[MM]] = MM;
-  /*
-   * Have obtained poly-repr of @^MM. Poly-repr of @^(i+1) is given by
-   * poly-repr of @^i shifted left one-bit and accounting for any @^MM
-   * term that may occur when poly-repr of @^i is shifted.
-   */
-  mask >>= 1;
-  for (i = MM + 1; i < NN; i++) {
-    if (Alpha_to[i - 1] >= mask)
-      Alpha_to[i] = Alpha_to[MM] ^ ((Alpha_to[i - 1] ^ mask) << 1);
-    else
-      Alpha_to[i] = Alpha_to[i - 1] << 1;
-    Index_of[Alpha_to[i]] = i;
-  }
-  Index_of[0] = A0;
-  Alpha_to[NN] = 0;
-}
-
-/*
- * Performs ERRORS+ERASURES decoding of RS codes. bb[] is the content
- * of the feedback shift register after having processed the data and
- * the ECC.
- *
- * Return number of symbols corrected, or -1 if codeword is illegal
- * or uncorrectable. If eras_pos is non-null, the detected error locations
- * are written back. NOTE! This array must be at least NN-KK elements long.
- * The corrected data are written in eras_val[]. They must be xor with the data
- * to retrieve the correct data : data[erase_pos[i]] ^= erase_val[i] .
- * 
- * First "no_eras" erasures are declared by the calling program. Then, the
- * maximum # of errors correctable is t_after_eras = floor((NN-KK-no_eras)/2).
- * If the number of channel errors is not greater than "t_after_eras" the
- * transmitted codeword will be recovered. Details of algorithm can be found
- * in R. Blahut's "Theory ... of Error-Correcting Codes".
-
- * Warning: the eras_pos[] array must not contain duplicate entries; decoder failure
- * will result. The decoder *could* check for this condition, but it would involve
- * extra time on every decoding operation.
- * */
-static int
-eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
-            gf bb[NN - KK + 1], gf eras_val[NN-KK], int eras_pos[NN-KK], 
-            int no_eras)
-{
-  int deg_lambda, el, deg_omega;
-  int i, j, r,k;
-  gf u,q,tmp,num1,num2,den,discr_r;
-  gf lambda[NN-KK + 1], s[NN-KK + 1];	/* Err+Eras Locator poly
-					 * and syndrome poly */
-  gf b[NN-KK + 1], t[NN-KK + 1], omega[NN-KK + 1];
-  gf root[NN-KK], reg[NN-KK + 1], loc[NN-KK];
-  int syn_error, count;
-
-  syn_error = 0;
-  for(i=0;i<NN-KK;i++)
-      syn_error |= bb[i];
-
-  if (!syn_error) {
-    /* if remainder is zero, data[] is a codeword and there are no
-     * errors to correct. So return data[] unmodified
-     */
-    count = 0;
-    goto finish;
-  }
-  
-  for(i=1;i<=NN-KK;i++){
-    s[i] = bb[0];
-  }
-  for(j=1;j<NN-KK;j++){
-    if(bb[j] == 0)
-      continue;
-    tmp = Index_of[bb[j]];
-    
-    for(i=1;i<=NN-KK;i++)
-      s[i] ^= Alpha_to[modnn(tmp + (B0+i-1)*PRIM*j)];
-  }
-
-  /* undo the feedback register implicit multiplication and convert
-     syndromes to index form */
-
-  for(i=1;i<=NN-KK;i++) {
-      tmp = Index_of[s[i]];
-      if (tmp != A0)
-          tmp = modnn(tmp + 2 * KK * (B0+i-1)*PRIM);
-      s[i] = tmp;
-  }
-  
-  CLEAR(&lambda[1],NN-KK);
-  lambda[0] = 1;
-
-  if (no_eras > 0) {
-    /* Init lambda to be the erasure locator polynomial */
-    lambda[1] = Alpha_to[modnn(PRIM * eras_pos[0])];
-    for (i = 1; i < no_eras; i++) {
-      u = modnn(PRIM*eras_pos[i]);
-      for (j = i+1; j > 0; j--) {
-	tmp = Index_of[lambda[j - 1]];
-	if(tmp != A0)
-	  lambda[j] ^= Alpha_to[modnn(u + tmp)];
-      }
-    }
-#if DEBUG >= 1
-    /* Test code that verifies the erasure locator polynomial just constructed
-       Needed only for decoder debugging. */
-    
-    /* find roots of the erasure location polynomial */
-    for(i=1;i<=no_eras;i++)
-      reg[i] = Index_of[lambda[i]];
-    count = 0;
-    for (i = 1,k=NN-Ldec; i <= NN; i++,k = modnn(NN+k-Ldec)) {
-      q = 1;
-      for (j = 1; j <= no_eras; j++)
-	if (reg[j] != A0) {
-	  reg[j] = modnn(reg[j] + j);
-	  q ^= Alpha_to[reg[j]];
-	}
-      if (q != 0)
-	continue;
-      /* store root and error location number indices */
-      root[count] = i;
-      loc[count] = k;
-      count++;
-    }
-    if (count != no_eras) {
-      printf("\n lambda(x) is WRONG\n");
-      count = -1;
-      goto finish;
-    }
-#if DEBUG >= 2
-    printf("\n Erasure positions as determined by roots of Eras Loc Poly:\n");
-    for (i = 0; i < count; i++)
-      printf("%d ", loc[i]);
-    printf("\n");
-#endif
-#endif
-  }
-  for(i=0;i<NN-KK+1;i++)
-    b[i] = Index_of[lambda[i]];
-  
-  /*
-   * Begin Berlekamp-Massey algorithm to determine error+erasure
-   * locator polynomial
-   */
-  r = no_eras;
-  el = no_eras;
-  while (++r <= NN-KK) {	/* r is the step number */
-    /* Compute discrepancy at the r-th step in poly-form */
-    discr_r = 0;
-    for (i = 0; i < r; i++){
-      if ((lambda[i] != 0) && (s[r - i] != A0)) {
-	discr_r ^= Alpha_to[modnn(Index_of[lambda[i]] + s[r - i])];
-      }
-    }
-    discr_r = Index_of[discr_r];	/* Index form */
-    if (discr_r == A0) {
-      /* 2 lines below: B(x) <-- x*B(x) */
-      COPYDOWN(&b[1],b,NN-KK);
-      b[0] = A0;
-    } else {
-      /* 7 lines below: T(x) <-- lambda(x) - discr_r*x*b(x) */
-      t[0] = lambda[0];
-      for (i = 0 ; i < NN-KK; i++) {
-	if(b[i] != A0)
-	  t[i+1] = lambda[i+1] ^ Alpha_to[modnn(discr_r + b[i])];
-	else
-	  t[i+1] = lambda[i+1];
-      }
-      if (2 * el <= r + no_eras - 1) {
-	el = r + no_eras - el;
-	/*
-	 * 2 lines below: B(x) <-- inv(discr_r) *
-	 * lambda(x)
-	 */
-	for (i = 0; i <= NN-KK; i++)
-	  b[i] = (lambda[i] == 0) ? A0 : modnn(Index_of[lambda[i]] - discr_r + NN);
-      } else {
-	/* 2 lines below: B(x) <-- x*B(x) */
-	COPYDOWN(&b[1],b,NN-KK);
-	b[0] = A0;
-      }
-      COPY(lambda,t,NN-KK+1);
-    }
-  }
-
-  /* Convert lambda to index form and compute deg(lambda(x)) */
-  deg_lambda = 0;
-  for(i=0;i<NN-KK+1;i++){
-    lambda[i] = Index_of[lambda[i]];
-    if(lambda[i] != A0)
-      deg_lambda = i;
-  }
-  /*
-   * Find roots of the error+erasure locator polynomial by Chien
-   * Search
-   */
-  COPY(&reg[1],&lambda[1],NN-KK);
-  count = 0;		/* Number of roots of lambda(x) */
-  for (i = 1,k=NN-Ldec; i <= NN; i++,k = modnn(NN+k-Ldec)) {
-    q = 1;
-    for (j = deg_lambda; j > 0; j--){
-      if (reg[j] != A0) {
-	reg[j] = modnn(reg[j] + j);
-	q ^= Alpha_to[reg[j]];
-      }
-    }
-    if (q != 0)
-      continue;
-    /* store root (index-form) and error location number */
-    root[count] = i;
-    loc[count] = k;
-    /* If we've already found max possible roots,
-     * abort the search to save time
-     */
-    if(++count == deg_lambda)
-      break;
-  }
-  if (deg_lambda != count) {
-    /*
-     * deg(lambda) unequal to number of roots => uncorrectable
-     * error detected
-     */
-    count = -1;
-    goto finish;
-  }
-  /*
-   * Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo
-   * x**(NN-KK)). in index form. Also find deg(omega).
-   */
-  deg_omega = 0;
-  for (i = 0; i < NN-KK;i++){
-    tmp = 0;
-    j = (deg_lambda < i) ? deg_lambda : i;
-    for(;j >= 0; j--){
-      if ((s[i + 1 - j] != A0) && (lambda[j] != A0))
-	tmp ^= Alpha_to[modnn(s[i + 1 - j] + lambda[j])];
-    }
-    if(tmp != 0)
-      deg_omega = i;
-    omega[i] = Index_of[tmp];
-  }
-  omega[NN-KK] = A0;
-  
-  /*
-   * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 =
-   * inv(X(l))**(B0-1) and den = lambda_pr(inv(X(l))) all in poly-form
-   */
-  for (j = count-1; j >=0; j--) {
-    num1 = 0;
-    for (i = deg_omega; i >= 0; i--) {
-      if (omega[i] != A0)
-	num1  ^= Alpha_to[modnn(omega[i] + i * root[j])];
-    }
-    num2 = Alpha_to[modnn(root[j] * (B0 - 1) + NN)];
-    den = 0;
-    
-    /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
-    for (i = min(deg_lambda,NN-KK-1) & ~1; i >= 0; i -=2) {
-      if(lambda[i+1] != A0)
-	den ^= Alpha_to[modnn(lambda[i+1] + i * root[j])];
-    }
-    if (den == 0) {
-#if DEBUG >= 1
-      printf("\n ERROR: denominator = 0\n");
-#endif
-      /* Convert to dual- basis */
-      count = -1;
-      goto finish;
-    }
-    /* Apply error to data */
-    if (num1 != 0) {
-        eras_val[j] = Alpha_to[modnn(Index_of[num1] + Index_of[num2] + NN - Index_of[den])];
-    } else {
-        eras_val[j] = 0;
-    }
-  }
- finish:
-  for(i=0;i<count;i++)
-      eras_pos[i] = loc[i];
-  return count;
-}
-
-/***************************************************************************/
-/* The DOC specific code begins here */
-
-#define SECTOR_SIZE 512
-/* The sector bytes are packed into NB_DATA MM bits words */
-#define NB_DATA (((SECTOR_SIZE + 1) * 8 + 6) / MM)
-
-/* 
- * Correct the errors in 'sector[]' by using 'ecc1[]' which is the
- * content of the feedback shift register applyied to the sector and
- * the ECC. Return the number of errors corrected (and correct them in
- * sector), or -1 if error 
- */
-int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
-{
-    int parity, i, nb_errors;
-    gf bb[NN - KK + 1];
-    gf error_val[NN-KK];
-    int error_pos[NN-KK], pos, bitpos, index, val;
-    dtype *Alpha_to, *Index_of;
-
-    /* init log and exp tables here to save memory. However, it is slower */
-    Alpha_to = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL);
-    if (!Alpha_to)
-        return -1;
-    
-    Index_of = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL);
-    if (!Index_of) {
-        kfree(Alpha_to);
-        return -1;
-    }
-
-    generate_gf(Alpha_to, Index_of);
-
-    parity = ecc1[1];
-
-    bb[0] =  (ecc1[4] & 0xff) | ((ecc1[5] & 0x03) << 8);
-    bb[1] = ((ecc1[5] & 0xfc) >> 2) | ((ecc1[2] & 0x0f) << 6);
-    bb[2] = ((ecc1[2] & 0xf0) >> 4) | ((ecc1[3] & 0x3f) << 4);
-    bb[3] = ((ecc1[3] & 0xc0) >> 6) | ((ecc1[0] & 0xff) << 2);
-
-    nb_errors = eras_dec_rs(Alpha_to, Index_of, bb, 
-                            error_val, error_pos, 0);
-    if (nb_errors <= 0)
-        goto the_end;
-
-    /* correct the errors */
-    for(i=0;i<nb_errors;i++) {
-        pos = error_pos[i];
-        if (pos >= NB_DATA && pos < KK) {
-            nb_errors = -1;
-            goto the_end;
-        }
-        if (pos < NB_DATA) {
-            /* extract bit position (MSB first) */
-            pos = 10 * (NB_DATA - 1 - pos) - 6;
-            /* now correct the following 10 bits. At most two bytes
-               can be modified since pos is even */
-            index = (pos >> 3) ^ 1;
-            bitpos = pos & 7;
-            if ((index >= 0 && index < SECTOR_SIZE) || 
-                index == (SECTOR_SIZE + 1)) {
-                val = error_val[i] >> (2 + bitpos);
-                parity ^= val;
-                if (index < SECTOR_SIZE)
-                    sector[index] ^= val;
-            }
-            index = ((pos >> 3) + 1) ^ 1;
-            bitpos = (bitpos + 10) & 7;
-            if (bitpos == 0)
-                bitpos = 8;
-            if ((index >= 0 && index < SECTOR_SIZE) || 
-                index == (SECTOR_SIZE + 1)) {
-                val = error_val[i] << (8 - bitpos);
-                parity ^= val;
-                if (index < SECTOR_SIZE)
-                    sector[index] ^= val;
-            }
-        }
-    }
-    
-    /* use parity to test extra errors */
-    if ((parity & 0xff) != 0)
-        nb_errors = -1;
-
- the_end:
-    kfree(Alpha_to);
-    kfree(Index_of);
-    return nb_errors;
-}
-
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/docprobe.c linux/drivers/mtd/docprobe.c
--- v2.4.5/linux/drivers/mtd/docprobe.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/docprobe.c	Wed Dec 31 16:00:00 1969
@@ -1,283 +0,0 @@
-
-/* Linux driver for Disk-On-Chip devices    */
-/* Probe routines common to all DoC devices */
-/* (c) 1999 Machine Vision Holdings, Inc.   */
-/* Author: David Woodhouse <dwmw2@mvhi.com> */
-/* $Id: docprobe.c,v 1.21 2000/12/03 19:32:34 dwmw2 Exp $ */
-
-
-
-/* DOC_PASSIVE_PROBE:
-   In order to ensure that the BIOS checksum is correct at boot time, and 
-   hence that the onboard BIOS extension gets executed, the DiskOnChip 
-   goes into reset mode when it is read sequentially: all registers 
-   return 0xff until the chip is woken up again by writing to the 
-   DOCControl register. 
-
-   Unfortunately, this means that the probe for the DiskOnChip is unsafe, 
-   because one of the first things it does is write to where it thinks 
-   the DOCControl register should be - which may well be shared memory 
-   for another device. I've had machines which lock up when this is 
-   attempted. Hence the possibility to do a passive probe, which will fail 
-   to detect a chip in reset mode, but is at least guaranteed not to lock
-   the machine.
-
-   If you have this problem, uncomment the following line:
-#define DOC_PASSIVE_PROBE
-*/
-
-
-/* DOC_SINGLE_DRIVER:
-   Millennium driver has been merged into DOC2000 driver.
-
-   The newly-merged driver doesn't appear to work for writing. It's the
-   same with the DiskOnChip 2000 and the Millennium. If you have a 
-   Millennium and you want write support to work, remove the definition
-   of DOC_SINGLE_DRIVER below to use the old doc2001-specific driver.
-
-   Otherwise, it's left on in the hope that it'll annoy someone with
-   a Millennium enough that they go through and work out what the 
-   difference is :)
-*/
-#define DOC_SINGLE_DRIVER
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/types.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/doc2000.h>
-
-/* Where to look for the devices? */
-#ifndef CONFIG_MTD_DOCPROBE_ADDRESS
-#define CONFIG_MTD_DOCPROBE_ADDRESS 0
-#endif
-
-
-static unsigned long doc_config_location = CONFIG_MTD_DOCPROBE_ADDRESS;
-MODULE_PARM(doc_config_location, "l");
-
-
-static unsigned long __initdata doc_locations[] = {
-#if defined (__alpha__) || defined(__i386__)
-#ifdef CONFIG_MTD_DOCPROBE_HIGH
-	0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000, 
-	0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
-	0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000, 
-	0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000, 
-	0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000,
-#else /*  CONFIG_MTD_DOCPROBE_HIGH */
-	0xc8000, 0xca000, 0xcc000, 0xce000, 
-	0xd0000, 0xd2000, 0xd4000, 0xd6000,
-	0xd8000, 0xda000, 0xdc000, 0xde000, 
-	0xe0000, 0xe2000, 0xe4000, 0xe6000, 
-	0xe8000, 0xea000, 0xec000, 0xee000,
-#endif /*  CONFIG_MTD_DOCPROBE_HIGH */
-#elif defined(__ppc__)
-	0xe4000000,
-#else 
-#warning Unknown architecture for DiskOnChip. No default probe locations defined
-#endif
-	0 };
-
-/* doccheck: Probe a given memory window to see if there's a DiskOnChip present */
-
-static inline int __init doccheck(unsigned long potential, unsigned long physadr)
-{
-	unsigned long window=potential;
-	unsigned char tmp, ChipID;
-#ifndef DOC_PASSIVE_PROBE
-	unsigned char tmp2;
-#endif
-
-	/* Routine copied from the Linux DOC driver */
-
-#ifdef CONFIG_MTD_DOCPROBE_55AA
-	/* Check for 0x55 0xAA signature at beginning of window,
-	   this is no longer true once we remove the IPL (for Millennium */
-	if (ReadDOC(window, Sig1) != 0x55 || ReadDOC(window, Sig2) != 0xaa)
-		return 0;
-#endif /* CONFIG_MTD_DOCPROBE_55AA */
-
-#ifndef DOC_PASSIVE_PROBE	
-	/* It's not possible to cleanly detect the DiskOnChip - the
-	 * bootup procedure will put the device into reset mode, and
-	 * it's not possible to talk to it without actually writing
-	 * to the DOCControl register. So we store the current contents
-	 * of the DOCControl register's location, in case we later decide
-	 * that it's not a DiskOnChip, and want to put it back how we
-	 * found it. 
-	 */
-	tmp2 = ReadDOC(window, DOCControl);
-	
-	/* Reset the DiskOnChip ASIC */
-	WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, 
-		 window, DOCControl);
-	WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, 
-		 window, DOCControl);
-	
-	/* Enable the DiskOnChip ASIC */
-	WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, 
-		 window, DOCControl);
-	WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, 
-		 window, DOCControl);
-#endif /* !DOC_PASSIVE_PROBE */	
-
-	ChipID = ReadDOC(window, ChipID);
-  
-	switch (ChipID) {
-	case DOC_ChipID_Doc2k:
-		/* Check the TOGGLE bit in the ECC register */
-		tmp = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT;
-		if ((ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT) != tmp)
-				return ChipID;
-		break;
-		
-	case DOC_ChipID_DocMil:
-		/* Check the TOGGLE bit in the ECC register */
-		tmp = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
-		if ((ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT) != tmp)
-				return ChipID;
-		break;
-		
-	default:
-#ifndef CONFIG_MTD_DOCPROBE_55AA
-		printk(KERN_WARNING "Possible DiskOnChip with unknown ChipID %2.2X found at 0x%lx\n",
-		       ChipID, physadr);
-#endif
-#ifndef DOC_PASSIVE_PROBE
-		/* Put back the contents of the DOCControl register, in case it's not
-		 * actually a DiskOnChip.
-		 */
-		WriteDOC(tmp2, window, DOCControl);
-#endif
-		return 0;
-	}
-
-	printk(KERN_WARNING "DiskOnChip failed TOGGLE test, dropping.\n");
-
-#ifndef DOC_PASSIVE_PROBE
-	/* Put back the contents of the DOCControl register: it's not a DiskOnChip */
-	WriteDOC(tmp2, window, DOCControl);
-#endif
-	return 0;
-}   
-
-
-static void DoC_Probe(unsigned long physadr)
-{
-	unsigned long docptr;
-	struct DiskOnChip *this;
-	struct mtd_info *mtd;
-	int ChipID;
-	char namebuf[15];
-	char *name = namebuf;
-	char *im_funcname = NULL;
-	char *im_modname = NULL;
-	void (*initroutine)(struct mtd_info *) = NULL;
-
-	docptr = (unsigned long)ioremap(physadr, 0x2000);
-	
-	if (!docptr)
-		return;
-	
-	if ((ChipID = doccheck(docptr, physadr))) {
-		
-		mtd = kmalloc(sizeof(struct DiskOnChip) + sizeof(struct mtd_info), GFP_KERNEL);
-
-		if (!mtd) {
-			printk("Cannot allocate memory for data structures. Dropping.\n");
-			iounmap((void *)docptr);
-			return;
-		}
-		
-		this = (struct DiskOnChip *)(&mtd[1]);
-		
-		memset((char *)mtd,0, sizeof(struct mtd_info));
-		memset((char *)this, 0, sizeof(struct DiskOnChip));
-
-		mtd->priv = this;
-		this->virtadr = docptr;
-		this->physadr = physadr;
-		this->ChipID = ChipID;
-		sprintf(namebuf, "with ChipID %2.2X", ChipID);
-
-		switch(ChipID) {
-		case DOC_ChipID_Doc2k:
-			name="2000";
-			im_funcname = "DoC2k_init";
-			im_modname = "doc2000";
-			break;
-			
-		case DOC_ChipID_DocMil:
-			name="Millennium";
-#ifdef DOC_SINGLE_DRIVER
-			im_funcname = "DoC2k_init";
-			im_modname = "doc2000";
-#else
-			im_funcname = "DoCMil_init";
-			im_modname = "doc2001";
-#endif /* DOC_SINGLE_DRIVER */
-			break;
-		}
-
-		if (im_funcname)
-			initroutine = inter_module_get_request(im_funcname, im_modname);
-
-		if (initroutine) {
-			(*initroutine)(mtd);
-			inter_module_put(im_funcname);
-			return;
-		}
-		printk("Cannot find driver for DiskOnChip %s at 0x%lX\n", name, physadr);
-	}
-	iounmap((void *)docptr);
-}
-
-
-/****************************************************************************
- *
- * Module stuff
- *
- ****************************************************************************/
-
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_doc init_module
-#endif
-
-int __init init_doc(void)
-{
-	int i;
-	
-	printk(KERN_NOTICE "M-Systems DiskOnChip driver. (C) 1999 Machine Vision Holdings, Inc.\n");
-#ifdef PRERELEASE
-	printk(KERN_INFO "$Id: docprobe.c,v 1.21 2000/12/03 19:32:34 dwmw2 Exp $\n");
-#endif
-	if (doc_config_location) {
-		printk("Using configured probe address 0x%lx\n", doc_config_location);
-		DoC_Probe(doc_config_location);
-	} else {
-		for (i=0; doc_locations[i]; i++) {
-			DoC_Probe(doc_locations[i]);
-		}
-	}
-	/* So it looks like we've been used and we get unloaded */
-	MOD_INC_USE_COUNT;
-	MOD_DEC_USE_COUNT;
-	return 0;
-	
-}
-
-module_init(init_doc);
-
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/ftl.c linux/drivers/mtd/ftl.c
--- v2.4.5/linux/drivers/mtd/ftl.c	Sat Apr 28 11:27:54 2001
+++ linux/drivers/mtd/ftl.c	Tue Jun 12 10:30:27 2001
@@ -1,10 +1,10 @@
 /* This version ported to the Linux-MTD system by dwmw2@infradead.org
+ * $Id: ftl.c,v 1.35 2001/06/09 00:40:17 dwmw2 Exp $
  *
- * - Based on Id: ftl.c,v 1.21 2000/08/01 13:07:49 dwmw2 Exp
- * - With the Franz Galiana's set_bam_entry fix from v1.23
- * - Perhaps it's about time I made a branch for the 2.4 series.
-
- * Originally based on:
+ * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups
+ *
+ * Based on:
  */
 /*======================================================================
 
@@ -30,8 +30,8 @@
     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 
     Alternatively, the contents of this file may be used under the
-    terms of the GNU General Public License version 2 (the "GPL"), in which
-    case the provisions of the GPL are applicable instead of the
+    terms of the GNU General Public License version 2 (the "GPL"), in
+    which case the provisions of the GPL are applicable instead of the
     above.  If you wish to allow the use of your version of this file
     only under the terms of the GPL and not to allow others to use
     your version of this file under the MPL, indicate your decision
@@ -55,11 +55,6 @@
     contact M-Systems (http://www.m-sys.com) directly.
       
 ======================================================================*/
-#define FTL_DEBUG 5
-#ifdef FTL_DEBUG
-#define DEBUGLVL debug
-#endif
-
 #include <linux/module.h>
 #include <linux/mtd/compatmac.h>
 #include <linux/mtd/mtd.h>
@@ -108,19 +103,16 @@
 /*====================================================================*/
 
 /* Parameters that can be set with 'insmod' */
-
-/* Major device # for FTL device */
 static int shuffle_freq = 50;
-
 MODULE_PARM(shuffle_freq, "i");
 
 /*====================================================================*/
 
+/* Major device # for FTL device */
 #ifndef FTL_MAJOR
 #define FTL_MAJOR	44
 #endif
 
-
 /* Funky stuff for setting up a block device */
 #define MAJOR_NR		FTL_MAJOR
 #define DEVICE_NAME		"ftl"
@@ -135,17 +127,8 @@
 
 #include <linux/blk.h>
 
-#ifdef FTL_DEBUG
-static int debug = FTL_DEBUG;
-MODULE_PARM(debug, "i");
-#endif
-
 /*====================================================================*/
 
-#ifndef FTL_MAJOR
-#define FTL_MAJOR	44
-#endif
-
 /* Maximum number of separate memory devices we'll allow */
 #define MAX_DEV		4
 
@@ -200,7 +183,10 @@
 
 void ftl_freepart(partition_t *part);
 
-static struct mtd_notifier ftl_notifier={ftl_notify_add, ftl_notify_remove, NULL};
+static struct mtd_notifier ftl_notifier = {
+	add:	ftl_notify_add,
+	remove:	ftl_notify_remove,
+};
 
 /* Partition state flags */
 #define FTL_FORMATTED	0x01
@@ -226,7 +212,6 @@
 #endif
     part:		ftl_hd,
     sizes:		ftl_sizes,
-    nr_real:		0
 };
 
 /*====================================================================*/
@@ -274,7 +259,7 @@
     /* Search first megabyte for a valid FTL header */
     for (offset = 0;
 	 offset < max_offset;
-	 offset += part->mtd->erasesize?part->mtd->erasesize:0x2000) {
+	 offset += part->mtd->erasesize ? : 0x2000) {
 
 	ret = part->mtd->read(part->mtd, offset, sizeof(header), &ret, 
 			      (unsigned char *)&header);
@@ -296,7 +281,7 @@
 	return -1;
     }
     if ((1 << header.EraseUnitSize) != part->mtd->erasesize) {
-	printk(KERN_NOTICE "ftl: FTL EraseUnitSize %x != MTD erasesize %lx\n",
+	printk(KERN_NOTICE "ftl: FTL EraseUnitSize %x != MTD erasesize %x\n",
 	       1 << header.EraseUnitSize,part->mtd->erasesize);
 	return -1;
     }
@@ -309,7 +294,7 @@
     erase_unit_header_t header;
     u_int16_t xvalid, xtrans, i;
     u_int blocks, j;
-    int hdr_ok, ret;
+    int hdr_ok, ret = -1;
     ssize_t retval;
     loff_t offset;
 
@@ -318,13 +303,15 @@
 	part->header.NumTransferUnits;
     part->EUNInfo = kmalloc(part->DataUnits * sizeof(struct eun_info_t),
 			    GFP_KERNEL);
-    if (!part->EUNInfo) return -1;
+    if (!part->EUNInfo)
+	    goto out;
     for (i = 0; i < part->DataUnits; i++)
 	part->EUNInfo[i].Offset = 0xffffffff;
     part->XferInfo =
 	kmalloc(part->header.NumTransferUnits * sizeof(struct xfer_info_t),
 		GFP_KERNEL);
-    if (!part->XferInfo) return -1;
+    if (!part->XferInfo)
+	    goto out_EUNInfo;
 
     xvalid = xtrans = 0;
     for (i = 0; i < le16_to_cpu(part->header.NumEraseUnits); i++) {
@@ -334,8 +321,9 @@
 			      (unsigned char *)&header);
 	
 	if (ret) 
-	    return ret;
+	    goto out_XferInfo;
 
+	ret = -1;
 	/* Is this a transfer partition? */
 	hdr_ok = (strcmp(header.DataOrgTuple+3, "FTL100") == 0);
 	if (hdr_ok && (le16_to_cpu(header.LogicalEUN) < part->DataUnits) &&
@@ -348,7 +336,7 @@
 	    if (xtrans == part->header.NumTransferUnits) {
 		printk(KERN_NOTICE "ftl_cs: format error: too many "
 		       "transfer units!\n");
-		return -1;
+		goto out_XferInfo;
 	    }
 	    if (hdr_ok && (le16_to_cpu(header.LogicalEUN) == 0xffff)) {
 		part->XferInfo[xtrans].state = XFER_PREPARED;
@@ -369,18 +357,22 @@
 	(xvalid+xtrans != le16_to_cpu(header.NumEraseUnits))) {
 	printk(KERN_NOTICE "ftl_cs: format error: erase units "
 	       "don't add up!\n");
-	return -1;
+	goto out_XferInfo;
     }
     
     /* Set up virtual page map */
     blocks = le32_to_cpu(header.FormattedSize) >> header.BlockSize;
     part->VirtualBlockMap = vmalloc(blocks * sizeof(u_int32_t));
+    if (!part->VirtualBlockMap)
+	    goto out_XferInfo;
+
     memset(part->VirtualBlockMap, 0xff, blocks * sizeof(u_int32_t));
     part->BlocksPerUnit = (1 << header.EraseUnitSize) >> header.BlockSize;
 
     part->bam_cache = kmalloc(part->BlocksPerUnit * sizeof(u_int32_t),
 			      GFP_KERNEL);
-    if (!part->bam_cache) return -1;
+    if (!part->bam_cache)
+	    goto out_VirtualBlockMap;
 
     part->bam_index = 0xffff;
     part->FreeTotal = 0;
@@ -395,7 +387,7 @@
 			      (unsigned char *)part->bam_cache);
 	
 	if (ret) 
-	    return ret;
+		goto out_bam_cache;
 
 	for (j = 0; j < part->BlocksPerUnit; j++) {
 	    if (BLOCK_FREE(le32_to_cpu(part->bam_cache[j]))) {
@@ -410,8 +402,19 @@
 	}
     }
     
-    return 0;
-    
+    ret = 0;
+    goto out;
+
+out_bam_cache:
+    kfree(part->bam_cache);
+out_VirtualBlockMap:
+    vfree(part->VirtualBlockMap);
+out_XferInfo:
+    kfree(part->XferInfo);
+out_EUNInfo:
+    kfree(part->EUNInfo);
+out:
+    return ret;
 } /* build_maps */
 
 /*======================================================================
@@ -699,7 +702,7 @@
     int queued, ret;
 
     DEBUG(0, "ftl_cs: reclaiming space...\n");
-    DEBUG(4, "NumTransferUnits == %x\n", part->header.NumTransferUnits);
+    DEBUG(3, "NumTransferUnits == %x\n", part->header.NumTransferUnits);
     /* Pick the least erased transfer unit */
     best = 0xffffffff; xfer = 0xffff;
     do {
@@ -707,22 +710,22 @@
 	for (i = 0; i < part->header.NumTransferUnits; i++) {
 	    int n=0;
 	    if (part->XferInfo[i].state == XFER_UNKNOWN) {
-		DEBUG(4,"XferInfo[%d].state == XFER_UNKNOWN\n",i);
+		DEBUG(3,"XferInfo[%d].state == XFER_UNKNOWN\n",i);
 		n=1;
 		erase_xfer(part, i);
 	    }
 	    if (part->XferInfo[i].state == XFER_ERASING) {
-		DEBUG(4,"XferInfo[%d].state == XFER_ERASING\n",i);
+		DEBUG(3,"XferInfo[%d].state == XFER_ERASING\n",i);
 		n=1;
 		queued = 1;
 	    }
 	    else if (part->XferInfo[i].state == XFER_ERASED) {
-		DEBUG(4,"XferInfo[%d].state == XFER_ERASED\n",i);
+		DEBUG(3,"XferInfo[%d].state == XFER_ERASED\n",i);
 		n=1;
 		prepare_xfer(part, i);
 	    }
 	    if (part->XferInfo[i].state == XFER_PREPARED) {
-		DEBUG(4,"XferInfo[%d].state == XFER_PREPARED\n",i);
+		DEBUG(3,"XferInfo[%d].state == XFER_PREPARED\n",i);
 		n=1;
 		if (part->XferInfo[i].EraseCount <= best) {
 		    best = part->XferInfo[i].EraseCount;
@@ -730,7 +733,7 @@
 		}
 	    }
 		if (!n)
-		    DEBUG(4,"XferInfo[%d].state == %x\n",i, part->XferInfo[i].state);
+		    DEBUG(3,"XferInfo[%d].state == %x\n",i, part->XferInfo[i].state);
 
 	}
 	if (xfer == 0xffff) {
@@ -1219,11 +1222,12 @@
     }
     whole = minor & ~(MAX_PART-1);
 
-    for (i = 0; i < MAX_PART; i++) {
+    i = MAX_PART - 1;
+    while (i-- > 0) {
 	if (ftl_hd[whole+i].nr_sects > 0) {
 	    kdev_t rdev = MKDEV(FTL_MAJOR, whole+i);
-	    sync_dev(rdev);
-	    invalidate_buffers(rdev);
+
+	    invalidate_device(rdev, 1);
 	}
 	ftl_hd[whole+i].start_sect = 0;
 	ftl_hd[whole+i].nr_sects = 0;
@@ -1362,7 +1366,8 @@
 		printk(KERN_INFO "ftl_cs: opening %d kb FTL partition\n",
 		       le32_to_cpu(partition->header.FormattedSize) >> 10);
 #endif
-	}
+	} else
+		kfree(partition);
 }
 
 static void ftl_notify_remove(struct mtd_info *mtd)
@@ -1395,13 +1400,10 @@
 		}
 }
 
-
-#if LINUX_VERSION_CODE < 0x20300
-#ifdef MODULE
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
 #define init_ftl init_module
 #define cleanup_ftl cleanup_module
 #endif
-#endif
 
 mod_init_t init_ftl(void)
 {
@@ -1409,6 +1411,8 @@
 
     memset(myparts, 0, sizeof(myparts));
     
+    DEBUG(0, "$Id: ftl.c,v 1.35 2001/06/09 00:40:17 dwmw2 Exp $\n");
+    
     if (register_blkdev(FTL_MAJOR, "ftl", &ftl_blk_fops)) {
 	printk(KERN_NOTICE "ftl_cs: unable to grab major "
 	       "device number!\n");
@@ -1449,7 +1453,5 @@
 	}
 }
 
-#if LINUX_VERSION_CODE > 0x20300
 module_init(init_ftl);
 module_exit(cleanup_ftl);
-#endif
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/jedec.c linux/drivers/mtd/jedec.c
--- v2.4.5/linux/drivers/mtd/jedec.c	Tue Jul  4 10:10:05 2000
+++ linux/drivers/mtd/jedec.c	Wed Dec 31 16:00:00 1969
@@ -1,773 +0,0 @@
-
-/* JEDEC Flash Interface.
- * This is an older type of interface for self programming flash. It is 
- * commonly use in older AMD chips and is obsolete compared with CFI.
- * It is called JEDEC because the JEDEC association distributes the ID codes
- * for the chips.
- *
- * See the AMD flash databook for information on how to operate the interface.
- *
- * This code does not support anything wider than 8 bit flash chips, I am
- * not going to guess how to send commands to them, plus I expect they will
- * all speak CFI..
- *
- * $Id: jedec.c,v 1.1 2000/07/04 07:21:57 jgg Exp $
- */
-
-#include <linux/mtd/jedec.h>
-
-struct mtd_info *jedec_probe(struct map_info *);
-int jedec_probe8(struct map_info *map,unsigned long base,
-		  struct jedec_private *priv);
-int jedec_probe16(struct map_info *map,unsigned long base,
-		  struct jedec_private *priv);
-int jedec_probe32(struct map_info *map,unsigned long base,
-		  struct jedec_private *priv);
-static void jedec_flash_chip_scan(struct jedec_private *priv,unsigned long start,
-			    unsigned long len);
-static int flash_erase(struct mtd_info *mtd, struct erase_info *instr);
-static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
-		       size_t *retlen, const u_char *buf);
-   
-EXPORT_SYMBOL(jedec_probe);
-
-/* Listing of parts and sizes. We need this table to learn the sector
-   size of the chip and the total length */
-static const struct JEDECTable JEDEC_table[] = 
-  {{0x01AD,"AMD Am29F016",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
-   {0x01D5,"AMD Am29F080",1*1024*1024,64*1024,MTD_CAP_NORFLASH},
-   {0x01A4,"AMD Am29F040",512*1024,64*1024,MTD_CAP_NORFLASH},
-   {}};
-
-static void jedec_sync(struct mtd_info *mtd) {};
-static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len, 
-		      size_t *retlen, u_char *buf);
-static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len, 
-			     size_t *retlen, u_char *buf);
-
-/* Probe entry point */
-   struct jedec_private priv;
-   struct mtd_info __MTD;
-struct mtd_info *jedec_probe(struct map_info *map)
-{
-   struct mtd_info *MTD = &__MTD;
-   unsigned long Base;
-   unsigned long SectorSize;
-   unsigned count;
-   unsigned I,Uniq;
-   char Part[200];
-   memset(&priv,0,sizeof(priv));
-   
-   if (map->bank_size == 0)
-      map->bank_size = map->size;
-
-   if (map->size/map->bank_size > MAX_JEDEC_CHIPS)
-   {
-      printk("mtd: Increase MAX_JEDEC_CHIPS, too many banks.\n");
-      return 0;
-   }
-   
-   for (Base = 0; Base < map->size; Base += map->bank_size)
-   {
-      // Perhaps zero could designate all tests?
-      if (map->bus_width == 0)
-	 map->bus_width = 8;
-      
-      if (map->bus_width == 8)
-	 jedec_probe8(map,Base,&priv);
-      if (map->bus_width == 16)
-	 jedec_probe16(map,Base,&priv);
-      if (map->bus_width == 32)
-	 jedec_probe32(map,Base,&priv);
-   }
-   
-   // Get the biggest sector size
-   SectorSize = 0;
-   for (I = 0; priv.chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
-   {
-      if (priv.chips[I].sectorsize > SectorSize)
-	 SectorSize = priv.chips[I].sectorsize;
-   }
-   
-   // Quickly ensure that the other sector sizes are factors of the largest
-   for (I = 0; priv.chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
-   {
-      if ((SectorSize/priv.chips[I].sectorsize)*priv.chips[I].sectorsize != SectorSize)
-      {
-	 printk("mtd: Failed. Device has incompatible mixed sector sizes\n");
-	 return 0;
-      }      
-   }
-   
-   /* Generate a part name that includes the number of different chips and
-      other configuration information */
-   count = 1;
-   strncpy(Part,map->name,sizeof(Part)-10);
-   Part[sizeof(Part)-11] = 0;
-   strcat(Part," ");
-   Uniq = 0;
-   for (I = 0; priv.chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
-   {
-      const struct JEDECTable *JEDEC;
-      
-      if (priv.chips[I+1].jedec == priv.chips[I].jedec)
-      {
-	 count++;
-	 continue;
-      }
-      
-      // Locate the chip in the jedec table
-      JEDEC = jedec_idtoinf(priv.chips[I].jedec >> 8,priv.chips[I].jedec);
-      if (JEDEC == 0)
-      {
-	 printk("mtd: Internal Error, JEDEC not set\n");
-	 return 0;
-      }
-      
-      if (Uniq != 0)
-	 strcat(Part,",");
-      Uniq++;
-      
-      if (count != 1)
-	 sprintf(Part+strlen(Part),"%x*[%s]",count,JEDEC->name);
-      else
-	 sprintf(Part+strlen(Part),"%s",JEDEC->name);
-      if (strlen(Part) > sizeof(Part)*2/3)
-	 break;
-      count = 1;
-   }   
-
-   /* Determine if the chips are organized in a linear fashion, or if there
-      are empty banks. Note, the last bank does not count here, only the
-      first banks are important. Holes on non-bank boundaries can not exist
-      due to the way the detection algorithm works. */
-   if (priv.size < map->bank_size)
-      map->bank_size = priv.size;
-   priv.is_banked = 0;
-   for (I = 0; I != priv.size/map->bank_size - 1; I++)
-   {
-      if (priv.bank_fill[I] != map->bank_size)
-	 priv.is_banked = 1;
-      
-      /* This even could be eliminated, but new de-optimized read/write
-         functions have to be written */
-      if (priv.bank_fill[I] != priv.bank_fill[0])
-      {
-	 printk("mtd: Failed. Cannot handle unsymetric banking\n");
-	 return 0;
-      }      
-   }
-   if (priv.is_banked == 1)
-      strcat(Part,", banked");
-
-   xprintf("Part: '%s'\n",Part);
-   
-   memset(MTD,0,sizeof(*MTD));
-   strncpy(MTD->name,Part,sizeof(MTD->name));
-   MTD->name[sizeof(MTD->name)-1] = 0;
-   MTD->type = MTD_NORFLASH;
-   MTD->flags = MTD_CAP_NORFLASH;
-   MTD->erasesize = SectorSize*(map->bus_width/8);
-   MTD->size = priv.size;
-   //MTD->module = THIS_MODULE; // ? Maybe this should be the low level module?
-   MTD->erase = flash_erase;
-   if (priv.is_banked == 1)
-      MTD->read = jedec_read_banked;
-   else
-      MTD->read = jedec_read;
-   MTD->write = flash_write;
-   MTD->sync = jedec_sync;
-   MTD->priv = map;
-   map->fldrv_priv = &priv;
-   
-   return MTD;
-}
-
-/* Helper for the JEDEC function, JEDEC numbers all have odd parity */
-static int checkparity(u_char C)
-{
-   u_char parity = 0;
-   while (C != 0)
-   {
-      parity ^= C & 1;
-      C >>= 1;
-   }
-
-   return parity == 1;
-}
-
-
-/* Take an array of JEDEC numbers that represent interleved flash chips
-   and process them. Check to make sure they are good JEDEC numbers, look
-   them up and then add them to the chip list */   
-int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
-		  unsigned long base,struct jedec_private *priv)
-{
-   unsigned I,J;
-   unsigned long Size;
-   unsigned long SectorSize;
-   const struct JEDECTable *JEDEC;
-
-   // Test #2 JEDEC numbers exhibit odd parity
-   for (I = 0; I != Count; I++)
-   {
-      if (checkparity(Mfg[I]) == 0 || checkparity(Id[I]) == 0)
-	 return 0;
-   }
-   
-   // Finally, just make sure all the chip sizes are the same
-   JEDEC = jedec_idtoinf(Mfg[0],Id[0]);
-   
-   if (JEDEC == 0)
-   {
-      printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]);
-      return 0;
-   }
-   
-   Size = JEDEC->size;
-   SectorSize = JEDEC->sectorsize;
-   for (I = 0; I != Count; I++)
-   {
-      JEDEC = jedec_idtoinf(Mfg[0],Id[0]);
-      if (JEDEC == 0)
-      {
-	 printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]);
-	 return 0;
-      }
-
-      if (Size != JEDEC->size || SectorSize != JEDEC->sectorsize)
-      {
-	 printk("mtd: Failed. Interleved flash does not have matching characteristics\n");
-	 return 0;
-      }      
-   }
-
-   // Load the Chips
-   for (I = 0; I != MAX_JEDEC_CHIPS; I++)
-   {
-      if (priv->chips[I].jedec == 0)
-	 break;
-   }
-
-   if (I + Count > MAX_JEDEC_CHIPS)
-   {
-      printk("mtd: Device has too many chips. Increase MAX_JEDEC_CHIPS\n");
-      return 0;
-   }      
-   
-   // Add them to the table
-   for (J = 0; J != Count; J++)
-   {
-      unsigned long Bank;
-	 
-      JEDEC = jedec_idtoinf(Mfg[J],Id[J]);
-      priv->chips[I].jedec = (Mfg[J] << 8) | Id[J];
-      priv->chips[I].size = JEDEC->size;
-      priv->chips[I].sectorsize = JEDEC->sectorsize;
-      priv->chips[I].base = base + J;
-      priv->chips[I].datashift = J*8;
-      priv->chips[I].capabilities = JEDEC->capabilities;
-      priv->chips[I].offset = priv->size + J;
-
-      // log2 n :|
-      priv->chips[I].addrshift = 0;
-      for (Bank = Count; Bank != 1; Bank >>= 1, priv->chips[I].addrshift++);
-      
-      // Determine how filled this bank is.
-      Bank = base & (~(map->bank_size-1));
-      if (priv->bank_fill[Bank/map->bank_size] < base + 
-	  (JEDEC->size << priv->chips[I].addrshift) - Bank)
-	 priv->bank_fill[Bank/map->bank_size] =  base + (JEDEC->size << priv->chips[I].addrshift) - Bank;
-      I++;
-   }
-
-   priv->size += priv->chips[I-1].size*Count;
-	 
-   return priv->chips[I-1].size;
-}
-
-/* Lookup the chip information from the JEDEC ID table. */
-const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id)
-{
-   __u16 Id = (mfr << 8) | id;
-   unsigned long I = 0;
-   for (I = 0; JEDEC_table[I].jedec != 0; I++)
-      if (JEDEC_table[I].jedec == Id)
-	 return JEDEC_table + I;
-   return 0;
-}
-
-// Look for flash using an 8 bit bus interface
-int jedec_probe8(struct map_info *map,unsigned long base,
-		  struct jedec_private *priv)
-{ 
-   return 0;
-}
-
-// Look for flash using a 16 bit bus interface (ie 2 8-bit chips)
-int jedec_probe16(struct map_info *map,unsigned long base,
-		  struct jedec_private *priv)
-{
-   return 0;
-}
-
-// Look for flash using a 32 bit bus interface (ie 4 8-bit chips)
-int jedec_probe32(struct map_info *map,unsigned long base,
-		  struct jedec_private *priv)
-{
-   #define flread(x) map->read32(map,base+((x)<<2))
-   #define flwrite(v,x) map->write32(map,v,base+((x)<<2))
-
-   const unsigned long AutoSel1 = 0xAAAAAAAA;
-   const unsigned long AutoSel2 = 0x55555555;
-   const unsigned long AutoSel3 = 0x90909090;
-   const unsigned long Reset = 0x90909090;
-   __u32 OldVal;
-   __u8 Mfg[4];
-   __u8 Id[4];
-   unsigned I;
-   unsigned long Size;
-
-   // Wait for any write/erase operation to settle
-   OldVal = flread(base);
-   for (I = 0; OldVal != flread(base) && I < 10000; I++)
-      OldVal = flread(base);
-   
-   // Reset the chip
-   flwrite(Reset,0x555); 
-   
-   // Send the sequence
-   flwrite(AutoSel1,0x555);
-   flwrite(AutoSel2,0x2AA);
-   flwrite(AutoSel3,0x555);
-   
-   // Test #1, JEDEC numbers are readable from 0x??00/0x??01
-   if (flread(0) != flread(0x100) || 
-       flread(1) != flread(0x101))
-   {
-      flwrite(Reset,0x555);
-      return 0;
-   }
-
-   // Split up the JEDEC numbers
-   OldVal = flread(0);
-   for (I = 0; I != 4; I++)
-      Mfg[I] = (OldVal >> (I*8));
-   OldVal = flread(1);
-   for (I = 0; I != 4; I++)
-      Id[I] = (OldVal >> (I*8));
-      
-   Size = handle_jedecs(map,Mfg,Id,4,base,priv);
-   if (Size == 0)
-   {
-      flwrite(Reset,0x555);
-      return 0;
-   }
-   
-   /* Check if there is address wrap around within a single bank, if this
-      returns JEDEC numbers then we assume that it is wrap around. Notice
-      we call this routine with the JEDEC return still enabled, if two or
-      more flashes have a truncated address space the probe test will still
-      work */
-   if (base + Size+0x555 < map->size &&
-       base + Size+0x555 < (base & (~(map->bank_size-1))) + map->bank_size)
-   {
-      if (flread(base+Size) != flread(base+Size + 0x100) ||
-	  flread(base+Size + 1) != flread(base+Size + 0x101))
-      {
-	 jedec_probe32(map,base+Size,priv);
-      }
-   }
-
-   // Reset.
-   flwrite(0xF0F0F0F0,0x555);
-   
-   return 1;
-   
-   #undef flread
-   #undef flwrite
-}
-
-/* Linear read. */
-static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len, 
-		      size_t *retlen, u_char *buf)
-{
-   struct map_info *map = (struct map_info *)mtd->priv;
-   
-   map->copy_from(map, buf, from, len);
-   *retlen = len;
-   return 0;   
-}
-
-/* Banked read. Take special care to jump past the holes in the bank
-   mapping. This version assumes symetry in the holes.. */
-static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len, 
-			     size_t *retlen, u_char *buf)
-{
-   struct map_info *map = (struct map_info *)mtd->priv;
-   struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv;
-
-   *retlen = 0;
-   while (len > 0)
-   {
-      // Determine what bank and offset into that bank the first byte is
-      unsigned long bank = from & (~(priv->bank_fill[0]-1));
-      unsigned long offset = from & (priv->bank_fill[0]-1);
-      unsigned long get = len;
-      if (priv->bank_fill[0] - offset < len)
-	 get = priv->bank_fill[0] - offset;
-
-      bank /= priv->bank_fill[0];      
-      map->copy_from(map,buf + *retlen,bank*map->bank_size + offset,get);
-      
-      len -= get;
-      *retlen += get;
-      from += get;
-   }   
-   return 0;   
-}
-
-/* Pass the flags value that the flash return before it re-entered read 
-   mode. */
-static void jedec_flash_failed(unsigned char code)
-{
-   /* Bit 5 being high indicates that there was an internal device
-      failure, erasure time limits exceeded or something */
-   if ((code & (1 << 5)) != 0)
-   {
-      printk("mtd: Internal Flash failure\n");
-      return;
-   }
-   printk("mtd: Programming didn't take\n");
-}
-
-/* This uses the erasure function described in the AMD Flash Handbook, 
-   it will work for flashes with a fixed sector size only. Flashes with
-   a selection of sector sizes (ie the AMD Am29F800B) will need a different
-   routine. This routine tries to parallize erasing multiple chips/sectors 
-   where possible */
-static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
-{
-   // Does IO to the currently selected chip
-   #define flread(x) map->read8(map,chip->base+((x)<<chip->addrshift))
-   #define flwrite(v,x) map->write8(map,v,chip->base+((x)<<chip->addrshift))
-   
-   unsigned long Time = 0;
-   unsigned long NoTime = 0;
-   unsigned long start = instr->addr, len = instr->len;
-   unsigned int I;
-   struct map_info *map = (struct map_info *)mtd->priv;
-   struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv;
-
-   // Verify the arguments..
-   if (start + len > mtd->size ||
-       (start % mtd->erasesize) != 0 ||
-       (len % mtd->erasesize) != 0 ||
-       (len/mtd->erasesize) == 0)
-      return -EINVAL;
-   
-   jedec_flash_chip_scan(priv,start,len);
-
-   // Start the erase sequence on each chip
-   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
-   {
-      unsigned long off;
-      struct jedec_flash_chip *chip = priv->chips + I;
-      
-      if (chip->length == 0)
-	 continue;
-      
-      // Send the erase setup code
-      xprintf("Erase: ");
-      puth(chip->start); putc(' ');
-      puth(chip->base); putc(' ');
-      puth(chip->length); putc(' ');
-      puth(chip->sectorsize); putc('\n');
-      
-      if (chip->start + chip->length > chip->size)
-      {
-	 xprintf("DIE\n");
-	 return -EIO;
-      }     
-      
-      flwrite(0xF0,chip->start + 0x555);
-      flwrite(0xAA,chip->start + 0x555);
-      flwrite(0x55,chip->start + 0x2AA);
-      flwrite(0x80,chip->start + 0x555);
-      flwrite(0xAA,chip->start + 0x555);
-      flwrite(0x55,chip->start + 0x2AA);
-
-      // Use chip erase if possible
-      if (chip->start == 0 && chip->length == chip->size)
-      {
-	 flwrite(0x10,0x555);
-	 continue;
-      }
-            
-      /* Once we start selecting the erase sectors the delay between each 
-         command must not exceed 50us or it will immediately start erasing 
-         and ignore the other sectors */
-/*    how do you portably turn off interrupts?
-      save_flags(flags);
-      cli();*/
-      for (off = 0; off < chip->length; off += chip->sectorsize)
-      {
-	 // Check to make sure we didn't timeout
-	 flwrite(0x30,chip->start + off);
-	 if (off == 0)
-	    continue;
-	 if ((flread(chip->start + off) & (1 << 3)) != 0)
-	 {
-	    printk("mtd: Ack! We timed out the erase timer!\n");
-	    return -EIO;
-	 }       	 
-      }
-//      restore_flags(flags);
-   }   
-
-   /* We could split this into a timer routine and return early, performing
-      background erasure.. Maybe later if the need warrents */
-
-   /* Poll the flash for erasure completion, specs say this can take as long
-      as 480 seconds to do all the sectors (for a 2 meg flash). 
-      Erasure time is dependant on chip age, temp and wear.. */
-   
-   /* This being a generic routine assumes a 32 bit bus. It does read32s
-      and bundles interleved chips into the same grouping. This will work 
-      for all bus widths */
-   Time = 0;
-   NoTime = 0;
-   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
-   {
-      struct jedec_flash_chip *chip = priv->chips + I;
-      unsigned long off = 0;
-      unsigned todo[4] = {0,0,0,0};
-      unsigned todo_left = 0;
-      unsigned J;
-      
-      if (chip->length == 0)
-	 continue;
-
-      /* Find all chips in this data line, realistically this is all 
-         or nothing up to the interleve count */
-      for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++)
-      {
-	 if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) == 
-	     (chip->base & (~((1<<chip->addrshift)-1))))
-	 {
-	    todo_left++;
-	    todo[priv->chips[J].base & ((1<<chip->addrshift)-1)] = 1;
-	 }	 
-      }
-
-      xprintf("todo: %x %x %x %x\n",(short)todo[0],(short)todo[1],
-	      (short)todo[2],(short)todo[3]);
-      
-      while (1)
-      {
-	 __u32 Last[4];
-	 unsigned long Count = 0;
-	 
-	 /* During erase bit 7 is held low and bit 6 toggles, we watch this,
-	    should it stop toggling or go high then the erase is completed,
-  	    or this is not really flash ;> */
-	 Last[0] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
-	 Last[1] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
-	 Last[2] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
-	 Count = 3;
-	 while (todo_left != 0)
-	 {
-	    for (J = 0; J != 4; J++)
-	    {
-	       __u8 Byte1 = (Last[(Count-1)%4] >> (J*8)) & 0xFF;
-	       __u8 Byte2 = (Last[(Count-2)%4] >> (J*8)) & 0xFF;
-	       __u8 Byte3 = (Last[(Count-3)%4] >> (J*8)) & 0xFF;
-	       if (todo[J] == 0)
-		  continue;
-	       
-	       if ((Byte1 & (1 << 7)) == 0 && Byte1 != Byte2)
-	       {
-//		  printk("Check %x %x %x\n",(short)J,(short)Byte1,(short)Byte2);
-		  continue;
-	       }
-	       
-	       if (Byte1 == Byte2)
-	       {
-		  jedec_flash_failed(Byte3);
-		  return -EIO;
-	       }
-	       
-	       todo[J] = 0;
-	       todo_left--;
-	    }
-	    
-/*	    if (NoTime == 0)
-	       Time += HZ/10 - schedule_timeout(HZ/10);*/
-	    NoTime = 0;
-	    
-	    Last[Count % 4] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
-	    Count++;
-	    
-	    putc('.');
-	    
-/*	    // Count time, max of 15s per sector (according to AMD)
-	    if (Time > 15*len/mtd->erasesize*HZ)
-	    {
-	       printk("mtd: Flash Erase Timed out\n");
-	       return -EIO;
-	    }	    */
-	 }
-	 	 
-	 puts("out\n");
-	    
-	 // Skip to the next chip if we used chip erase
-	 if (chip->length == chip->size)
-	    off = chip->size;
-	 else
-	    off += chip->sectorsize;
-	 
-	 if (off >= chip->length)
-	    break;
-	 NoTime = 1;
-      }
-      
-      for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++)
-      {
-	 if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
-	     (chip->base & (~((1<<chip->addrshift)-1))))
-	    priv->chips[J].length = 0;
-      }      
-   }
-       	    
-   puts("done\n");
-   return 0;
-   
-   #undef flread
-   #undef flwrite
-}
-
-/* This is the simple flash writing function. It writes to every byte, in
-   sequence. It takes care of how to properly address the flash if
-   the flash is interleved. It can only be used if all the chips in the 
-   array are identical!*/
-static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
-		       size_t *retlen, const u_char *buf)
-{
-   /* Does IO to the currently selected chip. It takes the bank addressing
-      base (which is divisable by the chip size) adds the necesary lower bits
-      of addrshift (interleve index) and then adds the control register index. */
-   #define flread(x) map->read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
-   #define flwrite(v,x) map->write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
-   
-   struct map_info *map = (struct map_info *)mtd->priv;
-   struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv;
-   unsigned long base;
-   unsigned long off;
-   
-   if (start + len > mtd->size)
-      return -EIO;
-   
-   puts("Here");
-   
-   while (len != 0)
-   {
-      struct jedec_flash_chip *chip = priv->chips;
-      unsigned long bank;
-      unsigned long boffset;
-	 
-      // Compute the base of the flash.
-      off = start % (chip->size << chip->addrshift);
-      base = start - off;
-
-      // Perform banked addressing translation.
-      bank = base & (~(priv->bank_fill[0]-1));
-      boffset = base & (priv->bank_fill[0]-1);
-      bank = (bank/priv->bank_fill[0])*map->bank_size;
-      base = bank + boffset;
-      
-      xprintf("Flasing %X %X %X\n",base,chip->size,len);
-      
-      // Loop over this page
-      for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++)
-      {
-	 unsigned char oldbyte = map->read8(map,base+off);
-	 unsigned char Last[4];
-	 unsigned long Count = 0;
-
-//	 putc('.');
-	 
-	 if (oldbyte == *buf)
-	    continue;
-	 if (((~oldbyte) & *buf) != 0)
-	    printk("mtd: warn: Trying to set a 0 to a 1\n");
-	     
-	 // Write
-	 flwrite(0xAA,0x555);
-	 flwrite(0x55,0x2AA);
-	 flwrite(0xA0,0x555);
-	 map->write8(map,*buf,base + off);
-	 Last[0] = map->read8(map,base + off);
-	 Last[1] = map->read8(map,base + off);
-	 Last[2] = map->read8(map,base + off);
-	 
-	 /* Wait for the flash to finish the operation. We store the last 4
-	    status bytes that have been retrieved so we can determine why
-	    it failed. The toggle bits keep toggling when there is a 
-	    failure */
-	 for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] &&
-	      Count < 10000; Count++)
-	    Last[Count % 4] = map->read8(map,base + off);
-	 if (Last[(Count - 1) % 4] != *buf)
-	 {
-	    jedec_flash_failed(Last[(Count - 3) % 4]);
-	    return -EIO;
-	 }	 
-      }
-   }
-   *retlen = len;
-   return 0;
-}
-
-/* This is used to enhance the speed of the erase routine,
-   when things are being done to multiple chips it is possible to
-   parallize the operations, particularly full memory erases of multi
-   chip memories benifit */
-static void jedec_flash_chip_scan(struct jedec_private *priv,unsigned long start,
-		     unsigned long len)
-{
-   unsigned int I;
-
-   // Zero the records
-   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
-      priv->chips[I].start = priv->chips[I].length = 0;
-   
-   // Intersect the region with each chip
-   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
-   {
-      struct jedec_flash_chip *chip = priv->chips + I;
-      unsigned long ByteStart;
-      unsigned long ChipEndByte = chip->offset + (chip->size << chip->addrshift);
-      
-      // End is before this chip or the start is after it
-      if (start+len < chip->offset ||
-	  ChipEndByte - (1 << chip->addrshift) < start)
-	 continue;
-      
-      if (start < chip->offset)
-      {
-	 ByteStart = chip->offset;
-	 chip->start = 0;
-      }      
-      else
-      {
-	 chip->start = (start - chip->offset + (1 << chip->addrshift)-1) >> chip->addrshift;
-	 ByteStart = start;
-      }
-
-      if (start + len >= ChipEndByte)
-	 chip->length = (ChipEndByte - ByteStart) >> chip->addrshift;
-      else
-	 chip->length = (start + len - ByteStart + (1 << chip->addrshift)-1) >> chip->addrshift;
-   }
-}
-									/*}}}*/
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/map_ram.c linux/drivers/mtd/map_ram.c
--- v2.4.5/linux/drivers/mtd/map_ram.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/map_ram.c	Wed Dec 31 16:00:00 1969
@@ -1,137 +0,0 @@
-/*
- * Common code to handle map devices which are simple RAM
- * (C) 2000 Red Hat. GPL'd.
- * $Id: map_ram.c,v 1.7 2000/12/10 01:39:13 dwmw2 Exp $
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <asm/io.h>
-#include <asm/byteorder.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-
-#include <linux/mtd/map.h>
-
-
-static int mapram_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
-static int mapram_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
-static int mapram_erase (struct mtd_info *, struct erase_info *);
-static void mapram_nop (struct mtd_info *);
-
-static const char im_name[] = "map_ram_probe";
-
-/* This routine is made available to other mtd code via
- * inter_module_register.  It must only be accessed through
- * inter_module_get which will bump the use count of this module.  The
- * addresses passed back in mtd are valid as long as the use count of
- * this module is non-zero, i.e. between inter_module_get and
- * inter_module_put.  Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
- */
-
-static struct mtd_info *map_ram_probe(struct map_info *map)
-{
-	struct mtd_info *mtd;
-
-	/* Check the first byte is RAM */
-	map->write8(map, 0x55, 0);
-	if (map->read8(map, 0) != 0x55)
-		return NULL;
-
-	map->write8(map, 0xAA, 0);
-	if (map->read8(map, 0) != 0xAA)
-		return NULL;
-
-	/* Check the last byte is RAM */
-	map->write8(map, 0x55, map->size-1);
-	if (map->read8(map, map->size-1) != 0x55)
-		return NULL;
-
-	map->write8(map, 0xAA, map->size-1);
-	if (map->read8(map, map->size-1) != 0xAA)
-		return NULL;
-
-	/* OK. It seems to be RAM. */
-
-	mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
-	if (!mtd)
-		return NULL;
-
-	memset(mtd, 0, sizeof(*mtd));
-
-	map->im_name = im_name;
-	map->fldrv_destroy = mapram_nop;
-	mtd->priv = map;
-	mtd->name = map->name;
-	mtd->type = MTD_RAM;
-	mtd->erasesize = 0x10000;
-	mtd->size = map->size;
-	mtd->erase = mapram_erase;
-	mtd->read = mapram_read;
-	mtd->write = mapram_write;
-	mtd->sync = mapram_nop;
-	mtd->flags = MTD_CAP_RAM | MTD_VOLATILE;
-	mtd->erasesize = PAGE_SIZE;
-
-	return mtd;
-}
-
-
-static int mapram_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
-{
-	struct map_info *map = (struct map_info *)mtd->priv;
-
-	map->copy_from(map, buf, from, len);
-	*retlen = len;
-	return 0;
-}
-
-static int mapram_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
-{
-	struct map_info *map = (struct map_info *)mtd->priv;
-
-	map->copy_to(map, to, buf, len);
-	*retlen = len;
-	return 0;
-}
-
-static int mapram_erase (struct mtd_info *mtd, struct erase_info *instr)
-{
-	/* Yeah, it's inefficient. Who cares? It's faster than a _real_
-	   flash erase. */
-	struct map_info *map = (struct map_info *)mtd->priv;
-	unsigned long i;
-
-	for (i=0; i<instr->len; i++)
-		map->write8(map, 0xFF, instr->addr + i);
-
-	if (instr->callback)
-		instr->callback(instr);
-
-	return 0;
-}
-
-static void mapram_nop(struct mtd_info *mtd)
-{
-	/* Nothing to see here */
-}
-
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define map_ram_init init_module
-#define map_ram_exit cleanup_module
-#endif
-
-static int __init map_ram_init(void)
-{
-	inter_module_register(im_name, THIS_MODULE, &map_ram_probe);
-	return 0;
-}
-
-static void __exit map_ram_exit(void)
-{
-	inter_module_unregister(im_name);
-}
-
-module_init(map_ram_init);
-module_exit(map_ram_exit);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/map_rom.c linux/drivers/mtd/map_rom.c
--- v2.4.5/linux/drivers/mtd/map_rom.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/map_rom.c	Wed Dec 31 16:00:00 1969
@@ -1,94 +0,0 @@
-/*
- * Common code to handle map devices which are simple ROM
- * (C) 2000 Red Hat. GPL'd.
- * $Id: map_rom.c,v 1.10 2000/12/10 01:39:13 dwmw2 Exp $
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <asm/io.h>
-#include <asm/byteorder.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-
-#include <linux/mtd/map.h>
-
-static int maprom_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
-static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
-static void maprom_nop (struct mtd_info *);
-
-static const char im_name[] = "map_rom_probe";
-
-/* This routine is made available to other mtd code via
- * inter_module_register.  It must only be accessed through
- * inter_module_get which will bump the use count of this module.  The
- * addresses passed back in mtd are valid as long as the use count of
- * this module is non-zero, i.e. between inter_module_get and
- * inter_module_put.  Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
- */
-
-struct mtd_info *map_rom_probe(struct map_info *map)
-{
-	struct mtd_info *mtd;
-
-	mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
-	if (!mtd)
-		return NULL;
-
-	memset(mtd, 0, sizeof(*mtd));
-
-	map->im_name = im_name;
-	map->fldrv_destroy = maprom_nop;
-	mtd->priv = map;
-	mtd->name = map->name;
-	mtd->type = MTD_ROM;
-	mtd->size = map->size;
-	mtd->read = maprom_read;
-	mtd->write = maprom_write;
-	mtd->sync = maprom_nop;
-	mtd->flags = MTD_CAP_ROM;
-	mtd->erasesize = 131072;
-
-	return mtd;
-}
-
-
-static int maprom_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
-{
-	struct map_info *map = (struct map_info *)mtd->priv;
-
-	map->copy_from(map, buf, from, len);
-	*retlen = len;
-	return 0;
-}
-
-static void maprom_nop(struct mtd_info *mtd)
-{
-	/* Nothing to see here */
-}
-
-static int maprom_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
-{
-	printk(KERN_NOTICE "maprom_write called\n");
-	return -EIO;
-}
-
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define map_rom_init init_module
-#define map_rom_exit cleanup_module
-#endif
-
-static int __init map_rom_init(void)
-{
-	inter_module_register(im_name, THIS_MODULE, &map_rom_probe);
-	return 0;
-}
-
-static void __exit map_rom_exit(void)
-{
-	inter_module_unregister(im_name);
-}
-
-module_init(map_rom_init);
-module_exit(map_rom_exit);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/maps/Config.in linux/drivers/mtd/maps/Config.in
--- v2.4.5/linux/drivers/mtd/maps/Config.in	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/Config.in	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,41 @@
+# drivers/mtd/maps/Config.in
+
+# $Id: Config.in,v 1.9.2.1 2001/06/09 19:43:49 dwmw2 Exp $
+
+mainmenu_option next_comment
+
+comment 'Mapping drivers for chip access'
+
+dep_tristate '  CFI Flash device in physical memory map' CONFIG_MTD_PHYSMAP $CONFIG_MTD_CFI
+if [ "$CONFIG_MTD_PHYSMAP" = "y" -o "$CONFIG_MTD_PHYSMAP" = "m" ]; then
+   hex '    Physical start address of flash mapping' CONFIG_MTD_PHYSMAP_START 0x8000000
+   hex '    Physical length of flash mapping' CONFIG_MTD_PHYSMAP_LEN 0x4000000
+   int '    Bus width in octets' CONFIG_MTD_PHYSMAP_BUSWIDTH 2
+fi
+
+dep_tristate '  Sun Microsystems userflash support' CONFIG_MTD_SUN_UFLASH $CONFIG_SPARC64
+dep_tristate '  CFI Flash device mapped on Nora' CONFIG_MTD_NORA $CONFIG_MTD_CFI
+dep_tristate '  CFI Flash device mapped on Photron PNC-2000' CONFIG_MTD_PNC2000 $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS
+dep_tristate '  CFI Flash device mapped on RPX Lite or CLLF' CONFIG_MTD_RPXLITE $CONFIG_MTD_CFI 
+dep_tristate '  CFI Flash device mapped on AMD SC520 CDP' CONFIG_MTD_SC520CDP $CONFIG_MTD_CFI
+dep_tristate '  CFI Flash device mapped on AMD NetSc520'  CONFIG_MTD_NETSC520 $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS
+dep_tristate '  CFI Flash device mapped on Arcom SBC-GXx boards' CONFIG_MTD_SBC_GXX $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS
+dep_tristate '  CFI Flash device mapped on Arcom ELAN-104NC' CONFIG_MTD_ELAN_104NC $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS
+dep_tristate '  CFI Flash device mapped on StrongARM SA11x0' CONFIG_MTD_SA1100 $CONFIG_MTD_CFI $CONFIG_ARCH_SA1100 $CONFIG_MTD_PARTITIONS
+   dep_bool '    Support for RedBoot partition tables on SA11x0' CONFIG_MTD_SA1100_REDBOOT_PARTITIONS $CONFIG_MTD_SA1100 $CONFIG_MTD_REDBOOT_PARTS
+   dep_bool '    Support for Compaq bootldr partition tables on SA11x0' CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS $CONFIG_MTD_SA1100 $CONFIG_MTD_BOOTLDR_PARTS
+dep_tristate '  CFI Flash device mapped on DC21285 Footbridge' CONFIG_MTD_DC21285 $CONFIG_MTD_CFI $CONFIG_ARCH_FOOTBRIDGE $CONFIG_MTD_PARTITIONS
+dep_tristate '  CFI Flash device mapped on the XScale IQ80310 board' CONFIG_MTD_IQ80310 $CONFIG_MTD_CFI $CONFIG_XSCALE_IQ80310
+dep_tristate '  CFI Flash device mapped on D-Box2' CONFIG_MTD_DBOX2 $CONFIG_MTD_CFI_INTELSTD $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_CFI_AMDSTD
+dep_tristate '  Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board' CONFIG_MTD_CSTM_MIPS_IXX $CONFIG_MTD_CFI $CONFIG_MTD_JEDEC $CONFIG_MTD_PARTITIONS 
+if [ "$CONFIG_MTD_CSTM_MIPS_IXX" = "y" -o "$CONFIG_MTD_CSTM_MIPS_IXX" = "m" ]; then
+   hex '    Physical start address of flash mapping' CONFIG_MTD_CSTM_MIPS_IXX_START 0x8000000
+   hex '    Physical length of flash mapping' CONFIG_MTD_CSTM_MIPS_IXX_LEN 0x4000000
+   int '    Bus width in octets' CONFIG_MTD_CSTM_MIPS_IXX_BUSWIDTH 2
+fi
+dep_tristate '  CFI Flash device mapping on FlagaDM' CONFIG_MTD_CFI_FLAGADM $CONFIG_MTD_CFI
+dep_tristate '  JEDEC Flash device mapped on Mixcom piggyback card' CONFIG_MTD_MIXMEM $CONFIG_MTD_JEDEC
+dep_tristate '  JEDEC Flash device mapped on Octagon 5066 SBC' CONFIG_MTD_OCTAGON $CONFIG_MTD_JEDEC
+dep_tristate '  JEDEC Flash device mapped on Tempustech VMAX SBC301' CONFIG_MTD_VMAX $CONFIG_MTD_JEDEC
+dep_tristate '  Momenco Ocelot boot flash device' CONFIG_MTD_OCELOT $CONFIG_MOMENCO_OCELOT
+endmenu
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/maps/Makefile linux/drivers/mtd/maps/Makefile
--- v2.4.5/linux/drivers/mtd/maps/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/Makefile	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,29 @@
+#
+# linux/drivers/maps/Makefile
+#
+# $Id: Makefile,v 1.9.2.1 2001/06/09 19:43:49 dwmw2 Exp $
+
+O_TARGET	:= mapslink.o
+
+# Chip mappings
+
+obj-$(CONFIG_MTD_CFI_FLAGADM)	+= cfi_flagadm.o
+obj-$(CONFIG_MTD_CSTM_MIPS_IXX) += cstm_mips_ixx.o
+obj-$(CONFIG_MTD_DC21285)       += dc21285.o
+obj-$(CONFIG_MTD_ELAN_104NC)    += elan-104nc.o
+obj-$(CONFIG_MTD_IQ80310)	+= iq80310.o
+obj-$(CONFIG_MTD_NORA)		+= nora.o
+obj-$(CONFIG_MTD_OCTAGON)	+= octagon-5066.o
+obj-$(CONFIG_MTD_PHYSMAP)	+= physmap.o 
+obj-$(CONFIG_MTD_PNC2000)	+= pnc2000.o
+obj-$(CONFIG_MTD_RPXLITE)	+= rpxlite.o
+obj-$(CONFIG_MTD_SA1100)        += sa1100-flash.o
+obj-$(CONFIG_MTD_SBC_GXX)	+= sbc_gxx.o
+obj-$(CONFIG_MTD_SC520CDP)	+= sc520cdp.o
+obj-$(CONFIG_MTD_NETSC520)	+= netsc520.o
+obj-$(CONFIG_MTD_SUN_UFLASH)    += sun_uflash.o
+obj-$(CONFIG_MTD_VMAX)		+= vmax301.o
+obj-$(CONFIG_MTD_DBOX2)		+= dbox2-flash.o
+obj-$(CONFIG_MTD_OCELOT)	+= ocelot.o
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/maps/cfi_flagadm.c linux/drivers/mtd/maps/cfi_flagadm.c
--- v2.4.5/linux/drivers/mtd/maps/cfi_flagadm.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/cfi_flagadm.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,184 @@
+/*
+ *  Copyright © 2001 Flaga hf. Medical Devices, Kári Davíđsson <kd@flaga.is>
+ *
+ *  $Id: cfi_flagadm.c,v 1.5 2001/05/29 15:47:49 kd Exp $
+ *  
+ *  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.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+
+/* We split the flash chip up into four parts.
+ * 1: bootloader firts 128k			(0x00000000 - 0x0001FFFF) size 0x020000
+ * 2: kernel 640k					(0x00020000 - 0x000BFFFF) size 0x0A0000
+ * 3: compressed 1536k root ramdisk	(0x000C0000 - 0x0023FFFF) size 0x180000
+ * 4: writeable diskpartition (jffs)(0x00240000 - 0x003FFFFF) size 0x1C0000
+ */
+
+#define FLASH_PHYS_ADDR 0x40000000
+#define FLASH_SIZE 0x400000  
+
+#define FLASH_PARTITION0_ADDR 0x00000000
+#define FLASH_PARTITION0_SIZE 0x00020000
+
+#define FLASH_PARTITION1_ADDR 0x00020000
+#define FLASH_PARTITION1_SIZE 0x000A0000
+
+#define FLASH_PARTITION2_ADDR 0x000C0000
+#define FLASH_PARTITION2_SIZE 0x00180000
+
+#define FLASH_PARTITION3_ADDR 0x00240000
+#define FLASH_PARTITION3_SIZE 0x001C0000
+
+__u8 flagadm_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+__u16 flagadm_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+__u32 flagadm_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void flagadm_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void flagadm_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void flagadm_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void flagadm_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void flagadm_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+struct map_info flagadm_map = {
+		name: "FlagaDM flash device",
+		size: FLASH_SIZE,
+		buswidth: 2,
+		read8: flagadm_read8,
+		read16: flagadm_read16,
+		read32: flagadm_read32,
+		copy_from: flagadm_copy_from,
+		write8: flagadm_write8,
+		write16: flagadm_write16,
+		write32: flagadm_write32,
+		copy_to: flagadm_copy_to
+};
+
+struct mtd_partition flagadm_parts[] = {
+	{
+		name	: "Bootloader",
+		offset	: FLASH_PARTITION0_ADDR,
+		size	: FLASH_PARTITION0_SIZE
+	},
+	{
+		name	: "Kernel image",
+		offset	: FLASH_PARTITION1_ADDR,
+		size	: FLASH_PARTITION1_SIZE
+	},
+	{
+		name	: "Initial ramdisk image",
+		offset	: FLASH_PARTITION2_ADDR,
+		size	: FLASH_PARTITION2_SIZE
+	},
+	{	
+		name	: "Persistant storage",
+		offset	: FLASH_PARTITION3_ADDR,
+		size	: FLASH_PARTITION3_SIZE
+	}
+};
+
+#define PARTITION_COUNT (sizeof(flagadm_parts)/sizeof(struct mtd_partition))
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_flagadm init_module
+#define cleanup_flagadm cleanup_module
+#endif
+
+static struct mtd_info *mymtd;
+
+int __init init_flagadm(void)
+{	
+	printk(KERN_NOTICE "FlagaDM flash device: %x at %x\n",
+			FLASH_SIZE, FLASH_PHYS_ADDR);
+	
+	flagadm_map.map_priv_1 = (unsigned long)ioremap(FLASH_PHYS_ADDR,
+					FLASH_SIZE);
+
+	if (!flagadm_map.map_priv_1) {
+		printk("Failed to ioremap\n");
+		return -EIO;
+	}
+	mymtd = do_map_probe("cfi", &flagadm_map);
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+		add_mtd_partitions(mymtd, flagadm_parts, PARTITION_COUNT);
+		printk(KERN_NOTICE "FlagaDM flash device initialized\n");
+		return 0;
+	}
+
+	iounmap((void *)flagadm_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_flagadm(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+	}
+	if (flagadm_map.map_priv_1) {
+		iounmap((void *)flagadm_map.map_priv_1);
+		flagadm_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_flagadm);
+module_exit(cleanup_flagadm);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/maps/cstm_mips_ixx.c linux/drivers/mtd/maps/cstm_mips_ixx.c
--- v2.4.5/linux/drivers/mtd/maps/cstm_mips_ixx.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/cstm_mips_ixx.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,314 @@
+/*
+ * $Id: cstm_mips_ixx.c,v 1.3 2001/06/02 14:52:23 dwmw2 Exp $
+ *
+ * Mapping of a custom board with both AMD CFI and JEDEC flash in partitions.
+ * Config with both CFI and JEDEC device support.
+ *
+ * Basically physmap.c with the addition of partitions and 
+ * an array of mapping info to accomodate more than one flash type per board.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  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.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/config.h>
+
+#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
+#include <linux/delay.h>
+#endif
+
+__u8 cstm_mips_ixx_read8(struct map_info *map, unsigned long ofs)
+{
+	return *(__u8 *)(map->map_priv_1 + ofs);
+}
+
+__u16 cstm_mips_ixx_read16(struct map_info *map, unsigned long ofs)
+{
+	return *(__u16 *)(map->map_priv_1 + ofs);
+}
+
+__u32 cstm_mips_ixx_read32(struct map_info *map, unsigned long ofs)
+{
+	return *(__u32 *)(map->map_priv_1 + ofs);
+}
+
+void cstm_mips_ixx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void cstm_mips_ixx_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	*(__u8 *)(map->map_priv_1 + adr) = d;
+}
+
+void cstm_mips_ixx_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	*(__u16 *)(map->map_priv_1 + adr) = d;
+}
+
+void cstm_mips_ixx_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	*(__u32 *)(map->map_priv_1 + adr) = d;
+}
+
+void cstm_mips_ixx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
+#define CC_GCR             0xB4013818
+#define CC_GPBCR           0xB401380A
+#define CC_GPBDR           0xB4013808
+#define CC_M68K_DEVICE     1
+#define CC_M68K_FUNCTION   6
+#define CC_CONFADDR        0xB8004000
+#define CC_CONFDATA        0xB8004004
+#define CC_FC_FCR          0xB8002004
+#define CC_FC_DCR          0xB8002008
+#define CC_GPACR           0xB4013802
+#define CC_GPAICR          0xB4013804
+#endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */
+
+void cstm_mips_ixx_set_vpp(struct map_info *map,int vpp)
+{
+  if (vpp) {
+#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
+        __u16	data;
+        __u8	data1;
+	static u8 first = 1;
+
+	// Set GPIO port B pin3 to high
+	data = *(__u16 *)(CC_GPBCR);
+	data = (data & 0xff0f) | 0x0040;
+	*(__u16 *)CC_GPBCR = data;
+	*(__u8 *)CC_GPBDR = (*(__u8*)CC_GPBDR) | 0x08;
+	if (first) {
+		first = 0;
+		/* need to have this delay for first
+		   enabling vpp after powerup */
+		udelay(40);
+	}
+#endif /* CONFIG_MIPS_ITE8172 */
+  }
+  else {
+#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
+        __u16	data;
+
+	// Set GPIO port B pin3 to high
+	data = *(__u16 *)(CC_GPBCR);
+	data = (data & 0xff3f) | 0x0040;
+	*(__u16 *)CC_GPBCR = data;
+	*(__u8 *)CC_GPBDR = (*(__u8*)CC_GPBDR) & 0xf7;
+#endif /* CONFIG_MIPS_ITE8172 */
+  }
+}
+
+const struct map_info basic_cstm_mips_ixx_map = {
+	NULL,
+	0,
+	0,
+	cstm_mips_ixx_read8,
+	cstm_mips_ixx_read16,
+	cstm_mips_ixx_read32,
+	cstm_mips_ixx_copy_from,
+	cstm_mips_ixx_write8,
+	cstm_mips_ixx_write16,
+	cstm_mips_ixx_write32,
+	cstm_mips_ixx_copy_to,
+        cstm_mips_ixx_set_vpp,
+	0,
+	0
+};
+
+/* board and partition description */
+
+#define MAX_PHYSMAP_PARTITIONS    8
+struct cstm_mips_ixx_info {
+	char *name;
+	unsigned long window_addr;
+	unsigned long window_size;
+	int buswidth;
+	int num_partitions;
+};
+
+#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
+#define PHYSMAP_NUMBER  1  // number of board desc structs needed, one per contiguous flash type 
+const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] = 
+{
+    {   // 28F128J3A in 2x16 configuration
+        "big flash",     // name
+	0x08000000,      // window_addr
+	0x02000000,      // window_size
+        4,               // buswidth
+	1,               // num_partitions
+    }
+
+};
+static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = {
+{   // 28F128J3A in 2x16 configuration
+	{
+		name: "main partition ",
+		size: 0x02000000, // 128 x 2 x 128k byte sectors
+		offset: 0,
+	},
+},
+};
+#else /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */
+#define PHYSMAP_NUMBER  1  // number of board desc structs needed, one per contiguous flash type 
+const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] = 
+{
+    {  
+        "MTD flash",                   // name
+	CONFIG_MTD_CSTM_MIPS_IXX_START,      // window_addr
+	CONFIG_MTD_CSTM_MIPS_IXX_LEN,        // window_size
+        CONFIG_MTD_CSTM_MIPS_IXX_BUSWIDTH,   // buswidth
+	1,                             // num_partitions
+    },
+
+};
+static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = {
+{ 
+	{
+		name: "main partition",
+		size:  CONFIG_MTD_CSTM_MIPS_IXX_LEN,
+		offset: 0,
+	},
+},
+};
+#endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */
+
+struct map_info cstm_mips_ixx_map[PHYSMAP_NUMBER];
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_cstm_mips_ixx init_module
+#define cleanup_cstm_mips_ixx cleanup_module
+#endif
+
+int __init init_cstm_mips_ixx(void)
+{
+	int i;
+	int jedec;
+        struct mtd_info *mymtd;
+        struct mtd_partition *parts;
+
+	/* Initialize mapping */
+	for (i=0;i<PHYSMAP_NUMBER;i++) {
+		printk(KERN_NOTICE "cstm_mips_ixx flash device: %lx at %lx\n", cstm_mips_ixx_board_desc[i].window_size, cstm_mips_ixx_board_desc[i].window_addr);
+                memcpy((char *)&cstm_mips_ixx_map[i],(char *)&basic_cstm_mips_ixx_map,sizeof(struct map_info));
+		cstm_mips_ixx_map[i].map_priv_1 = (unsigned long)ioremap(cstm_mips_ixx_board_desc[i].window_addr, cstm_mips_ixx_board_desc[i].window_size);
+		if (!cstm_mips_ixx_map[i].map_priv_1) {
+			printk(KERN_WARNING "Failed to ioremap\n");
+			return -EIO;
+	        }
+		cstm_mips_ixx_map[i].name = cstm_mips_ixx_board_desc[i].name;
+		cstm_mips_ixx_map[i].size = cstm_mips_ixx_board_desc[i].window_size;
+		cstm_mips_ixx_map[i].buswidth = cstm_mips_ixx_board_desc[i].buswidth;
+		//printk(KERN_NOTICE "cstm_mips_ixx: ioremap is %x\n",(unsigned int)(cstm_mips_ixx_map[i].map_priv_1));
+	}
+
+#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
+        setup_ITE_IVR_flash();
+#endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */
+
+	for (i=0;i<PHYSMAP_NUMBER;i++) {
+                parts = &cstm_mips_ixx_partitions[i][0];
+		jedec = 0;
+		mymtd = (struct mtd_info *)do_map_probe("cfi", &cstm_mips_ixx_map[i]);
+		//printk(KERN_NOTICE "phymap %d cfi_probe: mymtd is %x\n",i,(unsigned int)mymtd);
+		if (!mymtd) {
+			jedec = 1;
+			mymtd = (struct mtd_info *)do_map_probe("jedec", &cstm_mips_ixx_map[i]);
+		        printk(KERN_NOTICE "cstm_mips_ixx %d jedec: mymtd is %x\n",i,(unsigned int)mymtd);
+		}
+		if (mymtd) {
+			mymtd->module = THIS_MODULE;
+
+	                cstm_mips_ixx_map[i].map_priv_2 = (unsigned long)mymtd;
+		        add_mtd_partitions(mymtd, parts, cstm_mips_ixx_board_desc[i].num_partitions);
+		}
+		else
+	           return -ENXIO;
+	}
+	return 0;
+}
+
+static void __exit cleanup_cstm_mips_ixx(void)
+{
+	int i;
+        struct mtd_info *mymtd;
+
+	for (i=0;i<PHYSMAP_NUMBER;i++) {
+	        mymtd = (struct mtd_info *)cstm_mips_ixx_map[i].map_priv_2;
+		if (mymtd) {
+			del_mtd_partitions(mymtd);
+			map_destroy(mymtd);
+		}
+		if (cstm_mips_ixx_map[i].map_priv_1) {
+			iounmap((void *)cstm_mips_ixx_map[i].map_priv_1);
+			cstm_mips_ixx_map[i].map_priv_1 = 0;
+		}
+	}
+}
+#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
+void PCISetULongByOffset(__u32 DevNumber, __u32 FuncNumber, __u32 Offset, __u32 data)
+{
+	__u32	offset;
+
+	offset = ( unsigned long )( 0x80000000 | ( DevNumber << 11 ) + ( FuncNumber << 8 ) + Offset) ;
+
+	*(__u32 *)CC_CONFADDR = offset;	
+	*(__u32 *)CC_CONFDATA = data;
+}
+void setup_ITE_IVR_flash()
+{
+		__u32	size, base;
+
+		size = 0x0e000000;		// 32MiB
+		base = (0x08000000) >> 8 >>1; // Bug: we must shift one more bit
+
+		/* need to set ITE flash to 32 bits instead of default 8 */
+#ifdef CONFIG_MIPS_IVR
+		*(__u32 *)CC_FC_FCR = 0x55;
+		*(__u32 *)CC_GPACR = 0xfffc;
+#else
+		*(__u32 *)CC_FC_FCR = 0x77;
+#endif
+		/* turn bursting off */
+		*(__u32 *)CC_FC_DCR = 0x0;
+
+		/* setup for one chip 4 byte PCI access */
+		PCISetULongByOffset(CC_M68K_DEVICE, CC_M68K_FUNCTION, 0x60, size | base);
+		PCISetULongByOffset(CC_M68K_DEVICE, CC_M68K_FUNCTION, 0x64, 0x02);
+}
+#endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */
+
+module_init(init_cstm_mips_ixx);
+module_exit(cleanup_cstm_mips_ixx);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/maps/dbox2-flash.c linux/drivers/mtd/maps/dbox2-flash.c
--- v2.4.5/linux/drivers/mtd/maps/dbox2-flash.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/dbox2-flash.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,151 @@
+/*
+ * $Id: dbox2-flash.c,v 1.2 2001/04/26 15:42:43 dwmw2 Exp $
+ *
+ * Nokia / Sagem D-Box 2 flash driver
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/config.h>
+
+/* partition_info gives details on the logical partitions that the split the
+ * single flash device into. If the size if zero we use up to the end of the
+ * device. */
+static struct mtd_partition partition_info[]= {{name: "BR bootloader",		// raw
+						      size: 128 * 1024, 
+						      offset: 0,                  
+						      mask_flags: MTD_WRITEABLE},
+                                                     {name: "PPC bootloader",		// flfs
+						      size: 128 * 1024, 
+						      offset: MTDPART_OFS_APPEND, 
+						      mask_flags: 0},
+                                                     {name: "Kernel",			// idxfs
+						      size: 768 * 1024, 
+						      offset: MTDPART_OFS_APPEND, 
+						      mask_flags: 0},
+                                                     {name: "System",			// jffs
+						      size: MTDPART_SIZ_FULL, 
+						      offset: MTDPART_OFS_APPEND, 
+						      mask_flags: 0}};
+
+#define NUM_PARTITIONS (sizeof(partition_info) / sizeof(partition_info[0]))
+
+#define WINDOW_ADDR 0x10000000
+#define WINDOW_SIZE 0x800000
+
+static struct mtd_info *mymtd;
+
+__u8 dbox2_flash_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+__u16 dbox2_flash_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+__u32 dbox2_flash_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void dbox2_flash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void dbox2_flash_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void dbox2_flash_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void dbox2_flash_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void dbox2_flash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+struct map_info dbox2_flash_map = {
+	name: "D-Box 2 flash memory",
+	size: WINDOW_SIZE,
+	buswidth: 4,
+	read8: dbox2_flash_read8,
+	read16: dbox2_flash_read16,
+	read32: dbox2_flash_read32,
+	copy_from: dbox2_flash_copy_from,
+	write8: dbox2_flash_write8,
+	write16: dbox2_flash_write16,
+	write32: dbox2_flash_write32,
+	copy_to: dbox2_flash_copy_to
+};
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_dbox2_flash init_module
+#define cleanup_dbox2_flash cleanup_module
+#endif
+
+mod_init_t init_dbox2_flash(void)
+{
+       	printk(KERN_NOTICE "D-Box 2 flash driver (size->0x%X mem->0x%X)\n", WINDOW_SIZE, WINDOW_ADDR);
+	dbox2_flash_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
+
+	if (!dbox2_flash_map.map_priv_1) {
+		printk("Failed to ioremap\n");
+		return -EIO;
+	}
+
+	// Probe for dual Intel 28F320 or dual AMD
+	mymtd = do_map_probe("cfi", &dbox2_flash_map);
+	if (!mymtd) {
+	    // Probe for single Intel 28F640
+	    dbox2_flash_map.buswidth = 2;
+	
+	    mymtd = do_map_probe("cfi", &dbox2_flash_map);
+	}
+	    
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+
+                /* Create MTD devices for each partition. */
+	        add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
+		
+		return 0;
+	}
+
+	iounmap((void *)dbox2_flash_map.map_priv_1);
+	return -ENXIO;
+}
+
+mod_exit_t cleanup_dbox2_flash(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+	}
+	if (dbox2_flash_map.map_priv_1) {
+		iounmap((void *)dbox2_flash_map.map_priv_1);
+		dbox2_flash_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_dbox2_flash);
+module_exit(cleanup_dbox2_flash);
+
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/maps/dc21285.c linux/drivers/mtd/maps/dc21285.c
--- v2.4.5/linux/drivers/mtd/maps/dc21285.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/dc21285.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,193 @@
+/*
+ * MTD map driver for flash on the DC21285 (the StrongARM-110 companion chip)
+ *
+ * (C) 2000  Nicolas Pitre <nico@cam.org>
+ *
+ * This code is GPL
+ * 
+ * $Id: dc21285.c,v 1.4 2001/04/26 15:40:23 dwmw2 Exp $
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/io.h>
+#include <asm/hardware/dec21285.h>
+
+
+static struct mtd_info *mymtd;
+
+__u8 dc21285_read8(struct map_info *map, unsigned long ofs)
+{
+	return *(__u8*)(map->map_priv_1 + ofs);
+}
+
+__u16 dc21285_read16(struct map_info *map, unsigned long ofs)
+{
+	return *(__u16*)(map->map_priv_1 + ofs);
+}
+
+__u32 dc21285_read32(struct map_info *map, unsigned long ofs)
+{
+	return *(__u32*)(map->map_priv_1 + ofs);
+}
+
+void dc21285_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy(to, (void*)(map->map_priv_1 + from), len);
+}
+
+void dc21285_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	*CSR_ROMWRITEREG = adr;
+	adr &= ~3;
+	*(__u8*)(map->map_priv_1 + adr) = d;
+}
+
+void dc21285_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	*CSR_ROMWRITEREG = adr;
+	adr &= ~1;
+	*(__u16*)(map->map_priv_1 + adr) = d;
+}
+
+void dc21285_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	*(__u32*)(map->map_priv_1 + adr) = d;
+}
+
+void dc21285_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	switch (map->buswidth) {
+		case 4:
+			while (len > 0) {
+				__u32 d = *((__u32*)from)++;
+				dc21285_write32(map, d, to);
+				to += 4;
+				len -= 4;
+			}
+			break;
+		case 2:
+			while (len > 0) {
+				__u16 d = *((__u16*)from)++;
+				dc21285_write16(map, d, to);
+				to += 2;
+				len -= 2;
+			}
+			break;
+		case 1:
+			while (len > 0) {
+				__u8 d = *((__u8*)from)++;
+				dc21285_write8(map, d, to);
+				to++;
+				len--;
+			}
+			break;
+	}
+}
+
+struct map_info dc21285_map = {
+	name: "DC21285 flash",
+	size: 16*1024*1024,
+	read8: dc21285_read8,
+	read16: dc21285_read16,
+	read32: dc21285_read32,
+	copy_from: dc21285_copy_from,
+	write8: dc21285_write8,
+	write16: dc21285_write16,
+	write32: dc21285_write32,
+	copy_to: dc21285_copy_to
+};
+
+
+/* Partition stuff */
+static struct mtd_partition *dc21285_parts;
+		      
+extern int parse_redboot_partitions(struct mtd_info *, struct mtd_partition **);
+
+int __init init_dc21285(void)
+{
+	/* Determine buswidth */
+	switch (*CSR_SA110_CNTL & (3<<14)) {
+		case SA110_CNTL_ROMWIDTH_8: 
+			dc21285_map.buswidth = 1;
+			break;
+		case SA110_CNTL_ROMWIDTH_16: 
+			dc21285_map.buswidth = 2; 
+			break;
+		case SA110_CNTL_ROMWIDTH_32: 
+			dc21285_map.buswidth = 4; 
+			break;
+		default:
+			printk (KERN_ERR "DC21285 flash: undefined buswidth\n");
+			return -ENXIO;
+	}
+	printk (KERN_NOTICE "DC21285 flash support (%d-bit buswidth)\n",
+		dc21285_map.buswidth*8);
+
+	/* Let's map the flash area */
+	dc21285_map.map_priv_1 = (unsigned long)__ioremap(DC21285_FLASH, 16*1024*1024, 0);
+	if (!dc21285_map.map_priv_1) {
+		printk("Failed to ioremap\n");
+		return -EIO;
+	}
+
+	mymtd = do_map_probe("cfi", &dc21285_map);
+	if (mymtd) {
+		int nrparts;
+
+		mymtd->module = THIS_MODULE;
+			
+		/* partition fixup */
+
+		nrparts = parse_redboot_partitions(mymtd, &dc21285_parts);
+		if (nrparts <=0) {
+			printk(KERN_NOTICE "RedBoot partition table failed\n");
+			iounmap((void *)dc21285_map.map_priv_1);
+			return -ENXIO;
+		}
+
+		add_mtd_partitions(mymtd, dc21285_parts, nrparts);
+
+		/* 
+		 * Flash timing is determined with bits 19-16 of the
+		 * CSR_SA110_CNTL.  The value is the number of wait cycles, or
+		 * 0 for 16 cycles (the default).  Cycles are 20 ns.
+		 * Here we use 7 for 140 ns flash chips.
+		 */
+		/* access time */
+		*CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x000f0000) | (7 << 16));
+		/* burst time */
+		*CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x00f00000) | (7 << 20));
+		/* tristate time */
+		*CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24));
+
+		return 0;
+	}
+
+	iounmap((void *)dc21285_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_dc21285(void)
+{
+	if (mymtd) {
+		del_mtd_device(mymtd);
+		map_destroy(mymtd);
+		mymtd = NULL;
+	}
+	if (dc21285_map.map_priv_1) {
+		iounmap((void *)dc21285_map.map_priv_1);
+		dc21285_map.map_priv_1 = 0;
+	}
+	if(dc21285_parts)
+		kfree(dc21285_parts);
+}
+
+module_init(init_dc21285);
+module_exit(cleanup_dc21285);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/maps/elan-104nc.c linux/drivers/mtd/maps/elan-104nc.c
--- v2.4.5/linux/drivers/mtd/maps/elan-104nc.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/elan-104nc.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,277 @@
+/* elan-104nc.c -- MTD map driver for Arcom Control Systems ELAN-104NC
+ 
+   Copyright (C) 2000 Arcom Control System Ltd
+ 
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+ 
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+ 
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+   $Id: elan-104nc.c,v 1.10 2001/06/02 14:30:44 dwmw2 Exp $
+
+The ELAN-104NC has up to 8 Mibyte of Intel StrataFlash (28F320/28F640) in x16
+mode.  This drivers uses the CFI probe and Intel Extended Command Set drivers.
+
+The flash is accessed as follows:
+
+   32 kbyte memory window at 0xb0000-0xb7fff
+   
+   16 bit I/O port (0x22) for some sort of paging.
+
+The single flash device is divided into 3 partition which appear as seperate
+MTD devices.
+
+Linux thinks that the I/O port is used by the PIC and hence check_region() will
+always fail.  So we don't do it.  I just hope it doesn't break anything.
+*/
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <asm/io.h>
+
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#define WINDOW_START 0xb0000
+/* Number of bits in offset. */
+#define WINDOW_SHIFT 15
+#define WINDOW_LENGTH (1 << WINDOW_SHIFT)
+/* The bits for the offset into the window. */
+#define WINDOW_MASK (WINDOW_LENGTH-1)
+#define PAGE_IO 0x22
+#define PAGE_IO_SIZE 2
+
+static volatile int page_in_window = -1; // Current page in window.
+static unsigned long iomapadr;
+static spinlock_t elan_104nc_spin = SPIN_LOCK_UNLOCKED;
+
+/* partition_info gives details on the logical partitions that the split the 
+ * single flash device into. If the size if zero we use up to the end of the
+ * device. */
+static struct mtd_partition partition_info[]={
+    { name: "ELAN-104NC flash boot partition", 
+      offset: 0, 
+      size: 640*1024 },
+    { name: "ELAN-104NC flash partition 1", 
+      offset: 640*1024, 
+      size: 896*1024 },
+    { name: "ELAN-104NC flash partition 2", 
+      offset: (640+896)*1024 }
+};
+#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0]))
+
+/*
+ * If no idea what is going on here.  This is taken from the FlashFX stuff.
+ */
+#define ROMCS 1
+
+static inline void elan_104nc_setup(void)
+{
+    u16 t;
+
+    outw( 0x0023 + ROMCS*2, PAGE_IO );
+    t=inb( PAGE_IO+1 );
+
+    t=(t & 0xf9) | 0x04;
+
+    outw( ((0x0023 + ROMCS*2) | (t << 8)), PAGE_IO );
+}
+
+static inline void elan_104nc_page(struct map_info *map, unsigned long ofs)
+{
+	unsigned long page = ofs >> WINDOW_SHIFT;
+       
+	if( page!=page_in_window ) {
+		int cmd1;
+		int cmd2;
+
+		cmd1=(page & 0x700) + 0x0833 + ROMCS*0x4000;
+		cmd2=((page & 0xff) << 8) + 0x0032;
+
+		outw( cmd1, PAGE_IO );
+		outw( cmd2, PAGE_IO );
+
+		page_in_window = page;
+	}
+}
+
+
+static __u8 elan_104nc_read8(struct map_info *map, unsigned long ofs)
+{
+	__u8 ret;
+	spin_lock(&elan_104nc_spin);
+	elan_104nc_page(map, ofs);
+	ret = readb(iomapadr + (ofs & WINDOW_MASK));
+	spin_unlock(&elan_104nc_spin);
+	return ret;
+}
+
+static __u16 elan_104nc_read16(struct map_info *map, unsigned long ofs)
+{
+	__u16 ret;
+	spin_lock(&elan_104nc_spin);
+	elan_104nc_page(map, ofs);
+	ret = readw(iomapadr + (ofs & WINDOW_MASK));
+	spin_unlock(&elan_104nc_spin);
+	return ret;
+}
+
+static __u32 elan_104nc_read32(struct map_info *map, unsigned long ofs)
+{
+	__u32 ret;
+	spin_lock(&elan_104nc_spin);
+	elan_104nc_page(map, ofs);
+	ret = readl(iomapadr + (ofs & WINDOW_MASK));
+	spin_unlock(&elan_104nc_spin);
+	return ret;
+}
+
+static void elan_104nc_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	while(len) {
+		unsigned long thislen = len;
+		if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
+			thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
+		
+		spin_lock(&elan_104nc_spin);
+		elan_104nc_page(map, from);
+		memcpy_fromio(to, iomapadr + (from & WINDOW_MASK), thislen);
+		spin_unlock(&elan_104nc_spin);
+		(__u8*)to += thislen;
+		from += thislen;
+		len -= thislen;
+	}
+}
+
+static void elan_104nc_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	spin_lock(&elan_104nc_spin);
+	elan_104nc_page(map, adr);
+	writeb(d, iomapadr + (adr & WINDOW_MASK));
+	spin_unlock(&elan_104nc_spin);
+}
+
+static void elan_104nc_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	spin_lock(&elan_104nc_spin);
+	elan_104nc_page(map, adr);
+	writew(d, iomapadr + (adr & WINDOW_MASK));
+	spin_unlock(&elan_104nc_spin);
+}
+
+static void elan_104nc_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	spin_lock(&elan_104nc_spin);
+	elan_104nc_page(map, adr);
+	writel(d, iomapadr + (adr & WINDOW_MASK));
+	spin_unlock(&elan_104nc_spin);
+}
+
+static void elan_104nc_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{	
+	while(len) {
+		unsigned long thislen = len;
+		if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
+			thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
+		
+		spin_lock(&elan_104nc_spin);
+		elan_104nc_page(map, to);
+		memcpy_toio(iomapadr + (to & WINDOW_MASK), from, thislen);
+		spin_unlock(&elan_104nc_spin);
+		to += thislen;
+		from += thislen;
+		len -= thislen;
+	}
+}
+
+static struct map_info elan_104nc_map = {
+	name: "ELAN-104NC flash",
+	size: 8*1024*1024, /* this must be set to a maximum possible amount
+			of flash so the cfi probe routines find all
+			the chips */
+	buswidth: 2,
+	read8: elan_104nc_read8,
+	read16: elan_104nc_read16,
+	read32: elan_104nc_read32,
+	copy_from: elan_104nc_copy_from,
+	write8: elan_104nc_write8,
+	write16: elan_104nc_write16,
+	write32: elan_104nc_write32,
+	copy_to: elan_104nc_copy_to
+};
+
+/* MTD device for all of the flash. */
+static struct mtd_info *all_mtd;
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_elan_104nc init_module
+#define cleanup_elan_104nc cleanup_module
+#endif
+
+mod_exit_t cleanup_elan_104nc(void)
+{
+	if( all_mtd ) {
+		del_mtd_partitions( all_mtd );
+		map_destroy( all_mtd );
+	}
+
+	iounmap((void *)iomapadr);
+	release_region(PAGE_IO,PAGE_IO_SIZE);
+}
+
+mod_init_t init_elan_104nc(void)
+{
+	/* Urg! We use I/O port 0x22 without request_region()ing it */
+	/*
+	if (check_region(PAGE_IO,PAGE_IO_SIZE) != 0) {
+		printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n",
+			elan_104nc_map.name,
+			PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1 );
+		return -EAGAIN;
+	}
+	*/
+  	iomapadr = (unsigned long)ioremap(WINDOW_START, WINDOW_LENGTH);
+	if (!iomapadr) {
+		printk( KERN_ERR"%s: failed to ioremap memory region\n",
+			elan_104nc_map.name );
+		return -EIO;
+	}
+
+	/*
+	request_region( PAGE_IO, PAGE_IO_SIZE, "ELAN-104NC flash" );
+	*/
+
+	printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n",
+		elan_104nc_map.name,
+		PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1,
+		WINDOW_START, WINDOW_START+WINDOW_LENGTH-1 );
+
+	elan_104nc_setup();
+
+	/* Probe for chip. */
+	all_mtd = do_map_probe("cfi",  &elan_104nc_map );
+	if( !all_mtd ) {
+		cleanup_elan_104nc();
+		return -ENXIO;
+	}
+	
+	all_mtd->module=THIS_MODULE;
+
+	/* Create MTD devices for each partition. */
+	add_mtd_partitions( all_mtd, partition_info, NUM_PARTITIONS );
+
+	return 0;
+}
+
+module_init(init_elan_104nc);
+module_exit(cleanup_elan_104nc);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/maps/iq80310.c linux/drivers/mtd/maps/iq80310.c
--- v2.4.5/linux/drivers/mtd/maps/iq80310.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/iq80310.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,133 @@
+/*
+ * $Id: iq80310.c,v 1.3 2001/04/26 15:40:23 dwmw2 Exp $
+ *
+ * Mapping for the Intel XScale IQ80310 evaluation board
+ *
+ * Author:	Nicolas Pitre
+ * Copyright:	(C) 2001 MontaVista Software Inc.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+
+#define WINDOW_ADDR 	0
+#define WINDOW_SIZE 	8*1024*1024
+#define BUSWIDTH 	1
+
+static struct mtd_info *mymtd;
+
+static __u8 iq80310_read8(struct map_info *map, unsigned long ofs)
+{
+	return *(__u8 *)(map->map_priv_1 + ofs);
+}
+
+static __u16 iq80310_read16(struct map_info *map, unsigned long ofs)
+{
+	return *(__u16 *)(map->map_priv_1 + ofs);
+}
+
+static __u32 iq80310_read32(struct map_info *map, unsigned long ofs)
+{
+	return *(__u32 *)(map->map_priv_1 + ofs);
+}
+
+static void iq80310_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy(to, (void *)(map->map_priv_1 + from), len);
+}
+
+static void iq80310_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	*(__u8 *)(map->map_priv_1 + adr) = d;
+}
+
+static void iq80310_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	*(__u16 *)(map->map_priv_1 + adr) = d;
+}
+
+static void iq80310_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	*(__u32 *)(map->map_priv_1 + adr) = d;
+}
+
+static void iq80310_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy((void *)(map->map_priv_1 + to), from, len);
+}
+
+static struct map_info iq80310_map = {
+	name: "IQ80310 flash",
+	size: WINDOW_SIZE,
+	buswidth: BUSWIDTH,
+	read8:		iq80310_read8,
+	read16:		iq80310_read16,
+	read32:		iq80310_read32,
+	copy_from:	iq80310_copy_from,
+	write8:		iq80310_write8,
+	write16:	iq80310_write16,
+	write32:	iq80310_write32,
+	copy_to:	iq80310_copy_to
+};
+
+static struct mtd_partition iq80310_partitions[3] = {
+	{
+		name:		"firmware",
+		size:		0x00080000,
+		offset:		0,
+		mask_flags:	MTD_WRITEABLE  /* force read-only */
+	},{
+		name:		"kernel",
+		size:		0x00080000,
+		offset:		0x00080000,
+	},{
+		name:		"filesystem",
+		size:		0x00700000,
+		offset:		0x00100000
+	}
+};
+
+static int __init init_iq80310(void)
+{
+	iq80310_map.map_priv_1 = (unsigned long)__ioremap(WINDOW_ADDR, WINDOW_SIZE, 0);
+
+	if (!iq80310_map.map_priv_1) {
+		printk("Failed to ioremap\n");
+		return -EIO;
+	}
+	mymtd = do_map_probe("cfi", &iq80310_map);
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+		add_mtd_partitions(mymtd, iq80310_partitions, 3);
+		return 0;
+	}
+
+	iounmap((void *)iq80310_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_iq80310(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+	}
+	if (iq80310_map.map_priv_1) {
+		iounmap((void *)iq80310_map.map_priv_1);
+		iq80310_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_iq80310);
+module_exit(cleanup_iq80310);
+
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/maps/netsc520.c linux/drivers/mtd/maps/netsc520.c
--- v2.4.5/linux/drivers/mtd/maps/netsc520.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/netsc520.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,192 @@
+/* netsc520.c -- MTD map driver for AMD NetSc520 Demonstration Board
+ *
+ * Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com)
+ *	based on sc520cdp.c by Sysgo Real-Time Solutions GmbH
+ *
+ * $Id: netsc520.c,v 1.3 2001/06/02 14:52:23 dwmw2 Exp $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * The NetSc520 is a demonstration board for the Elan Sc520 processor available
+ * from AMD.  It has a single back of 16 megs of 32-bit Flash ROM and another
+ * 16 megs of SDRAM.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+
+/*
+** The single, 16 megabyte flash bank is divided into four virtual
+** partitions.  The first partition is 768 KiB and is intended to
+** store the kernel image loaded by the bootstrap loader.  The second
+** partition is 256 KiB and holds the BIOS image.  The third 
+** partition is 14.5 MiB and is intended for the flash file system
+** image.  The last partition is 512 KiB and contains another copy
+** of the BIOS image and the reset vector.
+**
+** Only the third partition should be mounted.  The first partition
+** should not be mounted, but it can erased and written to using the
+** MTD character routines.  The second and fourth partitions should
+** not be touched - it is possible to corrupt the BIOS image by
+** mounting these partitions, and potentially the board will not be
+** recoverable afterwards.
+*/
+
+static __u8 netsc520_read8(struct map_info *map, unsigned long ofs)
+{
+	return readb(map->map_priv_1 + ofs);
+}
+
+static __u16 netsc520_read16(struct map_info *map, unsigned long ofs)
+{
+	return readw(map->map_priv_1 + ofs);
+}
+
+static __u32 netsc520_read32(struct map_info *map, unsigned long ofs)
+{
+	return readl(map->map_priv_1 + ofs);
+}
+
+static void netsc520_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
+}
+
+static void netsc520_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	writeb(d, map->map_priv_1 + adr);
+}
+
+static void netsc520_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	writew(d, map->map_priv_1 + adr);
+}
+
+static void netsc520_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	writel(d, map->map_priv_1 + adr);
+}
+
+static void netsc520_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio((void *)(map->map_priv_1 + to), from, len);
+}
+
+/* partition_info gives details on the logical partitions that the split the 
+ * single flash device into. If the size if zero we use up to the end of the
+ * device. */
+static struct mtd_partition partition_info[]={
+    { 
+	    name: "NetSc520 boot kernel", 
+	    offset: 0, 
+	    size: 	0xc0000
+    },
+    { 
+	    name: "NetSc520 Low BIOS", 
+	    offset: 0xc0000, 
+	    size: 	0x40000
+    },
+    { 
+	    name: "NetSc520 file system", 
+	    offset: 0x100000, 
+	    size: 	0xe80000
+    },
+    { 
+	    name: "NetSc520 High BIOS", 
+	    offset: 0xf80000, 
+	    size: 0x80000
+    },
+};
+#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0]))
+
+/*
+ * If no idea what is going on here.  This is taken from the FlashFX stuff.
+ */
+#define ROMCS 1
+
+
+#define WINDOW_SIZE	0x00100000
+#define WINDOW_ADDR	0x00200000
+
+static struct map_info netsc520_map = {
+	name: "netsc520 Flash Bank",
+	size: WINDOW_SIZE,
+	buswidth: 4,
+	read8: netsc520_read8,
+	read16: netsc520_read16,
+	read32: netsc520_read32,
+	copy_from: netsc520_copy_from,
+	write8: netsc520_write8,
+	write16: netsc520_write16,
+	write32: netsc520_write32,
+	copy_to: netsc520_copy_to,
+	map_priv_2: WINDOW_ADDR
+};
+
+#define NUM_FLASH_BANKS	(sizeof(netsc520_map)/sizeof(struct map_info))
+
+static struct mtd_info *mymtd;
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_netsc520 init_module
+#define cleanup_netsc520 cleanup_module
+#endif
+
+
+static int __init init_netsc520(void)
+{
+	printk(KERN_NOTICE "NetSc520 flash device: %lx at %lx\n", netsc520_map.size, netsc520_map.map_priv_2);
+	netsc520_map.map_priv_1 = (unsigned long)ioremap_nocache(netsc520_map.map_priv_2, netsc520_map.size);
+
+	if (!netsc520_map.map_priv_1) {
+		printk("Failed to ioremap_nocache\n");
+		return -EIO;
+	}
+	mymtd = do_map_probe("cfi", &netsc520_map);
+	if(!mymtd)
+		mymtd = do_map_probe("ram", &netsc520_map);
+	if(!mymtd)
+		mymtd = do_map_probe("rom", &netsc520_map);
+
+	if (!mymtd) {
+		iounmap((void *)netsc520_map.map_priv_1);
+		return -ENXIO;
+	}
+		
+	mymtd->module = THIS_MODULE;
+	add_mtd_partitions( mymtd, partition_info, NUM_PARTITIONS );
+	return 0;
+}
+
+static void __exit cleanup_netsc520(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+	}
+	if (netsc520_map.map_priv_1) {
+		iounmap((void *)netsc520_map.map_priv_1);
+		netsc520_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_netsc520);
+module_exit(cleanup_netsc520);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/maps/nora.c linux/drivers/mtd/maps/nora.c
--- v2.4.5/linux/drivers/mtd/maps/nora.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/nora.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,206 @@
+/*
+ * $Id: nora.c,v 1.19 2001/04/26 15:40:23 dwmw2 Exp $
+ *
+ * This is so simple I love it.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+
+
+#define WINDOW_ADDR 0xd0000000
+#define WINDOW_SIZE 0x04000000
+
+static struct mtd_info *mymtd;
+
+__u8 nora_read8(struct map_info *map, unsigned long ofs)
+{
+  return *(__u8 *)(WINDOW_ADDR + ofs);
+}
+
+__u16 nora_read16(struct map_info *map, unsigned long ofs)
+{
+  return *(__u16 *)(WINDOW_ADDR + ofs);
+}
+
+__u32 nora_read32(struct map_info *map, unsigned long ofs)
+{
+  return *(__u32 *)(WINDOW_ADDR + ofs);
+}
+
+void nora_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+  memcpy(to, (void *)(WINDOW_ADDR + from), len);
+}
+
+void nora_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+  *(__u8 *)(WINDOW_ADDR + adr) = d;
+}
+
+void nora_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+  *(__u16 *)(WINDOW_ADDR + adr) = d;
+}
+
+void nora_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+  *(__u32 *)(WINDOW_ADDR + adr) = d;
+}
+
+void nora_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+  memcpy((void *)(WINDOW_ADDR + to), from, len);
+}
+
+struct map_info nora_map = {
+	name: "NORA",
+	size: WINDOW_SIZE,
+	buswidth: 2,
+	read8: nora_read8,
+	read16: nora_read16,
+	read32: nora_read32,
+	copy_from: nora_copy_from,
+	write8: nora_write8,
+	write16: nora_write16,
+	write32: nora_write32,
+	copy_to: nora_copy_to
+};
+
+
+static int nora_mtd_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
+{
+	return mymtd->read(mymtd, from + (unsigned long)mtd->priv, len, retlen, buf);
+}
+
+static int nora_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
+{
+	return mymtd->write(mymtd, to + (unsigned long)mtd->priv, len, retlen, buf);
+}
+
+static int nora_mtd_erase (struct mtd_info *mtd, struct erase_info *instr)
+{
+	instr->addr += (unsigned long)mtd->priv;
+	return mymtd->erase(mymtd, instr);
+}
+
+static void nora_mtd_sync (struct mtd_info *mtd)
+{
+	mymtd->sync(mymtd);
+}
+
+static int nora_mtd_suspend (struct mtd_info *mtd)
+{
+	return mymtd->suspend(mymtd);
+}
+
+static void nora_mtd_resume (struct mtd_info *mtd)
+{
+	mymtd->resume(mymtd);
+}
+
+
+static struct mtd_info nora_mtds[4] = {  /* boot, kernel, ramdisk, fs */
+	{
+		type: MTD_NORFLASH,
+		flags: MTD_CAP_NORFLASH,
+		size: 0x60000,
+		erasesize: 0x20000,
+		name: "NORA boot firmware",
+		module: THIS_MODULE,
+		erase: nora_mtd_erase,
+		read: nora_mtd_read,
+		write: nora_mtd_write,
+		suspend: nora_mtd_suspend,
+		resume: nora_mtd_resume,
+		sync: nora_mtd_sync,
+		priv: (void *)0
+	},
+	{
+		type: MTD_NORFLASH,
+		flags: MTD_CAP_NORFLASH,
+		size: 0x0a0000,
+		erasesize: 0x20000,
+		name: "NORA kernel",
+		module: THIS_MODULE,
+		erase: nora_mtd_erase,
+		read: nora_mtd_read,
+		write: nora_mtd_write,
+		suspend: nora_mtd_suspend,
+		resume: nora_mtd_resume,
+		sync: nora_mtd_sync,
+		priv: (void *)0x60000
+	},
+	{
+		type: MTD_NORFLASH,
+		flags: MTD_CAP_NORFLASH,
+		size: 0x900000,
+		erasesize: 0x20000,
+		name: "NORA root filesystem",
+		module: THIS_MODULE,
+		erase: nora_mtd_erase,
+		read: nora_mtd_read,
+		write: nora_mtd_write,
+		suspend: nora_mtd_suspend,
+		resume: nora_mtd_resume,
+		sync: nora_mtd_sync,
+		priv: (void *)0x100000
+	},
+	{
+		type: MTD_NORFLASH,
+		flags: MTD_CAP_NORFLASH,
+		size: 0x1600000,
+		erasesize: 0x20000,
+		name: "NORA second filesystem",
+		module: THIS_MODULE,
+		erase: nora_mtd_erase,
+		read: nora_mtd_read,
+		write: nora_mtd_write,
+		suspend: nora_mtd_suspend,
+		resume: nora_mtd_resume,
+		sync: nora_mtd_sync,
+		priv: (void *)0xa00000
+	}
+};
+
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_nora init_module
+#define cleanup_nora cleanup_module
+#endif
+
+int __init init_nora(void)
+{
+       	printk(KERN_NOTICE "nora flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
+
+	mymtd = do_map_probe("cfi", &nora_map);
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+		
+		add_mtd_device(&nora_mtds[2]);
+		add_mtd_device(&nora_mtds[0]);
+		add_mtd_device(&nora_mtds[1]);
+		add_mtd_device(&nora_mtds[3]);
+		return 0;
+	}
+
+	return -ENXIO;
+}
+
+static void __exit cleanup_nora(void)
+{
+	if (mymtd) {
+		del_mtd_device(&nora_mtds[3]);
+		del_mtd_device(&nora_mtds[1]);
+		del_mtd_device(&nora_mtds[0]);
+		del_mtd_device(&nora_mtds[2]);
+		map_destroy(mymtd);
+	}
+}
+
+module_init(init_nora);
+module_exit(cleanup_nora);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/maps/ocelot.c linux/drivers/mtd/maps/ocelot.c
--- v2.4.5/linux/drivers/mtd/maps/ocelot.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/ocelot.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,199 @@
+/*
+ * $Id: ocelot.c,v 1.4 2001/06/08 15:36:27 dwmw2 Exp $
+ *
+ * Flash on Momenco Ocelot
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#define OCELOT_PLD 0x2c000000
+#define FLASH_WINDOW_ADDR 0x2fc00000
+#define FLASH_WINDOW_SIZE 0x00080000
+#define FLASH_BUSWIDTH 1
+#define NVRAM_WINDOW_ADDR 0x2c800000
+#define NVRAM_WINDOW_SIZE 0x00007FF0
+#define NVRAM_BUSWIDTH 1
+
+extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
+
+static unsigned int cacheflush = 0;
+
+static struct mtd_info *flash_mtd;
+static struct mtd_info *nvram_mtd;
+
+__u8 ocelot_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+void ocelot_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	cacheflush = 1;
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void ocelot_copy_from_cache(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	if (cacheflush) {
+		dma_cache_inv(map->map_priv_2, map->size);
+		cacheflush = 0;
+	}
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void ocelot_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void ocelot_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	/* If we use memcpy, it does word-wide writes. Even though we told the 
+	   GT64120A that it's an 8-bit wide region, word-wide writes don't work.
+	   We end up just writing the first byte of the four to all four bytes.
+	   So we have this loop instead */
+	while(len) {
+		__raw_writeb(*(unsigned char *) from, map->map_priv_1 + to);
+		from++;
+		to++;
+		len--;
+	}
+}
+
+static struct mtd_partition *parsed_parts;
+
+struct map_info ocelot_flash_map = {
+	name: "Ocelot boot flash",
+	size: FLASH_WINDOW_SIZE,
+	buswidth: FLASH_BUSWIDTH,
+	read8: ocelot_read8,
+	copy_from: ocelot_copy_from_cache,
+	write8: ocelot_write8,
+};
+
+struct map_info ocelot_nvram_map = {
+	name: "Ocelot NVRAM",
+	size: NVRAM_WINDOW_SIZE,
+	buswidth: NVRAM_BUSWIDTH,
+	read8: ocelot_read8,
+	copy_from: ocelot_copy_from,
+	write8: ocelot_write8,
+	copy_to: ocelot_copy_to
+};
+
+static int __init init_ocelot_maps(void)
+{
+	void *pld;
+	int nr_parts;
+	unsigned char brd_status;
+
+       	printk(KERN_INFO "Momenco Ocelot MTD mappings: Flash 0x%x at 0x%x, NVRAM 0x%x at 0x%x\n", 
+	       FLASH_WINDOW_SIZE, FLASH_WINDOW_ADDR, NVRAM_WINDOW_SIZE, NVRAM_WINDOW_ADDR);
+
+	/* First check whether the flash jumper is present */
+	pld = ioremap(OCELOT_PLD, 0x10);
+	if (!pld) {
+		printk(KERN_NOTICE "Failed to ioremap Ocelot PLD\n");
+		return -EIO;
+	}
+	brd_status = readb(pld+4);
+	iounmap(pld);
+
+	/* Now ioremap the NVRAM space */
+	ocelot_nvram_map.map_priv_1 = (unsigned long)ioremap_nocache(NVRAM_WINDOW_ADDR, NVRAM_WINDOW_SIZE);
+	if (!ocelot_nvram_map.map_priv_1) {
+		printk(KERN_NOTICE "Failed to ioremap Ocelot NVRAM space\n");
+		return -EIO;
+	}
+	//	ocelot_nvram_map.map_priv_2 = ocelot_nvram_map.map_priv_1;
+
+	/* And do the RAM probe on it to get an MTD device */
+	nvram_mtd = do_map_probe("ram", &ocelot_nvram_map);
+	if (!nvram_mtd) {
+		printk("NVRAM probe failed\n");
+		goto fail_1;
+	}
+	nvram_mtd->module = THIS_MODULE;
+	nvram_mtd->erasesize = 16;
+
+	/* Now map the flash space */
+	ocelot_flash_map.map_priv_1 = (unsigned long)ioremap_nocache(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE);
+	if (!ocelot_flash_map.map_priv_1) {
+		printk(KERN_NOTICE "Failed to ioremap Ocelot flash space\n");
+		goto fail_2;
+	}
+	/* Now the cached version */
+	ocelot_flash_map.map_priv_2 = (unsigned long)__ioremap(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE, 0);
+
+	if (!ocelot_flash_map.map_priv_2) {
+		/* Doesn't matter if it failed. Just use the uncached version */
+		ocelot_flash_map.map_priv_2 = ocelot_flash_map.map_priv_1;
+	}
+
+	/* Only probe for flash if the write jumper is present */
+	if (brd_status & 0x40) {
+		flash_mtd = do_map_probe("jedec", &ocelot_flash_map);
+	} else {
+		printk(KERN_NOTICE "Ocelot flash write jumper not present. Treating as ROM\n");
+	}
+	/* If that failed or the jumper's absent, pretend it's ROM */
+	if (!flash_mtd) {
+		flash_mtd = do_map_probe("rom", &ocelot_flash_map);
+		/* If we're treating it as ROM, set the erase size */
+		if (flash_mtd)
+			flash_mtd->erasesize = 0x10000;
+	}
+	if (!flash_mtd)
+		goto fail3;
+
+	add_mtd_device(nvram_mtd);
+
+	flash_mtd->module = THIS_MODULE;
+	nr_parts = parse_redboot_partitions(flash_mtd, &parsed_parts);
+
+	if (nr_parts)
+		add_mtd_partitions(flash_mtd, parsed_parts, nr_parts);
+	else
+		add_mtd_device(flash_mtd);
+
+	return 0;
+	
+ fail3:	
+	iounmap((void *)ocelot_flash_map.map_priv_1);
+	if (ocelot_flash_map.map_priv_2 &&
+	    ocelot_flash_map.map_priv_2 != ocelot_flash_map.map_priv_1)
+			iounmap((void *)ocelot_flash_map.map_priv_2);
+ fail_2:
+	map_destroy(nvram_mtd);
+ fail_1:
+	iounmap((void *)ocelot_nvram_map.map_priv_1);
+
+	return -ENXIO;
+}
+
+static void __exit cleanup_ocelot_maps(void)
+{
+	del_mtd_device(nvram_mtd);
+	map_destroy(nvram_mtd);
+	iounmap((void *)ocelot_nvram_map.map_priv_1);
+
+	if (parsed_parts)
+		del_mtd_partitions(flash_mtd);
+	else
+		del_mtd_device(flash_mtd);
+	map_destroy(flash_mtd);
+	iounmap((void *)ocelot_flash_map.map_priv_1);
+	if (ocelot_flash_map.map_priv_2 != ocelot_flash_map.map_priv_1)
+		iounmap((void *)ocelot_flash_map.map_priv_2);
+}
+
+module_init(init_ocelot_maps);
+module_exit(cleanup_ocelot_maps);
+
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/maps/octagon-5066.c linux/drivers/mtd/maps/octagon-5066.c
--- v2.4.5/linux/drivers/mtd/maps/octagon-5066.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/octagon-5066.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,285 @@
+// $Id: octagon-5066.c,v 1.17 2001/06/02 14:30:44 dwmw2 Exp $
+/* ######################################################################
+
+   Octagon 5066 MTD Driver. 
+  
+   The Octagon 5066 is a SBC based on AMD's 586-WB running at 133 MHZ. It
+   comes with a builtin AMD 29F016 flash chip and a socketed EEPROM that
+   is replacable by flash. Both units are mapped through a multiplexer
+   into a 32k memory window at 0xe8000. The control register for the 
+   multiplexing unit is located at IO 0x208 with a bit map of
+     0-5 Page Selection in 32k increments
+     6-7 Device selection:
+        00 SSD off
+        01 SSD 0 (Socket)
+        10 SSD 1 (Flash chip)
+        11 undefined
+  
+   On each SSD, the first 128k is reserved for use by the bios
+   (actually it IS the bios..) This only matters if you are booting off the 
+   flash, you must not put a file system starting there.
+   
+   The driver tries to do a detection algorithm to guess what sort of devices
+   are plugged into the sockets.
+   
+   ##################################################################### */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <asm/io.h>
+
+#include <linux/mtd/map.h>
+
+#define WINDOW_START 0xe8000
+#define WINDOW_LENGTH 0x8000
+#define WINDOW_SHIFT 27
+#define WINDOW_MASK 0x7FFF
+#define PAGE_IO 0x208
+
+static volatile char page_n_dev = 0;
+static unsigned long iomapadr;
+static spinlock_t oct5066_spin = SPIN_LOCK_UNLOCKED;
+
+/*
+ * We use map_priv_1 to identify which device we are.
+ */
+
+static void __oct5066_page(struct map_info *map, __u8 byte)
+{
+	outb(byte,PAGE_IO);
+	page_n_dev = byte;
+}
+
+static inline void oct5066_page(struct map_info *map, unsigned long ofs)
+{
+	__u8 byte = map->map_priv_1 | (ofs >> WINDOW_SHIFT);
+	
+	if (page_n_dev != byte)
+		__oct5066_page(map, byte);
+}
+
+
+static __u8 oct5066_read8(struct map_info *map, unsigned long ofs)
+{
+	__u8 ret;
+	spin_lock(&oct5066_spin);
+	oct5066_page(map, ofs);
+	ret = readb(iomapadr + (ofs & WINDOW_MASK));
+	spin_unlock(&oct5066_spin);
+	return ret;
+}
+
+static __u16 oct5066_read16(struct map_info *map, unsigned long ofs)
+{
+	__u16 ret;
+	spin_lock(&oct5066_spin);
+	oct5066_page(map, ofs);
+	ret = readw(iomapadr + (ofs & WINDOW_MASK));
+	spin_unlock(&oct5066_spin);
+	return ret;
+}
+
+static __u32 oct5066_read32(struct map_info *map, unsigned long ofs)
+{
+	__u32 ret;
+	spin_lock(&oct5066_spin);
+	oct5066_page(map, ofs);
+	ret = readl(iomapadr + (ofs & WINDOW_MASK));
+	spin_unlock(&oct5066_spin);
+	return ret;
+}
+
+static void oct5066_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	while(len) {
+		unsigned long thislen = len;
+		if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
+			thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
+		
+		spin_lock(&oct5066_spin);
+		oct5066_page(map, from);
+		memcpy_fromio(to, iomapadr + from, thislen);
+		spin_unlock(&oct5066_spin);
+		to += thislen;
+		from += thislen;
+		len -= thislen;
+	}
+}
+
+static void oct5066_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	spin_lock(&oct5066_spin);
+	oct5066_page(map, adr);
+	writeb(d, iomapadr + (adr & WINDOW_MASK));
+	spin_unlock(&oct5066_spin);
+}
+
+static void oct5066_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	spin_lock(&oct5066_spin);
+	oct5066_page(map, adr);
+	writew(d, iomapadr + (adr & WINDOW_MASK));
+	spin_unlock(&oct5066_spin);
+}
+
+static void oct5066_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	spin_lock(&oct5066_spin);
+	oct5066_page(map, adr);
+	writel(d, iomapadr + (adr & WINDOW_MASK));
+	spin_unlock(&oct5066_spin);
+}
+
+static void oct5066_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	while(len) {
+		unsigned long thislen = len;
+		if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
+			thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
+		
+		spin_lock(&oct5066_spin);
+		oct5066_page(map, to);
+		memcpy_toio(iomapadr + to, from, thislen);
+		spin_unlock(&oct5066_spin);
+		to += thislen;
+		from += thislen;
+		len -= thislen;
+	}
+}
+
+static struct map_info oct5066_map[2] = {
+	{
+		name: "Octagon 5066 Socket",
+		size: 512 * 1024,
+		buswidth: 1,
+		read8: oct5066_read8,
+		read16: oct5066_read16,
+		read32: oct5066_read32,
+		copy_from: oct5066_copy_from,
+		write8: oct5066_write8,
+		write16: oct5066_write16,
+		write32: oct5066_write32,
+		copy_to: oct5066_copy_to,
+		map_priv_1: 1<<6
+	},
+	{
+		name: "Octagon 5066 Internal Flash",
+		size: 2 * 1024 * 1024,
+		buswidth: 1,
+		read8: oct5066_read8,
+		read16: oct5066_read16,
+		read32: oct5066_read32,
+		copy_from: oct5066_copy_from,
+		write8: oct5066_write8,
+		write16: oct5066_write16,
+		write32: oct5066_write32,
+		copy_to: oct5066_copy_to,
+		map_priv_1: 2<<6
+	}
+};
+
+static struct mtd_info *oct5066_mtd[2] = {NULL, NULL};
+
+// OctProbe - Sense if this is an octagon card
+// ---------------------------------------------------------------------
+/* Perform a simple validity test, we map the window select SSD0 and
+   change pages while monitoring the window. A change in the window, 
+   controlled by the PAGE_IO port is a functioning 5066 board. This will
+   fail if the thing in the socket is set to a uniform value. */
+static int __init OctProbe(void)
+{
+   unsigned int Base = (1 << 6);
+   unsigned long I;
+   unsigned long Values[10];
+   for (I = 0; I != 20; I++)
+   {
+      outb(Base + (I%10),PAGE_IO);
+      if (I < 10)
+      {
+	 // Record the value and check for uniqueness
+	 Values[I%10] = readl(iomapadr);
+	 if (I > 0 && Values[I%10] == Values[0])
+	    return -EAGAIN;
+      }      
+      else
+      {
+	 // Make sure we get the same values on the second pass
+	 if (Values[I%10] != readl(iomapadr))
+	    return -EAGAIN;
+      }      
+   }
+   return 0;
+}
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_oct5066 init_module
+#define cleanup_oct5066 cleanup_module
+#endif
+
+void cleanup_oct5066(void)
+{
+	int i;
+	for (i=0; i<2; i++) {
+		if (oct5066_mtd[i]) {
+			del_mtd_device(oct5066_mtd[i]);
+			map_destroy(oct5066_mtd[i]);
+		}
+	}
+	iounmap((void *)iomapadr);
+	release_region(PAGE_IO,1);
+}
+
+int __init init_oct5066(void)
+{
+	int i;
+	
+	// Do an autoprobe sequence
+	if (check_region(PAGE_IO,1) != 0)
+		{
+			printk("5066: Page Register in Use\n");
+			return -EAGAIN;
+		}
+	iomapadr = (unsigned long)ioremap(WINDOW_START, WINDOW_LENGTH);
+	if (!iomapadr) {
+		printk("Failed to ioremap memory region\n");
+		return -EIO;
+	}
+	if (OctProbe() != 0)
+		{
+			printk("5066: Octagon Probe Failed, is this an Octagon 5066 SBC?\n");
+			iounmap((void *)iomapadr);
+			return -EAGAIN;
+		}
+	
+	request_region(PAGE_IO,1,"Octagon SSD");
+	
+	// Print out our little header..
+	printk("Octagon 5066 SSD IO:0x%x MEM:0x%x-0x%x\n",PAGE_IO,WINDOW_START,
+	       WINDOW_START+WINDOW_LENGTH);
+	
+	for (i=0; i<2; i++) {
+		oct5066_mtd[i] = do_map_probe("cfi", &oct5066_map[i]);
+		if (!oct5066_mtd[i])
+			oct5066_mtd[i] = do_map_probe("jedec", &oct5066_map[i]);
+		if (!oct5066_mtd[i])
+			oct5066_mtd[i] = do_map_probe("ram", &oct5066_map[i]);
+		if (!oct5066_mtd[i])
+			oct5066_mtd[i] = do_map_probe("rom", &oct5066_map[i]);
+		if (oct5066_mtd[i]) {
+			oct5066_mtd[i]->module = THIS_MODULE;
+			add_mtd_device(oct5066_mtd[i]);
+		}
+	}
+	
+	if (!oct5066_mtd[0] && !oct5066_mtd[1]) {
+		cleanup_oct5066();
+		return -ENXIO;
+	}	  
+	
+	return 0;
+}
+
+module_init(init_oct5066);
+module_exit(cleanup_oct5066);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/maps/physmap.c linux/drivers/mtd/maps/physmap.c
--- v2.4.5/linux/drivers/mtd/maps/physmap.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/physmap.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,119 @@
+/*
+ * $Id: physmap.c,v 1.13 2001/06/10 00:14:55 dwmw2 Exp $
+ *
+ * Normal mappings of chips in physical memory
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/config.h>
+
+
+#define WINDOW_ADDR CONFIG_MTD_PHYSMAP_START
+#define WINDOW_SIZE CONFIG_MTD_PHYSMAP_LEN
+#define BUSWIDTH CONFIG_MTD_PHYSMAP_BUSWIDTH
+
+static struct mtd_info *mymtd;
+
+__u8 physmap_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+__u16 physmap_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+__u32 physmap_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void physmap_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void physmap_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void physmap_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+struct map_info physmap_map = {
+	name: "Physically mapped flash",
+	size: WINDOW_SIZE,
+	buswidth: BUSWIDTH,
+	read8: physmap_read8,
+	read16: physmap_read16,
+	read32: physmap_read32,
+	copy_from: physmap_copy_from,
+	write8: physmap_write8,
+	write16: physmap_write16,
+	write32: physmap_write32,
+	copy_to: physmap_copy_to
+};
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_physmap init_module
+#define cleanup_physmap cleanup_module
+#endif
+
+int __init init_physmap(void)
+{
+       	printk(KERN_NOTICE "physmap flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
+	physmap_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
+
+	if (!physmap_map.map_priv_1) {
+		printk("Failed to ioremap\n");
+		return -EIO;
+	}
+	mymtd = do_map_probe("cfi", &physmap_map);
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+
+		add_mtd_device(mymtd);
+		return 0;
+	}
+
+	iounmap((void *)physmap_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_physmap(void)
+{
+	if (mymtd) {
+		del_mtd_device(mymtd);
+		map_destroy(mymtd);
+	}
+	if (physmap_map.map_priv_1) {
+		iounmap((void *)physmap_map.map_priv_1);
+		physmap_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_physmap);
+module_exit(cleanup_physmap);
+
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/maps/pnc2000.c linux/drivers/mtd/maps/pnc2000.c
--- v2.4.5/linux/drivers/mtd/maps/pnc2000.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/pnc2000.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,136 @@
+/*
+ *	pnc2000.c - mapper for Photron PNC-2000 board.
+ *
+ * Copyright (C) 2000 Crossnet Co. <info@crossnet.co.jp>
+ *
+ * This code is GPL
+ *
+ * $Id: pnc2000.c,v 1.8 2001/06/10 00:09:45 dwmw2 Exp $
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+
+#define WINDOW_ADDR 0xbf000000
+#define WINDOW_SIZE 0x00400000
+
+/* 
+ * MAP DRIVER STUFF
+ */
+
+__u8 pnc_read8(struct map_info *map, unsigned long ofs)
+{
+  return *(__u8 *)(WINDOW_ADDR + ofs);
+}
+
+__u16 pnc_read16(struct map_info *map, unsigned long ofs)
+{
+  return *(__u16 *)(WINDOW_ADDR + ofs);
+}
+
+__u32 pnc_read32(struct map_info *map, unsigned long ofs)
+{
+  return *(volatile unsigned int *)(WINDOW_ADDR + ofs);
+}
+
+void pnc_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+  memcpy(to, (void *)(WINDOW_ADDR + from), len);
+}
+
+void pnc_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+  *(__u8 *)(WINDOW_ADDR + adr) = d;
+}
+
+void pnc_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+  *(__u16 *)(WINDOW_ADDR + adr) = d;
+}
+
+void pnc_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+  *(__u32 *)(WINDOW_ADDR + adr) = d;
+}
+
+void pnc_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+  memcpy((void *)(WINDOW_ADDR + to), from, len);
+}
+
+struct map_info pnc_map = {
+	name: "PNC-2000",
+	size: WINDOW_SIZE,
+	buswidth: 4,
+	read8: pnc_read8,
+	read16: pnc_read16,
+	read32: pnc_read32,
+	copy_from: pnc_copy_from,
+	write8: pnc_write8,
+	write16: pnc_write16,
+	write32: pnc_write32,
+	copy_to: pnc_copy_to
+};
+
+
+/*
+ * MTD 'PARTITIONING' STUFF 
+ */
+static struct mtd_partition pnc_partitions[3] = {
+	{
+		name: "PNC-2000 boot firmware",
+		size: 0x20000,
+		offset: 0
+	},
+	{
+		name: "PNC-2000 kernel",
+		size: 0x1a0000,
+		offset: 0x20000
+	},
+	{
+		name: "PNC-2000 filesystem",
+		size: 0x240000,
+		offset: 0x1c0000
+	}
+};
+
+/* 
+ * This is the master MTD device for which all the others are just
+ * auto-relocating aliases.
+ */
+static struct mtd_info *mymtd;
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_pnc2000 init_module
+#define cleanup_pnc2000 cleanup_module
+#endif
+
+int __init init_pnc2000(void)
+{
+	printk(KERN_NOTICE "Photron PNC-2000 flash mapping: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
+
+	mymtd = do_map_probe("cfi", &pnc_map);
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+		return add_mtd_partitions(mymtd, pnc_partitions, 3);
+	}
+
+	return -ENXIO;
+}
+
+static void __exit cleanup_pnc2000(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+	}
+}
+
+module_init(init_pnc2000);
+module_exit(cleanup_pnc2000);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/maps/rpxlite.c linux/drivers/mtd/maps/rpxlite.c
--- v2.4.5/linux/drivers/mtd/maps/rpxlite.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/rpxlite.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,112 @@
+/*
+ * $Id: rpxlite.c,v 1.12 2001/04/26 15:40:23 dwmw2 Exp $
+ *
+ * Handle mapping of the flash on the RPX Lite and CLLF boards
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+
+
+#define WINDOW_ADDR 0xfe000000
+#define WINDOW_SIZE 0x800000
+
+static struct mtd_info *mymtd;
+
+__u8 rpxlite_read8(struct map_info *map, unsigned long ofs)
+{
+	return readb(map->map_priv_1 + ofs);
+}
+
+__u16 rpxlite_read16(struct map_info *map, unsigned long ofs)
+{
+	return readw(map->map_priv_1 + ofs);
+}
+
+__u32 rpxlite_read32(struct map_info *map, unsigned long ofs)
+{
+	return readl(map->map_priv_1 + ofs);
+}
+
+void rpxlite_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
+}
+
+void rpxlite_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	writeb(d, map->map_priv_1 + adr);
+}
+
+void rpxlite_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	writew(d, map->map_priv_1 + adr);
+}
+
+void rpxlite_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	writel(d, map->map_priv_1 + adr);
+}
+
+void rpxlite_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio((void *)(map->map_priv_1 + to), from, len);
+}
+
+struct map_info rpxlite_map = {
+	name: "RPX",
+	size: WINDOW_SIZE,
+	buswidth: 4,
+	read8: rpxlite_read8,
+	read16: rpxlite_read16,
+	read32: rpxlite_read32,
+	copy_from: rpxlite_copy_from,
+	write8: rpxlite_write8,
+	write16: rpxlite_write16,
+	write32: rpxlite_write32,
+	copy_to: rpxlite_copy_to
+};
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_rpxlite init_module
+#define cleanup_rpxlite cleanup_module
+#endif
+
+int __init init_rpxlite(void)
+{
+	printk(KERN_NOTICE "RPX Lite or CLLF flash device: %x at %x\n", WINDOW_SIZE*4, WINDOW_ADDR);
+	rpxlite_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE * 4);
+
+	if (!rpxlite_map.map_priv_1) {
+		printk("Failed to ioremap\n");
+		return -EIO;
+	}
+	mymtd = do_map_probe("cfi", &rpxlite_map);
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+		add_mtd_device(mymtd);
+		return 0;
+	}
+
+	iounmap((void *)rpxlite_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_rpxlite(void)
+{
+	if (mymtd) {
+		del_mtd_device(mymtd);
+		map_destroy(mymtd);
+	}
+	if (rpxlite_map.map_priv_1) {
+		iounmap((void *)rpxlite_map.map_priv_1);
+		rpxlite_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_rpxlite);
+module_exit(cleanup_rpxlite);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/maps/sa1100-flash.c linux/drivers/mtd/maps/sa1100-flash.c
--- v2.4.5/linux/drivers/mtd/maps/sa1100-flash.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/sa1100-flash.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,644 @@
+/*
+ * Flash memory access on SA11x0 based devices
+ * 
+ * (C) 2000 Nicolas Pitre <nico@cam.org>
+ * 
+ * $Id: sa1100-flash.c,v 1.15 2001/06/02 18:29:22 nico Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/hardware.h>
+
+
+#ifndef CONFIG_ARCH_SA1100
+#error This is for SA1100 architecture only
+#endif
+
+
+#define WINDOW_ADDR 0xe8000000
+
+static __u8 sa1100_read8(struct map_info *map, unsigned long ofs)
+{
+	return *(__u8 *)(WINDOW_ADDR + ofs);
+}
+
+static __u16 sa1100_read16(struct map_info *map, unsigned long ofs)
+{
+	return *(__u16 *)(WINDOW_ADDR + ofs);
+}
+
+static __u32 sa1100_read32(struct map_info *map, unsigned long ofs)
+{
+	return *(__u32 *)(WINDOW_ADDR + ofs);
+}
+
+static void sa1100_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy(to, (void *)(WINDOW_ADDR + from), len);
+}
+
+static void sa1100_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	*(__u8 *)(WINDOW_ADDR + adr) = d;
+}
+
+static void sa1100_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	*(__u16 *)(WINDOW_ADDR + adr) = d;
+}
+
+static void sa1100_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	*(__u32 *)(WINDOW_ADDR + adr) = d;
+}
+
+static void sa1100_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy((void *)(WINDOW_ADDR + to), from, len);
+}
+
+
+#ifdef CONFIG_SA1100_BITSY
+
+static void bitsy_set_vpp(struct map_info *map, int vpp)
+{
+	if (vpp)
+		set_bitsy_egpio(EGPIO_BITSY_VPP_ON);
+	else
+		clr_bitsy_egpio(EGPIO_BITSY_VPP_ON);
+}
+
+#endif
+
+#ifdef CONFIG_SA1100_JORNADA720
+
+static void jornada720_set_vpp(int vpp)
+{
+  if (vpp)
+      PPSR |= 0x80;
+  else
+      PPSR &= ~0x80;
+  PPDR |= 0x80;
+}
+
+#endif
+
+static struct map_info sa1100_map = {
+	name:		"SA1100 flash",
+	read8:		sa1100_read8,
+	read16:		sa1100_read16,
+	read32:		sa1100_read32,
+	copy_from:	sa1100_copy_from,
+	write8:		sa1100_write8,
+	write16:	sa1100_write16,
+	write32:	sa1100_write32,
+	copy_to:	sa1100_copy_to
+};
+
+
+/*
+ * Here are partition information for all known SA1100-based devices.
+ * See include/linux/mtd/partitions.h for definition of the mtd_partition
+ * structure.
+ * 
+ * The *_max_flash_size is the maximum possible mapped flash size which
+ * is not necessarily the actual flash size.  It must correspond to the 
+ * value specified in the mapping definition defined by the
+ * "struct map_desc *_io_desc" for the corresponding machine.
+ */
+
+#ifdef CONFIG_SA1100_ASSABET
+
+/* Phase 4 Assabet has two 28F160B3 flash parts in bank 0: */
+static unsigned long assabet4_max_flash_size = 0x00400000;
+static struct mtd_partition assabet4_partitions[] = {
+        {
+                name: "bootloader",
+                size: 0x00020000,
+                offset: 0,
+                mask_flags: MTD_WRITEABLE
+        },{
+                name: "bootloader params",
+                size: 0x00020000,
+                offset: MTDPART_OFS_APPEND,
+                mask_flags: MTD_WRITEABLE
+        },{
+                name: "jffs",
+                size: MTDPART_SIZ_FULL,
+                offset: MTDPART_OFS_APPEND
+        }
+};
+
+/* Phase 5 Assabet has two 28F128J3A flash parts in bank 0: */
+static unsigned long assabet5_max_flash_size = 0x02000000;
+static struct mtd_partition assabet5_partitions[] = {
+        {
+                name: "bootloader",
+                size: 0x00040000,
+                offset: 0,
+                mask_flags: MTD_WRITEABLE
+        },{
+                name: "bootloader params",
+                size: 0x00040000,
+                offset: MTDPART_OFS_APPEND,
+                mask_flags: MTD_WRITEABLE
+        },{
+                name: "jffs",
+                size: MTDPART_SIZ_FULL,
+                offset: MTDPART_OFS_APPEND
+        }
+};
+
+#define assabet_max_flash_size assabet5_max_flash_size
+#define assabet_partitions     assabet5_partitions
+
+#endif
+
+#ifdef CONFIG_SA1100_FLEXANET
+
+/* Flexanet has two 28F128J3A flash parts in bank 0: */
+static unsigned long flexanet_max_flash_size = 0x02000000;
+static struct mtd_partition flexanet_partitions[] = {
+        {
+                name: "bootloader",
+                size: 0x00040000,
+                offset: 0,
+                mask_flags: MTD_WRITEABLE
+        },{
+                name: "bootloader params",
+                size: 0x00040000,
+                offset: MTDPART_OFS_APPEND,
+                mask_flags: MTD_WRITEABLE
+        },{
+                name: "kernel",
+                size: 0x000C0000,
+                offset: MTDPART_OFS_APPEND,
+                mask_flags: MTD_WRITEABLE
+        },{
+                name: "altkernel",
+                size: 0x000C0000,
+                offset: MTDPART_OFS_APPEND,
+                mask_flags: MTD_WRITEABLE
+        },{
+                name: "root",
+                size: 0x00400000,
+                offset: MTDPART_OFS_APPEND,
+                mask_flags: MTD_WRITEABLE
+        },{
+                name: "free1",
+                size: 0x00300000,
+                offset: MTDPART_OFS_APPEND,
+                mask_flags: MTD_WRITEABLE
+        },{
+                name: "free2",
+                size: 0x00300000,
+                offset: MTDPART_OFS_APPEND,
+                mask_flags: MTD_WRITEABLE
+        },{
+                name: "free3",
+                size: MTDPART_SIZ_FULL,
+                offset: MTDPART_OFS_APPEND,
+                mask_flags: MTD_WRITEABLE
+        }
+};
+
+#endif
+
+#ifdef CONFIG_SA1100_HUW_WEBPANEL
+static unsigned long huw_webpanel_max_flash_size = 0x01000000;
+static struct mtd_partition huw_webpanel_partitions[] = {
+	{ 
+	  name: "Loader",
+	  size: 0x00040000,
+	  offset: 0,
+	},{
+	  name: "Sector 1",
+	  size: 0x00040000,
+	  offset: MTDPART_OFS_APPEND,
+	},{
+	  size: MTDPART_SIZ_FULL,
+	  offset: MTDPART_OFS_APPEND,
+	}
+};
+#endif /* CONFIG_SA1100_HUW_WEBPANEL */
+
+
+#ifdef CONFIG_SA1100_BITSY
+
+static unsigned long bitsy_max_flash_size = 0x02000000;
+static struct mtd_partition bitsy_partitions[] = {
+	{
+		name: "BITSY boot firmware",
+		size: 0x00040000,
+		offset: 0,
+		mask_flags: MTD_WRITEABLE  /* force read-only */
+	},{
+		name: "BITSY kernel",
+		size: 0x00080000,
+		offset: 0x40000
+	},{
+		name: "BITSY params",
+		size: 0x00040000,
+		offset: 0xC0000
+	},{
+#ifdef CONFIG_JFFS2_FS
+		name: "BITSY root jffs2",
+		offset: 0x00100000,
+		size: MTDPART_SIZ_FULL
+#else
+		name: "BITSY initrd",
+		size: 0x00100000,
+		offset: 0x00100000
+	},{
+		name: "BITSY root cramfs",
+		size: 0x00300000,
+		offset: 0x00200000
+	},{
+		name: "BITSY usr cramfs",
+		size: 0x00800000,
+		offset: 0x00500000
+	},{
+		name: "BITSY usr local",
+		offset: 0x00d00000,
+		size: MTDPART_SIZ_FULL
+#endif
+	}
+};
+
+#endif
+#ifdef CONFIG_SA1100_FREEBIRD
+static unsigned long freebird_max_flash_size = 0x02000000;
+static struct mtd_partition freebird_partitions[] = {
+#if CONFIG_SA1100_FREEBIRD_NEW
+    {
+     name: "firmware",
+     size: 0x00040000,
+     offset: 0,
+     mask_flags: MTD_WRITEABLE  /* force read-only */
+    },{
+     name: "kernel",
+     size: 0x00080000,
+     offset: 0x40000
+    },{
+     name: "params",
+     size: 0x00040000,
+     offset: 0xC0000
+    },{
+     name: "initrd",
+     size: 0x00100000,
+     offset: 0x00100000
+    },{
+     name: "root cramfs",
+     size: 0x00300000,
+     offset: 0x00200000
+    },{
+     name: "usr cramfs",
+     size: 0x00C00000,
+     offset: 0x00500000
+    },{
+	 name: "local",
+	 offset: 0x01100000,
+	 size: MTDPART_SIZ_FULL 
+	}
+#else
+	{ offset: 0,            		size: 0x00040000,   },
+	{ offset: MTDPART_OFS_APPEND,   size: 0x000c0000,   },
+	{ offset: MTDPART_OFS_APPEND,	size: 0x00400000,	},
+	{ offset: MTDPART_OFS_APPEND,   size: MTDPART_SIZ_FULL  }
+#endif
+	};
+#endif
+																									
+
+#ifdef CONFIG_SA1100_CERF
+
+static unsigned long cerf_max_flash_size = 0x01000000;
+static struct mtd_partition cerf_partitions[] = {
+	{ offset: 0,			size: 0x00800000 	},
+	{ offset: MTDPART_OFS_APPEND,	size: 0x00800000 	}
+};
+
+#endif
+
+#ifdef CONFIG_SA1100_GRAPHICSCLIENT
+
+static unsigned long graphicsclient_max_flash_size = 0x01000000;
+static struct mtd_partition graphicsclient_partitions[] = {
+	{ 
+	 name: "Bootloader + zImage",
+	 offset: 0,
+	 size: 0x100000
+	},
+	{ 
+         name: "ramdisk.gz",
+         offset: MTDPART_OFS_APPEND,
+         size: 0x300000 		
+	},
+	{ 
+	  name: "User FS",
+          offset: MTDPART_OFS_APPEND,	
+          size: MTDPART_SIZ_FULL
+	}
+};
+
+#endif
+
+#ifdef CONFIG_SA1100_LART
+
+static unsigned long lart_max_flash_size = 0x00400000;
+static struct mtd_partition lart_partitions[] = {
+	{ offset: 0,			size: 0x020000 		},
+	{ offset: MTDPART_OFS_APPEND,	size: 0x0e0000 		},
+	{ offset: MTDPART_OFS_APPEND,	size: MTDPART_SIZ_FULL 	}
+};
+
+#endif
+
+#ifdef CONFIG_SA1100_PANGOLIN
+
+static unsigned long pangolin_max_flash_size = 0x04000000;
+static struct mtd_partition pangolin_partitions[] = {
+	{
+	  name: "boot firmware",
+	  offset: 0x00000000,
+	  size: 0x00080000,
+	  mask_flags: MTD_WRITEABLE,  /* force read-only */
+	},
+	{
+	  name: "kernel",
+	  offset: 0x00080000,
+	  size: 0x00100000,
+	},
+	{
+	  name: "initrd",
+	  offset: 0x00180000,
+	  size: 0x00200000,
+	},
+	{
+	  name: "initrd-test",
+	  offset: 0x00400000,
+	  size: 0x03C00000,
+	}
+};
+
+#endif
+
+#ifdef CONFIG_SA1100_YOPY
+
+static unsigned long yopy_max_flash_size = 0x08000000;
+static struct mtd_partition yopy_partitions[] = {
+	{
+		name: "boot firmware",
+		offset: 0x00000000,
+		size: 0x00040000,
+		mask_flags: MTD_WRITEABLE,  /* force read-only */
+	},
+	{
+		name: "kernel",
+		offset: 0x00080000,
+		size: 0x00080000,
+	},
+	{
+		name: "initrd",
+		offset: 0x00100000,
+		size: 0x00300000,
+	},
+	{
+		name: "root",
+		offset: 0x00400000,
+		size: 0x01000000,
+	},
+};
+
+#endif
+
+#ifdef CONFIG_SA1100_JORNADA720
+
+static unsigned long jornada720_max_flash_size = 0x02000000;
+static struct mtd_partition jornada720_partitions[] = {
+	{
+		name: "JORNADA720 boot firmware",
+		size: 0x00040000,
+		offset: 0,
+		mask_flags: MTD_WRITEABLE  /* force read-only */
+	},{
+		name: "JORNADA720 kernel",
+		size: 0x000c0000,
+		offset: 0x40000
+	},{
+		name: "JORNADA720 params",
+		size: 0x00040000,
+		offset: 0x100000
+	},{
+		name: "JORNADA720 initrd",
+		size: 0x00100000,
+		offset: 0x00140000
+	},{
+		name: "JORNADA720 root cramfs",
+		size: 0x00300000,
+		offset: 0x00240000
+	},{
+		name: "JORNADA720 usr cramfs",
+		size: 0x00800000,
+		offset: 0x00540000
+	},{
+		name: "JORNADA720 usr local",
+		offset: 0x00d00000,
+		size: 0  /* will expand to the end of the flash */
+	}
+};
+#endif
+
+#ifdef CONFIG_SA1100_SHERMAN
+
+static unsigned long sherman_max_flash_size = 0x02000000;
+static struct mtd_partition sherman_partitions[] = {
+	{ offset: 0,			size: 0x50000 	},
+	{ offset: MTDPART_OFS_APPEND,	size: 0x70000 	},
+	{ offset: MTDPART_OFS_APPEND,	size: 0x600000 	},
+	{ offset: MTDPART_OFS_APPEND,	size: 0xA0000 	}
+};
+
+#endif
+
+#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
+
+
+extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
+extern int parse_bootldr_partitions(struct mtd_info *master, struct mtd_partition **pparts);
+
+static struct mtd_partition *parsed_parts;
+static struct mtd_info *mymtd;
+
+int __init sa1100_mtd_init(void)
+{
+	struct mtd_partition *parts;
+	int nb_parts = 0;
+	int parsed_nr_parts = 0;
+	char *part_type;
+	
+	sa1100_map.buswidth = (MSC0 & MSC_RBW) ? 2 : 4;
+	printk(KERN_NOTICE "SA1100 flash: probing %d-bit flash bus\n", sa1100_map.buswidth*8);
+	mymtd = do_map_probe("cfi", &sa1100_map);
+	if (!mymtd)
+		return -ENXIO;
+	mymtd->module = THIS_MODULE;
+
+	/*
+	 * Static partition definition selection
+	 */
+	part_type = "static";
+#ifdef CONFIG_SA1100_ASSABET
+	if (machine_is_assabet()) {
+		parts = assabet_partitions;
+		nb_parts = NB_OF(assabet_partitions);
+		sa1100_map.size = assabet_max_flash_size;
+	}
+#endif
+
+#ifdef CONFIG_SA1100_HUW_WEBPANEL
+	if (machine_is_huw_webpanel()) {
+		parts = huw_webpanel_partitions;
+		nb_parts = NB_OF(huw_webpanel_partitions);
+		sa1100_map.size = huw_webpanel_max_flash_size;
+	}
+#endif
+
+#ifdef CONFIG_SA1100_BITSY
+	if (machine_is_bitsy()) {
+		parts = bitsy_partitions;
+		nb_parts = NB_OF(bitsy_partitions);
+		sa1100_map.size = bitsy_max_flash_size;
+		sa1100_map.set_vpp = bitsy_set_vpp;
+	}
+#endif
+#ifdef CONFIG_SA1100_FREEBIRD
+	if (machine_is_freebird()) {
+		parts = freebird_partitions;
+		nb_parts = NB_OF(freebird_partitions);
+		sa1100_map.size = freebird_max_flash_size;
+	}
+#endif
+#ifdef CONFIG_SA1100_CERF
+	if (machine_is_cerf()) {
+		parts = cerf_partitions;
+		nb_parts = NB_OF(cerf_partitions);
+		sa1100_map.size = cerf_max_flash_size;
+	}
+#endif
+#ifdef CONFIG_SA1100_GRAPHICSCLIENT
+	if (machine_is_graphicsclient()) {
+		parts = graphicsclient_partitions;
+		nb_parts = NB_OF(graphicsclient_partitions);
+		sa1100_map.size = graphicsclient_max_flash_size;
+	}
+#endif
+#ifdef CONFIG_SA1100_LART
+	if (machine_is_lart()) {
+		parts = lart_partitions;
+		nb_parts = NB_OF(lart_partitions);
+		sa1100_map.size = lart_max_flash_size;
+	}
+#endif
+#ifdef CONFIG_SA1100_PANGOLIN
+	if (machine_is_pangolin()) {
+		parts = pangolin_partitions;
+		nb_parts = NB_OF(pangolin_partitions);
+		sa1100_map.size = pangolin_max_flash_size;
+	}
+#endif
+#ifdef CONFIG_SA1100_JORNADA720
+	if (machine_is_jornada720()) {
+		parts = jornada720_partitions;
+		nb_parts = NB_OF(jornada720_partitions);
+		sa1100_map.size = jornada720_max_flash_size;
+		sa1100_map.set_vpp = jornada720_set_vpp;
+	}
+#endif
+#ifdef CONFIG_SA1100_YOPY
+	if (machine_is_yopy()) {
+		parts = yopy_partitions;
+		nb_parts = NB_OF(yopy_partitions);
+		sa1100_map.size = yopy_max_flash_size;
+	}
+#endif
+#ifdef CONFIG_SA1100_SHERMAN
+	if (machine_is_sherman()) {
+		parts = sherman_partitions;
+		nb_parts = NB_OF(sherman_partitions);
+		sa1100_map.size = sherman_max_flash_size;
+	}
+#endif
+#ifdef CONFIG_SA1100_FLEXANET
+	if (machine_is_flexanet()) {
+		parts = flexanet_partitions;
+		nb_parts = NB_OF(flexanet_partitions);
+		sa1100_map.size = flexanet_max_flash_size;
+	}
+#endif
+
+
+	if (!nb_parts) {
+		printk(KERN_WARNING "MTD: no known flash definition for this SA1100 machine\n");
+		return -ENXIO;
+	}
+
+
+	/*
+	 * Dynamic partition selection stuff (might override the static ones)
+	 */
+#ifdef CONFIG_MTD_SA1100_REDBOOT_PARTITIONS
+	if (parsed_nr_parts == 0) {
+		int ret = parse_redboot_partitions(mymtd, &parsed_parts);
+		
+		if (ret > 0) {
+			part_type = "RedBoot";
+			parsed_nr_parts = ret;
+		}
+	}
+#endif
+#ifdef CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS
+	if (parsed_nr_parts == 0) {
+		int ret = parse_bootldr_partitions(mymtd, &parsed_parts);
+		if (ret > 0) {
+			part_type = "Compaq bootldr";
+			parsed_nr_parts = ret;
+		}
+	}
+#endif
+
+	if (parsed_nr_parts > 0) {
+		parts = parsed_parts;
+		nb_parts = parsed_nr_parts;
+	}
+
+	if (nb_parts == 0) {
+		printk(KERN_NOTICE "SA1100 flash: no partition info available, registering whole flash at once\n");
+		add_mtd_device(mymtd);
+	} else {
+		printk(KERN_NOTICE "Using %s partition definition\n", part_type);
+		add_mtd_partitions(mymtd, parts, nb_parts);
+	}
+	return 0;
+}
+
+static void __exit sa1100_mtd_cleanup(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+		if (parsed_parts)
+			kfree(parsed_parts);
+	}
+}
+
+module_init(sa1100_mtd_init);
+module_exit(sa1100_mtd_cleanup);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/maps/sbc_gxx.c linux/drivers/mtd/maps/sbc_gxx.c
--- v2.4.5/linux/drivers/mtd/maps/sbc_gxx.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/sbc_gxx.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,278 @@
+/* sbc_gxx.c -- MTD map driver for Arcom Control Systems SBC-MediaGX,
+                SBC-GXm and SBC-GX1 series boards.
+ 
+   Copyright (C) 2001 Arcom Control System Ltd
+ 
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+ 
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+ 
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+   $Id: sbc_gxx.c,v 1.17 2001/06/02 14:52:23 dwmw2 Exp $
+
+The SBC-MediaGX / SBC-GXx has up to 16 MiB of 
+Intel StrataFlash (28F320/28F640) in x8 mode.  
+
+This driver uses the CFI probe and Intel Extended Command Set drivers.
+
+The flash is accessed as follows:
+
+   16 kbyte memory window at 0xdc000-0xdffff
+   
+   Two IO address locations for paging
+   
+   0x258
+       bit 0-7: address bit 14-21
+   0x259
+       bit 0-1: address bit 22-23
+       bit 7:   0 - reset/powered down
+                1 - device enabled
+
+The single flash device is divided into 3 partition which appear as 
+separate MTD devices.
+
+25/04/2001 AJL (Arcom)  Modified signon strings and partition sizes
+                        (to support bzImages up to 638KiB-ish)
+*/
+
+// Includes
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <asm/io.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+// Defines
+
+// - Hardware specific
+
+#define WINDOW_START 0xdc000
+
+/* Number of bits in offset. */
+#define WINDOW_SHIFT 14
+#define WINDOW_LENGTH (1 << WINDOW_SHIFT)
+
+/* The bits for the offset into the window. */
+#define WINDOW_MASK (WINDOW_LENGTH-1)
+#define PAGE_IO 0x258
+#define PAGE_IO_SIZE 2
+
+/* bit 7 of 0x259 must be 1 to enable device. */
+#define DEVICE_ENABLE 0x8000
+
+// - Flash / Partition sizing
+
+#define MAX_SIZE_KiB             16384
+#define BOOT_PARTITION_SIZE_KiB  768
+#define DATA_PARTITION_SIZE_KiB  1280
+#define APP_PARTITION_SIZE_KiB   6144
+
+// Globals
+
+static volatile int page_in_window = -1; // Current page in window.
+static unsigned long iomapadr;
+static spinlock_t sbc_gxx_spin = SPIN_LOCK_UNLOCKED;
+
+/* partition_info gives details on the logical partitions that the split the 
+ * single flash device into. If the size if zero we use up to the end of the
+ * device. */
+static struct mtd_partition partition_info[]={
+    { name: "SBC-GXx flash boot partition", 
+      offset: 0, 
+      size:   BOOT_PARTITION_SIZE_KiB*1024 },
+    { name: "SBC-GXx flash data partition", 
+      offset: BOOT_PARTITION_SIZE_KiB*1024, 
+      size: (DATA_PARTITION_SIZE_KiB)*1024 },
+    { name: "SBC-GXx flash application partition", 
+      offset: (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 }
+};
+
+#define NUM_PARTITIONS 3
+
+static inline void sbc_gxx_page(struct map_info *map, unsigned long ofs)
+{
+	unsigned long page = ofs >> WINDOW_SHIFT;
+
+	if( page!=page_in_window ) {
+		outw( page | DEVICE_ENABLE, PAGE_IO );
+		page_in_window = page;
+	}
+}
+
+
+static __u8 sbc_gxx_read8(struct map_info *map, unsigned long ofs)
+{
+	__u8 ret;
+	spin_lock(&sbc_gxx_spin);
+	sbc_gxx_page(map, ofs);
+	ret = readb(iomapadr + (ofs & WINDOW_MASK));
+	spin_unlock(&sbc_gxx_spin);
+	return ret;
+}
+
+static __u16 sbc_gxx_read16(struct map_info *map, unsigned long ofs)
+{
+	__u16 ret;
+	spin_lock(&sbc_gxx_spin);
+	sbc_gxx_page(map, ofs);
+	ret = readw(iomapadr + (ofs & WINDOW_MASK));
+	spin_unlock(&sbc_gxx_spin);
+	return ret;
+}
+
+static __u32 sbc_gxx_read32(struct map_info *map, unsigned long ofs)
+{
+	__u32 ret;
+	spin_lock(&sbc_gxx_spin);
+	sbc_gxx_page(map, ofs);
+	ret = readl(iomapadr + (ofs & WINDOW_MASK));
+	spin_unlock(&sbc_gxx_spin);
+	return ret;
+}
+
+static void sbc_gxx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	while(len) {
+		unsigned long thislen = len;
+		if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
+			thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
+		
+		spin_lock(&sbc_gxx_spin);
+		sbc_gxx_page(map, from);
+		memcpy_fromio(to, iomapadr + (from & WINDOW_MASK), thislen);
+		spin_unlock(&sbc_gxx_spin);
+		(__u8*)to += thislen;
+		from += thislen;
+		len -= thislen;
+	}
+}
+
+static void sbc_gxx_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	spin_lock(&sbc_gxx_spin);
+	sbc_gxx_page(map, adr);
+	writeb(d, iomapadr + (adr & WINDOW_MASK));
+	spin_unlock(&sbc_gxx_spin);
+}
+
+static void sbc_gxx_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	spin_lock(&sbc_gxx_spin);
+	sbc_gxx_page(map, adr);
+	writew(d, iomapadr + (adr & WINDOW_MASK));
+	spin_unlock(&sbc_gxx_spin);
+}
+
+static void sbc_gxx_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	spin_lock(&sbc_gxx_spin);
+	sbc_gxx_page(map, adr);
+	writel(d, iomapadr + (adr & WINDOW_MASK));
+	spin_unlock(&sbc_gxx_spin);
+}
+
+static void sbc_gxx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{	
+	while(len) {
+		unsigned long thislen = len;
+		if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
+			thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
+		
+		spin_lock(&sbc_gxx_spin);
+		sbc_gxx_page(map, to);
+		memcpy_toio(iomapadr + (to & WINDOW_MASK), from, thislen);
+		spin_unlock(&sbc_gxx_spin);
+		to += thislen;
+		from += thislen;
+		len -= thislen;
+	}
+}
+
+static struct map_info sbc_gxx_map = {
+	name: "SBC-GXx flash",
+	size: MAX_SIZE_KiB*1024, /* this must be set to a maximum possible amount
+			 of flash so the cfi probe routines find all
+			 the chips */
+	buswidth: 1,
+	read8: sbc_gxx_read8,
+	read16: sbc_gxx_read16,
+	read32: sbc_gxx_read32,
+	copy_from: sbc_gxx_copy_from,
+	write8: sbc_gxx_write8,
+	write16: sbc_gxx_write16,
+	write32: sbc_gxx_write32,
+	copy_to: sbc_gxx_copy_to
+};
+
+/* MTD device for all of the flash. */
+static struct mtd_info *all_mtd;
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_sbc_gxx init_module
+#define cleanup_sbc_gxx cleanup_module
+#endif
+
+mod_exit_t cleanup_sbc_gxx(void)
+{
+	if( all_mtd ) {
+		del_mtd_partitions( all_mtd );
+		map_destroy( all_mtd );
+	}
+
+	iounmap((void *)iomapadr);
+	release_region(PAGE_IO,PAGE_IO_SIZE);
+}
+
+mod_init_t init_sbc_gxx(void)
+{
+	if (check_region(PAGE_IO,PAGE_IO_SIZE) != 0) {
+		printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n",
+			sbc_gxx_map.name,
+			PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1 );
+		return -EAGAIN;
+	}
+  	iomapadr = (unsigned long)ioremap(WINDOW_START, WINDOW_LENGTH);
+	if (!iomapadr) {
+		printk( KERN_ERR"%s: failed to ioremap memory region\n",
+			sbc_gxx_map.name );
+		return -EIO;
+	}
+	
+	request_region( PAGE_IO, PAGE_IO_SIZE, "SBC-GXx flash" );
+	
+	printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n",
+		sbc_gxx_map.name,
+		PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1,
+		WINDOW_START, WINDOW_START+WINDOW_LENGTH-1 );
+
+	/* Probe for chip. */
+	all_mtd = do_map_probe( "cfi", &sbc_gxx_map );
+	if( !all_mtd ) {
+		cleanup_sbc_gxx();
+		return -ENXIO;
+	}
+	
+	all_mtd->module=THIS_MODULE;
+
+	/* Create MTD devices for each partition. */
+	add_mtd_partitions(all_mtd, partition_info, NUM_PARTITIONS );
+
+	return 0;
+}
+
+module_init(init_sbc_gxx);
+module_exit(cleanup_sbc_gxx);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/maps/sc520cdp.c linux/drivers/mtd/maps/sc520cdp.c
--- v2.4.5/linux/drivers/mtd/maps/sc520cdp.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/sc520cdp.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,348 @@
+/* sc520cdp.c -- MTD map driver for AMD SC520 Customer Development Platform
+ *
+ * Copyright (C) 2001 Sysgo Real-Time Solutions GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: sc520cdp.c,v 1.7 2001/06/02 14:52:23 dwmw2 Exp $
+ *
+ *
+ * The SC520CDP is an evaluation board for the Elan SC520 processor available
+ * from AMD. It has two banks of 32-bit Flash ROM, each 8 Megabytes in size,
+ * and up to 512 KiB of 8-bit DIL Flash ROM.
+ * For details see http://www.amd.com/products/epd/desiging/evalboards/18.elansc520/520_cdp_brief/index.html
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+
+
+/*
+** The Embedded Systems BIOS decodes the first FLASH starting at
+** 0x8400000. This is a *terrible* place for it because accessing
+** the flash at this location causes the A22 address line to be high
+** (that's what 0x8400000 binary's ought to be). But this is the highest
+** order address line on the raw flash devices themselves!!
+** This causes the top HALF of the flash to be accessed first. Beyond
+** the physical limits of the flash, the flash chip aliases over (to
+** 0x880000 which causes the bottom half to be accessed. This splits the
+** flash into two and inverts it! If you then try to access this from another
+** program that does NOT do this insanity, then you *will* access the
+** first half of the flash, but not find what you expect there. That
+** stuff is in the *second* half! Similarly, the address used by the
+** BIOS for the second FLASH bank is also quite a bad choice.
+** If REPROGRAM_PAR is defined below (the default), then this driver will
+** choose more useful addresses for the FLASH banks by reprogramming the
+** responsible PARxx registers in the SC520's MMCR region. This will
+** cause the settings to be incompatible with the BIOS's settings, which
+** shouldn't be a problem since you are running Linux, (i.e. the BIOS is
+** not much use anyway). However, if you need to be compatible with
+** the BIOS for some reason, just undefine REPROGRAM_PAR.
+*/
+#define REPROGRAM_PAR
+
+
+
+#ifdef REPROGRAM_PAR
+
+/* These are the addresses we want.. */
+#define WINDOW_ADDR_0	0x08800000
+#define WINDOW_ADDR_1	0x09000000
+#define WINDOW_ADDR_2	0x09800000
+
+/* .. and these are the addresses the BIOS gives us */
+#define WINDOW_ADDR_0_BIOS	0x08400000
+#define WINDOW_ADDR_1_BIOS	0x08c00000
+#define WINDOW_ADDR_2_BIOS	0x09400000
+
+#else
+
+#define WINDOW_ADDR_0	0x08400000
+#define WINDOW_ADDR_1	0x08C00000
+#define WINDOW_ADDR_2	0x09400000
+
+#endif
+
+#define WINDOW_SIZE_0	0x00800000
+#define WINDOW_SIZE_1	0x00800000
+#define WINDOW_SIZE_2	0x00080000
+
+static __u8 sc520cdp_read8(struct map_info *map, unsigned long ofs)
+{
+	return readb(map->map_priv_1 + ofs);
+}
+
+static __u16 sc520cdp_read16(struct map_info *map, unsigned long ofs)
+{
+	return readw(map->map_priv_1 + ofs);
+}
+
+static __u32 sc520cdp_read32(struct map_info *map, unsigned long ofs)
+{
+	return readl(map->map_priv_1 + ofs);
+}
+
+static void sc520cdp_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
+}
+
+static void sc520cdp_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	writeb(d, map->map_priv_1 + adr);
+}
+
+static void sc520cdp_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	writew(d, map->map_priv_1 + adr);
+}
+
+static void sc520cdp_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	writel(d, map->map_priv_1 + adr);
+}
+
+static void sc520cdp_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio((void *)(map->map_priv_1 + to), from, len);
+}
+
+static struct map_info sc520cdp_map[] = {
+	{
+		name: "SC520CDP Flash Bank #0",
+		size: WINDOW_SIZE_0,
+		buswidth: 4,
+		read8: sc520cdp_read8,
+		read16: sc520cdp_read16,
+		read32: sc520cdp_read32,
+		copy_from: sc520cdp_copy_from,
+		write8: sc520cdp_write8,
+		write16: sc520cdp_write16,
+		write32: sc520cdp_write32,
+		copy_to: sc520cdp_copy_to,
+		map_priv_2: WINDOW_ADDR_0
+	},
+	{
+		name: "SC520CDP Flash Bank #1",
+		size: WINDOW_SIZE_1,
+		buswidth: 4,
+		read8: sc520cdp_read8,
+		read16: sc520cdp_read16,
+		read32: sc520cdp_read32,
+		copy_from: sc520cdp_copy_from,
+		write8: sc520cdp_write8,
+		write16: sc520cdp_write16,
+		write32: sc520cdp_write32,
+		copy_to: sc520cdp_copy_to,
+		map_priv_2: WINDOW_ADDR_1
+	},
+	{
+		name: "SC520CDP DIL Flash",
+		size: WINDOW_SIZE_2,
+		buswidth: 1,
+		read8: sc520cdp_read8,
+		read16: sc520cdp_read16,
+		read32: sc520cdp_read32,
+		copy_from: sc520cdp_copy_from,
+		write8: sc520cdp_write8,
+		write16: sc520cdp_write16,
+		write32: sc520cdp_write32,
+		copy_to: sc520cdp_copy_to,
+		map_priv_2: WINDOW_ADDR_2
+	},
+};
+
+#define NUM_FLASH_BANKS	(sizeof(sc520cdp_map)/sizeof(struct map_info))
+
+static struct mtd_info *mymtd[NUM_FLASH_BANKS];
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_sc520cdp init_module
+#define cleanup_sc520cdp cleanup_module
+#endif
+
+#ifdef REPROGRAM_PAR
+
+/*
+** The SC520 MMCR (memory mapped control register) region resides
+** at 0xFFFEF000. The 16 Programmable Address Region (PAR) registers
+** are at offset 0x88 in the MMCR:
+*/
+#define SC520_MMCR_BASE		0xFFFEF000
+#define SC520_MMCR_EXTENT	0x1000
+#define SC520_PAR(x)		((0x88/sizeof(unsigned long)) + (x))
+#define NUM_SC520_PAR		16	/* total number of PAR registers */
+
+/*
+** The highest three bits in a PAR register determine what target
+** device is controlled by this PAR. Here, only ROMCS? and BOOTCS
+** devices are of interest.
+*/
+#define SC520_PAR_BOOTCS	(0x4<<29)
+#define SC520_PAR_ROMCS0	(0x5<<29)
+#define SC520_PAR_ROMCS1	(0x6<<29)
+#define SC520_PAR_TRGDEV	(0x7<<29)
+
+/*
+** Bits 28 thru 26 determine some attributes for the
+** region controlled by the PAR. (We only use non-cacheable)
+*/
+#define SC520_PAR_WRPROT	(1<<26)	/* write protected       */
+#define SC520_PAR_NOCACHE	(1<<27)	/* non-cacheable         */
+#define SC520_PAR_NOEXEC	(1<<28)	/* code execution denied */
+
+
+/*
+** Bit 25 determines the granularity: 4K or 64K
+*/
+#define SC520_PAR_PG_SIZ4	(0<<25)
+#define SC520_PAR_PG_SIZ64	(1<<25)
+
+/*
+** Build a value to be written into a PAR register.
+** We only need ROM entries, 64K page size:
+*/
+#define SC520_PAR_ENTRY(trgdev, address, size) \
+	((trgdev) | SC520_PAR_NOCACHE | SC520_PAR_PG_SIZ64 | \
+	(address) >> 16 | (((size) >> 16) - 1) << 14)
+
+struct sc520_par_table
+{
+	unsigned long trgdev;
+	unsigned long new_par;
+	unsigned long default_address;
+};
+
+static struct sc520_par_table par_table[NUM_FLASH_BANKS] =
+{
+	{	/* Flash Bank #0: selected by ROMCS0 */
+		SC520_PAR_ROMCS0,
+		SC520_PAR_ENTRY(SC520_PAR_ROMCS0, WINDOW_ADDR_0, WINDOW_SIZE_0),
+		WINDOW_ADDR_0_BIOS
+	},
+	{	/* Flash Bank #1: selected by ROMCS1 */
+		SC520_PAR_ROMCS1,
+		SC520_PAR_ENTRY(SC520_PAR_ROMCS1, WINDOW_ADDR_1, WINDOW_SIZE_1),
+		WINDOW_ADDR_1_BIOS
+	},
+	{	/* DIL (BIOS) Flash: selected by BOOTCS */
+		SC520_PAR_BOOTCS,
+		SC520_PAR_ENTRY(SC520_PAR_BOOTCS, WINDOW_ADDR_2, WINDOW_SIZE_2),
+		WINDOW_ADDR_2_BIOS
+	}
+};
+
+
+static void sc520cdp_setup_par(void)
+{
+	volatile unsigned long *mmcr;
+	unsigned long mmcr_val;
+	int i, j;
+
+	/* map in SC520's MMCR area */
+	mmcr = (unsigned long *)ioremap_nocache(SC520_MMCR_BASE, SC520_MMCR_EXTENT);
+	if(!mmcr) { /* ioremap_nocache failed: skip the PAR reprogramming */
+		/* force map_priv_2 fields to BIOS defaults: */
+		for(i = 0; i < NUM_FLASH_BANKS; i++)
+			sc520cdp_map[i].map_priv_2 = par_table[i].default_address;
+		return;
+	}
+
+	/*
+	** Find the PARxx registers that are reponsible for activating
+	** ROMCS0, ROMCS1 and BOOTCS. Reprogram each of these with a
+	** new value from the table.
+	*/
+	for(i = 0; i < NUM_FLASH_BANKS; i++) {		/* for each par_table entry  */
+		for(j = 0; j < NUM_SC520_PAR; j++) {	/* for each PAR register     */
+			mmcr_val = mmcr[SC520_PAR(j)];
+			/* if target device field matches, reprogram the PAR */
+			if((mmcr_val & SC520_PAR_TRGDEV) == par_table[i].trgdev)
+			{
+				mmcr[SC520_PAR(j)] = par_table[i].new_par;
+				break;
+			}
+		}
+		if(j == NUM_SC520_PAR)
+		{	/* no matching PAR found: try default BIOS address */
+			printk(KERN_NOTICE "Could not find PAR responsible for %s\n",
+				sc520cdp_map[i].name);
+			printk(KERN_NOTICE "Trying default address 0x%lx\n",
+				par_table[i].default_address);
+			sc520cdp_map[i].map_priv_2 = par_table[i].default_address;
+		}
+	}
+	iounmap((void *)mmcr);
+}
+#endif
+
+
+static int __init init_sc520cdp(void)
+{
+	int i, devices_found = 0;
+	
+#ifdef REPROGRAM_PAR
+	/* reprogram PAR registers so flash appears at the desired addresses */
+	sc520cdp_setup_par();
+#endif
+
+	for (i = 0; i < NUM_FLASH_BANKS; i++) {
+		printk(KERN_NOTICE "SC520 CDP flash device: %lx at %lx\n", sc520cdp_map[i].size, sc520cdp_map[i].map_priv_2);
+		sc520cdp_map[i].map_priv_1 = (unsigned long)ioremap_nocache(sc520cdp_map[i].map_priv_2, sc520cdp_map[i].size);
+
+		if (!sc520cdp_map[i].map_priv_1) {
+			printk("Failed to ioremap_nocache\n");
+			return -EIO;
+		}
+		mymtd[i] = do_map_probe("cfi", &sc520cdp_map[i]);
+		if(!mymtd[i])
+			mymtd[i] = do_map_probe("jedec", &sc520cdp_map[i]);
+		if(!mymtd[i])
+			mymtd[i] = do_map_probe("rom", &sc520cdp_map[i]);
+
+		if (mymtd[i]) {
+			mymtd[i]->module = THIS_MODULE;
+			add_mtd_device(mymtd[i]);
+			++devices_found;
+		}
+		else {
+			iounmap((void *)sc520cdp_map[i].map_priv_1);
+		}
+	}
+	return(devices_found ? 0 : -ENXIO);
+}
+
+static void __exit cleanup_sc520cdp(void)
+{
+	int i;
+	
+	for (i = 0; i < NUM_FLASH_BANKS; i++) {
+		if (mymtd[i]) {
+			del_mtd_device(mymtd[i]);
+			map_destroy(mymtd[i]);
+		}
+		if (sc520cdp_map[i].map_priv_1) {
+			iounmap((void *)sc520cdp_map[i].map_priv_1);
+			sc520cdp_map[i].map_priv_1 = 0;
+		}
+	}
+}
+
+module_init(init_sc520cdp);
+module_exit(cleanup_sc520cdp);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/maps/sun_uflash.c linux/drivers/mtd/maps/sun_uflash.c
--- v2.4.5/linux/drivers/mtd/maps/sun_uflash.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/sun_uflash.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,224 @@
+/* $Id: sun_uflash.c,v 1.2 2001/04/26 15:40:23 dwmw2 Exp $
+ *
+ * sun_uflash - Driver implementation for user-programmable flash
+ * present on many Sun Microsystems SME boardsets.
+ *
+ * This driver does NOT provide access to the OBP-flash for
+ * safety reasons-- use <linux>/drivers/sbus/char/flash.c instead.
+ *
+ * Copyright (c) 2001 Eric Brower (ebrower@usa.net)
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <asm/ebus.h>
+#include <asm/oplib.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+
+#define UFLASH_OBPNAME	"flashprom"
+#define UFLASH_DEVNAME 	"userflash"
+
+#define UFLASH_WINDOW_SIZE	0x200000
+#define UFLASH_BUSWIDTH		1			/* EBus is 8-bit */
+
+MODULE_AUTHOR
+	("Eric Brower <ebrower@usa.net>");
+MODULE_DESCRIPTION
+	("User-programmable flash device on Sun Microsystems boardsets");
+MODULE_SUPPORTED_DEVICE
+	("userflash");
+
+static LIST_HEAD(device_list);
+struct uflash_dev {
+	char *			name;	/* device name */
+	struct map_info 	map;	/* mtd map info */
+	struct mtd_info *	mtd;	/* mtd info */
+	struct list_head	list;
+};
+
+__u8 uflash_read8(struct map_info *map, unsigned long ofs)
+{
+	return(__raw_readb(map->map_priv_1 + ofs));
+}
+
+__u16 uflash_read16(struct map_info *map, unsigned long ofs)
+{
+	return(__raw_readw(map->map_priv_1 + ofs));
+}
+
+__u32 uflash_read32(struct map_info *map, unsigned long ofs)
+{
+	return(__raw_readl(map->map_priv_1 + ofs));
+}
+
+void uflash_copy_from(struct map_info *map, void *to, unsigned long from, 
+		      ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void uflash_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+}
+
+void uflash_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+}
+
+void uflash_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+}
+
+void uflash_copy_to(struct map_info *map, unsigned long to, const void *from,
+		    ssize_t len)
+{
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+struct map_info uflash_map_templ = {
+		name:		"SUNW,???-????",
+		size:		UFLASH_WINDOW_SIZE,
+		buswidth:	UFLASH_BUSWIDTH,
+		read8:		uflash_read8,
+		read16:		uflash_read16,
+		read32:		uflash_read32,
+		copy_from:	uflash_copy_from,
+		write8:		uflash_write8,
+		write16:	uflash_write16,
+		write32:	uflash_write32,
+		copy_to:	uflash_copy_to
+};
+
+int uflash_devinit(struct linux_ebus_device* edev)
+{
+	int iTmp, nregs;
+	struct linux_prom_registers regs[2];
+	struct uflash_dev *pdev;
+
+	iTmp = prom_getproperty(
+		edev->prom_node, "reg", (void *)regs, sizeof(regs));
+	if ((iTmp % sizeof(regs[0])) != 0) {
+		printk("%s: Strange reg property size %d\n", 
+			UFLASH_DEVNAME, iTmp);
+		return -ENODEV;
+	}
+
+	nregs = iTmp / sizeof(regs[0]);
+
+	if (nregs != 1) {
+		/* Non-CFI userflash device-- once I find one we
+		 * can work on supporting it.
+		 */
+		printk("%s: unsupported device at 0x%lx (%d regs): " \
+			"email ebrower@usa.net\n", 
+			UFLASH_DEVNAME, edev->resource[0].start, nregs);
+		return -ENODEV;
+	}
+
+	if(0 == (pdev = kmalloc(sizeof(struct uflash_dev), GFP_KERNEL))) {
+		printk("%s: unable to kmalloc new device\n", UFLASH_DEVNAME);
+		return(-ENOMEM);
+	}
+	
+	/* copy defaults and tweak parameters */
+	memcpy(&pdev->map, &uflash_map_templ, sizeof(uflash_map_templ));
+	pdev->map.size = regs[0].reg_size;
+
+	iTmp = prom_getproplen(edev->prom_node, "model");
+	pdev->name = kmalloc(iTmp, GFP_KERNEL);
+	prom_getstring(edev->prom_node, "model", pdev->name, iTmp);
+	if(0 != pdev->name && 0 < strlen(pdev->name)) {
+		pdev->map.name = pdev->name;
+	}
+
+	pdev->map.map_priv_1 = 
+		(unsigned long)ioremap_nocache(edev->resource[0].start, pdev->map.size);
+	if(0 == pdev->map.map_priv_1) {
+		printk("%s: failed to map device\n", __FUNCTION__);
+		kfree(pdev->name);
+		kfree(pdev);
+		return(-1);
+	}
+
+	/* MTD registration */
+	pdev->mtd = do_map_probe("cfi", &pdev->map);
+	if(0 == pdev->mtd) {
+		iounmap((void *)pdev->map.map_priv_1);
+		kfree(pdev->name);
+		kfree(pdev);
+		return(-ENXIO);
+	}
+
+	list_add(&pdev->list, &device_list);
+
+	pdev->mtd->module = THIS_MODULE;
+
+	add_mtd_device(pdev->mtd);
+	return(0);
+}
+
+static int __init uflash_init(void)
+{
+	struct linux_ebus *ebus = NULL;
+	struct linux_ebus_device *edev = NULL;
+
+	for_each_ebus(ebus) {
+		for_each_ebusdev(edev, ebus) {
+			if (!strcmp(edev->prom_name, UFLASH_OBPNAME)) {
+				if(0 > prom_getproplen(edev->prom_node, "user")) {
+					DEBUG(2, "%s: ignoring device at 0x%lx\n",
+							UFLASH_DEVNAME, edev->resource[0].start);
+				} else {
+					uflash_devinit(edev);
+				}
+			}
+		}
+	}
+
+	if(list_empty(&device_list)) {
+		printk("%s: unable to locate device\n", UFLASH_DEVNAME);
+		return -ENODEV;
+	}
+	return(0);
+}
+
+static void __exit uflash_cleanup(void)
+{
+	struct list_head *udevlist;
+	struct uflash_dev *udev;
+
+	list_for_each(udevlist, &device_list) {
+		udev = list_entry(udevlist, struct uflash_dev, list);
+		DEBUG(2, "%s: removing device %s\n", 
+			UFLASH_DEVNAME, udev->name);
+
+		if(0 != udev->mtd) {
+			del_mtd_device(udev->mtd);
+			map_destroy(udev->mtd);
+		}
+		if(0 != udev->map.map_priv_1) {
+			iounmap((void*)udev->map.map_priv_1);
+			udev->map.map_priv_1 = 0;
+		}
+		if(0 != udev->name) {
+			kfree(udev->name);
+		}
+		kfree(udev);
+	}	
+}
+
+module_init(uflash_init);
+module_exit(uflash_cleanup);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/maps/vmax301.c linux/drivers/mtd/maps/vmax301.c
--- v2.4.5/linux/drivers/mtd/maps/vmax301.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/vmax301.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,240 @@
+// $Id: vmax301.c,v 1.22 2001/06/02 14:30:44 dwmw2 Exp $
+/* ######################################################################
+
+   Tempustech VMAX SBC301 MTD Driver.
+  
+   The VMAx 301 is a SBC based on . It
+   comes with three builtin AMD 29F016B flash chips and a socket for SRAM or
+   more flash. Each unit has it's own 8k mapping into a settable region 
+   (0xD8000). There are two 8k mappings for each MTD, the first is always set
+   to the lower 8k of the device the second is paged. Writing a 16 bit page
+   value to anywhere in the first 8k will cause the second 8k to page around.
+
+   To boot the device a bios extension must be installed into the first 8k 
+   of flash that is smart enough to copy itself down, page in the rest of 
+   itself and begin executing.
+   
+   ##################################################################### */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <asm/io.h>
+
+#include <linux/mtd/map.h>
+
+
+#define WINDOW_START 0xd8000
+#define WINDOW_LENGTH 0x2000
+#define WINDOW_SHIFT 25
+#define WINDOW_MASK 0x1FFF
+
+/* Actually we could use two spinlocks, but we'd have to have
+   more private space in the struct map_info. We lose a little
+   performance like this, but we'd probably lose more by having
+   the extra indirection from having one of the map->map_priv 
+   fields pointing to yet another private struct.
+*/
+static spinlock_t vmax301_spin = SPIN_LOCK_UNLOCKED;
+
+static void __vmax301_page(struct map_info *map, unsigned long page)
+{
+	writew(page, map->map_priv_2 - WINDOW_LENGTH);
+	map->map_priv_1 = page;
+}
+
+static inline void vmax301_page(struct map_info *map,
+				  unsigned long ofs)
+{
+	unsigned long page = (ofs >> WINDOW_SHIFT);
+	if (map->map_priv_1 != page)
+		__vmax301_page(map, page);
+}
+
+static __u8 vmax301_read8(struct map_info *map, unsigned long ofs)
+{
+	__u8 ret;
+	spin_lock(&vmax301_spin);
+	vmax301_page(map, ofs);
+	ret = readb(map->map_priv_2 + (ofs & WINDOW_MASK));
+	spin_unlock(&vmax301_spin);
+	return ret;
+}
+
+static __u16 vmax301_read16(struct map_info *map, unsigned long ofs)
+{
+	__u16 ret;
+	spin_lock(&vmax301_spin);
+	vmax301_page(map, ofs);
+	ret = readw(map->map_priv_2 + (ofs & WINDOW_MASK));
+	spin_unlock(&vmax301_spin);
+	return ret;
+}
+
+static __u32 vmax301_read32(struct map_info *map, unsigned long ofs)
+{
+	__u32 ret;
+	spin_lock(&vmax301_spin);
+	vmax301_page(map, ofs);
+	ret =  readl(map->map_priv_2 + (ofs & WINDOW_MASK));
+	spin_unlock(&vmax301_spin);
+	return ret;
+}
+
+static void vmax301_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	while(len) {
+		unsigned long thislen = len;
+		if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
+			thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
+		spin_lock(&vmax301_spin);
+		vmax301_page(map, from);
+		memcpy_fromio(to, map->map_priv_2 + from, thislen);
+		spin_unlock(&vmax301_spin);
+		to += thislen;
+		from += thislen;
+		len -= thislen;
+	}
+}
+
+static void vmax301_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	spin_lock(&vmax301_spin);
+	vmax301_page(map, adr);
+	writeb(d, map->map_priv_2 + (adr & WINDOW_MASK));
+	spin_unlock(&vmax301_spin);
+}
+
+static void vmax301_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	spin_lock(&vmax301_spin);
+	vmax301_page(map, adr);
+	writew(d, map->map_priv_2 + (adr & WINDOW_MASK));
+	spin_unlock(&vmax301_spin);
+}
+
+static void vmax301_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	spin_lock(&vmax301_spin);
+	vmax301_page(map, adr);
+	writel(d, map->map_priv_2 + (adr & WINDOW_MASK));
+	spin_unlock(&vmax301_spin);
+}
+
+static void vmax301_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	while(len) {
+		unsigned long thislen = len;
+		if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
+			thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
+
+		spin_lock(&vmax301_spin);
+		vmax301_page(map, to);
+		memcpy_toio(map->map_priv_2 + to, from, thislen);
+		spin_unlock(&vmax301_spin);		
+		to += thislen;
+		from += thislen;
+		len -= thislen;
+	}
+}
+
+static struct map_info vmax_map[2] = {
+	{
+		name: "VMAX301 Internal Flash",
+		size: 3*2*1024*1024,
+		buswidth: 1,
+		read8: vmax301_read8,
+		read16: vmax301_read16,
+		read32: vmax301_read32,
+		copy_from: vmax301_copy_from,
+		write8: vmax301_write8,
+		write16: vmax301_write16,
+		write32: vmax301_write32,
+		copy_to: vmax301_copy_to,
+		map_priv_1: WINDOW_START + WINDOW_LENGTH,
+		map_priv_2: 0xFFFFFFFF
+	},
+	{
+		name: "VMAX301 Socket",
+		size: 0,
+		buswidth: 1,
+		read8: vmax301_read8,
+		read16: vmax301_read16,
+		read32: vmax301_read32,
+		copy_from: vmax301_copy_from,
+		write8: vmax301_write8,
+		write16: vmax301_write16,
+		write32: vmax301_write32,
+		copy_to: vmax301_copy_to,
+		map_priv_1: WINDOW_START + (3*WINDOW_LENGTH),
+		map_priv_2: 0xFFFFFFFF
+	}
+};
+
+static struct mtd_info *vmax_mtd[2] = {NULL, NULL};
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_vmax301 init_module
+#define cleanup_vmax301 cleanup_module
+#endif
+
+static void __exit cleanup_vmax301(void)
+{
+	int i;
+	
+	for (i=0; i<2; i++) {
+		if (vmax_mtd[i]) {
+			del_mtd_device(vmax_mtd[i]);
+			map_destroy(vmax_mtd[i]);
+		}
+	}
+	iounmap((void *)vmax_map[0].map_priv_1 - WINDOW_START);
+}
+
+int __init init_vmax301(void)
+{
+	int i;
+	unsigned long iomapadr;
+	// Print out our little header..
+	printk("Tempustech VMAX 301 MEM:0x%x-0x%x\n",WINDOW_START,
+	       WINDOW_START+4*WINDOW_LENGTH);
+
+	iomapadr = (unsigned long)ioremap(WINDOW_START, WINDOW_LENGTH*4);
+	if (!iomapadr) {
+		printk("Failed to ioremap memory region\n");
+		return -EIO;
+	}
+	/* Put the address in the map's private data area.
+	   We store the actual MTD IO address rather than the 
+	   address of the first half, because it's used more
+	   often. 
+	*/
+	vmax_map[0].map_priv_1 = iomapadr + WINDOW_START;
+	vmax_map[1].map_priv_1 = iomapadr + (3*WINDOW_START);
+	
+	for (i=0; i<2; i++) {
+		vmax_mtd[i] = do_map_probe("cfi", &vmax_map[i]);
+		if (!vmax_mtd[i])
+			vmax_mtd[i] = do_map_probe("jedec", &vmax_map[i]);
+		if (!vmax_mtd[i])
+			vmax_mtd[i] = do_map_probe("ram", &vmax_map[i]);
+		if (!vmax_mtd[i])
+			vmax_mtd[i] = do_map_probe("rom", &vmax_map[i]);
+		if (vmax_mtd[i]) {
+			vmax_mtd[i]->module = THIS_MODULE;
+			add_mtd_device(vmax_mtd[i]);
+		}
+	}
+
+	if (!vmax_mtd[1] && !vmax_mtd[2]) {
+		iounmap((void *)iomapadr);
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+module_init(init_vmax301);
+module_exit(cleanup_vmax301);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/mixmem.c linux/drivers/mtd/mixmem.c
--- v2.4.5/linux/drivers/mtd/mixmem.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/mixmem.c	Wed Dec 31 16:00:00 1969
@@ -1,151 +0,0 @@
-/* 
- * mixmem - a block device driver for flash rom found on the 
- *          piggyback board of the multi-purpose mixcom card
- *
- * Author: Gergely Madarasz <gorgo@itc.hu> 
- *
- * Copyright (c) 1999 ITConsult-Pro Co. <info@itc.hu>
- *
- * This code is GPL
- *
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <asm/io.h>
-#include <linux/init.h>
-#include <linux/mtd/mapped.h>
-
-#define MIXCOM_ID_OFFSET 0xc10
-#define MIXCOM_PAGE_OFFSET 0xc11
-#define MIXCOM_ID_1 0x11
-#define MIXCOM_ID_2 0x13
-#define MIXMEM_PAGESIZE 4096
-#define FIRST_BLOCK_OFFSET 0x1000
-
-#if LINUX_VERSION_CODE < 0x20300
-#define __exit
-#endif
-
-static unsigned int mixmem_addrs[] = { 0xc8000, 0xd8000, 0 };
-static unsigned int mixcom_ports[] = { 0x180, 0x280, 0x380, 0 };
-
-// We could store these in the mtd structure, but we only support 1 device..
-static unsigned long base_io = 0;
-static unsigned long base_addr = 0;
-static struct mapped_mtd_info *SSD;
-
-static unsigned long mixmem_page(struct mapped_mtd_info *map,
-				 unsigned long page)
-{
-	outb((char)(page & 0xff), base_io+MIXCOM_PAGE_OFFSET);
-	outb((char)((page >> 8) & 0x7), base_io+MIXCOM_PAGE_OFFSET+1);
-   	return base_addr;
-}
-
-static int flash_probe(int base)
-{
-	int prev,curr;
-	unsigned long flags;
-
-	writeb(0xf0, base);
-	save_flags(flags); cli();
-	
-	prev=readw(base);
-
-	writeb(0xaa, base+0x555);
-	writeb(0x55, base+0x2AA);
-	writeb(0x90, base+0x555);
-	
-	curr=readw(base);
-	
-	restore_flags(flags);
-	writeb(0xf0, base);
-	return(prev==curr?0:curr);
-}
-
-static int mixmem_probe(void) 
-{
-	int i;
-	int id;
-	int chip;
-	
-        /* This should really check to see if the io ports are in use before
-           writing to them */
-	for(i=0;mixcom_ports[i]!=0;i++) {
-		id=inb(mixcom_ports[i]+MIXCOM_ID_OFFSET);
-		if(id==MIXCOM_ID_1 || id==MIXCOM_ID_2) {
-			printk("mixmem: mixcom board found at 0x%3x\n",mixcom_ports[i]);
-			break;
-		}
-	}
-	
-	if(mixcom_ports[i]==0) {
-		printk("mixmem: no mixcom board found\n");
-		return -ENODEV;
-	}
-	
-	if (check_region(mixcom_ports[i]+MIXCOM_PAGE_OFFSET, 2)) return -EAGAIN;
-
-	
-	
-	// What is the deal with first_block_offset?
-	for(i=0;mixmem_addrs[i]!=0;i++) {
-		chip=flash_probe(mixmem_addrs[i]+FIRST_BLOCK_OFFSET);
-		if(chip)break;
-	}
-	
-	if(mixmem_addrs[i]==0) {
-		printk("mixmem: no flash available\n");
-		return -ENODEV;
-	}
-        base_io = mixcom_ports[i];
-        base_addr = mixmem_addrs[i];
-	request_region(mixcom_ports[i]+MIXCOM_PAGE_OFFSET, 2, "mixmem");
-        return 0;
-}
-
-
-static void __exit cleanup_mixmem()
-{
-	mtd_mapped_remove(SSD);
-	kfree(SSD);
-	SSD = 0;
-	release_region(base_io+MIXCOM_PAGE_OFFSET, 2);
-}
-
-//static int __init init_mixmem(void)
-int __init init_mixmem(void)
-{   
-   if (mixmem_probe() != 0)
-      return -EAGAIN;
-
-   // Print out our little header..
-   printk("mixcom MTD IO:0x%lx MEM:0x%lx-0x%lx\n",base_io,base_addr,
-	  base_addr+MIXMEM_PAGESIZE);
-   
-   // Allocate some memory
-   SSD = (struct mapped_mtd_info *)kmalloc(sizeof(*SSD),GFP_KERNEL);
-   if (SSD == 0)
-      return 0;   
-   memset(SSD,0,sizeof(*SSD));
-
-   // Setup the MTD structure
-   SSD->page = mixmem_page;
-   SSD->pagesize = MIXMEM_PAGESIZE;
-   SSD->maxsize = 0x7FF;
-   SSD->mtd.name = "mixcom piggyback";
-
-   // Setup the MTD, this will sense the flash parameters and so on..
-   if (mtd_mapped_setup(SSD) != 0)
-   {
-      printk("Failed to register new device\n");
-      cleanup_module();
-      return -EAGAIN;
-   }
-
-   return 0;
-}
-module_init(init_mixmem);
-module_exit(cleanup_mixmem);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/mtdblock_ro.c linux/drivers/mtd/mtdblock_ro.c
--- v2.4.5/linux/drivers/mtd/mtdblock_ro.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/mtdblock_ro.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,289 @@
+/*
+ * $Id: mtdblock_ro.c,v 1.5 2001/06/10 01:41:53 dwmw2 Exp $
+ *
+ * Read-only version of the mtdblock device, without the 
+ * read/erase/modify/writeback stuff
+ */
+
+#ifdef MTDBLOCK_DEBUG
+#define DEBUGLVL debug
+#endif							       
+
+
+#include <linux/module.h>
+#include <linux/types.h>
+
+#include <linux/mtd/mtd.h>
+
+#define MAJOR_NR MTD_BLOCK_MAJOR
+#define DEVICE_NAME "mtdblock"
+#define DEVICE_REQUEST mtdblock_request
+#define DEVICE_NR(device) (device)
+#define DEVICE_ON(device)
+#define DEVICE_OFF(device)
+#define DEVICE_NO_RANDOM
+#include <linux/blk.h>
+
+#if LINUX_VERSION_CODE < 0x20300
+#define RQFUNC_ARG void
+#define blkdev_dequeue_request(req) do {CURRENT = req->next;} while (0)
+#else
+#define RQFUNC_ARG request_queue_t *q
+#endif
+
+#ifdef MTDBLOCK_DEBUG
+static int debug = MTDBLOCK_DEBUG;
+MODULE_PARM(debug, "i");
+#endif
+
+
+static int mtd_sizes[MAX_MTD_DEVICES];
+
+
+static int mtdblock_open(struct inode *inode, struct file *file)
+{
+	struct mtd_info *mtd = NULL;
+
+	int dev;
+
+	DEBUG(1,"mtdblock_open\n");
+	
+	if (inode == 0)
+		return -EINVAL;
+	
+	dev = MINOR(inode->i_rdev);
+	
+	MOD_INC_USE_COUNT;
+
+	mtd = get_mtd_device(NULL, dev);
+
+	if (!mtd) {
+		MOD_DEC_USE_COUNT;
+		return -ENODEV;
+	}
+
+	mtd_sizes[dev] = mtd->size>>9;
+
+	DEBUG(1, "ok\n");
+
+	return 0;
+}
+
+static release_t mtdblock_release(struct inode *inode, struct file *file)
+{
+	int dev;
+	struct mtd_info *mtd;
+
+   	DEBUG(1, "mtdblock_release\n");
+
+	if (inode == NULL)
+		release_return(-ENODEV);
+   
+	invalidate_device(inode->i_rdev, 1);
+
+	dev = MINOR(inode->i_rdev);
+	mtd = __get_mtd_device(NULL, dev);
+
+	if (!mtd) {
+		printk(KERN_WARNING "MTD device is absent on mtd_release!\n");
+		MOD_DEC_USE_COUNT;
+		release_return(-ENODEV);
+	}
+	
+	if (mtd->sync)
+		mtd->sync(mtd);
+
+	put_mtd_device(mtd);
+
+	DEBUG(1, "ok\n");
+
+	MOD_DEC_USE_COUNT;
+	release_return(0);
+}  
+
+
+static void mtdblock_request(RQFUNC_ARG)
+{
+   struct request *current_request;
+   unsigned int res = 0;
+   struct mtd_info *mtd;
+
+   while (1)
+   {
+      /* Grab the Request and unlink it from the request list, INIT_REQUEST
+       	 will execute a return if we are done. */
+      INIT_REQUEST;
+      current_request = CURRENT;
+   
+      if (MINOR(current_request->rq_dev) >= MAX_MTD_DEVICES)
+      {
+	 printk("mtd: Unsupported device!\n");
+	 end_request(0);
+	 continue;
+      }
+      
+      // Grab our MTD structure
+
+      mtd = __get_mtd_device(NULL, MINOR(current_request->rq_dev));
+      if (!mtd) {
+	      printk("MTD device %d doesn't appear to exist any more\n", CURRENT_DEV);
+	      end_request(0);
+      }
+
+      if (current_request->sector << 9 > mtd->size ||
+	  (current_request->sector + current_request->nr_sectors) << 9 > mtd->size)
+      {
+	 printk("mtd: Attempt to read past end of device!\n");
+	 printk("size: %x, sector: %lx, nr_sectors %lx\n", mtd->size, current_request->sector, current_request->nr_sectors);
+	 end_request(0);
+	 continue;
+      }
+      
+      /* Remove the request we are handling from the request list so nobody messes
+         with it */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+      /* Now drop the lock that the ll_rw_blk functions grabbed for us
+         and process the request. This is necessary due to the extreme time
+         we spend processing it. */
+      spin_unlock_irq(&io_request_lock);
+#endif
+
+      // Handle the request
+      switch (current_request->cmd)
+      {
+         size_t retlen;
+
+	 case READ:
+	 if (MTD_READ(mtd,current_request->sector<<9, 
+		      current_request->nr_sectors << 9, 
+		      &retlen, current_request->buffer) == 0)
+	    res = 1;
+	 else
+	    res = 0;
+	 break;
+	 
+	 case WRITE:
+
+	 /* printk("mtdblock_request WRITE sector=%d(%d)\n",current_request->sector,
+		current_request->nr_sectors);
+	 */
+
+	 // Read only device
+	 if ((mtd->flags & MTD_CAP_RAM) == 0)
+	 {
+	    res = 0;
+	    break;
+	 }
+
+	 // Do the write
+	 if (MTD_WRITE(mtd,current_request->sector<<9, 
+		       current_request->nr_sectors << 9, 
+		       &retlen, current_request->buffer) == 0)
+	    res = 1;
+	 else
+	    res = 0;
+	 break;
+	 
+	 // Shouldn't happen
+	 default:
+	 printk("mtd: unknown request\n");
+	 break;
+      }
+
+      // Grab the lock and re-thread the item onto the linked list
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+	spin_lock_irq(&io_request_lock);
+#endif
+	end_request(res);
+   }
+}
+
+
+
+static int mtdblock_ioctl(struct inode * inode, struct file * file,
+		      unsigned int cmd, unsigned long arg)
+{
+	struct mtd_info *mtd;
+
+	mtd = __get_mtd_device(NULL, MINOR(inode->i_rdev));
+
+	if (!mtd) return -EINVAL;
+
+	switch (cmd) {
+	case BLKGETSIZE:   /* Return device size */
+		if (!arg)  return -EFAULT;
+		return Put_user((mtd->size >> 9),
+                                (long *) arg);
+		
+	case BLKFLSBUF:
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+		if(!capable(CAP_SYS_ADMIN))  return -EACCES;
+#endif
+		fsync_dev(inode->i_rdev);
+		invalidate_buffers(inode->i_rdev);
+		if (mtd->sync)
+			mtd->sync(mtd);
+		return 0;
+
+	default:
+		return -ENOTTY;
+	}
+}
+
+#if LINUX_VERSION_CODE < 0x20326
+static struct file_operations mtd_fops =
+{
+	open: mtdblock_open,
+	ioctl: mtdblock_ioctl,
+	release: mtdblock_release,
+	read: block_read,
+	write: block_write
+};
+#else
+static struct block_device_operations mtd_fops = 
+{
+	open: mtdblock_open,
+	release: mtdblock_release,
+	ioctl: mtdblock_ioctl
+};
+#endif
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_mtdblock init_module
+#define cleanup_mtdblock cleanup_module
+#endif
+
+int __init init_mtdblock(void)
+{
+	int i;
+
+	if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) {
+		printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
+		       MTD_BLOCK_MAJOR);
+		return EAGAIN;
+	}
+	
+	/* We fill it in at open() time. */
+	for (i=0; i< MAX_MTD_DEVICES; i++) {
+		mtd_sizes[i] = 0;
+	}
+	
+	/* Allow the block size to default to BLOCK_SIZE. */
+	blksize_size[MAJOR_NR] = NULL;
+	blk_size[MAJOR_NR] = mtd_sizes;
+	
+#if LINUX_VERSION_CODE < 0x20320
+	blk_dev[MAJOR_NR].request_fn = mtdblock_request;
+#else
+	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request);
+#endif
+	return 0;
+}
+
+static void __exit cleanup_mtdblock(void)
+{
+	unregister_blkdev(MAJOR_NR,DEVICE_NAME);
+}
+
+module_init(init_mtdblock);
+module_exit(cleanup_mtdblock);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/mtdchar.c linux/drivers/mtd/mtdchar.c
--- v2.4.5/linux/drivers/mtd/mtdchar.c	Mon May 21 17:06:29 2001
+++ linux/drivers/mtd/mtdchar.c	Tue Jun 12 10:30:27 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: mtdchar.c,v 1.21.2.3 2001/01/09 00:18:31 dwmw2 Exp $
+ * $Id: mtdchar.c,v 1.38.2.1 2001/06/09 17:31:16 dwmw2 Exp $
  *
  * Character-device access to raw MTD devices.
  *
@@ -7,7 +7,6 @@
 
 
 #include <linux/mtd/compatmac.h>
-
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -18,21 +17,18 @@
 #include <linux/devfs_fs_kernel.h>
 static void mtd_notify_add(struct mtd_info* mtd);
 static void mtd_notify_remove(struct mtd_info* mtd);
+
 static struct mtd_notifier notifier = {
-	mtd_notify_add,
-	mtd_notify_remove,
-	NULL
+	add:	mtd_notify_add,
+	remove:	mtd_notify_remove,
 };
-static devfs_handle_t devfs_dir_handle = NULL;
+
+static devfs_handle_t devfs_dir_handle;
 static devfs_handle_t devfs_rw_handle[MAX_MTD_DEVICES];
 static devfs_handle_t devfs_ro_handle[MAX_MTD_DEVICES];
 #endif
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
 static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
-#else
-static int mtd_lseek (struct inode *inode, struct file *file, off_t offset, int orig)
-#endif
 {
 	struct mtd_info *mtd=(struct mtd_info *)file->private_data;
 
@@ -119,15 +115,18 @@
 #define FILE_POS file->f_pos
 #endif
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+/* FIXME: This _really_ needs to die. In 2.5, we should lock the
+   userspace buffer down and use it directly with readv/writev.
+*/
+#define MAX_KMALLOC_SIZE 0x20000
+
 static ssize_t mtd_read(struct file *file, char *buf, size_t count,loff_t *ppos)
-#else
-static int mtd_read(struct inode *inode,struct file *file, char *buf, int count)
-#endif
 {
 	struct mtd_info *mtd = (struct mtd_info *)file->private_data;
 	size_t retlen=0;
+	size_t total_retlen=0;
 	int ret=0;
+	int len;
 	char *kbuf;
 	
 	DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n");
@@ -138,39 +137,50 @@
 	if (!count)
 		return 0;
 	
-	/* FIXME: Use kiovec in 2.3 or 2.2+rawio, or at
-	 * least split the IO into smaller chunks.
-	 */
-	
-	kbuf = vmalloc(count);
-	if (!kbuf)
-		return -ENOMEM;
-	
-	ret = MTD_READ(mtd, FILE_POS, count, &retlen, kbuf);
-	if (!ret) {
-		FILE_POS += retlen;
-		if (copy_to_user(buf, kbuf, retlen))
-			ret = -EFAULT;
+	/* FIXME: Use kiovec in 2.5 to lock down the user's buffers
+	   and pass them directly to the MTD functions */
+	while (count) {
+		if (count > MAX_KMALLOC_SIZE) 
+			len = MAX_KMALLOC_SIZE;
 		else
-			ret = retlen;
+			len = count;
 
+		kbuf=kmalloc(len,GFP_KERNEL);
+		if (!kbuf)
+			return -ENOMEM;
+		
+		ret = MTD_READ(mtd, FILE_POS, len, &retlen, kbuf);
+		if (!ret) {
+			FILE_POS += retlen;
+			if (copy_to_user(buf, kbuf, retlen)) {
+			        kfree(kbuf);
+				return -EFAULT;
+			}
+			else
+				total_retlen += retlen;
+
+			count -= retlen;
+			buf += retlen;
+		}
+		else {
+			kfree(kbuf);
+			return ret;
+		}
+		
+		kfree(kbuf);
 	}
 	
-	vfree(kbuf);
-	
-	return ret;
+	return total_retlen;
 } /* mtd_read */
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
 static ssize_t mtd_write(struct file *file, const char *buf, size_t count,loff_t *ppos)
-#else
-static read_write_t mtd_write(struct inode *inode,struct file *file, const char *buf, count_t count)
-#endif
 {
 	struct mtd_info *mtd = (struct mtd_info *)file->private_data;
 	char *kbuf;
 	size_t retlen;
+	size_t total_retlen=0;
 	int ret=0;
+	int len;
 
 	DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n");
 	
@@ -183,27 +193,39 @@
 	if (!count)
 		return 0;
 
-	kbuf=vmalloc(count);
+	while (count) {
+		if (count > MAX_KMALLOC_SIZE) 
+			len = MAX_KMALLOC_SIZE;
+		else
+			len = count;
 
-	if (!kbuf)
-		return -ENOMEM;
-	
-	if (copy_from_user(kbuf, buf, count)) {
-		vfree(kbuf);
-		return -EFAULT;
-	}
-		
+		kbuf=kmalloc(len,GFP_KERNEL);
+		if (!kbuf) {
+			printk("kmalloc is null\n");
+			return -ENOMEM;
+		}
 
-	ret = (*(mtd->write))(mtd, FILE_POS, count, &retlen, buf);
+		if (copy_from_user(kbuf, buf, len)) {
+			kfree(kbuf);
+			return -EFAULT;
+		}
 		
-	if (!ret) {
-		FILE_POS += retlen;
-		ret = retlen;
+	        ret = (*(mtd->write))(mtd, FILE_POS, len, &retlen, kbuf);
+		if (!ret) {
+			FILE_POS += retlen;
+			total_retlen += retlen;
+			count -= retlen;
+			buf += retlen;
+		}
+		else {
+			kfree(kbuf);
+			return ret;
+		}
+		
+		kfree(kbuf);
 	}
 
-	vfree(kbuf);
-
-	return ret;
+	return total_retlen;
 } /* mtd_write */
 
 /*======================================================================
@@ -236,6 +258,30 @@
 	}
 	
 	switch (cmd) {
+	case MEMGETREGIONCOUNT:
+		if (copy_to_user((int *) arg, &(mtd->numeraseregions), sizeof(int)))
+			return -EFAULT;
+		break;
+
+	case MEMGETREGIONINFO:
+	{
+		struct region_info_user ur;
+
+		if (copy_from_user(	&ur, 
+					(struct region_info_user *)arg, 
+					sizeof(struct region_info_user))) {
+			return -EFAULT;
+		}
+
+		if (ur.regionindex >= mtd->numeraseregions)
+			return -EINVAL;
+		if (copy_to_user((struct mtd_erase_region_info *) arg, 
+				&(mtd->eraseregions[ur.regionindex]),
+				sizeof(struct mtd_erase_region_info)))
+			return -EFAULT;
+		break;
+	}
+
 	case MEMGETINFO:
 		if (copy_to_user((struct mtd_info *)arg, mtd,
 				 sizeof(struct mtd_info_user)))
@@ -317,7 +363,7 @@
 
 		ret = (mtd->write_oob)(mtd, buf.start, buf.length, &retlen, databuf);
 
-		if (copy_to_user((void *)arg + sizeof(loff_t), &retlen, sizeof(ssize_t)))
+		if (copy_to_user((void *)arg + sizeof(u_int32_t), &retlen, sizeof(u_int32_t)))
 			ret = -EFAULT;
 
 		kfree(databuf);
@@ -351,7 +397,7 @@
 		
 		ret = (mtd->read_oob)(mtd, buf.start, buf.length, &retlen, databuf);
 
-		if (copy_to_user((void *)arg + sizeof(loff_t), &retlen, sizeof(ssize_t)))
+		if (copy_to_user((void *)arg + sizeof(u_int32_t), &retlen, sizeof(u_int32_t)))
 			ret = -EFAULT;
 		else if (retlen && copy_to_user(buf.ptr, databuf, retlen))
 			ret = -EFAULT;
@@ -371,6 +417,7 @@
 			ret = -EOPNOTSUPP;
 		else
 			ret = mtd->lock(mtd, adrs[0], adrs[1]);
+		break;
 	}
 
 	case MEMUNLOCK:
@@ -384,14 +431,15 @@
 			ret = -EOPNOTSUPP;
 		else
 			ret = mtd->unlock(mtd, adrs[0], adrs[1]);
+		break;
 	}
 
 		
 	default:
-	  printk("Invalid ioctl %x (MEMGETINFO = %x)\n",cmd, MEMGETINFO);
-		ret = -EINVAL;
+		DEBUG(MTD_DEBUG_LEVEL0, "Invalid ioctl %x (MEMGETINFO = %x)\n", cmd, MEMGETINFO);
+		ret = -ENOTTY;
 	}
-	
+
 	return ret;
 } /* memory_ioctl */
 
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/mtdcore.c linux/drivers/mtd/mtdcore.c
--- v2.4.5/linux/drivers/mtd/mtdcore.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/mtdcore.c	Tue Jun 12 10:30:27 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: mtdcore.c,v 1.27 2000/12/10 01:10:09 dwmw2 Exp $
+ * $Id: mtdcore.c,v 1.30 2001/06/02 14:30:42 dwmw2 Exp $
  *
  * Core registration and callback routines for MTD
  * drivers and users.
@@ -258,8 +258,8 @@
 	if (!this)
 		return 0;
 
-	return sprintf(buf, "mtd%d: %8.8lx \"%s\"\n", i, this->size,
-		       this->name);
+	return sprintf(buf, "mtd%d: %8.8x %8.8x \"%s\"\n", i, this->size,
+		       this->erasesize, this->name);
 }
 
 static int mtd_read_proc ( char *page, char **start, off_t off,int count
@@ -270,11 +270,12 @@
 #endif
 			)
 {
-	int len = 0, l, i;
+	int len, l, i;
         off_t   begin = 0;
 
 	down(&mtd_table_mutex);
 
+	len = sprintf(page, "dev:    size   erasesize  name\n");
         for (i=0; i< MAX_MTD_DEVICES; i++) {
 
                 l = mtd_proc_info(page + len, i);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/mtdpart.c linux/drivers/mtd/mtdpart.c
--- v2.4.5/linux/drivers/mtd/mtdpart.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/mtdpart.c	Tue Jun 12 10:30:27 2001
@@ -5,7 +5,7 @@
  *
  * This code is GPL
  *
- * $Id: mtdpart.c,v 1.7 2000/12/09 23:29:47 dwmw2 Exp $
+ * $Id: mtdpart.c,v 1.21 2001/06/09 16:33:32 dwmw2 Exp $
  */
 
 #include <linux/module.h>
@@ -25,7 +25,7 @@
 struct mtd_part {
 	struct mtd_info mtd;
 	struct mtd_info *master;
-	loff_t offset;
+	u_int32_t offset;
 	int index;
 	struct list_head list;
 };
@@ -100,15 +100,36 @@
 static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len)
 {
 	struct mtd_part *part = PART(mtd);
+	if ((len + ofs) > mtd->size) 
+		return -EINVAL;
 	return part->master->lock(part->master, ofs + part->offset, len);
 }
 
 static int part_unlock (struct mtd_info *mtd, loff_t ofs, size_t len)
 {
 	struct mtd_part *part = PART(mtd);
+	if ((len + ofs) > mtd->size) 
+		return -EINVAL;
 	return part->master->unlock(part->master, ofs + part->offset, len);
 }
 
+static void part_sync(struct mtd_info *mtd)
+{
+	struct mtd_part *part = PART(mtd);
+	part->master->sync(part->master);
+}
+
+static int part_suspend(struct mtd_info *mtd)
+{
+	struct mtd_part *part = PART(mtd);
+	return part->master->suspend(part->master);
+}
+
+static void part_resume(struct mtd_info *mtd)
+{
+	struct mtd_part *part = PART(mtd);
+	part->master->resume(part->master);
+}
 
 /* 
  * This function unregisters and destroy all slave MTD objects which are 
@@ -130,14 +151,12 @@
 			del_mtd_device(&slave->mtd);
 			kfree(slave);
 			node = prev;
-			MOD_DEC_USE_COUNT;
 		}
 	}
 
 	return 0;
 }
 
-
 /*
  * This function, given a master MTD object and a partition table, creates
  * and registers slave MTD objects which are bound to the master according to
@@ -150,10 +169,13 @@
 		       int nbparts)
 {
 	struct mtd_part *slave;
-	u_long cur_offset = 0;
+	u_int32_t cur_offset = 0;
 	int i;
 
+	printk (KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);
+
 	for (i = 0; i < nbparts; i++) {
+
 		/* allocate the partition structure */
 		slave = kmalloc (sizeof(*slave), GFP_KERNEL);
 		if (!slave) {
@@ -162,63 +184,102 @@
 			del_mtd_partitions(master);
 			return -ENOMEM;
 		}
+		memset(slave, 0, sizeof(*slave));
 		list_add(&slave->list, &mtd_partitions);
 
 		/* set up the MTD object for this partition */
-		slave->mtd = *master;
-		slave->mtd.name = parts[i].name;
+		slave->mtd.type = master->type;
+		slave->mtd.flags = master->flags & ~parts[i].mask_flags;
 		slave->mtd.size = parts[i].size;
-		slave->mtd.flags &= ~parts[i].mask_flags;
+		slave->mtd.oobblock = master->oobblock;
+		slave->mtd.oobsize = master->oobsize;
+		slave->mtd.ecctype = master->ecctype;
+		slave->mtd.eccsize = master->eccsize;
+
+		slave->mtd.name = parts[i].name;
+		slave->mtd.bank_size = master->bank_size;
+
+		slave->mtd.module = master->module;
+
 		slave->mtd.read = part_read;
 		slave->mtd.write = part_write;
-		if (slave->mtd.writev)
+		slave->mtd.sync = part_sync;
+		if (!i && master->suspend && master->resume) {
+				slave->mtd.suspend = part_suspend;
+				slave->mtd.resume = part_resume;
+		}
+
+		if (master->writev)
 			slave->mtd.writev = part_writev;
-		if (slave->mtd.readv)
+		if (master->readv)
 			slave->mtd.readv = part_readv;
-		if (slave->mtd.lock)
+		if (master->lock)
 			slave->mtd.lock = part_lock;
-		if (slave->mtd.unlock)
+		if (master->unlock)
 			slave->mtd.unlock = part_unlock;
 		slave->mtd.erase = part_erase;
 		slave->master = master;
 		slave->offset = parts[i].offset;
 		slave->index = i;
 
-		if (slave->offset == 0)
+		if (slave->offset == MTDPART_OFS_APPEND)
 			slave->offset = cur_offset;
-		if (slave->mtd.size == 0)
+		if (slave->mtd.size == MTDPART_SIZ_FULL)
 			slave->mtd.size = master->size - slave->offset;
 		cur_offset = slave->offset + slave->mtd.size;
+	
+		printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset, 
+			slave->offset + slave->mtd.size, slave->mtd.name);
 
 		/* let's do some sanity checks */
+		if (slave->offset >= master->size) {
+				/* let's register it anyway to preserve ordering */
+			slave->offset = 0;
+			slave->mtd.size = 0;
+			printk ("mtd: partition \"%s\" is out of reach -- disabled\n",
+				parts[i].name);
+		}
+		if (slave->offset + slave->mtd.size > master->size) {
+			slave->mtd.size = master->size - slave->offset;
+			printk ("mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#x\n",
+				parts[i].name, master->name, slave->mtd.size);
+		}
+		if (master->numeraseregions>1) {
+			/* Deal with variable erase size stuff */
+			int i;
+			struct mtd_erase_region_info *regions = master->eraseregions;
+			
+			/* Find the first erase regions which is part of this partition. */
+			for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++)
+				;
+
+			for (i--; i < master->numeraseregions && slave->offset + slave->mtd.size > regions[i].offset; i++) {
+				if (slave->mtd.erasesize < regions[i].erasesize) {
+					slave->mtd.erasesize = regions[i].erasesize;
+				}
+			}
+		} else {
+			/* Single erase size */
+			slave->mtd.erasesize = master->erasesize;
+		}
+
 		if ((slave->mtd.flags & MTD_WRITEABLE) && 
-		    (parts[i].offset % master->erasesize)) {
+		    (slave->offset % slave->mtd.erasesize)) {
+			/* Doesn't start on a boundary of major erase size */
+			/* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */
 			slave->mtd.flags &= ~MTD_WRITEABLE;
 			printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n",
-					parts[i].name);
+				parts[i].name);
 		}
 		if ((slave->mtd.flags & MTD_WRITEABLE) && 
-		    (parts[i].size % master->erasesize)) {
+		    (slave->mtd.size % slave->mtd.erasesize)) {
 			slave->mtd.flags &= ~MTD_WRITEABLE;
 			printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n",
-					parts[i].name);
-		}
-		if (parts[i].offset >= master->size) {
-			/* let's register it anyway to preserve ordering */
-			slave->offset = 0;
-			slave->mtd.size = 0;
-			printk ("mtd: partition \"%s\" is out of reach -- disabled\n",
-					parts[i].name);
-		}
-		if (parts[i].offset + parts[i].size > master->size) {
-			slave->mtd.size = master->size - parts[i].offset;
-			printk ("mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#lx\n",
-					parts[i].name, master->name, slave->mtd.size);
+				parts[i].name);
 		}
 
 		/* register our partition */
 		add_mtd_device(&slave->mtd);
-		MOD_INC_USE_COUNT;
 	}
 
 	return 0;
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/mtdram.c linux/drivers/mtd/mtdram.c
--- v2.4.5/linux/drivers/mtd/mtdram.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/mtdram.c	Wed Dec 31 16:00:00 1969
@@ -1,148 +0,0 @@
-/* 
- * mtdram - a test mtd device
- * $Id: mtdram.c,v 1.15 2000/07/13 12:40:46 scote1 Exp $
- * Author: Alexander Larsson <alex@cendio.se> 
- *
- * Copyright (c) 1999 Alexander Larsson <alex@cendio.se>
- *
- * This code is GPL
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/mtd/compatmac.h>
-#include <linux/mtd/mtd.h>
-
-
-#define MTDRAM_TOTAL_SIZE (CONFIG_MTDRAM_TOTAL_SIZE * 1024)
-#define MTDRAM_ERASE_SIZE (CONFIG_MTDRAM_ERASE_SIZE * 1024)
-
-
-// We could store these in the mtd structure, but we only support 1 device..
-static struct mtd_info *mtd_info;
-
-
-static int
-ram_erase(struct mtd_info *mtd, struct erase_info *instr)
-{
-  if (instr->addr + instr->len > mtd->size)
-    return -EINVAL;
-	
-  memset((char *)mtd->priv + instr->addr, 0xff, instr->len);
-  
-  instr->state = MTD_ERASE_DONE;
-
-  if (instr->callback)
-    (*(instr->callback))(instr);
-  return 0;
-}
-
-static int ram_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf)
-{
-  if (from + len > mtd->size)
-    return -EINVAL;
-  
-  *mtdbuf = mtd->priv + from;
-  *retlen = len;
-  return 0;
-}
-
-static void ram_unpoint (struct mtd_info *mtd, u_char *addr)
-{
-}
-
-static int ram_read(struct mtd_info *mtd, loff_t from, size_t len,
-	     size_t *retlen, u_char *buf)
-{
-  if (from + len > mtd->size)
-    return -EINVAL;
-
-  memcpy(buf, mtd->priv + from, len);
-
-  *retlen=len;
-  return 0;
-}
-
-static int ram_write(struct mtd_info *mtd, loff_t to, size_t len,
-	      size_t *retlen, const u_char *buf)
-{
-  if (to + len > mtd->size)
-    return -EINVAL;
-  
-  memcpy ((char *)mtd->priv + to, buf, len);
-
-  *retlen=len;
-  return 0;
-}
-
-#if LINUX_VERSION_CODE < 0x20300
-#ifdef MODULE
-#define init_mtdram init_module
-#define cleanup_mtdram cleanup_module
-#endif
-#endif
-
-//static void __exit cleanup_mtdram(void)
-mod_exit_t cleanup_mtdram(void)
-{
-  if (mtd_info) {
-    del_mtd_device(mtd_info);
-    if (mtd_info->priv)
-      vfree(mtd_info->priv);
-    kfree(mtd_info);
-  }
-}
-
-extern struct module __this_module;
-
-mod_init_t init_mtdram(void)
-{
-   // Allocate some memory
-   mtd_info = (struct mtd_info *)kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
-   if (mtd_info == 0)
-      return 0;
-   
-   memset(mtd_info, 0, sizeof(*mtd_info));
-
-   // Setup the MTD structure
-   mtd_info->name = "mtdram test device";
-   mtd_info->type = MTD_RAM;
-   mtd_info->flags = MTD_CAP_RAM;
-   mtd_info->size = MTDRAM_TOTAL_SIZE;
-   mtd_info->erasesize = MTDRAM_ERASE_SIZE;
-   mtd_info->priv = vmalloc(MTDRAM_TOTAL_SIZE);
-   memset(mtd_info->priv, 0xff, MTDRAM_TOTAL_SIZE);
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-   mtd_info->module = THIS_MODULE;			
-#endif
-
-   if (!mtd_info->priv) {
-     kfree(mtd_info);
-     mtd_info = NULL;
-     return -ENOMEM;
-   }
-   mtd_info->erase = ram_erase;
-   mtd_info->point = ram_point;
-   mtd_info->unpoint = ram_unpoint;
-   mtd_info->read = ram_read;
-   mtd_info->write = ram_write;
-
-   if (add_mtd_device(mtd_info)) {
-     vfree(mtd_info->priv);
-     kfree(mtd_info);
-     mtd_info = NULL;
-     return -EIO;
-   }
-   
-   return 0;
-}
-
-#if LINUX_VERSION_CODE > 0x20300
-module_init(init_mtdram);
-module_exit(cleanup_mtdram);
-#endif
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/nand/Config.in linux/drivers/mtd/nand/Config.in
--- v2.4.5/linux/drivers/mtd/nand/Config.in	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/nand/Config.in	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,16 @@
+# drivers/mtd/nand/Config.in
+
+# $Id: Config.in,v 1.1 2001/04/20 15:27:38 dwmw2 Exp $
+
+mainmenu_option next_comment
+
+comment 'NAND Flash Device Drivers'
+
+dep_tristate '  NAND Device Support' CONFIG_MTD_NAND $CONFIG_MTD
+if [ "$CONFIG_MTD_NAND" = "y" -o "$CONFIG_MTD_NAND" = "m" ]; then
+   bool '    Enable ECC correction algorithm'  CONFIG_MTD_NAND_ECC y
+   bool '    Verify NAND page writes' CONFIG_MTD_NAND_VERIFY_WRITE y
+fi
+dep_tristate '  NAND Flash device on SPIA board' CONFIG_MTD_NAND_SPIA $CONFIG_MTD_NAND
+
+endmenu
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/nand/Makefile linux/drivers/mtd/nand/Makefile
--- v2.4.5/linux/drivers/mtd/nand/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/nand/Makefile	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,14 @@
+#
+# linux/drivers/nand/Makefile
+#
+# $Id: Makefile,v 1.3 2001/04/19 23:54:48 dwmw2 Exp $
+
+O_TARGET	:= nandlink.o
+
+export-objs	:= nand.o
+
+obj-$(CONFIG_MTD_NAND)		+= nand.o
+obj-$(CONFIG_MTD_NAND_ECC)	+= nand_ecc.o
+obj-$(CONFIG_MTD_NAND_SPIA)	+= spia.o
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/nand/nand.c linux/drivers/mtd/nand/nand.c
--- v2.4.5/linux/drivers/mtd/nand/nand.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/nand/nand.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,1369 @@
+/*
+ *  drivers/mtd/nand.c
+ *
+ *  Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
+ *
+ * $Id: nand.c,v 1.10 2001/03/20 07:26:01 dwmw2 Exp $
+ *
+ * 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.
+ *
+ *  Overview:
+ *   This is the generic MTD driver for NAND flash devices. It should be
+ *   capable of working with almost all NAND chips currently available.
+ */
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ids.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_MTD_NAND_ECC
+#include <linux/mtd/nand_ecc.h>
+#endif
+
+/*
+ * Macros for low-level register control
+ */
+#define NAND_CTRL (*(volatile unsigned char *) \
+			((struct nand_chip *) mtd->priv)->CTRL_ADDR)
+#define nand_select()	NAND_CTRL &= ~this->NCE; \
+			nand_command(mtd, NAND_CMD_RESET, -1, -1); \
+			udelay (10);
+#define nand_deselect() NAND_CTRL |= ~this->NCE;
+
+/*
+ * NAND low-level MTD interface functions
+ */
+static int nand_read (struct mtd_info *mtd, loff_t from, size_t len,
+			size_t *retlen, u_char *buf);
+static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
+				size_t *retlen, u_char *buf, u_char *ecc_code);
+static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len,
+				size_t *retlen, u_char *buf);
+static int nand_write (struct mtd_info *mtd, loff_t to, size_t len,
+			size_t *retlen, const u_char *buf);
+static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
+				size_t *retlen, const u_char *buf,
+				u_char *ecc_code);
+static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len,
+				size_t *retlen, const u_char *buf);
+static int nand_writev (struct mtd_info *mtd, const struct iovec *vecs,
+				unsigned long count, loff_t to, size_t *retlen);
+static int nand_erase (struct mtd_info *mtd, struct erase_info *instr);
+static void nand_sync (struct mtd_info *mtd);
+
+/*
+ * Send command to NAND device
+ */
+static void nand_command (struct mtd_info *mtd, unsigned command,
+				int column, int page_addr)
+{
+	register struct nand_chip *this = mtd->priv;
+	register unsigned long NAND_IO_ADDR = this->IO_ADDR;
+
+	/* Begin command latch cycle */
+	NAND_CTRL |= this->CLE;
+
+	/*
+	 * Write out the command to the device.
+	 */
+	if (command != NAND_CMD_SEQIN)	
+		writeb (command, NAND_IO_ADDR);
+	else {
+		if (mtd->oobblock == 256 && column >= 256) {
+			column -= 256;
+			writeb(NAND_CMD_RESET, NAND_IO_ADDR);
+			writeb(NAND_CMD_READOOB, NAND_IO_ADDR);
+			writeb(NAND_CMD_SEQIN, NAND_IO_ADDR);
+		}
+		else if (mtd->oobblock == 512 && column >= 256) {
+			if (column < 512) {
+				column -= 256;
+				writeb(NAND_CMD_READ1, NAND_IO_ADDR);
+				writeb(NAND_CMD_SEQIN, NAND_IO_ADDR);
+			}
+			else {
+				column -= 512;
+				writeb(NAND_CMD_READOOB, NAND_IO_ADDR);
+				writeb(NAND_CMD_SEQIN, NAND_IO_ADDR);
+			}
+		}
+		else {
+			writeb(NAND_CMD_READ0, NAND_IO_ADDR);
+			writeb(NAND_CMD_SEQIN, NAND_IO_ADDR);
+		}
+	}
+
+	/* Set ALE and clear CLE to start address cycle */
+	NAND_CTRL &= ~this->CLE;
+	NAND_CTRL |= this->ALE;
+
+	/* Serially input address */
+	if (column != -1)
+		writeb (column, NAND_IO_ADDR);
+	if (page_addr != -1) {
+		writeb ((unsigned char) (page_addr & 0xff), NAND_IO_ADDR);
+		writeb ((unsigned char) ((page_addr >> 8) & 0xff), NAND_IO_ADDR);
+		/* One more address cycle for higher density devices */
+		if (mtd->size & 0x0c000000) {
+			writeb ((unsigned char) ((page_addr >> 16) & 0x0f),
+					NAND_IO_ADDR);
+		}
+	}
+
+	/* Latch in address */
+	NAND_CTRL &= ~this->ALE;
+
+	/* Pause for 15us */
+	udelay (15);
+}
+
+/*
+ * NAND read
+ */
+static int nand_read (struct mtd_info *mtd, loff_t from, size_t len,
+			size_t *retlen, u_char *buf)
+{
+#ifdef CONFIG_MTD_NAND_ECC
+	struct nand_chip *this = mtd->priv;
+	
+	return nand_read_ecc (mtd, from, len, retlen, buf, this->ecc_code_buf);
+#else
+	return nand_read_ecc (mtd, from, len, retlen, buf, NULL);
+#endif
+}
+
+/*
+ * NAND read with ECC
+ */
+static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
+				size_t *retlen, u_char *buf, u_char *ecc_code)
+{
+	int j, col, page, state;
+	int erase_state = 0;
+	struct nand_chip *this = mtd->priv;
+	DECLARE_WAITQUEUE(wait, current);
+#ifdef CONFIG_MTD_NAND_ECC
+	int ecc_result;
+	u_char ecc_calc[6];
+#endif
+
+	DEBUG (MTD_DEBUG_LEVEL3,
+		"nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from,
+		(int) len);
+
+	/* Do not allow reads past end of device */
+	if ((from + len) > mtd->size) {
+		DEBUG (MTD_DEBUG_LEVEL0,
+			"nand_read_ecc: Attempt read beyond end of device\n");
+		*retlen = 0;
+		return -EINVAL;
+	}
+
+	/* Grab the lock and see if the device is available */
+retry:
+	spin_lock_bh (&this->chip_lock);
+
+	switch (this->state) {
+	case FL_READY:
+		this->state = FL_READING;
+		spin_unlock_bh (&this->chip_lock);
+		break;
+
+	case FL_ERASING:
+		this->state = FL_READING;
+		erase_state = 1;
+		spin_unlock_bh (&this->chip_lock);
+		break;
+
+	default:
+		set_current_state (TASK_UNINTERRUPTIBLE);
+		add_wait_queue (&this->wq, &wait);
+		spin_unlock_bh (&this->chip_lock);
+		schedule();
+
+		remove_wait_queue (&this->wq, &wait);
+		goto retry;
+	};
+
+	/* First we calculate the starting page */
+	page = from >> this->page_shift;
+
+	/* Get raw starting column */
+	col = from & (mtd->oobblock - 1);
+
+	/* State machine for devices having pages larger than 256 bytes */
+	state = (col < mtd->eccsize) ? 0 : 1;
+
+	/* Calculate column address within ECC block context */
+	col = (col >= mtd->eccsize) ? (col - mtd->eccsize) : col;
+
+	/* Initialize return value */
+	*retlen = 0;
+
+	/* Select the NAND device */
+	nand_select ();
+
+	/* Loop until all data read */
+	while (*retlen < len) {
+
+#ifdef CONFIG_MTD_NAND_ECC
+		/* Send the read command */
+		if (!state)
+			nand_command (mtd, NAND_CMD_READ0, 0x00, page);
+		else 
+			nand_command (mtd, NAND_CMD_READ1, 0x00, page);
+
+		/* Read in a block big enough for ECC */
+		for (j=0 ; j < mtd->eccsize ; j++)
+			this->data_buf[j] = readb (this->IO_ADDR);
+
+		/* Read in the out-of-band data */
+		if (!state) {
+			nand_command (mtd, NAND_CMD_READOOB, 0x00, page);
+			for (j=0 ; j<3 ; j++)
+				ecc_code[j] = readb(this->IO_ADDR);
+			nand_command (mtd, NAND_CMD_READ0, 0x00, page);
+		}
+		else {
+			nand_command (mtd, NAND_CMD_READOOB, 0x03, page);
+			for (j=3 ; j<6 ; j++)
+				ecc_code[j] = readb(this->IO_ADDR);
+			nand_command (mtd, NAND_CMD_READ0, 0x00, page);
+		}
+
+		/* Calculate the ECC and verify it */
+		if (!state) {
+			nand_calculate_ecc (&this->data_buf[0],
+						&ecc_calc[0]);
+			ecc_result = nand_correct_data (&this->data_buf[0],
+						&ecc_code[0], &ecc_calc[0]);
+		}
+		else {
+			nand_calculate_ecc (&this->data_buf[0],
+						&ecc_calc[3]);
+			ecc_result = nand_correct_data (&this->data_buf[0],
+						&ecc_code[3], &ecc_calc[3]);
+		}
+		if (ecc_result == -1) {
+			DEBUG (MTD_DEBUG_LEVEL0,
+				"nand_read_ecc: " \
+				"Failed ECC read, page 0x%08x\n", page);
+			nand_deselect ();
+			spin_lock_bh (&this->chip_lock);
+			if (erase_state)
+				this->state = FL_ERASING;
+			else
+				this->state = FL_READY;
+			wake_up (&this->wq);
+			spin_unlock_bh (&this->chip_lock);
+			return -EIO;
+		}
+
+		/* Read the data from ECC data buffer into return buffer */
+		if ((*retlen + (mtd->eccsize - col)) >= len) {
+			while (*retlen < len)
+				buf[(*retlen)++] = this->data_buf[col++];
+			/* We're done */
+			continue;
+		}
+		else
+			for (j=col ; j < mtd->eccsize ; j++)
+				buf[(*retlen)++] = this->data_buf[j];
+#else
+		/* Send the read command */
+		if (!state)
+			nand_command (mtd, NAND_CMD_READ0, col, page);
+		else 
+			nand_command (mtd, NAND_CMD_READ1, col, page);
+
+		/* Read the data directly into the return buffer */ 
+		if ((*retlen + (mtd->eccsize - col)) >= len) {
+			while (*retlen < len)
+				buf[(*retlen)++] = readb (this->IO_ADDR);
+			/* We're done */
+			continue;
+		}
+		else
+			for (j=col ; j < mtd->eccsize ; j++)
+				buf[(*retlen)++] = readb (this->IO_ADDR);
+#endif
+
+		/*
+		 * If the amount of data to be read is greater than
+		 * (256 - col), then all subsequent reads will take
+		 * place on page or half-page (in the case of 512 byte
+		 * page devices) aligned boundaries and the column
+		 * address will be zero. Setting the column address to
+		 * to zero after the first read allows us to simplify
+		 * the reading of data and the if/else statements above.
+		 */
+		if (col)
+			col = 0x00;
+
+		/* Increment page address */
+		if ((mtd->oobblock == 256) || state)
+			page++;
+
+		/* Toggle state machine */
+		if (mtd->oobblock == 512)
+			state = state ? 0 : 1;
+	}
+
+	/* De-select the NAND device */
+	nand_deselect ();
+
+	/* Wake up anyone waiting on the device */
+	spin_lock_bh (&this->chip_lock);
+	if (erase_state)
+		this->state = FL_ERASING;
+	else
+		this->state = FL_READY;
+	wake_up (&this->wq);
+	spin_unlock_bh (&this->chip_lock);
+	
+	/* Return happy */
+	return 0;
+}
+
+/*
+ * NAND read out-of-band
+ */
+static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len,
+				size_t *retlen, u_char *buf)
+{
+	int i, col, page;
+	int erase_state = 0;
+	struct nand_chip *this = mtd->priv;
+	DECLARE_WAITQUEUE(wait, current);
+	
+	DEBUG (MTD_DEBUG_LEVEL3,
+		"nand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from,
+		(int) len);
+
+	/* Shift to get page */
+	page = ((int) from) >> this->page_shift;
+
+	/* Mask to get column */
+	col = from & 0x0f;
+
+	/* Initialize return length value */
+	*retlen = 0;
+
+	/* Do not allow read past end of page */
+	if ((col + len) > mtd->oobsize) {
+		DEBUG (MTD_DEBUG_LEVEL0,
+			"nand_read_oob: Attempt read past end of page " \
+			"0x%08x, column %i, length %i\n", page, col, len);
+		return -EINVAL;
+	}
+
+retry:
+	/* Grab the lock and see if the device is available */
+	spin_lock_bh (&this->chip_lock);
+
+	switch (this->state) {
+	case FL_READY:
+		this->state = FL_READING;
+		spin_unlock_bh (&this->chip_lock);
+		break;
+
+	case FL_ERASING:
+		this->state = FL_READING;
+		erase_state = 1;
+		spin_unlock_bh (&this->chip_lock);
+		break;
+
+	default:
+		set_current_state (TASK_UNINTERRUPTIBLE);
+		add_wait_queue (&this->wq, &wait);
+		spin_unlock_bh (&this->chip_lock);
+		schedule();
+
+		remove_wait_queue (&this->wq, &wait);
+		goto retry;
+	};
+
+	/* Select the NAND device */
+	nand_select ();
+
+	/* Send the read command */
+	nand_command (mtd, NAND_CMD_READOOB, col, page);	
+
+	/* Read the data */
+	for (i = 0 ; i < len ; i++)
+		buf[i] = readb (this->IO_ADDR);
+
+	/* De-select the NAND device */
+	nand_deselect ();
+
+	/* Wake up anyone waiting on the device */
+	spin_lock_bh (&this->chip_lock);
+	if (erase_state)
+		this->state = FL_ERASING;
+	else
+		this->state = FL_READY;
+	wake_up (&this->wq);
+	spin_unlock_bh (&this->chip_lock);
+
+	/* Return happy */
+	*retlen = len;
+	return 0;
+}
+
+/*
+ * NAND write
+ */
+static int nand_write (struct mtd_info *mtd, loff_t to, size_t len,
+			size_t *retlen, const u_char *buf)
+{
+#ifdef CONFIG_MTD_NAND_ECC
+	struct nand_chip *this = mtd->priv;
+	
+	return nand_write_ecc (mtd, to, len, retlen, buf, this->ecc_code_buf);
+#else
+	return nand_write_ecc (mtd, to, len, retlen, buf, NULL);
+#endif
+}
+
+/*
+ * NAND write with ECC
+ */
+static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
+				size_t *retlen, const u_char *buf,
+				u_char *ecc_code)
+{
+	int i, page, col, cnt, status;
+	struct nand_chip *this = mtd->priv;
+	DECLARE_WAITQUEUE(wait, current);
+#ifdef CONFIG_MTD_NAND_ECC
+	int ecc_bytes = (mtd->oobblock == 512) ? 6 : 3;
+#endif
+
+	DEBUG (MTD_DEBUG_LEVEL3,
+		"nand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to,
+		(int) len);
+
+	/* Do not allow write past end of page */
+	if ((to + len) > mtd->size) {
+		DEBUG (MTD_DEBUG_LEVEL0,
+			"nand_write_ecc: Attempted write past end of device\n");
+		return -EINVAL;
+	}
+
+retry:
+	/* Grab the lock and see if the device is available */
+	spin_lock_bh (&this->chip_lock);
+
+	switch (this->state) {
+	case FL_READY:
+		this->state = FL_WRITING;
+		spin_unlock_bh (&this->chip_lock);
+		break;
+
+	default:
+		set_current_state (TASK_UNINTERRUPTIBLE);
+		add_wait_queue (&this->wq, &wait);
+		spin_unlock_bh (&this->chip_lock);
+		schedule();
+
+		remove_wait_queue (&this->wq, &wait);
+		goto retry;
+	};
+
+	/* Shift to get page */
+	page = ((int) to) >> this->page_shift;
+
+	/* Get the starting column */
+	col = to & (mtd->oobblock - 1);
+
+	/* Initialize return length value */
+	*retlen = 0;
+
+	/* Select the NAND device */
+	nand_select ();
+
+	/* Check the WP bit */
+	nand_command (mtd, NAND_CMD_STATUS, -1, -1);
+	if (!(readb (this->IO_ADDR) & 0x80)) {
+		DEBUG (MTD_DEBUG_LEVEL0,
+			"nand_write_ecc: Device is write protected!!!\n");
+		nand_deselect ();
+		spin_lock_bh (&this->chip_lock);
+		this->state = FL_READY;
+		wake_up (&this->wq);
+		spin_unlock_bh (&this->chip_lock);
+		return -EIO;
+	}
+
+	/* Loop until all data is written */
+	while (*retlen < len) {
+		/* Write data into buffer */
+		if ((col + len) >= mtd->oobblock)
+			for(i=col, cnt=0 ; i < mtd->oobblock ; i++, cnt++)
+				this->data_buf[i] = buf[(*retlen + cnt)];
+		else
+			for(i=col, cnt=0 ; cnt < (len - *retlen) ; i++, cnt++)
+				this->data_buf[i] = buf[(*retlen + cnt)];
+		
+#ifdef CONFIG_MTD_NAND_ECC
+		/* Zero out the ECC array */
+		for (i=0 ; i < 6 ; i++)
+			ecc_code[i] = 0x00;
+
+		/* Calculate and write the ECC if we have enough data */
+		if ((col < mtd->eccsize) &&
+			((col + (len - *retlen)) >= mtd->eccsize)) {
+			nand_command (mtd, NAND_CMD_READ0, col, page);
+			for (i=0 ; i < col ; i++)
+				this->data_buf[i] = readb (this->IO_ADDR); 
+			nand_calculate_ecc (&this->data_buf[0], &ecc_code[0]);
+			for (i=0 ; i<3 ; i++)
+				this->data_buf[(mtd->oobblock + i)] =
+					ecc_code[i];
+		}
+
+		/* Calculate and write the second ECC if we have enough data */
+		if ((mtd->oobblock == 512) &&
+			((col + (len - *retlen)) >= mtd->oobblock)) {
+			nand_calculate_ecc (&this->data_buf[256], &ecc_code[3]);
+			for (i=3 ; i<6 ; i++)
+				this->data_buf[(mtd->oobblock + i)] =
+					ecc_code[i];
+		}
+
+		/* Write ones for partial page programming */
+		for (i=ecc_bytes ; i < mtd->oobsize ; i++)
+			this->data_buf[(mtd->oobblock + i)] = 0xff;
+#else
+		/* Write ones for partial page programming */
+		for (i=mtd->oobblock ; i < (mtd->oobblock + mtd->oobsize) ; i++)
+			this->data_buf[i] = 0xff;
+#endif
+
+		/* Write pre-padding bytes into buffer */
+		for (i=0 ; i < col ; i++)
+			this->data_buf[i] = 0xff;
+
+		/* Write post-padding bytes into buffer */
+		if ((col + (len - *retlen)) < mtd->oobblock) {
+			for(i=(col + cnt) ; i < mtd->oobblock ; i++)
+				this->data_buf[i] = 0xff;
+		}
+
+		/* Send command to begin auto page programming */
+		nand_command (mtd, NAND_CMD_SEQIN, 0x00, page);
+
+		/* Write out complete page of data */
+		for (i=0 ; i < (mtd->oobblock + mtd->oobsize) ; i++)
+			writeb (this->data_buf[i], this->IO_ADDR);
+
+		/* Send command to actually program the data */
+		nand_command (mtd, NAND_CMD_PAGEPROG, -1, -1);
+
+		/*
+		 * Wait for program operation to complete. This could
+		 * take up to 3000us (3ms) on some devices, so we try
+		 * and exit as quickly as possible.
+		 */
+		status = 0;
+		for (i=0 ; i<24 ; i++) {
+			/* Delay for 125us */
+			udelay (125);
+
+			/* Check the status */
+			nand_command (mtd, NAND_CMD_STATUS, -1, -1);
+			status = (int) readb (this->IO_ADDR);
+			if (status & 0x40)
+				break;
+		}
+
+		/* See if device thinks it succeeded */
+		if (status & 0x01) {
+			DEBUG (MTD_DEBUG_LEVEL0,
+				"nand_write_ecc: " \
+				"Failed write, page 0x%08x, " \
+				"%6i bytes were succesful\n", page, *retlen);
+			nand_deselect ();
+			spin_lock_bh (&this->chip_lock);
+			this->state = FL_READY;
+			wake_up (&this->wq);
+			spin_unlock_bh (&this->chip_lock);
+			return -EIO;
+		}
+
+#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
+		/*
+		 * The NAND device assumes that it is always writing to
+		 * a cleanly erased page. Hence, it performs its internal
+		 * write verification only on bits that transitioned from
+		 * 1 to 0. The device does NOT verify the whole page on a
+		 * byte by byte basis. It is possible that the page was
+		 * not completely erased or the page is becoming unusable
+		 * due to wear. The read with ECC would catch the error
+		 * later when the ECC page check fails, but we would rather
+		 * catch it early in the page write stage. Better to write
+		 * no data than invalid data.
+		 */
+		
+		/* Send command to read back the page */
+		if (col < mtd->eccsize)
+			nand_command (mtd, NAND_CMD_READ0, col, page);
+		else
+			nand_command (mtd, NAND_CMD_READ1, col - 256, page);
+
+		/* Loop through and verify the data */
+		for (i=col ; i < cnt ; i++) {
+			if (this->data_buf[i] != readb (this->IO_ADDR)) {
+				DEBUG (MTD_DEBUG_LEVEL0,
+					"nand_write_ecc: " \
+					"Failed write verify, page 0x%08x, " \
+					"%6i bytes were succesful\n",
+					page, *retlen);
+				nand_deselect ();
+				spin_lock_bh (&this->chip_lock);
+				this->state = FL_READY;
+				wake_up (&this->wq);
+				spin_unlock_bh (&this->chip_lock);
+				return -EIO;
+			}
+		}
+
+#ifdef CONFIG_MTD_NAND_ECC
+		/*
+		 * We also want to check that the ECC bytes wrote
+		 * correctly for the same reasons stated above.
+		 */
+		nand_command (mtd, NAND_CMD_READOOB, 0x00, page);
+		for (i=0 ; i < ecc_bytes ; i++) {
+			if ((readb (this->IO_ADDR) != ecc_code[i]) &&
+					ecc_code[i]) {
+				DEBUG (MTD_DEBUG_LEVEL0,
+					"nand_write_ecc: Failed ECC write " \
+					"verify, page 0x%08x, " \
+					"%6i bytes were succesful\n",
+					page, i);
+				nand_deselect ();
+				spin_lock_bh (&this->chip_lock);
+				this->state = FL_READY;
+				wake_up (&this->wq);
+				spin_unlock_bh (&this->chip_lock);
+				return -EIO;
+			}
+		}
+#endif
+
+#endif
+
+		/*
+		 * If we are writing a large amount of data and/or it
+		 * crosses page or half-page boundaries, we set the
+		 * the column to zero. It simplifies the program logic.
+		 */
+		if (col)
+			col = 0x00;
+
+		/* Update written bytes count */
+		*retlen += cnt;
+
+		/* Increment page address */
+		page++;
+	}
+
+	/* De-select the NAND device */
+	nand_deselect ();
+
+	/* Wake up anyone waiting on the device */
+	spin_lock_bh (&this->chip_lock);
+	this->state = FL_READY;
+	wake_up (&this->wq);
+	spin_unlock_bh (&this->chip_lock);
+
+	/* Return happy */
+	*retlen = len;
+	return 0;
+}
+
+/*
+ * NAND write out-of-band
+ */
+static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len,
+				size_t *retlen, const u_char *buf)
+{
+	int i, column, page, status;
+	struct nand_chip *this = mtd->priv;
+	DECLARE_WAITQUEUE(wait, current);
+	
+	DEBUG (MTD_DEBUG_LEVEL3,
+		"nand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to,
+		(int) len);
+
+	/* Shift to get page */
+	page = ((int) to) >> this->page_shift;
+
+	/* Mask to get column */
+	column = to & 0x1f;
+
+	/* Initialize return length value */
+	*retlen = 0;
+
+	/* Do not allow write past end of page */
+	if ((column + len) > mtd->oobsize) {
+		DEBUG (MTD_DEBUG_LEVEL0,
+			"nand_write_oob: Attempt to write past end of page\n");
+		return -EINVAL;
+	}
+
+retry:
+	/* Grab the lock and see if the device is available */
+	spin_lock_bh (&this->chip_lock);
+
+	switch (this->state) {
+	case FL_READY:
+		this->state = FL_WRITING;
+		spin_unlock_bh (&this->chip_lock);
+		break;
+
+	default:
+		set_current_state (TASK_UNINTERRUPTIBLE);
+		add_wait_queue (&this->wq, &wait);
+		spin_unlock_bh (&this->chip_lock);
+		schedule();
+
+		remove_wait_queue (&this->wq, &wait);
+		goto retry;
+	};
+
+	/* Select the NAND device */
+	nand_select ();
+
+	/* Check the WP bit */
+	nand_command (mtd, NAND_CMD_STATUS, -1, -1);
+	if (!(readb (this->IO_ADDR) & 0x80)) {
+		DEBUG (MTD_DEBUG_LEVEL0,
+			"nand_write_oob: Device is write protected!!!\n");
+		nand_deselect ();
+		spin_lock_bh (&this->chip_lock);
+		this->state = FL_READY;
+		wake_up (&this->wq);
+		spin_unlock_bh (&this->chip_lock);
+		return -EIO;
+	}
+
+	/* Write out desired data */
+	nand_command (mtd, NAND_CMD_SEQIN, column + 512, page);
+	for (i=0 ; i<len ; i++)
+		writeb (buf[i], this->IO_ADDR);
+
+	/* Send command to program the OOB data */
+	nand_command (mtd, NAND_CMD_PAGEPROG, -1, -1);
+
+	/*
+	 * Wait for program operation to complete. This could
+	 * take up to 3000us (3ms) on some devices, so we try
+	 * and exit as quickly as possible.
+	 */
+	status = 0;
+	for (i=0 ; i<24 ; i++) {
+		/* Delay for 125us */
+		udelay (125);
+
+		/* Check the status */
+		nand_command (mtd, NAND_CMD_STATUS, -1, -1);
+		status = (int) readb (this->IO_ADDR);
+		if (status & 0x40)
+			break;
+	}
+
+	/* See if device thinks it succeeded */
+	if (status & 0x01) {
+		DEBUG (MTD_DEBUG_LEVEL0,
+			"nand_write_oob: " \
+			"Failed write, page 0x%08x\n", page);
+		nand_deselect ();
+		spin_lock_bh (&this->chip_lock);
+		this->state = FL_READY;
+		wake_up (&this->wq);
+		spin_unlock_bh (&this->chip_lock);
+		return -EIO;
+	}
+
+#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
+	/* Send command to read back the data */
+	nand_command (mtd, NAND_CMD_READOOB, column, page);
+
+	/* Loop through and verify the data */
+	for (i=0 ; i<len ; i++) {
+		if (buf[i] != readb (this->IO_ADDR)) {
+			DEBUG (MTD_DEBUG_LEVEL0,
+				"nand_write_oob: " \
+				"Failed write verify, page 0x%08x\n", page);
+			nand_deselect ();
+			spin_lock_bh (&this->chip_lock);
+			this->state = FL_READY;
+			wake_up (&this->wq);
+			spin_unlock_bh (&this->chip_lock);
+			return -EIO;
+		}
+	}
+#endif
+
+	/* De-select the NAND device */
+	nand_deselect ();
+
+	/* Wake up anyone waiting on the device */
+	spin_lock_bh (&this->chip_lock);
+	this->state = FL_READY;
+	wake_up (&this->wq);
+	spin_unlock_bh (&this->chip_lock);
+
+	/* Return happy */
+	*retlen = len;
+	return 0;
+}
+
+/*
+ * NAND write with iovec
+ */
+static int nand_writev (struct mtd_info *mtd, const struct iovec *vecs,
+				unsigned long count, loff_t to, size_t *retlen)
+{
+	int i, page, col, cnt, len, total_len, status;
+	struct nand_chip *this = mtd->priv;
+	DECLARE_WAITQUEUE(wait, current);
+#ifdef CONFIG_MTD_NAND_ECC
+	int ecc_bytes = (mtd->oobblock == 512) ? 6 : 3;
+#endif
+
+	/* Calculate total length of data */
+	total_len = 0;
+	for (i=0 ; i < count ; i++)
+		total_len += (int) vecs[i].iov_len;
+
+	DEBUG (MTD_DEBUG_LEVEL3,
+		"nand_writev: to = 0x%08x, len = %i\n", (unsigned int) to,
+			(unsigned int) total_len);
+
+	/* Do not allow write past end of page */
+	if ((to + total_len) > mtd->size) {
+		DEBUG (MTD_DEBUG_LEVEL0,
+			"nand_writev: Attempted write past end of device\n");
+		return -EINVAL;
+	}
+
+retry:
+	/* Grab the lock and see if the device is available */
+	spin_lock_bh (&this->chip_lock);
+
+	switch (this->state) {
+	case FL_READY:
+		this->state = FL_WRITING;
+		spin_unlock_bh (&this->chip_lock);
+		break;
+
+	default:
+		set_current_state (TASK_UNINTERRUPTIBLE);
+		add_wait_queue (&this->wq, &wait);
+		spin_unlock_bh (&this->chip_lock);
+		schedule();
+
+		remove_wait_queue (&this->wq, &wait);
+		goto retry;
+	};
+
+	/* Shift to get page */
+	page = ((int) to) >> this->page_shift;
+
+	/* Get the starting column */
+	col = to & (mtd->oobblock - 1);
+
+	/* Initialize return length value */
+	*retlen = 0;
+
+	/* Select the NAND device */
+	nand_select ();
+
+	/* Check the WP bit */
+	nand_command (mtd, NAND_CMD_STATUS, -1, -1);
+	if (!(readb (this->IO_ADDR) & 0x80)) {
+		DEBUG (MTD_DEBUG_LEVEL0,
+			"nand_writev: Device is write protected!!!\n");
+		nand_deselect ();
+		spin_lock_bh (&this->chip_lock);
+		this->state = FL_READY;
+		wake_up (&this->wq);
+		spin_unlock_bh (&this->chip_lock);
+		return -EIO;
+	}
+
+	/* Loop until all iovecs' data has been written */
+	cnt = col;
+	len = 0;
+	while (count) {
+		/* Do any need pre-fill for partial page programming */
+		for (i=0 ; i < cnt ; i++)
+			this->data_buf[i] = 0xff;
+
+		/*
+		 * Read data out of each tuple until we have a full page
+		 * to write or we've read all the tuples.
+		 */
+		while ((cnt < mtd->oobblock) && count) {
+			this->data_buf[cnt++] =
+				((u_char *) vecs->iov_base)[len++];
+			if (len >= (int) vecs->iov_len) {
+				vecs++;
+				len = 0;
+				count--;
+			}
+		}
+		
+		/* Do any need post-fill for partial page programming */
+		for (i=cnt ; i < mtd->oobblock ; i++)
+			this->data_buf[i] = 0xff;
+
+#ifdef CONFIG_MTD_NAND_ECC
+		/* Zero out the ECC array */
+		for (i=0 ; i < 6 ; i++)
+			this->ecc_code_buf[i] = 0x00;
+
+		/* Calculate and write the first ECC */
+		if (col >= mtd->eccsize) {
+			nand_command (mtd, NAND_CMD_READ0, col, page);
+			for (i=0 ; i < col ; i++)
+				this->data_buf[i] = readb (this->IO_ADDR); 
+			nand_calculate_ecc (&this->data_buf[0],
+				&(this->ecc_code_buf[0]));
+			for (i=0 ; i<3 ; i++)
+				this->data_buf[(mtd->oobblock + i)] =
+					this->ecc_code_buf[i];
+		}
+
+		/* Calculate and write the second ECC */
+		if ((mtd->oobblock == 512) && (cnt == mtd->oobblock)) {
+			nand_calculate_ecc (&this->data_buf[256],
+				&(this->ecc_code_buf[3]));
+			for (i=3 ; i<6 ; i++)
+				this->data_buf[(mtd->oobblock + i)] =
+					this->ecc_code_buf[i];
+		}
+
+		/* Write ones for partial page programming */
+		for (i=ecc_bytes ; i < mtd->oobsize ; i++)
+			this->data_buf[(mtd->oobblock + i)] = 0xff;
+#else
+		/* Write ones for partial page programming */
+		for (i=mtd->oobblock ; i < (mtd->oobblock + mtd->oobsize) ; i++)
+			this->data_buf[i] = 0xff;
+#endif
+		/* Send command to begin auto page programming */
+		nand_command (mtd, NAND_CMD_SEQIN, 0x00, page);
+
+		/* Write out complete page of data */
+		for (i=0 ; i < (mtd->oobblock + mtd->oobsize) ; i++)
+			writeb (this->data_buf[i], this->IO_ADDR);
+
+		/* Send command to actually program the data */
+		nand_command (mtd, NAND_CMD_PAGEPROG, -1, -1);
+
+		/*
+		 * Wait for program operation to complete. This could
+		 * take up to 3000us (3ms) on some devices, so we try
+		 * and exit as quickly as possible.
+		 */
+		status = 0;
+		for (i=0 ; i<24 ; i++) {
+			/* Delay for 125us */
+			udelay (125);
+
+			/* Check the status */
+			nand_command (mtd, NAND_CMD_STATUS, -1, -1);
+			status = (int) readb (this->IO_ADDR);
+			if (status & 0x40)
+				break;
+		}
+
+		/* See if device thinks it succeeded */
+		if (status & 0x01) {
+			DEBUG (MTD_DEBUG_LEVEL0,
+				"nand_writev: " \
+				"Failed write, page 0x%08x, " \
+				"%6i bytes were succesful\n", page, *retlen);
+			nand_deselect ();
+			spin_lock_bh (&this->chip_lock);
+			this->state = FL_READY;
+			wake_up (&this->wq);
+			spin_unlock_bh (&this->chip_lock);
+			return -EIO;
+		}
+
+#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
+		/*
+		 * The NAND device assumes that it is always writing to
+		 * a cleanly erased page. Hence, it performs its internal
+		 * write verification only on bits that transitioned from
+		 * 1 to 0. The device does NOT verify the whole page on a
+		 * byte by byte basis. It is possible that the page was
+		 * not completely erased or the page is becoming unusable
+		 * due to wear. The read with ECC would catch the error
+		 * later when the ECC page check fails, but we would rather
+		 * catch it early in the page write stage. Better to write
+		 * no data than invalid data.
+		 */
+		
+		/* Send command to read back the page */
+		if (col < mtd->eccsize)
+			nand_command (mtd, NAND_CMD_READ0, col, page);
+		else
+			nand_command (mtd, NAND_CMD_READ1, col - 256, page);
+
+		/* Loop through and verify the data */
+		for (i=col ; i < cnt ; i++) {
+			if (this->data_buf[i] != readb (this->IO_ADDR)) {
+				DEBUG (MTD_DEBUG_LEVEL0,
+					"nand_writev: " \
+					"Failed write verify, page 0x%08x, " \
+					"%6i bytes were succesful\n",
+					page, *retlen);
+				nand_deselect ();
+				spin_lock_bh (&this->chip_lock);
+				this->state = FL_READY;
+				wake_up (&this->wq);
+				spin_unlock_bh (&this->chip_lock);
+				return -EIO;
+			}
+		}
+
+#ifdef CONFIG_MTD_NAND_ECC
+		/*
+		 * We also want to check that the ECC bytes wrote
+		 * correctly for the same reasons stated above.
+		 */
+		nand_command (mtd, NAND_CMD_READOOB, 0x00, page);
+		for (i=0 ; i < ecc_bytes ; i++) {
+			if ((readb (this->IO_ADDR) != this->ecc_code_buf[i]) &&
+					this->ecc_code_buf[i]) {
+				DEBUG (MTD_DEBUG_LEVEL0,
+					"nand_writev: Failed ECC write " \
+					"verify, page 0x%08x, " \
+					"%6i bytes were succesful\n",
+					page, i);
+				nand_deselect ();
+				spin_lock_bh (&this->chip_lock);
+				this->state = FL_READY;
+				wake_up (&this->wq);
+				spin_unlock_bh (&this->chip_lock);
+				return -EIO;
+			}
+		}
+#endif
+
+#endif
+		/* Update written bytes count */
+		*retlen += (cnt - col);
+
+		/* Reset written byte counter and column */
+		col = cnt = 0;
+
+		/* Increment page address */
+		page++;
+	}
+
+	/* De-select the NAND device */
+	nand_deselect ();
+
+	/* Wake up anyone waiting on the device */
+	spin_lock_bh (&this->chip_lock);
+	this->state = FL_READY;
+	wake_up (&this->wq);
+	spin_unlock_bh (&this->chip_lock);
+
+	/* Return happy */
+	return 0;
+}
+
+/*
+ * NAND erase a block
+ */
+static int nand_erase (struct mtd_info *mtd, struct erase_info *instr)
+{
+	int i, page, len, status, pages_per_block;
+	struct nand_chip *this = mtd->priv;
+	DECLARE_WAITQUEUE(wait, current);
+
+	DEBUG (MTD_DEBUG_LEVEL3,
+		"nand_erase: start = 0x%08x, len = %i\n",
+		(unsigned int) instr->addr, (unsigned int) instr->len);
+
+	/* Start address must align on block boundary */
+	if (instr->addr & (mtd->erasesize - 1)) {
+		DEBUG (MTD_DEBUG_LEVEL0,
+			"nand_erase: Unaligned address\n");
+		return -EINVAL;
+	}
+
+	/* Length must align on block boundary */
+	if (instr->len & (mtd->erasesize - 1)) {
+		DEBUG (MTD_DEBUG_LEVEL0,
+			"nand_erase: Length not block aligned\n");
+		return -EINVAL;
+	}
+
+	/* Do not allow erase past end of device */
+	if ((instr->len + instr->addr) > mtd->size) {
+		DEBUG (MTD_DEBUG_LEVEL0,
+			"nand_erase: Erase past end of device\n");
+		return -EINVAL;
+	}
+
+retry:
+	/* Grab the lock and see if the device is available */
+	spin_lock_bh (&this->chip_lock);
+
+	switch (this->state) {
+	case FL_READY:
+		this->state = FL_ERASING;
+		break;
+
+	default:
+		set_current_state (TASK_UNINTERRUPTIBLE);
+		add_wait_queue (&this->wq, &wait);
+		spin_unlock_bh (&this->chip_lock);
+		schedule();
+
+		remove_wait_queue (&this->wq, &wait);
+		goto retry;
+	};
+
+	/* Shift to get first page */
+	page = (int) (instr->addr >> this->page_shift);
+
+	/* Calculate pages in each block */
+	pages_per_block = mtd->erasesize / mtd->oobblock;
+
+	/* Select the NAND device */
+	nand_select ();
+
+	/* Check the WP bit */
+	nand_command (mtd, NAND_CMD_STATUS, -1, -1);
+	if (!(readb (this->IO_ADDR) & 0x80)) {
+		DEBUG (MTD_DEBUG_LEVEL0,
+			"nand_erase: Device is write protected!!!\n");
+		nand_deselect ();
+		this->state = FL_READY;
+		spin_unlock_bh (&this->chip_lock);
+		return -EIO;
+	}
+
+	/* Loop through the pages */
+	len = instr->len;
+	while (len) {
+		/* Send commands to erase a page */
+		nand_command(mtd, NAND_CMD_ERASE1, -1, page);
+		nand_command(mtd, NAND_CMD_ERASE2, -1, -1);
+
+		/*
+		 * Wait for program operation to complete. This could
+		 * take up to 4000us (4ms) on some devices, so we try
+		 * and exit as quickly as possible.
+		 */
+		status = 0;
+		for (i=0 ; i<32 ; i++) {
+			/* Delay for 125us */
+			udelay (125);
+
+			/* Check the status */
+			nand_command (mtd, NAND_CMD_STATUS, -1, -1);
+			status = (int) readb (this->IO_ADDR);
+			if (status & 0x40)
+				break;
+		}
+
+		/* See if block erase succeeded */
+		if (status & 0x01) {
+			DEBUG (MTD_DEBUG_LEVEL0,
+				"nand_erase: " \
+				"Failed erase, page 0x%08x\n", page);
+			nand_deselect ();
+			this->state = FL_READY;
+			spin_unlock_bh (&this->chip_lock);
+			return -EIO;
+		}
+
+		/* Increment page address and decrement length */
+		len -= mtd->erasesize;
+		page += pages_per_block;
+
+		/* Release the spin lock */
+		spin_unlock_bh (&this->chip_lock);
+
+erase_retry:
+		/* Check the state and sleep if it changed */
+		spin_lock_bh (&this->chip_lock);
+		if (this->state == FL_ERASING) {
+			continue;
+		}
+		else {
+			set_current_state (TASK_UNINTERRUPTIBLE);
+			add_wait_queue (&this->wq, &wait);
+			spin_unlock_bh (&this->chip_lock);
+			schedule();
+
+			remove_wait_queue (&this->wq, &wait);
+			goto erase_retry;
+		}
+	}
+	spin_unlock_bh (&this->chip_lock);
+
+	/* De-select the NAND device */
+	nand_deselect ();
+
+	/* Do call back function */
+	if (instr->callback)
+		instr->callback (instr);
+
+	/* The device is ready */
+	spin_lock_bh (&this->chip_lock);
+	this->state = FL_READY;
+	spin_unlock_bh (&this->chip_lock);
+
+	/* Return happy */
+	return 0;
+}
+
+/*
+ * NAND sync
+ */
+static void nand_sync (struct mtd_info *mtd)
+{
+	struct nand_chip *this = mtd->priv;
+	DECLARE_WAITQUEUE(wait, current);
+
+	DEBUG (MTD_DEBUG_LEVEL3, "nand_sync: called\n");
+
+retry:
+	/* Grab the spinlock */
+	spin_lock_bh(&this->chip_lock);
+
+	/* See what's going on */
+	switch(this->state) {
+	case FL_READY:
+	case FL_SYNCING:
+		this->state = FL_SYNCING;
+		spin_unlock_bh (&this->chip_lock);
+		break;
+
+	default:
+		/* Not an idle state */
+		add_wait_queue (&this->wq, &wait);
+		spin_unlock_bh (&this->chip_lock);
+		schedule ();
+
+		remove_wait_queue (&this->wq, &wait);
+		goto retry;
+	}
+
+        /* Lock the device */
+	spin_lock_bh (&this->chip_lock);
+
+	/* Set the device to be ready again */
+	if (this->state == FL_SYNCING) {
+		this->state = FL_READY;
+		wake_up (&this->wq);
+	}
+
+        /* Unlock the device */
+	spin_unlock_bh (&this->chip_lock);
+}
+
+/*
+ * Scan for the NAND device
+ */
+int nand_scan (struct mtd_info *mtd)
+{
+	int i, nand_maf_id, nand_dev_id;
+	struct nand_chip *this = mtd->priv;
+
+	/* Select the device */
+	nand_select ();
+
+	/* Send the command for reading device ID */
+	nand_command (mtd, NAND_CMD_READID, 0x00, -1);
+
+	/* Read manufacturer and device IDs */
+	nand_maf_id = readb (this->IO_ADDR);
+	nand_dev_id = readb (this->IO_ADDR);
+
+	/* Print and store flash device information */
+	for (i = 0; nand_flash_ids[i].name != NULL; i++) {
+		if (nand_maf_id == nand_flash_ids[i].manufacture_id &&
+		    nand_dev_id == nand_flash_ids[i].model_id) {
+			if (!mtd->size) {
+				mtd->name = nand_flash_ids[i].name;
+				mtd->erasesize = nand_flash_ids[i].erasesize;
+				mtd->size = (1 << nand_flash_ids[i].chipshift);
+				mtd->eccsize = 256;
+				if (nand_flash_ids[i].page256) {
+					mtd->oobblock = 256;
+					mtd->oobsize = 8;
+					this->page_shift = 8;
+				}
+				else {
+					mtd->oobblock = 512;
+					mtd->oobsize = 16;
+					this->page_shift = 9;
+				}
+			}
+			printk (KERN_INFO "NAND device: Manufacture ID:" \
+				" 0x%02x, Chip ID: 0x%02x (%s)\n",
+			       nand_maf_id, nand_dev_id, mtd->name);
+			break;
+		}
+	}
+
+	/* Initialize state and spinlock */
+	this->state = FL_READY;
+	spin_lock_init(&this->chip_lock);
+
+	/* De-select the device */
+	nand_deselect ();
+
+	/* Print warning message for no device */
+	if (!mtd->size) {
+		printk (KERN_WARNING "No NAND device found!!!\n");
+		return 1;
+	}
+
+	/* Fill in remaining MTD driver data */
+	mtd->type = MTD_NANDFLASH;
+	mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC;
+	mtd->module = THIS_MODULE;
+	mtd->ecctype = MTD_ECC_SW;
+	mtd->erase = nand_erase;
+	mtd->point = NULL;
+	mtd->unpoint = NULL;
+	mtd->read = nand_read;
+	mtd->write = nand_write;
+	mtd->read_ecc = nand_read_ecc;
+	mtd->write_ecc = nand_write_ecc;
+	mtd->read_oob = nand_read_oob;
+	mtd->write_oob = nand_write_oob;
+	mtd->readv = NULL;
+	mtd->writev = nand_writev;
+	mtd->sync = nand_sync;
+	mtd->lock = NULL;
+	mtd->unlock = NULL;
+	mtd->suspend = NULL;
+	mtd->resume = NULL;
+
+	/* Return happy */
+	return 0;
+}
+
+EXPORT_SYMBOL(nand_scan);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/nand/nand_ecc.c linux/drivers/mtd/nand/nand_ecc.c
--- v2.4.5/linux/drivers/mtd/nand/nand_ecc.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/nand/nand_ecc.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,204 @@
+/*
+ *  drivers/mtd/nand_ecc.c
+ *
+ *  Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
+ *                     Toshiba America Electronics Components, Inc.
+ *
+ * $Id: nand_ecc.c,v 1.4 2001/01/03 20:02:20 mgadbois Exp $
+ *
+ * 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.
+ *
+ * This file contains an ECC algorithm from Toshiba that detects and
+ * corrects 1 bit errors in a 256 byte block of data.
+ */
+
+#include <linux/types.h>
+
+/*
+ * Pre-calculated 256-way 1 byte column parity
+ */
+const u_char nand_ecc_precalc_table[] = {
+	0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
+	0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
+	0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
+	0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
+	0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
+	0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
+	0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
+	0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
+	0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
+	0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
+	0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
+	0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
+	0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
+	0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
+	0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
+	0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
+};
+
+
+/*
+ * Creates non-inverted ECC code from line parity
+ */
+void nand_trans_result(u_char reg2, u_char reg3,
+	u_char *ecc_code)
+{
+	u_char a, b, i, tmp1, tmp2;
+	
+	/* Initialize variables */
+	a = b = 0x80;
+	tmp1 = tmp2 = 0;
+	
+	/* Calculate first ECC byte */
+	for (i = 0; i < 4; i++) {
+		if (reg3 & a)		/* LP15,13,11,9 --> ecc_code[0] */
+			tmp1 |= b;
+		b >>= 1;
+		if (reg2 & a)		/* LP14,12,10,8 --> ecc_code[0] */
+			tmp1 |= b;
+		b >>= 1;
+		a >>= 1;
+	}
+	
+	/* Calculate second ECC byte */
+	b = 0x80;
+	for (i = 0; i < 4; i++) {
+		if (reg3 & a)		/* LP7,5,3,1 --> ecc_code[1] */
+			tmp2 |= b;
+		b >>= 1;
+		if (reg2 & a)		/* LP6,4,2,0 --> ecc_code[1] */
+			tmp2 |= b;
+		b >>= 1;
+		a >>= 1;
+	}
+	
+	/* Store two of the ECC bytes */
+	ecc_code[0] = tmp1;
+	ecc_code[1] = tmp2;
+}
+
+/*
+ * Calculate 3 byte ECC code for 256 byte block
+ */
+void nand_calculate_ecc (const u_char *dat, u_char *ecc_code)
+{
+	u_char idx, reg1, reg2, reg3;
+	int j;
+	
+	/* Initialize variables */
+	reg1 = reg2 = reg3 = 0;
+	ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
+	
+	/* Build up column parity */ 
+	for(j = 0; j < 256; j++) {
+		
+		/* Get CP0 - CP5 from table */
+		idx = nand_ecc_precalc_table[dat[j]];
+		reg1 ^= (idx & 0x3f);
+		
+		/* All bit XOR = 1 ? */
+		if (idx & 0x40) {
+			reg3 ^= (u_char) j;
+			reg2 ^= ~((u_char) j);
+		}
+	}
+	
+	/* Create non-inverted ECC code from line parity */
+	nand_trans_result(reg2, reg3, ecc_code);
+	
+	/* Calculate final ECC code */
+	ecc_code[0] = ~ecc_code[0];
+	ecc_code[1] = ~ecc_code[1];
+	ecc_code[2] = ((~reg1) << 2) | 0x03;
+}
+
+/*
+ * Detect and correct a 1 bit error for 256 byte block
+ */
+int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc)
+{
+	u_char a, b, c, d1, d2, d3, add, bit, i;
+	
+	/* Do error detection */ 
+	d1 = calc_ecc[0] ^ read_ecc[0];
+	d2 = calc_ecc[1] ^ read_ecc[1];
+	d3 = calc_ecc[2] ^ read_ecc[2];
+	
+	if ((d1 | d2 | d3) == 0) {
+		/* No errors */
+		return 0;
+	}
+	else {
+		a = (d1 ^ (d1 >> 1)) & 0x55;
+		b = (d2 ^ (d2 >> 1)) & 0x55;
+		c = (d3 ^ (d3 >> 1)) & 0x54;
+		
+		/* Found and will correct single bit error in the data */
+		if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
+			c = 0x80;
+			add = 0;
+			a = 0x80;
+			for (i=0; i<4; i++) {
+				if (d1 & c)
+					add |= a;
+				c >>= 2;
+				a >>= 1;
+			}
+			c = 0x80;
+			for (i=0; i<4; i++) {
+				if (d2 & c)
+					add |= a;
+				c >>= 2;
+				a >>= 1;
+			}
+			bit = 0;
+			b = 0x04;
+			c = 0x80;
+			for (i=0; i<3; i++) {
+				if (d3 & c)
+					bit |= b;
+				c >>= 2;
+				b >>= 1;
+			}
+			b = 0x01;
+			a = dat[add];
+			a ^= (b << bit);
+			dat[add] = a;
+			return 1;
+		}
+		else {
+			i = 0;
+			while (d1) {
+				if (d1 & 0x01)
+					++i;
+				d1 >>= 1;
+			}
+			while (d2) {
+				if (d2 & 0x01)
+					++i;
+				d2 >>= 1;
+			}
+			while (d3) {
+				if (d3 & 0x01)
+					++i;
+				d3 >>= 1;
+			}
+			if (i == 1) {
+				/* ECC Code Error Correction */
+				read_ecc[0] = calc_ecc[0];
+				read_ecc[1] = calc_ecc[1];
+				read_ecc[2] = calc_ecc[2];
+				return 2;
+			}
+			else {
+				/* Uncorrectable Error */
+				return -1;
+			}
+		}
+	}
+	
+	/* Should never happen */
+	return -1;
+}
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/nand/spia.c linux/drivers/mtd/nand/spia.c
--- v2.4.5/linux/drivers/mtd/nand/spia.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/nand/spia.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,129 @@
+/*
+ *  drivers/mtd/spia.c
+ *
+ *  Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
+ *
+ * $Id: spia.c,v 1.9 2001/06/02 14:47:16 dwmw2 Exp $
+ *
+ * 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.
+ *
+ *  Overview:
+ *   This is a device driver for the NAND flash device found on the
+ *   SPIA board which utilizes the Toshiba TC58V64AFT part. This is
+ *   a 64Mibit (8MiB x 8 bits) NAND flash device.
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <asm/io.h>
+
+/*
+ * MTD structure for SPIA board
+ */
+static struct mtd_info *spia_mtd = NULL;
+
+/*
+ * Module stuff
+ */
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+  #define spia_init init_module
+  #define spia_cleanup cleanup_module
+#endif
+
+/*
+ * Define partitions for flash device
+ */
+const static struct mtd_partition partition_info[] = {
+	{ name: "SPIA flash partition 1",
+	  offset: 0,
+	  size: 2*1024*1024 },
+	{ name: "SPIA flash partition 2",
+	  offset: 2*1024*1024,
+	  size: 6*1024*1024 }
+};
+#define NUM_PARTITIONS 2
+
+/*
+ * Main initialization routine
+ */
+int __init spia_init (void)
+{
+	struct nand_chip *this;
+
+	/* Allocate memory for MTD device structure and private data */
+	spia_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
+				GFP_KERNEL);
+	if (!spia_mtd) {
+		printk ("Unable to allocate SPIA NAND MTD device structure.\n");
+		return -ENOMEM;
+	}
+
+	/* Get pointer to private data */
+	this = (struct nand_chip *) (&spia_mtd[1]);
+
+	/* Initialize structures */
+	memset((char *) spia_mtd, 0, sizeof(struct mtd_info));
+	memset((char *) this, 0, sizeof(struct nand_chip));
+
+	/* Link the private data with the MTD structure */
+	spia_mtd->priv = this;
+
+	/*
+	 * Set GPIO Port E control register so that the pins are configured
+	 * to be outputs for controlling the NAND flash.
+	 */
+	(*(volatile unsigned char *) (IO_BASE + PEDDR)) = 0x07;
+
+	/* Set address of NAND IO lines */
+	this->IO_ADDR = FIO_BASE;
+	this->CTRL_ADDR = IO_BASE + PEDR;
+	this->CLE = 0x01;
+	this->ALE = 0x02;
+	this->NCE = 0x04;
+
+	/* Scan to find existance of the device */
+	if (nand_scan (spia_mtd)) {
+		kfree (spia_mtd);
+		return -ENXIO;
+	}
+
+	/* Allocate memory for internal data buffer */
+	this->data_buf = kmalloc (sizeof(u_char) * (spia_mtd->oobblock + spia_mtd->oobsize), GFP_KERNEL);
+	if (!this->data_buf) {
+		printk ("Unable to allocate NAND data buffer for SPIA.\n");
+		kfree (spia_mtd);
+		return -ENOMEM;
+	}
+
+	/* Register the partitions */
+	add_mtd_partitions(spia_mtd, partition_info, NUM_PARTITIONS);
+
+	/* Return happy */
+	return 0;
+}
+module_init(spia_init);
+
+/*
+ * Clean up routine
+ */
+#ifdef MODULE
+static void __exit spia_cleanup (void)
+{
+	struct nand_chip *this = (struct nand_chip *) &spia_mtd[1];
+
+	/* Unregister the device */
+	del_mtd_device (spia_mtd);
+
+	/* Free internal data buffer */
+	kfree (this->data_buf);
+
+	/* Free the MTD device structure */
+	kfree (spia_mtd);
+}
+module_exit(spia_cleanup);
+#endif
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/nftl.c linux/drivers/mtd/nftl.c
--- v2.4.5/linux/drivers/mtd/nftl.c	Sat Apr 28 11:27:54 2001
+++ linux/drivers/mtd/nftl.c	Wed Dec 31 16:00:00 1969
@@ -1,1108 +0,0 @@
-/* Linux driver for NAND Flash Translation Layer      */
-/* (c) 1999 Machine Vision Holdings, Inc.             */
-/* Author: David Woodhouse <dwmw2@infradead.org>      */
-/* $Id: nftl.c,v 1.57 2000/12/01 17:51:54 dwmw2 Exp $ */
-
-/*
-  The contents of this file are distributed under the GNU General
-  Public License version 2 ("GPL"). The author places no additional
-  restrictions of any kind on it. However, local legislation in some
-  countries may restrict the use of the algorithms implemented by this
-  code in certain circumstances.
-
-  The legal note below refers only to the _use_ of the code in the 
-  affected jurisdictions, and does not in any way affect the copying,
-  distribution and modification of this code, which are permitted, and
-  indeed required, under the terms of the GPL.
-
-  Section 0 of the GPL says:
- "Activities other than copying, distribution and modification are not
-  covered by this License; they are outside its scope."
-
-  You may copy, distribute and modify this code to your hearts'
-  content - it's just that in some jurisdictions, you may only _use_
-  it under the terms of the patent grant below. This puts it in a
-  similar situation to the ISDN code, which you may need telco
-  approval to use, and indeed any code which has uses that may be
-  restricted in law. For example, certain malicious uses of the
-  networking stack may be illegal, but that doesn't prevent the
-  networking code from being under GPL.
-
-  In fact the ISDN case is worse than this, because modification of
-  the code automatically invalidates its approval. Modification,
-  unlike usage, _is_ one of the rights which is protected by the
-  GPL. Happily, the law in those places where approval is required
-  doesn't actually prevent you from modifying the code - it's just
-  that you may not be allowed to _use_ it once you've done so - and
-  because usage isn't addressed by the GPL, that's just fine.
-
-  dwmw2@infradead.org
-  30/10/0
-
-  LEGAL NOTE: The NFTL format is patented by M-Systems.  They have
-  granted a licence for its use with their DiskOnChip products:
-
-    "M-Systems grants a royalty-free, non-exclusive license under
-    any presently existing M-Systems intellectual property rights
-    necessary for the design and development of NFTL-compatible
-    drivers, file systems and utilities to use the data formats with, 
-    and solely to support, M-Systems' DiskOnChip products"
-
-  A signed copy of this agreement from M-Systems is kept on file by
-  Red Hat UK Limited. In the unlikely event that you need access to it,
-  please contact dwmw2@redhat.com for assistance.  */
-
-#define PRERELEASE
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/blkpg.h>
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nftl.h>
-#include <linux/mtd/compatmac.h>
-
-/* maximum number of loops while examining next block, to have a
-   chance to detect consistency problems (they should never happen
-   because of the checks done in the mounting */
-
-#define MAX_LOOPS 10000
-
-/* NFTL block device stuff */
-#define MAJOR_NR NFTL_MAJOR
-#define DEVICE_REQUEST nftl_request
-#define DEVICE_OFF(device)
-
-
-#include <linux/blk.h>
-#include <linux/hdreg.h>
-
-/* Linux-specific block device functions */
-
-/* I _HATE_ the Linux block device setup more than anything else I've ever
- *  encountered, except ...
- */
-
-static int nftl_sizes[256] = {0,};
-static int nftl_blocksizes[256] = {0,};
-
-/* .. for the Linux partition table handling. */
-struct hd_struct part_table[256] = {{0,0},};
-
-#if LINUX_VERSION_CODE < 0x20328
-static void dummy_init (struct gendisk *crap)
-{}
-#endif
-
-static struct gendisk nftl_gendisk = {
-        MAJOR_NR,     /* Major number */      
-        "nftl",          /* Major name */
-        4,              /* Bits to shift to get real from partition */
-        15,             /* Number of partitions per real */
-#if LINUX_VERSION_CODE < 0x20328
-        MAX_NFTLS,      /* maximum number of real */
-        dummy_init,     /* init function */
-#endif
-        part_table,     /* hd struct */
-        nftl_sizes,     /* block sizes */
-        0,              /* number */
-        NULL,           /* internal use, not presently used */
-        NULL            /* next */
-};
-
-struct NFTLrecord *NFTLs[MAX_NFTLS] = {NULL};
-
-static void NFTL_setup(struct mtd_info *mtd)
-{
-	int i;
-	struct NFTLrecord *nftl;
-	unsigned long temp;
-	int firstfree = -1;
-
-	DEBUG(MTD_DEBUG_LEVEL1,"NFTL_setup\n");
-
-	for (i = 0; i < MAX_NFTLS; i++) {
-		if (!NFTLs[i] && firstfree == -1)
-			firstfree = i;
-		else if (NFTLs[i] && NFTLs[i]->mtd == mtd) {
-			/* This is a Spare Media Header for an NFTL we've already found */
-			DEBUG(MTD_DEBUG_LEVEL1, "MTD already mounted as NFTL\n");
-			return;
-		}
-	}
-        if (firstfree == -1) {
-		printk(KERN_WARNING "No more NFTL slot available\n");
-		return;
-        }
-
-	nftl = kmalloc(sizeof(struct NFTLrecord), GFP_KERNEL);
-	if (!nftl) {
-		printk(KERN_WARNING "Out of memory for NFTL data structures\n");
-		return;
-	}
-
-	init_MUTEX(&nftl->mutex);
-
-        /* get physical parameters */
-	nftl->EraseSize = mtd->erasesize;
-        nftl->nb_blocks = mtd->size / mtd->erasesize;
-	nftl->mtd = mtd;
-
-        if (NFTL_mount(nftl) < 0) {
-		printk(KERN_WARNING "Could not mount NFTL device\n");
-		kfree(nftl);
-		return;
-        }
-
-	/* OK, it's a new one. Set up all the data structures. */
-#ifdef PSYCHO_DEBUG
-	printk("Found new NFTL nftl%c\n", firstfree + 'a');
-#endif
-
-        /* linux stuff */
-	nftl->usecount = 0;
-	nftl->cylinders = 1024;
-	nftl->heads = 16;
-
-	temp = nftl->cylinders * nftl->heads;
-	nftl->sectors = nftl->nr_sects / temp;
-	if (nftl->nr_sects % temp) {
-		nftl->sectors++;
-		temp = nftl->cylinders * nftl->sectors;
-		nftl->heads = nftl->nr_sects / temp;
-
-		if (nftl->nr_sects % temp) {
-			nftl->heads++;
-			temp = nftl->heads * nftl->sectors;
-			nftl->cylinders = nftl->nr_sects / temp;
-		}
-	}
-
-	if (nftl->nr_sects != nftl->heads * nftl->cylinders * nftl->sectors) {
-		printk(KERN_WARNING "Cannot calculate an NFTL geometry to "
-		       "match size of 0x%lx.\n", nftl->nr_sects);
-		printk(KERN_WARNING "Using C:%d H:%d S:%d (== 0x%lx sects)\n", 
-		       nftl->cylinders, nftl->heads , nftl->sectors, 
-		       (long)nftl->cylinders * (long)nftl->heads * (long)nftl->sectors );
-
-		/* Oh no we don't have nftl->nr_sects = nftl->heads * nftl->cylinders * nftl->sectors; */
-	}
-	NFTLs[firstfree] = nftl;
-	/* Finally, set up the block device sizes */
-	nftl_sizes[firstfree * 16] = nftl->nr_sects;
-	//nftl_blocksizes[firstfree*16] = 512;
-	part_table[firstfree * 16].nr_sects = nftl->nr_sects;
-
-	/* partition check ... */
-#if LINUX_VERSION_CODE < 0x20328
-	resetup_one_dev(&nftl_gendisk, firstfree);
-#else
-	grok_partitions(&nftl_gendisk, firstfree, 1<<4, nftl->nr_sects);
-#endif
-}
-
-static void NFTL_unsetup(int i)
-{
-	struct NFTLrecord *nftl = NFTLs[i];
-
-	DEBUG(MTD_DEBUG_LEVEL1, "NFTL_unsetup %d\n", i);
-	
-	NFTLs[i] = NULL;
-	
-	if (nftl->ReplUnitTable)
-		kfree(nftl->ReplUnitTable);
-	if (nftl->EUNtable)
-		kfree(nftl->EUNtable);
-		      
-	kfree(nftl);
-}
-
-/* Search the MTD device for NFTL partitions */
-static void NFTL_notify_add(struct mtd_info *mtd)
-{
-	DEBUG(MTD_DEBUG_LEVEL1, "NFTL_notify_add for %s\n", mtd->name);
-
-	if (mtd) {
-		if (!mtd->read_oob) {
-			/* If this MTD doesn't have out-of-band data,
-			   then there's no point continuing */
-			DEBUG(MTD_DEBUG_LEVEL1, "No OOB data, quitting\n");
-			return;
-		}
-		DEBUG(MTD_DEBUG_LEVEL3, "mtd->read = %p, size = %d, erasesize = %d\n", 
-		      mtd->read, mtd->size, mtd->erasesize);
-
-                NFTL_setup(mtd);
-	}
-}
-
-static void NFTL_notify_remove(struct mtd_info *mtd)
-{
-	int i;
-
-	for (i = 0; i < MAX_NFTLS; i++) {
-		if (NFTLs[i] && NFTLs[i]->mtd == mtd)
-			NFTL_unsetup(i);
-	}
-}
-
-#ifdef CONFIG_NFTL_RW
-
-/* Actual NFTL access routines */
-/* NFTL_findfreeblock: Find a free Erase Unit on the NFTL partition. This function is used
- *	when the give Virtual Unit Chain
- */
-static u16 NFTL_findfreeblock(struct NFTLrecord *nftl, int desperate )
-{
-	/* For a given Virtual Unit Chain: find or create a free block and
-	   add it to the chain */
-	/* We're passed the number of the last EUN in the chain, to save us from
-	   having to look it up again */
-	u16 pot = nftl->LastFreeEUN;
-	int silly = -1;
-
-	/* Normally, we force a fold to happen before we run out of free blocks completely */
-	if (!desperate && nftl->numfreeEUNs < 2) {
-		DEBUG(MTD_DEBUG_LEVEL1, "NFTL_findfreeblock: there are too few free EUNs\n");
-		return 0xffff;
-	}
-
-	/* Scan for a free block */
-	do {
-		if (nftl->ReplUnitTable[pot] == BLOCK_FREE) {
-			nftl->LastFreeEUN = pot;
-			nftl->numfreeEUNs--;
-			return pot;
-		}
-
-		/* This will probably point to the MediaHdr unit itself,
-		   right at the beginning of the partition. But that unit
-		   (and the backup unit too) should have the UCI set
-		   up so that it's not selected for overwriting */
-		if (++pot > nftl->lastEUN)
-			pot = le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN);
-
-		if (!silly--) {
-			printk("Argh! No free blocks found! LastFreeEUN = %d, "
-			       "FirstEUN = %d\n", nftl->LastFreeEUN, 
-			       le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN));
-			return 0xffff;
-		}
-	} while (pot != nftl->LastFreeEUN);
-
-	return 0xffff;
-}
-
-static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned pendingblock )
-{
-	u16 BlockMap[MAX_SECTORS_PER_UNIT];
-	unsigned char BlockLastState[MAX_SECTORS_PER_UNIT];
-	unsigned char BlockFreeFound[MAX_SECTORS_PER_UNIT];
-	unsigned int thisEUN;
-	int block;
-	int silly;
-	unsigned int targetEUN;
-	struct nftl_oob oob;
-	int inplace = 1;
-        size_t retlen;
-
-	memset(BlockMap, 0xff, sizeof(BlockMap));
-	memset(BlockFreeFound, 0, sizeof(BlockFreeFound));
-
-	thisEUN = nftl->EUNtable[thisVUC];
-
-	if (thisEUN == BLOCK_NIL) {
-		printk(KERN_WARNING "Trying to fold non-existent "
-		       "Virtual Unit Chain %d!\n", thisVUC);
-		return BLOCK_NIL;
-	}
-	
-	/* Scan to find the Erase Unit which holds the actual data for each
-	   512-byte block within the Chain.
-	*/
-        silly = MAX_LOOPS;
-	targetEUN = BLOCK_NIL;
-	while (thisEUN <= nftl->lastEUN ) {
-                unsigned int status, foldmark;
-
-		targetEUN = thisEUN;
-		for (block = 0; block < nftl->EraseSize / 512; block ++) {
-			MTD_READOOB(nftl->mtd,
-				    (thisEUN * nftl->EraseSize) + (block * 512),
-				    16 , &retlen, (char *)&oob);
-			if (block == 2) {
-                                foldmark = oob.u.c.FoldMark | oob.u.c.FoldMark1;
-                                if (foldmark == FOLD_MARK_IN_PROGRESS) {
-                                        DEBUG(MTD_DEBUG_LEVEL1, 
-                                              "Write Inhibited on EUN %d\n", thisEUN);
-					inplace = 0;
-				} else {
-					/* There's no other reason not to do inplace,
-					   except ones that come later. So we don't need
-					   to preserve inplace */
-					inplace = 1;
-				}
-			}
-                        status = oob.b.Status | oob.b.Status1;
-			BlockLastState[block] = status;
-
-			switch(status) {
-			case SECTOR_FREE:
-				BlockFreeFound[block] = 1;
-				break;
-
-			case SECTOR_USED:
-				if (!BlockFreeFound[block])
-					BlockMap[block] = thisEUN;
-				else
-					printk(KERN_WARNING 
-					       "SECTOR_USED found after SECTOR_FREE "
-					       "in Virtual Unit Chain %d for block %d\n",
-					       thisVUC, block);
-				break;
-			case SECTOR_IGNORE:
-			case SECTOR_DELETED:
-				break;
-			default:
-				printk("Unknown status for block %d in EUN %d: %x\n",
-				       block, thisEUN, status);
-			}
-		}
-
-		if (!silly--) {
-			printk(KERN_WARNING "Infinite loop in Virtual Unit Chain 0x%x\n",
-			       thisVUC);
-			return BLOCK_NIL;
-		}
-		
-		thisEUN = nftl->ReplUnitTable[thisEUN];
-	}
-
-	if (inplace) {
-		/* We're being asked to be a fold-in-place. Check
-		   that all blocks are either present or SECTOR_FREE
-		   in the target block. If not, we're going to have
-		   to fold out-of-place anyway.
-		*/
-		for (block = 0; block < nftl->EraseSize / 512 ; block++) {
-			if (BlockLastState[block] != SECTOR_FREE &&
-			    BlockMap[block] != targetEUN) {
-				DEBUG(MTD_DEBUG_LEVEL1, "Setting inplace to 0. VUC %d, "
-				      "block %d was %x lastEUN, "
-				      "and is in EUN %d (%s) %d\n",
-				      thisVUC, block, BlockLastState[block],
-				      BlockMap[block], 
-				      BlockMap[block]== targetEUN ? "==" : "!=",
-				      targetEUN);
-				inplace = 0;
-				break;
-			}
-		}
-
-		if (pendingblock >= (thisVUC * (nftl->EraseSize / 512)) &&
-		    pendingblock < ((thisVUC + 1)* (nftl->EraseSize / 512)) &&
-		    BlockLastState[pendingblock - (thisVUC * (nftl->EraseSize / 512))] !=
-		    SECTOR_FREE) {
-			DEBUG(MTD_DEBUG_LEVEL1, "Pending write not free in EUN %d. "
-			      "Folding out of place.\n", targetEUN);
-			inplace = 0;
-		}
-	}
-	
-	if (!inplace) {
-		DEBUG(MTD_DEBUG_LEVEL1, "Cannot fold Virtual Unit Chain %d in place. "
-		      "Trying out-of-place\n", thisVUC);
-		/* We need to find a targetEUN to fold into. */
-		targetEUN = NFTL_findfreeblock(nftl, 1);
-		if (targetEUN == BLOCK_NIL) {
-			/* Ouch. Now we're screwed. We need to do a 
-			   fold-in-place of another chain to make room
-			   for this one. We need a better way of selecting
-			   which chain to fold, because makefreeblock will 
-			   only ask us to fold the same one again.
-			*/
-			printk(KERN_WARNING
-			       "NFTL_findfreeblock(desperate) returns 0xffff.\n");
-			return BLOCK_NIL;
-		}
-	} else {
-            /* We put a fold mark in the chain we are folding only if
-               we fold in place to help the mount check code. If we do
-               not fold in place, it is possible to find the valid
-               chain by selecting the longer one */
-            oob.u.c.FoldMark = oob.u.c.FoldMark1 = cpu_to_le16(FOLD_MARK_IN_PROGRESS);
-            oob.u.c.unused = 0xffffffff;
-            MTD_WRITEOOB(nftl->mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8, 
-                         8, &retlen, (char *)&oob.u);
-        }
-
-	/* OK. We now know the location of every block in the Virtual Unit Chain,
-	   and the Erase Unit into which we are supposed to be copying.
-	   Go for it.
-	*/
-	DEBUG(MTD_DEBUG_LEVEL1,"Folding chain %d into unit %d\n", thisVUC, targetEUN);
-	for (block = 0; block < nftl->EraseSize / 512 ; block++) {
-		unsigned char movebuf[512];
-		int ret;
-
-		/* If it's in the target EUN already, or if it's pending write, do nothing */
-		if (BlockMap[block] == targetEUN ||
-		    (pendingblock == (thisVUC * (nftl->EraseSize / 512) + block))) {
-			continue;
-		}
-
-                /* copy only in non free block (free blocks can only
-                   happen in case of media errors or deleted blocks) */
-                if (BlockMap[block] == BLOCK_NIL)
-                        continue;
-                
-                ret = MTD_READECC(nftl->mtd, (nftl->EraseSize * BlockMap[block])
-                                  + (block * 512), 512, &retlen, movebuf, (char *)&oob); 
-                if (ret < 0) {
-                    ret = MTD_READECC(nftl->mtd, (nftl->EraseSize * BlockMap[block])
-                                      + (block * 512), 512, &retlen,
-                                      movebuf, (char *)&oob); 
-                    if (ret != -EIO) 
-                        printk("Error went away on retry.\n");
-                }
-                MTD_WRITEECC(nftl->mtd, (nftl->EraseSize * targetEUN) + (block * 512),
-                             512, &retlen, movebuf, (char *)&oob);
-	}
-        
-        /* add the header so that it is now a valid chain */
-        oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum
-                = cpu_to_le16(thisVUC);
-        oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff;
-        
-        MTD_WRITEOOB(nftl->mtd, (nftl->EraseSize * targetEUN) + 8, 
-                     8, &retlen, (char *)&oob.u);
-
-	/* OK. We've moved the whole lot into the new block. Now we have to free the original blocks. */
-
-	/* At this point, we have two different chains for this Virtual Unit, and no way to tell 
-	   them apart. If we crash now, we get confused. However, both contain the same data, so we
-	   shouldn't actually lose data in this case. It's just that when we load up on a medium which
-	   has duplicate chains, we need to free one of the chains because it's not necessary any more.
-	*/
-	thisEUN = nftl->EUNtable[thisVUC];
-	DEBUG(MTD_DEBUG_LEVEL1,"Want to erase\n");
-
-	/* For each block in the old chain (except the targetEUN of course), 
-	   free it and make it available for future use */
-	while (thisEUN <= nftl->lastEUN && thisEUN != targetEUN) {
-		unsigned int EUNtmp;
-
-                EUNtmp = nftl->ReplUnitTable[thisEUN];
-
-                if (NFTL_formatblock(nftl, thisEUN) < 0) {
-			/* could not erase : mark block as reserved
-			 * FixMe: Update Bad Unit Table on disk
-			 */
-			nftl->ReplUnitTable[thisEUN] = BLOCK_RESERVED;
-                } else {
-			/* correctly erased : mark it as free */
-			nftl->ReplUnitTable[thisEUN] = BLOCK_FREE;
-			nftl->numfreeEUNs++;
-                }
-                thisEUN = EUNtmp;
-	}
-	
-	/* Make this the new start of chain for thisVUC */
-	nftl->ReplUnitTable[targetEUN] = BLOCK_NIL;
-	nftl->EUNtable[thisVUC] = targetEUN;
-
-	return targetEUN;
-}
-
-u16 NFTL_makefreeblock( struct NFTLrecord *nftl , unsigned pendingblock)
-{
-	/* This is the part that needs some cleverness applied. 
-	   For now, I'm doing the minimum applicable to actually
-	   get the thing to work.
-	   Wear-levelling and other clever stuff needs to be implemented
-	   and we also need to do some assessment of the results when
-	   the system loses power half-way through the routine.
-	*/
-	u16 LongestChain = 0;
-	u16 ChainLength = 0, thislen;
-	u16 chain, EUN;
-
-	for (chain = 0; chain < nftl->MediaHdr.FormattedSize / nftl->EraseSize; chain++) {
-		EUN = nftl->EUNtable[chain];
-		thislen = 0;
-
-		while (EUN <= nftl->lastEUN) {
-			thislen++;
-			//printk("VUC %d reaches len %d with EUN %d\n", chain, thislen, EUN);
-			EUN = nftl->ReplUnitTable[EUN] & 0x7fff;
-			if (thislen > 0xff00) {
-				printk("Endless loop in Virtual Chain %d: Unit %x\n",
-				       chain, EUN);
-			}
-			if (thislen > 0xff10) {
-				/* Actually, don't return failure. Just ignore this chain and
-				   get on with it. */
-				thislen = 0;
-				break;
-			}
-		}
-
-		if (thislen > ChainLength) {
-			//printk("New longest chain is %d with length %d\n", chain, thislen);
-			ChainLength = thislen;
-			LongestChain = chain;
-		}
-	}
-
-	if (ChainLength < 2) {
-		printk(KERN_WARNING "No Virtual Unit Chains available for folding. "
-		       "Failing request\n");
-		return 0xffff;
-	}
-
-	return NFTL_foldchain (nftl, LongestChain, pendingblock);
-}
-
-/* NFTL_findwriteunit: Return the unit number into which we can write 
-                       for this block. Make it available if it isn't already
-*/
-static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
-{
-	u16 lastEUN;
-	u16 thisVUC = block / (nftl->EraseSize / 512);
-	unsigned int writeEUN;
-	unsigned long blockofs = (block * 512) & (nftl->EraseSize -1);
-	size_t retlen;
-	int silly, silly2 = 3;
-	struct nftl_oob oob;
-
-	do {
-		/* Scan the media to find a unit in the VUC which has
-		   a free space for the block in question.
-		*/
-
-		/* This condition catches the 0x[7f]fff cases, as well as 
-		   being a sanity check for past-end-of-media access
-		*/
-		lastEUN = BLOCK_NIL;
-		writeEUN = nftl->EUNtable[thisVUC];
-                silly = MAX_LOOPS;
-		while (writeEUN <= nftl->lastEUN) {
-			struct nftl_bci bci;
-			size_t retlen;
-                        unsigned int status;
-
-			lastEUN = writeEUN;
-
-			MTD_READOOB(nftl->mtd, (writeEUN * nftl->EraseSize) + blockofs,
-				    8, &retlen, (char *)&bci);
-			
-			DEBUG(MTD_DEBUG_LEVEL2, "Status of block %d in EUN %d is %x\n",
-			      block , writeEUN, le16_to_cpu(bci.Status));
-
-                        status = bci.Status | bci.Status1;
-			switch(status) {
-			case SECTOR_FREE:
-				return writeEUN;
-
-			case SECTOR_DELETED:
-			case SECTOR_USED:
-			case SECTOR_IGNORE:
-				break;
-			default:
-				// Invalid block. Don't use it any more. Must implement.
-				break;			
-			}
-			
-			if (!silly--) { 
-				printk(KERN_WARNING
-				       "Infinite loop in Virtual Unit Chain 0x%x\n",
-				       thisVUC);
-				return 0xffff;
-			}
-
-			/* Skip to next block in chain */
-			writeEUN = nftl->ReplUnitTable[writeEUN];
-		}
-
-		/* OK. We didn't find one in the existing chain, or there 
-		   is no existing chain. */
-
-		/* Try to find an already-free block */
-		writeEUN = NFTL_findfreeblock(nftl, 0);
-
-		if (writeEUN == BLOCK_NIL) {
-			/* That didn't work - there were no free blocks just
-			   waiting to be picked up. We're going to have to fold
-			   a chain to make room.
-			*/
-
-			/* First remember the start of this chain */
-			//u16 startEUN = nftl->EUNtable[thisVUC];
-			
-			//printk("Write to VirtualUnitChain %d, calling makefreeblock()\n", thisVUC);
-			writeEUN = NFTL_makefreeblock(nftl, 0xffff);
-			
-			if (writeEUN == BLOCK_NIL) {
-				/* Ouch. This should never happen - we should
-				   always be able to make some room somehow. 
-				   If we get here, we've allocated more storage 
-				   space than actual media, or our makefreeblock
-				   routine is missing something.
-				*/
-				printk(KERN_WARNING "Cannot make free space.\n");
-				return BLOCK_NIL;
-			}			
-			//printk("Restarting scan\n");
-			lastEUN = BLOCK_NIL;
-			continue;
-		}
-
-		/* We've found a free block. Insert it into the chain. */
-		
-		if (lastEUN != BLOCK_NIL) {
-                    thisVUC |= 0x8000; /* It's a replacement block */
-		} else {
-                    /* The first block in a new chain */
-                    nftl->EUNtable[thisVUC] = writeEUN;
-		}
-
-		/* set up the actual EUN we're writing into */
-		/* Both in our cache... */
-		nftl->ReplUnitTable[writeEUN] = BLOCK_NIL;
-
-		/* ... and on the flash itself */
-		MTD_READOOB(nftl->mtd, writeEUN * nftl->EraseSize + 8, 8,
-			    &retlen, (char *)&oob.u);
-
-		oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum = cpu_to_le16(thisVUC);
-
-		MTD_WRITEOOB(nftl->mtd, writeEUN * nftl->EraseSize + 8, 8,
-                             &retlen, (char *)&oob.u);
-
-                /* we link the new block to the chain only after the
-                   block is ready. It avoids the case where the chain
-                   could point to a free block */
-                if (lastEUN != BLOCK_NIL) {
-			/* Both in our cache... */
-			nftl->ReplUnitTable[lastEUN] = writeEUN;
-			/* ... and on the flash itself */
-			MTD_READOOB(nftl->mtd, (lastEUN * nftl->EraseSize) + 8,
-				    8, &retlen, (char *)&oob.u);
-
-			oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum
-				= cpu_to_le16(writeEUN);
-
-			MTD_WRITEOOB(nftl->mtd, (lastEUN * nftl->EraseSize) + 8,
-				     8, &retlen, (char *)&oob.u);
-		}
-
-		return writeEUN;
-
-	} while (silly2--);
-
-	printk(KERN_WARNING "Error folding to make room for Virtual Unit Chain 0x%x\n",
-	       thisVUC);
-	return 0xffff;
-}
-
-static int NFTL_writeblock(struct NFTLrecord *nftl, unsigned block, char *buffer)
-{
-	u16 writeEUN;
-	unsigned long blockofs = (block * 512) & (nftl->EraseSize - 1);
-	size_t retlen;
-	u8 eccbuf[6];
-
-	writeEUN = NFTL_findwriteunit(nftl, block);
-
-	if (writeEUN == BLOCK_NIL) {
-		printk(KERN_WARNING
-		       "NFTL_writeblock(): Cannot find block to write to\n");
-		/* If we _still_ haven't got a block to use, we're screwed */
-		return 1;
-	}
-
-	MTD_WRITEECC(nftl->mtd, (writeEUN * nftl->EraseSize) + blockofs,
-		     512, &retlen, (char *)buffer, (char *)eccbuf);
-        /* no need to write SECTOR_USED flags since they are written in mtd_writeecc */
-
-	return 0;
-}
-#endif /* CONFIG_NFTL_RW */
-
-static int NFTL_readblock(struct NFTLrecord *nftl, unsigned block, char *buffer)
-{
-	u16 lastgoodEUN;
-	u16 thisEUN = nftl->EUNtable[block / (nftl->EraseSize / 512)];
-	unsigned long blockofs = (block * 512) & (nftl->EraseSize - 1);
-        unsigned int status;
-	int silly = MAX_LOOPS;
-        size_t retlen;
-        struct nftl_bci bci;
-
-	lastgoodEUN = BLOCK_NIL;
-
-        if (thisEUN != BLOCK_NIL) {
-		while (thisEUN < nftl->nb_blocks) {
-			if (MTD_READOOB(nftl->mtd, (thisEUN * nftl->EraseSize) + blockofs,
-					8, &retlen, (char *)&bci) < 0)
-				status = SECTOR_IGNORE;
-			else
-				status = bci.Status | bci.Status1;
-
-			switch (status) {
-			case SECTOR_FREE:
-				/* no modification of a sector should follow a free sector */
-				goto the_end;
-			case SECTOR_DELETED:
-				lastgoodEUN = BLOCK_NIL;
-				break;
-			case SECTOR_USED:
-				lastgoodEUN = thisEUN;
-				break;
-			case SECTOR_IGNORE:
-				break;
-			default:
-				printk("Unknown status for block %d in EUN %d: %x\n",
-				       block, thisEUN, status);
-				break;
-			}
-
-			if (!silly--) {
-				printk(KERN_WARNING "Infinite loop in Virtual Unit Chain 0x%x\n",
-				       block / (nftl->EraseSize / 512));
-				return 1;
-			}
-			thisEUN = nftl->ReplUnitTable[thisEUN];
-		}
-        }
-
- the_end:
-	if (lastgoodEUN == BLOCK_NIL) {
-		/* the requested block is not on the media, return all 0x00 */
-		memset(buffer, 0, 512);
-	} else {
-		loff_t ptr = (lastgoodEUN * nftl->EraseSize) + blockofs;
-		size_t retlen;
-		u_char eccbuf[6];
-		if (MTD_READECC(nftl->mtd, ptr, 512, &retlen, buffer, eccbuf))
-			return -EIO;
-	}
-	return 0;
-}
-
-static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
-{
-	struct NFTLrecord *nftl;
-
-	nftl = NFTLs[MINOR(inode->i_rdev) / 16];
-
-	if (!nftl) return -EINVAL;
-
-	switch (cmd) {
-	case HDIO_GETGEO: {
-		struct hd_geometry g;
-
-		g.heads = nftl->heads;
-		g.sectors = nftl->sectors;
-		g.cylinders = nftl->cylinders;
-		g.start = part_table[MINOR(inode->i_rdev)].start_sect;
-		return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0;
-	}
-	case BLKGETSIZE:   /* Return device size */
-		if (!arg) return -EINVAL;
-		return put_user(part_table[MINOR(inode->i_rdev)].nr_sects,
-                                (long *) arg);
-		
-	case BLKFLSBUF:
-		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-		fsync_dev(inode->i_rdev);
-		invalidate_buffers(inode->i_rdev);
-		if (nftl->mtd->sync)
-			nftl->mtd->sync(nftl->mtd);
-		return 0;
-
-	case BLKRRPART:
-		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-		if (nftl->usecount > 1) return -EBUSY;
-#if LINUX_VERSION_CODE < 0x20328
-		resetup_one_dev(&nftl_gendisk, MINOR(inode->i_rdev) / 16);
-#else
-		grok_partitions(&nftl_gendisk, MINOR(inode->i_rdev) / 16,
-				1<<4, nftl->nr_sects);
-#endif
-		return 0;
-
-#if (LINUX_VERSION_CODE < 0x20303)		
-	RO_IOCTLS(inode->i_rdev, arg);  /* ref. linux/blk.h */
-#else
-	case BLKROSET:
-	case BLKROGET:
-	case BLKSSZGET:
-		return blk_ioctl(inode->i_rdev, cmd, arg);
-#endif
-
-	default:
-		return -EINVAL;
-	}
-}
-
-void nftl_request(RQFUNC_ARG)
-{
-	unsigned int dev, block, nsect;
-	struct NFTLrecord *nftl;
-	char *buffer;
-	struct request *req;
-	int res;
-
-	while (1) {
-		INIT_REQUEST;	/* blk.h */
-		req = CURRENT;
-		
-		/* We can do this because the generic code knows not to
-		   touch the request at the head of the queue */
-		spin_unlock_irq(&io_request_lock);
-
-		DEBUG(MTD_DEBUG_LEVEL2, "NFTL_request\n");
-		DEBUG(MTD_DEBUG_LEVEL3, "NFTL %s request, from sector 0x%04lx for 0x%04lx sectors\n",
-		      (req->cmd == READ) ? "Read " : "Write",
-		      req->sector, req->current_nr_sectors);
-
-		dev = MINOR(req->rq_dev);
-		block = req->sector;
-		nsect = req->current_nr_sectors;
-		buffer = req->buffer;
-		res = 1; /* succeed */
-
-		if (dev >= MAX_NFTLS * 16) {
-			/* there is no such partition */
-			printk("nftl: bad minor number: device = %s\n",
-			       kdevname(req->rq_dev));
-			res = 0; /* fail */
-			goto repeat;
-		}
-		
-		nftl = NFTLs[dev / 16];
-		DEBUG(MTD_DEBUG_LEVEL3, "Waiting for mutex\n");
-		down(&nftl->mutex);
-		DEBUG(MTD_DEBUG_LEVEL3, "Got mutex\n");
-
-		if (block + nsect > part_table[dev].nr_sects) {
-			/* access past the end of device */
-			printk("nftl%c%d: bad access: block = %d, count = %d\n",
-			       (MINOR(req->rq_dev)>>6)+'a', dev & 0xf, block, nsect);
-			up(&nftl->mutex);
-			res = 0; /* fail */
-			goto repeat;
-		}
-		
-		block += part_table[dev].start_sect;
-		
-		if (req->cmd == READ) {
-			DEBUG(MTD_DEBUG_LEVEL2, "NFTL read request of 0x%x sectors @ %x "
-			      "(req->nr_sectors == %lx)\n", nsect, block, req->nr_sectors);
-	
-			for ( ; nsect > 0; nsect-- , block++, buffer += 512) {
-				/* Read a single sector to req->buffer + (512 * i) */
-				if (NFTL_readblock(nftl, block, buffer)) {
-					DEBUG(MTD_DEBUG_LEVEL2, "NFTL read request failed\n");
-					up(&nftl->mutex);
-					res = 0;
-					goto repeat;
-				}
-			}
-
-			DEBUG(MTD_DEBUG_LEVEL2,"NFTL read request completed OK\n");
-			up(&nftl->mutex);
-			goto repeat;
-		} else if (req->cmd == WRITE) {
-			DEBUG(MTD_DEBUG_LEVEL2, "NFTL write request of 0x%x sectors @ %x "
-			      "(req->nr_sectors == %lx)\n", nsect, block,
-			      req->nr_sectors);
-#ifdef CONFIG_NFTL_RW
-			for ( ; nsect > 0; nsect-- , block++, buffer += 512) {
-				/* Read a single sector to req->buffer + (512 * i) */
-				if (NFTL_writeblock(nftl, block, buffer)) {
-					DEBUG(MTD_DEBUG_LEVEL1,"NFTL write request failed\n");
-					up(&nftl->mutex);
-					res = 0;
-					goto repeat;
-				}
-			}
-			DEBUG(MTD_DEBUG_LEVEL2,"NFTL write request completed OK\n");
-#else
-			res = 0; /* Writes always fail */
-#endif /* CONFIG_NFTL_RW */
-			up(&nftl->mutex);
-			goto repeat;
-		} else {
-			DEBUG(MTD_DEBUG_LEVEL0, "NFTL unknown request\n");
-			up(&nftl->mutex);
-			res = 0;
-			goto repeat;
-		}
-	repeat: 
-		DEBUG(MTD_DEBUG_LEVEL3, "end_request(%d)\n", res);
-		spin_lock_irq(&io_request_lock);
-		end_request(res);
-	}
-}
-
-static int nftl_open(struct inode *ip, struct file *fp)
-{
-	int nftlnum = MINOR(ip->i_rdev) / 16;
-	struct NFTLrecord *thisNFTL;
-	thisNFTL = NFTLs[nftlnum];
-
-	DEBUG(MTD_DEBUG_LEVEL2,"NFTL_open\n");
-
-#ifdef CONFIG_KMOD
-	if (!thisNFTL && nftlnum == 0) {
-		request_module("docprobe");
-		thisNFTL = NFTLs[nftlnum];
-	}
-#endif
-	if (!thisNFTL) {
-		DEBUG(MTD_DEBUG_LEVEL2,"ENODEV: thisNFTL = %d, minor = %d, ip = %p, fp = %p\n", 
-		      nftlnum, ip->i_rdev, ip, fp);
-		return -ENODEV;
-	}
-
-#ifndef CONFIG_NFTL_RW
-	if (fp->f_mode & FMODE_WRITE)
-		return -EROFS;
-#endif /* !CONFIG_NFTL_RW */
-
-	thisNFTL->usecount++;
-	MOD_INC_USE_COUNT;
-	if (!get_mtd_device(thisNFTL->mtd, -1)) {
-		MOD_DEC_USE_COUNT;
-		return /* -E'SBUGGEREDOFF */ -ENXIO;
-	}
-
-	return 0;
-}
-
-static int nftl_release(struct inode *inode, struct file *fp)
-{
-	struct NFTLrecord *thisNFTL;
-
-	thisNFTL = NFTLs[MINOR(inode->i_rdev) / 16];
-
-	DEBUG(MTD_DEBUG_LEVEL2, "NFTL_release\n");
-
-	invalidate_device(inode->i_rdev, 1);
-
-	if (thisNFTL->mtd->sync)
-		thisNFTL->mtd->sync(thisNFTL->mtd);
-	thisNFTL->usecount--;
-	MOD_DEC_USE_COUNT;
-
-	put_mtd_device(thisNFTL->mtd);
-
-	return 0;
-}
-#if LINUX_VERSION_CODE < 0x20326
-static struct file_operations nftl_fops = {
-	read:		block_read,
-	write:		block_write,
-	ioctl:		nftl_ioctl,
-	open:		nftl_open,
-	release:	nftl_release,
-	fsync:		block_fsync,
-};
-#else
-static struct block_device_operations nftl_fops = 
-{
-	open:		nftl_open,
-	release:	nftl_release,
-	ioctl: 		nftl_ioctl
-};
-#endif
-
-
-
-/****************************************************************************
- *
- * Module stuff
- *
- ****************************************************************************/
-
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_nftl init_module
-#define cleanup_nftl cleanup_module
-#endif
-
-static struct mtd_notifier nftl_notifier = {NFTL_notify_add, NFTL_notify_remove, NULL};
-
-/* static int __init init_nftl(void) */
-int __init init_nftl(void)
-{
-	int i;
-
-	printk(KERN_NOTICE
-	       "M-Systems NAND Flash Translation Layer driver. (C) 1999 MVHI\n");
-#ifdef PRERELEASE 
-	printk(KERN_INFO"$Id: nftl.c,v 1.57 2000/12/01 17:51:54 dwmw2 Exp $\n");
-#endif
-
-	if (register_blkdev(MAJOR_NR, "nftl", &nftl_fops)){
-		printk("unable to register NFTL block device on major %d\n", MAJOR_NR);
-		return -EBUSY;
-	} else {
-#if LINUX_VERSION_CODE < 0x20320
-		blk_dev[MAJOR_NR].request_fn = nftl_request;
-#else
-		blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &nftl_request);
-#endif
-		/* set block size to 1kB each */
-		for (i = 0; i < 256; i++) {
-			nftl_blocksizes[i] = 1024;
-		}
-		blksize_size[MAJOR_NR] = nftl_blocksizes;
-
-		nftl_gendisk.next = gendisk_head;
-		gendisk_head = &nftl_gendisk;
-	}
-	
-	register_mtd_user(&nftl_notifier);
-
-	return 0;
-}
-
-static void __exit cleanup_nftl(void)
-{
-	struct gendisk *gd, **gdp;
-
-  	unregister_mtd_user(&nftl_notifier);
-  	unregister_blkdev(MAJOR_NR, "nftl");
-  	
-#if LINUX_VERSION_CODE < 0x20320
-  	blk_dev[MAJOR_NR].request_fn = 0;
-#else
-  	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-#endif	
-
-	/* remove ourself from generic harddisk list
-	   FIXME: why can't I found this partition on /proc/partition */
-  	for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))
-    		if (*gdp == &nftl_gendisk) {
-      			gd = *gdp; *gdp = gd->next;
-      			break;
-    	}
-}
-
-module_init(init_nftl);
-module_exit(cleanup_nftl);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/nftlcore.c linux/drivers/mtd/nftlcore.c
--- v2.4.5/linux/drivers/mtd/nftlcore.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/nftlcore.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,1094 @@
+/* Linux driver for NAND Flash Translation Layer      */
+/* (c) 1999 Machine Vision Holdings, Inc.             */
+/* Author: David Woodhouse <dwmw2@infradead.org>      */
+/* $Id: nftlcore.c,v 1.73 2001/06/09 01:09:43 dwmw2 Exp $ */
+
+/*
+  The contents of this file are distributed under the GNU General
+  Public License version 2. The author places no additional
+  restrictions of any kind on it.
+ */
+
+#define PRERELEASE
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/blkpg.h>
+
+#ifdef CONFIG_KMOD
+#include <linux/kmod.h>
+#endif
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nftl.h>
+#include <linux/mtd/compatmac.h>
+
+/* maximum number of loops while examining next block, to have a
+   chance to detect consistency problems (they should never happen
+   because of the checks done in the mounting */
+
+#define MAX_LOOPS 10000
+
+/* NFTL block device stuff */
+#define MAJOR_NR NFTL_MAJOR
+#define DEVICE_REQUEST nftl_request
+#define DEVICE_OFF(device)
+
+
+#include <linux/blk.h>
+#include <linux/hdreg.h>
+
+/* Linux-specific block device functions */
+
+/* I _HATE_ the Linux block device setup more than anything else I've ever
+ *  encountered, except ...
+ */
+
+static int nftl_sizes[256];
+static int nftl_blocksizes[256];
+
+/* .. for the Linux partition table handling. */
+struct hd_struct part_table[256];
+
+#if LINUX_VERSION_CODE < 0x20328
+static void dummy_init (struct gendisk *crap)
+{}
+#endif
+
+static struct gendisk nftl_gendisk = {
+	major:		MAJOR_NR,
+	major_name:	"nftl",
+	minor_shift:	NFTL_PARTN_BITS,	/* Bits to shift to get real from partition */
+	max_p:		(1<<NFTL_PARTN_BITS)-1,	/* Number of partitions per real */
+#if LINUX_VERSION_CODE < 0x20328
+	max_nr:		MAX_NFTLS,      /* maximum number of real */
+	init:		dummy_init,     /* init function */
+#endif
+	part:		part_table,     /* hd struct */
+	sizes:		nftl_sizes,     /* block sizes */
+};
+
+struct NFTLrecord *NFTLs[MAX_NFTLS];
+
+static void NFTL_setup(struct mtd_info *mtd)
+{
+	int i;
+	struct NFTLrecord *nftl;
+	unsigned long temp;
+	int firstfree = -1;
+
+	DEBUG(MTD_DEBUG_LEVEL1,"NFTL_setup\n");
+
+	for (i = 0; i < MAX_NFTLS; i++) {
+		if (!NFTLs[i] && firstfree == -1)
+			firstfree = i;
+		else if (NFTLs[i] && NFTLs[i]->mtd == mtd) {
+			/* This is a Spare Media Header for an NFTL we've already found */
+			DEBUG(MTD_DEBUG_LEVEL1, "MTD already mounted as NFTL\n");
+			return;
+		}
+	}
+        if (firstfree == -1) {
+		printk(KERN_WARNING "No more NFTL slot available\n");
+		return;
+        }
+
+	nftl = kmalloc(sizeof(struct NFTLrecord), GFP_KERNEL);
+	if (!nftl) {
+		printk(KERN_WARNING "Out of memory for NFTL data structures\n");
+		return;
+	}
+
+	init_MUTEX(&nftl->mutex);
+
+        /* get physical parameters */
+	nftl->EraseSize = mtd->erasesize;
+        nftl->nb_blocks = mtd->size / mtd->erasesize;
+	nftl->mtd = mtd;
+
+        if (NFTL_mount(nftl) < 0) {
+		printk(KERN_WARNING "Could not mount NFTL device\n");
+		kfree(nftl);
+		return;
+        }
+
+	/* OK, it's a new one. Set up all the data structures. */
+#ifdef PSYCHO_DEBUG
+	printk("Found new NFTL nftl%c\n", firstfree + 'a');
+#endif
+
+        /* linux stuff */
+	nftl->usecount = 0;
+	nftl->cylinders = 1024;
+	nftl->heads = 16;
+
+	temp = nftl->cylinders * nftl->heads;
+	nftl->sectors = nftl->nr_sects / temp;
+	if (nftl->nr_sects % temp) {
+		nftl->sectors++;
+		temp = nftl->cylinders * nftl->sectors;
+		nftl->heads = nftl->nr_sects / temp;
+
+		if (nftl->nr_sects % temp) {
+			nftl->heads++;
+			temp = nftl->heads * nftl->sectors;
+			nftl->cylinders = nftl->nr_sects / temp;
+		}
+	}
+
+	if (nftl->nr_sects != nftl->heads * nftl->cylinders * nftl->sectors) {
+		printk(KERN_WARNING "Cannot calculate an NFTL geometry to "
+		       "match size of 0x%lx.\n", nftl->nr_sects);
+		printk(KERN_WARNING "Using C:%d H:%d S:%d (== 0x%lx sects)\n", 
+		       nftl->cylinders, nftl->heads , nftl->sectors, 
+		       (long)nftl->cylinders * (long)nftl->heads * (long)nftl->sectors );
+
+		/* Oh no we don't have nftl->nr_sects = nftl->heads * nftl->cylinders * nftl->sectors; */
+	}
+	NFTLs[firstfree] = nftl;
+	/* Finally, set up the block device sizes */
+	nftl_sizes[firstfree * 16] = nftl->nr_sects;
+	//nftl_blocksizes[firstfree*16] = 512;
+	part_table[firstfree * 16].nr_sects = nftl->nr_sects;
+
+	nftl_gendisk.nr_real++;
+
+	/* partition check ... */
+#if LINUX_VERSION_CODE < 0x20328
+	resetup_one_dev(&nftl_gendisk, firstfree);
+#else
+	grok_partitions(&nftl_gendisk, firstfree, 1<<NFTL_PARTN_BITS, nftl->nr_sects);
+#endif
+}
+
+static void NFTL_unsetup(int i)
+{
+	struct NFTLrecord *nftl = NFTLs[i];
+
+	DEBUG(MTD_DEBUG_LEVEL1, "NFTL_unsetup %d\n", i);
+	
+	NFTLs[i] = NULL;
+	
+	if (nftl->ReplUnitTable)
+		kfree(nftl->ReplUnitTable);
+	if (nftl->EUNtable)
+		kfree(nftl->EUNtable);
+		      
+	nftl_gendisk.nr_real--;
+	kfree(nftl);
+}
+
+/* Search the MTD device for NFTL partitions */
+static void NFTL_notify_add(struct mtd_info *mtd)
+{
+	DEBUG(MTD_DEBUG_LEVEL1, "NFTL_notify_add for %s\n", mtd->name);
+
+	if (mtd) {
+		if (!mtd->read_oob) {
+			/* If this MTD doesn't have out-of-band data,
+			   then there's no point continuing */
+			DEBUG(MTD_DEBUG_LEVEL1, "No OOB data, quitting\n");
+			return;
+		}
+		DEBUG(MTD_DEBUG_LEVEL3, "mtd->read = %p, size = %d, erasesize = %d\n", 
+		      mtd->read, mtd->size, mtd->erasesize);
+
+                NFTL_setup(mtd);
+	}
+}
+
+static void NFTL_notify_remove(struct mtd_info *mtd)
+{
+	int i;
+
+	for (i = 0; i < MAX_NFTLS; i++) {
+		if (NFTLs[i] && NFTLs[i]->mtd == mtd)
+			NFTL_unsetup(i);
+	}
+}
+
+#ifdef CONFIG_NFTL_RW
+
+/* Actual NFTL access routines */
+/* NFTL_findfreeblock: Find a free Erase Unit on the NFTL partition. This function is used
+ *	when the give Virtual Unit Chain
+ */
+static u16 NFTL_findfreeblock(struct NFTLrecord *nftl, int desperate )
+{
+	/* For a given Virtual Unit Chain: find or create a free block and
+	   add it to the chain */
+	/* We're passed the number of the last EUN in the chain, to save us from
+	   having to look it up again */
+	u16 pot = nftl->LastFreeEUN;
+	int silly = -1;
+
+	/* Normally, we force a fold to happen before we run out of free blocks completely */
+	if (!desperate && nftl->numfreeEUNs < 2) {
+		DEBUG(MTD_DEBUG_LEVEL1, "NFTL_findfreeblock: there are too few free EUNs\n");
+		return 0xffff;
+	}
+
+	/* Scan for a free block */
+	do {
+		if (nftl->ReplUnitTable[pot] == BLOCK_FREE) {
+			nftl->LastFreeEUN = pot;
+			nftl->numfreeEUNs--;
+			return pot;
+		}
+
+		/* This will probably point to the MediaHdr unit itself,
+		   right at the beginning of the partition. But that unit
+		   (and the backup unit too) should have the UCI set
+		   up so that it's not selected for overwriting */
+		if (++pot > nftl->lastEUN)
+			pot = le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN);
+
+		if (!silly--) {
+			printk("Argh! No free blocks found! LastFreeEUN = %d, "
+			       "FirstEUN = %d\n", nftl->LastFreeEUN, 
+			       le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN));
+			return 0xffff;
+		}
+	} while (pot != nftl->LastFreeEUN);
+
+	return 0xffff;
+}
+
+static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned pendingblock )
+{
+	u16 BlockMap[MAX_SECTORS_PER_UNIT];
+	unsigned char BlockLastState[MAX_SECTORS_PER_UNIT];
+	unsigned char BlockFreeFound[MAX_SECTORS_PER_UNIT];
+	unsigned int thisEUN;
+	int block;
+	int silly;
+	unsigned int targetEUN;
+	struct nftl_oob oob;
+	int inplace = 1;
+        size_t retlen;
+
+	memset(BlockMap, 0xff, sizeof(BlockMap));
+	memset(BlockFreeFound, 0, sizeof(BlockFreeFound));
+
+	thisEUN = nftl->EUNtable[thisVUC];
+
+	if (thisEUN == BLOCK_NIL) {
+		printk(KERN_WARNING "Trying to fold non-existent "
+		       "Virtual Unit Chain %d!\n", thisVUC);
+		return BLOCK_NIL;
+	}
+	
+	/* Scan to find the Erase Unit which holds the actual data for each
+	   512-byte block within the Chain.
+	*/
+        silly = MAX_LOOPS;
+	targetEUN = BLOCK_NIL;
+	while (thisEUN <= nftl->lastEUN ) {
+                unsigned int status, foldmark;
+
+		targetEUN = thisEUN;
+		for (block = 0; block < nftl->EraseSize / 512; block ++) {
+			MTD_READOOB(nftl->mtd,
+				    (thisEUN * nftl->EraseSize) + (block * 512),
+				    16 , &retlen, (char *)&oob);
+			if (block == 2) {
+                                foldmark = oob.u.c.FoldMark | oob.u.c.FoldMark1;
+                                if (foldmark == FOLD_MARK_IN_PROGRESS) {
+                                        DEBUG(MTD_DEBUG_LEVEL1, 
+                                              "Write Inhibited on EUN %d\n", thisEUN);
+					inplace = 0;
+				} else {
+					/* There's no other reason not to do inplace,
+					   except ones that come later. So we don't need
+					   to preserve inplace */
+					inplace = 1;
+				}
+			}
+                        status = oob.b.Status | oob.b.Status1;
+			BlockLastState[block] = status;
+
+			switch(status) {
+			case SECTOR_FREE:
+				BlockFreeFound[block] = 1;
+				break;
+
+			case SECTOR_USED:
+				if (!BlockFreeFound[block])
+					BlockMap[block] = thisEUN;
+				else
+					printk(KERN_WARNING 
+					       "SECTOR_USED found after SECTOR_FREE "
+					       "in Virtual Unit Chain %d for block %d\n",
+					       thisVUC, block);
+				break;
+			case SECTOR_IGNORE:
+			case SECTOR_DELETED:
+				break;
+			default:
+				printk("Unknown status for block %d in EUN %d: %x\n",
+				       block, thisEUN, status);
+			}
+		}
+
+		if (!silly--) {
+			printk(KERN_WARNING "Infinite loop in Virtual Unit Chain 0x%x\n",
+			       thisVUC);
+			return BLOCK_NIL;
+		}
+		
+		thisEUN = nftl->ReplUnitTable[thisEUN];
+	}
+
+	if (inplace) {
+		/* We're being asked to be a fold-in-place. Check
+		   that all blocks are either present or SECTOR_FREE
+		   in the target block. If not, we're going to have
+		   to fold out-of-place anyway.
+		*/
+		for (block = 0; block < nftl->EraseSize / 512 ; block++) {
+			if (BlockLastState[block] != SECTOR_FREE &&
+			    BlockMap[block] != targetEUN) {
+				DEBUG(MTD_DEBUG_LEVEL1, "Setting inplace to 0. VUC %d, "
+				      "block %d was %x lastEUN, "
+				      "and is in EUN %d (%s) %d\n",
+				      thisVUC, block, BlockLastState[block],
+				      BlockMap[block], 
+				      BlockMap[block]== targetEUN ? "==" : "!=",
+				      targetEUN);
+				inplace = 0;
+				break;
+			}
+		}
+
+		if (pendingblock >= (thisVUC * (nftl->EraseSize / 512)) &&
+		    pendingblock < ((thisVUC + 1)* (nftl->EraseSize / 512)) &&
+		    BlockLastState[pendingblock - (thisVUC * (nftl->EraseSize / 512))] !=
+		    SECTOR_FREE) {
+			DEBUG(MTD_DEBUG_LEVEL1, "Pending write not free in EUN %d. "
+			      "Folding out of place.\n", targetEUN);
+			inplace = 0;
+		}
+	}
+	
+	if (!inplace) {
+		DEBUG(MTD_DEBUG_LEVEL1, "Cannot fold Virtual Unit Chain %d in place. "
+		      "Trying out-of-place\n", thisVUC);
+		/* We need to find a targetEUN to fold into. */
+		targetEUN = NFTL_findfreeblock(nftl, 1);
+		if (targetEUN == BLOCK_NIL) {
+			/* Ouch. Now we're screwed. We need to do a 
+			   fold-in-place of another chain to make room
+			   for this one. We need a better way of selecting
+			   which chain to fold, because makefreeblock will 
+			   only ask us to fold the same one again.
+			*/
+			printk(KERN_WARNING
+			       "NFTL_findfreeblock(desperate) returns 0xffff.\n");
+			return BLOCK_NIL;
+		}
+	} else {
+            /* We put a fold mark in the chain we are folding only if
+               we fold in place to help the mount check code. If we do
+               not fold in place, it is possible to find the valid
+               chain by selecting the longer one */
+            oob.u.c.FoldMark = oob.u.c.FoldMark1 = cpu_to_le16(FOLD_MARK_IN_PROGRESS);
+            oob.u.c.unused = 0xffffffff;
+            MTD_WRITEOOB(nftl->mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8, 
+                         8, &retlen, (char *)&oob.u);
+        }
+
+	/* OK. We now know the location of every block in the Virtual Unit Chain,
+	   and the Erase Unit into which we are supposed to be copying.
+	   Go for it.
+	*/
+	DEBUG(MTD_DEBUG_LEVEL1,"Folding chain %d into unit %d\n", thisVUC, targetEUN);
+	for (block = 0; block < nftl->EraseSize / 512 ; block++) {
+		unsigned char movebuf[512];
+		int ret;
+
+		/* If it's in the target EUN already, or if it's pending write, do nothing */
+		if (BlockMap[block] == targetEUN ||
+		    (pendingblock == (thisVUC * (nftl->EraseSize / 512) + block))) {
+			continue;
+		}
+
+                /* copy only in non free block (free blocks can only
+                   happen in case of media errors or deleted blocks) */
+                if (BlockMap[block] == BLOCK_NIL)
+                        continue;
+                
+                ret = MTD_READECC(nftl->mtd, (nftl->EraseSize * BlockMap[block])
+                                  + (block * 512), 512, &retlen, movebuf, (char *)&oob); 
+                if (ret < 0) {
+                    ret = MTD_READECC(nftl->mtd, (nftl->EraseSize * BlockMap[block])
+                                      + (block * 512), 512, &retlen,
+                                      movebuf, (char *)&oob); 
+                    if (ret != -EIO) 
+                        printk("Error went away on retry.\n");
+                }
+                MTD_WRITEECC(nftl->mtd, (nftl->EraseSize * targetEUN) + (block * 512),
+                             512, &retlen, movebuf, (char *)&oob);
+	}
+        
+        /* add the header so that it is now a valid chain */
+        oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum
+                = cpu_to_le16(thisVUC);
+        oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff;
+        
+        MTD_WRITEOOB(nftl->mtd, (nftl->EraseSize * targetEUN) + 8, 
+                     8, &retlen, (char *)&oob.u);
+
+	/* OK. We've moved the whole lot into the new block. Now we have to free the original blocks. */
+
+	/* At this point, we have two different chains for this Virtual Unit, and no way to tell 
+	   them apart. If we crash now, we get confused. However, both contain the same data, so we
+	   shouldn't actually lose data in this case. It's just that when we load up on a medium which
+	   has duplicate chains, we need to free one of the chains because it's not necessary any more.
+	*/
+	thisEUN = nftl->EUNtable[thisVUC];
+	DEBUG(MTD_DEBUG_LEVEL1,"Want to erase\n");
+
+	/* For each block in the old chain (except the targetEUN of course), 
+	   free it and make it available for future use */
+	while (thisEUN <= nftl->lastEUN && thisEUN != targetEUN) {
+		unsigned int EUNtmp;
+
+                EUNtmp = nftl->ReplUnitTable[thisEUN];
+
+                if (NFTL_formatblock(nftl, thisEUN) < 0) {
+			/* could not erase : mark block as reserved
+			 * FixMe: Update Bad Unit Table on disk
+			 */
+			nftl->ReplUnitTable[thisEUN] = BLOCK_RESERVED;
+                } else {
+			/* correctly erased : mark it as free */
+			nftl->ReplUnitTable[thisEUN] = BLOCK_FREE;
+			nftl->numfreeEUNs++;
+                }
+                thisEUN = EUNtmp;
+	}
+	
+	/* Make this the new start of chain for thisVUC */
+	nftl->ReplUnitTable[targetEUN] = BLOCK_NIL;
+	nftl->EUNtable[thisVUC] = targetEUN;
+
+	return targetEUN;
+}
+
+u16 NFTL_makefreeblock( struct NFTLrecord *nftl , unsigned pendingblock)
+{
+	/* This is the part that needs some cleverness applied. 
+	   For now, I'm doing the minimum applicable to actually
+	   get the thing to work.
+	   Wear-levelling and other clever stuff needs to be implemented
+	   and we also need to do some assessment of the results when
+	   the system loses power half-way through the routine.
+	*/
+	u16 LongestChain = 0;
+	u16 ChainLength = 0, thislen;
+	u16 chain, EUN;
+
+	for (chain = 0; chain < nftl->MediaHdr.FormattedSize / nftl->EraseSize; chain++) {
+		EUN = nftl->EUNtable[chain];
+		thislen = 0;
+
+		while (EUN <= nftl->lastEUN) {
+			thislen++;
+			//printk("VUC %d reaches len %d with EUN %d\n", chain, thislen, EUN);
+			EUN = nftl->ReplUnitTable[EUN] & 0x7fff;
+			if (thislen > 0xff00) {
+				printk("Endless loop in Virtual Chain %d: Unit %x\n",
+				       chain, EUN);
+			}
+			if (thislen > 0xff10) {
+				/* Actually, don't return failure. Just ignore this chain and
+				   get on with it. */
+				thislen = 0;
+				break;
+			}
+		}
+
+		if (thislen > ChainLength) {
+			//printk("New longest chain is %d with length %d\n", chain, thislen);
+			ChainLength = thislen;
+			LongestChain = chain;
+		}
+	}
+
+	if (ChainLength < 2) {
+		printk(KERN_WARNING "No Virtual Unit Chains available for folding. "
+		       "Failing request\n");
+		return 0xffff;
+	}
+
+	return NFTL_foldchain (nftl, LongestChain, pendingblock);
+}
+
+/* NFTL_findwriteunit: Return the unit number into which we can write 
+                       for this block. Make it available if it isn't already
+*/
+static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
+{
+	u16 lastEUN;
+	u16 thisVUC = block / (nftl->EraseSize / 512);
+	unsigned int writeEUN;
+	unsigned long blockofs = (block * 512) & (nftl->EraseSize -1);
+	size_t retlen;
+	int silly, silly2 = 3;
+	struct nftl_oob oob;
+
+	do {
+		/* Scan the media to find a unit in the VUC which has
+		   a free space for the block in question.
+		*/
+
+		/* This condition catches the 0x[7f]fff cases, as well as 
+		   being a sanity check for past-end-of-media access
+		*/
+		lastEUN = BLOCK_NIL;
+		writeEUN = nftl->EUNtable[thisVUC];
+                silly = MAX_LOOPS;
+		while (writeEUN <= nftl->lastEUN) {
+			struct nftl_bci bci;
+			size_t retlen;
+                        unsigned int status;
+
+			lastEUN = writeEUN;
+
+			MTD_READOOB(nftl->mtd, (writeEUN * nftl->EraseSize) + blockofs,
+				    8, &retlen, (char *)&bci);
+			
+			DEBUG(MTD_DEBUG_LEVEL2, "Status of block %d in EUN %d is %x\n",
+			      block , writeEUN, le16_to_cpu(bci.Status));
+
+                        status = bci.Status | bci.Status1;
+			switch(status) {
+			case SECTOR_FREE:
+				return writeEUN;
+
+			case SECTOR_DELETED:
+			case SECTOR_USED:
+			case SECTOR_IGNORE:
+				break;
+			default:
+				// Invalid block. Don't use it any more. Must implement.
+				break;			
+			}
+			
+			if (!silly--) { 
+				printk(KERN_WARNING
+				       "Infinite loop in Virtual Unit Chain 0x%x\n",
+				       thisVUC);
+				return 0xffff;
+			}
+
+			/* Skip to next block in chain */
+			writeEUN = nftl->ReplUnitTable[writeEUN];
+		}
+
+		/* OK. We didn't find one in the existing chain, or there 
+		   is no existing chain. */
+
+		/* Try to find an already-free block */
+		writeEUN = NFTL_findfreeblock(nftl, 0);
+
+		if (writeEUN == BLOCK_NIL) {
+			/* That didn't work - there were no free blocks just
+			   waiting to be picked up. We're going to have to fold
+			   a chain to make room.
+			*/
+
+			/* First remember the start of this chain */
+			//u16 startEUN = nftl->EUNtable[thisVUC];
+			
+			//printk("Write to VirtualUnitChain %d, calling makefreeblock()\n", thisVUC);
+			writeEUN = NFTL_makefreeblock(nftl, 0xffff);
+
+			if (writeEUN == BLOCK_NIL) {
+				/* OK, we accept that the above comment is 
+				   lying - there may have been free blocks
+				   last time we called NFTL_findfreeblock(),
+				   but they are reserved for when we're
+				   desperate. Well, now we're desperate.
+				*/
+				DEBUG(MTD_DEBUG_LEVEL1, "Using desperate==1 to find free EUN to accommodate write to VUC %d\n", thisVUC);
+				writeEUN = NFTL_findfreeblock(nftl, 1);
+			}
+			if (writeEUN == BLOCK_NIL) {
+				/* Ouch. This should never happen - we should
+				   always be able to make some room somehow. 
+				   If we get here, we've allocated more storage 
+				   space than actual media, or our makefreeblock
+				   routine is missing something.
+				*/
+				printk(KERN_WARNING "Cannot make free space.\n");
+				return BLOCK_NIL;
+			}			
+			//printk("Restarting scan\n");
+			lastEUN = BLOCK_NIL;
+			continue;
+		}
+
+		/* We've found a free block. Insert it into the chain. */
+		
+		if (lastEUN != BLOCK_NIL) {
+                    thisVUC |= 0x8000; /* It's a replacement block */
+		} else {
+                    /* The first block in a new chain */
+                    nftl->EUNtable[thisVUC] = writeEUN;
+		}
+
+		/* set up the actual EUN we're writing into */
+		/* Both in our cache... */
+		nftl->ReplUnitTable[writeEUN] = BLOCK_NIL;
+
+		/* ... and on the flash itself */
+		MTD_READOOB(nftl->mtd, writeEUN * nftl->EraseSize + 8, 8,
+			    &retlen, (char *)&oob.u);
+
+		oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum = cpu_to_le16(thisVUC);
+
+		MTD_WRITEOOB(nftl->mtd, writeEUN * nftl->EraseSize + 8, 8,
+                             &retlen, (char *)&oob.u);
+
+                /* we link the new block to the chain only after the
+                   block is ready. It avoids the case where the chain
+                   could point to a free block */
+                if (lastEUN != BLOCK_NIL) {
+			/* Both in our cache... */
+			nftl->ReplUnitTable[lastEUN] = writeEUN;
+			/* ... and on the flash itself */
+			MTD_READOOB(nftl->mtd, (lastEUN * nftl->EraseSize) + 8,
+				    8, &retlen, (char *)&oob.u);
+
+			oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum
+				= cpu_to_le16(writeEUN);
+
+			MTD_WRITEOOB(nftl->mtd, (lastEUN * nftl->EraseSize) + 8,
+				     8, &retlen, (char *)&oob.u);
+		}
+
+		return writeEUN;
+
+	} while (silly2--);
+
+	printk(KERN_WARNING "Error folding to make room for Virtual Unit Chain 0x%x\n",
+	       thisVUC);
+	return 0xffff;
+}
+
+static int NFTL_writeblock(struct NFTLrecord *nftl, unsigned block, char *buffer)
+{
+	u16 writeEUN;
+	unsigned long blockofs = (block * 512) & (nftl->EraseSize - 1);
+	size_t retlen;
+	u8 eccbuf[6];
+
+	writeEUN = NFTL_findwriteunit(nftl, block);
+
+	if (writeEUN == BLOCK_NIL) {
+		printk(KERN_WARNING
+		       "NFTL_writeblock(): Cannot find block to write to\n");
+		/* If we _still_ haven't got a block to use, we're screwed */
+		return 1;
+	}
+
+	MTD_WRITEECC(nftl->mtd, (writeEUN * nftl->EraseSize) + blockofs,
+		     512, &retlen, (char *)buffer, (char *)eccbuf);
+        /* no need to write SECTOR_USED flags since they are written in mtd_writeecc */
+
+	return 0;
+}
+#endif /* CONFIG_NFTL_RW */
+
+static int NFTL_readblock(struct NFTLrecord *nftl, unsigned block, char *buffer)
+{
+	u16 lastgoodEUN;
+	u16 thisEUN = nftl->EUNtable[block / (nftl->EraseSize / 512)];
+	unsigned long blockofs = (block * 512) & (nftl->EraseSize - 1);
+        unsigned int status;
+	int silly = MAX_LOOPS;
+        size_t retlen;
+        struct nftl_bci bci;
+
+	lastgoodEUN = BLOCK_NIL;
+
+        if (thisEUN != BLOCK_NIL) {
+		while (thisEUN < nftl->nb_blocks) {
+			if (MTD_READOOB(nftl->mtd, (thisEUN * nftl->EraseSize) + blockofs,
+					8, &retlen, (char *)&bci) < 0)
+				status = SECTOR_IGNORE;
+			else
+				status = bci.Status | bci.Status1;
+
+			switch (status) {
+			case SECTOR_FREE:
+				/* no modification of a sector should follow a free sector */
+				goto the_end;
+			case SECTOR_DELETED:
+				lastgoodEUN = BLOCK_NIL;
+				break;
+			case SECTOR_USED:
+				lastgoodEUN = thisEUN;
+				break;
+			case SECTOR_IGNORE:
+				break;
+			default:
+				printk("Unknown status for block %d in EUN %d: %x\n",
+				       block, thisEUN, status);
+				break;
+			}
+
+			if (!silly--) {
+				printk(KERN_WARNING "Infinite loop in Virtual Unit Chain 0x%x\n",
+				       block / (nftl->EraseSize / 512));
+				return 1;
+			}
+			thisEUN = nftl->ReplUnitTable[thisEUN];
+		}
+        }
+
+ the_end:
+	if (lastgoodEUN == BLOCK_NIL) {
+		/* the requested block is not on the media, return all 0x00 */
+		memset(buffer, 0, 512);
+	} else {
+		loff_t ptr = (lastgoodEUN * nftl->EraseSize) + blockofs;
+		size_t retlen;
+		u_char eccbuf[6];
+		if (MTD_READECC(nftl->mtd, ptr, 512, &retlen, buffer, eccbuf))
+			return -EIO;
+	}
+	return 0;
+}
+
+static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
+{
+	struct NFTLrecord *nftl;
+	int p;
+
+	nftl = NFTLs[MINOR(inode->i_rdev) >> NFTL_PARTN_BITS];
+
+	if (!nftl) return -EINVAL;
+
+	switch (cmd) {
+	case HDIO_GETGEO: {
+		struct hd_geometry g;
+
+		g.heads = nftl->heads;
+		g.sectors = nftl->sectors;
+		g.cylinders = nftl->cylinders;
+		g.start = part_table[MINOR(inode->i_rdev)].start_sect;
+		return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0;
+	}
+	case BLKGETSIZE:   /* Return device size */
+		if (!arg) return -EINVAL;
+		return put_user(part_table[MINOR(inode->i_rdev)].nr_sects,
+                                (long *) arg);
+		
+	case BLKFLSBUF:
+		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+		fsync_dev(inode->i_rdev);
+		invalidate_buffers(inode->i_rdev);
+		if (nftl->mtd->sync)
+			nftl->mtd->sync(nftl->mtd);
+		return 0;
+
+	case BLKRRPART:
+		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+		if (nftl->usecount > 1) return -EBUSY;
+		/* 
+		 * We have to flush all buffers and invalidate caches,
+		 * or we won't be able to re-use the partitions,
+		 * if there was a change and we don't want to reboot
+		 */
+		p = (1<<NFTL_PARTN_BITS) - 1;
+		while (p-- > 0) {
+			kdev_t devp = MKDEV(MAJOR(inode->i_dev), MINOR(inode->i_dev)+p);
+			if (part_table[p].nr_sects > 0)
+				invalidate_device (devp, 1);
+
+			part_table[MINOR(inode->i_dev)+p].start_sect = 0;
+			part_table[MINOR(inode->i_dev)+p].nr_sects = 0;
+		}
+		
+#if LINUX_VERSION_CODE < 0x20328
+		resetup_one_dev(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS);
+#else
+		grok_partitions(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS,
+				1<<NFTL_PARTN_BITS, nftl->nr_sects);
+#endif
+		return 0;
+
+#if (LINUX_VERSION_CODE < 0x20303)		
+	RO_IOCTLS(inode->i_rdev, arg);  /* ref. linux/blk.h */
+#else
+	case BLKROSET:
+	case BLKROGET:
+	case BLKSSZGET:
+		return blk_ioctl(inode->i_rdev, cmd, arg);
+#endif
+
+	default:
+		return -EINVAL;
+	}
+}
+
+void nftl_request(RQFUNC_ARG)
+{
+	unsigned int dev, block, nsect;
+	struct NFTLrecord *nftl;
+	char *buffer;
+	struct request *req;
+	int res;
+
+	while (1) {
+		INIT_REQUEST;	/* blk.h */
+		req = CURRENT;
+		
+		/* We can do this because the generic code knows not to
+		   touch the request at the head of the queue */
+		spin_unlock_irq(&io_request_lock);
+
+		DEBUG(MTD_DEBUG_LEVEL2, "NFTL_request\n");
+		DEBUG(MTD_DEBUG_LEVEL3, "NFTL %s request, from sector 0x%04lx for 0x%04lx sectors\n",
+		      (req->cmd == READ) ? "Read " : "Write",
+		      req->sector, req->current_nr_sectors);
+
+		dev = MINOR(req->rq_dev);
+		block = req->sector;
+		nsect = req->current_nr_sectors;
+		buffer = req->buffer;
+		res = 1; /* succeed */
+
+		if (dev >= MAX_NFTLS * (1<<NFTL_PARTN_BITS)) {
+			/* there is no such partition */
+			printk("nftl: bad minor number: device = %s\n",
+			       kdevname(req->rq_dev));
+			res = 0; /* fail */
+			goto repeat;
+		}
+		
+		nftl = NFTLs[dev / (1<<NFTL_PARTN_BITS)];
+		DEBUG(MTD_DEBUG_LEVEL3, "Waiting for mutex\n");
+		down(&nftl->mutex);
+		DEBUG(MTD_DEBUG_LEVEL3, "Got mutex\n");
+
+		if (block + nsect > part_table[dev].nr_sects) {
+			/* access past the end of device */
+			printk("nftl%c%d: bad access: block = %d, count = %d\n",
+			       (MINOR(req->rq_dev)>>6)+'a', dev & 0xf, block, nsect);
+			up(&nftl->mutex);
+			res = 0; /* fail */
+			goto repeat;
+		}
+		
+		block += part_table[dev].start_sect;
+		
+		if (req->cmd == READ) {
+			DEBUG(MTD_DEBUG_LEVEL2, "NFTL read request of 0x%x sectors @ %x "
+			      "(req->nr_sectors == %lx)\n", nsect, block, req->nr_sectors);
+	
+			for ( ; nsect > 0; nsect-- , block++, buffer += 512) {
+				/* Read a single sector to req->buffer + (512 * i) */
+				if (NFTL_readblock(nftl, block, buffer)) {
+					DEBUG(MTD_DEBUG_LEVEL2, "NFTL read request failed\n");
+					up(&nftl->mutex);
+					res = 0;
+					goto repeat;
+				}
+			}
+
+			DEBUG(MTD_DEBUG_LEVEL2,"NFTL read request completed OK\n");
+			up(&nftl->mutex);
+			goto repeat;
+		} else if (req->cmd == WRITE) {
+			DEBUG(MTD_DEBUG_LEVEL2, "NFTL write request of 0x%x sectors @ %x "
+			      "(req->nr_sectors == %lx)\n", nsect, block,
+			      req->nr_sectors);
+#ifdef CONFIG_NFTL_RW
+			for ( ; nsect > 0; nsect-- , block++, buffer += 512) {
+				/* Read a single sector to req->buffer + (512 * i) */
+				if (NFTL_writeblock(nftl, block, buffer)) {
+					DEBUG(MTD_DEBUG_LEVEL1,"NFTL write request failed\n");
+					up(&nftl->mutex);
+					res = 0;
+					goto repeat;
+				}
+			}
+			DEBUG(MTD_DEBUG_LEVEL2,"NFTL write request completed OK\n");
+#else
+			res = 0; /* Writes always fail */
+#endif /* CONFIG_NFTL_RW */
+			up(&nftl->mutex);
+			goto repeat;
+		} else {
+			DEBUG(MTD_DEBUG_LEVEL0, "NFTL unknown request\n");
+			up(&nftl->mutex);
+			res = 0;
+			goto repeat;
+		}
+	repeat: 
+		DEBUG(MTD_DEBUG_LEVEL3, "end_request(%d)\n", res);
+		spin_lock_irq(&io_request_lock);
+		end_request(res);
+	}
+}
+
+static int nftl_open(struct inode *ip, struct file *fp)
+{
+	int nftlnum = MINOR(ip->i_rdev) >> NFTL_PARTN_BITS;
+	struct NFTLrecord *thisNFTL;
+	thisNFTL = NFTLs[nftlnum];
+
+	DEBUG(MTD_DEBUG_LEVEL2,"NFTL_open\n");
+
+#ifdef CONFIG_KMOD
+	if (!thisNFTL && nftlnum == 0) {
+		request_module("docprobe");
+		thisNFTL = NFTLs[nftlnum];
+	}
+#endif
+	if (!thisNFTL) {
+		DEBUG(MTD_DEBUG_LEVEL2,"ENODEV: thisNFTL = %d, minor = %d, ip = %p, fp = %p\n", 
+		      nftlnum, ip->i_rdev, ip, fp);
+		return -ENODEV;
+	}
+
+#ifndef CONFIG_NFTL_RW
+	if (fp->f_mode & FMODE_WRITE)
+		return -EROFS;
+#endif /* !CONFIG_NFTL_RW */
+
+	thisNFTL->usecount++;
+	MOD_INC_USE_COUNT;
+	if (!get_mtd_device(thisNFTL->mtd, -1)) {
+		MOD_DEC_USE_COUNT;
+		return /* -E'SBUGGEREDOFF */ -ENXIO;
+	}
+
+	return 0;
+}
+
+static int nftl_release(struct inode *inode, struct file *fp)
+{
+	struct NFTLrecord *thisNFTL;
+
+	thisNFTL = NFTLs[MINOR(inode->i_rdev) / 16];
+
+	DEBUG(MTD_DEBUG_LEVEL2, "NFTL_release\n");
+
+	invalidate_device(inode->i_rdev, 1);
+
+	if (thisNFTL->mtd->sync)
+		thisNFTL->mtd->sync(thisNFTL->mtd);
+	thisNFTL->usecount--;
+	MOD_DEC_USE_COUNT;
+
+	put_mtd_device(thisNFTL->mtd);
+
+	return 0;
+}
+#if LINUX_VERSION_CODE < 0x20326
+static struct file_operations nftl_fops = {
+	read:		block_read,
+	write:		block_write,
+	ioctl:		nftl_ioctl,
+	open:		nftl_open,
+	release:	nftl_release,
+	fsync:		block_fsync,
+};
+#else
+static struct block_device_operations nftl_fops = 
+{
+	open:		nftl_open,
+	release:	nftl_release,
+	ioctl: 		nftl_ioctl
+};
+#endif
+
+
+
+/****************************************************************************
+ *
+ * Module stuff
+ *
+ ****************************************************************************/
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define init_nftl init_module
+#define cleanup_nftl cleanup_module
+#endif
+
+static struct mtd_notifier nftl_notifier = {
+	add:	NFTL_notify_add,
+	remove:	NFTL_notify_remove
+};
+
+static int __init init_nftl(void)
+{
+	int i;
+
+	printk(KERN_NOTICE
+	       "M-Systems NAND Flash Translation Layer driver. (C) 1999 MVHI\n");
+#ifdef PRERELEASE 
+	printk(KERN_INFO"$Id: nftlcore.c,v 1.73 2001/06/09 01:09:43 dwmw2 Exp $\n");
+#endif
+
+	if (register_blkdev(MAJOR_NR, "nftl", &nftl_fops)){
+		printk("unable to register NFTL block device on major %d\n", MAJOR_NR);
+		return -EBUSY;
+	} else {
+#if LINUX_VERSION_CODE < 0x20320
+		blk_dev[MAJOR_NR].request_fn = nftl_request;
+#else
+		blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &nftl_request);
+#endif
+		/* set block size to 1kB each */
+		for (i = 0; i < 256; i++) {
+			nftl_blocksizes[i] = 1024;
+		}
+		blksize_size[MAJOR_NR] = nftl_blocksizes;
+
+		nftl_gendisk.next = gendisk_head;
+		gendisk_head = &nftl_gendisk;
+	}
+	
+	register_mtd_user(&nftl_notifier);
+
+	return 0;
+}
+
+static void __exit cleanup_nftl(void)
+{
+	struct gendisk *gd, **gdp;
+
+  	unregister_mtd_user(&nftl_notifier);
+  	unregister_blkdev(MAJOR_NR, "nftl");
+  	
+#if LINUX_VERSION_CODE < 0x20320
+  	blk_dev[MAJOR_NR].request_fn = 0;
+#else
+  	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+#endif	
+
+	/* remove ourself from generic harddisk list
+	   FIXME: why can't I found this partition on /proc/partition */
+  	for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))
+    		if (*gdp == &nftl_gendisk) {
+      			gd = *gdp; *gdp = gd->next;
+      			break;
+		}
+}
+
+module_init(init_nftl);
+module_exit(cleanup_nftl);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/nftlmount.c linux/drivers/mtd/nftlmount.c
--- v2.4.5/linux/drivers/mtd/nftlmount.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/nftlmount.c	Tue Jun 12 10:30:27 2001
@@ -4,7 +4,7 @@
  * Author: Fabrice Bellard (fabrice.bellard@netgem.com) 
  * Copyright (C) 2000 Netgem S.A.
  *
- * $Id: nftlmount.c,v 1.11 2000/11/17 12:24:09 ollie Exp $
+ * $Id: nftlmount.c,v 1.17 2001/06/02 20:33:20 dwmw2 Exp $
  *
  * 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
@@ -20,6 +20,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+
+#define __NO_VERSION__
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <asm/errno.h>
@@ -85,13 +87,20 @@
 				}
 
 				nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN);
-				if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks)
+				if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) {
+					printk(KERN_NOTICE "Potential NFTL Media Header found, but sanity check failed:\n");
+					printk(KERN_NOTICE "nb_boot_blocks (%d) + 2 > nb_blocks (%d)\n", 
+					       nftl->nb_boot_blocks, nftl->nb_blocks);
 					goto ReplUnitTable; /* small consistency check */
+				}
 
 				nftl->numvunits = le32_to_cpu(mh->FormattedSize) / nftl->EraseSize;
-				if (nftl->numvunits > (nftl->nb_blocks - nftl->nb_boot_blocks - 2))
+				if (nftl->numvunits > (nftl->nb_blocks - nftl->nb_boot_blocks - 2)) {
+					printk(KERN_NOTICE "Potential NFTL Media Header found, but sanity check failed:\n");
+					printk(KERN_NOTICE "numvunits (%d) > nb_blocks (%d) - nb_boot_blocks(%d) - 2\n",
+					       nftl->numvunits, nftl->nb_blocks, nftl->nb_boot_blocks);
 					goto ReplUnitTable; /* small consistency check */
-
+				}
 				/* FixMe: with bad blocks, the total size available is not FormattedSize any
 				   more !!! */
 				nftl->nr_sects  = nftl->numvunits * (nftl->EraseSize / SECTORSIZE);
@@ -359,8 +368,7 @@
 {
 	struct nftl_uci1 h1;
 	unsigned int erase_mark;
-	int i, retlen;
-	unsigned char buf[SECTORSIZE];
+	int retlen;
 
 	/* check erase mark. */
 	if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, 
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/nora.c linux/drivers/mtd/nora.c
--- v2.4.5/linux/drivers/mtd/nora.c	Mon Dec 11 14:57:58 2000
+++ linux/drivers/mtd/nora.c	Wed Dec 31 16:00:00 1969
@@ -1,208 +0,0 @@
-/*
- * $Id: nora.c,v 1.17 2000/12/03 19:32:21 dwmw2 Exp $
- *
- * This is so simple I love it.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-
-
-#define WINDOW_ADDR 0xd0000000
-#define WINDOW_SIZE 0x04000000
-
-static struct mtd_info *mymtd;
-
-__u8 nora_read8(struct map_info *map, unsigned long ofs)
-{
-  return *(__u8 *)(WINDOW_ADDR + ofs);
-}
-
-__u16 nora_read16(struct map_info *map, unsigned long ofs)
-{
-  return *(__u16 *)(WINDOW_ADDR + ofs);
-}
-
-__u32 nora_read32(struct map_info *map, unsigned long ofs)
-{
-  return *(__u32 *)(WINDOW_ADDR + ofs);
-}
-
-void nora_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-{
-  memcpy(to, (void *)(WINDOW_ADDR + from), len);
-}
-
-void nora_write8(struct map_info *map, __u8 d, unsigned long adr)
-{
-  *(__u8 *)(WINDOW_ADDR + adr) = d;
-}
-
-void nora_write16(struct map_info *map, __u16 d, unsigned long adr)
-{
-  *(__u16 *)(WINDOW_ADDR + adr) = d;
-}
-
-void nora_write32(struct map_info *map, __u32 d, unsigned long adr)
-{
-  *(__u32 *)(WINDOW_ADDR + adr) = d;
-}
-
-void nora_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-{
-  memcpy((void *)(WINDOW_ADDR + to), from, len);
-}
-
-struct map_info nora_map = {
-	name: "NORA",
-	size: WINDOW_SIZE,
-	buswidth: 2,
-	read8: nora_read8,
-	read16: nora_read16,
-	read32: nora_read32,
-	copy_from: nora_copy_from,
-	write8: nora_write8,
-	write16: nora_write16,
-	write32: nora_write32,
-	copy_to: nora_copy_to
-};
-
-
-static int nora_mtd_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
-{
-	return mymtd->read(mymtd, from + (unsigned long)mtd->priv, len, retlen, buf);
-}
-
-static int nora_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
-{
-	return mymtd->write(mymtd, to + (unsigned long)mtd->priv, len, retlen, buf);
-}
-
-static int nora_mtd_erase (struct mtd_info *mtd, struct erase_info *instr)
-{
-	instr->addr += (unsigned long)mtd->priv;
-	return mymtd->erase(mymtd, instr);
-}
-
-static void nora_mtd_sync (struct mtd_info *mtd)
-{
-	mymtd->sync(mymtd);
-}
-
-static int nora_mtd_suspend (struct mtd_info *mtd)
-{
-	return mymtd->suspend(mymtd);
-}
-
-static void nora_mtd_resume (struct mtd_info *mtd)
-{
-	mymtd->resume(mymtd);
-}
-
-
-static struct mtd_info nora_mtds[4] = {  /* boot, kernel, ramdisk, fs */
-	{
-		type: MTD_NORFLASH,
-		flags: MTD_CAP_NORFLASH,
-		size: 0x60000,
-		erasesize: 0x20000,
-		name: "NORA boot firmware",
-		module: THIS_MODULE,
-		erase: nora_mtd_erase,
-		read: nora_mtd_read,
-		write: nora_mtd_write,
-		suspend: nora_mtd_suspend,
-		resume: nora_mtd_resume,
-		sync: nora_mtd_sync,
-		priv: (void *)0
-	},
-	{
-		type: MTD_NORFLASH,
-		flags: MTD_CAP_NORFLASH,
-		size: 0x0a0000,
-		erasesize: 0x20000,
-		name: "NORA kernel",
-		module: THIS_MODULE,
-		erase: nora_mtd_erase,
-		read: nora_mtd_read,
-		write: nora_mtd_write,
-		suspend: nora_mtd_suspend,
-		resume: nora_mtd_resume,
-		sync: nora_mtd_sync,
-		priv: (void *)0x60000
-	},
-	{
-		type: MTD_NORFLASH,
-		flags: MTD_CAP_NORFLASH,
-		size: 0x900000,
-		erasesize: 0x20000,
-		name: "NORA root filesystem",
-		module: THIS_MODULE,
-		erase: nora_mtd_erase,
-		read: nora_mtd_read,
-		write: nora_mtd_write,
-		suspend: nora_mtd_suspend,
-		resume: nora_mtd_resume,
-		sync: nora_mtd_sync,
-		priv: (void *)0x100000
-	},
-	{
-		type: MTD_NORFLASH,
-		flags: MTD_CAP_NORFLASH,
-		size: 0x1600000,
-		erasesize: 0x20000,
-		name: "NORA second filesystem",
-		module: THIS_MODULE,
-		erase: nora_mtd_erase,
-		read: nora_mtd_read,
-		write: nora_mtd_write,
-		suspend: nora_mtd_suspend,
-		resume: nora_mtd_resume,
-		sync: nora_mtd_sync,
-		priv: (void *)0xa00000
-	}
-};
-
-
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_nora init_module
-#define cleanup_nora cleanup_module
-#endif
-
-int __init init_nora(void)
-{
-       	printk(KERN_NOTICE "nora flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
-
-	mymtd = do_cfi_probe(&nora_map);
-	if (mymtd) {
-#ifdef MODULE
-		mymtd->module = &__this_module;
-#endif
-		
-		add_mtd_device(&nora_mtds[2]);
-		add_mtd_device(&nora_mtds[0]);
-		add_mtd_device(&nora_mtds[1]);
-		add_mtd_device(&nora_mtds[3]);
-		return 0;
-	}
-
-	return -ENXIO;
-}
-
-static void __exit cleanup_nora(void)
-{
-	if (mymtd) {
-		del_mtd_device(&nora_mtds[3]);
-		del_mtd_device(&nora_mtds[1]);
-		del_mtd_device(&nora_mtds[0]);
-		del_mtd_device(&nora_mtds[2]);
-		map_destroy(mymtd);
-	}
-}
-
-module_init(init_nora);
-module_exit(cleanup_nora);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/octagon-5066.c linux/drivers/mtd/octagon-5066.c
--- v2.4.5/linux/drivers/mtd/octagon-5066.c	Fri Feb 16 16:02:36 2001
+++ linux/drivers/mtd/octagon-5066.c	Wed Dec 31 16:00:00 1969
@@ -1,285 +0,0 @@
-// $Id: octagon-5066.c,v 1.12.2.1 2001/02/15 10:12:48 dwmw2 Exp $
-/* ######################################################################
-
-   Octagon 5066 MTD Driver. 
-  
-   The Octagon 5066 is a SBC based on AMD's 586-WB running at 133 MHZ. It
-   comes with a builtin AMD 29F016 flash chip and a socketed EEPROM that
-   is replacable by flash. Both units are mapped through a multiplexer
-   into a 32k memory window at 0xe8000. The control register for the 
-   multiplexing unit is located at IO 0x208 with a bit map of
-     0-5 Page Selection in 32k increments
-     6-7 Device selection:
-        00 SSD off
-        01 SSD 0 (Socket)
-        10 SSD 1 (Flash chip)
-        11 undefined
-  
-   On each SSD, the first 128k is reserved for use by the bios
-   (actually it IS the bios..) This only matters if you are booting off the 
-   flash, you must not put a file system starting there.
-   
-   The driver tries to do a detection algorithm to guess what sort of devices
-   are plugged into the sockets.
-   
-   ##################################################################### */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <asm/io.h>
-
-#include <linux/mtd/map.h>
-
-#define WINDOW_START 0xe8000
-#define WINDOW_LENGTH 0x8000
-#define WINDOW_SHIFT 27
-#define WINDOW_MASK 0x7FFF
-#define PAGE_IO 0x208
-
-static volatile char page_n_dev = 0;
-static unsigned long iomapadr;
-static spinlock_t oct5066_spin = SPIN_LOCK_UNLOCKED;
-
-/*
- * We use map_priv_1 to identify which device we are.
- */
-
-static void __oct5066_page(struct map_info *map, __u8 byte)
-{
-	outb(byte,PAGE_IO);
-	page_n_dev = byte;
-}
-
-static inline void oct5066_page(struct map_info *map, unsigned long ofs)
-{
-	__u8 byte = map->map_priv_1 | (ofs >> WINDOW_SHIFT);
-	
-	if (page_n_dev != byte)
-		__oct5066_page(map, byte);
-}
-
-
-static __u8 oct5066_read8(struct map_info *map, unsigned long ofs)
-{
-	__u8 ret;
-	spin_lock(&oct5066_spin);
-	oct5066_page(map, ofs);
-	ret = readb(iomapadr + (ofs & WINDOW_MASK));
-	spin_unlock(&oct5066_spin);
-	return ret;
-}
-
-static __u16 oct5066_read16(struct map_info *map, unsigned long ofs)
-{
-	__u16 ret;
-	spin_lock(&oct5066_spin);
-	oct5066_page(map, ofs);
-	ret = readw(iomapadr + (ofs & WINDOW_MASK));
-	spin_unlock(&oct5066_spin);
-	return ret;
-}
-
-static __u32 oct5066_read32(struct map_info *map, unsigned long ofs)
-{
-	__u32 ret;
-	spin_lock(&oct5066_spin);
-	oct5066_page(map, ofs);
-	ret = readl(iomapadr + (ofs & WINDOW_MASK));
-	spin_unlock(&oct5066_spin);
-	return ret;
-}
-
-static void oct5066_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-{
-	while(len) {
-		unsigned long thislen = len;
-		if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
-			thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
-		
-		spin_lock(&oct5066_spin);
-		oct5066_page(map, from);
-		memcpy_fromio(to, iomapadr + from, thislen);
-		spin_unlock(&oct5066_spin);
-		to += thislen;
-		from += thislen;
-		len -= thislen;
-	}
-}
-
-static void oct5066_write8(struct map_info *map, __u8 d, unsigned long adr)
-{
-	spin_lock(&oct5066_spin);
-	oct5066_page(map, adr);
-	writeb(d, iomapadr + (adr & WINDOW_MASK));
-	spin_unlock(&oct5066_spin);
-}
-
-static void oct5066_write16(struct map_info *map, __u16 d, unsigned long adr)
-{
-	spin_lock(&oct5066_spin);
-	oct5066_page(map, adr);
-	writew(d, iomapadr + (adr & WINDOW_MASK));
-	spin_unlock(&oct5066_spin);
-}
-
-static void oct5066_write32(struct map_info *map, __u32 d, unsigned long adr)
-{
-	spin_lock(&oct5066_spin);
-	oct5066_page(map, adr);
-	writel(d, iomapadr + (adr & WINDOW_MASK));
-	spin_unlock(&oct5066_spin);
-}
-
-static void oct5066_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-{
-	while(len) {
-		unsigned long thislen = len;
-		if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
-			thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
-		
-		spin_lock(&oct5066_spin);
-		oct5066_page(map, to);
-		memcpy_toio(iomapadr + to, from, thislen);
-		spin_unlock(&oct5066_spin);
-		to += thislen;
-		from += thislen;
-		len -= thislen;
-	}
-}
-
-static struct map_info oct5066_map[2] = {
-	{
-		name: "Octagon 5066 Socket",
-		size: 512 * 1024,
-		buswidth: 1,
-		read8: oct5066_read8,
-		read16: oct5066_read16,
-		read32: oct5066_read32,
-		copy_from: oct5066_copy_from,
-		write8: oct5066_write8,
-		write16: oct5066_write16,
-		write32: oct5066_write32,
-		copy_to: oct5066_copy_to,
-		map_priv_1: 1<<6
-	},
-	{
-		name: "Octagon 5066 Internal Flash",
-		size: 2 * 1024 * 1024,
-		buswidth: 1,
-		read8: oct5066_read8,
-		read16: oct5066_read16,
-		read32: oct5066_read32,
-		copy_from: oct5066_copy_from,
-		write8: oct5066_write8,
-		write16: oct5066_write16,
-		write32: oct5066_write32,
-		copy_to: oct5066_copy_to,
-		map_priv_1: 2<<6
-	}
-};
-
-static struct mtd_info *oct5066_mtd[2] = {NULL, NULL};
-
-// OctProbe - Sense if this is an octagon card
-// ---------------------------------------------------------------------
-/* Perform a simple validity test, we map the window select SSD0 and
-   change pages while monitoring the window. A change in the window, 
-   controlled by the PAGE_IO port is a functioning 5066 board. This will
-   fail if the thing in the socket is set to a uniform value. */
-static int __init OctProbe()
-{
-   unsigned int Base = (1 << 6);
-   unsigned long I;
-   unsigned long Values[10];
-   for (I = 0; I != 20; I++)
-   {
-      outb(Base + (I%10),PAGE_IO);
-      if (I < 10)
-      {
-	 // Record the value and check for uniqueness
-	 Values[I%10] = readl(iomapadr);
-	 if (I > 0 && Values[I%10] == Values[0])
-	    return -EAGAIN;
-      }      
-      else
-      {
-	 // Make sure we get the same values on the second pass
-	 if (Values[I%10] != readl(iomapadr))
-	    return -EAGAIN;
-      }      
-   }
-   return 0;
-}
-
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_oct5066 init_module
-#define cleanup_oct5066 cleanup_module
-#endif
-
-void cleanup_oct5066(void)
-{
-	int i;
-	for (i=0; i<2; i++) {
-		if (oct5066_mtd[i]) {
-			del_mtd_device(oct5066_mtd[i]);
-			map_destroy(oct5066_mtd[i]);
-		}
-	}
-	iounmap((void *)iomapadr);
-	release_region(PAGE_IO,1);
-}
-
-int __init init_oct5066(void)
-{
-	int i;
-	
-	// Do an autoprobe sequence
-	if (check_region(PAGE_IO,1) != 0)
-		{
-			printk("5066: Page Register in Use\n");
-			return -EAGAIN;
-		}
-	iomapadr = (unsigned long)ioremap(WINDOW_START, WINDOW_LENGTH);
-	if (!iomapadr) {
-		printk("Failed to ioremap memory region\n");
-		return -EIO;
-	}
-	if (OctProbe() != 0)
-		{
-			printk("5066: Octagon Probe Failed, is this an Octagon 5066 SBC?\n");
-			iounmap((void *)iomapadr);
-			return -EAGAIN;
-		}
-	
-	request_region(PAGE_IO,1,"Octagon SSD");
-	
-	// Print out our little header..
-	printk("Octagon 5066 SSD IO:0x%x MEM:0x%x-0x%x\n",PAGE_IO,WINDOW_START,
-	       WINDOW_START+WINDOW_LENGTH);
-	
-	for (i=0; i<2; i++) {
-		oct5066_mtd[i] = do_cfi_probe(&oct5066_map[i]);
-		if (!oct5066_mtd[i])
-			oct5066_mtd[i] = do_jedec_probe(&oct5066_map[i]);
-		if (!oct5066_mtd[i])
-			oct5066_mtd[i] = do_ram_probe(&oct5066_map[i]);
-		if (!oct5066_mtd[i])
-			oct5066_mtd[i] = do_rom_probe(&oct5066_map[i]);
-		if (oct5066_mtd[i]) {
-			oct5066_mtd[i]->module = THIS_MODULE;
-			add_mtd_device(oct5066_mtd[i]);
-		}
-	}
-	
-	if (!oct5066_mtd[0] && !oct5066_mtd[1]) {
-		cleanup_oct5066();
-		return -ENXIO;
-	}	  
-	
-	return 0;
-}
-
-module_init(init_oct5066);
-module_exit(cleanup_oct5066);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/physmap.c linux/drivers/mtd/physmap.c
--- v2.4.5/linux/drivers/mtd/physmap.c	Mon Dec 11 14:57:58 2000
+++ linux/drivers/mtd/physmap.c	Wed Dec 31 16:00:00 1969
@@ -1,117 +0,0 @@
-/*
- * $Id: physmap.c,v 1.8 2000/11/27 08:50:22 dwmw2 Exp $
- *
- * Normal mappings of chips in physical memory
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <asm/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/config.h>
-
-
-#define WINDOW_ADDR CONFIG_MTD_PHYSMAP_START
-#define WINDOW_SIZE CONFIG_MTD_PHYSMAP_LEN
-#define BUSWIDTH CONFIG_MTD_PHYSMAP_BUSWIDTH
-
-static struct mtd_info *mymtd;
-
-__u8 physmap_read8(struct map_info *map, unsigned long ofs)
-{
-	return readb(map->map_priv_1 + ofs);
-}
-
-__u16 physmap_read16(struct map_info *map, unsigned long ofs)
-{
-	return readw(map->map_priv_1 + ofs);
-}
-
-__u32 physmap_read32(struct map_info *map, unsigned long ofs)
-{
-	return readl(map->map_priv_1 + ofs);
-}
-
-void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-{
-	memcpy_fromio(to, map->map_priv_1 + from, len);
-}
-
-void physmap_write8(struct map_info *map, __u8 d, unsigned long adr)
-{
-	writeb(d, map->map_priv_1 + adr);
-}
-
-void physmap_write16(struct map_info *map, __u16 d, unsigned long adr)
-{
-	writew(d, map->map_priv_1 + adr);
-}
-
-void physmap_write32(struct map_info *map, __u32 d, unsigned long adr)
-{
-	writel(d, map->map_priv_1 + adr);
-}
-
-void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-{
-	memcpy_toio(map->map_priv_1 + to, from, len);
-}
-
-struct map_info physmap_map = {
-	name: "Physically mapped flash",
-	size: WINDOW_SIZE,
-	buswidth: BUSWIDTH,
-	read8: physmap_read8,
-	read16: physmap_read16,
-	read32: physmap_read32,
-	copy_from: physmap_copy_from,
-	write8: physmap_write8,
-	write16: physmap_write16,
-	write32: physmap_write32,
-	copy_to: physmap_copy_to
-};
-
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_physmap init_module
-#define cleanup_physmap cleanup_module
-#endif
-
-int __init init_physmap(void)
-{
-       	printk(KERN_NOTICE "physmap flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
-	physmap_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
-
-	if (!physmap_map.map_priv_1) {
-		printk("Failed to ioremap\n");
-		return -EIO;
-	}
-	mymtd = do_cfi_probe(&physmap_map);
-	if (mymtd) {
-#ifdef MODULE
-		mymtd->module = &__this_module;
-#endif
-		add_mtd_device(mymtd);
-		return 0;
-	}
-
-	iounmap((void *)physmap_map.map_priv_1);
-	return -ENXIO;
-}
-
-static void __exit cleanup_physmap(void)
-{
-	if (mymtd) {
-		del_mtd_device(mymtd);
-		map_destroy(mymtd);
-	}
-	if (physmap_map.map_priv_1) {
-		iounmap((void *)physmap_map.map_priv_1);
-		physmap_map.map_priv_1 = 0;
-	}
-}
-
-module_init(init_physmap);
-module_exit(cleanup_physmap);
-
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/pmc551.c linux/drivers/mtd/pmc551.c
--- v2.4.5/linux/drivers/mtd/pmc551.c	Fri Apr  6 10:42:55 2001
+++ linux/drivers/mtd/pmc551.c	Wed Dec 31 16:00:00 1969
@@ -1,863 +0,0 @@
-/*
- * $Id: pmc551.c,v 1.11 2000/11/23 13:40:12 dwmw2 Exp $
- *
- * PMC551 PCI Mezzanine Ram Device
- *
- * Author:
- *       Mark Ferrell <mferrell@mvista.com>
- *       Copyright 1999,2000 Nortel Networks
- *
- * License:
- *	 As part of this driver was derrived from the slram.c driver it falls
- *	 under the same license, which is GNU General Public License v2
- *
- * Description:
- *	 This driver is intended to support the PMC551 PCI Ram device from
- *	 Ramix Inc.  The PMC551 is a PMC Mezzanine module for cPCI embedded
- *	 systems.  The device contains a single SROM that initally programs the
- *	 V370PDC chipset onboard the device, and various banks of DRAM/SDRAM
- *	 onboard.  This driver implements this PCI Ram device as an MTD (Memory
- *	 Technologies Device) so that it can be used to hold a filesystem, or
- *	 for added swap space in embedded systems.  Since the memory on this
- *	 board isn't as fast as main memory we do not try to hook it into main
- *	 memeory as that would simply reduce performance on the system.  Using
- *	 it as a block device allows us to use it as high speed swap or for a
- *	 high speed disk device of some sort.  Which becomes very useful on
- *	 diskless systems in the embedded market I might add.
- *	 
- * Notes:
- *	 Due to what I assume is more buggy SROM, the 64M PMC551 I have
- *	 available claims that all 4 of it's DRAM banks have 64M of ram 
- *	 configured (making a grand total of 256M onboard).  This is slightly
- *	 annoying since the BAR0 size reflects the aperture size, not the dram
- *	 size, and the V370PDC supplies no other method for memory size
- *	 discovery.  This problem is mostly only relivant when compiled as a
- *	 module, as the unloading of the module with an aperture size  smaller
- *	 then the ram will cause the driver to detect the onboard memory size
- *	 to be equal to the aperture size when the module is reloaded.  Soooo,
- *	 to help, the module supports an msize option to allow the
- *	 specification of the onboard memory, and an asize option, to allow the
- *	 specification of the aperture size.  The aperture must be equal to or
- *	 less then the memory size, the driver will correct this if you screw
- *	 it up.  This problem is not relivant for compiled in drivers as
- *	 compiled in drivers only init once.
- *
- * Credits:
- *       Saeed Karamooz <saeed@ramix.com> of Ramix INC. for the initial
- *       example code of how to initialize this device and for help with
- *       questions I had concerning operation of the device.
- *
- *       Most of the MTD code for this driver was originally written for the
- *       slram.o module in the MTD drivers package written by David Hinds
- *       <dhinds@allegro.stanford.edu> which allows the mapping of system
- *       memory into an mtd device.  Since the PMC551 memory module is
- *       accessed in the same fashion as system memory, the slram.c code
- *       became a very nice fit to the needs of this driver.  All we added was
- *       PCI detection/initialization to the driver and automaticly figure out
- *       the size via the PCI detection.o, later changes by Corey Minyard
- *       settup the card to utilize a 1M sliding apature.
- *
- *	 Corey Minyard <minyard@nortelnetworks.com>
- *       * Modified driver to utilize a sliding apature instead of mapping all
- *       memory into kernel space which turned out to be very wastefull.
- *       * Located a bug in the SROM's initialization sequence that made the
- *       memory unusable, added a fix to code to touch up the DRAM some.
- *
- * Bugs/FIXME's:
- *       * MUST fix the init function to not spin on a register
- *       waiting for it to set .. this does not safely handle busted devices
- *       that never reset the register correctly which will cause the system to
- *       hang w/ a reboot beeing the only chance at recover.
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <asm/uaccess.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/major.h>
-#include <linux/fs.h>
-#include <linux/ioctl.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/segment.h>
-#include <stdarg.h>
-#include <linux/pci.h>
-
-#ifndef CONFIG_PCI
-#error Enable PCI in your kernel config
-#endif
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/pmc551.h>
-#include <linux/mtd/compatmac.h>
-
-#if LINUX_VERSION_CODE > 0x20300
-#define PCI_BASE_ADDRESS(dev) (dev->resource[0].start)
-#else
-#define PCI_BASE_ADDRESS(dev) (dev->base_address[0])
-#endif
-
-static struct mtd_info *pmc551list = NULL;
-
-static int pmc551_erase (struct mtd_info *mtd, struct erase_info *instr)
-{
-        struct mypriv *priv = mtd->priv;
-        u32 start_addr_highbits;
-        u32 end_addr_highbits;
-        u32 start_addr_lowbits;
-        u32 end_addr_lowbits;
-        unsigned long end;
-
-        end = instr->addr + instr->len;
-
-        /* Is it too much memory?  The second check find if we wrap around
-           past the end of a u32. */
-        if ((end > mtd->size) || (end < instr->addr)) {
-                return -EINVAL;
-        }
-
-        start_addr_highbits = instr->addr & PMC551_ADDR_HIGH_MASK;
-        end_addr_highbits = end & PMC551_ADDR_HIGH_MASK;
-        start_addr_lowbits = instr->addr & PMC551_ADDR_LOW_MASK;
-        end_addr_lowbits = end & PMC551_ADDR_LOW_MASK;
-
-        pci_write_config_dword ( priv->dev,
-                                 PMC551_PCI_MEM_MAP0,
-                                 (priv->mem_map0_base_val
-                                  | start_addr_highbits));
-        if (start_addr_highbits == end_addr_highbits) {
-                /* The whole thing fits within one access, so just one shot
-                   will do it. */
-                memset(priv->start + start_addr_lowbits,
-                       0xff,
-                       instr->len);
-        } else {
-                /* We have to do multiple writes to get all the data
-                   written. */
-                memset(priv->start + start_addr_lowbits,
-                       0xff,
-                       priv->aperture_size - start_addr_lowbits);
-                start_addr_highbits += priv->aperture_size;
-                while (start_addr_highbits != end_addr_highbits) {
-                        pci_write_config_dword ( priv->dev,
-                                                 PMC551_PCI_MEM_MAP0,
-                                                 (priv->mem_map0_base_val
-                                                  | start_addr_highbits));
-                        memset(priv->start,
-                               0xff,
-                               priv->aperture_size);
-                        start_addr_highbits += priv->aperture_size;
-                }
-                priv->curr_mem_map0_val = (priv->mem_map0_base_val
-                                           | start_addr_highbits);
-                pci_write_config_dword ( priv->dev,
-                                         PMC551_PCI_MEM_MAP0,
-                                         priv->curr_mem_map0_val);
-                memset(priv->start,
-                       0xff,
-                       end_addr_lowbits);
-        }
-
-	instr->state = MTD_ERASE_DONE;
-
-        if (instr->callback) {
-                (*(instr->callback))(instr);
-	}
-
-        return 0;
-}
-
-
-static void pmc551_unpoint (struct mtd_info *mtd, u_char *addr)
-{}
-
-
-static int pmc551_read (struct mtd_info *mtd,
-                        loff_t from,
-                        size_t len,
-                        size_t *retlen,
-                        u_char *buf)
-{
-        struct mypriv *priv = (struct mypriv *)mtd->priv;
-        u32 start_addr_highbits;
-        u32 end_addr_highbits;
-        u32 start_addr_lowbits;
-        u32 end_addr_lowbits;
-        unsigned long end;
-        u_char *copyto = buf;
-
-
-        /* Is it past the end? */
-        if (from > mtd->size) {
-                return -EINVAL;
-        }
-
-        end = from + len;
-        start_addr_highbits = from & PMC551_ADDR_HIGH_MASK;
-        end_addr_highbits = end & PMC551_ADDR_HIGH_MASK;
-        start_addr_lowbits = from & PMC551_ADDR_LOW_MASK;
-        end_addr_lowbits = end & PMC551_ADDR_LOW_MASK;
-
-
-        /* Only rewrite the first value if it doesn't match our current
-           values.  Most operations are on the same page as the previous
-           value, so this is a pretty good optimization. */
-        if (priv->curr_mem_map0_val !=
-                        (priv->mem_map0_base_val | start_addr_highbits)) {
-                priv->curr_mem_map0_val = (priv->mem_map0_base_val
-                                           | start_addr_highbits);
-                pci_write_config_dword ( priv->dev,
-                                         PMC551_PCI_MEM_MAP0,
-                                         priv->curr_mem_map0_val);
-        }
-
-        if (start_addr_highbits == end_addr_highbits) {
-                /* The whole thing fits within one access, so just one shot
-                   will do it. */
-                memcpy(copyto,
-                       priv->start + start_addr_lowbits,
-                       len);
-                copyto += len;
-        } else {
-                /* We have to do multiple writes to get all the data
-                   written. */
-                memcpy(copyto,
-                       priv->start + start_addr_lowbits,
-                       priv->aperture_size - start_addr_lowbits);
-                copyto += priv->aperture_size - start_addr_lowbits;
-                start_addr_highbits += priv->aperture_size;
-                while (start_addr_highbits != end_addr_highbits) {
-                        pci_write_config_dword ( priv->dev,
-                                                 PMC551_PCI_MEM_MAP0,
-                                                 (priv->mem_map0_base_val
-                                                  | start_addr_highbits));
-                        memcpy(copyto,
-                               priv->start,
-                               priv->aperture_size);
-                        copyto += priv->aperture_size;
-                        start_addr_highbits += priv->aperture_size;
-                        if (start_addr_highbits >= mtd->size) {
-                                /* Make sure we have the right value here. */
-                                priv->curr_mem_map0_val
-                                = (priv->mem_map0_base_val
-                                   | start_addr_highbits);
-                                goto out;
-                        }
-                }
-                priv->curr_mem_map0_val = (priv->mem_map0_base_val
-                                           | start_addr_highbits);
-                pci_write_config_dword ( priv->dev,
-                                         PMC551_PCI_MEM_MAP0,
-                                         priv->curr_mem_map0_val);
-                memcpy(copyto,
-                       priv->start,
-                       end_addr_lowbits);
-                copyto += end_addr_lowbits;
-        }
-
-out:
-        *retlen = copyto - buf;
-        return 0;
-}
-
-static int pmc551_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
-{
-        struct mypriv *priv = (struct mypriv *)mtd->priv;
-        u32 start_addr_highbits;
-        u32 end_addr_highbits;
-        u32 start_addr_lowbits;
-        u32 end_addr_lowbits;
-        unsigned long end;
-        const u_char *copyfrom = buf;
-
-
-        /* Is it past the end? */
-        if (to > mtd->size) {
-                return -EINVAL;
-        }
-
-        end = to + len;
-        start_addr_highbits = to & PMC551_ADDR_HIGH_MASK;
-        end_addr_highbits = end & PMC551_ADDR_HIGH_MASK;
-        start_addr_lowbits = to & PMC551_ADDR_LOW_MASK;
-        end_addr_lowbits = end & PMC551_ADDR_LOW_MASK;
-
-
-        /* Only rewrite the first value if it doesn't match our current
-           values.  Most operations are on the same page as the previous
-           value, so this is a pretty good optimization. */
-        if (priv->curr_mem_map0_val !=
-                        (priv->mem_map0_base_val | start_addr_highbits)) {
-                priv->curr_mem_map0_val = (priv->mem_map0_base_val
-                                           | start_addr_highbits);
-                pci_write_config_dword ( priv->dev,
-                                         PMC551_PCI_MEM_MAP0,
-                                         priv->curr_mem_map0_val);
-        }
-
-        if (start_addr_highbits == end_addr_highbits) {
-                /* The whole thing fits within one access, so just one shot
-                   will do it. */
-                memcpy(priv->start + start_addr_lowbits,
-                       copyfrom,
-                       len);
-                copyfrom += len;
-        } else {
-                /* We have to do multiple writes to get all the data
-                   written. */
-                memcpy(priv->start + start_addr_lowbits,
-                       copyfrom,
-                       priv->aperture_size - start_addr_lowbits);
-                copyfrom += priv->aperture_size - start_addr_lowbits;
-                start_addr_highbits += priv->aperture_size;
-                while (start_addr_highbits != end_addr_highbits) {
-                        pci_write_config_dword ( priv->dev,
-                                                 PMC551_PCI_MEM_MAP0,
-                                                 (priv->mem_map0_base_val
-                                                  | start_addr_highbits));
-                        memcpy(priv->start,
-                               copyfrom,
-                               priv->aperture_size);
-                        copyfrom += priv->aperture_size;
-                        start_addr_highbits += priv->aperture_size;
-                        if (start_addr_highbits >= mtd->size) {
-                                /* Make sure we have the right value here. */
-                                priv->curr_mem_map0_val
-                                = (priv->mem_map0_base_val
-                                   | start_addr_highbits);
-                                goto out;
-                        }
-                }
-                priv->curr_mem_map0_val = (priv->mem_map0_base_val
-                                           | start_addr_highbits);
-                pci_write_config_dword ( priv->dev,
-                                         PMC551_PCI_MEM_MAP0,
-                                         priv->curr_mem_map0_val);
-                memcpy(priv->start,
-                       copyfrom,
-                       end_addr_lowbits);
-                copyfrom += end_addr_lowbits;
-        }
-
-out:
-        *retlen = copyfrom - buf;
-        return 0;
-}
-
-/*
- * Fixup routines for the V370PDC
- * PCI device ID 0x020011b0
- *
- * This function basicly kick starts the DRAM oboard the card and gets it
- * ready to be used.  Before this is done the device reads VERY erratic, so
- * much that it can crash the Linux 2.2.x series kernels when a user cat's
- * /proc/pci .. though that is mainly a kernel bug in handling the PCI DEVSEL
- * register.  FIXME: stop spinning on registers .. must implement a timeout
- * mechanism
- * returns the size of the memory region found.
- */
-static u32 fixup_pmc551 (struct pci_dev *dev)
-{
-#ifdef CONFIG_MTD_PMC551_BUGFIX
-        u32 dram_data;
-#endif
-        u32 size, dcmd, cfg, dtmp;
-        u16 cmd, tmp, i;
-	u8 bcmd, counter;
-
-        /* Sanity Check */
-        if(!dev) {
-                return -ENODEV;
-        }
-
-	/*
-	 * Attempt to reset the card
-	 * FIXME: Stop Spinning registers
-	 */
-	counter=0;
-	/* unlock registers */
-	pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, 0xA5 );
-	/* read in old data */
-	pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd );
-	/* bang the reset line up and down for a few */
-	for(i=0;i<10;i++) {
-		counter=0;
-		bcmd &= ~0x80;
-		while(counter++ < 100) {
-			pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd);
-		}
-		counter=0;
-		bcmd |= 0x80;
-		while(counter++ < 100) {
-			pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd);
-		}
-	}
-	bcmd |= (0x40|0x20);
-	pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd);
-
-        /* 
-	 * Take care and turn off the memory on the device while we
-	 * tweak the configurations
-	 */
-        pci_read_config_word(dev, PCI_COMMAND, &cmd);
-        tmp = cmd & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY);
-        pci_write_config_word(dev, PCI_COMMAND, tmp);
-
-	/*
-	 * Disable existing aperture before probing memory size
-	 */
-	pci_read_config_dword(dev, PMC551_PCI_MEM_MAP0, &dcmd);
-        dtmp=(dcmd|PMC551_PCI_MEM_MAP_ENABLE|PMC551_PCI_MEM_MAP_REG_EN);
-	pci_write_config_dword(dev, PMC551_PCI_MEM_MAP0, dtmp);
-	/*
-	 * Grab old BAR0 config so that we can figure out memory size
-	 * This is another bit of kludge going on.  The reason for the
-	 * redundancy is I am hoping to retain the original configuration
-	 * previously assigned to the card by the BIOS or some previous 
-	 * fixup routine in the kernel.  So we read the old config into cfg,
-	 * then write all 1's to the memory space, read back the result into
-	 * "size", and then write back all the old config.
-	 */
-	pci_read_config_dword( dev, PCI_BASE_ADDRESS_0, &cfg );
-#ifndef CONFIG_MTD_PMC551_BUGFIX
-	pci_write_config_dword( dev, PCI_BASE_ADDRESS_0, ~0 );
-	pci_read_config_dword( dev, PCI_BASE_ADDRESS_0, &size );
-	pci_write_config_dword( dev, PCI_BASE_ADDRESS_0, cfg );
-	size=~(size&PCI_BASE_ADDRESS_MEM_MASK)+1;
-#else
-        /*
-         * Get the size of the memory by reading all the DRAM size values
-         * and adding them up.
-         *
-         * KLUDGE ALERT: the boards we are using have invalid column and
-         * row mux values.  We fix them here, but this will break other
-         * memory configurations.
-         */
-        pci_read_config_dword(dev, PMC551_DRAM_BLK0, &dram_data);
-        size = PMC551_DRAM_BLK_GET_SIZE(dram_data);
-        dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
-        dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
-        pci_write_config_dword(dev, PMC551_DRAM_BLK0, dram_data);
-
-        pci_read_config_dword(dev, PMC551_DRAM_BLK1, &dram_data);
-        size += PMC551_DRAM_BLK_GET_SIZE(dram_data);
-        dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
-        dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
-        pci_write_config_dword(dev, PMC551_DRAM_BLK1, dram_data);
-
-        pci_read_config_dword(dev, PMC551_DRAM_BLK2, &dram_data);
-        size += PMC551_DRAM_BLK_GET_SIZE(dram_data);
-        dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
-        dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
-        pci_write_config_dword(dev, PMC551_DRAM_BLK2, dram_data);
-
-        pci_read_config_dword(dev, PMC551_DRAM_BLK3, &dram_data);
-        size += PMC551_DRAM_BLK_GET_SIZE(dram_data);
-        dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
-        dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
-        pci_write_config_dword(dev, PMC551_DRAM_BLK3, dram_data);
-
-        /*
-         * Oops .. something went wrong
-         */
-        if( (size &= PCI_BASE_ADDRESS_MEM_MASK) == 0) {
-                return -ENODEV;
-        }
-#endif /* CONFIG_MTD_PMC551_BUGFIX */
-
-	if ((cfg&PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY) {
-                return -ENODEV;
-	}
-
-        /*
-         * Precharge Dram
-         */
-        pci_write_config_word( dev, PMC551_SDRAM_MA, 0x0400 );
-        pci_write_config_word( dev, PMC551_SDRAM_CMD, 0x00bf );
-
-        /*
-         * Wait until command has gone through
-         * FIXME: register spinning issue
-         */
-        do {	pci_read_config_word( dev, PMC551_SDRAM_CMD, &cmd );
-		if(counter++ > 100)break;
-        } while ( (PCI_COMMAND_IO) & cmd );
-
-        /*
-	 * Turn on auto refresh 
-	 * The loop is taken directly from Ramix's example code.  I assume that
-	 * this must be held high for some duration of time, but I can find no
-	 * documentation refrencing the reasons why.
-	 * 
-         */
-        for ( i = 1; i<=8 ; i++) {
-                pci_write_config_word (dev, PMC551_SDRAM_CMD, 0x0df);
-
-                /*
-                 * Make certain command has gone through
-                 * FIXME: register spinning issue
-                 */
-		counter=0;
-                do {	pci_read_config_word(dev, PMC551_SDRAM_CMD, &cmd);
-			if(counter++ > 100)break;
-                } while ( (PCI_COMMAND_IO) & cmd );
-        }
-
-        pci_write_config_word ( dev, PMC551_SDRAM_MA, 0x0020);
-        pci_write_config_word ( dev, PMC551_SDRAM_CMD, 0x0ff);
-
-        /*
-         * Wait until command completes
-         * FIXME: register spinning issue
-         */
-	counter=0;
-        do {	pci_read_config_word ( dev, PMC551_SDRAM_CMD, &cmd);
-		if(counter++ > 100)break;
-        } while ( (PCI_COMMAND_IO) & cmd );
-
-        pci_read_config_dword ( dev, PMC551_DRAM_CFG, &dcmd);
-        dcmd |= 0x02000000;
-        pci_write_config_dword ( dev, PMC551_DRAM_CFG, dcmd);
-
-        /*
-         * Check to make certain fast back-to-back, if not
-         * then set it so
-         */
-        pci_read_config_word( dev, PCI_STATUS, &cmd);
-        if((cmd&PCI_COMMAND_FAST_BACK) == 0) {
-                cmd |= PCI_COMMAND_FAST_BACK;
-                pci_write_config_word( dev, PCI_STATUS, cmd);
-        }
-
-        /*
-         * Check to make certain the DEVSEL is set correctly, this device
-         * has a tendancy to assert DEVSEL and TRDY when a write is performed
-         * to the memory when memory is read-only
-         */
-        if((cmd&PCI_STATUS_DEVSEL_MASK) != 0x0) {
-                cmd &= ~PCI_STATUS_DEVSEL_MASK;
-                pci_write_config_word( dev, PCI_STATUS, cmd );
-        }
-        /*
-         * Set to be prefetchable and put everything back based on old cfg.
-	 * it's possible that the reset of the V370PDC nuked the original
-	 * settup
-         */
-        cfg |= PCI_BASE_ADDRESS_MEM_PREFETCH;
-	pci_write_config_dword( dev, PCI_BASE_ADDRESS_0, cfg );
-
-        /*
-         * Turn PCI memory and I/O bus access back on
-         */
-        pci_write_config_word( dev, PCI_COMMAND,
-                               PCI_COMMAND_MEMORY | PCI_COMMAND_IO );
-#ifdef CONFIG_MTD_PMC551_DEBUG
-        /*
-         * Some screen fun
-         */
-        printk(KERN_DEBUG "pmc551: %d%c (0x%x) of %sprefetchable memory at 0x%lx\n",
-	       (size<1024)?size:(size<1048576)?size/1024:size/1024/1024,
-               (size<1024)?'B':(size<1048576)?'K':'M',
-	       size, ((dcmd&(0x1<<3)) == 0)?"non-":"",
-               PCI_BASE_ADDRESS(dev)&PCI_BASE_ADDRESS_MEM_MASK );
-
-        /*
-         * Check to see the state of the memory
-         */
-        pci_read_config_dword( dev, PMC551_DRAM_BLK0, &dcmd );
-        printk(KERN_DEBUG "pmc551: DRAM_BLK0 Flags: %s,%s\n"
-			  "pmc551: DRAM_BLK0 Size: %d at %d\n"
-			  "pmc551: DRAM_BLK0 Row MUX: %d, Col MUX: %d\n",
-               (((0x1<<1)&dcmd) == 0)?"RW":"RO",
-               (((0x1<<0)&dcmd) == 0)?"Off":"On",
-	       PMC551_DRAM_BLK_GET_SIZE(dcmd),
-	       ((dcmd>>20)&0x7FF), ((dcmd>>13)&0x7), ((dcmd>>9)&0xF) );
-
-        pci_read_config_dword( dev, PMC551_DRAM_BLK1, &dcmd );
-        printk(KERN_DEBUG "pmc551: DRAM_BLK1 Flags: %s,%s\n"
-			  "pmc551: DRAM_BLK1 Size: %d at %d\n"
-			  "pmc551: DRAM_BLK1 Row MUX: %d, Col MUX: %d\n",
-               (((0x1<<1)&dcmd) == 0)?"RW":"RO",
-               (((0x1<<0)&dcmd) == 0)?"Off":"On",
-	       PMC551_DRAM_BLK_GET_SIZE(dcmd),
-	       ((dcmd>>20)&0x7FF), ((dcmd>>13)&0x7), ((dcmd>>9)&0xF) );
-
-        pci_read_config_dword( dev, PMC551_DRAM_BLK2, &dcmd );
-        printk(KERN_DEBUG "pmc551: DRAM_BLK2 Flags: %s,%s\n"
-			  "pmc551: DRAM_BLK2 Size: %d at %d\n"
-			  "pmc551: DRAM_BLK2 Row MUX: %d, Col MUX: %d\n",
-               (((0x1<<1)&dcmd) == 0)?"RW":"RO",
-               (((0x1<<0)&dcmd) == 0)?"Off":"On",
-	       PMC551_DRAM_BLK_GET_SIZE(dcmd),
-	       ((dcmd>>20)&0x7FF), ((dcmd>>13)&0x7), ((dcmd>>9)&0xF) );
-
-        pci_read_config_dword( dev, PMC551_DRAM_BLK3, &dcmd );
-        printk(KERN_DEBUG "pmc551: DRAM_BLK3 Flags: %s,%s\n"
-			  "pmc551: DRAM_BLK3 Size: %d at %d\n"
-			  "pmc551: DRAM_BLK3 Row MUX: %d, Col MUX: %d\n",
-               (((0x1<<1)&dcmd) == 0)?"RW":"RO",
-               (((0x1<<0)&dcmd) == 0)?"Off":"On",
-	       PMC551_DRAM_BLK_GET_SIZE(dcmd),
-	       ((dcmd>>20)&0x7FF), ((dcmd>>13)&0x7), ((dcmd>>9)&0xF) );
-
-        pci_read_config_word( dev, PCI_COMMAND, &cmd );
-        printk( KERN_DEBUG "pmc551: Memory Access %s\n",
-                (((0x1<<1)&cmd) == 0)?"off":"on" );
-        printk( KERN_DEBUG "pmc551: I/O Access %s\n",
-                (((0x1<<0)&cmd) == 0)?"off":"on" );
-
-        pci_read_config_word( dev, PCI_STATUS, &cmd );
-        printk( KERN_DEBUG "pmc551: Devsel %s\n",
-                ((PCI_STATUS_DEVSEL_MASK&cmd)==0x000)?"Fast":
-                ((PCI_STATUS_DEVSEL_MASK&cmd)==0x200)?"Medium":
-                ((PCI_STATUS_DEVSEL_MASK&cmd)==0x400)?"Slow":"Invalid" );
-
-        printk( KERN_DEBUG "pmc551: %sFast Back-to-Back\n",
-                ((PCI_COMMAND_FAST_BACK&cmd) == 0)?"Not ":"" );
-
-	pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd );
-	printk( KERN_DEBUG "pmc551: EEPROM is under %s control\n"
-			   "pmc551: System Control Register is %slocked to PCI access\n"
-			   "pmc551: System Control Register is %slocked to EEPROM access\n", 
-		(bcmd&0x1)?"software":"hardware",
-		(bcmd&0x20)?"":"un", (bcmd&0x40)?"":"un");
-#endif
-        return size;
-}
-
-/*
- * Kernel version specific module stuffages
- */
-#if LINUX_VERSION_CODE < 0x20211
-#ifdef MODULE
-#define init_pmc551 init_module
-#define cleanup_pmc551 cleanup_module
-#endif
-#define __exit
-#endif
-
-#if defined(MODULE)
-MODULE_AUTHOR("Mark Ferrell <mferrell@mvista.com>");
-MODULE_DESCRIPTION(PMC551_VERSION);
-MODULE_PARM(msize, "i");
-MODULE_PARM_DESC(msize, "memory size, 6=32M, 7=64M, 8=128M, ect.. [32M-1024M]");
-MODULE_PARM(asize, "i");
-MODULE_PARM_DESC(asize, "aperture size, must be <= memsize [1M-1024M]");
-#endif
-/*
- * Stuff these outside the ifdef so as to not bust compiled in driver support
- */
-static int msize=0;
-#if defined(CONFIG_MTD_PMC551_APERTURE_SIZE)
-static int asize=CONFIG_MTD_PMC551_APERTURE_SIZE
-#else
-static int asize=0;
-#endif
-
-/*
- * PMC551 Card Initialization
- */
-int __init init_pmc551(void)
-{
-        struct pci_dev *PCI_Device = NULL;
-        struct mypriv *priv;
-        int count, found=0;
-        struct mtd_info *mtd;
-        u32 length = 0;
-
-	if(msize) {
-		if (msize < 6 || msize > 11 ) {
-			printk(KERN_NOTICE "pmc551: Invalid memory size\n");
-			return -ENODEV;
-		}
-		msize = (512*1024)<<msize;
-	}
-
-	if(asize) {
-		if (asize < 1 || asize > 11 ) {
-			printk(KERN_NOTICE "pmc551: Invalid aperture size\n");
-			return -ENODEV;
-		}
-		asize = (512*1024)<<asize;
-	}
-
-        printk(KERN_INFO PMC551_VERSION);
-
-        if(!pci_present()) {
-                printk(KERN_NOTICE "pmc551: PCI not enabled.\n");
-                return -ENODEV;
-        }
-
-        /*
-         * PCU-bus chipset probe.
-         */
-        for( count = 0; count < MAX_MTD_DEVICES; count++ ) {
-
-                if ( (PCI_Device = pci_find_device( PCI_VENDOR_ID_V3_SEMI,
-                                                    PCI_DEVICE_ID_V3_SEMI_V370PDC, PCI_Device ) ) == NULL) {
-                        break;
-                }
-
-                printk(KERN_NOTICE "pmc551: Found PCI V370PDC IRQ:%d\n",
-                       PCI_Device->irq);
-
-                /*
-                 * The PMC551 device acts VERY weird if you don't init it
-                 * first.  i.e. it will not correctly report devsel.  If for
-                 * some reason the sdram is in a wrote-protected state the
-                 * device will DEVSEL when it is written to causing problems
-                 * with the oldproc.c driver in
-                 * some kernels (2.2.*)
-                 */
-                if((length = fixup_pmc551(PCI_Device)) <= 0) {
-                        printk(KERN_NOTICE "pmc551: Cannot init SDRAM\n");
-                        break;
-                }
-		if(msize) {
-			length = msize;
-			printk(KERN_NOTICE "pmc551: Using specified memory size 0x%x\n", length);
-		}
-
-                mtd = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
-                if (!mtd) {
-                        printk(KERN_NOTICE "pmc551: Cannot allocate new MTD device.\n");
-                        break;
-                }
-
-                memset(mtd, 0, sizeof(struct mtd_info));
-
-                priv = kmalloc (sizeof(struct mypriv), GFP_KERNEL);
-                if (!priv) {
-                        printk(KERN_NOTICE "pmc551: Cannot allocate new MTD device.\n");
-                        kfree(mtd);
-                        break;
-                }
-                memset(priv, 0, sizeof(*priv));
-                mtd->priv = priv;
-
-                priv->dev = PCI_Device;
-		if(asize) {
-			if(asize > length) {
-				asize=length;
-				printk(KERN_NOTICE "pmc551: reducing aperture size to fit memory [0x%x]\n",asize);
-			} else {
-				printk(KERN_NOTICE "pmc551: Using specified aperture size 0x%x\n", asize);
-			}
-			priv->aperture_size = asize;
-		} else {
-                	priv->aperture_size = length;
-		}
-                priv->start = ioremap((PCI_BASE_ADDRESS(PCI_Device)
-                                       & PCI_BASE_ADDRESS_MEM_MASK),
-                                      priv->aperture_size);
-		
-		/*
-		 * Due to the dynamic nature of the code, we need to figure
-		 * this out in order to stuff the register to set the proper
-		 * aperture size.  If you know of an easier way to do this then
-		 * PLEASE help yourself.
-		 *
-		 * Not with bloody floating point, you don't. Consider yourself
-		 * duly LARTed. dwmw2.
-		 */
-		{
-			u32 size;
-			u16 bits;
-			size = priv->aperture_size>>20;
-			for(bits=0;!(size&0x01)&&size>0;bits++,size=size>>1);
-			//size=((u32)((log10(priv->aperture_size)/.30103)-19)<<4);
-                	priv->mem_map0_base_val = (PMC551_PCI_MEM_MAP_REG_EN
-						| PMC551_PCI_MEM_MAP_ENABLE
-						| size);
-#ifdef CONFIG_MTD_PMC551_DEBUG
-			printk(KERN_NOTICE "pmc551: aperture set to %d[%d]\n", 
-					size, size>>4);
-#endif
-		}
-                priv->curr_mem_map0_val = priv->mem_map0_base_val;
-
-                pci_write_config_dword ( priv->dev,
-                                         PMC551_PCI_MEM_MAP0,
-                                         priv->curr_mem_map0_val);
-
-                mtd->size 		= length;
-                mtd->flags 		= (MTD_CLEAR_BITS
-                                | MTD_SET_BITS
-                                | MTD_WRITEB_WRITEABLE
-                                | MTD_VOLATILE);
-                mtd->erase 		= pmc551_erase;
-                mtd->point 		= NULL;
-                mtd->unpoint 		= pmc551_unpoint;
-                mtd->read 		= pmc551_read;
-                mtd->write 		= pmc551_write;
-                mtd->module 		= THIS_MODULE;
-                mtd->type 		= MTD_RAM;
-                mtd->name 		= "PMC551 RAM board";
-                mtd->erasesize 		= 0x10000;
-
-                if (add_mtd_device(mtd)) {
-                        printk(KERN_NOTICE "pmc551: Failed to register new device\n");
-			iounmap(priv->start);
-                        kfree(mtd->priv);
-                        kfree(mtd);
-                        break;
-                }
-                printk(KERN_NOTICE "Registered pmc551 memory device.\n");
-                printk(KERN_NOTICE "Mapped %dM of memory from 0x%p to 0x%p\n",
-                       priv->aperture_size/1024/1024,
-                       priv->start,
-                       priv->start + priv->aperture_size);
-                printk(KERN_NOTICE "Total memory is %d%c\n",
-	       		(length<1024)?length:
-				(length<1048576)?length/1024:length/1024/1024,
-               		(length<1024)?'B':(length<1048576)?'K':'M');
-		priv->nextpmc551 = pmc551list;
-		pmc551list = mtd;
-		found++;
-        }
-
-        if( !pmc551list ) {
-                printk(KERN_NOTICE "pmc551: not detected,\n");
-                return -ENODEV;
-        } else {
-		printk(KERN_NOTICE "pmc551: %d pmc551 devices loaded\n", found);
-                return 0;
-	}
-}
-
-/*
- * PMC551 Card Cleanup
- */
-static void __exit cleanup_pmc551(void)
-{
-        int found=0;
-        struct mtd_info *mtd;
-	struct mypriv *priv;
-
-	while((mtd=pmc551list)) {
-		priv = (struct mypriv *)mtd->priv;
-		pmc551list = priv->nextpmc551;
-		
-		if(priv->start)
-			iounmap(((struct mypriv *)mtd->priv)->start);
-		
-		kfree (mtd->priv);
-		del_mtd_device(mtd);
-		kfree(mtd);
-		found++;
-	}
-
-	printk(KERN_NOTICE "pmc551: %d pmc551 devices unloaded\n", found);
-}
-
-#if LINUX_VERSION_CODE >= 0x20211
-module_init(init_pmc551);
-module_exit(cleanup_pmc551);
-#endif
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/pnc2000.c linux/drivers/mtd/pnc2000.c
--- v2.4.5/linux/drivers/mtd/pnc2000.c	Mon Dec 11 14:57:58 2000
+++ linux/drivers/mtd/pnc2000.c	Wed Dec 31 16:00:00 1969
@@ -1,136 +0,0 @@
-/*
- *	pnc2000.c - mapper for Photron PNC-2000 board.
- *
- * Copyright (C) 2000 Crossnet Co. <info@crossnet.co.jp>
- *
- * This code is GPL
- *
- * $Id: pnc2000.c,v 1.4 2000/11/27 08:50:22 dwmw2 Exp $
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-
-#define WINDOW_ADDR 0xbf000000
-#define WINDOW_SIZE 0x00400000
-
-/* 
- * MAP DRIVER STUFF
- */
-
-__u8 pnc_read8(struct map_info *map, unsigned long ofs)
-{
-  return *(__u8 *)(WINDOW_ADDR + ofs);
-}
-
-__u16 pnc_read16(struct map_info *map, unsigned long ofs)
-{
-  return *(__u16 *)(WINDOW_ADDR + ofs);
-}
-
-__u32 pnc_read32(struct map_info *map, unsigned long ofs)
-{
-  return *(volatile unsigned int *)(WINDOW_ADDR + ofs);
-}
-
-void pnc_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-{
-  memcpy(to, (void *)(WINDOW_ADDR + from), len);
-}
-
-void pnc_write8(struct map_info *map, __u8 d, unsigned long adr)
-{
-  *(__u8 *)(WINDOW_ADDR + adr) = d;
-}
-
-void pnc_write16(struct map_info *map, __u16 d, unsigned long adr)
-{
-  *(__u16 *)(WINDOW_ADDR + adr) = d;
-}
-
-void pnc_write32(struct map_info *map, __u32 d, unsigned long adr)
-{
-  *(__u32 *)(WINDOW_ADDR + adr) = d;
-}
-
-void pnc_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-{
-  memcpy((void *)(WINDOW_ADDR + to), from, len);
-}
-
-struct map_info pnc_map = {
-	name: "PNC-2000",
-	size: WINDOW_SIZE,
-	buswidth: 4,
-	read8: pnc_read8,
-	read16: pnc_read16,
-	read32: pnc_read32,
-	copy_from: pnc_copy_from,
-	write8: pnc_write8,
-	write16: pnc_write16,
-	write32: pnc_write32,
-	copy_to: pnc_copy_to
-};
-
-
-/*
- * MTD 'PARTITIONING' STUFF 
- */
-static struct mtd_partition pnc_partitions[3] = {
-	{
-		name: "PNC-2000 boot firmware",
-		size: 0x20000,
-		offset: 0
-	},
-	{
-		name: "PNC-2000 kernel",
-		size: 0x1a0000,
-		offset: 0x20000
-	},
-	{
-		name: "PNC-2000 filesystem",
-		size: 0x240000,
-		offset: 0x1c0000
-	}
-};
-
-/* 
- * This is the master MTD device for which all the others are just
- * auto-relocating aliases.
- */
-static struct mtd_info *mymtd;
-
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_pnc init_module
-#define cleanup_pnc cleanup_module
-#endif
-
-int __init init_pnc(void)
-{
-	printk(KERN_NOTICE "Photron PNC-2000 flash mapping: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
-
-	mymtd = do_cfi_probe(&pnc_map);
-	if (mymtd) {
-		mymtd->module = THIS_MODULE;
-		return add_mtd_partitions(mymtd, pnc_partitions, 3);
-	}
-
-	return -ENXIO;
-}
-
-static void __exit cleanup_pnc(void)
-{
-	if (mymtd) {
-		del_mtd_partitions(mymtd);
-		map_destroy(mymtd);
-	}
-}
-
-module_init(init_pnc);
-module_exit(cleanup_pnc);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/redboot.c linux/drivers/mtd/redboot.c
--- v2.4.5/linux/drivers/mtd/redboot.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/redboot.c	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,150 @@
+/*
+ * $Id: redboot.c,v 1.4 2001/05/31 20:43:18 dwmw2 Exp $
+ *
+ * Parse RedBoot-style Flash Image System (FIS) tables and
+ * produce a Linux partition array to match.
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+struct fis_image_desc {
+    unsigned char name[16];      // Null terminated name
+    unsigned long flash_base;    // Address within FLASH of image
+    unsigned long mem_base;      // Address in memory where it executes
+    unsigned long size;          // Length of image
+    unsigned long entry_point;   // Execution entry point
+    unsigned long data_length;   // Length of actual data
+    unsigned char _pad[256-(16+7*sizeof(unsigned long))];
+    unsigned long desc_cksum;    // Checksum over image descriptor
+    unsigned long file_cksum;    // Checksum over image data
+};
+
+struct fis_list {
+	struct fis_image_desc *img;
+	struct fis_list *next;
+};
+
+static inline int redboot_checksum(struct fis_image_desc *img)
+{
+	/* RedBoot doesn't actually write the desc_cksum field yet AFAICT */
+	return 1;
+}
+
+int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts)
+{
+	int nrparts = 0;
+	struct fis_image_desc *buf;
+	struct mtd_partition *parts;
+	struct fis_list *fl = NULL, *tmp_fl;
+	int ret, i;
+	size_t retlen;
+	char *names;
+	int namelen = 0;
+
+	buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+
+	if (!buf)
+		return -ENOMEM;
+
+	/* Read the start of the last erase block */
+	ret = master->read(master, master->size - master->erasesize,
+			   PAGE_SIZE, &retlen, (void *)buf);
+
+	if (ret)
+		goto out;
+
+	if (retlen != PAGE_SIZE) {
+		ret = -EIO;
+		goto out;
+	}
+
+	if (memcmp(buf, "RedBoot", 8)) {
+		ret = 0;
+		goto out;
+	}
+
+	for (i = 0; i < PAGE_SIZE / sizeof(struct fis_image_desc); i++) {
+		struct fis_list *new_fl, **prev;
+
+		if (buf[i].name[0] == 0xff)
+			break;
+		if (!redboot_checksum(&buf[i]))
+			break;
+
+		new_fl = kmalloc(sizeof(struct fis_list), GFP_KERNEL);
+		namelen += strlen(buf[i].name)+1;
+		if (!new_fl) {
+			ret = -ENOMEM;
+			goto out;
+		}
+		new_fl->img = &buf[i];
+		buf[i].flash_base &= master->size-1;
+
+		/* I'm sure the JFFS2 code has done me permanent damage.
+		 * I now think the following is _normal_
+		 */
+		prev = &fl;
+		while(*prev && (*prev)->img->flash_base < new_fl->img->flash_base)
+			prev = &(*prev)->next;
+		new_fl->next = *prev;
+		*prev = new_fl;
+
+		nrparts++;
+	}
+	if (fl->img->flash_base)
+		nrparts++;
+
+	for (tmp_fl = fl; tmp_fl->next; tmp_fl = tmp_fl->next) {
+		if (tmp_fl->img->flash_base + tmp_fl->img->size + master->erasesize < tmp_fl->next->img->flash_base)
+			nrparts++;
+	}
+	parts = kmalloc(sizeof(*parts)*nrparts + namelen, GFP_KERNEL);
+
+	if (!parts) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	names = (char *)&parts[nrparts];
+	memset(parts, 0, sizeof(*parts)*nrparts + namelen);
+	i=0;
+
+	if (fl->img->flash_base) {
+	       parts[0].name = "unallocated space";
+	       parts[0].size = fl->img->flash_base;
+	       parts[0].offset = 0;
+	}
+	for ( ; i<nrparts; i++) {
+		parts[i].size = fl->img->size;
+		parts[i].offset = fl->img->flash_base;
+		parts[i].name = names;
+
+		strcpy(names, fl->img->name);
+		names += strlen(names)+1;
+
+		if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize < fl->next->img->flash_base) {
+			i++;
+			parts[i].offset = parts[i-1].size + parts[i-1].offset;
+			parts[i].size = fl->next->img->flash_base - parts[i].offset;
+			parts[i].name = "unallocated space";
+		}
+		tmp_fl = fl;
+		fl = fl->next;
+		kfree(tmp_fl);
+	}
+	ret = nrparts;
+	*pparts = parts;
+ out:
+	while (fl) {
+		struct fis_list *old = fl;
+		fl = fl->next;
+		kfree(old);
+	}
+	kfree(buf);
+	return ret;
+}
+
+EXPORT_SYMBOL(parse_redboot_partitions);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/rpxlite.c linux/drivers/mtd/rpxlite.c
--- v2.4.5/linux/drivers/mtd/rpxlite.c	Sun Feb  4 10:05:30 2001
+++ linux/drivers/mtd/rpxlite.c	Wed Dec 31 16:00:00 1969
@@ -1,114 +0,0 @@
-/*
- * $Id: rpxlite.c,v 1.8 2000/12/09 22:00:31 dwmw2 Exp $
- *
- * Handle mapping of the flash on the RPX Lite and CLLF boards
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <asm/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-
-
-#define WINDOW_ADDR 0xfe000000
-#define WINDOW_SIZE 0x800000
-
-static struct mtd_info *mymtd;
-
-__u8 rpxlite_read8(struct map_info *map, unsigned long ofs)
-{
-	return readb(map->map_priv_1 * ofs);
-}
-
-__u16 rpxlite_read16(struct map_info *map, unsigned long ofs)
-{
-	return readw(map->map_priv_1 + ofs);
-}
-
-__u32 rpxlite_read32(struct map_info *map, unsigned long ofs)
-{
-	return readl(map->map_priv_1 + ofs);
-}
-
-void rpxlite_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-{
-	memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
-}
-
-void rpxlite_write8(struct map_info *map, __u8 d, unsigned long adr)
-{
-	writeb(d, map->map_priv_1 + adr);
-}
-
-void rpxlite_write16(struct map_info *map, __u16 d, unsigned long adr)
-{
-	writew(d, map->map_priv_1 + adr);
-}
-
-void rpxlite_write32(struct map_info *map, __u32 d, unsigned long adr)
-{
-	writel(d, map->map_priv_1 + adr);
-}
-
-void rpxlite_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-{
-	memcpy_toio((void *)(map->map_priv_1 + to), from, len);
-}
-
-struct map_info rpxlite_map = {
-	name: "RPX",
-	size: WINDOW_SIZE,
-	buswidth: 4,
-	read8: rpxlite_read8,
-	read16: rpxlite_read16,
-	read32: rpxlite_read32,
-	copy_from: rpxlite_copy_from,
-	write8: rpxlite_write8,
-	write16: rpxlite_write16,
-	write32: rpxlite_write32,
-	copy_to: rpxlite_copy_to
-};
-
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_rpxlite init_module
-#define cleanup_rpxlite cleanup_module
-#endif
-
-int __init init_rpxlite(void)
-{
-	printk(KERN_NOTICE "RPX Lite or CLLF flash device: %x at %x\n", WINDOW_SIZE*4, WINDOW_ADDR);
-	rpxlite_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE * 4);
-
-	if (!rpxlite_map.map_priv_1) {
-		printk("Failed to ioremap\n");
-		return -EIO;
-	}
-	mymtd = do_cfi_probe(&rpxlite_map);
-	if (mymtd) {
-#ifdef MODULE
-		mymtd->module = &__this_module;
-#endif
-		add_mtd_device(mymtd);
-		return 0;
-	}
-
-	iounmap((void *)rpxlite_map.map_priv_1);
-	return -ENXIO;
-}
-
-static void __exit cleanup_rpxlite(void)
-{
-	if (mymtd) {
-		del_mtd_device(mymtd);
-		map_destroy(mymtd);
-	}
-	if (rpxlite_map.map_priv_1) {
-		iounmap((void *)rpxlite_map.map_priv_1);
-		rpxlite_map.map_priv_1 = 0;
-	}
-}
-
-module_init(init_rpxlite);
-module_exit(cleanup_rpxlite);
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/slram.c linux/drivers/mtd/slram.c
--- v2.4.5/linux/drivers/mtd/slram.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/slram.c	Wed Dec 31 16:00:00 1969
@@ -1,227 +0,0 @@
-/*======================================================================
-
-  $Id: slram.c,v 1.10 2000/07/03 10:01:38 dwmw2 Exp $
-
-======================================================================*/
-
-
-#include <linux/module.h>
-#include <asm/uaccess.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/major.h>
-#include <linux/fs.h>
-#include <linux/ioctl.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/segment.h>
-#include <stdarg.h>
-
-#include <linux/mtd/mtd.h>
-
-struct mypriv {
-	u_char *start;
-	u_char *end;
-};
-
-int physmem_erase (struct mtd_info *mtd, struct erase_info *instr);
-int physmem_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf);
-void physmem_unpoint (struct mtd_info *mtd, u_char *addr);
-int physmem_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
-int physmem_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
-	
-
-int physmem_erase (struct mtd_info *mtd, struct erase_info *instr)
-{
-	struct mypriv *priv = mtd->priv;
-
-	if (instr->addr + instr->len > mtd->size)
-		return -EINVAL;
-	
-	memset(priv->start + instr->addr, 0xff, instr->len);
-
-	/* This'll catch a few races. Free the thing before returning :) 
-	 * I don't feel at all ashamed. This kind of thing is possible anyway
-	 * with flash, but unlikely.
-	 */
-
-	instr->state = MTD_ERASE_DONE;
-
-	if (instr->callback)
-		(*(instr->callback))(instr);
-	else
-		kfree(instr);
-
-	return 0;
-}
-
-
-int physmem_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf)
-{
-	struct mypriv *priv = (struct mypriv *)mtd->priv;
-
-	*mtdbuf = priv->start + from;
-	*retlen = len;
-	return 0;
-}
-
-void physmem_unpoint (struct mtd_info *mtd, u_char *addr)
-{
-}
-
-int physmem_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
-{
-	struct mypriv *priv = (struct mypriv *)mtd->priv;
-	
-	memcpy (buf, priv->start + from, len);
-
-	*retlen=len;
-	return 0;
-}
-
-int physmem_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
-{
-	struct mypriv *priv = (struct mypriv *)mtd->priv;
-
-	memcpy (priv->start + to, buf, len);
-
-	*retlen=len;
-	return 0;
-}
-
-
-
-
-/*====================================================================*/
-
-/* Place your defaults here */
-
-static u_long start = 100663296;
-static u_long length = 33554432;
-static u_long end = 0;
-
-#if LINUX_VERSION_CODE < 0x20300
-#ifdef MODULE
-#define init_slram init_module
-#define cleanup_slram cleanup_module
-#endif
-#define __exit
-#endif
-
-#ifdef MODULE
-MODULE_PARM(start,"l");
-MODULE_PARM(length,"l");
-MODULE_PARM(end,"l");
-#endif
-
-struct mtd_info *mymtd;
-
-void __init mtd_slram_setup(char *str, int *ints)
-{
-	if (ints[0] > 0)
-		start=ints[1];
-	if (ints[0] > 1)
-		length=ints[2];
-}
-
-int init_slram(void)
-{
-	if (!start)
-	{
-		printk(KERN_NOTICE "physmem: No start address for memory device.\n");
-		return -EINVAL;
-	}
-	
-	if (!length && !end)
-	{
-		printk(KERN_NOTICE "physmem: No length or endpointer given.\n");
-		return -EINVAL;
-	}
-	
-	if (!end)
-		end = start + length;
-	
-	if (!length)
-	  length = end - start;
-
-	if (start + length != end)
-	  {
-	    printk(KERN_NOTICE "physmem: start(%lx) + length(%lx) != end(%lx) !\n",
-		   start, length, end);
-	    return -EINVAL;
-	  }
-
-	mymtd = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
-	
-	memset(mymtd, 0, sizeof(*mymtd));
-	
-	if (mymtd)
-	{
-		memset((char *)mymtd, 0, sizeof(struct mtd_info));
-		mymtd->priv = (void *) kmalloc (sizeof(struct mypriv), GFP_KERNEL);
-		if (!mymtd->priv)
-		{
-			kfree(mymtd);
-			mymtd = NULL;
-		}
-		memset(mymtd->priv, 0, sizeof(struct mypriv));
-	}
-
-	if (!mymtd)
-	{
-		printk(KERN_NOTICE "physmem: Cannot allocate new MTD device.\n");
-		return -ENOMEM;
-	}
-	
-	
-	((struct mypriv *)mymtd->priv)->start = ioremap(start, length);
-	((struct mypriv *)mymtd->priv)->end = ((struct mypriv *)mymtd->priv)->start + length;
-
-
-	mymtd->name = "Raw memory";
-
-	mymtd->size = length;
-	mymtd->flags = MTD_CLEAR_BITS | MTD_SET_BITS | MTD_WRITEB_WRITEABLE | MTD_VOLATILE;
-        mymtd->erase = physmem_erase;
-	mymtd->point = physmem_point;
-	mymtd->unpoint = physmem_unpoint;
-	mymtd->read = physmem_read;
-	mymtd->write = physmem_write;
-	mymtd->module = THIS_MODULE;
-	mymtd->type = MTD_RAM;
-	mymtd->erasesize = 0x10000;
-
-	if (add_mtd_device(mymtd))
-	{
-		printk("Failed to register new device\n");
-	        iounmap(((struct mypriv *)mymtd->priv)->start);
-		kfree(mymtd->priv);
-		kfree(mymtd);
-		return -EAGAIN;
-	}
-	printk("Registered physmem device from %dKb to %dKb\n",
-	       (int)(start / 1024), (int)(end / 1024));
-	printk("Mapped from 0x%p to 0x%p\n",((struct mypriv *)mymtd->priv)->start,
-((struct mypriv *)mymtd->priv)->end);
-
-	return 0;
-}
-
-static void __exit cleanup_slram(void)
-{
-	iounmap(((struct mypriv *)mymtd->priv)->start);
-	kfree (mymtd->priv);
-	del_mtd_device(mymtd);
-	kfree(mymtd);
-}
-
-#if LINUX_VERSION_CODE > 0x20300
-module_init(init_slram);
-module_exit(cleanup_slram);
-#endif
diff -u --recursive --new-file v2.4.5/linux/drivers/mtd/vmax301.c linux/drivers/mtd/vmax301.c
--- v2.4.5/linux/drivers/mtd/vmax301.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/vmax301.c	Wed Dec 31 16:00:00 1969
@@ -1,240 +0,0 @@
-// $Id: vmax301.c,v 1.15 2000/11/27 08:50:22 dwmw2 Exp $
-/* ######################################################################
-
-   Tempustech VMAX SBC301 MTD Driver.
-  
-   The VMAx 301 is a SBC based on . It
-   comes with three builtin AMD 29F016B flash chips and a socket for SRAM or
-   more flash. Each unit has it's own 8k mapping into a settable region 
-   (0xD8000). There are two 8k mappings for each MTD, the first is always set
-   to the lower 8k of the device the second is paged. Writing a 16 bit page
-   value to anywhere in the first 8k will cause the second 8k to page around.
-
-   To boot the device a bios extension must be installed into the first 8k 
-   of flash that is smart enough to copy itself down, page in the rest of 
-   itself and begin executing.
-   
-   ##################################################################### */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <asm/spinlock.h>
-#include <asm/io.h>
-
-#include <linux/mtd/map.h>
-
-
-#define WINDOW_START 0xd8000
-#define WINDOW_LENGTH 0x2000
-#define WINDOW_SHIFT 25
-#define WINDOW_MASK 0x1FFF
-
-/* Actually we could use two spinlocks, but we'd have to have
-   more private space in the struct map_info. We lose a little
-   performance like this, but we'd probably lose more by having
-   the extra indirection from having one of the map->map_priv 
-   fields pointing to yet another private struct.
-*/
-static spinlock_t vmax301_spin = SPIN_LOCK_UNLOCKED;
-
-static void __vmax301_page(struct map_info *map, unsigned long page)
-{
-	writew(page, map->map_priv_2 - WINDOW_LENGTH);
-	map->map_priv_1 = page;
-}
-
-static inline void vmax301_page(struct map_info *map,
-				  unsigned long ofs)
-{
-	unsigned long page = (ofs >> WINDOW_SHIFT);
-	if (map->map_priv_1 != page)
-		__vmax301_page(map, page);
-}
-
-static __u8 vmax301_read8(struct map_info *map, unsigned long ofs)
-{
-	__u8 ret;
-	spin_lock(&vmax301_spin);
-	vmax301_page(map, ofs);
-	ret = readb(map->map_priv_2 + (ofs & WINDOW_MASK));
-	spin_unlock(&vmax301_spin);
-	return ret;
-}
-
-static __u16 vmax301_read16(struct map_info *map, unsigned long ofs)
-{
-	__u16 ret;
-	spin_lock(&vmax301_spin);
-	vmax301_page(map, ofs);
-	ret = readw(map->map_priv_2 + (ofs & WINDOW_MASK));
-	spin_unlock(&vmax301_spin);
-	return ret;
-}
-
-static __u32 vmax301_read32(struct map_info *map, unsigned long ofs)
-{
-	__u32 ret;
-	spin_lock(&vmax301_spin);
-	vmax301_page(map, ofs);
-	ret =  readl(map->map_priv_2 + (ofs & WINDOW_MASK));
-	spin_unlock(&vmax301_spin);
-	return ret;
-}
-
-static void vmax301_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-{
-	while(len) {
-		unsigned long thislen = len;
-		if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
-			thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
-		spin_lock(&vmax301_spin);
-		vmax301_page(map, from);
-		memcpy_fromio(to, map->map_priv_2 + from, thislen);
-		spin_unlock(&vmax301_spin);
-		to += thislen;
-		from += thislen;
-		len -= thislen;
-	}
-}
-
-static void vmax301_write8(struct map_info *map, __u8 d, unsigned long adr)
-{
-	spin_lock(&vmax301_spin);
-	vmax301_page(map, adr);
-	writeb(d, map->map_priv_2 + (adr & WINDOW_MASK));
-	spin_unlock(&vmax301_spin);
-}
-
-static void vmax301_write16(struct map_info *map, __u16 d, unsigned long adr)
-{
-	spin_lock(&vmax301_spin);
-	vmax301_page(map, adr);
-	writew(d, map->map_priv_2 + (adr & WINDOW_MASK));
-	spin_unlock(&vmax301_spin);
-}
-
-static void vmax301_write32(struct map_info *map, __u32 d, unsigned long adr)
-{
-	spin_lock(&vmax301_spin);
-	vmax301_page(map, adr);
-	writel(d, map->map_priv_2 + (adr & WINDOW_MASK));
-	spin_unlock(&vmax301_spin);
-}
-
-static void vmax301_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-{
-	while(len) {
-		unsigned long thislen = len;
-		if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
-			thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
-
-		spin_lock(&vmax301_spin);
-		vmax301_page(map, to);
-		memcpy_toio(map->map_priv_2 + to, from, thislen);
-		spin_unlock(&vmax301_spin);		
-		to += thislen;
-		from += thislen;
-		len -= thislen;
-	}
-}
-
-static struct map_info vmax_map[2] = {
-	{
-		name: "VMAX301 Internal Flash",
-		size: 3*2*1024*1024,
-		buswidth: 1,
-		read8: vmax301_read8,
-		read16: vmax301_read16,
-		read32: vmax301_read32,
-		copy_from: vmax301_copy_from,
-		write8: vmax301_write8,
-		write16: vmax301_write16,
-		write32: vmax301_write32,
-		copy_to: vmax301_copy_to,
-		map_priv_1: WINDOW_START + WINDOW_LENGTH,
-		map_priv_2: 0xFFFFFFFF
-	},
-	{
-		name: "VMAX301 Socket",
-		size: 0,
-		buswidth: 1,
-		read8: vmax301_read8,
-		read16: vmax301_read16,
-		read32: vmax301_read32,
-		copy_from: vmax301_copy_from,
-		write8: vmax301_write8,
-		write16: vmax301_write16,
-		write32: vmax301_write32,
-		copy_to: vmax301_copy_to,
-		map_priv_1: WINDOW_START + (3*WINDOW_LENGTH),
-		map_priv_2: 0xFFFFFFFF
-	}
-};
-
-static struct mtd_info *vmax_mtd[2] = {NULL, NULL};
-
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_vmax301 init_module
-#define cleanup_vmax301 cleanup_module
-#endif
-
-static void __exit cleanup_vmax301(void)
-{
-	int i;
-	
-	for (i=0; i<2; i++) {
-		if (vmax_mtd[i]) {
-			del_mtd_device(vmax_mtd[i]);
-			map_destroy(vmax_mtd[i]);
-		}
-	}
-	iounmap((void *)vmax_map[0].map_priv_1 - WINDOW_START);
-}
-
-int __init init_vmax301(void)
-{
-	int i;
-	unsigned long iomapadr;
-	// Print out our little header..
-	printk("Tempustech VMAX 301 MEM:0x%x-0x%x\n",WINDOW_START,
-	       WINDOW_START+4*WINDOW_LENGTH);
-
-	iomapadr = (unsigned long)ioremap(WINDOW_START, WINDOW_LENGTH*4);
-	if (!iomapadr) {
-		printk("Failed to ioremap memory region\n");
-		return -EIO;
-	}
-	/* Put the address in the map's private data area.
-	   We store the actual MTD IO address rather than the 
-	   address of the first half, because it's used more
-	   often. 
-	*/
-	vmax_map[0].map_priv_1 = iomapadr + WINDOW_START;
-	vmax_map[1].map_priv_1 = iomapadr + (3*WINDOW_START);
-	
-	for (i=0; i<2; i++) {
-		vmax_mtd[i] = do_cfi_probe(&vmax_map[i]);
-		if (!vmax_mtd[i])
-			vmax_mtd[i] = do_jedec_probe(&vmax_map[i]);
-		if (!vmax_mtd[i])
-			vmax_mtd[i] = do_ram_probe(&vmax_map[i]);
-		if (!vmax_mtd[i])
-			vmax_mtd[i] = do_rom_probe(&vmax_map[i]);
-		if (vmax_mtd[i]) {
-			vmax_mtd[i]->module = THIS_MODULE;
-			add_mtd_device(vmax_mtd[i]);
-		}
-	}
-
-	if (!vmax_mtd[1] && !vmax_mtd[2]) {
-		iounmap(iomapadr);
-		return -ENXIO;
-	}
-
-	return 0;
-}
-
-module_init(init_vmax301);
-module_exit(cleanup_vmax301);
diff -u --recursive --new-file v2.4.5/linux/drivers/net/3c501.c linux/drivers/net/3c501.c
--- v2.4.5/linux/drivers/net/3c501.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/3c501.c	Wed Jun 20 11:10:53 2001
@@ -251,7 +251,7 @@
 }
 
 /**
- *	el1_probe: 
+ *	el1_probe1: 
  *	@dev: The device structure to use
  *	@ioaddr: An I/O address to probe at.
  *
@@ -925,6 +925,8 @@
 static int irq=5;
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
+MODULE_PARM_DESC(io, "EtherLink I/O base address");
+MODULE_PARM_DESC(irq, "EtherLink IRQ number");
 
 /**
  * init_module:
diff -u --recursive --new-file v2.4.5/linux/drivers/net/3c503.c linux/drivers/net/3c503.c
--- v2.4.5/linux/drivers/net/3c503.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/3c503.c	Wed Jun 20 11:10:53 2001
@@ -615,6 +615,9 @@
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i");
 MODULE_PARM(xcvr, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i");
+MODULE_PARM_DESC(io, "EtherLink II I/O base address(es)");
+MODULE_PARM_DESC(irq, "EtherLink II IRQ number(s) (assigned)");
+MODULE_PARM_DESC(xcvr, "EtherLink II tranceiver(s) (0=internal, 1=external)");
 
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
diff -u --recursive --new-file v2.4.5/linux/drivers/net/3c505.c linux/drivers/net/3c505.c
--- v2.4.5/linux/drivers/net/3c505.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/3c505.c	Wed Jun 20 11:10:53 2001
@@ -1621,6 +1621,9 @@
 MODULE_PARM(io, "1-" __MODULE_STRING(ELP_MAX_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(ELP_MAX_CARDS) "i");
 MODULE_PARM(dma, "1-" __MODULE_STRING(ELP_MAX_CARDS) "i");
+MODULE_PARM_DESC(io, "EtherLink Plus I/O base address(es)");
+MODULE_PARM_DESC(irq, "EtherLink Plus IRQ number(s) (assigned)");
+MODULE_PARM_DESC(dma, "EtherLink Plus DMA channel(s)");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.4.5/linux/drivers/net/3c507.c linux/drivers/net/3c507.c
--- v2.4.5/linux/drivers/net/3c507.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/3c507.c	Wed Jun 20 11:10:53 2001
@@ -861,6 +861,8 @@
 static int irq;
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
+MODULE_PARM_DESC(io, "EtherLink16 I/O base address");
+MODULE_PARM_DESC(irq, "(ignored)");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.4.5/linux/drivers/net/3c509.c linux/drivers/net/3c509.c
--- v2.4.5/linux/drivers/net/3c509.c	Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/3c509.c	Wed Jun 27 17:10:55 2001
@@ -192,6 +192,9 @@
 		ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5098),
 		(long) "3Com Etherlink III (TPC)" },
 	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+		ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_FUNCTION(0x80f7),
+		(long) "3Com Etherlink III compatible" },
+	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
 		ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_FUNCTION(0x80f8),
 		(long) "3Com Etherlink III compatible" },
 	{ }	/* terminate list */
@@ -1007,9 +1010,14 @@
 MODULE_PARM(irq,"1-8i");
 MODULE_PARM(xcvr,"1-8i");
 MODULE_PARM(max_interrupt_work, "i");
+MODULE_PARM_DESC(debug, "EtherLink III debug level (0-6)");
+MODULE_PARM_DESC(irq, "EtherLink III IRQ number(s) (assigned)");
+MODULE_PARM_DESC(xcvr,"EtherLink III tranceiver(s) (0=internal, 1=external)");
+MODULE_PARM_DESC(max_interrupt_work, "EtherLink III maximum events handled per interrupt");
 #ifdef CONFIG_ISAPNP
 MODULE_PARM(nopnp, "i");
-#endif
+MODULE_PARM_DESC(nopnp, "EtherLink III disable ISA PnP support (0-1)");
+#endif	/* CONFIG_ISAPNP */
 
 int
 init_module(void)
diff -u --recursive --new-file v2.4.5/linux/drivers/net/3c515.c linux/drivers/net/3c515.c
--- v2.4.5/linux/drivers/net/3c515.c	Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/3c515.c	Wed Jun 20 11:10:53 2001
@@ -85,6 +85,11 @@
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
 MODULE_PARM(rx_copybreak, "i");
 MODULE_PARM(max_interrupt_work, "i");
+MODULE_PARM_DESC(debug, "3c515 debug level (0-6)");
+MODULE_PARM_DESC(options, "3c515: Bits 0-2: media type, bit 3: full duplex, bit 4: bus mastering");
+MODULE_PARM_DESC(full_duplex, "(ignored)");
+MODULE_PARM_DESC(rx_copybreak, "3c515 copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(max_interrupt_work, "3c515 maximum events handled per interrupt");
 
 /* "Knobs" for adjusting internal parameters. */
 /* Put out somewhat more debugging messages. (0 - no msg, 1 minimal msgs). */
diff -u --recursive --new-file v2.4.5/linux/drivers/net/3c523.c linux/drivers/net/3c523.c
--- v2.4.5/linux/drivers/net/3c523.c	Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/3c523.c	Wed Jun 20 11:10:53 2001
@@ -1226,6 +1226,8 @@
 static int io[MAX_3C523_CARDS];
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_3C523_CARDS) "i");
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_3C523_CARDS) "i");
+MODULE_PARM_DESC(io, "EtherLink/MC I/O base address(es)");
+MODULE_PARM_DESC(irq, "EtherLink/MC IRQ number(s)");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.4.5/linux/drivers/net/3c59x.c linux/drivers/net/3c59x.c
--- v2.4.5/linux/drivers/net/3c59x.c	Thu Apr 12 12:16:35 2001
+++ linux/drivers/net/3c59x.c	Wed Jun 20 11:15:44 2001
@@ -142,6 +142,13 @@
     - If a device's internalconfig register reports it has NWAY,
       use it, even if autoselect is enabled.
 
+   LK1.1.15 6 June 2001 akpm
+    - Prevent double counting of received bytes (Lars Christensen)
+    - Add ethtool support (jgarzik)
+    - Add module parm descriptions (Andrzej M. Krzysztofowicz)
+    - Implemented alloc_etherdev() API
+    - Special-case the 'Tx error 82' message.
+
     - See http://www.uow.edu.au/~andrewm/linux/#3c59x-2.3 for more details.
     - Also see Documentation/networking/vortex.txt
 */
@@ -155,6 +162,13 @@
  * elimination of all the tests and reduced cache footprint.
  */
 
+
+#define DRV_NAME	"3c59x"
+#define DRV_VERSION	"LK1.1.15"
+#define DRV_RELDATE	"6 June 2001"
+
+
+
 /* A few values that may be tweaked. */
 /* Keep the ring sizes a power of two for efficiency. */
 #define TX_RING_SIZE	16
@@ -208,9 +222,11 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/ethtool.h>
 #include <asm/irq.h>			/* For NR_IRQS only. */
 #include <asm/bitops.h>
 #include <asm/io.h>
+#include <asm/uaccess.h>
 
 /* Kernel compatibility defines, some common to David Hinds' PCMCIA package.
    This is only in the support-all-kernels source code. */
@@ -219,8 +235,9 @@
 
 #include <linux/delay.h>
 
+
 static char version[] __devinitdata =
-"3c59x.c:LK1.1.13 27 Jan 2001  Donald Becker and others. http://www.scyld.com/network/vortex.html\n";
+DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE "  Donald Becker and others. http://www.scyld.com/network/vortex.html\n";
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("3Com 3c59x/3c90x/3c575 series Vortex/Boomerang/Cyclone driver");
@@ -236,6 +253,18 @@
 MODULE_PARM(compaq_irq, "i");
 MODULE_PARM(compaq_device_id, "i");
 MODULE_PARM(watchdog, "i");
+MODULE_PARM_DESC(debug, "3c59x debug level (0-6)");
+MODULE_PARM_DESC(options, "3c59x: Bits 0-3: media type, bit 4: bus mastering, bit 9: full duplex");
+MODULE_PARM_DESC(full_duplex, "3c59x full duplex setting(s) (1)");
+MODULE_PARM_DESC(hw_checksums, "3c59x Hardware checksum checking by adapter(s) (0-1)");
+MODULE_PARM_DESC(flow_ctrl, "3c59x 802.3x flow control usage (PAUSE only) (0-1)");
+MODULE_PARM_DESC(enable_wol, "3c59x: Turn on Wake-on-LAN for adapter(s) (0-1)");
+MODULE_PARM_DESC(rx_copybreak, "3c59x copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(max_interrupt_work, "3c59x maximum events handled per interrupt");
+MODULE_PARM_DESC(compaq_ioaddr, "3c59x PCI I/O base address (Compaq BIOS problem workaround)");
+MODULE_PARM_DESC(compaq_irq, "3c59x PCI IRQ number (Compaq BIOS problem workaround)");
+MODULE_PARM_DESC(compaq_device_id, "3c59x PCI device ID (Compaq BIOS problem workaround)");
+MODULE_PARM_DESC(watchdog, "3c59x transmit timeout in milliseconds");
 
 /* Operational parameter that usually are not changed. */
 
@@ -251,7 +280,7 @@
    code size of a per-interface flag is not worthwhile. */
 static char mii_preamble_required;
 
-#define PFX "3c59x: "
+#define PFX DRV_NAME ": "
 
 
 
@@ -805,7 +834,9 @@
 
 static int vortex_cards_found;
 
-static void vortex_suspend (struct pci_dev *pdev)
+#ifdef CONFIG_PM
+
+static int vortex_suspend (struct pci_dev *pdev, u32 state)
 {
 	struct net_device *dev = pdev->driver_data;
 
@@ -818,9 +849,10 @@
 			vortex_down(dev);
 		}
 	}
+	return 0;
 }
 
-static void vortex_resume (struct pci_dev *pdev)
+static int vortex_resume (struct pci_dev *pdev)
 {
 	struct net_device *dev = pdev->driver_data;
 
@@ -833,8 +865,11 @@
 			netif_device_attach(dev);
 		}
 	}
+	return 0;
 }
 
+#endif /* CONFIG_PM */
+
 /* returns count found (>= 0), or negative on error */
 static int __init vortex_eisa_init (void)
 {
@@ -849,7 +884,7 @@
 	for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
 		int device_id;
 
-		if (request_region(ioaddr, VORTEX_TOTAL_SIZE, "3c59x") == NULL)
+		if (request_region(ioaddr, VORTEX_TOTAL_SIZE, DRV_NAME) == NULL)
 			continue;
 
 		/* Check the standard EISA ID register for an encoded '3Com'. */
@@ -918,6 +953,7 @@
 	static int printed_version;
 	int retval;
 	struct vortex_chip_info * const vci = &vortex_info_tbl[chip_idx];
+	char *print_name;
 
 	if (!printed_version) {
 		printk (KERN_INFO "%s", version);
@@ -925,7 +961,9 @@
 		printed_version = 1;
 	}
 
-	dev = init_etherdev(NULL, sizeof(*vp));
+	print_name = pdev ? pdev->slot_name : "3c59x";
+
+	dev = alloc_etherdev(sizeof(*vp));
 	retval = -ENOMEM;
 	if (!dev) {
 		printk (KERN_ERR PFX "unable to allocate etherdev, aborting\n");
@@ -934,7 +972,7 @@
 	SET_MODULE_OWNER(dev);
 
 	printk(KERN_INFO "%s: 3Com %s %s at 0x%lx, ",
-	       dev->name,
+	       print_name,
 	       pdev ? "PCI" : "EISA",
 	       vci->name,
 	       ioaddr);
@@ -958,7 +996,7 @@
 	if (pdev) {
 		/* EISA resources already marked, so only PCI needs to do this here */
 		/* Ignore return value, because Cardbus drivers already allocate for us */
-		if (request_region(ioaddr, vci->io_size, dev->name) != NULL)
+		if (request_region(ioaddr, vci->io_size, print_name) != NULL)
 			vp->must_free_region = 1;
 
 		/* enable bus-mastering if necessary */		
@@ -977,7 +1015,7 @@
 			if (pci_latency < new_latency) {
 				printk(KERN_INFO "%s: Overriding PCI latency"
 					" timer (CFLT) setting of %d, new value is %d.\n",
-					dev->name, pci_latency, new_latency);
+					print_name, pci_latency, new_latency);
 					pci_write_config_byte(pdev, PCI_LATENCY_TIMER, new_latency);
 			}
 		}
@@ -1107,7 +1145,7 @@
 				goto free_ring;
 		}
 		printk(KERN_INFO "%s: CardBus functions mapped %8.8lx->%p\n",
-			   dev->name, fn_st_addr, vp->cb_fn_base);
+			   print_name, fn_st_addr, vp->cb_fn_base);
 		EL3WINDOW(2);
 
 		n = inw(ioaddr + Wn2_ResetOptions) & ~0x4010;
@@ -1230,7 +1268,7 @@
 
 	if (vortex_debug > 0) {
 		printk(KERN_INFO "%s: scatter/gather %sabled. h/w checksums %sabled\n",
-				dev->name,
+				print_name,
 				(dev->features & NETIF_F_SG) ? "en":"dis",
 				(dev->features & NETIF_F_IP_CSUM) ? "en":"dis");
 	}
@@ -1241,7 +1279,9 @@
 	dev->set_multicast_list = set_rx_mode;
 	dev->tx_timeout = vortex_tx_timeout;
 	dev->watchdog_timeo = (watchdog * HZ) / 1000;
-	return 0;
+	retval = register_netdev(dev);
+	if (retval == 0)
+		return 0;
 
 free_ring:
 	pci_free_consistent(pdev,
@@ -1252,7 +1292,6 @@
 free_region:
 	if (vp->must_free_region)
 		release_region(ioaddr, vci->io_size);
-	unregister_netdev(dev);
 	kfree (dev);
 	printk(KERN_ERR PFX "vortex_probe1 fails.  Returns %d\n", retval);
 out:
@@ -1725,7 +1764,7 @@
 	unsigned char tx_status = 0;
 
 	if (vortex_debug > 2) {
-		printk(KERN_DEBUG "%s: vortex_error(), status=0x%x\n", dev->name, status);
+		printk(KERN_ERR "%s: vortex_error(), status=0x%x\n", dev->name, status);
 	}
 
 	if (status & TxComplete) {			/* Really "TxError" for us. */
@@ -1733,8 +1772,12 @@
 		/* Presumably a tx-timeout. We must merely re-enable. */
 		if (vortex_debug > 2
 			|| (tx_status != 0x88 && vortex_debug > 0)) {
-			printk(KERN_DEBUG"%s: Transmit error, Tx status register %2.2x.\n",
+			printk(KERN_ERR "%s: Transmit error, Tx status register %2.2x.\n",
 				   dev->name, tx_status);
+			if (tx_status == 0x82) {
+				printk(KERN_ERR "Probably a duplex mismatch.  See "
+						"Documentation/networking/vortex.txt\n");
+			}
 			dump_tx_ring(dev);
 		}
 		if (tx_status & 0x14)  vp->stats.tx_fifo_errors++;
@@ -2293,7 +2336,6 @@
 			struct sk_buff *skb;
 			dma_addr_t dma = le32_to_cpu(vp->rx_ring[entry].addr);
 
-			vp->stats.rx_bytes += pkt_len;
 			if (vortex_debug > 4)
 				printk(KERN_DEBUG "Receiving packet size %d status %4.4x.\n",
 					   pkt_len, rx_status);
@@ -2571,6 +2613,35 @@
 	return;
 }
 
+
+static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+{
+	struct vortex_private *vp = dev->priv;
+	u32 ethcmd;
+		
+	if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
+		return -EFAULT;
+
+        switch (ethcmd) {
+        case ETHTOOL_GDRVINFO: {
+		struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
+		strcpy(info.driver, DRV_NAME);
+		strcpy(info.version, DRV_VERSION);
+		if (vp->pdev)
+			strcpy(info.bus_info, vp->pdev->slot_name);
+		else
+			sprintf(info.bus_info, "EISA 0x%lx %d",
+				dev->base_addr, dev->irq);
+		if (copy_to_user(useraddr, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+
+        }
+	
+	return -EOPNOTSUPP;
+}
+
 static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct vortex_private *vp = (struct vortex_private *)dev->priv;
@@ -2580,6 +2651,8 @@
 	int retval;
 
 	switch(cmd) {
+	case SIOCETHTOOL:
+		return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
 	case SIOCDEVPRIVATE:		/* Get the address of the PHY in use. */
 		data[0] = phy;
 	case SIOCDEVPRIVATE+1:		/* Read the specified MII register. */
@@ -2774,9 +2847,11 @@
 	name:		"3c59x",
 	probe:		vortex_init_one,
 	remove:		vortex_remove_one,
+	id_table:	vortex_pci_tbl,
+#ifdef CONFIG_PM
 	suspend:	vortex_suspend,
 	resume:		vortex_resume,
-	id_table:	vortex_pci_tbl,
+#endif
 };
 
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/8139too.c linux/drivers/net/8139too.c
--- v2.4.5/linux/drivers/net/8139too.c	Mon May  7 14:13:19 2001
+++ linux/drivers/net/8139too.c	Wed Jun 20 11:10:52 2001
@@ -136,6 +136,10 @@
 
 */
 
+#define DRV_NAME	"8139too"
+#define DRV_VERSION	"0.9.18-pre3"
+
+
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -146,13 +150,14 @@
 #include <linux/etherdevice.h>
 #include <linux/rtnetlink.h>
 #include <linux/delay.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
 #include <asm/io.h>
+#include <asm/uaccess.h>
 
 
-#define RTL8139_VERSION "0.9.17"
-#define MODNAME "8139too"
-#define RTL8139_DRIVER_NAME   MODNAME " Fast Ethernet driver " RTL8139_VERSION
-#define PFX MODNAME ": "
+#define RTL8139_DRIVER_NAME   DRV_NAME " Fast Ethernet driver " DRV_VERSION
+#define PFX DRV_NAME ": "
 
 
 /* enable PIO instead of MMIO, if CONFIG_8139TOO_PIO is selected */
@@ -363,7 +368,10 @@
 	TxOK = 0x04,
 	RxErr = 0x02,
 	RxOK = 0x01,
+
+	RxAckBits = RxFIFOOver | RxOverflow | RxOK,
 };
+
 enum TxStatusBits {
 	TxHostOwns = 0x2000,
 	TxUnderrun = 0x4000,
@@ -542,6 +550,11 @@
 
 };
 
+struct rtl_extra_stats {
+	unsigned long early_rx;
+	unsigned long tx_buf_mapped;
+	unsigned long tx_timeouts;
+};
 
 struct rtl8139_private {
 	void *mmio_addr;
@@ -560,7 +573,6 @@
 	dma_addr_t rx_ring_dma;
 	dma_addr_t tx_bufs_dma;
 	signed char phys[4];		/* MII device addresses. */
-	u16 advertising;		/* NWay media advertisement */
 	char twistie, twist_row, twist_col;	/* Twister tune state. */
 	unsigned int full_duplex:1;	/* Full-duplex operation requested. */
 	unsigned int duplex_lock:1;
@@ -574,6 +586,7 @@
 	wait_queue_head_t thr_wait;
 	struct semaphore thr_exited;
 	u32 rx_config;
+	struct rtl_extra_stats xstats;
 };
 
 MODULE_AUTHOR ("Jeff Garzik <jgarzik@mandrakesoft.com>");
@@ -582,6 +595,10 @@
 MODULE_PARM (max_interrupt_work, "i");
 MODULE_PARM (media, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM (full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM_DESC (multicast_filter_limit, "8139too maximum number of filtered multicast addresses");
+MODULE_PARM_DESC (max_interrupt_work, "8139too maximum events handled per interrupt");
+MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
+MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");
 
 static int read_eeprom (void *ioaddr, int location, int addr_len);
 static int rtl8139_open (struct net_device *dev);
@@ -984,11 +1001,11 @@
 		for (phy = 0; phy < 32 && phy_idx < sizeof(tp->phys); phy++) {
 			int mii_status = mdio_read(dev, phy, 1);
 			if (mii_status != 0xffff  &&  mii_status != 0x0000) {
+				u16 advertising = mdio_read(dev, phy, 4);
 				tp->phys[phy_idx++] = phy;
-				tp->advertising = mdio_read(dev, phy, 4);
 				printk(KERN_INFO "%s: MII transceiver %d status 0x%4.4x "
 					   "advertising %4.4x.\n",
-					   dev->name, phy, mii_status, tp->advertising);
+					   dev->name, phy, mii_status, advertising);
 			}
 		}
 		if (phy_idx == 0) {
@@ -1314,6 +1331,28 @@
 }
 
 
+static void rtl_check_media (struct net_device *dev)
+{
+	struct rtl8139_private *tp = dev->priv;
+
+	DPRINTK("ENTER\n");
+	
+	if (tp->phys[0] >= 0) {
+		u16 mii_reg5 = mdio_read(dev, tp->phys[0], 5);
+		if (mii_reg5 == 0xffff)
+			;					/* Not there */
+		else if ((mii_reg5 & 0x0100) == 0x0100
+				 || (mii_reg5 & 0x00C0) == 0x0040)
+			tp->full_duplex = 1;
+
+		printk (KERN_INFO"%s: Setting %s%s-duplex based on"
+				" auto-negotiated partner ability %4.4x.\n",
+		        dev->name, mii_reg5 == 0 ? "" :
+				(mii_reg5 & 0x0180) ? "100mbps " : "10mbps ",
+			tp->full_duplex ? "full" : "half", mii_reg5);
+	}
+}
+
 /* Start the hardware at open or resume. */
 static void rtl8139_hw_start (struct net_device *dev)
 {
@@ -1331,50 +1370,25 @@
 	rtl8139_chip_reset (ioaddr);
 
 	/* unlock Config[01234] and BMCR register writes */
-	RTL_W8 (Cfg9346, Cfg9346_Unlock);
+	RTL_W8_F (Cfg9346, Cfg9346_Unlock);
 	/* Restore our idea of the MAC address. */
 	RTL_W32_F (MAC0 + 0, cpu_to_le32 (*(u32 *) (dev->dev_addr + 0)));
-	RTL_W32 (MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4)));
+	RTL_W32_F (MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4)));
 
 	/* Must enable Tx/Rx before setting transfer thresholds! */
 	RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
 
 	tp->rx_config = rtl8139_rx_config | AcceptBroadcast | AcceptMyPhys;
-	RTL_W32 (RxConfig, rtl8139_rx_config);
+	RTL_W32 (RxConfig, tp->rx_config);
 
 	/* Check this value: the documentation for IFG contradicts ifself. */
 	RTL_W32 (TxConfig, (TX_DMA_BURST << TxDMAShift));
 
 	tp->cur_rx = 0;
 	
-	DPRINTK("check_duplex");
-
-	/* This is check_duplex() */
-	if (tp->phys[0] >= 0  ||  (tp->drv_flags & HAS_MII_XCVR)) {
-		u16 mii_reg5 = mdio_read(dev, tp->phys[0], 5);
-		if (mii_reg5 == 0xffff)
-			;					/* Not there */
-		else if ((mii_reg5 & 0x0100) == 0x0100
-				 || (mii_reg5 & 0x00C0) == 0x0040)
-			tp->full_duplex = 1;
-		if (mii_reg5) {
-			printk(KERN_INFO"%s: Setting %s%s-duplex based on"
-			   " auto-negotiated partner ability %4.4x.\n", dev->name,
-			   mii_reg5 == 0 ? "" :
-			   (mii_reg5 & 0x0180) ? "100mbps " : "10mbps ",
-			   tp->full_duplex ? "full" : "half", mii_reg5);
-		} else {
-			printk(KERN_INFO"%s: media is unconnected, link down, or incompatible connection\n",
-			       dev->name);
-		}
-	}
+	rtl_check_media (dev);
 
 	if (tp->chipset >= CH_8139B) {
-		tmp = RTL_R8 (Config4) & ~(1<<2);
-		/* chip will clear Rx FIFO overflow automatically */
-		tmp |= (1<<7);
-		RTL_W8 (Config4, tmp);
-
 		/* disable magic packet scanning, which is enabled
 		 * when PM is enabled in Config1 */
 		RTL_W8 (Config3, RTL_R8 (Config3) & ~(1<<5));
@@ -1654,6 +1668,8 @@
 		 RTL_R16 (IntrStatus),
 		 RTL_R8 (MediaStatus));
 
+	tp->xstats.tx_timeouts++;
+
 	/* disable Tx ASAP, if not already */
 	tmp8 = RTL_R8 (ChipCmd);
 	if (tmp8 & CmdTxEnb)
@@ -1691,6 +1707,10 @@
 	unsigned int entry;
 	unsigned long flags;
 
+	/* XXX paranoid + sledgehammer == temporary system crash fix */
+	wmb();
+	spin_lock_irqsave (&tp->lock, flags);
+
 	/* Calculate the next Tx descriptor entry. */
 	entry = tp->cur_tx % NUM_TX_DESC;
 
@@ -1701,13 +1721,14 @@
 	if ((long) skb->data & 3) {	/* Must use alignment buffer. */
 		/* tp->tx_info[entry].mapping = 0; */
 		memcpy (tp->tx_buf[entry], skb->data, skb->len);
-		RTL_W32 (TxAddr0 + (entry * 4),
-			 tp->tx_bufs_dma + (tp->tx_buf[entry] - tp->tx_bufs));
+		RTL_W32_F (TxAddr0 + (entry * 4),
+			   tp->tx_bufs_dma + (tp->tx_buf[entry] - tp->tx_bufs));
 	} else {
+		tp->xstats.tx_buf_mapped++;
 		tp->tx_info[entry].mapping =
 		    pci_map_single (tp->pci_dev, skb->data, skb->len,
 				    PCI_DMA_TODEVICE);
-		RTL_W32 (TxAddr0 + (entry * 4), tp->tx_info[entry].mapping);
+		RTL_W32_F (TxAddr0 + (entry * 4), tp->tx_info[entry].mapping);
 	}
 
 	/* Note: the chip doesn't have auto-pad! */
@@ -1716,8 +1737,6 @@
 
 	dev->trans_start = jiffies;
 
-	spin_lock_irqsave (&tp->lock, flags);
-
 	tp->cur_tx++;
 	if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx)
 		netif_stop_queue (dev);
@@ -1760,7 +1779,7 @@
 			tp->stats.tx_errors++;
 			if (txstatus & TxAborted) {
 				tp->stats.tx_aborted_errors++;
-				RTL_W32 (TxConfig, TxClearAbt | (TX_DMA_BURST << TxDMAShift));
+				RTL_W32_F (TxConfig, TxClearAbt);
 			}
 			if (txstatus & TxCarrierLost)
 				tp->stats.tx_carrier_errors++;
@@ -1865,11 +1884,10 @@
 
 
 static void rtl8139_rx_interrupt (struct net_device *dev,
-				  struct rtl8139_private *tp, void *ioaddr,
-				  u16 status)
+				  struct rtl8139_private *tp, void *ioaddr)
 {
 	unsigned char *rx_ring;
-	u16 cur_rx, ackstat;
+	u16 cur_rx;
 
 	assert (dev != NULL);
 	assert (tp != NULL);
@@ -1883,11 +1901,6 @@
 		 RTL_R16 (RxBufAddr),
 		 RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
 
-	if (status & RxFIFOOver)
-		status = RxOverflow | RxOK;
-	else
-		status = RxOK;
-
 	while ((RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
 		int ring_offset = cur_rx % RX_BUF_LEN;
 		u32 rx_status;
@@ -1895,8 +1908,6 @@
 		unsigned int pkt_size;
 		struct sk_buff *skb;
 
-		mb();
-
 		/* read size+status of next frame from DMA ring buffer */
 		rx_status = le32_to_cpu (*(u32 *) (rx_ring + ring_offset));
 		rx_size = rx_status >> 16;
@@ -1916,8 +1927,10 @@
 		}
 #endif
 
-		if (rx_size == 0xfff0) /* Early Rx in progress */
+		if (rx_size == 0xfff0) { /* Early Rx in progress */
+			tp->xstats.early_rx++;
 			break;
+		}
 
 		/* If Rx err or invalid rx_size/rx_status received
 		 * (which happens if we get lost in the ring),
@@ -1963,9 +1976,8 @@
 		cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
 		RTL_W16 (RxBufPtr, cur_rx - 16);
 
-		ackstat = RTL_R16 (IntrStatus) & status;
-		if (ackstat)
-			RTL_W16 (IntrStatus, ackstat);
+		if (RTL_R16 (IntrStatus) & RxAckBits)
+			RTL_W16_F (IntrStatus, RxAckBits);
 	}
 
 	DPRINTK ("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x,"
@@ -1975,11 +1987,9 @@
 
 	tp->cur_rx = cur_rx;
 
-	if (RTL_R8 (ChipCmd) & RxBufEmpty) {
-		ackstat = RTL_R16 (IntrStatus) & status;
-		if (ackstat)
-			RTL_W16_F (IntrStatus, ackstat);
-	}
+	if ((RTL_R8 (ChipCmd) & RxBufEmpty) &&
+	    (RTL_R16 (IntrStatus) & RxAckBits))
+		RTL_W16_F (IntrStatus, RxAckBits);
 }
 
 
@@ -2059,26 +2069,10 @@
 		if (status & RxUnderrun)
 			link_changed = RTL_R16 (CSCR) & CSCR_LinkChangeBit;
 
-		/* E. Gill */
-		/* In case of an RxFIFOOver we must also clear the RxOverflow
-		   bit to avoid dropping frames for ever. Believe me, I got a
-		   lot of troubles copying huge data (approximately 2 RxFIFOOver
-		   errors per 1GB data transfer).
-		   The following is written in the 'p-guide.pdf' file (RTL8139(A/B)
-		   Programming guide V0.1, from 1999/1/15) on page 9 from REALTEC.
-		   -----------------------------------------------------------
-		   2. RxFIFOOvw handling:
-		     When RxFIFOOvw occurs, all incoming packets are discarded.
-		     Clear ISR(RxFIFOOvw) doesn't dismiss RxFIFOOvw event. To
-		     dismiss RxFIFOOvw event, the ISR(RxBufOvw) must be written
-		     with a '1'.
-		   -----------------------------------------------------------
-		   Unfortunately I was not able to find any reason for the
-		   RxFIFOOver error (I got the feeling this depends on the
-		   CPU speed, lower CPU speed --> more errors).
-		   After clearing the RxOverflow bit the transfer of the
-		   packet was repeated and all data are error free transferred */
-		ackstat = status & ~(RxFIFOOver | RxOverflow | RxOK);
+		/* The chip takes special action when we clear RxAckBits,
+		 * so we clear them later in rtl8139_rx_interrupt
+		 */
+		ackstat = status & ~RxAckBits;
 		RTL_W16 (IntrStatus, ackstat);
 
 		DPRINTK ("%s: interrupt  status=%#4.4x ackstat=%#4.4x new intstat=%#4.4x.\n",
@@ -2089,9 +2083,8 @@
 		      RxFIFOOver | TxErr | TxOK | RxErr | RxOK)) == 0)
 			break;
 
-		if (netif_running (dev) &&
-		    status & (RxOK | RxUnderrun | RxOverflow | RxFIFOOver))	/* Rx interrupt */
-			rtl8139_rx_interrupt (dev, tp, ioaddr, status);
+		if (netif_running (dev) && (status & RxAckBits))
+			rtl8139_rx_interrupt (dev, tp, ioaddr);
 
 		/* Check uncommon events with one test. */
 		if (status & (PCIErr | PCSTimeout | RxUnderrun | RxOverflow |
@@ -2099,8 +2092,7 @@
 			rtl8139_weird_interrupt (dev, tp, ioaddr,
 						 status, link_changed);
 
-		if (netif_running (dev) &&
-		    status & (TxOK | TxErr)) {
+		if (netif_running (dev) && (status & (TxOK | TxErr))) {
 			spin_lock (&tp->lock);
 			rtl8139_tx_interrupt (dev, tp, ioaddr);
 			spin_unlock (&tp->lock);
@@ -2110,10 +2102,8 @@
 	} while (boguscnt > 0);
 
 	if (boguscnt <= 0) {
-		printk (KERN_WARNING
-			"%s: Too much work at interrupt, "
-			"IntrStatus=0x%4.4x.\n", dev->name,
-			status);
+		printk (KERN_WARNING "%s: Too much work at interrupt, "
+			"IntrStatus=0x%4.4x.\n", dev->name, status);
 
 		/* Clear all interrupt sources. */
 		RTL_W16 (IntrStatus, 0xffff);
@@ -2216,7 +2206,7 @@
 				if (tp->medialock)
 					tp->full_duplex = (value & 0x0100) ? 1 : 0;
 				break;
-			case 4: tp->advertising = value; break;
+			case 4: /* tp->advertising = value; */ break;
 			}
 		}
 		mdio_write(dev, data[0], data[1] & 0x1f, data[2]);
@@ -2308,8 +2298,9 @@
 		mc_filter[1] = mc_filter[0] = 0;
 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
 		     i++, mclist = mclist->next) {
-			set_bit (ether_crc (ETH_ALEN, mclist->dmi_addr) >> 26,
-				 mc_filter);
+			int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
+
+			mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
 			rx_mode |= AcceptMulticast;
 		}
 	}
@@ -2323,7 +2314,7 @@
 		tp->rx_config = tmp;
 	}
 	RTL_W32_F (MAR0 + 0, mc_filter[0]);
-	RTL_W32 (MAR0 + 4, mc_filter[1]);
+	RTL_W32_F (MAR0 + 4, mc_filter[1]);
 
 	spin_unlock_irqrestore (&tp->lock, flags);
 
@@ -2331,7 +2322,9 @@
 }
 
 
-static void rtl8139_suspend (struct pci_dev *pdev)
+#ifdef CONFIG_PM
+
+static int rtl8139_suspend (struct pci_dev *pdev, u32 state)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
 	struct rtl8139_private *tp = dev->priv;
@@ -2339,7 +2332,7 @@
 	unsigned long flags;
 
 	if (!netif_running (dev))
-		return;
+		return 0;
 
 	netif_device_detach (dev);
 
@@ -2354,27 +2347,33 @@
 	RTL_W32 (RxMissed, 0);
 
 	spin_unlock_irqrestore (&tp->lock, flags);
+	return 0;
 }
 
 
-static void rtl8139_resume (struct pci_dev *pdev)
+static int rtl8139_resume (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
 
 	if (!netif_running (dev))
-		return;
+		return 0;
 	netif_device_attach (dev);
 	rtl8139_hw_start (dev);
+	return 0;
 }
 
+#endif /* CONFIG_PM */
+
 
 static struct pci_driver rtl8139_pci_driver = {
-	name:		MODNAME,
+	name:		DRV_NAME,
 	id_table:	rtl8139_pci_tbl,
 	probe:		rtl8139_init_one,
 	remove:		rtl8139_remove_one,
+#ifdef CONFIG_PM
 	suspend:	rtl8139_suspend,
 	resume:		rtl8139_resume,
+#endif /* CONFIG_PM */
 };
 
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/82596.c linux/drivers/net/82596.c
--- v2.4.5/linux/drivers/net/82596.c	Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/82596.c	Wed Jun 20 11:10:53 2001
@@ -151,6 +151,7 @@
 MODULE_AUTHOR("Richard Hirst");
 MODULE_DESCRIPTION("i82596 driver");
 MODULE_PARM(i596_debug, "i");
+MODULE_PARM_DESC(i596_debug, "i82596 debug mask");
 
 
 /* Copy frames shorter than rx_copybreak, otherwise pass on up in
@@ -1493,9 +1494,11 @@
 static int io = 0x300;
 static int irq = 10;
 MODULE_PARM(irq, "i");
+MODULE_PARM_DESC(irq, "Apricot IRQ number");
 #endif
 
 MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "i82596 debug mask");
 static int debug = -1;
 
 int init_module(void)
diff -u --recursive --new-file v2.4.5/linux/drivers/net/Config.in linux/drivers/net/Config.in
--- v2.4.5/linux/drivers/net/Config.in	Sat May 19 17:55:11 2001
+++ linux/drivers/net/Config.in	Wed Jun 27 14:12:04 2001
@@ -15,7 +15,9 @@
    fi
 fi
 
-tristate 'General Instruments Surfboard 1000' CONFIG_NET_SB1000
+if [ "$CONFIG_ISAPNP" = "y" ]; then
+   tristate 'General Instruments Surfboard 1000' CONFIG_NET_SB1000 $CONFIG_ISAPNP
+fi
 
 #
 #	Ethernet
@@ -26,12 +28,9 @@
 
 bool 'Ethernet (10 or 100Mbit)' CONFIG_NET_ETHERNET
 if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
-   if [ "$CONFIG_ARM" = "y" ]; then
-      if [ "$CONFIG_ARCH_ACORN" != "y" ]; then
-	 tristate '  AM79C961A support' CONFIG_ARM_AM79C961A
-      else
-	 source drivers/acorn/net/Config.in
-      fi
+   dep_bool '  ARM EBSA110 AM79C961A support' CONFIG_ARM_AM79C961A $CONFIG_ARCH_EBSA110
+   if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
+      source drivers/acorn/net/Config.in
    fi
    if [ "$CONFIG_PPC" = "y" ]; then
       tristate '  MACE (Power Mac ethernet) support' CONFIG_MACE
@@ -64,6 +63,14 @@
    if [ "$CONFIG_SUPERH" = "y" ]; then
       tristate '  National DP83902AV  support' CONFIG_STNIC
    fi
+   dep_tristate '  Sun LANCE support' CONFIG_SUNLANCE $CONFIG_SBUS
+   if [ "$CONFIG_SBUS" = "y" -o "$CONFIG_PCI" = "y" ]; then
+      tristate '  Sun Happy Meal 10/100baseT support' CONFIG_HAPPYMEAL
+   fi
+   dep_tristate '  Sun BigMAC 10/100baseT support (EXPERIMENTAL)' CONFIG_SUNBMAC $CONFIG_SBUS $CONFIG_EXPERIMENTAL
+   dep_tristate '  Sun QuadEthernet support' CONFIG_SUNQE $CONFIG_SBUS
+   dep_tristate '  Sun LANCE support' CONFIG_SUNLANCE $CONFIG_SBUS
+   dep_tristate '  Sun GEM support' CONFIG_SUNGEM $CONFIG_PCI
    bool '  3COM cards' CONFIG_NET_VENDOR_3COM
    if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then
       dep_tristate '    3c501 "EtherLink" support' CONFIG_EL1 $CONFIG_ISA
@@ -85,24 +92,28 @@
    dep_tristate '  AMD LANCE and PCnet (AT1500 and NE2100) support' CONFIG_LANCE $CONFIG_ISA
    bool '  Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC
    if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then
-      tristate '    WD80*3 support' CONFIG_WD80x3
-      if [ "$CONFIG_MCA" = "y" ]; then
-	 tristate '    SMC Ultra MCA support' CONFIG_ULTRAMCA
+      dep_tristate '    WD80*3 support' CONFIG_WD80x3 $CONFIG_ISA
+      dep_tristate '    SMC Ultra MCA support' CONFIG_ULTRAMCA $CONFIG_MCA
+      if [ "$CONFIG_ISA" = "y" -o "$CONFIG_ISAPNP" = "y" ]; then
+         tristate '    SMC Ultra support' CONFIG_ULTRA
       fi
-      tristate '    SMC Ultra support' CONFIG_ULTRA
       dep_tristate '    SMC Ultra32 EISA support' CONFIG_ULTRA32 $CONFIG_EISA
-      tristate '    SMC 9194 support' CONFIG_SMC9194
+      dep_tristate '    SMC 9194 support' CONFIG_SMC9194 $CONFIG_ISA
    fi
    bool '  Racal-Interlan (Micom) NI cards' CONFIG_NET_VENDOR_RACAL
    if [ "$CONFIG_NET_VENDOR_RACAL" = "y" ]; then
-      dep_tristate '    NI5010 support (EXPERIMENTAL)' CONFIG_NI5010 $CONFIG_EXPERIMENTAL
-      tristate '    NI5210 support' CONFIG_NI52
-      tristate '    NI6510 support' CONFIG_NI65
+      dep_tristate '    NI5010 support (EXPERIMENTAL)' CONFIG_NI5010 $CONFIG_ISA $CONFIG_EXPERIMENTAL
+      dep_tristate '    NI5210 support' CONFIG_NI52 $CONFIG_ISA
+      dep_tristate '    NI6510 support' CONFIG_NI65 $CONFIG_ISA
    fi
    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      tristate '  AT1700/1720 support (EXPERIMENTAL)' CONFIG_AT1700
+      if [ "$CONFIG_ISA" = "y" -o "$CONFIG_MCA" = "y" ]; then
+         tristate '  AT1700/1720 support (EXPERIMENTAL)' CONFIG_AT1700
+      fi
+   fi
+   if [ "$CONFIG_ISA" = "y" -o "$CONFIG_EISA" = "y" -o "$CONFIG_MCA" = "y" ]; then
+      tristate '  DEPCA, DE10x, DE200, DE201, DE202, DE422 support' CONFIG_DEPCA
    fi
-   tristate '  DEPCA, DE10x, DE200, DE201, DE202, DE422 support' CONFIG_DEPCA
    if [ "$CONFIG_ISA" = "y" -o "$CONFIG_EISA" = "y" -o "$CONFIG_PCI" = "y" ]; then
       tristate '  HP 10/100VG PCLAN (ISA, EISA, PCI) support' CONFIG_HP100
    fi
@@ -131,7 +142,7 @@
       tristate '  NE/2 (ne2000 MCA version) support' CONFIG_NE2_MCA
       tristate '  IBM LAN Adapter/A support' CONFIG_IBMLANA
    fi
-   bool '  EISA, VLB, PCI and on board controllers' CONFIG_NET_PCI
+   dep_bool '  EISA, VLB, PCI and on board controllers' CONFIG_NET_PCI
    if [ "$CONFIG_NET_PCI" = "y" ]; then
       dep_tristate '    AMD PCnet32 PCI support' CONFIG_PCNET32 $CONFIG_PCI
       dep_tristate '    Adaptec Starfire support (EXPERIMENTAL)' CONFIG_ADAPTEC_STARFIRE $CONFIG_PCI $CONFIG_EXPERIMENTAL
@@ -139,16 +150,19 @@
 	 dep_tristate '    Ansel Communications EISA 3200 support (EXPERIMENTAL)' CONFIG_AC3200 $CONFIG_EXPERIMENTAL
       fi
 
-      tristate '    Apricot Xen-II on board Ethernet' CONFIG_APRICOT
+      dep_tristate '    Apricot Xen-II on board Ethernet' CONFIG_APRICOT $CONFIG_ISA
       dep_tristate '    CS89x0 support' CONFIG_CS89x0 $CONFIG_ISA
       dep_tristate '    DECchip Tulip (dc21x4x) PCI support' CONFIG_TULIP $CONFIG_PCI
+      if [ "$CONFIG_TULIP" = "y" -o "$CONFIG_TULIP" = "m" ]; then
+         dep_bool '      New bus configuration (EXPERIMENTAL)' CONFIG_TULIP_MWI $CONFIG_EXPERIMENTAL
+         bool '      Use PCI shared mem for NIC registers' CONFIG_TULIP_MMIO
+      fi
       if [ "$CONFIG_PCI" = "y" -o "$CONFIG_EISA" = "y" ]; then
          tristate '    Generic DECchip & DIGITAL EtherWORKS PCI/EISA' CONFIG_DE4X5
          tristate '    Digi Intl. RightSwitch SE-X support' CONFIG_DGRS
       fi
       dep_tristate '    Davicom DM910x/DM980x support' CONFIG_DM9102 $CONFIG_PCI
       dep_tristate '    EtherExpressPro/100 support' CONFIG_EEPRO100 $CONFIG_PCI
-      dep_mbool '      Enable Power Management (EXPERIMENTAL)' CONFIG_EEPRO100_PM $CONFIG_EEPRO100 $CONFIG_EXPERIMENTAL
       dep_tristate '    Mylex EISA LNE390A/B support (EXPERIMENTAL)' CONFIG_LNE390 $CONFIG_EISA $CONFIG_EXPERIMENTAL
       dep_tristate '    Myson MTD-8xx PCI Ethernet support' CONFIG_FEALNX $CONFIG_PCI
       dep_tristate '    National Semiconductor DP8381x series PCI Ethernet support' CONFIG_NATSEMI $CONFIG_PCI
@@ -167,9 +181,8 @@
       fi
       dep_tristate '    VIA Rhine support' CONFIG_VIA_RHINE $CONFIG_PCI
       dep_tristate '    Winbond W89c840 Ethernet support' CONFIG_WINBOND_840 $CONFIG_PCI
-      dep_tristate '    Sun Happy Meal 10/100baseT PCI support' CONFIG_HAPPYMEAL $CONFIG_PCI
       if [ "$CONFIG_OBSOLETE" = "y" ]; then
-	 bool '    Zenith Z-Note support (EXPERIMENTAL)' CONFIG_ZNET
+	 dep_bool '    Zenith Z-Note support (EXPERIMENTAL)' CONFIG_ZNET $CONFIG_ISA
       fi
       if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_ORION" = "y" ]; then
 	 bool '    Philips SAA9730 Ethernet support (EXPERIMENTAL)' CONFIG_LAN_SAA9730
@@ -177,9 +190,11 @@
    fi
    bool '  Pocket and portable adapters' CONFIG_NET_POCKET
    if [ "$CONFIG_NET_POCKET" = "y" ]; then
-      dep_tristate '    AT-LAN-TEC/RealTek pocket adapter support' CONFIG_ATP $CONFIG_ISA
-      tristate '    D-Link DE600 pocket adapter support' CONFIG_DE600
-      tristate '    D-Link DE620 pocket adapter support' CONFIG_DE620
+      if [ "$CONFIG_ISA" = "y" -a "$CONFIG_X86" = "y" ]; then
+         tristate '    AT-LAN-TEC/RealTek pocket adapter support' CONFIG_ATP
+      fi
+      dep_tristate '    D-Link DE600 pocket adapter support' CONFIG_DE600 $CONFIG_ISA
+      dep_tristate '    D-Link DE620 pocket adapter support' CONFIG_DE620 $CONFIG_ISA
    fi
 fi
 
@@ -196,10 +211,9 @@
 if [ "$CONFIG_ACENIC" != "n" ]; then
    bool '  Omit support for old Tigon I based AceNICs' CONFIG_ACENIC_OMIT_TIGON_I
 fi
+dep_tristate 'MyriCOM Gigabit Ethernet support' CONFIG_MYRI_SBUS $CONFIG_SBUS
 dep_tristate 'Packet Engines Hamachi GNIC-II support' CONFIG_HAMACHI $CONFIG_PCI
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-   dep_tristate 'Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)' CONFIG_YELLOWFIN $CONFIG_PCI
-fi
+dep_tristate 'Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)' CONFIG_YELLOWFIN $CONFIG_PCI $CONFIG_EXPERIMENTAL
 dep_tristate 'SysKonnect SK-98xx support' CONFIG_SK98LIN $CONFIG_PCI
 
 endmenu
@@ -209,14 +223,14 @@
    if [ "$CONFIG_PCI" = "y" -o "$CONFIG_EISA" = "y" ]; then
       tristate '  Digital DEFEA and DEFPA adapter support' CONFIG_DEFXX
    fi
-   tristate '  SysKonnect FDDI PCI support' CONFIG_SKFP
+   dep_tristate '  SysKonnect FDDI PCI support' CONFIG_SKFP $CONFIG_PCI
 fi
 
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
    if [ "$CONFIG_INET" = "y" ]; then
       bool 'HIPPI driver support (EXPERIMENTAL)' CONFIG_HIPPI
       if [ "$CONFIG_HIPPI" = "y" -a "$CONFIG_PCI" = "y" ]; then
-         tristate '  Essential RoadRunner HIPPI PCI adapter support' CONFIG_ROADRUNNER
+         dep_tristate '  Essential RoadRunner HIPPI PCI adapter support' CONFIG_ROADRUNNER $CONFIG_PCI
          if [ "$CONFIG_ROADRUNNER" != "n" ]; then
    	    bool '    Use large TX/RX rings' CONFIG_ROADRUNNER_LARGE_RINGS
          fi
@@ -224,9 +238,7 @@
    fi
 fi
 
-if [ ! "$CONFIG_PARPORT" = "n" ]; then
-   dep_tristate 'PLIP (parallel port) support' CONFIG_PLIP $CONFIG_PARPORT
-fi
+dep_tristate 'PLIP (parallel port) support' CONFIG_PLIP $CONFIG_PARPORT
 
 tristate 'PPP (point-to-point protocol) support' CONFIG_PPP
 if [ ! "$CONFIG_PPP" = "n" ]; then
diff -u --recursive --new-file v2.4.5/linux/drivers/net/Makefile linux/drivers/net/Makefile
--- v2.4.5/linux/drivers/net/Makefile	Wed May 16 10:25:38 2001
+++ linux/drivers/net/Makefile	Wed Jun 20 11:13:18 2001
@@ -30,7 +30,7 @@
 endif
 
 subdir-$(CONFIG_NET_PCMCIA) += pcmcia
-subdir-$(CONFIG_NET_RADIO) += wireless
+subdir-$(CONFIG_NET_WIRELESS) += wireless
 subdir-$(CONFIG_TULIP) += tulip
 subdir-$(CONFIG_IRDA) += irda
 subdir-$(CONFIG_TR) += tokenring
diff -u --recursive --new-file v2.4.5/linux/drivers/net/ac3200.c linux/drivers/net/ac3200.c
--- v2.4.5/linux/drivers/net/ac3200.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/ac3200.c	Wed Jun 20 11:10:53 2001
@@ -344,6 +344,9 @@
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
 MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
+MODULE_PARM_DESC(io, "ac3200 I/O base adress(es)");
+MODULE_PARM_DESC(irq, "ac3200 IRQ number(s)");
+MODULE_PARM_DESC(mem, "ac3200 Memory base address(es)");
 
 int
 init_module(void)
diff -u --recursive --new-file v2.4.5/linux/drivers/net/acenic.c linux/drivers/net/acenic.c
--- v2.4.5/linux/drivers/net/acenic.c	Fri Apr 13 20:26:07 2001
+++ linux/drivers/net/acenic.c	Wed Jun 20 11:10:53 2001
@@ -740,7 +740,6 @@
 }
 
 
-#ifdef MODULE
 MODULE_AUTHOR("Jes Sorensen <jes@linuxcare.com>");
 MODULE_DESCRIPTION("AceNIC/3C985/GA620 Gigabit Ethernet driver");
 MODULE_PARM(link, "1-" __MODULE_STRING(8) "i");
@@ -749,7 +748,12 @@
 MODULE_PARM(max_tx_desc, "1-" __MODULE_STRING(8) "i");
 MODULE_PARM(rx_coal_tick, "1-" __MODULE_STRING(8) "i");
 MODULE_PARM(max_rx_desc, "1-" __MODULE_STRING(8) "i");
-#endif
+MODULE_PARM_DESC(link, "Acenic/3C985/NetGear link state");
+MODULE_PARM_DESC(trace, "Acenic/3C985/NetGear firmware trace level");
+MODULE_PARM_DESC(tx_coal_tick, "Acenic/3C985/NetGear maximum clock ticks to wait for packets");
+MODULE_PARM_DESC(max_tx_desc, "Acenic/3C985/NetGear maximum number of transmit descriptors");
+MODULE_PARM_DESC(rx_coal_tick, "Acenic/3C985/NetGear maximum clock ticks to wait for packets");
+MODULE_PARM_DESC(max_rx_desc, "Acenic/3C985/NetGear maximum number of receive descriptors");
 
 
 static void __exit ace_module_cleanup(void)
diff -u --recursive --new-file v2.4.5/linux/drivers/net/aironet4500_card.c linux/drivers/net/aironet4500_card.c
--- v2.4.5/linux/drivers/net/aironet4500_card.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/aironet4500_card.c	Wed Jun 20 11:10:53 2001
@@ -707,14 +707,14 @@
 	awc_i365_card_release(s);
 
 
-	udelay(100000);
+	mdelay(100);
 	
 	i365_out(s, 0x2, 0x10 ); 	// power enable
-	udelay(200000);
+	mdelay(200);
 	
 	i365_out(s, 0x2, 0x10 | 0x01 | 0x04 | 0x80);	//power enable
 	
-	udelay(250000);
+	mdelay(250);
 	
 	if (!s->irq)
 		s->irq = 11;
@@ -740,7 +740,7 @@
 	i365_out(s,0x15,0x3f | 0x40);		// enab mem reg bit
 	i365_out(s,0x06,0x01);			// enab mem 
 	
-	udelay(10000);
+	mdelay(10);
 	
 	cis[0] = 0x45;
 	
@@ -751,7 +751,7 @@
 
 	mem[0x3e0] = 0x45;
 
-	udelay(10000);
+	mdelay(10);
 	
 	memcpy_fromio(cis,0xD000, 0x3e0);
 	
@@ -779,7 +779,7 @@
 		s->socket, s->manufacturer,s->product);
 
 	i365_out(s,0x07, 0x1 | 0x2); 		// enable io 16bit
-	udelay(1000);
+	mdelay(1);
 	port = s->io;
 	i365_out(s,0x08, port & 0xff);
 	i365_out(s,0x09, (port & 0xff00)/ 0x100);
@@ -788,7 +788,7 @@
 
 	i365_out(s,0x06, 0x40); 		// enable io window
 
-	udelay(1000);
+	mdelay(1);
 
 	i365_out(s,0x3e0,0x45);
 	
@@ -806,13 +806,10 @@
 
 	
 	outw(0x10, s->io + 0x34);
-	udelay(10000);
+	mdelay(10);
 	
 	return 0;
-	
-	
 
-		
 };
 
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/aironet4500_core.c linux/drivers/net/aironet4500_core.c
--- v2.4.5/linux/drivers/net/aironet4500_core.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/aironet4500_core.c	Wed Jun 20 11:10:53 2001
@@ -2567,7 +2567,7 @@
 MODULE_PARM(rx_queue_len,"i");
 MODULE_PARM(tx_rate,"i");
 MODULE_PARM(channel,"i");
-MODULE_PARM(tx_full_rate,"i");
+//MODULE_PARM(tx_full_rate,"i");
 MODULE_PARM(adhoc,"i");
 MODULE_PARM(master,"i");
 MODULE_PARM(slave,"i");
@@ -2576,6 +2576,12 @@
 MODULE_PARM(large_buff_mem,"i");
 MODULE_PARM(small_buff_no,"i");
 MODULE_PARM(SSID,"c33");
+MODULE_PARM_DESC(awc_debug,"Aironet debug mask");
+MODULE_PARM_DESC(channel,"Aironet ");
+MODULE_PARM_DESC(adhoc,"Aironet Access Points not available (0-1)");
+MODULE_PARM_DESC(master,"Aironet is Adhoc master (creates network sync) (0-1)");
+MODULE_PARM_DESC(slave,"Aironet is Adhoc slave (0-1)");
+MODULE_PARM_DESC(max_mtu,"Aironet MTU limit (256-2312)");
 #endif
 
 /*EXPORT_SYMBOL(tx_queue_len);
diff -u --recursive --new-file v2.4.5/linux/drivers/net/am79c961a.c linux/drivers/net/am79c961a.c
--- v2.4.5/linux/drivers/net/am79c961a.c	Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/am79c961a.c	Wed Jun 27 14:12:04 2001
@@ -1,7 +1,7 @@
 /*
  *  linux/drivers/net/am79c961.c
  *
- *  by Russell King <rmk@arm.linux.org.uk> 1995-2000.
+ *  by Russell King <rmk@arm.linux.org.uk> 1995-2001.
  *
  * 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
@@ -10,9 +10,9 @@
  * Derived from various things including skeleton.c
  *
  * This is a special driver for the am79c961A Lance chip used in the
- * Intel (formally Digital Equipment Corp) EBSA110 platform.
+ * Intel (formally Digital Equipment Corp) EBSA110 platform.  Please
+ * note that this can not be built as a module (it doesn't make sense).
  */
-#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/types.h>
@@ -35,7 +35,6 @@
 #include <asm/irq.h>
 #include <asm/io.h>
 #include <asm/dma.h>
-#include <asm/ecard.h>
 
 #define TX_BUFFERS 15
 #define RX_BUFFERS 25
@@ -46,45 +45,42 @@
 
 static unsigned int net_debug = NET_DEBUG;
 
-static char *version = "am79c961 ethernet driver (c) 1995 R.M.King v0.02\n";
+static const char version[] =
+	"am79c961 ethernet driver (C) 1995-2001 Russell King v0.04\n";
 
 /* --------------------------------------------------------------------------- */
 
 #ifdef __arm__
-static void
-write_rreg (unsigned long base, unsigned int reg, unsigned short val)
+static void write_rreg(u_long base, u_int reg, u_int val)
 {
 	__asm__("str%?h	%1, [%2]	@ NET_RAP
 		str%?h	%0, [%2, #-4]	@ NET_RDP
-		" : : "r" (val), "r" (reg), "r" (0xf0000464));
+		" : : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
 }
 
-static inline unsigned short
-read_rreg (unsigned int base_addr, unsigned int reg)
+static inline unsigned short read_rreg(u_long base_addr, u_int reg)
 {
 	unsigned short v;
 	__asm__("str%?h	%1, [%2]	@ NET_RAP
 		ldr%?h	%0, [%2, #-4]	@ NET_RDP
-		" : "=r" (v): "r" (reg), "r" (0xf0000464));
+		" : "=r" (v): "r" (reg), "r" (ISAIO_BASE + 0x0464));
 	return v;
 }
 
-static inline void
-write_ireg (unsigned long base, unsigned int reg, unsigned short val)
+static inline void write_ireg(u_long base, u_int reg, u_int val)
 {
 	__asm__("str%?h	%1, [%2]	@ NET_RAP
 		str%?h	%0, [%2, #8]	@ NET_IDP
-		" : : "r" (val), "r" (reg), "r" (0xf0000464));
+		" : : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
 }
 
-#define am_writeword(dev,off,val)\
-	__asm__("str%?h	%0, [%1]" : : \
-		"r" ((val) & 0xffff), "r" (0xe0000000 + ((off) << 1)));
+#define am_writeword(dev,off,val) __raw_writew(val, ISAMEM_BASE + ((off) << 1))
+#define am_readword(dev,off)      __raw_readw(ISAMEM_BASE + ((off) << 1))
 
 static inline void
 am_writebuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length)
 {
-	offset = 0xe0000000 + (offset << 1);
+	offset = ISAMEM_BASE + (offset << 1);
 	length = (length + 1) & ~1;
 	if ((int)buf & 2) {
 		__asm__ __volatile__("str%?h	%2, [%0], #4"
@@ -114,23 +110,10 @@
 	}
 }
 
-/*
- * This reads a 16-bit quantity in little-endian
- * mode from the am79c961 buffer.
- */
-static inline unsigned short am_readword(struct net_device *dev, u_int off)
-{
-	unsigned long address = 0xe0000000 + (off << 1);
-	unsigned short val;
-
-	__asm__("ldr%?h	%0, [%1]" : "=r" (val): "r" (address));
-	return val;
-}
-
 static inline void
 am_readbuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length)
 {
-	offset = 0xe0000000 + (offset << 1);
+	offset = ISAMEM_BASE + (offset << 1);
 	length = (length + 1) & ~1;
 	if ((int)buf & 2) {
 		unsigned int tmp;
@@ -274,12 +257,7 @@
 }
 
 /*
- * Open/initialize the board.  This is called (in the current kernel)
- * sometime after booting when the 'ifconfig' program is run.
- *
- * This routine should set everything up anew at each open, even
- * registers that "should" only need to be set once at boot, so that
- * there is non-reboot way to recover if something goes wrong.
+ * Open/initialize the board.
  */
 static int
 am79c961_open(struct net_device *dev)
@@ -322,8 +300,7 @@
 }
 
 /*
- * Get the current statistics.	This may be called with the card open or
- * closed.
+ * Get the current statistics.
  */
 static struct net_device_stats *am79c961_getstats (struct net_device *dev)
 {
@@ -367,7 +344,7 @@
 }
 
 /*
- * Set or clear promiscuous/multicast mode filter for this adaptor.
+ * Set or clear promiscuous/multicast mode filter for this adapter.
  */
 static void am79c961_setmulticastlist (struct net_device *dev)
 {
@@ -478,10 +455,8 @@
 	 * then the tx ring is full and we can't add another
 	 * packet.
 	 */
-	if (am_readword(dev, priv->txhdr + (priv->txhead << 3) + 2) & TMD_OWN) {
-		printk(KERN_DEBUG"tx ring full, stopping queue\n");
+	if (am_readword(dev, priv->txhdr + (priv->txhead << 3) + 2) & TMD_OWN)
 		netif_stop_queue(dev);
-	}
 
 	dev_kfree_skb(skb);
 
@@ -557,9 +532,7 @@
 	do {
 		u_int hdraddr;
 		u_int status;
-int bufnum;
 
-bufnum = priv->txtail;
 		hdraddr = priv->txhdr + (priv->txtail << 3);
 		status = am_readword (dev, hdraddr + 2);
 		if (status & TMD_OWN)
@@ -654,7 +627,6 @@
 	if (!dev)
 		goto out;
 
-	SET_MODULE_OWNER(dev);
 	priv = dev->priv;
 
 	/*
@@ -668,7 +640,7 @@
 	/*
 	 * Reset the device.
 	 */
-	inb((dev->base_addr + NET_RESET) >> 1);
+	inb(dev->base_addr + NET_RESET);
 	udelay(5);
 
 	/*
@@ -676,21 +648,20 @@
 	 * ether address.
 	 */
     	ret = -ENODEV;
-	if (inb(dev->base_addr >> 1) != 0x08 ||
-	    inb((dev->base_addr >> 1) + 1) != 00 ||
-	    inb((dev->base_addr >> 1) + 2) != 0x2b)
+	if (inb(dev->base_addr) != 0x08 ||
+	    inb(dev->base_addr + 2) != 0x00 ||
+	    inb(dev->base_addr + 4) != 0x2b)
 	    	goto nodev;
 
 	if (!request_region(dev->base_addr, 0x18, dev->name))
 		goto nodev;
 
 	am79c961_banner();
-	printk(KERN_INFO "%s: am79c961 found at %08lx, IRQ%d, ether address ",
-		dev->name, dev->base_addr, dev->irq);
+	printk(KERN_INFO "%s: ether address ", dev->name);
 
 	/* Retrive and print the ethernet address. */
 	for (i = 0; i < 6; i++) {
-		dev->dev_addr[i] = inb((dev->base_addr >> 1) + i) & 0xff;
+		dev->dev_addr[i] = inb(dev->base_addr + i * 2) & 0xff;
 		printk (i == 5 ? "%02x\n" : "%02x:", dev->dev_addr[i]);
 	}
 
@@ -715,4 +686,4 @@
 	return ret;
 }
 
-module_init(am79c961_init);
+__initcall(am79c961_init);
diff -u --recursive --new-file v2.4.5/linux/drivers/net/appletalk/ipddp.c linux/drivers/net/appletalk/ipddp.c
--- v2.4.5/linux/drivers/net/appletalk/ipddp.c	Wed May 16 10:31:27 2001
+++ linux/drivers/net/appletalk/ipddp.c	Wed Jun 27 17:10:55 2001
@@ -255,22 +255,26 @@
 static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
         struct ipddp_route *rt = (struct ipddp_route *)ifr->ifr_data;
+        struct ipddp_route rcp;
 
         if(!capable(CAP_NET_ADMIN))
                 return -EPERM;
 
+	if(copy_from_user(&rcp, rt, sizeof(rcp)))
+		return -EFAULT;
+
         switch(cmd)
         {
 		case SIOCADDIPDDPRT:
-                        return (ipddp_create(rt));
+                        return (ipddp_create(&rcp));
 
                 case SIOCFINDIPDDPRT:
-                        if(copy_to_user(rt, ipddp_find_route(rt), sizeof(struct ipddp_route)))
+                        if(copy_to_user(rt, ipddp_find_route(&rcp), sizeof(struct ipddp_route)))
                                 return -EFAULT;
                         return 0;
 
                 case SIOCDELIPDDPRT:
-                        return (ipddp_delete(rt));
+                        return (ipddp_delete(&rcp));
 
                 default:
                         return -EINVAL;
diff -u --recursive --new-file v2.4.5/linux/drivers/net/arlan.c linux/drivers/net/arlan.c
--- v2.4.5/linux/drivers/net/arlan.c	Tue Mar  6 19:28:33 2001
+++ linux/drivers/net/arlan.c	Wed Jun 20 11:10:53 2001
@@ -68,6 +68,23 @@
 MODULE_PARM(arlan_exit_debug, "i");
 MODULE_PARM(arlan_entry_and_exit_debug, "i");
 MODULE_PARM(arlan_EEPROM_bad, "i");
+MODULE_PARM_DESC(irq, "(unused)");
+MODULE_PARM_DESC(mem, "Arlan memory address for single device probing");
+MODULE_PARM_DESC(probe, "Arlan probe at initialization (0-1)");
+MODULE_PARM_DESC(arlan_debug, "Arlan debug enable (0-1)");
+MODULE_PARM_DESC(numDevices, "Number of Arlan devices; ignored if >1");
+MODULE_PARM_DESC(testMemory, "(unused)");
+MODULE_PARM_DESC(mdebug, "Arlan multicast debugging (0-1)");
+MODULE_PARM_DESC(retries, "Arlan maximum packet retransmisions");
+#ifdef ARLAN_ENTRY_EXIT_DEBUGGING
+MODULE_PARM_DESC(arlan_entry_debug, "Arlan driver function entry debugging");
+MODULE_PARM_DESC(arlan_exit_debug, "Arlan driver function exit debugging");
+MODULE_PARM_DESC(arlan_entry_and_exit_debug, "Arlan driver function entry and exit debugging");
+#else
+MODULE_PARM_DESC(arlan_entry_debug, "(ignored)");
+MODULE_PARM_DESC(arlan_exit_debug, "(ignored)");
+MODULE_PARM_DESC(arlan_entry_and_exit_debug, "(ignored)");
+#endif
 
 EXPORT_SYMBOL(arlan_device);
 EXPORT_SYMBOL(arlan_conf);
diff -u --recursive --new-file v2.4.5/linux/drivers/net/at1700.c linux/drivers/net/at1700.c
--- v2.4.5/linux/drivers/net/at1700.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/at1700.c	Wed Jun 20 11:13:18 2001
@@ -70,7 +70,7 @@
 
 /* These unusual address orders are used to verify the CONFIG register. */
 
-static int fmv18x_probe_list[] = {
+static int fmv18x_probe_list[] __initdata = {
 	0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x300, 0x340, 0
 };
 
@@ -78,7 +78,7 @@
  *	ISA
  */
 
-static int at1700_probe_list[] = {
+static int at1700_probe_list[] __initdata = {
 	0x260, 0x280, 0x2a0, 0x240, 0x340, 0x320, 0x380, 0x300, 0
 };
 
@@ -86,15 +86,15 @@
  *	MCA
  */
 #ifdef CONFIG_MCA	
-static int at1700_ioaddr_pattern[] = {
+static int at1700_ioaddr_pattern[] __initdata = {
 	0x00, 0x04, 0x01, 0x05, 0x02, 0x06, 0x03, 0x07
 };
 
-static int at1700_mca_probe_list[] = {
+static int at1700_mca_probe_list[] __initdata = {
 	0x400, 0x1400, 0x2400, 0x3400, 0x4400, 0x5400, 0x6400, 0x7400, 0
 };
 
-static int at1700_irq_pattern[] = {
+static int at1700_irq_pattern[] __initdata = {
 	0x00, 0x00, 0x00, 0x30, 0x70, 0xb0, 0x00, 0x00,
 	0x00, 0xf0, 0x34, 0x74, 0xb4, 0x00, 0x00, 0xf4, 0x00
 };
@@ -175,10 +175,10 @@
 };
 /* rEnE : maybe there are others I don't know off... */
 
-static struct at1720_mca_adapters_struct at1720_mca_adapters[] = {
+static struct at1720_mca_adapters_struct at1720_mca_adapters[] __initdata = {
 	{ "Allied Telesys AT1720AT",	0x6410 },
 	{ "Allied Telesys AT1720BT", 	0x6413 },
-	{ "Allied Telesys AT1720T",		0x6416 },
+	{ "Allied Telesys AT1720T",	0x6416 },
 	{ NULL, 0 },
 };
 #endif
@@ -470,7 +470,7 @@
 #define EE_READ_CMD		(6 << 6)
 #define EE_ERASE_CMD	(7 << 6)
 
-static int read_eeprom(int ioaddr, int location)
+static int __init read_eeprom(int ioaddr, int location)
 {
 	int i;
 	unsigned short retval = 0;
@@ -880,6 +880,9 @@
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
 MODULE_PARM(net_debug, "i");
+MODULE_PARM_DESC(io, "AT1700/FMV18X I/O base address");
+MODULE_PARM_DESC(irq, "AT1700/FMV18X IRQ number");
+MODULE_PARM_DESC(net_debug, "AT1700/FMV18X debug level (0-6)");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.4.5/linux/drivers/net/atari_bionet.c linux/drivers/net/atari_bionet.c
--- v2.4.5/linux/drivers/net/atari_bionet.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/atari_bionet.c	Wed Jun 20 11:10:53 2001
@@ -127,6 +127,7 @@
  */
 unsigned int bionet_debug = NET_DEBUG;
 MODULE_PARM(bionet_debug, "i");
+MODULE_PARM_DESC(bionet_debug, "bionet debug level (0-2)");
 
 static unsigned int bionet_min_poll_time = 2;
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/atari_pamsnet.c linux/drivers/net/atari_pamsnet.c
--- v2.4.5/linux/drivers/net/atari_pamsnet.c	Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/atari_pamsnet.c	Wed Jun 20 11:10:53 2001
@@ -123,6 +123,7 @@
  */
 unsigned int pamsnet_debug = NET_DEBUG;
 MODULE_PARM(pamsnet_debug, "i");
+MODULE_PARM_DESC(pamsnet_debug, "pamsnet debug enable (0-1)");
 
 static unsigned int pamsnet_min_poll_time = 2;
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/atarilance.c linux/drivers/net/atarilance.c
--- v2.4.5/linux/drivers/net/atarilance.c	Fri Apr 20 11:54:22 2001
+++ linux/drivers/net/atarilance.c	Wed Jun 20 11:10:53 2001
@@ -83,6 +83,7 @@
 static int lance_debug = 1;
 #endif
 MODULE_PARM(lance_debug, "i");
+MODULE_PARM_DESC(lance_debug, "atarilance debug level (0-3)");
 
 /* Print debug messages on probing? */
 #undef LANCE_DEBUG_PROBE
diff -u --recursive --new-file v2.4.5/linux/drivers/net/atp.c linux/drivers/net/atp.c
--- v2.4.5/linux/drivers/net/atp.c	Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/atp.c	Wed Jun 20 11:10:53 2001
@@ -153,9 +153,14 @@
 MODULE_DESCRIPTION("RealTek RTL8002/8012 parallel port Ethernet driver");
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(debug, "i");
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(xcvr, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(io, "1-" __MODULE_STRING(NUM_UNITS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(NUM_UNITS) "i");
+MODULE_PARM(xcvr, "1-" __MODULE_STRING(NUM_UNITS) "i");
+MODULE_PARM_DESC(max_interrupt_work, "ATP maximum events handled per interrupt");
+MODULE_PARM_DESC(debug, "ATP debug level (0-7)");
+MODULE_PARM_DESC(io, "ATP I/O base address(es)");
+MODULE_PARM_DESC(irq, "ATP IRQ number(s)");
+MODULE_PARM_DESC(xcvr, "ATP tranceiver(s) (0=internal, 1=external)");
 
 #define RUN_AT(x) (jiffies + (x))
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/bagetlance.c linux/drivers/net/bagetlance.c
--- v2.4.5/linux/drivers/net/bagetlance.c	Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/bagetlance.c	Wed Jun 20 11:10:53 2001
@@ -1,5 +1,5 @@
 /* $Id$
- * vmelance.c: Ethernet driver for VME Lance cards on Baget/MIPS
+ * bagetlance.c: Ethernet driver for VME Lance cards on Baget/MIPS
  *      This code stealed and adopted from linux/drivers/net/atarilance.c
  *      See that for author info
  *
@@ -59,6 +59,7 @@
 static int lance_debug = 1;
 #endif
 MODULE_PARM(lance_debug, "i");
+MODULE_PARM_DESC(lance_debug, "Lance debug level (0-3)");
 
 /* Print debug messages on probing? */
 #undef LANCE_DEBUG_PROBE
diff -u --recursive --new-file v2.4.5/linux/drivers/net/cs89x0.c linux/drivers/net/cs89x0.c
--- v2.4.5/linux/drivers/net/cs89x0.c	Thu Apr 12 12:16:35 2001
+++ linux/drivers/net/cs89x0.c	Wed Jun 20 11:10:53 2001
@@ -1607,6 +1607,25 @@
 MODULE_PARM(dma , "i");
 MODULE_PARM(dmasize , "i");
 MODULE_PARM(use_dma , "i");
+MODULE_PARM_DESC(io, "cs89x0 I/O base address");
+MODULE_PARM_DESC(irq, "cs89x0 IRQ number");
+#if DEBUGGING
+MODULE_PARM_DESC(debug, "cs89x0 debug level (0-6)");
+#else
+MODULE_PARM_DESC(debug, "(ignored)");
+#endif
+MODULE_PARM_DESC(media, "Set cs89x0 adapter(s) media type(s) (rj45,bnc,aui)");
+/* No other value than -1 for duplex seems to be currently interpreted */
+MODULE_PARM_DESC(duplex, "(ignored)");
+#if ALLOW_DMA
+MODULE_PARM_DESC(dma , "cs89x0 ISA DMA channel; ignored if use_dma=0");
+MODULE_PARM_DESC(dmasize , "cs89x0 DMA size in kB (16,64); ignored if use_dma=0");
+MODULE_PARM_DESC(use_dma , "cs89x0 using DMA (0-1)");
+#else
+MODULE_PARM_DESC(dma , "(ignored)");
+MODULE_PARM_DESC(dmasize , "(ignored)");
+MODULE_PARM_DESC(use_dma , "(ignored)");
+#endif
 
 MODULE_AUTHOR("Mike Cruse, Russwll Nelson <nelson@crynwr.com>, Andrew Morton <andrewm@uow.edu.au>");
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c
--- v2.4.5/linux/drivers/net/de4x5.c	Fri Apr 13 20:26:07 2001
+++ linux/drivers/net/de4x5.c	Wed Jun 20 11:10:53 2001
@@ -1044,6 +1044,9 @@
 MODULE_PARM(de4x5_debug, "i");
 MODULE_PARM(dec_only, "i");
 MODULE_PARM(args, "s");
+MODULE_PARM_DESC(de4x5_debug, "de4x5 debug mask");
+MODULE_PARM_DESC(dec_only, "de4x5 probe only for Digital boards (0-1)");
+MODULE_PARM_DESC(args, "de4x5 full duplex and media type settings; see de4x5.c for details");
 # else
 static int loading_module;
 #endif /* MODULE */
@@ -5784,6 +5787,7 @@
 static struct net_device *mdev = NULL;
 static int io=0x0;/* EDIT THIS LINE FOR YOUR CONFIGURATION IF NEEDED        */
 MODULE_PARM(io, "i");
+MODULE_PARM_DESC(io, "de4x5 I/O base address");
 
 int
 init_module(void)
diff -u --recursive --new-file v2.4.5/linux/drivers/net/de600.c linux/drivers/net/de600.c
--- v2.4.5/linux/drivers/net/de600.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/de600.c	Wed Jun 20 11:10:53 2001
@@ -113,9 +113,11 @@
 
 static unsigned int de600_debug = DE600_DEBUG;
 MODULE_PARM(de600_debug, "i");
+MODULE_PARM_DESC(de600_debug, "DE-600 debug level (0-2)");
 
 static unsigned int delay_time = 10;
 MODULE_PARM(delay_time, "i");
+MODULE_PARM_DESC(delay_time, "DE-600 deley on I/O in microseconds");
 
 #ifdef FAKE_SMALL_MAX
 static unsigned long de600_rspace(struct sock *sk);
diff -u --recursive --new-file v2.4.5/linux/drivers/net/de620.c linux/drivers/net/de620.c
--- v2.4.5/linux/drivers/net/de620.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/de620.c	Wed Jun 20 11:10:53 2001
@@ -197,6 +197,12 @@
 MODULE_PARM(irq, "i");
 MODULE_PARM(clone, "i");
 MODULE_PARM(de620_debug, "i");
+MODULE_PARM_DESC(bnc, "DE-620 set BNC medium (0-1)");
+MODULE_PARM_DESC(utp, "DE-620 set UTP medium (0-1)");
+MODULE_PARM_DESC(io, "DE-620 I/O base address,required");
+MODULE_PARM_DESC(irq, "DE-620 IRQ number,required");
+MODULE_PARM_DESC(clone, "Check also for non-D-Link DE-620 clones (0-1)");
+MODULE_PARM_DESC(de620_debug, "DE-620 debug level (0-2)");
 
 /***********************************************
  *                                             *
diff -u --recursive --new-file v2.4.5/linux/drivers/net/depca.c linux/drivers/net/depca.c
--- v2.4.5/linux/drivers/net/depca.c	Fri Apr 13 20:26:07 2001
+++ linux/drivers/net/depca.c	Wed Jun 20 11:10:53 2001
@@ -2039,6 +2039,8 @@
 static int io=0x200;    /* Or use the irq= io= options to insmod */
 MODULE_PARM(irq, "i");
 MODULE_PARM(io, "i");
+MODULE_PARM_DESC(irq, "DEPCA IRQ number");
+MODULE_PARM_DESC(io, "DEPCA I/O base address");
 
 /* See depca_probe() for autoprobe messages when a module */	
 int
diff -u --recursive --new-file v2.4.5/linux/drivers/net/dgrs.c linux/drivers/net/dgrs.c
--- v2.4.5/linux/drivers/net/dgrs.c	Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/dgrs.c	Wed Jun 20 21:00:55 2001
@@ -538,7 +538,7 @@
 				break; /* For safety */
 			if ( (p-putp) >= len)
 			{
-				printk("%s: cbp = %x\n", devN->name, H2S(cbp));
+				printk("%s: cbp = %lx\n", devN->name, (long) H2S(cbp));
 				proc_reset(dev0, 1);	/* Freeze IDT */
 				break; /* For Safety */
 			}
@@ -607,7 +607,7 @@
 				break; /* For safety */
 			if ( (p-putp) >= len)
 			{
-				printk("%s: cbp = %x\n", devN->name, H2S(cbp));
+				printk("%s: cbp = %lx\n", devN->name, (long) H2S(cbp));
 				proc_reset(dev0, 1);	/* Freeze IDT */
 				break; /* For Safety */
 			}
@@ -642,7 +642,7 @@
 				break; /* For safety */
 			if ( (p-putp) >= len)
 			{
-				printk("%s: cbp = %x\n", devN->name, H2S(cbp));
+				printk("%s: cbp = %lx\n", devN->name, (long) H2S(cbp));
 				proc_reset(dev0, 1);	/* Freeze IDT */
 				break; /* For Safety */
 			}
@@ -1441,6 +1441,9 @@
 MODULE_PARM(iptrap, "1-4i");
 MODULE_PARM(ipxnet, "i");
 MODULE_PARM(nicmode, "i");
+MODULE_PARM_DESC(debug, "Digi RightSwitch enable debugging (0-1)");
+MODULE_PARM_DESC(dma, "Digi RightSwitch enable BM DMA (0-1)");
+MODULE_PARM_DESC(nicmode, "Digi RightSwitch operating mode (1: switch, 2: multi-NIC)");
 
 static int __init dgrs_init_module (void)
 {
diff -u --recursive --new-file v2.4.5/linux/drivers/net/dmfe.c linux/drivers/net/dmfe.c
--- v2.4.5/linux/drivers/net/dmfe.c	Sat May 19 18:05:23 2001
+++ linux/drivers/net/dmfe.c	Thu Jun 21 14:28:39 2001
@@ -77,6 +77,10 @@
 #include <asm/io.h>
 #include <asm/dma.h>
 
+#if BITS_PER_LONG == 64
+#error FIXME: driver does not support 64-bit platforms
+#endif
+
 
 /* Board/System/Debug information/definition ---------------- */
 #define PCI_DM9132_ID   0x91321282      /* Davicom DM9132 ID */
@@ -2014,7 +2018,10 @@
 MODULE_PARM(HPNA_tx_cmd, "i");
 MODULE_PARM(HPNA_NoiseFloor, "i");
 MODULE_PARM(SF_mode, "i");
-
+MODULE_PARM_DESC(debug, "Davicom DM9xxx enable debugging (0-1)");
+MODULE_PARM_DESC(mode, "Davicom DM9xxx: Bit 0: 10/100Mbps, bit 2: duplex, bit 8: HomePNA");
+MODULE_PARM_DESC(SF_mode, "Davicom DM9xxx special function (bit 0: VLAN, bit 1 Flow Control, bit 2: TX pause packet)");
+                                                                                                                                
 /*	Description:
  *	when user used insmod to add module, system invoked init_module()
  *	to initilize and register.
diff -u --recursive --new-file v2.4.5/linux/drivers/net/e2100.c linux/drivers/net/e2100.c
--- v2.4.5/linux/drivers/net/e2100.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/e2100.c	Wed Jun 20 11:10:53 2001
@@ -386,6 +386,10 @@
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
 MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
 MODULE_PARM(xcvr, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
+MODULE_PARM_DESC(io, "E2100 I/O base address(es)");
+MODULE_PARM_DESC(irq, "E2100 IRQ number(s)");
+MODULE_PARM_DESC(mem, " E2100 memory base address(es)");
+MODULE_PARM_DESC(xcvr, "E2100 tranceiver(s) (0=internal, 1=external)");
 
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
diff -u --recursive --new-file v2.4.5/linux/drivers/net/eepro.c linux/drivers/net/eepro.c
--- v2.4.5/linux/drivers/net/eepro.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/eepro.c	Wed Jun 20 11:10:53 2001
@@ -1771,6 +1771,10 @@
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_EEPRO) "i");
 MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_EEPRO) "i");
 MODULE_PARM(autodetect, "1-" __MODULE_STRING(1) "i");
+MODULE_PARM_DESC(io, "EtherExpress Pro/10 I/O base addres(es)");
+MODULE_PARM_DESC(irq, "EtherExpress Pro/10 IRQ number(s)");
+MODULE_PARM_DESC(mem, "EtherExpress Pro/10 Rx buffer size(es) in kB (3-29)");
+MODULE_PARM_DESC(autodetect, "EtherExpress Pro/10 force board(s) detection (0-1)");
 
 int 
 init_module(void)
diff -u --recursive --new-file v2.4.5/linux/drivers/net/eepro100.c linux/drivers/net/eepro100.c
--- v2.4.5/linux/drivers/net/eepro100.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/eepro100.c	Wed Jun 20 11:16:01 2001
@@ -124,18 +124,29 @@
 MODULE_PARM(rx_copybreak, "i");
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(multicast_filter_limit, "i");
+MODULE_PARM_DESC(debug, "eepro100 debug level (0-6)");
+MODULE_PARM_DESC(options, "epro100: Bits 0-3: tranceiver type, bit 4: full duplex, bit 5: 100Mbps");
+MODULE_PARM_DESC(full_duplex, "epro100 full duplex setting(s) (1)");
+MODULE_PARM_DESC(congenb, "epro100  Enable congestion control (1)");
+MODULE_PARM_DESC(txfifo, "epro100 Tx FIFO threshold in 4 byte units, (0-15)");
+MODULE_PARM_DESC(rxfifo, "epro100 Rx FIFO threshold in 4 byte units, (0-15)");
+MODULE_PARM_DESC(txdmaccount, "epro100 Tx DMA burst length; 128 - disable (0-128)");
+MODULE_PARM_DESC(rxdmaccount, "epro100 Rx DMA burst length; 128 - disable (0-128)");
+MODULE_PARM_DESC(rx_copybreak, "epro100 copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(max_interrupt_work, "epro100 maximum events handled per interrupt");
+MODULE_PARM_DESC(multicast_filter_limit, "epro100 maximum number of filtered multicast addresses");
 
 #define RUN_AT(x) (jiffies + (x))
 
 /* ACPI power states don't universally work (yet) */
-#ifndef CONFIG_EEPRO100_PM
+#ifndef CONFIG_PM
 #undef pci_set_power_state
 #define pci_set_power_state null_set_power_state
 static inline int null_set_power_state(struct pci_dev *dev, int state)
 {
 	return 0;
 }
-#endif /* CONFIG_EEPRO100_PM */
+#endif /* CONFIG_PM */
 
 #define netdevice_start(dev)
 #define netdevice_stop(dev)
@@ -470,7 +481,7 @@
 	struct timer_list timer;			/* Media selection timer. */
 	struct speedo_mc_block *mc_setup_head;/* Multicast setup frame list head. */
 	struct speedo_mc_block *mc_setup_tail;/* Multicast setup frame list tail. */
-	int in_interrupt;					/* Word-aligned dev->interrupt */
+	long in_interrupt;					/* Word-aligned dev->interrupt */
 	unsigned char acpi_pwr;
 	signed char rx_mode;					/* Current PROMISC/ALLMULTI setting. */
 	unsigned int tx_full:1;				/* The Tx queue is full. */
@@ -512,9 +523,9 @@
 static int eepro100_init_one(struct pci_dev *pdev,
 		const struct pci_device_id *ent);
 static void eepro100_remove_one (struct pci_dev *pdev);
-#ifdef CONFIG_EEPRO100_PM
-static void eepro100_suspend (struct pci_dev *pdev);
-static void eepro100_resume (struct pci_dev *pdev);
+#ifdef CONFIG_PM
+static int eepro100_suspend (struct pci_dev *pdev, u32 state);
+static int eepro100_resume (struct pci_dev *pdev);
 #endif
 
 static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len);
@@ -1910,7 +1921,7 @@
 		   timer routine.  2000/05/09 SAW */
 		saved_acpi = pci_set_power_state(sp->pdev, 0);
 		t = del_timer_sync(&sp->timer);
-		data[3] = mdio_read(ioaddr, data[0], data[1]);
+		data[3] = mdio_read(ioaddr, data[0] & 0x1f, data[1] & 0x1f);
 		if (t)
 			add_timer(&sp->timer); /* may be set to the past  --SAW */
 		pci_set_power_state(sp->pdev, saved_acpi);
@@ -2129,8 +2140,8 @@
 	sp->rx_mode = new_rx_mode;
 }
 
-#ifdef CONFIG_EEPRO100_PM
-static void eepro100_suspend(struct pci_dev *pdev)
+#ifdef CONFIG_PM
+static int eepro100_suspend(struct pci_dev *pdev, u32 state)
 {
 	struct net_device *dev = pdev->driver_data;
 	long ioaddr = dev->base_addr;
@@ -2139,9 +2150,10 @@
 	outl(PortPartialReset, ioaddr + SCBPort);
 	
 	/* XXX call pci_set_power_state ()? */
+	return 0;
 }
 
-static void eepro100_resume(struct pci_dev *pdev)
+static int eepro100_resume(struct pci_dev *pdev)
 {
 	struct net_device *dev = pdev->driver_data;
 	struct speedo_private *sp = (struct speedo_private *)dev->priv;
@@ -2160,8 +2172,9 @@
 	sp->rx_mode = -1;
 	sp->flow_ctrl = sp->partner = 0;
 	set_rx_mode(dev);
+	return 0;
 }
-#endif /* CONFIG_EEPRO100_PM */
+#endif /* CONFIG_PM */
 
 static void __devexit eepro100_remove_one (struct pci_dev *pdev)
 {
@@ -2192,7 +2205,7 @@
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1030,
 		PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82820FW_4,
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_7,
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0,}
 };
@@ -2203,10 +2216,10 @@
 	id_table:	eepro100_pci_tbl,
 	probe:		eepro100_init_one,
 	remove:		eepro100_remove_one,
-#ifdef CONFIG_EEPRO100_PM
+#ifdef CONFIG_PM
 	suspend:	eepro100_suspend,
 	resume:		eepro100_resume,
-#endif
+#endif /* CONFIG_PM */
 };
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,48)
diff -u --recursive --new-file v2.4.5/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c
--- v2.4.5/linux/drivers/net/eexpress.c	Tue Mar 20 12:05:01 2001
+++ linux/drivers/net/eexpress.c	Wed Jun 20 11:10:53 2001
@@ -1632,6 +1632,8 @@
 
 MODULE_PARM(io, "1-" __MODULE_STRING(EEXP_MAX_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(EEXP_MAX_CARDS) "i");
+MODULE_PARM_DESC(io, "EtherExpress 16 I/O base address(es)");
+MODULE_PARM_DESC(irq, "EtherExpress 16 IRQ number(s)");
 
 /* Ideally the user would give us io=, irq= for every card.  If any parameters
  * are specified, we verify and then use them.  If no parameters are given, we
diff -u --recursive --new-file v2.4.5/linux/drivers/net/epic100.c linux/drivers/net/epic100.c
--- v2.4.5/linux/drivers/net/epic100.c	Sat May 19 18:02:45 2001
+++ linux/drivers/net/epic100.c	Wed Jun 20 11:13:18 2001
@@ -100,6 +100,7 @@
 #error You must compile this driver with "-O".
 #endif
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
@@ -116,6 +117,7 @@
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/ethtool.h>
+#include <linux/mii.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -135,6 +137,11 @@
 MODULE_PARM(rx_copybreak, "i");
 MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM_DESC(debug, "EPIC/100 debug level (0-5)");
+MODULE_PARM_DESC(max_interrupt_work, "EPIC/100 maximum events handled per interrupt");
+MODULE_PARM_DESC(options, "EPIC/100: Bits 0-3: media type, bit 4: full duplex");
+MODULE_PARM_DESC(rx_copybreak, "EPIC/100 copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(full_duplex, "EPIC/100 full duplex setting(s) (1)");
 
 /*
 				Theory of Operation
@@ -1169,7 +1176,7 @@
 			if (pkt_len > PKT_BUF_SZ - 4) {
 				printk(KERN_ERR "%s: Oversized Ethernet frame, status %x "
 					   "%d bytes.\n",
-					   dev->name, pkt_len, status);
+					   dev->name, status, pkt_len);
 				pkt_len = 1514;
 			}
 			/* Check if the packet is long enough to accept without copying
@@ -1445,38 +1452,46 @@
 }
 
 
-static void epic_suspend (struct pci_dev *pdev)
+#ifdef CONFIG_PM
+
+static int epic_suspend (struct pci_dev *pdev, u32 state)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	long ioaddr = dev->base_addr;
 
 	if (!netif_running(dev))
-		return;
+		return 0;
 	epic_pause(dev);
 	/* Put the chip into low-power mode. */
 	outl(0x0008, ioaddr + GENCTL);
 	/* pci_power_off(pdev, -1); */
+	return 0;
 }
 
 
-static void epic_resume (struct pci_dev *pdev)
+static int epic_resume (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 
 	if (!netif_running(dev))
-		return;
+		return 0;
 	epic_restart(dev);
 	/* pci_power_on(pdev); */
+	return 0;
 }
 
+#endif /* CONFIG_PM */
+
 
 static struct pci_driver epic_driver = {
 	name:		DRV_NAME,
 	id_table:	epic_pci_tbl,
 	probe:		epic_init_one,
 	remove:		epic_remove_one,
+#ifdef CONFIG_PM
 	suspend:	epic_suspend,
 	resume:		epic_resume,
+#endif /* CONFIG_PM */
 };
 
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/es3210.c linux/drivers/net/es3210.c
--- v2.4.5/linux/drivers/net/es3210.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/es3210.c	Wed Jun 20 11:10:53 2001
@@ -383,6 +383,9 @@
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ES_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ES_CARDS) "i");
 MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_ES_CARDS) "i");
+MODULE_PARM_DESC(io, "ES3210 I/O base address(es)");
+MODULE_PARM_DESC(irq, "ES3210 IRQ number(s)");
+MODULE_PARM_DESC(mem, "ES3210 memory base address(es)");
 
 int
 init_module(void)
diff -u --recursive --new-file v2.4.5/linux/drivers/net/eth16i.c linux/drivers/net/eth16i.c
--- v2.4.5/linux/drivers/net/eth16i.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/eth16i.c	Wed Jun 20 11:10:53 2001
@@ -1407,7 +1407,7 @@
 MODULE_DESCRIPTION("ICL EtherTeam 16i/32 driver");
 
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "i");
-MODULE_PARM_DESC(io, "eth16i io base address");
+MODULE_PARM_DESC(io, "eth16i I/O base address(es)");
 
 #if 0
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "i");
@@ -1415,10 +1415,10 @@
 #endif
 
 MODULE_PARM(mediatype, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "s");
-MODULE_PARM_DESC(mediatype, "eth16i interfaceport mediatype");
+MODULE_PARM_DESC(mediatype, "eth16i media type of interface(s) (bnc,tp,dix,auto,eprom)");
 
 MODULE_PARM(debug, "i");
-MODULE_PARM_DESC(debug, "eth16i debug level (0-4)");
+MODULE_PARM_DESC(debug, "eth16i debug level (0-6)");
 #endif
 
 int init_module(void)
diff -u --recursive --new-file v2.4.5/linux/drivers/net/ethertap.c linux/drivers/net/ethertap.c
--- v2.4.5/linux/drivers/net/ethertap.c	Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/ethertap.c	Wed Jun 20 11:10:53 2001
@@ -336,6 +336,7 @@
 
 static int unit;
 MODULE_PARM(unit,"i");
+MODULE_PARM_DESC(unit,"Ethertap device number");
 
 static struct net_device dev_ethertap =
 {
diff -u --recursive --new-file v2.4.5/linux/drivers/net/ewrk3.c linux/drivers/net/ewrk3.c
--- v2.4.5/linux/drivers/net/ewrk3.c	Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/ewrk3.c	Wed Jun 27 17:10:55 2001
@@ -1633,38 +1633,44 @@
 	u_long iobase = dev->base_addr;
 	int i, j, status = 0;
 	u_char csr;
-	union {
+	union ewrk3_addr {
 		u_char addr[HASH_TABLE_LEN * ETH_ALEN];
 		u_short val[(HASH_TABLE_LEN * ETH_ALEN) >> 1];
-	} tmp;
+	};
+	
+	union ewrk3_addr *tmp;
+
+	tmp = kmalloc(sizeof(union ewrk3_addr), GFP_KERNEL);
+	if(tmp==NULL)
+		return -ENOMEM;
 
 	switch (ioc->cmd) {
 	case EWRK3_GET_HWADDR:	/* Get the hardware address */
 		for (i = 0; i < ETH_ALEN; i++) {
-			tmp.addr[i] = dev->dev_addr[i];
+			tmp->addr[i] = dev->dev_addr[i];
 		}
 		ioc->len = ETH_ALEN;
-		if (copy_to_user(ioc->data, tmp.addr, ioc->len)) {
+		if (copy_to_user(ioc->data, tmp->addr, ioc->len))
 			status = -EFAULT;
-			break;
-		}
+		break;
+		
 	case EWRK3_SET_HWADDR:	/* Set the hardware address */
 		if (capable(CAP_NET_ADMIN)) {
-				csr = inb(EWRK3_CSR);
-				csr |= (CSR_TXD | CSR_RXD);
-				outb(csr, EWRK3_CSR);	/* Disable the TX and RX */
-
-				if (copy_from_user(tmp.addr, ioc->data, ETH_ALEN)) {
-					status = -EFAULT;
-					break;
-				}
-				for (i = 0; i < ETH_ALEN; i++) {
-					dev->dev_addr[i] = tmp.addr[i];
-					outb(tmp.addr[i], EWRK3_PAR0 + i);
-				}
+			csr = inb(EWRK3_CSR);
+			csr |= (CSR_TXD | CSR_RXD);
+			outb(csr, EWRK3_CSR);	/* Disable the TX and RX */
+
+			if (copy_from_user(tmp->addr, ioc->data, ETH_ALEN)) {
+				status = -EFAULT;
+				break;
+			}
+			for (i = 0; i < ETH_ALEN; i++) {
+				dev->dev_addr[i] = tmp->addr[i];
+				outb(tmp->addr[i], EWRK3_PAR0 + i);
+			}
 
-				csr &= ~(CSR_TXD | CSR_RXD);	/* Enable the TX and RX */
-				outb(csr, EWRK3_CSR);
+			csr &= ~(CSR_TXD | CSR_RXD);	/* Enable the TX and RX */
+			outb(csr, EWRK3_CSR);
 		} else {
 			status = -EPERM;
 		}
@@ -1691,32 +1697,28 @@
 		}
 
 		break;
-	case EWRK3_SAY_BOO:	/* Say "Boo!" to the kernel log file */
-		printk("%s: Boo!\n", dev->name);
-
-		break;
 	case EWRK3_GET_MCA:	/* Get the multicast address table */
 		spin_lock_irq(&lp->hw_lock);
 		if (lp->shmem_length == IO_ONLY) {
 			outb(0, EWRK3_IOPR);
 			outw(PAGE0_HTE, EWRK3_PIR1);
 			for (i = 0; i < (HASH_TABLE_LEN >> 3); i++) {
-				tmp.addr[i] = inb(EWRK3_DATA);
+				tmp->addr[i] = inb(EWRK3_DATA);
 			}
 		} else {
 			outb(0, EWRK3_MPR);
-			isa_memcpy_fromio(tmp.addr, lp->shmem_base + PAGE0_HTE, (HASH_TABLE_LEN >> 3));
+			isa_memcpy_fromio(tmp->addr, lp->shmem_base + PAGE0_HTE, (HASH_TABLE_LEN >> 3));
 		}
 		spin_unlock_irq(&lp->hw_lock);
 
 		ioc->len = (HASH_TABLE_LEN >> 3);
-		if (copy_to_user(ioc->data, tmp.addr, ioc->len))
+		if (copy_to_user(ioc->data, tmp->addr, ioc->len))
 			status = -EFAULT;
 
 		break;
 	case EWRK3_SET_MCA:	/* Set a multicast address */
 		if (capable(CAP_NET_ADMIN)) {
-			if (copy_from_user(tmp.addr, ioc->data, ETH_ALEN * ioc->len)) {
+			if (copy_from_user(tmp->addr, ioc->data, ETH_ALEN * ioc->len)) {
 				status = -EFAULT;
 				break;
 			}
@@ -1764,18 +1766,18 @@
 
 		break;
 	case EWRK3_GET_CSR:	/* Get the CSR Register contents */
-		tmp.addr[0] = inb(EWRK3_CSR);
+		tmp->addr[0] = inb(EWRK3_CSR);
 		ioc->len = 1;
-		if (copy_to_user(ioc->data, tmp.addr, ioc->len))
+		if (copy_to_user(ioc->data, tmp->addr, ioc->len))
 			status = -EFAULT;
 		break;
 	case EWRK3_SET_CSR:	/* Set the CSR Register contents */
 		if (capable(CAP_NET_ADMIN)) {
-			if (copy_from_user(tmp.addr, ioc->data, 1)) {
+			if (copy_from_user(tmp->addr, ioc->data, 1)) {
 				status = -EFAULT;
 				break;
 			}
-			outb(tmp.addr[0], EWRK3_CSR);
+			outb(tmp->addr[0], EWRK3_CSR);
 		} else {
 			status = -EPERM;
 		}
@@ -1784,15 +1786,15 @@
 	case EWRK3_GET_EEPROM:	/* Get the EEPROM contents */
 		if (capable(CAP_NET_ADMIN)) {
 			for (i = 0; i < (EEPROM_MAX >> 1); i++) {
-				tmp.val[i] = (short) Read_EEPROM(iobase, i);
+				tmp->val[i] = (short) Read_EEPROM(iobase, i);
 			}
 			i = EEPROM_MAX;
-			tmp.addr[i++] = inb(EWRK3_CMR);		/* Config/Management Reg. */
+			tmp->addr[i++] = inb(EWRK3_CMR);		/* Config/Management Reg. */
 			for (j = 0; j < ETH_ALEN; j++) {
-				tmp.addr[i++] = inb(EWRK3_PAR0 + j);
+				tmp->addr[i++] = inb(EWRK3_PAR0 + j);
 			}
 			ioc->len = EEPROM_MAX + 1 + ETH_ALEN;
-			if (copy_to_user(ioc->data, tmp.addr, ioc->len))
+			if (copy_to_user(ioc->data, tmp->addr, ioc->len))
 				status = -EFAULT;
 		} else {
 			status = -EPERM;
@@ -1801,12 +1803,12 @@
 		break;
 	case EWRK3_SET_EEPROM:	/* Set the EEPROM contents */
 		if (capable(CAP_NET_ADMIN)) {
-			if (copy_from_user(tmp.addr, ioc->data, EEPROM_MAX)) {
+			if (copy_from_user(tmp->addr, ioc->data, EEPROM_MAX)) {
 				status = -EFAULT;
 				break;
 			}
 			for (i = 0; i < (EEPROM_MAX >> 1); i++) {
-				Write_EEPROM(tmp.val[i], iobase, i);
+				Write_EEPROM(tmp->val[i], iobase, i);
 			}
 		} else {
 			status = -EPERM;
@@ -1814,9 +1816,9 @@
 
 		break;
 	case EWRK3_GET_CMR:	/* Get the CMR Register contents */
-		tmp.addr[0] = inb(EWRK3_CMR);
+		tmp->addr[0] = inb(EWRK3_CMR);
 		ioc->len = 1;
-		if (copy_to_user(ioc->data, tmp.addr, ioc->len))
+		if (copy_to_user(ioc->data, tmp->addr, ioc->len))
 			status = -EFAULT;
 		break;
 	case EWRK3_SET_TX_CUT_THRU:	/* Set TX cut through mode */
@@ -1838,7 +1840,7 @@
 	default:
 		status = -EOPNOTSUPP;
 	}
-
+	kfree(tmp);
 	return status;
 }
 
@@ -1849,6 +1851,8 @@
 
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
+MODULE_PARM_DESC(io, "EtherWORKS 3 I/O base address");
+MODULE_PARM_DESC(irq, "EtherWORKS 3 IRQ number");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.4.5/linux/drivers/net/fc/iph5526.c linux/drivers/net/fc/iph5526.c
--- v2.4.5/linux/drivers/net/fc/iph5526.c	Wed Apr 18 14:40:05 2001
+++ linux/drivers/net/fc/iph5526.c	Wed Jun 20 11:19:02 2001
@@ -222,7 +222,7 @@
 static int get_scsi_oxid(struct fc_info *fi);
 static void update_scsi_oxid(struct fc_info *fi);
 
-Scsi_Host_Template driver_template = IPH5526_SCSI_FC;
+static Scsi_Host_Template driver_template = IPH5526_SCSI_FC;
 
 static void iph5526_timeout(struct net_device *dev);
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/fealnx.c linux/drivers/net/fealnx.c
--- v2.4.5/linux/drivers/net/fealnx.c	Thu May 24 15:37:37 2001
+++ linux/drivers/net/fealnx.c	Thu Jun 21 14:28:39 2001
@@ -46,6 +46,8 @@
 // #define RX_RING_SIZE    32
 #define TX_RING_SIZE    6
 #define RX_RING_SIZE    12
+#define TX_TOTAL_SIZE	TX_RING_SIZE*sizeof(struct fealnx_desc)
+#define RX_TOTAL_SIZE	RX_RING_SIZE*sizeof(struct fealnx_desc)
 
 /* Operational parameters that usually are not changed. */
 /* Time in jiffies before concluding the transmitter is hung. */
@@ -107,12 +109,18 @@
 MODULE_AUTHOR("Myson or whoever");
 MODULE_DESCRIPTION("Myson MTD-8xx 100/10M Ethernet PCI Adapter Driver");
 MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(min_pci_latency, "i");
+//MODULE_PARM(min_pci_latency, "i");
 MODULE_PARM(debug, "i");
 MODULE_PARM(rx_copybreak, "i");
 MODULE_PARM(multicast_filter_limit, "i");
 MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM_DESC(max_interrupt_work, "fealnx maximum events handled per interrupt");
+MODULE_PARM_DESC(debug, "fealnx enable debugging (0-1)");
+MODULE_PARM_DESC(rx_copybreak, "fealnx copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(multicast_filter_limit, "fealnx maximum number of filtered multicast addresses");
+MODULE_PARM_DESC(options, "fealnx: Bits 0-3: media type, bit 17: full duplex");
+MODULE_PARM_DESC(full_duplex, "fealnx full duplex setting(s) (1)");
 
 #define MIN_REGION_SIZE 136
 
@@ -363,8 +371,11 @@
 
 struct netdev_private {
 	/* Descriptor rings first for alignment. */
-	struct fealnx_desc rx_ring[RX_RING_SIZE];
-	struct fealnx_desc tx_ring[TX_RING_SIZE];
+	struct fealnx_desc *rx_ring;
+	struct fealnx_desc *tx_ring;
+
+	dma_addr_t rx_ring_dma;
+	dma_addr_t tx_ring_dma;
 
 	struct net_device_stats stats;
 
@@ -461,6 +472,8 @@
 	long ioaddr;
 	unsigned int chip_id = ent->driver_data;
 	struct net_device *dev;
+	void *ring_space;
+	dma_addr_t ring_dma;
 	
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -528,6 +541,22 @@
 	np->flags = skel_netdrv_tbl[chip_id].flags;
 	pci_set_drvdata(pdev, dev);
 
+	ring_space = pci_alloc_consistent(pdev, RX_TOTAL_SIZE, &ring_dma);
+	if (!ring_space) {
+		err = -ENOMEM;
+		goto err_out_free_dev;
+	}
+	np->rx_ring = (struct fealnx_desc *)ring_space;
+	np->rx_ring_dma = ring_dma;
+
+	ring_space = pci_alloc_consistent(pdev, TX_TOTAL_SIZE, &ring_dma);
+	if (!ring_space) {
+		err = -ENOMEM;
+		goto err_out_free_rx;
+	}
+	np->tx_ring = (struct fealnx_desc *)ring_space;
+	np->tx_ring_dma = ring_dma;
+
 	/* find the connected MII xcvrs */
 	if (np->flags == HAS_MII_XCVR) {
 		int phy, phy_idx = 0;
@@ -623,7 +652,7 @@
 	
 	err = register_netdev(dev);
 	if (err)
-		goto err_out_free;
+		goto err_out_free_tx;
 
 	printk(KERN_INFO "%s: %s at 0x%lx, ",
 	       dev->name, skel_netdrv_tbl[chip_id].chip_name, ioaddr);
@@ -633,7 +662,11 @@
 
 	return 0;
 
-err_out_free:
+err_out_free_tx:
+	pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring, np->tx_ring_dma);
+err_out_free_rx:
+	pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring, np->rx_ring_dma);
+err_out_free_dev:
 	kfree(dev);
 err_out_unmap:
 #ifndef USE_IO_OPS
@@ -647,7 +680,14 @@
 static void __devexit fealnx_remove_one(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
+
 	if (dev) {
+		struct netdev_private *np = dev->priv;
+
+		pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring,
+			np->tx_ring_dma);
+		pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring,
+			np->rx_ring_dma);
 		unregister_netdev(dev);
 #ifndef USE_IO_OPS
 		iounmap((void *)dev->base_addr);
@@ -828,8 +868,8 @@
 
 	init_ring(dev);
 
-	writel(virt_to_bus(np->rx_ring), ioaddr + RXLBA);
-	writel(virt_to_bus(np->tx_ring), ioaddr + TXLBA);
+	writel(np->rx_ring_dma, ioaddr + RXLBA);
+	writel(np->tx_ring_dma, ioaddr + TXLBA);
 
 	/* Initialize other registers. */
 	/* Configure the PCI bus bursts and FIFO thresholds.
@@ -846,7 +886,7 @@
 	   1 1 1   256
 	   Wait the specified 50 PCI cycles after a reset by initializing
 	   Tx and Rx queues and the address filter list. */
-#if defined(__powerpc__)
+#if defined(__powerpc__) || defined(__sparc__)
 // 89/9/1 modify, 
 //   np->bcrvalue=0x04 | 0x0x38;  /* big-endian, 256 burst length */
 	np->bcrvalue = 0x04 | 0x10;	/* big-endian, tx 8 burst length */
@@ -1077,7 +1117,8 @@
 			break;	/* Better luck next round. */
 
 		skb->dev = dev;	/* Mark as being used by this device. */
-		np->lack_rxbuf->buffer = virt_to_bus(skb->tail);
+		np->lack_rxbuf->buffer = pci_map_single(np->pci_dev, skb->tail,
+			np->rx_buf_sz, PCI_DMA_FROMDEVICE);
 		np->lack_rxbuf = np->lack_rxbuf->next_desc_logical;
 		++np->really_rx_count;
 	}
@@ -1125,19 +1166,17 @@
 	printk(KERN_WARNING "%s: Transmit timed out, status %8.8x,"
 	       " resetting...\n", dev->name, readl(ioaddr + ISR));
 
-#ifndef __alpha__
 	{
 		int i;
 
-		printk(KERN_DEBUG "  Rx ring %8.8x: ", (int) np->rx_ring);
+		printk(KERN_DEBUG "  Rx ring %p: ", np->rx_ring);
 		for (i = 0; i < RX_RING_SIZE; i++)
 			printk(" %8.8x", (unsigned int) np->rx_ring[i].status);
-		printk("\n" KERN_DEBUG "  Tx ring %8.8x: ", (int) np->tx_ring);
+		printk("\n" KERN_DEBUG "  Tx ring %p: ", np->tx_ring);
 		for (i = 0; i < TX_RING_SIZE; i++)
 			printk(" %4.4x", np->tx_ring[i].status);
 		printk("\n");
 	}
-#endif
 
 	/* Perhaps we should reinitialize the hardware here.  Just trigger a
 	   Tx demand for now. */
@@ -1168,14 +1207,15 @@
 	for (i = 0; i < RX_RING_SIZE; i++) {
 		np->rx_ring[i].status = 0;
 		np->rx_ring[i].control = np->rx_buf_sz << RBSShift;
-		np->rx_ring[i].next_desc = virt_to_bus(&np->rx_ring[i + 1]);
+		np->rx_ring[i].next_desc = np->rx_ring_dma +
+			(i + 1)*sizeof(struct fealnx_desc);
 		np->rx_ring[i].next_desc_logical = &np->rx_ring[i + 1];
 		np->rx_ring[i].skbuff = NULL;
 	}
 
 	/* for the last rx descriptor */
-	np->rx_ring[i - 1].next_desc = virt_to_bus(&np->rx_ring[0]);
-	np->rx_ring[i - 1].next_desc_logical = &np->rx_ring[0];
+	np->rx_ring[i - 1].next_desc = np->rx_ring_dma;
+	np->rx_ring[i - 1].next_desc_logical = np->rx_ring;
 
 	/* allocate skb for rx buffers */
 	for (i = 0; i < RX_RING_SIZE; i++) {
@@ -1189,7 +1229,8 @@
 		++np->really_rx_count;
 		np->rx_ring[i].skbuff = skb;
 		skb->dev = dev;	/* Mark as being used by this device. */
-		np->rx_ring[i].buffer = virt_to_bus(skb->tail);
+		np->rx_ring[i].buffer = pci_map_single(np->pci_dev, skb->tail,
+			np->rx_buf_sz, PCI_DMA_FROMDEVICE);
 		np->rx_ring[i].status = RXOWN;
 		np->rx_ring[i].control |= RXIC;
 	}
@@ -1202,13 +1243,14 @@
 
 	for (i = 0; i < TX_RING_SIZE; i++) {
 		np->tx_ring[i].status = 0;
-		np->tx_ring[i].next_desc = virt_to_bus(&np->tx_ring[i + 1]);
+		np->tx_ring[i].next_desc = np->tx_ring_dma +
+			(i + 1)*sizeof(struct fealnx_desc);
 		np->tx_ring[i].next_desc_logical = &np->tx_ring[i + 1];
 		np->tx_ring[i].skbuff = NULL;
 	}
 
 	/* for the last tx descriptor */
-	np->tx_ring[i - 1].next_desc = virt_to_bus(&np->tx_ring[0]);
+	np->tx_ring[i - 1].next_desc = np->tx_ring_dma;
 	np->tx_ring[i - 1].next_desc_logical = &np->tx_ring[0];
 
 	return;
@@ -1220,11 +1262,12 @@
 	struct netdev_private *np = dev->priv;
 
 	np->cur_tx_copy->skbuff = skb;
-	np->cur_tx_copy->buffer = virt_to_bus(skb->data);
 
 #define one_buffer
 #define BPT 1022
 #if defined(one_buffer)
+	np->cur_tx_copy->buffer = pci_map_single(np->pci_dev, skb->data,
+		skb->len, PCI_DMA_TODEVICE);
 	np->cur_tx_copy->control = TXIC | TXLD | TXFD | CRCEnable | PADEnable;
 	np->cur_tx_copy->control |= (skb->len << PKTSShift);	/* pkt size */
 	np->cur_tx_copy->control |= (skb->len << TBSShift);	/* buffer size */
@@ -1239,6 +1282,8 @@
 		struct fealnx_desc *next;
 
 		/* for the first descriptor */
+		np->cur_tx_copy->buffer = pci_map_single(np->pci_dev, skb->data,
+			BPT, PCI_DMA_TODEVICE);
 		np->cur_tx_copy->control = TXIC | TXFD | CRCEnable | PADEnable;
 		np->cur_tx_copy->control |= (skb->len << PKTSShift);	/* pkt size */
 		np->cur_tx_copy->control |= (BPT << TBSShift);	/* buffer size */
@@ -1252,7 +1297,8 @@
 // 89/12/29 add,
 		if (np->pci_dev->device == 0x891)
 			np->cur_tx_copy->control |= ETIControl | RetryTxLC;
-		next->buffer = virt_to_bus(skb->data) + BPT;
+		next->buffer = pci_map_single(ep->pci_dev, skb->data + BPT,
+                                skb->len - BPT, PCI_DMA_TODEVICE);
 
 		next->status = TXOWN;
 		np->cur_tx_copy->status = TXOWN;
@@ -1260,6 +1306,8 @@
 		np->cur_tx_copy = next->next_desc_logical;
 		np->free_tx_count -= 2;
 	} else {
+		np->cur_tx_copy->buffer = pci_map_single(np->pci_dev, skb->data,
+			skb->len, PCI_DMA_TODEVICE);
 		np->cur_tx_copy->control = TXIC | TXLD | TXFD | CRCEnable | PADEnable;
 		np->cur_tx_copy->control |= (skb->len << PKTSShift);	/* pkt size */
 		np->cur_tx_copy->control |= (skb->len << TBSShift);	/* buffer size */
@@ -1308,7 +1356,8 @@
 
 	allocate_rx_buffers(dev);
 
-	writel(virt_to_bus(np->cur_rx), dev->base_addr + RXLBA);
+	writel(np->rx_ring_dma + (np->cur_rx - np->rx_ring),
+		dev->base_addr + RXLBA);
 	writel(np->crvalue, dev->base_addr + TCRRCR);
 }
 
@@ -1421,6 +1470,8 @@
 			}
 
 			/* Free the original skb. */
+			pci_unmap_single(np->pci_dev, np->cur_tx->buffer,
+				np->cur_tx->skbuff->len, PCI_DMA_TODEVICE);
 			dev_kfree_skb_irq(np->cur_tx->skbuff);
 			np->cur_tx->skbuff = NULL;
 			--np->really_tx_count;
@@ -1554,6 +1605,10 @@
 				printk(KERN_DEBUG "  netdev_rx() normal Rx pkt length %d"
 				       " status %x.\n", pkt_len, rx_status);
 #endif
+			pci_dma_sync_single(np->pci_dev, np->cur_rx->buffer,
+				np->rx_buf_sz, PCI_DMA_FROMDEVICE);
+			pci_unmap_single(np->pci_dev, np->cur_rx->buffer,
+				np->rx_buf_sz, PCI_DMA_FROMDEVICE);
 
 			/* Check if the packet is long enough to accept without copying
 			   to a minimally-sized skbuff. */
@@ -1564,12 +1619,12 @@
 				/* Call copy + cksum if available. */
 
 #if ! defined(__alpha__)
-				eth_copy_and_sum(skb, bus_to_virt(np->cur_rx->buffer),
-						 pkt_len, 0);
+				eth_copy_and_sum(skb, 
+					np->cur_rx->skbuff->tail, pkt_len, 0);
 				skb_put(skb, pkt_len);
 #else
 				memcpy(skb_put(skb, pkt_len),
-				       bus_to_virt(np->cur_rx->buffer), pkt_len);
+					np->cur_rx->skbuff->tail, pkt_len);
 #endif
 			} else {
 				skb_put(skb = np->cur_rx->skbuff, pkt_len);
@@ -1592,7 +1647,8 @@
 
 			if (skb != NULL) {
 				skb->dev = dev;	/* Mark as being used by this device. */
-				np->cur_rx->buffer = virt_to_bus(skb->tail);
+				np->cur_rx->buffer = pci_map_single(np->pci_dev, skb->tail,
+					np->rx_buf_sz, PCI_DMA_FROMDEVICE);
 				np->cur_rx->skbuff = skb;
 				++np->really_rx_count;
 			}
@@ -1727,16 +1783,26 @@
 
 	/* Free all the skbuffs in the Rx queue. */
 	for (i = 0; i < RX_RING_SIZE; i++) {
+		struct sk_buff *skb = np->rx_ring[i].skbuff;
+
 		np->rx_ring[i].status = 0;
-		if (np->rx_ring[i].skbuff)
-			dev_kfree_skb(np->rx_ring[i].skbuff);
-		np->rx_ring[i].skbuff = NULL;
+		if (skb) {
+			pci_unmap_single(np->pci_dev, np->rx_ring[i].buffer,
+				np->rx_buf_sz, PCI_DMA_FROMDEVICE);
+			dev_kfree_skb(skb);
+			np->rx_ring[i].skbuff = NULL;
+		}
 	}
 
 	for (i = 0; i < TX_RING_SIZE; i++) {
-		if (np->tx_ring[i].skbuff)
-			dev_kfree_skb(np->tx_ring[i].skbuff);
-		np->tx_ring[i].skbuff = NULL;
+		struct sk_buff *skb = np->tx_ring[i].skbuff;
+
+		if (skb) {
+			pci_unmap_single(np->pci_dev, np->tx_ring[i].buffer,
+				skb->len, PCI_DMA_TODEVICE);
+			dev_kfree_skb(skb);
+			np->tx_ring[i].skbuff = NULL;
+		}
 	}
 
 	return 0;
diff -u --recursive --new-file v2.4.5/linux/drivers/net/fmv18x.c linux/drivers/net/fmv18x.c
--- v2.4.5/linux/drivers/net/fmv18x.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/fmv18x.c	Wed Jun 20 11:10:53 2001
@@ -628,6 +628,9 @@
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
 MODULE_PARM(net_debug, "i");
+MODULE_PARM_DESC(io, "FMV-18X I/O address");
+MODULE_PARM_DESC(irq, "FMV-18X IRQ number");
+MODULE_PARM_DESC(net_debug, "FMV-18X debug level (0-1,5-6)");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.4.5/linux/drivers/net/hamachi.c linux/drivers/net/hamachi.c
--- v2.4.5/linux/drivers/net/hamachi.c	Sat May 19 18:02:45 2001
+++ linux/drivers/net/hamachi.c	Wed Jun 20 11:10:53 2001
@@ -535,7 +535,22 @@
 MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM(force32, "i");
-
+MODULE_PARM_DESC(max_interrupt_work, "GNIC-II maximum events handled per interrupt");
+MODULE_PARM_DESC(mtu, "GNIC-II MTU (all boards)");
+MODULE_PARM_DESC(debug, "GNIC-II debug level (0-7)");
+MODULE_PARM_DESC(min_rx_pkt, "GNIC-II minimum Rx packets processed between interrupts");
+MODULE_PARM_DESC(max_rx_gap, "GNIC-II maximum Rx inter-packet gap in 8.192 microsecond units");
+MODULE_PARM_DESC(max_rx_latency, "GNIC-II time between Rx interrupts in 8.192 microsecond units");
+MODULE_PARM_DESC(min_tx_pkt, "GNIC-II minimum Tx packets processed between interrupts");
+MODULE_PARM_DESC(max_tx_gap, "GNIC-II maximum Tx inter-packet gap in 8.192 microsecond units");
+MODULE_PARM_DESC(max_tx_latency, "GNIC-II time between Tx interrupts in 8.192 microsecond units");
+MODULE_PARM_DESC(rx_copybreak, "GNIC-II copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(rx_params, "GNIC-II min_rx_pkt+max_rx_gap+max_rx_latency");
+MODULE_PARM_DESC(tx_params, "GNIC-II min_tx_pkt+max_tx_gap+max_tx_latency");
+MODULE_PARM_DESC(options, "GNIC-II Bits 0-3: media type, bits 4-6: as force32, bit 7: half duplex, bit 9 full duplex");
+MODULE_PARM_DESC(full_duplex, "GNIC-II full duplex setting(s) (1)");
+MODULE_PARM_DESC(force32, "GNIC-II: Bit 0: 32 bit PCI, bit 1: disable parity, bit 2: 64 bit PCI (all boards)");
+                                                                        
 static int read_eeprom(long ioaddr, int location);
 static int mdio_read(long ioaddr, int phy_id, int location);
 static void mdio_write(long ioaddr, int phy_id, int location, int value);
diff -u --recursive --new-file v2.4.5/linux/drivers/net/hamradio/bpqether.c linux/drivers/net/hamradio/bpqether.c
--- v2.4.5/linux/drivers/net/hamradio/bpqether.c	Wed Apr 18 14:40:06 2001
+++ linux/drivers/net/hamradio/bpqether.c	Wed Jun 27 17:10:55 2001
@@ -166,7 +166,7 @@
  */
 static int bpq_check_devices(struct net_device *dev)
 {
-	struct bpqdev *bpq, *bpq_prev;
+	struct bpqdev *bpq, *bpq_prev, *bpq_next;
 	int result = 0;
 	unsigned long flags;
 
@@ -175,7 +175,8 @@
 
 	bpq_prev = NULL;
 
-	for (bpq = bpq_devices; bpq != NULL; bpq = bpq->next) {
+	for (bpq = bpq_devices; bpq != NULL; bpq = bpq_next) {
+		bpq_next = bpq->next;
 		if (!dev_get(bpq->ethname)) {
 			if (bpq_prev)
 				bpq_prev->next = bpq->next;
@@ -192,8 +193,8 @@
 			unregister_netdevice(&bpq->axdev);
 			kfree(bpq);
 		}
-
-		bpq_prev = bpq;
+		else
+			bpq_prev = bpq;
 	}
 
 	restore_flags(flags);
diff -u --recursive --new-file v2.4.5/linux/drivers/net/hamradio/scc.c linux/drivers/net/hamradio/scc.c
--- v2.4.5/linux/drivers/net/hamradio/scc.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/hamradio/scc.c	Wed Jun 27 17:10:55 2001
@@ -216,7 +216,7 @@
 
 static unsigned char SCC_DriverName[] = "scc";
 
-static struct irqflags { unsigned char used : 1; } Ivec[16];
+static struct irqflags { unsigned char used : 1; } Ivec[NR_IRQS];
 	
 static struct scc_channel SCC_Info[2 * SCC_MAXCHIPS];	/* information per channel */
 
@@ -1484,7 +1484,7 @@
 	printk(KERN_INFO "Init Z8530 driver: %u channels, IRQ", Nchips*2);
 	
 	flag=" ";
-	for (k = 0; k < 16; k++)
+	for (k = 0; k < NR_IRQS; k++)
 		if (Ivec[k].used) 
 		{
 			printk("%s%d", flag, k);
@@ -1764,6 +1764,9 @@
 
 			if (hwcfg.irq == 2) hwcfg.irq = 9;
 
+			if (hwcfg.irq <0 || hwcfg.irq > NR_IRQS)
+				return -EINVAL;
+				
 			if (!Ivec[hwcfg.irq].used && hwcfg.irq)
 			{
 				if (request_irq(hwcfg.irq, scc_isr, SA_INTERRUPT, "AX.25 SCC", NULL))
@@ -2162,7 +2165,7 @@
 		}
 	}
 	
-	for (k=0; k < 16 ; k++)
+	for (k=0; k < NR_IRQS ; k++)
 		if (Ivec[k].used) free_irq(k, NULL);
 		
 	if (Vector_Latch)
diff -u --recursive --new-file v2.4.5/linux/drivers/net/hamradio/soundmodem/sm.h linux/drivers/net/hamradio/soundmodem/sm.h
--- v2.4.5/linux/drivers/net/hamradio/soundmodem/sm.h	Mon Dec 11 13:22:15 2000
+++ linux/drivers/net/hamradio/soundmodem/sm.h	Wed Jun 27 17:10:55 2001
@@ -299,6 +299,8 @@
 
 #ifdef __i386__
 
+#include <asm/msr.h>
+
 /*
  * only do 32bit cycle counter arithmetic; we hope we won't overflow.
  * in fact, overflowing modems would require over 2THz CPU clock speeds :-)
@@ -307,10 +309,10 @@
 #define time_exec(var,cmd)                                              \
 ({                                                                      \
 	if (cpu_has_tsc) {                                              \
-		unsigned int cnt1, cnt2, cnt3;                          \
-		__asm__(".byte 0x0f,0x31" : "=a" (cnt1), "=d" (cnt3));  \
+		unsigned int cnt1, cnt2;                                \
+		rdtscl(cnt1);                                           \
 		cmd;                                                    \
-		__asm__(".byte 0x0f,0x31" : "=a" (cnt2), "=d" (cnt3));  \
+		rdtscl(cnt2);                                           \
 		var = cnt2-cnt1;                                        \
 	} else {                                                        \
 		cmd;                                                    \
diff -u --recursive --new-file v2.4.5/linux/drivers/net/hamradio/soundmodem/sm_wss.c linux/drivers/net/hamradio/soundmodem/sm_wss.c
--- v2.4.5/linux/drivers/net/hamradio/soundmodem/sm_wss.c	Tue Jul 18 16:55:19 2000
+++ linux/drivers/net/hamradio/soundmodem/sm_wss.c	Wed Jun 27 17:10:55 2001
@@ -172,8 +172,10 @@
 		/* MCE and interface config reg */
 		write_codec(dev, 0x49, fdx ? 0x8 : 0xc);
 	outb(0xb, WSS_CODEC_IA(dev->base_addr)); /* leave MCE */
-	if (SCSTATE->crystal && !fullcalib)
+	if (SCSTATE->crystal && !fullcalib) {
+		restore_flags(flags);
 		return 0;
+	}
 	/*
 	 * wait for ACI start
 	 */
diff -u --recursive --new-file v2.4.5/linux/drivers/net/hp-plus.c linux/drivers/net/hp-plus.c
--- v2.4.5/linux/drivers/net/hp-plus.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/hp-plus.c	Wed Jun 20 11:10:53 2001
@@ -408,6 +408,8 @@
 
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_HPP_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_HPP_CARDS) "i");
+MODULE_PARM_DESC(io, "HP PC-LAN+ I/O port address(es)");
+MODULE_PARM_DESC(irq, "HP PC-LAN+ IRQ number(s); ignored if properly detected");
 
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
diff -u --recursive --new-file v2.4.5/linux/drivers/net/hp.c linux/drivers/net/hp.c
--- v2.4.5/linux/drivers/net/hp.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/hp.c	Wed Jun 20 11:10:53 2001
@@ -379,6 +379,8 @@
 
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_HP_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_HP_CARDS) "i");
+MODULE_PARM_DESC(io, "HP PC-LAN I/O base address(es)");
+MODULE_PARM_DESC(irq, "HP PC-LAN IRQ number(s) (assigned)");
 
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
diff -u --recursive --new-file v2.4.5/linux/drivers/net/ibmlana.c linux/drivers/net/ibmlana.c
--- v2.4.5/linux/drivers/net/ibmlana.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/ibmlana.c	Wed Jun 20 11:10:53 2001
@@ -1197,6 +1197,8 @@
 static int io;
 MODULE_PARM(irq, "i");
 MODULE_PARM(io, "i");
+MODULE_PARM_DESC(irq, "IBM LAN/A IRQ number");
+MODULE_PARM_DESC(io, "IBM LAN/A I/O base address");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.4.5/linux/drivers/net/lance.c linux/drivers/net/lance.c
--- v2.4.5/linux/drivers/net/lance.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/lance.c	Wed Jun 20 11:10:53 2001
@@ -299,6 +299,10 @@
 MODULE_PARM(dma, "1-" __MODULE_STRING(MAX_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_CARDS) "i");
 MODULE_PARM(lance_debug, "i");
+MODULE_PARM_DESC(io, "LANCE/PCnet I/O base address(es),required");
+MODULE_PARM_DESC(dma, "LANCE/PCnet ISA DMA channel (ignored for some devices)");
+MODULE_PARM_DESC(irq, "LANCE/PCnet IRQ number (ignored for some devices)");
+MODULE_PARM_DESC(lance_debug, "LANCE/PCnet debug level (0-7)");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.4.5/linux/drivers/net/lasi_82596.c linux/drivers/net/lasi_82596.c
--- v2.4.5/linux/drivers/net/lasi_82596.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/lasi_82596.c	Wed Jun 20 11:10:53 2001
@@ -181,7 +181,7 @@
 MODULE_AUTHOR("Richard Hirst");
 MODULE_DESCRIPTION("i82596 driver");
 MODULE_PARM(i596_debug, "i");
-
+MODULE_PARM_DESC(i596_debug, "lasi_82596 debug mask");
 
 /* Copy frames shorter than rx_copybreak, otherwise pass on up in
  * a full sized sk_buff.  Value of 100 stolen from tulip.c (!alpha).
diff -u --recursive --new-file v2.4.5/linux/drivers/net/lne390.c linux/drivers/net/lne390.c
--- v2.4.5/linux/drivers/net/lne390.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/lne390.c	Wed Jun 20 11:10:53 2001
@@ -381,6 +381,9 @@
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_LNE_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_LNE_CARDS) "i");
 MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_LNE_CARDS) "i");
+MODULE_PARM_DESC(io, "LNE390 I/O base address(es)");
+MODULE_PARM_DESC(irq, "LNE390 IRQ number(s)");
+MODULE_PARM_DESC(mem, "LNE390 memory base address(es)");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.4.5/linux/drivers/net/mac89x0.c linux/drivers/net/mac89x0.c
--- v2.4.5/linux/drivers/net/mac89x0.c	Tue Mar  6 19:28:35 2001
+++ linux/drivers/net/mac89x0.c	Wed Jun 20 11:10:53 2001
@@ -626,6 +626,7 @@
 static int debug;
 
 MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "CS89[02]0 debug level (0-5)");
 
 EXPORT_NO_SYMBOLS;
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/mace.c linux/drivers/net/mace.c
--- v2.4.5/linux/drivers/net/mace.c	Sun May 20 12:11:38 2001
+++ linux/drivers/net/mace.c	Wed Jun 20 11:10:53 2001
@@ -25,6 +25,7 @@
 static int port_aaui = -1;
 
 MODULE_PARM(port_aaui, "i");
+MODULE_PARM_DESC(port_aaui, "MACE uses AAUI port (0-1)");
 
 #define N_RX_RING	8
 #define N_TX_RING	6
diff -u --recursive --new-file v2.4.5/linux/drivers/net/macsonic.c linux/drivers/net/macsonic.c
--- v2.4.5/linux/drivers/net/macsonic.c	Sun Mar 25 18:24:31 2001
+++ linux/drivers/net/macsonic.c	Wed Jun 20 11:10:53 2001
@@ -575,6 +575,7 @@
 static struct net_device dev_macsonic;
 
 MODULE_PARM(sonic_debug, "i");
+MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)");
 
 EXPORT_NO_SYMBOLS;
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/natsemi.c linux/drivers/net/natsemi.c
--- v2.4.5/linux/drivers/net/natsemi.c	Sat May 19 18:02:45 2001
+++ linux/drivers/net/natsemi.c	Thu Jun 21 14:28:39 2001
@@ -51,10 +51,24 @@
 		* One-liner removal of a duplicate declaration of
 		netdev_error(). (uzi)
 
+	Version 1.0.7: (Manfred Spraul)
+		* pci dma
+		* SMP locking update
+		* full reset added into tx_timeout
+		* correct multicast hash generation (both big and little endian)
+			[copied from a natsemi driver version
+			 from Myrio Corporation, Greg Smith]
+		* suspend/resume
+
+	TODO:
+	* big endian support with CFG:BEM instead of cpu_to_le32
+	* support for an external PHY
+	* flow control
+	* Wake-On-LAN
 */
 
 #define DRV_NAME	"natsemi"
-#define DRV_VERSION	"1.07+LK1.0.6"
+#define DRV_VERSION	"1.07+LK1.0.7"
 #define DRV_RELDATE	"May 18, 2001"
 
 
@@ -111,6 +125,8 @@
 /* Time in jiffies before concluding the transmitter is hung. */
 #define TX_TIMEOUT  (2*HZ)
 
+#define NATSEMI_HW_TIMEOUT	200
+
 #define PKT_BUF_SZ		1536			/* Size of each temporary Rx buffer.*/
 
 #if !defined(__OPTIMIZE__)
@@ -119,6 +135,7 @@
 #error You must compile this driver with "-O".
 #endif
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
@@ -134,6 +151,8 @@
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/ethtool.h>
+#include <linux/delay.h>
+#include <linux/rtnetlink.h>
 #include <asm/processor.h>		/* Processor type for cache alignment. */
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -145,10 +164,6 @@
 KERN_INFO "  http://www.scyld.com/network/natsemi.html\n"
 KERN_INFO "  (unofficial 2.4.x kernel port, version " DRV_VERSION ", " DRV_RELDATE "  Jeff Garzik, Tjeerd Mulder)\n";
 
-/* Condensed operations for readability. */
-#define virt_to_le32desc(addr)  cpu_to_le32(virt_to_bus(addr))
-#define le32desc_to_virt(addr)  bus_to_virt(le32_to_cpu(addr))
-
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("National Semiconductor DP8381x series PCI Ethernet driver");
 MODULE_PARM(max_interrupt_work, "i");
@@ -157,6 +172,12 @@
 MODULE_PARM(rx_copybreak, "i");
 MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM_DESC(max_interrupt_work, "DP8381x maximum events handled per interrupt");
+MODULE_PARM_DESC(mtu, "DP8381x MTU (all boards)");
+MODULE_PARM_DESC(debug, "DP8381x debug level (0-5)");
+MODULE_PARM_DESC(rx_copybreak, "DP8381x copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(options, "DP8381x: Bits 0-3: media type, bit 17: full duplex");
+MODULE_PARM_DESC(full_duplex, "DP8381x full duplex setting(s) (1)");
 
 /*
 				Theory of Operation
@@ -330,15 +351,17 @@
 	DescPktOK=0x08000000, RxTooLong=0x00400000,
 };
 
-#define PRIV_ALIGN	15 	/* Required alignment mask */
 struct netdev_private {
 	/* Descriptor rings first for alignment. */
-	struct netdev_desc rx_ring[RX_RING_SIZE];
-	struct netdev_desc tx_ring[TX_RING_SIZE];
+	dma_addr_t ring_dma;
+	struct netdev_desc* rx_ring;
+	struct netdev_desc* tx_ring;
 	/* The addresses of receive-in-place skbuffs. */
 	struct sk_buff* rx_skbuff[RX_RING_SIZE];
+	dma_addr_t rx_dma[RX_RING_SIZE];
 	/* The saved address of a sent-in-place packet/buffer, for later free(). */
 	struct sk_buff* tx_skbuff[TX_RING_SIZE];
+	dma_addr_t tx_dma[TX_RING_SIZE];
 	struct net_device_stats stats;
 	struct timer_list timer;	/* Media monitoring timer. */
 	/* Frequently used values: keep some adjacent for cache effect. */
@@ -348,10 +371,7 @@
 	unsigned int cur_tx, dirty_tx;
 	unsigned int rx_buf_sz;				/* Based on MTU+slack. */
 	/* These values are keep track of the transceiver/media in use. */
-	unsigned int full_duplex:1;			/* Full-duplex operation requested. */
-	unsigned int duplex_lock:1;
-	unsigned int medialock:1;			/* Do not sense media. */
-	unsigned int default_port:4;		/* Last dev->if_port value. */
+	unsigned int full_duplex;
 	/* Rx filter. */
 	u32 cur_rx_mode;
 	u32 rx_filter[16];
@@ -360,24 +380,31 @@
 	/* original contents of ClkRun register */
 	u32 SavedClkRun;
 	/* MII transceiver section. */
-	u16 advertising;					/* NWay media advertisement */
-	
+	u16 advertising;			/* NWay media advertisement */
 	unsigned int iosize;
 	spinlock_t lock;
 };
 
 static int  eeprom_read(long ioaddr, int location);
 static int  mdio_read(struct net_device *dev, int phy_id, int location);
+static void natsemi_reset(struct net_device *dev);
 static int  netdev_open(struct net_device *dev);
-static void check_duplex(struct net_device *dev);
+static void check_link(struct net_device *dev);
 static void netdev_timer(unsigned long data);
 static void tx_timeout(struct net_device *dev);
+static int alloc_ring(struct net_device *dev);
 static void init_ring(struct net_device *dev);
+static void drain_ring(struct net_device *dev);
+static void free_ring(struct net_device *dev);
+static void init_registers(struct net_device *dev);
 static int  start_tx(struct sk_buff *skb, struct net_device *dev);
 static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
 static void netdev_error(struct net_device *dev, int intr_status);
-static int  netdev_rx(struct net_device *dev);
+static void netdev_rx(struct net_device *dev);
+static void netdev_tx_done(struct net_device *dev);
+static void __set_rx_mode(struct net_device *dev);
 static void set_rx_mode(struct net_device *dev);
+static void __get_stats(struct net_device *dev);
 static struct net_device_stats *get_stats(struct net_device *dev);
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static int  netdev_close(struct net_device *dev);
@@ -417,7 +444,6 @@
 	}
 
 	find_cnt++;
-	option = find_cnt < MAX_UNITS ? options[find_cnt] : 0;
 	ioaddr = pci_resource_start(pdev, pcibar);
 	iosize = pci_resource_len(pdev, pcibar);
 	irq = pdev->irq;
@@ -455,9 +481,6 @@
 		prev_eedata = eedata;
 	}
 
-	/* Reset the chip to erase previous misconfiguration. */
-	writel(ChipReset, ioaddr + ChipCmd);
-
 	dev->base_addr = ioaddr;
 	dev->irq = irq;
 
@@ -468,6 +491,9 @@
 	np->iosize = iosize;
 	spin_lock_init(&np->lock);
 
+	/* Reset the chip to erase previous misconfiguration. */
+	natsemi_reset(dev);
+	option = find_cnt < MAX_UNITS ? options[find_cnt] : 0;
 	if (dev->mem_start)
 		option = dev->mem_start;
 
@@ -475,16 +501,13 @@
 	if (option > 0) {
 		if (option & 0x200)
 			np->full_duplex = 1;
-		np->default_port = option & 15;
-		if (np->default_port)
-			np->medialock = 1;
+		if (option & 15)
+			printk(KERN_INFO "%s: ignoring user supplied media type %d",
+				dev->name, option & 15);
 	}
 	if (find_cnt < MAX_UNITS  &&  full_duplex[find_cnt] > 0)
 		np->full_duplex = 1;
 
-	if (np->full_duplex)
-		np->duplex_lock = 1;
-
 	/* The chip-specific entries in the device structure. */
 	dev->open = &netdev_open;
 	dev->hard_start_xmit = &start_tx;
@@ -598,6 +621,25 @@
 		return 0xffff;
 }
 
+static void natsemi_reset(struct net_device *dev)
+{
+	int i;
+
+	writel(ChipReset, dev->base_addr + ChipCmd);
+	for (i=0;i<NATSEMI_HW_TIMEOUT;i++) {
+		if (!(readl(dev->base_addr + ChipCmd) & ChipReset))
+			break;
+		udelay(5);
+	}
+	if (i==NATSEMI_HW_TIMEOUT && debug) {
+		printk(KERN_INFO "%s: reset did not complete in %d usec.\n",
+		   dev->name, i*5);
+	} else if (debug > 2) {
+		printk(KERN_DEBUG "%s: reset completed in %d usec.\n",
+		   dev->name, i*5);
+	}
+}
+
 
 static int netdev_open(struct net_device *dev)
 {
@@ -606,25 +648,7 @@
 	int i;
 
 	/* Reset the chip, just in case. */
-	writel(ChipReset, ioaddr + ChipCmd);
-
-	/* On page 78 of the spec, they recommend some settings for "optimum
-	   performance" to be done in sequence.  These settings optimize some
-	   of the 100Mbit autodetection circuitry.  Also, we only want to do
-	   this for rev C of the chip.
-	*/
-	if (readl(ioaddr + SiliconRev) == 0x302) {
-		writew(0x0001, ioaddr + PGSEL);
-		writew(0x189C, ioaddr + PMDCSR);
-		writew(0x0000, ioaddr + TSTDAT);
-		writew(0x5040, ioaddr + DSPCFG);
-		writew(0x008C, ioaddr + SDCFG);
-	}
-
-	/* Enable PHY Specific event based interrupts.  Link state change
-	   and Auto-Negotiation Completion are among the affected.
-	*/
-	writew(0x0002, ioaddr + MIntrCtrl);
+	natsemi_reset(dev);
 
 	i = request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev);
 	if (i) return i;
@@ -632,56 +656,16 @@
 	if (debug > 1)
 		printk(KERN_DEBUG "%s: netdev_open() irq %d.\n",
 			   dev->name, dev->irq);
-
-	init_ring(dev);
-
-	writel(virt_to_bus(np->rx_ring), ioaddr + RxRingPtr);
-	writel(virt_to_bus(np->tx_ring), ioaddr + TxRingPtr);
-
-	for (i = 0; i < ETH_ALEN; i += 2) {
-		writel(i, ioaddr + RxFilterAddr);
-		writew(dev->dev_addr[i] + (dev->dev_addr[i+1] << 8),
-			   ioaddr + RxFilterData);
-	}
-
-	/* Initialize other registers. */
-	/* Configure the PCI bus bursts and FIFO thresholds. */
-	/* Configure for standard, in-spec Ethernet. */
-
-	if (readl(ioaddr + ChipConfig) & 0x20000000) {	/* Full duplex */
-		np->tx_config = 0xD0801002;
-		np->rx_config = 0x10000020;
-	} else {
-		np->tx_config = 0x10801002;
-		np->rx_config = 0x0020;
+	i = alloc_ring(dev);
+	if (i < 0) {
+		free_irq(dev->irq, dev);
+		return i;
 	}
-	writel(np->tx_config, ioaddr + TxConfig);
-	writel(np->rx_config, ioaddr + RxConfig);
-
-	if (dev->if_port == 0)
-		dev->if_port = np->default_port;
-
-	/* Disable PME:
-	 * The PME bit is initialized from the EEPROM contents.
-	 * PCI cards probably have PME disabled, but motherboard
-	 * implementations may have PME set to enable WakeOnLan. 
-	 * With PME set the chip will scan incoming packets but
-	 * nothing will be written to memory. */
-	np->SavedClkRun = readl(ioaddr + ClkRun);
-	writel(np->SavedClkRun & ~0x100, ioaddr + ClkRun);
+	init_ring(dev);
+	init_registers(dev);
 
 	netif_start_queue(dev);
 
-	check_duplex(dev);
-	set_rx_mode(dev);
-
-	/* Enable interrupts by setting the interrupt mask. */
-	writel(IntrNormalSummary | IntrAbnormalSummary | 0x1f, ioaddr + IntrMask);
-	writel(1, ioaddr + IntrEnable);
-
-	writel(RxOn | TxOn, ioaddr + ChipCmd);
-	writel(4, ioaddr + StatsCtrl); 					/* Clear Stats */
-
 	if (debug > 2)
 		printk(KERN_DEBUG "%s: Done netdev_open(), status: %x.\n",
 			   dev->name, (int)readl(ioaddr + ChipCmd));
@@ -696,17 +680,33 @@
 	return 0;
 }
 
-static void check_duplex(struct net_device *dev)
+static void check_link(struct net_device *dev)
 {
 	struct netdev_private *np = dev->priv;
 	long ioaddr = dev->base_addr;
 	int duplex;
+	int chipcfg = readl(ioaddr + ChipConfig);
 
-	if (np->duplex_lock)
+	if(!(chipcfg & 0x80000000)) {
+		if (netif_carrier_ok(dev)) {
+			if (debug)
+				printk(KERN_INFO "%s: no link. Disabling watchdog.\n",
+					dev->name);
+			netif_carrier_off(dev);
+		}
 		return;
-	duplex = readl(ioaddr + ChipConfig) & 0x20000000 ? 1 : 0;
-	if (np->full_duplex != duplex) {
-		np->full_duplex = duplex;
+	}
+	if (!netif_carrier_ok(dev)) {
+		if (debug)
+			printk(KERN_INFO "%s: link is back. Enabling watchdog.\n",
+					dev->name);
+		netif_carrier_on(dev);
+	}
+
+	duplex = np->full_duplex || (chipcfg & 0x20000000 ? 1 : 0);
+
+	/* if duplex is set then bit 28 must be set, too */
+	if (duplex ^ !!(np->rx_config & 0x10000000)) {
 		if (debug)
 			printk(KERN_INFO "%s: Setting %s-duplex based on negotiated link"
 				   " capability.\n", dev->name,
@@ -723,17 +723,104 @@
 	}
 }
 
+static void init_registers(struct net_device *dev)
+{
+	struct netdev_private *np = dev->priv;
+	long ioaddr = dev->base_addr;
+	int i;
+
+	if (debug > 4)
+		printk(KERN_DEBUG "%s: found silicon revision %xh.\n",
+				dev->name, readl(ioaddr + SiliconRev));
+	/* On page 78 of the spec, they recommend some settings for "optimum
+	   performance" to be done in sequence.  These settings optimize some
+	   of the 100Mbit autodetection circuitry.  Also, we only want to do
+	   this for rev C of the chip.
+
+	   There seems to be a typo on page 78: the fixup should be performed
+	   for "DP83815CVNG (SRR = 203h)", but the description of the
+	   SiliconRev regsiters says "DP83815CVNG: 00000302h"
+	*/
+	if (readl(ioaddr + SiliconRev) == 0x302) {
+		writew(0x0001, ioaddr + PGSEL);
+		writew(0x189C, ioaddr + PMDCSR);
+		writew(0x0000, ioaddr + TSTDAT);
+		writew(0x5040, ioaddr + DSPCFG);
+		writew(0x008C, ioaddr + SDCFG);
+	}
+
+	/* Enable PHY Specific event based interrupts.  Link state change
+	   and Auto-Negotiation Completion are among the affected.
+	*/
+	writew(0x0002, ioaddr + MIntrCtrl);
+
+	writel(np->ring_dma, ioaddr + RxRingPtr);
+	writel(np->ring_dma + RX_RING_SIZE * sizeof(struct netdev_desc), ioaddr + TxRingPtr);
+
+	for (i = 0; i < ETH_ALEN; i += 2) {
+		writel(i, ioaddr + RxFilterAddr);
+		writew(dev->dev_addr[i] + (dev->dev_addr[i+1] << 8),
+			   ioaddr + RxFilterData);
+	}
+
+	/* Initialize other registers.
+	 * Configure the PCI bus bursts and FIFO thresholds.
+	 * Configure for standard, in-spec Ethernet.
+	 * Start with half-duplex. check_link will update
+	 * to the correct settings. 
+	 */
+
+	/* DRTH: 2: start tx if 64 bytes are in the fifo
+	 * FLTH: 0x10: refill with next packet if 512 bytes are free
+	 * MXDMA: 0: up to 512 byte bursts.
+	 * 	MXDMA must be <= FLTH
+	 * ECRETRY=1
+	 * ATP=1
+	 */
+	np->tx_config = 0x10801002;
+	/* DRTH 0x10: start copying to memory if 128 bytes are in the fifo
+	 * MXDMA 0: up to 512 byte bursts
+	 */
+	np->rx_config = 0x0020;
+	writel(np->tx_config, ioaddr + TxConfig);
+	writel(np->rx_config, ioaddr + RxConfig);
+
+	/* Disable PME:
+	 * The PME bit is initialized from the EEPROM contents.
+	 * PCI cards probably have PME disabled, but motherboard
+	 * implementations may have PME set to enable WakeOnLan. 
+	 * With PME set the chip will scan incoming packets but
+	 * nothing will be written to memory. */
+	np->SavedClkRun = readl(ioaddr + ClkRun);
+	writel(np->SavedClkRun & ~0x100, ioaddr + ClkRun);
+
+	check_link(dev);
+	__set_rx_mode(dev);
+
+	/* Enable interrupts by setting the interrupt mask. */
+	writel(IntrNormalSummary | IntrAbnormalSummary | 0x1f, ioaddr + IntrMask);
+	writel(1, ioaddr + IntrEnable);
+
+	writel(RxOn | TxOn, ioaddr + ChipCmd);
+	writel(4, ioaddr + StatsCtrl); 					/* Clear Stats */
+}
+
 static void netdev_timer(unsigned long data)
 {
 	struct net_device *dev = (struct net_device *)data;
 	struct netdev_private *np = dev->priv;
-	long ioaddr = dev->base_addr;
 	int next_tick = 60*HZ;
 
-	if (debug > 3)
-		printk(KERN_DEBUG "%s: Media selection timer tick, status %8.8x.\n",
-			   dev->name, (int)readl(ioaddr + IntrStatus));
-	check_duplex(dev);
+	if (debug > 3) {
+		/* DO NOT read the IntrStatus register, 
+		 * a read clears any pending interrupts.
+		 */
+		printk(KERN_DEBUG "%s: Media selection timer tick.\n",
+			   dev->name);
+	}
+	spin_lock_irq(&np->lock);
+	check_link(dev);
+	spin_unlock_irq(&np->lock);
 	np->timer.expires = jiffies + next_tick;
 	add_timer(&np->timer);
 }
@@ -746,30 +833,39 @@
 	printk(KERN_WARNING "%s: Transmit timed out, status %8.8x,"
 		   " resetting...\n", dev->name, (int)readl(ioaddr + TxRingPtr));
 
-#ifndef __alpha__
 	{
 		int i;
-		printk(KERN_DEBUG "  Rx ring %8.8x: ", (int)np->rx_ring);
+		printk(KERN_DEBUG "  Rx ring %p: ", np->rx_ring);
 		for (i = 0; i < RX_RING_SIZE; i++)
 			printk(" %8.8x", (unsigned int)np->rx_ring[i].cmd_status);
-		printk("\n"KERN_DEBUG"  Tx ring %8.8x: ", (int)np->tx_ring);
+		printk("\n"KERN_DEBUG"  Tx ring %p: ", np->tx_ring);
 		for (i = 0; i < TX_RING_SIZE; i++)
 			printk(" %4.4x", np->tx_ring[i].cmd_status);
 		printk("\n");
 	}
-#endif
-
-	/* Perhaps we should reinitialize the hardware here. */
-	dev->if_port = 0;
-	/* Stop and restart the chip's Tx processes . */
-
-	/* Trigger an immediate transmit demand. */
+	spin_lock_irq(&np->lock);
+	natsemi_reset(dev);
+	drain_ring(dev);
+	init_ring(dev);
+	init_registers(dev);
+	spin_unlock_irq(&np->lock);
 
 	dev->trans_start = jiffies;
 	np->stats.tx_errors++;
 	netif_wake_queue(dev);
 }
 
+static int alloc_ring(struct net_device *dev)
+{
+	struct netdev_private *np = dev->priv;
+	np->rx_ring = pci_alloc_consistent(np->pci_dev,
+				sizeof(struct netdev_desc) * (RX_RING_SIZE+TX_RING_SIZE),
+				&np->ring_dma);
+	if (!np->rx_ring)
+		return -ENOMEM;
+	np->tx_ring = &np->rx_ring[RX_RING_SIZE];
+	return 0;
+}
 
 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
 static void init_ring(struct net_device *dev)
@@ -785,12 +881,12 @@
 
 	/* Initialize all Rx descriptors. */
 	for (i = 0; i < RX_RING_SIZE; i++) {
-		np->rx_ring[i].next_desc = virt_to_le32desc(&np->rx_ring[i+1]);
-		np->rx_ring[i].cmd_status = DescOwn;
-		np->rx_skbuff[i] = 0;
+		np->rx_ring[i].next_desc = cpu_to_le32(np->ring_dma+sizeof(struct netdev_desc)*(i+1));
+		np->rx_ring[i].cmd_status = cpu_to_le32(DescOwn);
+		np->rx_skbuff[i] = NULL;
 	}
 	/* Mark the last entry as wrapping the ring. */
-	np->rx_ring[i-1].next_desc = virt_to_le32desc(&np->rx_ring[0]);
+	np->rx_ring[i-1].next_desc = cpu_to_le32(np->ring_dma);
 
 	/* Fill in the Rx buffers.  Handle allocation failure gracefully. */
 	for (i = 0; i < RX_RING_SIZE; i++) {
@@ -799,19 +895,59 @@
 		if (skb == NULL)
 			break;
 		skb->dev = dev;			/* Mark as being used by this device. */
-		np->rx_ring[i].addr = virt_to_le32desc(skb->tail);
-		np->rx_ring[i].cmd_status =
-			cpu_to_le32(DescIntr | np->rx_buf_sz);
+		np->rx_dma[i] = pci_map_single(np->pci_dev,
+						skb->data, skb->len, PCI_DMA_FROMDEVICE);
+		np->rx_ring[i].addr = cpu_to_le32(np->rx_dma[i]);
+		np->rx_ring[i].cmd_status = cpu_to_le32(DescIntr | np->rx_buf_sz);
 	}
 	np->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
 
 	for (i = 0; i < TX_RING_SIZE; i++) {
-		np->tx_skbuff[i] = 0;
-		np->tx_ring[i].next_desc = virt_to_le32desc(&np->tx_ring[i+1]);
+		np->tx_skbuff[i] = NULL;
+		np->tx_ring[i].next_desc = cpu_to_le32(np->ring_dma
+					+sizeof(struct netdev_desc)*(i+1+RX_RING_SIZE));
 		np->tx_ring[i].cmd_status = 0;
 	}
-	np->tx_ring[i-1].next_desc = virt_to_le32desc(&np->tx_ring[0]);
-	return;
+	np->tx_ring[i-1].next_desc = cpu_to_le32(np->ring_dma
+					+sizeof(struct netdev_desc)*(RX_RING_SIZE));
+}
+
+static void drain_ring(struct net_device *dev)
+{
+	struct netdev_private *np = dev->priv;
+	int i;
+
+	/* Free all the skbuffs in the Rx queue. */
+	for (i = 0; i < RX_RING_SIZE; i++) {
+		np->rx_ring[i].cmd_status = 0;
+		np->rx_ring[i].addr = 0xBADF00D0; /* An invalid address. */
+		if (np->rx_skbuff[i]) {
+			pci_unmap_single(np->pci_dev,
+						np->rx_dma[i],
+						np->rx_skbuff[i]->len,
+						PCI_DMA_FROMDEVICE);
+			dev_kfree_skb(np->rx_skbuff[i]);
+		}
+		np->rx_skbuff[i] = NULL;
+	}
+	for (i = 0; i < TX_RING_SIZE; i++) {
+		if (np->tx_skbuff[i]) {
+			pci_unmap_single(np->pci_dev,
+						np->rx_dma[i],
+						np->rx_skbuff[i]->len,
+						PCI_DMA_TODEVICE);
+			dev_kfree_skb(np->tx_skbuff[i]);
+		}
+		np->tx_skbuff[i] = NULL;
+	}
+}
+
+static void free_ring(struct net_device *dev)
+{
+	struct netdev_private *np = dev->priv;
+	pci_free_consistent(np->pci_dev,
+				sizeof(struct netdev_desc) * (RX_RING_SIZE+TX_RING_SIZE),
+				np->rx_ring, np->ring_dma);
 }
 
 static int start_tx(struct sk_buff *skb, struct net_device *dev)
@@ -826,17 +962,26 @@
 	entry = np->cur_tx % TX_RING_SIZE;
 
 	np->tx_skbuff[entry] = skb;
+	np->tx_dma[entry] = pci_map_single(np->pci_dev,
+				skb->data,skb->len, PCI_DMA_TODEVICE);
 
-	np->tx_ring[entry].addr = virt_to_le32desc(skb->data);
-	np->tx_ring[entry].cmd_status = cpu_to_le32(DescOwn|DescIntr | skb->len);
-	np->cur_tx++;
+	np->tx_ring[entry].addr = cpu_to_le32(np->tx_dma[entry]);
+
+	spin_lock_irq(&np->lock);
 
+#if 0
+	np->tx_ring[entry].cmd_status = cpu_to_le32(DescOwn | DescIntr | skb->len);
+#else
+	np->tx_ring[entry].cmd_status = cpu_to_le32(DescOwn | skb->len);
+#endif
 	/* StrongARM: Explicitly cache flush np->tx_ring and skb->data,skb->len. */
 	wmb();
-
-	spin_lock_irq(&np->lock);
-	if (np->cur_tx - np->dirty_tx >= TX_QUEUE_LEN - 1)
-		netif_stop_queue(dev);
+	np->cur_tx++;
+	if (np->cur_tx - np->dirty_tx >= TX_QUEUE_LEN - 1) {
+		netdev_tx_done(dev);
+		if (np->cur_tx - np->dirty_tx >= TX_QUEUE_LEN - 1)
+			netif_stop_queue(dev);
+	}
 	spin_unlock_irq(&np->lock);
 
 	/* Wake the potentially-idle transmit channel. */
@@ -851,6 +996,48 @@
 	return 0;
 }
 
+static void netdev_tx_done(struct net_device *dev)
+{
+	struct netdev_private *np = dev->priv;
+
+	for (; np->cur_tx - np->dirty_tx > 0; np->dirty_tx++) {
+		int entry = np->dirty_tx % TX_RING_SIZE;
+		if (np->tx_ring[entry].cmd_status & cpu_to_le32(DescOwn)) {
+			if (debug > 4)
+				printk(KERN_DEBUG "%s: tx frame #%d is busy.\n",
+						dev->name, np->dirty_tx);
+			break;
+		}
+		if (debug > 4)
+			printk(KERN_DEBUG "%s: tx frame #%d finished with status %8.8xh.\n",
+					dev->name, np->dirty_tx,
+					le32_to_cpu(np->tx_ring[entry].cmd_status));
+		if (np->tx_ring[entry].cmd_status & cpu_to_le32(0x08000000)) {
+			np->stats.tx_packets++;
+			np->stats.tx_bytes += np->tx_skbuff[entry]->len;
+		} else {			/* Various Tx errors */
+			int tx_status = le32_to_cpu(np->tx_ring[entry].cmd_status);
+			if (tx_status & 0x04010000) np->stats.tx_aborted_errors++;
+			if (tx_status & 0x02000000) np->stats.tx_fifo_errors++;
+			if (tx_status & 0x01000000) np->stats.tx_carrier_errors++;
+			if (tx_status & 0x00200000) np->stats.tx_window_errors++;
+			np->stats.tx_errors++;
+		}
+		pci_unmap_single(np->pci_dev,np->tx_dma[entry],
+					np->tx_skbuff[entry]->len,
+					PCI_DMA_TODEVICE);
+		/* Free the original skb. */
+		dev_kfree_skb_irq(np->tx_skbuff[entry]);
+		np->tx_skbuff[entry] = NULL;
+	}
+	if (netif_queue_stopped(dev)
+		&& np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) {
+		/* The ring is no longer full, wake queue. */
+		netif_wake_queue(dev);
+	}
+	spin_unlock(&np->lock);
+
+}
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
 static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
@@ -864,11 +1051,9 @@
 	np = dev->priv;
 
 	do {
+		/* Reading automatically acknowledges all int sources. */
 		u32 intr_status = readl(ioaddr + IntrStatus);
 
-		/* Acknowledge all of the current interrupt sources ASAP. */
-		writel(intr_status & 0x000ffff, ioaddr + IntrStatus);
-
 		if (debug > 4)
 			printk(KERN_DEBUG "%s: Interrupt, status %4.4x.\n",
 				   dev->name, intr_status);
@@ -879,35 +1064,12 @@
 		if (intr_status & (IntrRxDone | IntrRxIntr))
 			netdev_rx(dev);
 
-		spin_lock(&np->lock);
-
-		for (; np->cur_tx - np->dirty_tx > 0; np->dirty_tx++) {
-			int entry = np->dirty_tx % TX_RING_SIZE;
-			if (np->tx_ring[entry].cmd_status & cpu_to_le32(DescOwn))
-				break;
-			if (np->tx_ring[entry].cmd_status & cpu_to_le32(0x08000000)) {
-				np->stats.tx_packets++;
-				np->stats.tx_bytes += np->tx_skbuff[entry]->len;
-			} else {			/* Various Tx errors */
-				int tx_status = le32_to_cpu(np->tx_ring[entry].cmd_status);
-				if (tx_status & 0x04010000) np->stats.tx_aborted_errors++;
-				if (tx_status & 0x02000000) np->stats.tx_fifo_errors++;
-				if (tx_status & 0x01000000) np->stats.tx_carrier_errors++;
-				if (tx_status & 0x00200000) np->stats.tx_window_errors++;
-				np->stats.tx_errors++;
-			}
-			/* Free the original skb. */
-			dev_kfree_skb_irq(np->tx_skbuff[entry]);
-			np->tx_skbuff[entry] = 0;
-		}
-		if (netif_queue_stopped(dev)
-			&& np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) {
-			/* The ring is no longer full, wake queue. */
-			netif_wake_queue(dev);
+		if (intr_status & (IntrTxDone | IntrTxIntr | IntrTxIdle | IntrTxErr) ) {
+			spin_lock(&np->lock);
+			netdev_tx_done(dev);
+			spin_unlock(&np->lock);
 		}
 
-		spin_unlock(&np->lock);
-
 		/* Abnormal error summary/uncommon events handlers. */
 		if (intr_status & IntrAbnormalSummary)
 			netdev_error(dev, intr_status);
@@ -921,13 +1083,13 @@
 	} while (1);
 
 	if (debug > 3)
-		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
-			   dev->name, (int)readl(ioaddr + IntrStatus));
+		printk(KERN_DEBUG "%s: exiting interrupt.\n",
+			   dev->name);
 }
 
 /* This routine is logically part of the interrupt handler, but separated
    for clarity and better register allocation. */
-static int netdev_rx(struct net_device *dev)
+static void netdev_rx(struct net_device *dev)
 {
 	struct netdev_private *np = dev->priv;
 	int entry = np->cur_rx % RX_RING_SIZE;
@@ -967,6 +1129,9 @@
 				&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
 				skb->dev = dev;
 				skb_reserve(skb, 2);	/* 16 byte align the IP header */
+				pci_dma_sync_single(np->pci_dev, np->rx_dma[entry],
+							np->rx_skbuff[entry]->len,
+							PCI_DMA_FROMDEVICE);
 #if HAS_IP_COPYSUM
 				eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0);
 				skb_put(skb, pkt_len);
@@ -975,16 +1140,11 @@
 					   pkt_len);
 #endif
 			} else {
-				char *temp = skb_put(skb = np->rx_skbuff[entry], pkt_len);
+				pci_unmap_single(np->pci_dev, np->rx_dma[entry],
+							np->rx_skbuff[entry]->len,
+							PCI_DMA_FROMDEVICE);
+				skb_put(skb = np->rx_skbuff[entry], pkt_len);
 				np->rx_skbuff[entry] = NULL;
-#ifndef final_version				/* Remove after testing. */
-				if (le32desc_to_virt(np->rx_ring[entry].addr) != temp)
-					printk(KERN_ERR "%s: Internal fault: The skbuff addresses "
-						   "do not match in netdev_rx: %p vs. %p / %p.\n",
-						   dev->name,
-						   le32desc_to_virt(np->rx_ring[entry].addr),
-						   skb->head, temp);
-#endif
 			}
 			skb->protocol = eth_type_trans(skb, dev);
 			/* W/ hardware checksum: skb->ip_summed = CHECKSUM_UNNECESSARY; */
@@ -1008,7 +1168,9 @@
 			if (skb == NULL)
 				break;				/* Better luck next round. */
 			skb->dev = dev;			/* Mark as being used by this device. */
-			np->rx_ring[entry].addr = virt_to_le32desc(skb->tail);
+			np->rx_dma[entry] = pci_map_single(np->pci_dev,
+							skb->data, skb->len, PCI_DMA_FROMDEVICE);
+			np->rx_ring[entry].addr = cpu_to_le32(np->rx_dma[entry]);
 		}
 		np->rx_ring[entry].cmd_status =
 			cpu_to_le32(DescIntr | np->rx_buf_sz);
@@ -1016,7 +1178,6 @@
 
 	/* Restart Rx engine if stopped. */
 	writel(RxOn, dev->base_addr + ChipCmd);
-	return 0;
 }
 
 static void netdev_error(struct net_device *dev, int intr_status)
@@ -1024,20 +1185,24 @@
 	struct netdev_private *np = dev->priv;
 	long ioaddr = dev->base_addr;
 
+	spin_lock(&np->lock);
 	if (intr_status & LinkChange) {
 		printk(KERN_NOTICE "%s: Link changed: Autonegotiation advertising"
 			   " %4.4x  partner %4.4x.\n", dev->name,
 			   (int)readl(ioaddr + 0x90), (int)readl(ioaddr + 0x94));
 		/* read MII int status to clear the flag */
 		readw(ioaddr + MIntrStatus);
-		check_duplex(dev);
+		check_link(dev);
 	}
 	if (intr_status & StatsMax) {
-		get_stats(dev);
+		__get_stats(dev);
 	}
 	if (intr_status & IntrTxUnderrun) {
 		if ((np->tx_config & 0x3f) < 62)
 			np->tx_config += 2;
+		if (debug > 2)
+			printk(KERN_NOTICE "%s: increasing Tx theshold, new tx cfg %8.8xh.\n",
+					dev->name, np->tx_config);
 		writel(np->tx_config, ioaddr + TxConfig);
 	}
 	if (intr_status & WOLPkt) {
@@ -1054,23 +1219,30 @@
 		np->stats.tx_fifo_errors++;
 		np->stats.rx_fifo_errors++;
 	}
+	spin_unlock(&np->lock);
 }
 
-static struct net_device_stats *get_stats(struct net_device *dev)
+static void __get_stats(struct net_device *dev)
 {
 	long ioaddr = dev->base_addr;
 	struct netdev_private *np = dev->priv;
 
-	/* We should lock this segment of code for SMP eventually, although
-	   the vulnerability window is very small and statistics are
-	   non-critical. */
 	/* The chip only need report frame silently dropped. */
 	np->stats.rx_crc_errors	+= readl(ioaddr + RxCRCErrs);
 	np->stats.rx_missed_errors	+= readl(ioaddr + RxMissed);
+}
+
+static struct net_device_stats *get_stats(struct net_device *dev)
+{
+	struct netdev_private *np = dev->priv;
+
+	/* The chip only need report frame silently dropped. */
+	spin_lock_irq(&np->lock);
+	__get_stats(dev);
+	spin_unlock_irq(&np->lock);
 
 	return &np->stats;
 }
-
 /* The little-endian AUTODIN II ethernet CRC calculations.
    A big-endian version is also available.
    This is slow but compact code.  Do not use this routine for bulk data,
@@ -1079,6 +1251,7 @@
    Chips may use the upper or lower CRC bits, and may reverse and/or invert
    them.  Select the endian-ness that results in minimal calculations.
 */
+#if 0
 static unsigned const ethernet_polynomial_le = 0xedb88320U;
 static inline unsigned ether_crc_le(int length, unsigned char *data)
 {
@@ -1096,8 +1269,41 @@
 	}
 	return crc;
 }
+#else
+#define DP_POLYNOMIAL			0x04C11DB7
+/* dp83815_crc - computer CRC for hash table entries */
+static unsigned ether_crc_le(int length, unsigned char *data)
+{
+    u32 crc;
+    u8 cur_byte;
+    u8 msb;
+    u8 byte, bit;
+
+    crc = ~0;
+    for (byte=0; byte<length; byte++) {
+        cur_byte = *data++;
+        for (bit=0; bit<8; bit++) {
+            msb = crc >> 31;
+            crc <<= 1;
+            if (msb ^ (cur_byte & 1)) {
+                crc ^= DP_POLYNOMIAL;
+                crc |= 1;
+            }
+            cur_byte >>= 1;
+        }
+    }
+    crc >>= 23;
 
-static void set_rx_mode(struct net_device *dev)
+    return (crc);
+}
+#endif
+
+void set_bit_le(int offset, unsigned char * data)
+{
+	data[offset >> 3] |= (1 << (offset & 0x07));
+}
+#define HASH_TABLE	0x200
+static void __set_rx_mode(struct net_device *dev)
 {
 	long ioaddr = dev->base_addr;
 	struct netdev_private *np = dev->priv;
@@ -1118,17 +1324,25 @@
 		memset(mc_filter, 0, sizeof(mc_filter));
 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
 			 i++, mclist = mclist->next) {
-			set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x1ff,
+			set_bit_le(ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x1ff,
 					mc_filter);
 		}
 		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
 		for (i = 0; i < 64; i += 2) {
-			writew(0x200 + i, ioaddr + RxFilterAddr);
+			writew(HASH_TABLE + i, ioaddr + RxFilterAddr);
 			writew((mc_filter[i+1]<<8) + mc_filter[i], ioaddr + RxFilterData);
 		}
 	}
 	writel(rx_mode, ioaddr + RxFilterAddr);
 	np->cur_rx_mode = rx_mode;
+	spin_unlock_irq(&np->lock);
+}
+static void set_rx_mode(struct net_device *dev)
+{
+	struct netdev_private *np = dev->priv;
+	spin_lock_irq(&np->lock);
+	__set_rx_mode(dev);
+	spin_unlock_irq(&np->lock);
 }
 
 static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
@@ -1177,12 +1391,6 @@
 			u16 value = data[2];
 			writew(value, dev->base_addr + 0x80 + (miireg << 2));
 			switch (miireg) {
-			case 0:
-				/* Check for autonegotiation on or reset. */
-				np->duplex_lock = (value & 0x9000) ? 0 : 1;
-				if (np->duplex_lock)
-					np->full_duplex = (value & 0x0100) ? 1 : 0;
-				break;
 			case 4: np->advertising = value; break;
 			}
 		}
@@ -1196,15 +1404,12 @@
 {
 	long ioaddr = dev->base_addr;
 	struct netdev_private *np = dev->priv;
-	int i;
 
 	netif_stop_queue(dev);
 
 	if (debug > 1) {
-		printk(KERN_DEBUG "%s: Shutting down ethercard, status was %4.4x "
-			   "Int %2.2x.\n",
-			   dev->name, (int)readl(ioaddr + ChipCmd),
-			   (int)readl(ioaddr + IntrStatus));
+		printk(KERN_DEBUG "%s: Shutting down ethercard, status was %4.4x.",
+			   dev->name, (int)readl(ioaddr + ChipCmd));
 		printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d,  Rx %d / %d.\n",
 			   dev->name, np->cur_tx, np->dirty_tx, np->cur_rx, np->dirty_rx);
 	}
@@ -1221,13 +1426,14 @@
 
 #ifdef __i386__
 	if (debug > 2) {
+		int i;
 		printk("\n"KERN_DEBUG"  Tx ring at %8.8x:\n",
-			   (int)virt_to_bus(np->tx_ring));
+			   (int)np->tx_ring);
 		for (i = 0; i < TX_RING_SIZE; i++)
 			printk(" #%d desc. %8.8x %8.8x.\n",
 				   i, np->tx_ring[i].cmd_status, np->tx_ring[i].addr);
 		printk("\n"KERN_DEBUG "  Rx ring %8.8x:\n",
-			   (int)virt_to_bus(np->rx_ring));
+			   (int)np->rx_ring);
 		for (i = 0; i < RX_RING_SIZE; i++) {
 			printk(KERN_DEBUG " #%d desc. %8.8x %8.8x\n",
 				   i, np->rx_ring[i].cmd_status, np->rx_ring[i].addr);
@@ -1236,21 +1442,9 @@
 #endif /* __i386__ debugging only */
 
 	free_irq(dev->irq, dev);
+	drain_ring(dev);
+	free_ring(dev);
 
-	/* Free all the skbuffs in the Rx queue. */
-	for (i = 0; i < RX_RING_SIZE; i++) {
-		np->rx_ring[i].cmd_status = 0;
-		np->rx_ring[i].addr = 0xBADF00D0; /* An invalid address. */
-		if (np->rx_skbuff[i]) {
-			dev_kfree_skb(np->rx_skbuff[i]);
-		}
-		np->rx_skbuff[i] = 0;
-	}
-	for (i = 0; i < TX_RING_SIZE; i++) {
-		if (np->tx_skbuff[i])
-			dev_kfree_skb(np->tx_skbuff[i]);
-		np->tx_skbuff[i] = 0;
-	}
 	/* Restore PME enable bit */
 	writel(np->SavedClkRun, ioaddr + ClkRun);
 #if 0
@@ -1272,11 +1466,86 @@
 	pci_set_drvdata(pdev, NULL);
 }
 
+#ifdef CONFIG_PM
+
+static int natsemi_suspend (struct pci_dev *pdev, u32 state)
+{
+	struct net_device *dev = pci_get_drvdata (pdev);
+	struct netdev_private *np = dev->priv;
+	long ioaddr = dev->base_addr;
+
+	netif_device_detach(dev);
+	/* no more calls to tx_timeout, hard_start_xmit, set_rx_mode */
+	rtnl_lock();
+	rtnl_unlock();
+	/* noone within ->open */
+	if (netif_running (dev)) {
+		int i;
+		del_timer_sync(&np->timer);
+		/* no more link beat timer calls */
+		spin_lock_irq(&np->lock);
+		writel(RxOff | TxOff, ioaddr + ChipCmd);
+		for(i=0;i< NATSEMI_HW_TIMEOUT;i++) {
+			if ((readl(ioaddr + ChipCmd) & (TxOn|RxOn)) == 0)
+				break;
+			udelay(5);
+		}
+		if (i==NATSEMI_HW_TIMEOUT && debug) {
+			printk(KERN_INFO "%s: Tx/Rx process did not stop in %d usec.\n",
+					dev->name, i*5);
+		} else if (debug > 2) {
+			printk(KERN_DEBUG "%s: Tx/Rx process stopped in %d usec.\n",
+					dev->name, i*5);
+		}
+		/* Tx and Rx processes stopped */
+
+		writel(0, ioaddr + IntrEnable);
+		/* all irq events disabled. */
+		spin_unlock_irq(&np->lock);
+
+		synchronize_irq();
+
+		/* Update the error counts. */
+		__get_stats(dev);
+
+		/* pci_power_off(pdev, -1); */
+		drain_ring(dev);
+	}
+	return 0;
+}
+
+
+static int natsemi_resume (struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata (pdev);
+	struct netdev_private *np = dev->priv;
+
+	if (netif_running (dev)) {
+		pci_enable_device(pdev);
+	/*	pci_power_on(pdev); */
+		
+		natsemi_reset(dev);
+		init_ring(dev);
+		init_registers(dev);
+
+		np->timer.expires = jiffies + 1*HZ;
+		add_timer(&np->timer);
+	}
+	netif_device_attach(dev);
+	return 0;
+}
+
+#endif /* CONFIG_PM */
+
 static struct pci_driver natsemi_driver = {
 	name:		DRV_NAME,
 	id_table:	natsemi_pci_tbl,
 	probe:		natsemi_probe1,
 	remove:		natsemi_remove1,
+#ifdef CONFIG_PM
+	suspend:	natsemi_suspend,
+	resume:		natsemi_resume,
+#endif
 };
 
 static int __init natsemi_init_mod (void)
diff -u --recursive --new-file v2.4.5/linux/drivers/net/ne.c linux/drivers/net/ne.c
--- v2.4.5/linux/drivers/net/ne.c	Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/ne.c	Wed Jun 20 11:10:53 2001
@@ -735,6 +735,9 @@
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
 MODULE_PARM(bad, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
+MODULE_PARM_DESC(io, "NEx000 I/O base address(es),required");
+MODULE_PARM_DESC(irq, "NEx000 IRQ number(s)");
+MODULE_PARM_DESC(bad, "NEx000 accept bad clone(s)");
 
 /* This is set up so that no ISA autoprobe takes place. We can't guarantee
 that the ne2k probe is the last 8390 based probe to take place (as it
diff -u --recursive --new-file v2.4.5/linux/drivers/net/ne2.c linux/drivers/net/ne2.c
--- v2.4.5/linux/drivers/net/ne2.c	Fri Feb  9 11:40:02 2001
+++ linux/drivers/net/ne2.c	Wed Jun 20 11:10:53 2001
@@ -749,6 +749,9 @@
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
 MODULE_PARM(bad, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
+MODULE_PARM_DESC(io, "(ignored)");
+MODULE_PARM_DESC(irq, "(ignored)");
+MODULE_PARM_DESC(bad, "(ignored)");
 #endif
 
 /* Module code fixed by David Weinehall */
diff -u --recursive --new-file v2.4.5/linux/drivers/net/ne2k-pci.c linux/drivers/net/ne2k-pci.c
--- v2.4.5/linux/drivers/net/ne2k-pci.c	Fri Apr 20 11:54:23 2001
+++ linux/drivers/net/ne2k-pci.c	Wed Jun 20 11:13:18 2001
@@ -25,6 +25,11 @@
 	Limited full-duplex support.
 */
 
+#define DRV_NAME	"ne2k-pci"
+#define DRV_VERSION	"1.02"
+#define DRV_RELDATE	"10/19/2000"
+
+
 /* The user-configurable values.
    These may be modified when a driver module is loaded.*/
 
@@ -45,10 +50,12 @@
 #include <linux/errno.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/ethtool.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/uaccess.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -56,7 +63,7 @@
 
 /* These identify the driver base version and may not be removed. */
 static char version[] __devinitdata =
-KERN_INFO "ne2k-pci.c:v1.02 10/19/2000 D. Becker/P. Gortmaker\n"
+KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " D. Becker/P. Gortmaker\n"
 KERN_INFO "  http://www.scyld.com/network/ne2k-pci.html\n";
 
 #if defined(__powerpc__)
@@ -66,11 +73,16 @@
 #define outsl outsl_ns
 #endif
 
+#define PFX DRV_NAME ": "
+
 MODULE_AUTHOR("Donald Becker / Paul Gortmaker");
 MODULE_DESCRIPTION("PCI NE2000 clone driver");
 MODULE_PARM(debug, "i");
 MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM_DESC(debug, "PCI NE2000 debug level (1-2)");
+MODULE_PARM_DESC(options, "PCI NE2000: Bit 5: full duplex");
+MODULE_PARM_DESC(full_duplex, "PCI NE2000 full duplex setting(s) (1)");
 
 /* Some defines that people can play with if so inclined. */
 
@@ -160,6 +172,7 @@
 			  struct sk_buff *skb, int ring_offset);
 static void ne2k_pci_block_output(struct net_device *dev, const int count,
 		const unsigned char *buf, const int start_page);
+static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 
 
 
@@ -215,12 +228,12 @@
 	irq = pdev->irq;
 
 	if (!ioaddr || ((pci_resource_flags (pdev, 0) & IORESOURCE_IO) == 0)) {
-		printk (KERN_ERR "ne2k-pci: no I/O resource at PCI BAR #0\n");
+		printk (KERN_ERR PFX "no I/O resource at PCI BAR #0\n");
 		return -ENODEV;
 	}
 
-	if (request_region (ioaddr, NE_IO_EXTENT, "ne2k-pci") == NULL) {
-		printk (KERN_ERR "ne2k-pci: I/O resource 0x%x @ 0x%lx busy\n",
+	if (request_region (ioaddr, NE_IO_EXTENT, DRV_NAME) == NULL) {
+		printk (KERN_ERR PFX "I/O resource 0x%x @ 0x%lx busy\n",
 			NE_IO_EXTENT, ioaddr);
 		return -EBUSY;
 	}
@@ -246,7 +259,7 @@
 
 	dev = alloc_etherdev(0);
 	if (!dev) {
-		printk (KERN_ERR "ne2k-pci: cannot allocate ethernet device\n");
+		printk (KERN_ERR PFX "cannot allocate ethernet device\n");
 		goto err_out_free_res;
 	}
 	SET_MODULE_OWNER(dev);
@@ -263,7 +276,7 @@
 		while ((inb(ioaddr + EN0_ISR) & ENISR_RESET) == 0)
 			/* Limit wait: '2' avoids jiffy roll-over. */
 			if (jiffies - reset_start_time > 2) {
-				printk("ne2k-pci: Card failure (no reset ack).\n");
+				printk(KERN_ERR PFX "Card failure (no reset ack).\n");
 				goto err_out_free_netdev;
 			}
 
@@ -342,8 +355,10 @@
 	ei_status.block_input = &ne2k_pci_block_input;
 	ei_status.block_output = &ne2k_pci_block_output;
 	ei_status.get_8390_hdr = &ne2k_pci_get_8390_hdr;
+	ei_status.priv = (unsigned long) pdev;
 	dev->open = &ne2k_pci_open;
 	dev->stop = &ne2k_pci_close;
+	dev->do_ioctl = &netdev_ioctl;
 	NS8390_init(dev, 0);
 
 	i = register_netdev(dev);
@@ -573,6 +588,40 @@
 	return;
 }
 
+static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+{
+	struct ei_device *ei = dev->priv;
+	struct pci_dev *pci_dev = (struct pci_dev *) ei->priv;
+	u32 ethcmd;
+		
+	if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
+		return -EFAULT;
+
+        switch (ethcmd) {
+        case ETHTOOL_GDRVINFO: {
+		struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
+		strcpy(info.driver, DRV_NAME);
+		strcpy(info.version, DRV_VERSION);
+		strcpy(info.bus_info, pci_dev->slot_name);
+		if (copy_to_user(useraddr, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+
+        }
+	
+	return -EOPNOTSUPP;
+}
+
+static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	switch(cmd) {
+	case SIOCETHTOOL:
+		return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
 
 static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev)
 {
@@ -589,7 +638,7 @@
 
 
 static struct pci_driver ne2k_driver = {
-	name:		"ne2k-pci",
+	name:		DRV_NAME,
 	probe:		ne2k_pci_init_one,
 	remove:		ne2k_pci_remove_one,
 	id_table:	ne2k_pci_tbl,
diff -u --recursive --new-file v2.4.5/linux/drivers/net/ne3210.c linux/drivers/net/ne3210.c
--- v2.4.5/linux/drivers/net/ne3210.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/ne3210.c	Wed Jun 20 11:10:53 2001
@@ -370,6 +370,9 @@
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE3210_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE3210_CARDS) "i");
 MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_NE3210_CARDS) "i");
+MODULE_PARM_DESC(io, "NE3210 I/O base address(es)");
+MODULE_PARM_DESC(irq, "NE3210 IRQ number(s)");
+MODULE_PARM_DESC(mem, "NE3210 memory base address(es)");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.4.5/linux/drivers/net/ni5010.c linux/drivers/net/ni5010.c
--- v2.4.5/linux/drivers/net/ni5010.c	Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/ni5010.c	Wed Jun 20 11:10:53 2001
@@ -739,6 +739,8 @@
 
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
+MODULE_PARM_DESC(io, "ni5010 I/O base address");
+MODULE_PARM_DESC(irq, "ni5010 IRQ number");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.4.5/linux/drivers/net/ni52.c linux/drivers/net/ni52.c
--- v2.4.5/linux/drivers/net/ni52.c	Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/ni52.c	Wed Jun 20 11:10:53 2001
@@ -1296,6 +1296,10 @@
 MODULE_PARM(irq, "i");
 MODULE_PARM(memstart, "l");
 MODULE_PARM(memend, "l");
+MODULE_PARM_DESC(io, "NI5210 I/O base address,required");
+MODULE_PARM_DESC(irq, "NI5210 IRQ number,required");
+MODULE_PARM_DESC(memstart, "NI5210 memory base address,required");
+MODULE_PARM_DESC(memend, "NI5210 memory end address,required");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.4.5/linux/drivers/net/ni65.c linux/drivers/net/ni65.c
--- v2.4.5/linux/drivers/net/ni65.c	Wed Apr 18 14:40:04 2001
+++ linux/drivers/net/ni65.c	Wed Jun 20 11:10:53 2001
@@ -1184,6 +1184,9 @@
 MODULE_PARM(irq, "i");
 MODULE_PARM(io, "i");
 MODULE_PARM(dma, "i");
+MODULE_PARM_DESC(irq, "ni6510 IRQ number (ignored for some cards)");
+MODULE_PARM_DESC(io, "ni6510 I/O base address");
+MODULE_PARM_DESC(dma, "ni6510 ISA DMA channel (ignored for some cards)");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.4.5/linux/drivers/net/pci-skeleton.c linux/drivers/net/pci-skeleton.c
--- v2.4.5/linux/drivers/net/pci-skeleton.c	Fri Apr 20 11:54:23 2001
+++ linux/drivers/net/pci-skeleton.c	Wed Jun 20 11:13:18 2001
@@ -85,6 +85,7 @@
 
 */
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
@@ -480,11 +481,15 @@
 };
 
 MODULE_AUTHOR ("Jeff Garzik <jgarzik@mandrakesoft.com>");
-MODULE_DESCRIPTION ("RealTek RTL-8139 Fast Ethernet driver");
+MODULE_DESCRIPTION ("Skeleton for a PCI Fast Ethernet driver");
 MODULE_PARM (multicast_filter_limit, "i");
 MODULE_PARM (max_interrupt_work, "i");
 MODULE_PARM (debug, "i");
 MODULE_PARM (media, "1-" __MODULE_STRING(8) "i");
+MODULE_PARM_DESC (multicast_filter_limit, "pci-skeleton maximum number of filtered multicast addresses");
+MODULE_PARM_DESC (max_interrupt_work, "pci-skeleton maximum events handled per interrupt");
+MODULE_PARM_DESC (media, "pci-skeleton: Bits 0-3: media type, bit 17: full duplex");
+MODULE_PARM_DESC (debug, "(unused)");
 
 static int read_eeprom (void *ioaddr, int location, int addr_len);
 static int netdrv_open (struct net_device *dev);
@@ -1790,7 +1795,7 @@
 
 	case SIOCDEVPRIVATE + 1:	/* Read the specified MII register. */
 		spin_lock_irqsave (&tp->lock, flags);
-		data[3] = mdio_read (dev, data[0], data[1] & 0x1f);
+		data[3] = mdio_read (dev, data[0] & 0x1f, data[1] & 0x1f);
 		spin_unlock_irqrestore (&tp->lock, flags);
 		break;
 
@@ -1801,7 +1806,7 @@
 		}
 
 		spin_lock_irqsave (&tp->lock, flags);
-		mdio_write (dev, data[0], data[1] & 0x1f, data[2]);
+		mdio_write (dev, data[0] & 0x1f, data[1] & 0x1f, data[2]);
 		spin_unlock_irqrestore (&tp->lock, flags);
 		break;
 
@@ -1918,7 +1923,9 @@
 }
 
 
-static void netdrv_suspend (struct pci_dev *pdev)
+#ifdef CONFIG_PM
+
+static int netdrv_suspend (struct pci_dev *pdev, u32 state)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
 	struct netdrv_private *tp = dev->priv;
@@ -1942,10 +1949,12 @@
 	spin_unlock_irqrestore (&tp->lock, flags);
 
 	pci_power_off (pdev, -1);
+
+	return 0;
 }
 
 
-static void netdrv_resume (struct pci_dev *pdev)
+static int netdrv_resume (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
 
@@ -1954,16 +1963,22 @@
 	pci_power_on (pdev);
 	netif_device_attach (dev);
 	netdrv_hw_start (dev);
+
+	return 0;
 }
 
+#endif /* CONFIG_PM */
+
 
 static struct pci_driver netdrv_pci_driver = {
 	name:		MODNAME,
 	id_table:	netdrv_pci_tbl,
 	probe:		netdrv_init_one,
 	remove:		netdrv_remove_one,
+#ifdef CONFIG_PM
 	suspend:	netdrv_suspend,
 	resume:		netdrv_resume,
+#endif /* CONFIG_PM */
 };
 
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/pcmcia/Config.in linux/drivers/net/pcmcia/Config.in
--- v2.4.5/linux/drivers/net/pcmcia/Config.in	Mon May  7 19:42:14 2001
+++ linux/drivers/net/pcmcia/Config.in	Wed Jun 20 11:13:18 2001
@@ -32,13 +32,4 @@
    fi
 fi
 
-if [ "$CONFIG_PCMCIA_3C589" = "y" -o "$CONFIG_PCMCIA_3C574" = "y" -o \
-     "$CONFIG_PCMCIA_FMVJ18X" = "y" -o "$CONFIG_PCMCIA_PCNET" = "y" -o \
-     "$CONFIG_PCMCIA_NMCLAN" = "y" -o "$CONFIG_PCMCIA_SMC91C92" = "y" -o \
-     "$CONFIG_PCMCIA_XIRC2PS" = "y" -o "$CONFIG_PCMCIA_RAYCS" = "y" -o \
-     "$CONFIG_PCMCIA_NETWAVE" = "y" -o "$CONFIG_PCMCIA_WAVELAN" = "y" -o \
-     "$CONFIG_PCMCIA_XIRTULIP" = "y" ]; then
-   define_bool CONFIG_PCMCIA_NETCARD y
-fi
-
 endmenu
diff -u --recursive --new-file v2.4.5/linux/drivers/net/pcmcia/Makefile linux/drivers/net/pcmcia/Makefile
--- v2.4.5/linux/drivers/net/pcmcia/Makefile	Mon May  7 19:42:14 2001
+++ linux/drivers/net/pcmcia/Makefile	Wed Jun 20 11:13:18 2001
@@ -36,10 +36,3 @@
 obj-$(CONFIG_PCMCIA_IBMTR)	+= ibmtr_cs.o
 
 include $(TOPDIR)/Rules.make
-
-tmp-ibmtr.o: ../tokenring/ibmtr.c
-	$(CC) $(CFLAGS) -D__NO_VERSION__ -DPCMCIA -c -o $@ ../tokenring/ibmtr.c
-
-ibmtr_cs.o: tmp-ibmtr.o ibmtr_cs.c
-	$(CC) $(CFLAGS) -DPCMCIA -c -o tmp-$@ ibmtr_cs.c
-	$(LD) -r -o $@ tmp-$@ tmp-ibmtr.o
diff -u --recursive --new-file v2.4.5/linux/drivers/net/pcmcia/ibmtr_cs.c linux/drivers/net/pcmcia/ibmtr_cs.c
--- v2.4.5/linux/drivers/net/pcmcia/ibmtr_cs.c	Wed Apr 18 14:40:05 2001
+++ linux/drivers/net/pcmcia/ibmtr_cs.c	Wed Jun 20 11:13:18 2001
@@ -73,6 +73,9 @@
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
 
+#define PCMCIA
+#include "../tokenring/ibmtr.c"
+
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
 MODULE_PARM(pc_debug, "i");
@@ -130,7 +133,7 @@
 unsigned char pcmcia_reality_check(unsigned char gss);
 
 extern int trdev_init(struct net_device *dev);
-extern void tok_interrupt(int irq, struct pt_regs *regs);
+extern void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs);
 extern int tok_init_card(struct net_device *dev);
 extern unsigned char get_sram_size(struct tok_info *ti);
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/pcmcia/xircom_tulip_cb.c linux/drivers/net/pcmcia/xircom_tulip_cb.c
--- v2.4.5/linux/drivers/net/pcmcia/xircom_tulip_cb.c	Sun Mar 25 18:24:31 2001
+++ linux/drivers/net/pcmcia/xircom_tulip_cb.c	Wed Jun 20 11:16:01 2001
@@ -245,10 +245,6 @@
 /* This table use during operation for capabilities and media timer. */
 
 static void tulip_timer(unsigned long data);
-static void t21142_timer(unsigned long data);
-static void mxic_timer(unsigned long data);
-static void pnic_timer(unsigned long data);
-static void comet_timer(unsigned long data);
 
 enum tbl_flag {
 	HAS_MII=1, HAS_MEDIA_TABLE=2, CSR12_IN_SROM=4, ALWAYS_CHECK_MII=8,
@@ -262,37 +258,15 @@
 	int flags;
 	void (*media_timer)(unsigned long data);
 } tulip_tbl[] = {
-  { "Digital DC21040 Tulip", 128, 0x0001ebef, 0, tulip_timer },
-  { "Digital DC21041 Tulip", 128, 0x0001ebef, HAS_MEDIA_TABLE, tulip_timer },
-  { "Digital DS21140 Tulip", 128, 0x0001ebef,
-	HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, tulip_timer },
-  { "Digital DS21143 Tulip", 128, 0x0801fbff,
-	HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY143, t21142_timer },
-  { "Lite-On 82c168 PNIC", 256, 0x0001ebef,
-	HAS_MII, pnic_timer },
-  { "Macronix 98713 PMAC", 128, 0x0001ebef,
-	HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer },
-  { "Macronix 98715 PMAC", 256, 0x0001ebef,
-	HAS_MEDIA_TABLE, mxic_timer },
-  { "Macronix 98725 PMAC", 256, 0x0001ebef,
-	HAS_MEDIA_TABLE, mxic_timer },
-  { "ASIX AX88140", 128, 0x0001fbff,
-	HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | MC_HASH_ONLY, tulip_timer },
-  { "Lite-On PNIC-II", 256, 0x0001ebef,
-	HAS_MII | HAS_NWAY143, pnic_timer },
-  { "ADMtek Comet", 256, 0x0001abef,
-	MC_HASH_ONLY, comet_timer },
-  { "Compex 9881 PMAC", 128, 0x0001ebef,
-	HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer },
   { "Xircom Cardbus Adapter (DEC 21143 compatible mode)", 128, 0x0801fbff,
        HAS_MII | HAS_ACPI, tulip_timer }, 
   {0},
 };
 /* This matches the table above.  Note 21142 == 21143. */
 enum chips {
-	DC21040=0, DC21041=1, DC21140=2, DC21142=3, DC21143=3,
-	LC82C168, MX98713, MX98715, MX98725, AX88140, PNIC2, COMET, COMPEX9881,
 	X3201_3,
+	DC21040, DC21041, DC21140, DC21142=4, DC21143=4,
+	LC82C168, MX98713, MX98715, MX98725, AX88140, PNIC2, COMET, COMPEX9881,
 };
 
 /* A full-duplex map for media types. */
@@ -307,9 +281,7 @@
 static u16 t21041_csr14[] = { 0x7F3F, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, };
 static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
 
-static u16 t21142_csr13[] = { 0x0001, 0x0009, 0x0009, 0x0000, 0x0001, };
 static u16 t21142_csr14[] = { 0xFFFF, 0x0705, 0x0705, 0x0000, 0x7F3D, };
-static u16 t21142_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
 
 /* Offsets to the Command and Status Registers, "CSRs".  All accesses
    must be longword instructions and quadword aligned. */
@@ -1272,7 +1244,7 @@
 		*setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1];
 		*setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2];
 		/* Put the setup frame on the Tx list. */
-		tp->tx_ring[0].length = 0x08000000 | 192;
+		tp->tx_ring[0].length = 0x68000000 | 192;
 		tp->tx_ring[0].buffer1 = virt_to_bus(tp->setup_frame);
 		tp->tx_ring[0].status = DescOwned;
 
@@ -1291,7 +1263,7 @@
 		}
 
 		/* Put the setup frame on the Tx list. */
-		tp->tx_ring[tp->cur_tx].length = 0x08000000 | 192;
+		tp->tx_ring[tp->cur_tx].length = 0x68000000 | 192;
 		/* Lie about the address of our setup frame to make the */
 		/* chip happy */
 		tp->tx_ring[tp->cur_tx].buffer1 = virt_to_bus(tp->setup_frame);
@@ -1862,83 +1834,6 @@
 	add_timer(&tp->timer);
 }
 
-/* Handle the 21143 uniquely: do autoselect with NWay, not the EEPROM list
-   of available transceivers.  */
-static void t21142_timer(unsigned long data)
-{
-	struct net_device *dev = (struct net_device *)data;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	long ioaddr = dev->base_addr;
-	int csr12 = inl(ioaddr + CSR12);
-	int next_tick = 60*HZ;
-	int new_csr6 = 0;
-
-	if ((tulip_debug > 2) && !(media_cap[dev->if_port] & MediaIsMII))
-		printk(KERN_INFO"%s: 21143 negotiation status %8.8x, %s.\n",
-			   dev->name, csr12, medianame[dev->if_port]);
-	if (media_cap[dev->if_port] & MediaIsMII) {
-		check_duplex(dev);
-		next_tick = 60*HZ;
-	} else if (tp->nwayset) {
-		/* Don't screw up a negotiated session! */
-		if (tulip_debug > 1)
-			printk(KERN_INFO"%s: Using NWay-set %s media, csr12 %8.8x.\n",
-				   dev->name, medianame[dev->if_port], csr12);
-	} else if (tp->medialock) {
-			;
-	} else if (dev->if_port == 3) {
-		if (csr12 & 2) {	/* No 100mbps link beat, revert to 10mbps. */
-			if (tulip_debug > 1)
-				printk(KERN_INFO"%s: No 21143 100baseTx link beat, %8.8x, "
-					   "trying NWay.\n", dev->name, csr12);
-			t21142_start_nway(dev);
-			next_tick = 3*HZ;
-		}
-	} else if (((csr12 & 0x7000) != 0x5000)
-			   && tp->chip_id != X3201_3) {
-		/* Negotiation failed.  Search media types. */
-		if (tulip_debug > 1)
-			printk(KERN_INFO"%s: 21143 negotiation failed, status %8.8x.\n",
-				   dev->name, csr12);
-		if (!(csr12 & 4)) {		/* 10mbps link beat good. */
-			new_csr6 = 0x82420000;
-			dev->if_port = 0;
-			outl(0, ioaddr + CSR13);
-			outl(0x0003FFFF, ioaddr + CSR14);
-			outw(t21142_csr15[dev->if_port], ioaddr + CSR15);
-			outl(t21142_csr13[dev->if_port], ioaddr + CSR13);
-		} else {
-			/* Select 100mbps port to check for link beat. */
-			new_csr6 = 0x83860000;
-			dev->if_port = 3;
-			outl(0, ioaddr + CSR13);
-			outl(0x0003FF7F, ioaddr + CSR14);
-			outw(8, ioaddr + CSR15);
-			outl(1, ioaddr + CSR13);
-		}
-		if (tulip_debug > 1)
-			printk(KERN_INFO"%s: Testing new 21143 media %s.\n",
-				   dev->name, medianame[dev->if_port]);
-		if (new_csr6 != (tp->csr6 & ~0x00D5)) {
-			tp->csr6 &= 0x00D5;
-			tp->csr6 |= new_csr6;
-			outl(0x0301, ioaddr + CSR12);
-			outl_CSR6(tp->csr6 | 0x0002, ioaddr, tp->chip_id);
-			outl_CSR6(tp->csr6 | 0x2002, ioaddr, tp->chip_id);
-		}
-		next_tick = 3*HZ;
-	}
-	if (tp->cur_tx - tp->dirty_tx > 0  &&
-		jiffies - dev->trans_start > TX_TIMEOUT) {
-		printk(KERN_WARNING "%s: Tx hung, %d vs. %d.\n",
-			   dev->name, tp->cur_tx, tp->dirty_tx);
-		tulip_tx_timeout(dev);
-	}
-
-	tp->timer.expires = RUN_AT(next_tick);
-	add_timer(&tp->timer);
-}
-
 static void t21142_start_nway(struct net_device *dev)
 {
 	struct tulip_private *tp = (struct tulip_private *)dev->priv;
@@ -2069,123 +1964,6 @@
 	}
 }
 
-static void mxic_timer(unsigned long data)
-{
-	struct net_device *dev = (struct net_device *)data;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	long ioaddr = dev->base_addr;
-	int next_tick = 60*HZ;
-
-	if (tulip_debug > 3) {
-		printk(KERN_INFO"%s: MXIC negotiation status %8.8x.\n", dev->name,
-			   inl(ioaddr + CSR12));
-	}
-	if (next_tick) {
-		tp->timer.expires = RUN_AT(next_tick);
-		add_timer(&tp->timer);
-	}
-}
-
-static void pnic_timer(unsigned long data)
-{
-	struct net_device *dev = (struct net_device *)data;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	long ioaddr = dev->base_addr;
-	int csr12 = inl(ioaddr + CSR12);
-	int next_tick = 60*HZ;
-	int new_csr6 = tp->csr6 & ~0x40C40200;
-
-	if (media_cap[dev->if_port] & MediaIsMII) {
-		int negotiated = mdio_read(dev, tp->phys[0], 5) & tp->advertising[0];
-
-		if (tulip_debug > 1)
-			printk(KERN_DEBUG "%s: PNIC negotiated capability %8.8x, "
-				   "CSR5 %8.8x.\n",
-				   dev->name, negotiated, inl(ioaddr + CSR5));
-
-		if (negotiated & 0x0380) 				/* 10 vs 100mbps */
-			new_csr6 |= 0x810E0000;
-		else
-			new_csr6 |= 0x814E0000;
-		if (((negotiated & 0x0300) == 0x0100)			/* Duplex */
-			|| (negotiated & 0x00C0) == 0x0040
-			|| tp->full_duplex_lock) {
-			tp->full_duplex = 1;
-			new_csr6 |= 0x0200;
-		}
-		if (tulip_debug > 1)
-			printk(KERN_DEBUG "%s: PNIC MII PHY status %4.4x, Link "
-				   "partner report %4.4x, csr6 %8.8x/%8.8x.\n",
-			   dev->name, mdio_read(dev, tp->phys[0], 1), negotiated,
-				   tp->csr6, inl(ioaddr + CSR6));
-	} else {
-		int phy_reg = inl(ioaddr + 0xB8);
-		int csr5 = inl(ioaddr + CSR5);
-
-		if (tulip_debug > 1)
-			printk(KERN_DEBUG "%s: PNIC PHY status %8.8x, CSR5 %8.8x.\n",
-				   dev->name, phy_reg, csr5);
-
-		if (phy_reg & 0x04000000) {	/* Remote link fault */
-			/*outl(0x0201F078, ioaddr + 0xB8);*/
-			next_tick = 3*HZ;
-		}
-		if (inl(ioaddr + CSR5) & TPLnkFail) { /* 100baseTx link beat */
-			if (tulip_debug > 1)
-				printk(KERN_DEBUG "%s: %s link beat failed, CSR12 %4.4x, "
-					   "CSR5 %8.8x, PHY %3.3x.\n",
-					   dev->name, medianame[dev->if_port], csr12,
-					   inl(ioaddr + CSR5), inl(ioaddr + 0xB8));
-			if (tp->medialock) {
-			} else if (dev->if_port == 0) {
-				dev->if_port = 3;
-				outl(0x33, ioaddr + CSR12);
-				new_csr6 = 0x01860000;
-				outl(0x1F868, ioaddr + 0xB8);
-			} else {
-				dev->if_port = 0;
-				outl(0x32, ioaddr + CSR12);
-				new_csr6 = 0x00420000;
-				outl(0x1F078, ioaddr + 0xB8);
-			}
-			new_csr6 |= (tp->csr6 & 0xfdff);
-			next_tick = 3*HZ;
-		} else
-			new_csr6 = tp->csr6;
-		if (tp->full_duplex_lock  ||  (phy_reg & 0x30000000) != 0) {
-			tp->full_duplex = 1;
-			new_csr6 |= 0x00000200;
-		}
-	}
-	if (tp->csr6 != new_csr6) {
-		tp->csr6 = new_csr6;
-		outl_CSR6(tp->csr6 | 0x0002, ioaddr, tp->chip_id);	/* Restart Tx */
-		outl_CSR6(tp->csr6 | 0x2002, ioaddr, tp->chip_id);
-		dev->trans_start = jiffies;
-		if (tulip_debug > 1)
-			printk(KERN_INFO "%s: Changing PNIC configuration to %s-duplex, "
-				   "CSR6 %8.8x.\n",
-				   dev->name, tp->full_duplex ? "full" : "half", new_csr6);
-	}
-	tp->timer.expires = RUN_AT(next_tick);
-	add_timer(&tp->timer);
-}
-
-static void comet_timer(unsigned long data)
-{
-	struct net_device *dev = (struct net_device *)data;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	long ioaddr = dev->base_addr;
-	int next_tick = 60*HZ;
-
-	if (tulip_debug > 1)
-		printk(KERN_DEBUG "%s: Comet link status %4.4x partner capability "
-			   "%4.4x.\n",
-			   dev->name, inl(ioaddr + 0xB8), inl(ioaddr + 0xC8));
-	tp->timer.expires = RUN_AT(next_tick);
-	add_timer(&tp->timer);
-}
-
 static void tulip_tx_timeout(struct net_device *dev)
 {
 	struct tulip_private *tp = (struct tulip_private *)dev->priv;
@@ -2741,12 +2519,6 @@
 	case SIOCDEVPRIVATE:		/* Get the address of the PHY in use. */
 		if (tp->mii_cnt)
 			data[0] = phy;
-		else if (tp->chip_id == DC21142)	/* 21142 pseudo-MII */
-			data[0] = 32;
-		else if (tp->chip_id == PNIC2)
-			data[0] = 32;
-		else if (tp->chip_id == COMET)
-			data[0] = 1;
 		else
 			return -ENODEV;
 		return 0;
@@ -2874,27 +2646,18 @@
 			for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
 				 i++, mclist = mclist->next)
 				set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr)>>26, mc_filter);
-			if (tp->chip_id == AX88140) {
-				outl(2, ioaddr + CSR13);
-				outl(mc_filter[0], ioaddr + CSR14);
-				outl(3, ioaddr + CSR13);
-				outl(mc_filter[1], ioaddr + CSR14);
-			} else if (tp->chip_id == COMET) { /* Has a simple hash filter. */
-				outl(mc_filter[0], ioaddr + 0xAC);
-				outl(mc_filter[1], ioaddr + 0xB0);
-			}
 		}
 	} else {
 		u16 *eaddrs, *setup_frm = tp->setup_frame;
 		struct dev_mc_list *mclist;
-		u32 tx_flags = 0x08000000 | 192;
+		u32 tx_flags = 0x68000000 | 192;
 		int i;
 
 		/* Note that only the low-address shortword of setup_frame is valid!
 		   The values are doubled for big-endian architectures. */
-		if ((dev->mc_count > 14) || ((dev->mc_count > 6) && (tp->chip_id == X3201_3))) { /* Must use a multicast hash table. */
+		if (dev->mc_count > 14) { /* Must use a multicast hash table. */
 			u16 hash_table[32];
-			tx_flags = 0x08400000 | 192;		/* Use hash filter. */
+			tx_flags = 0x68400000 | 192;		/* Use hash filter. */
 			memset(hash_table, 0, sizeof(hash_table));
 			set_bit(255, hash_table); 			/* Broadcast entry */
 			/* This should work on big-endian machines as well. */
@@ -2907,7 +2670,7 @@
 				*setup_frm++ = hash_table[i];
 			}
 			setup_frm = &tp->setup_frame[13*6];
-		} else if(tp->chip_id != X3201_3) {
+		} else {
 			/* We have <= 14 addresses so we can use the wonderful
 			   16 address perfect filtering of the Tulip. */
 			for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
@@ -2920,30 +2683,6 @@
 			/* Fill the unused entries with the broadcast address. */
 			memset(setup_frm, 0xff, (15-i)*12);
 			setup_frm = &tp->setup_frame[15*6];
-		} else {
-			/* fill the first two table entries with our address */
-			eaddrs = (u16 *)dev->dev_addr;
-			for(i=0; i<2; i++) {
-				*setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0];
-				*setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1];
-				*setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2];
-			}
-			/* Double fill each entry to accomodate chips that */
-			/* don't like to parse these correctly */
-			for (i=0, mclist=dev->mc_list; i<dev->mc_count;
-				 i++, mclist=mclist->next) {
-				eaddrs = (u16 *)mclist->dmi_addr;
-				*setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0];
-				*setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1];
-				*setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2];
-				*setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0];
-				*setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1];
-				*setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2];
-			}
-			i=((i+1)*2);
-			/* Fill the unused entries with the broadcast address. */
-			memset(setup_frm, 0xff, (15-i)*12);
-			setup_frm = &tp->setup_frame[15*6];
 		}
 
 		/* Fill the final entry with our physical address. */
@@ -2995,20 +2734,6 @@
 }
 
 static  struct pci_device_id tulip_pci_table[] __devinitdata = {
-#if 0 /* these entries conflict with regular tulip driver */
-  { 0x1011, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21040 },
-  { 0x1011, 0x0014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21041 },
-  { 0x1011, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21140 },
-  { 0x1011, 0x0019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21142 },
-  { 0x11AD, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, LC82C168 },
-  { 0x10d9, 0x0512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98713 },
-  { 0x10d9, 0x0531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 },
-  { 0x10d9, 0x0531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98725 },
-  { 0x125B, 0x1400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AX88140 },
-  { 0x11AD, 0xc115, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PNIC2 },
-  { 0x1317, 0x0981, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
-  { 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 },
-#endif
   { 0x115D, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, X3201_3 },
   {0},
 };
@@ -3034,20 +2759,22 @@
 	return -ENODEV;
 }
 
-static void tulip_suspend(struct pci_dev *pdev)
+static int tulip_suspend(struct pci_dev *pdev, u32 state)
 {
 	struct net_device *dev = pdev->driver_data;
 	struct tulip_private *tp = (struct tulip_private *)dev->priv;
 	printk(KERN_INFO "tulip_suspend(%s)\n", dev->name);
 	if (tp->open) tulip_down(dev);
+	return 0;
 }
 
-static void tulip_resume(struct pci_dev *pdev)
+static int tulip_resume(struct pci_dev *pdev)
 {
 	struct net_device *dev = pdev->driver_data;
 	struct tulip_private *tp = (struct tulip_private *)dev->priv;
 	printk(KERN_INFO "tulip_resume(%s)\n", dev->name);
 	if (tp->open) tulip_up(dev);
+	return 0;
 }
 
 static void __devexit tulip_remove(struct pci_dev *pdev)
diff -u --recursive --new-file v2.4.5/linux/drivers/net/plip.c linux/drivers/net/plip.c
--- v2.4.5/linux/drivers/net/plip.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/plip.c	Wed Jun 20 11:10:53 2001
@@ -1297,6 +1297,7 @@
 
 MODULE_PARM(parport, "1-" __MODULE_STRING(PLIP_MAX) "i");
 MODULE_PARM(timid, "1i");
+MODULE_PARM_DESC(parport, "List of parport device numbers to use by plip");
 
 static struct net_device *dev_plip[PLIP_MAX] = { NULL, };
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/ppp_async.c linux/drivers/net/ppp_async.c
--- v2.4.5/linux/drivers/net/ppp_async.c	Fri Apr 20 11:54:24 2001
+++ linux/drivers/net/ppp_async.c	Wed Jun 20 11:10:53 2001
@@ -80,6 +80,7 @@
 
 static int flag_time = HZ;
 MODULE_PARM(flag_time, "i");
+MODULE_PARM_DESC(flag_time, "ppp_async: interval between flagged packets (in clock ticks)");
 
 /*
  * Prototypes.
diff -u --recursive --new-file v2.4.5/linux/drivers/net/saa9730.c linux/drivers/net/saa9730.c
--- v2.4.5/linux/drivers/net/saa9730.c	Fri Apr 13 20:26:07 2001
+++ linux/drivers/net/saa9730.c	Wed Jun 20 11:10:53 2001
@@ -335,7 +335,7 @@
 			printk("Error: lan_saa9730_mii_init: timeout\n");
 			return -1;
 		}
-		udelay(1000);	/* wait 1 ms. */
+		mdelay(1);	/* wait 1 ms. */
 	}
 
 	/* Now set the control and address register. */
@@ -350,11 +350,11 @@
 			printk("Error: lan_saa9730_mii_init: timeout\n");
 			return -1;
 		}
-		udelay(1000);	/* wait 1 ms. */
+		mdelay(1);	/* wait 1 ms. */
 	}
 
 	/* Wait for 1 ms. */
-	udelay(1000);
+	mdelay(1);
 
 	/* Check the link status. */
 	if (INL(&lp->lan_saa9730_regs->StationMgmtData) &
@@ -369,7 +369,7 @@
 		     &lp->lan_saa9730_regs->StationMgmtCtl);
 
 		/* Wait for 1 ms. */
-		udelay(1000);
+		mdelay(1);
 
 		/* set 'CONTROL' = force reset and renegotiate */
 		OUTL(PHY_CONTROL_RESET | PHY_CONTROL_AUTO_NEG |
@@ -377,7 +377,7 @@
 		     &lp->lan_saa9730_regs->StationMgmtData);
 
 		/* Wait for 50 ms. */
-		udelay(50 * 1000);
+		mdelay(50);
 
 		/* set 'BUSY' to start operation */
 		OUTL(MD_CA_BUSY | PHY_ADDRESS << MD_CA_PHY_SHF | MD_CA_WR |
@@ -393,11 +393,11 @@
 				    ("Error: lan_saa9730_mii_init: timeout\n");
 				return -1;
 			}
-			udelay(1000);	/* wait 1 ms. */
+			mdelay(1);	/* wait 1 ms. */
 		}
 
 		/* Wait for 1 ms. */
-		udelay(1000);
+		mdelay(1);
 
 		for (l = 0; l < 2; l++) {
 			/* set PHY address = 'STATUS' */
@@ -415,11 +415,11 @@
 					    ("Error: lan_saa9730_mii_init: timeout\n");
 					return -1;
 				}
-				udelay(1000);	/* wait 1 ms. */
+				mdelay(1);	/* wait 1 ms. */
 			}
 
 			/* wait for 3 sec. */
-			udelay(3000 * 1000);
+			mdelay(3000);
 
 			/* check the link status */
 			if (INL(&lp->lan_saa9730_regs->StationMgmtData) &
@@ -495,7 +495,7 @@
 			    ("Error: lan_sa9730_stop: MAC reset timeout\n");
 			return -1;
 		}
-		udelay(1000);	/* wait 1 ms. */
+		mdelay(1);	/* wait 1 ms. */
 	}
 
 	return 0;
diff -u --recursive --new-file v2.4.5/linux/drivers/net/sb1000.c linux/drivers/net/sb1000.c
--- v2.4.5/linux/drivers/net/sb1000.c	Wed Apr 18 11:49:14 2001
+++ linux/drivers/net/sb1000.c	Wed Jun 20 11:10:53 2001
@@ -1211,6 +1211,8 @@
 MODULE_DESCRIPTION("General Instruments SB1000 driver");
 MODULE_PARM(io, "1-2i");
 MODULE_PARM(irq, "i");
+MODULE_PARM_DESC(io, "SB1000 I/O base addresses");
+MODULE_PARM_DESC(irq, "SB1000 IRQ number");
 
 static struct net_device dev_sb1000;
 static int io[2];
diff -u --recursive --new-file v2.4.5/linux/drivers/net/seeq8005.c linux/drivers/net/seeq8005.c
--- v2.4.5/linux/drivers/net/seeq8005.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/seeq8005.c	Wed Jun 20 11:10:53 2001
@@ -101,8 +101,6 @@
 /* Check for a network adaptor of this type, and return '0' iff one exists.
    If dev->base_addr == 0, probe all likely locations.
    If dev->base_addr == 1, always return failure.
-   If dev->base_addr == 2, allocate space for the device and return success
-   (detachable devices only).
    */
 
 int __init 
@@ -715,6 +713,8 @@
 static int irq = 10;
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
+MODULE_PARM_DESC(io, "SEEQ 8005 I/O base address");
+MODULE_PARM_DESC(irq, "SEEQ 8005 IRQ number");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.4.5/linux/drivers/net/shaper.c linux/drivers/net/shaper.c
--- v2.4.5/linux/drivers/net/shaper.c	Wed Apr 18 14:40:06 2001
+++ linux/drivers/net/shaper.c	Wed Jun 27 17:10:55 2001
@@ -283,7 +283,7 @@
 				shaper->dev->name,newskb->priority);
 		dev_queue_xmit(newskb);
 
-                shaper->stats.tx_bytes+=newskb->len;
+                shaper->stats.tx_bytes += skb->len;
 		shaper->stats.tx_packets++;
 
                 if(sh_debug)
@@ -682,6 +682,7 @@
 #ifdef MODULE
 
 MODULE_PARM(shapers, "i");
+MODULE_PARM_DESC(shapers, "Traffic shaper: maximum nuber of shapers");
 
 #else /* MODULE */
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/sis900.c linux/drivers/net/sis900.c
--- v2.4.5/linux/drivers/net/sis900.c	Fri Apr 20 11:54:23 2001
+++ linux/drivers/net/sis900.c	Thu Jun 21 14:28:39 2001
@@ -1,6 +1,6 @@
 /* sis900.c: A SiS 900/7016 PCI Fast Ethernet driver for Linux.
    Copyright 1999 Silicon Integrated System Corporation 
-   Revision:	1.07.11	Apr. 10 2001
+   Revision:	1.08.00	Jun. 11 2001
    
    Modified from the driver which is originally written by Donald Becker.
    
@@ -18,6 +18,7 @@
    preliminary Rev. 1.0 Jan. 18, 1998
    http://www.sis.com.tw/support/databook.htm
 
+   Rev 1.08.00 Jun. 11 2001 Hui-Fen Hsu workaround for RTL8201 PHY and some bug fix
    Rev 1.07.11 Apr.  2 2001 Hui-Fen Hsu  updates PCI drivers to use the new pci_set_dma_mask for kernel 2.4.3
    Rev 1.07.10 Mar.  1 2001 Hui-Fen Hsu <hfhsu@sis.com.tw> some bug fix & 635M/B support 
    Rev 1.07.09 Feb.  9 2001 Dave Jones <davej@suse.de> PCI enable cleanup
@@ -63,7 +64,7 @@
 #include "sis900.h"
 
 static char version[] __devinitdata =
-KERN_INFO "sis900.c: v1.07.11  4/10/2001\n";
+KERN_INFO "sis900.c: v1.08.00  6/11/2001\n";
 
 static int max_interrupt_work = 40;
 static int multicast_filter_limit = 128;
@@ -110,6 +111,7 @@
 	{ "AMD 79C901 HomePNA PHY",		0x0000, 0x6B90, HOME},
 	{ "ICS LAN PHY",			0x0015, 0xF440, LAN },
 	{ "NS 83851 PHY",			0x2000, 0x5C20, MIX },
+	{ "Realtek RTL8201 PHY",		0x0000, 0x8200, LAN },
 	{0,},
 };
 
@@ -158,6 +160,9 @@
 MODULE_PARM(multicast_filter_limit, "i");
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(multicast_filter_limit, "SiS 900/7016 maximum number of filtered multicast addresses");
+MODULE_PARM_DESC(max_interrupt_work, "SiS 900/7016 maximum events handled per interrupt");
+MODULE_PARM_DESC(debug, "SiS 900/7016 debug level (2-4)");
 
 static int sis900_open(struct net_device *net_dev);
 static int sis900_mii_probe (struct net_device * net_dev);
@@ -375,13 +380,13 @@
 
 	if (ret == 0) {
 		ret = -ENODEV;
-		goto err_out_region;
+		goto err_out_unregister;
 	}
 
 	/* probe for mii transciver */
 	if (sis900_mii_probe(net_dev) == 0) {
 		ret = -ENODEV;
-		goto err_out_region;
+		goto err_out_unregister;
 	}
 
 	/* print some information about our NIC */
@@ -393,9 +398,10 @@
 
 	return 0;
 
+ err_out_unregister:
+ 	unregister_netdev(net_dev);
  err_out_cleardev:
  	pci_set_drvdata(pci_dev, NULL);
- err_out_region:
 	pci_release_regions(pci_dev);
  err_out:
 	kfree(net_dev);
@@ -996,7 +1002,7 @@
 static void sis630_set_eq(struct net_device *net_dev, u8 revision)
 {
 	struct sis900_private *sis_priv = net_dev->priv;
-	u16 reg14h, eq_value, max_value=0, min_value=0;
+	u16 reg14h, eq_value=0, max_value=0, min_value=0;
 	u8 host_bridge_rev;
 	int i, maxcount=10;
 	struct pci_dev *dev=NULL;
@@ -1243,6 +1249,7 @@
 static void sis900_read_mode(struct net_device *net_dev, int *speed, int *duplex)
 {
 	struct sis900_private *sis_priv = net_dev->priv;
+	struct mii_phy *phy = sis_priv->mii;
 	int phy_addr = sis_priv->cur_phy;
 	u32 status;
 	u16 autoadv, autorec;
@@ -1258,18 +1265,25 @@
 	autoadv = mdio_read(net_dev, phy_addr, MII_ANADV);
 	autorec = mdio_read(net_dev, phy_addr, MII_ANLPAR);
 	status = autoadv & autorec;
+	
+	*speed = HW_SPEED_10_MBPS;
+	*duplex = FDX_CAPABLE_HALF_SELECTED;
 
 	if (status & (MII_NWAY_TX | MII_NWAY_TX_FDX))
 		*speed = HW_SPEED_100_MBPS;
-	else
-		*speed = HW_SPEED_10_MBPS;
 	if (status & ( MII_NWAY_TX_FDX | MII_NWAY_T_FDX))
 		*duplex = FDX_CAPABLE_FULL_SELECTED;
-	else
-		*duplex = FDX_CAPABLE_HALF_SELECTED;
-
-	sis_priv->autong_complete = 1;
 	
+	sis_priv->autong_complete = 1;
+
+	/* Workaround for Realtek RTL8201 PHY issue */
+	if((phy->phy_id0 == 0x0000) && ((phy->phy_id1 & 0xFFF0) == 0x8200)){
+		if(mdio_read(net_dev, phy_addr, MII_CONTROL) & MII_CNTL_FDX)
+			*duplex = FDX_CAPABLE_FULL_SELECTED;
+		if(mdio_read(net_dev, phy_addr, 0x0019) & 0x01)
+			*speed = HW_SPEED_100_MBPS;
+	}
+
 	printk(KERN_INFO "%s: Media Link On %s %s-duplex \n",
 	       net_dev->name,
 	       *speed == HW_SPEED_100_MBPS ?
diff -u --recursive --new-file v2.4.5/linux/drivers/net/slip.c linux/drivers/net/slip.c
--- v2.4.5/linux/drivers/net/slip.c	Wed Apr 18 14:40:06 2001
+++ linux/drivers/net/slip.c	Wed Jun 20 11:10:53 2001
@@ -96,6 +96,7 @@
 
 int slip_maxdev = SL_NRUNIT;		/* Can be overridden with insmod! */
 MODULE_PARM(slip_maxdev, "i");
+MODULE_PARM_DESC(slip_maxdev, "Maximum number of slip devices");
 
 static struct tty_ldisc	sl_ldisc;
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/smc-mca.c linux/drivers/net/smc-mca.c
--- v2.4.5/linux/drivers/net/smc-mca.c	Sun Mar  4 14:05:04 2001
+++ linux/drivers/net/smc-mca.c	Wed Jun 20 11:10:53 2001
@@ -440,6 +440,8 @@
 
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ULTRAMCA_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ULTRAMCA_CARDS) "i");
+MODULE_PARM_DESC(io, "SMC Ultra/EtherEZ MCA I/O base address(es)");
+MODULE_PARM_DESC(irq, "SMC Ultra/EtherEZ MCA IRQ number(s)");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.4.5/linux/drivers/net/smc-ultra.c linux/drivers/net/smc-ultra.c
--- v2.4.5/linux/drivers/net/smc-ultra.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/smc-ultra.c	Wed Jun 20 11:10:53 2001
@@ -500,6 +500,8 @@
 
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ULTRA_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ULTRA_CARDS) "i");
+MODULE_PARM_DESC(io, "SMC Ultra I/O base address(es)");
+MODULE_PARM_DESC(irq, "SMC Ultra IRQ number(s) (assigned)");
 
 EXPORT_NO_SYMBOLS;
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/smc9194.c linux/drivers/net/smc9194.c
--- v2.4.5/linux/drivers/net/smc9194.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/smc9194.c	Wed Jun 20 11:10:53 2001
@@ -1566,6 +1566,9 @@
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
 MODULE_PARM(ifport, "i");
+MODULE_PARM_DESC(io, "SMC 99194 I/O base address");
+MODULE_PARM_DESC(irq, "SMC 99194 IRQ number");
+MODULE_PARM_DESC(ifport, "SMC 99194 interface port (0-default, 1-TP, 2-AUI)");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.4.5/linux/drivers/net/starfire.c linux/drivers/net/starfire.c
--- v2.4.5/linux/drivers/net/starfire.c	Fri Apr 20 11:54:23 2001
+++ linux/drivers/net/starfire.c	Wed Jun 20 21:00:55 2001
@@ -2,6 +2,10 @@
 /*
 	Written 1998-2000 by Donald Becker.
 
+	Current maintainer is Ion Badulescu <ionut@cs.columbia.edu>. Please
+	send all bug reports to me, and not to Donald Becker, as this code
+	has been modified quite a bit from Donald's original version.
+
 	This software may be used and distributed according to the terms of
 	the GNU General Public License (GPL), incorporated herein by reference.
 	Drivers based on or derived from this code fall under the GPL and must
@@ -20,7 +24,7 @@
 	-----------------------------------------------------------
 
 	Linux kernel-specific changes:
-	
+
 	LK1.1.1 (jgarzik):
 	- Use PCI driver interface
 	- Fix MOD_xxx races
@@ -31,35 +35,130 @@
 
 	LK1.1.3 (Andrew Morton)
 	- Timer cleanups
-	
+
 	LK1.1.4 (jgarzik):
 	- Merge Becker version 1.03
+
+	LK1.2.1 (Ion Badulescu <ionut@cs.columbia.edu>)
+	- Support hardware Rx/Tx checksumming
+	- Use the GFP firmware taken from Adaptec's Netware driver
+
+	LK1.2.2 (Ion Badulescu)
+	- Backported to 2.2.x
+
+	LK1.2.3 (Ion Badulescu)
+	- Fix the flaky mdio interface
+	- More compat clean-ups
+
+	LK1.2.4 (Ion Badulescu)
+	- More 2.2.x initialization fixes
+
+	LK1.2.5 (Ion Badulescu)
+	- Several fixes from Manfred Spraul
+
+	LK1.2.6 (Ion Badulescu)
+	- Fixed ifup/ifdown/ifup problem in 2.4.x
+
+	LK1.2.7 (Ion Badulescu)
+	- Removed unused code
+	- Made more functions static and __init
+
+	LK1.2.8 (Ion Badulescu)
+	- Quell bogus error messages, inform about the Tx threshold
+	- Removed #ifdef CONFIG_PCI, this driver is PCI only
+
+	LK1.2.9 (Ion Badulescu)
+	- Merged Jeff Garzik's changes from 2.4.4-pre5
+	- Added 2.2.x compatibility stuff required by the above changes
+
+	LK1.2.9a (Ion Badulescu)
+	- More updates from Jeff Garzik
+
+	LK1.3.0 (Ion Badulescu)
+	- Merged zerocopy support
+
+	LK1.3.1 (Ion Badulescu)
+	- Added ethtool support
+	- Added GPIO (media change) interrupt support
+
+	LK1.3.2 (Ion Badulescu)
+	- Fixed 2.2.x compatibility issues introduced in 1.3.1
+	- Fixed ethtool ioctl returning uninitialized memory
+
+TODO:
+	- implement tx_timeout() properly
 */
 
+#define DRV_NAME	"starfire"
+#define DRV_VERSION	"1.03+LK1.3.2"
+#define DRV_RELDATE	"June 04, 2001"
+
+/*
+ * Adaptec's license for their Novell drivers (which is where I got the
+ * firmware files) does not allow one to redistribute them. Thus, we can't
+ * include the firmware with this driver.
+ *
+ * However, an end-user is allowed to download and use it, after
+ * converting it to C header files using starfire_firmware.pl.
+ * Once that's done, the #undef below must be changed into a #define
+ * for this driver to really use the firmware. Note that Rx/Tx
+ * hardware TCP checksumming is not possible without the firmware.
+ *
+ * I'm currently [Feb 2001] talking to Adaptec about this redistribution
+ * issue. Stay tuned...
+ */
+#undef HAS_FIRMWARE
+/*
+ * The current frame processor firmware fails to checksum a fragment
+ * of length 1. If and when this is fixed, the #define below can be removed.
+ */
+#define HAS_BROKEN_FIRMWARE
+/*
+ * Define this if using the driver with the zero-copy patch
+ */
+#if defined(HAS_FIRMWARE) && defined(MAX_SKB_FRAGS)
+#define ZEROCOPY
+#endif
+
 /* The user-configurable values.
    These may be modified when a driver module is loaded.*/
 
 /* Used for tuning interrupt latency vs. overhead. */
-static int interrupt_mitigation = 0x0;
+static int interrupt_mitigation;
 
 static int debug = 1;			/* 1 normal messages, 0 quiet .. 7 verbose. */
 static int max_interrupt_work = 20;
 static int mtu;
 /* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
-   The Starfire has a 512 element hash table based on the Ethernet CRC.  */
-static int multicast_filter_limit = 32;
+   The Starfire has a 512 element hash table based on the Ethernet CRC. */
+static int multicast_filter_limit = 512;
 
-/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
-   Setting to > 1518 effectively disables this feature. */
+#define PKT_BUF_SZ	1536		/* Size of each temporary Rx buffer.*/
+/*
+ * Set the copy breakpoint for the copy-only-tiny-frames scheme.
+ * Setting to > 1518 effectively disables this feature.
+ *
+ * NOTE:
+ * The ia64 doesn't allow for unaligned loads even of integers being
+ * misaligned on a 2 byte boundary. Thus always force copying of
+ * packets as the starfire doesn't allow for misaligned DMAs ;-(
+ * 23/10/2000 - Jes
+ *
+ * The Alpha and the Sparc don't allow unaligned loads, either. -Ion
+ */
+#if defined(__ia64__) || defined(__alpha__) || defined(__sparc__)
+static int rx_copybreak = PKT_BUF_SZ;
+#else
 static int rx_copybreak = 0;
+#endif
 
 /* Used to pass the media type, etc.
    Both 'options[]' and 'full_duplex[]' exist for driver interoperability.
    The media type is usually passed in 'options[]'.
 */
 #define MAX_UNITS 8		/* More are supported, limit only on options */
-static int options[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+static int options[MAX_UNITS] = {0, };
+static int full_duplex[MAX_UNITS] = {0, };
 
 /* Operational parameters that are set at compile time. */
 
@@ -75,21 +174,23 @@
 
 /* Operational parameters that usually are not changed. */
 /* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT  (2*HZ)
+#define TX_TIMEOUT	(2 * HZ)
 
-#define PKT_BUF_SZ		1536			/* Size of each temporary Rx buffer.*/
-
-/*
- * The ia64 doesn't allow for unaligned loads even of integers being
- * misaligned on a 2 byte boundary. Thus always force copying of
- * packets as the starfire doesn't allow for misaligned DMAs ;-(
- * 23/10/2000 - Jes
- */
-#ifdef __ia64__
-#define PKT_SHOULD_COPY(pkt_len)	1
-#else
-#define PKT_SHOULD_COPY(pkt_len)	(pkt_len < rx_copybreak)
-#endif
+#ifdef ZEROCOPY
+#if MAX_SKB_FRAGS <= 6
+#define MAX_STARFIRE_FRAGS 6
+#else  /* MAX_STARFIRE_FRAGS > 6 */
+#warning This driver will not work with more than 6 skb fragments.
+#warning Turning off zerocopy support.
+#undef ZEROCOPY
+#endif /* MAX_STARFIRE_FRAGS > 6 */
+#endif /* ZEROCOPY */
+
+#ifdef ZEROCOPY
+#define skb_first_frag_len(skb)	skb_headlen(skb)
+#else  /* not ZEROCOPY */
+#define skb_first_frag_len(skb)	(skb->len)
+#endif /* not ZEROCOPY */
 
 #if !defined(__OPTIMIZE__)
 #warning  You must compile this file with the correct options!
@@ -97,28 +198,54 @@
 #error You must compile this driver with "-O".
 #endif
 
+#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
-#include <linux/skbuff.h>
 #include <linux/init.h>
+#include <linux/delay.h>
 #include <asm/processor.h>		/* Processor type for cache alignment. */
-#include <asm/bitops.h>
+#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
+
+#include "starfire-kcomp22.h"
+
+#else  /* LINUX_VERSION_CODE > 0x20300 */
+
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+
+#define COMPAT_MOD_INC_USE_COUNT
+#define COMPAT_MOD_DEC_USE_COUNT
+
+#define init_tx_timer(dev, func, timeout) \
+	dev->tx_timeout = func; \
+	dev->watchdog_timeo = timeout;
+#define kick_tx_timer(dev, func, timeout)
+
+#define netif_start_if(dev)
+#define netif_stop_if(dev)
+
+#define PCI_SLOT_NAME(pci_dev)	(pci_dev)->slot_name
+
+#endif /* LINUX_VERSION_CODE > 0x20300 */
+/* end of compatibility code */
+
+
 /* 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.4.x kernel port, version 1.1.4a, April 17, 2001)\n";
+KERN_INFO " (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n";
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("Adaptec Starfire Ethernet driver");
@@ -126,8 +253,15 @@
 MODULE_PARM(mtu, "i");
 MODULE_PARM(debug, "i");
 MODULE_PARM(rx_copybreak, "i");
+MODULE_PARM(interrupt_mitigation, "i");
 MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM_DESC(max_interrupt_work, "Starfire maximum events handled per interrupt");
+MODULE_PARM_DESC(mtu, "Starfire MTU (all boards)");
+MODULE_PARM_DESC(debug, "Starfire debug level (0-6)");
+MODULE_PARM_DESC(rx_copybreak, "Starfire copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(options, "Starfire: Bits 0-3: media type, bit 17: full duplex");
+MODULE_PARM_DESC(full_duplex, "Starfire full duplex setting(s) (1)");
 
 /*
 				Theory of Operation
@@ -158,8 +292,9 @@
 See the Adaptec manual for the many possible structures, and options for
 each structure.  There are far too many to document here.
 
-For transmit this driver uses type 1 transmit descriptors, and relies on
-automatic minimum-length padding.  It does not use the completion queue
+For transmit this driver uses type 0/1 transmit descriptors (depending
+on the presence of the zerocopy infrastructure), and relies on automatic
+minimum-length padding.  It does not use the completion queue
 consumer index, but instead checks for non-zero status entries.
 
 For receive this driver uses type 0 receive descriptors.  The driver
@@ -174,10 +309,11 @@
 phase of receive.
 
 A notable aspect of operation is that unaligned buffers are not permitted by
-the Starfire hardware.  The IP header at offset 14 in an ethernet frame thus
+the Starfire hardware.  Thus the IP header at offset 14 in an ethernet frame
 isn't longword aligned, which may cause problems on some machine
-e.g. Alphas.  Copied frames are put into the skbuff at an offset of "+2",
-16-byte aligning the IP header.
+e.g. Alphas and IA64. For these architectures, the driver is forced to copy
+the frame into a new skbuff unconditionally. Copied frames are put into the
+skbuff at an offset of "+2", thus 16-byte aligning the IP header.
 
 IIId. Synchronization
 
@@ -212,7 +348,6 @@
 
 enum chip_capability_flags {CanHaveMII=1, };
 #define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR0)
-#define MEM_ADDR_SZ 0x80000		/* And maps in 0.5MB(!).  */
 
 #if 0
 #define ADDR_64BITS 1			/* This chip uses 64 bit addresses. */
@@ -233,10 +368,9 @@
 /* A chip capabilities table, matching the CH_xxx entries in xxx_pci_tbl[] above. */
 static struct chip_info {
 	const char *name;
-	int io_size;
 	int drv_flags;
 } netdrv_tbl[] __devinitdata = {
-	{ "Adaptec Starfire 6915", MEM_ADDR_SZ, CanHaveMII },
+	{ "Adaptec Starfire 6915", CanHaveMII },
 };
 
 
@@ -252,26 +386,40 @@
 	PCIDeviceConfig=0x50040, GenCtrl=0x50070, IntrTimerCtrl=0x50074,
 	IntrClear=0x50080, IntrStatus=0x50084, IntrEnable=0x50088,
 	MIICtrl=0x52000, StationAddr=0x50120, EEPROMCtrl=0x51000,
-	TxDescCtrl=0x50090,
+	GPIOCtrl=0x5008C, TxDescCtrl=0x50090,
 	TxRingPtr=0x50098, HiPriTxRingPtr=0x50094, /* Low and High priority. */
 	TxRingHiAddr=0x5009C,		/* 64 bit address extension. */
 	TxProducerIdx=0x500A0, TxConsumerIdx=0x500A4,
 	TxThreshold=0x500B0,
 	CompletionHiAddr=0x500B4, TxCompletionAddr=0x500B8,
 	RxCompletionAddr=0x500BC, RxCompletionQ2Addr=0x500C0,
-	CompletionQConsumerIdx=0x500C4,
+	CompletionQConsumerIdx=0x500C4, RxDMACtrl=0x500D0,
 	RxDescQCtrl=0x500D4, RxDescQHiAddr=0x500DC, RxDescQAddr=0x500E0,
 	RxDescQIdx=0x500E8, RxDMAStatus=0x500F0, RxFilterMode=0x500F4,
-	TxMode=0x55000,
+	TxMode=0x55000, PerfFilterTable=0x56000, HashTable=0x56100,
+	TxGfpMem=0x58000, RxGfpMem=0x5a000,
 };
 
 /* Bits in the interrupt status/mask registers. */
 enum intr_status_bits {
-	IntrNormalSummary=0x8000,	IntrAbnormalSummary=0x02000000,
-	IntrRxDone=0x0300, IntrRxEmpty=0x10040, IntrRxPCIErr=0x80000,
-	IntrTxDone=0x4000, IntrTxEmpty=0x1000, IntrTxPCIErr=0x80000,
-	StatsMax=0x08000000, LinkChange=0xf0000000,
-	IntrTxDataLow=0x00040000,
+	IntrLinkChange=0xf0000000, IntrStatsMax=0x08000000,
+	IntrAbnormalSummary=0x02000000, IntrGeneralTimer=0x01000000,
+	IntrSoftware=0x800000, IntrRxComplQ1Low=0x400000,
+	IntrTxComplQLow=0x200000, IntrPCI=0x100000,
+	IntrDMAErr=0x080000, IntrTxDataLow=0x040000,
+	IntrRxComplQ2Low=0x020000, IntrRxDescQ1Low=0x010000,
+	IntrNormalSummary=0x8000, IntrTxDone=0x4000,
+	IntrTxDMADone=0x2000, IntrTxEmpty=0x1000,
+	IntrEarlyRxQ2=0x0800, IntrEarlyRxQ1=0x0400,
+	IntrRxQ2Done=0x0200, IntrRxQ1Done=0x0100,
+	IntrRxGFPDead=0x80, IntrRxDescQ2Low=0x40,
+	IntrNoTxCsum=0x20, IntrTxBadID=0x10,
+	IntrHiPriTxBadID=0x08, IntrRxGfp=0x04,
+	IntrTxGfp=0x02, IntrPCIPad=0x01,
+	/* not quite bits */
+	IntrRxDone=IntrRxQ2Done | IntrRxQ1Done,
+	IntrRxEmpty=IntrRxDescQ1Low | IntrRxDescQ2Low,
+	IntrNormalMask=0xf0, IntrAbnormalMask=0x3f0e,
 };
 
 /* Bits in the RxFilterMode register. */
@@ -280,9 +428,40 @@
 	AcceptMulticast=0x10, AcceptMyPhys=0xE040,
 };
 
+/* Bits in the TxDescCtrl register. */
+enum tx_ctrl_bits {
+	TxDescSpaceUnlim=0x00, TxDescSpace32=0x10, TxDescSpace64=0x20,
+	TxDescSpace128=0x30, TxDescSpace256=0x40,
+	TxDescType0=0x00, TxDescType1=0x01, TxDescType2=0x02,
+	TxDescType3=0x03, TxDescType4=0x04,
+	TxNoDMACompletion=0x08, TxDescQ64bit=0x80,
+	TxHiPriFIFOThreshShift=24, TxPadLenShift=16,
+	TxDMABurstSizeShift=8,
+};
+
+/* Bits in the RxDescQCtrl register. */
+enum rx_ctrl_bits {
+	RxBufferLenShift=16, RxMinDescrThreshShift=0,
+	RxPrefetchMode=0x8000, Rx2048QEntries=0x4000,
+	RxVariableQ=0x2000, RxDesc64bit=0x1000,
+	RxDescQAddr64bit=0x0100,
+	RxDescSpace4=0x000, RxDescSpace8=0x100,
+	RxDescSpace16=0x200, RxDescSpace32=0x300,
+	RxDescSpace64=0x400, RxDescSpace128=0x500,
+	RxConsumerWrEn=0x80,
+};
+
+/* Bits in the RxCompletionAddr register */
+enum rx_compl_bits {
+	RxComplQAddr64bit=0x80, TxComplProducerWrEn=0x40,
+	RxComplType0=0x00, RxComplType1=0x10,
+	RxComplType2=0x20, RxComplType3=0x30,
+	RxComplThreshShift=0,
+};
+
 /* The Rx and Tx buffer descriptors. */
 struct starfire_rx_desc {
-	u32 rxaddr;					/* Optionally 64 bits. */
+	u32 rxaddr;			/* Optionally 64 bits. */
 };
 enum rx_desc_bits {
 	RxDescValid=1, RxDescEndRing=2,
@@ -291,42 +470,72 @@
 /* Completion queue entry.
    You must update the page allocation, init_ring and the shift count in rx()
    if using a larger format. */
+#ifdef HAS_FIRMWARE
+#define csum_rx_status
+#endif /* HAS_FIRMWARE */
 struct rx_done_desc {
-	u32 status;					/* Low 16 bits is length. */
+	u32 status;			/* Low 16 bits is length. */
+#ifdef csum_rx_status
+	u32 status2;			/* Low 16 bits is csum */
+#endif /* csum_rx_status */
 #ifdef full_rx_status
 	u32 status2;
 	u16 vlanid;
-	u16 csum; 			/* partial checksum */
+	u16 csum;			/* partial checksum */
 	u32 timestamp;
-#endif
+#endif /* full_rx_status */
 };
 enum rx_done_bits {
 	RxOK=0x20000000, RxFIFOErr=0x10000000, RxBufQ2=0x08000000,
 };
 
+#ifdef ZEROCOPY
+/* Type 0 Tx descriptor. */
+/* If more fragments are needed, don't forget to change the
+   descriptor spacing as well! */
+struct starfire_tx_desc {
+	u32 status;
+	u32 nbufs;
+	u32 first_addr;
+	u16 first_len;
+	u16 total_len;
+	struct {
+		u32 addr;
+		u32 len;
+	} frag[MAX_STARFIRE_FRAGS];
+};
+#else  /* not ZEROCOPY */
 /* Type 1 Tx descriptor. */
 struct starfire_tx_desc {
-	u32 status;					/* Upper bits are status, lower 16 length. */
-	u32 addr;
+	u32 status;			/* Upper bits are status, lower 16 length. */
+	u32 first_addr;
 };
+#endif /* not ZEROCOPY */
 enum tx_desc_bits {
-	TxDescID=0xB1010000,		/* Also marks single fragment, add CRC.  */
-	TxDescIntr=0x08000000, TxRingWrap=0x04000000,
+	TxDescID=0xB0000000,
+	TxCRCEn=0x01000000, TxDescIntr=0x08000000,
+	TxRingWrap=0x04000000, TxCalTCP=0x02000000,
 };
 struct tx_done_report {
-	u32 status;					/* timestamp, index. */
+	u32 status;			/* timestamp, index. */
 #if 0
-	u32 intrstatus;				/* interrupt status */
+	u32 intrstatus;			/* interrupt status */
 #endif
 };
 
-#define PRIV_ALIGN	15 	/* Required alignment mask */
-struct ring_info {
+struct rx_ring_info {
 	struct sk_buff *skb;
 	dma_addr_t mapping;
 };
+struct tx_ring_info {
+	struct sk_buff *skb;
+	dma_addr_t first_mapping;
+#ifdef ZEROCOPY
+	dma_addr_t frag_mapping[MAX_STARFIRE_FRAGS];
+#endif /* ZEROCOPY */
+};
 
-#define MII_CNT		4
+#define PHY_CNT		2
 struct netdev_private {
 	/* Descriptor rings first for alignment. */
 	struct starfire_rx_desc *rx_ring;
@@ -334,66 +543,65 @@
 	dma_addr_t rx_ring_dma;
 	dma_addr_t tx_ring_dma;
 	/* The addresses of rx/tx-in-place skbuffs. */
-	struct ring_info rx_info[RX_RING_SIZE];
-	struct ring_info tx_info[TX_RING_SIZE];
-	/* Pointers to completion queues (full pages).  I should cache line pad..*/
-	u8 pad0[100];
+	struct rx_ring_info rx_info[RX_RING_SIZE];
+	struct tx_ring_info tx_info[TX_RING_SIZE];
+	/* Pointers to completion queues (full pages). */
 	struct rx_done_desc *rx_done_q;
 	dma_addr_t rx_done_q_dma;
 	unsigned int rx_done;
 	struct tx_done_report *tx_done_q;
-	unsigned int tx_done;
 	dma_addr_t tx_done_q_dma;
+	unsigned int tx_done;
 	struct net_device_stats stats;
-	struct timer_list timer;	/* Media monitoring timer. */
 	struct pci_dev *pci_dev;
 	/* Frequently used values: keep some adjacent for cache effect. */
-	unsigned int cur_rx, dirty_rx;		/* Producer/consumer ring indices */
+	unsigned int cur_rx, dirty_rx;	/* Producer/consumer ring indices */
 	unsigned int cur_tx, dirty_tx;
-	unsigned int rx_buf_sz;				/* Based on MTU+slack. */
-	unsigned int tx_full:1;				/* The Tx queue is full. */
+	unsigned int rx_buf_sz;		/* Based on MTU+slack. */
+	unsigned int tx_full:1,		/* The Tx queue is full. */
 	/* These values are keep track of the transceiver/media in use. */
-	unsigned int full_duplex:1,			/* Full-duplex operation requested. */
-		medialock:1,					/* Xcvr set to fixed speed/duplex. */
-		rx_flowctrl:1,
-		tx_flowctrl:1;					/* Use 802.3x flow control. */
-	unsigned int default_port:4;		/* Last dev->if_port value. */
+		autoneg:1,		/* Autonegotiation allowed. */
+		full_duplex:1,		/* Full-duplex operation. */
+		speed100:1;		/* Set if speed == 100MBit. */
+	unsigned int intr_mitigation;
 	u32 tx_mode;
 	u8 tx_threshold;
 	/* MII transceiver section. */
-	int mii_cnt;						/* MII device addresses. */
-	u16 advertising;					/* NWay media advertisement */
-	unsigned char phys[MII_CNT];		/* MII device addresses, only first one used. */
-};
-
-static int  mdio_read(struct net_device *dev, int phy_id, int location);
-static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
-static int  netdev_open(struct net_device *dev);
-static void check_duplex(struct net_device *dev, int startup);
-static void netdev_timer(unsigned long data);
-static void tx_timeout(struct net_device *dev);
-static void init_ring(struct net_device *dev);
-static int  start_tx(struct sk_buff *skb, struct net_device *dev);
-static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
-static void netdev_error(struct net_device *dev, int intr_status);
-static int  netdev_rx(struct net_device *dev);
-static void netdev_error(struct net_device *dev, int intr_status);
-static void set_rx_mode(struct net_device *dev);
+	u16 advertising;		/* NWay media advertisement */
+	int phy_cnt;			/* MII device addresses. */
+	unsigned char phys[PHY_CNT];	/* MII device addresses. */
+};
+
+static int	mdio_read(struct net_device *dev, int phy_id, int location);
+static void	mdio_write(struct net_device *dev, int phy_id, int location, int value);
+static int	netdev_open(struct net_device *dev);
+static void	check_duplex(struct net_device *dev);
+static void	tx_timeout(struct net_device *dev);
+static void	init_ring(struct net_device *dev);
+static int	start_tx(struct sk_buff *skb, struct net_device *dev);
+static void	intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
+static void	netdev_error(struct net_device *dev, int intr_status);
+static int	netdev_rx(struct net_device *dev);
+static void	netdev_error(struct net_device *dev, int intr_status);
+static void	set_rx_mode(struct net_device *dev);
 static struct net_device_stats *get_stats(struct net_device *dev);
-static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static int  netdev_close(struct net_device *dev);
+static int	mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int	netdev_close(struct net_device *dev);
+static void	netdev_media_change(struct net_device *dev);
 
 
 
-static int __devinit starfire_init_one (struct pci_dev *pdev,
-					const struct pci_device_id *ent)
+static int __devinit starfire_init_one(struct pci_dev *pdev,
+				       const struct pci_device_id *ent)
 {
 	struct netdev_private *np;
 	int i, irq, option, chip_idx = ent->driver_data;
 	struct net_device *dev;
 	static int card_idx = -1;
 	long ioaddr;
-	int drv_flags, io_size = netdrv_tbl[chip_idx].io_size;
+	int drv_flags, io_size;
+	int boguscnt;
+	u8 cache;
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -403,38 +611,58 @@
 #endif
 
 	card_idx++;
-	option = card_idx < MAX_UNITS ? options[card_idx] : 0;
 
 	if (pci_enable_device (pdev))
 		return -EIO;
 
 	ioaddr = pci_resource_start (pdev, 0);
+	io_size = pci_resource_len (pdev, 0);
 	if (!ioaddr || ((pci_resource_flags (pdev, 0) & IORESOURCE_MEM) == 0)) {
-		printk (KERN_ERR "starfire %d: no PCI MEM resources, aborting\n", card_idx);
+		printk (KERN_ERR DRV_NAME " %d: no PCI MEM resources, aborting\n", card_idx);
 		return -ENODEV;
 	}
-	
+
 	dev = alloc_etherdev(sizeof(*np));
 	if (!dev) {
-		printk (KERN_ERR "starfire %d: cannot alloc etherdev, aborting\n", card_idx);
+		printk (KERN_ERR DRV_NAME " %d: cannot alloc etherdev, aborting\n", card_idx);
 		return -ENOMEM;
 	}
 	SET_MODULE_OWNER(dev);
-	
-	irq = pdev->irq; 
 
-	if (pci_request_regions (pdev, "starfire"))
+	irq = pdev->irq;
+
+	if (pci_request_regions (pdev, dev->name)) {
+		printk (KERN_ERR DRV_NAME " %d: cannot reserve PCI resources, aborting\n", card_idx);
 		goto err_out_free_netdev;
+	}
 
 	ioaddr = (long) ioremap (ioaddr, io_size);
 	if (!ioaddr) {
-		printk (KERN_ERR "starfire %d: cannot remap 0x%x @ 0x%lx, aborting\n",
+		printk (KERN_ERR DRV_NAME " %d: cannot remap 0x%x @ 0x%lx, aborting\n",
 			card_idx, io_size, ioaddr);
 		goto err_out_free_res;
 	}
 
 	pci_set_master (pdev);
-	
+
+	/* set PCI cache size */
+	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache);
+	if ((cache << 2) != SMP_CACHE_BYTES) {
+		printk(KERN_INFO "  PCI cache line size set incorrectly "
+		       "(%i bytes) by BIOS/FW, correcting to %i\n",
+		       (cache << 2), SMP_CACHE_BYTES);
+		pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
+				      SMP_CACHE_BYTES >> 2);
+	}
+
+#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 */
+#endif /* ZEROCOPY */
+
 	/* Serial EEPROM reads are hidden by the hardware. */
 	for (i = 0; i < 6; i++)
 		dev->dev_addr[i] = readb(ioaddr + EEPROMCtrl + 20-i);
@@ -442,12 +670,28 @@
 #if ! defined(final_version) /* Dump the EEPROM contents during development. */
 	if (debug > 4)
 		for (i = 0; i < 0x20; i++)
-			printk("%2.2x%s", (unsigned int)readb(ioaddr + EEPROMCtrl + i),
-				   i % 16 != 15 ? " " : "\n");
+			printk("%2.2x%s",
+			       (unsigned int)readb(ioaddr + EEPROMCtrl + i),
+			       i % 16 != 15 ? " " : "\n");
 #endif
 
+	/* Issue soft reset */
+	writel(0x8000, ioaddr + TxMode);
+	udelay(1000);
+	writel(0, ioaddr + TxMode);
+
 	/* Reset the chip to erase previous misconfiguration. */
 	writel(1, ioaddr + PCIDeviceConfig);
+	boguscnt = 1000;
+	while (--boguscnt > 0) {
+		udelay(10);
+		if ((readl(ioaddr + PCIDeviceConfig) & 1) == 0)
+			break;
+	}
+	if (boguscnt == 0)
+		printk("%s: chipset reset never completed!\n", dev->name);
+	/* wait a little longer */
+	udelay(1000);
 
 	dev->base_addr = ioaddr;
 	dev->irq = irq;
@@ -458,28 +702,27 @@
 	np->pci_dev = pdev;
 	drv_flags = netdrv_tbl[chip_idx].drv_flags;
 
+	option = card_idx < MAX_UNITS ? options[card_idx] : 0;
 	if (dev->mem_start)
 		option = dev->mem_start;
 
 	/* The lower four bits are the media type. */
-	if (option > 0) {
-		if (option & 0x200)
-			np->full_duplex = 1;
-		np->default_port = option & 15;
-		if (np->default_port)
-			np->medialock = 1;
-	}
-	if (card_idx < MAX_UNITS  &&  full_duplex[card_idx] > 0)
+	if (option & 0x200)
+		np->full_duplex = 1;
+
+	if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0)
 		np->full_duplex = 1;
 
 	if (np->full_duplex)
-		np->medialock = 1;
+		np->autoneg = 0;
+	else
+		np->autoneg = 1;
+	np->speed100 = 1;
 
 	/* The chip-specific entries in the device structure. */
 	dev->open = &netdev_open;
 	dev->hard_start_xmit = &start_tx;
-	dev->tx_timeout = &tx_timeout;
-	dev->watchdog_timeo = TX_TIMEOUT;
+	init_tx_timer(dev, tx_timeout, TX_TIMEOUT);
 	dev->stop = &netdev_close;
 	dev->get_stats = &get_stats;
 	dev->set_multicast_list = &set_rx_mode;
@@ -495,22 +738,35 @@
 	printk(KERN_INFO "%s: %s at 0x%lx, ",
 		   dev->name, netdrv_tbl[chip_idx].name, ioaddr);
 	for (i = 0; i < 5; i++)
-			printk("%2.2x:", dev->dev_addr[i]);
+		printk("%2.2x:", dev->dev_addr[i]);
 	printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
 
 	if (drv_flags & CanHaveMII) {
 		int phy, phy_idx = 0;
-		for (phy = 0; phy < 32 && phy_idx < MII_CNT; phy++) {
-			int mii_status = mdio_read(dev, phy, 1);
-			if (mii_status != 0xffff  &&  mii_status != 0x0000) {
+		int mii_status;
+		for (phy = 0; phy < 32 && phy_idx < PHY_CNT; phy++) {
+			mdio_write(dev, phy, MII_BMCR, BMCR_RESET);
+			udelay(500);
+			boguscnt = 1000;
+			while (--boguscnt > 0)
+				if ((mdio_read(dev, phy, MII_BMCR) & BMCR_RESET) == 0)
+					break;
+			if (boguscnt == 0) {
+				printk("%s: PHY reset never completed!\n", dev->name);
+				continue;
+			}
+			mii_status = mdio_read(dev, phy, MII_BMSR);
+			if (mii_status != 0) {
 				np->phys[phy_idx++] = phy;
-				np->advertising = mdio_read(dev, phy, 4);
+				np->advertising = mdio_read(dev, phy, MII_ADVERTISE);
 				printk(KERN_INFO "%s: MII PHY found at address %d, status "
 					   "0x%4.4x advertising %4.4x.\n",
 					   dev->name, phy, mii_status, np->advertising);
+				/* there can be only one PHY on-board */
+				break;
 			}
 		}
-		np->mii_cnt = phy_idx;
+		np->phy_cnt = phy_idx;
 	}
 
 	return 0;
@@ -536,7 +792,11 @@
 	/* ??? Should we add a busy-wait here? */
 	do
 		result = readl(mdio_addr);
-	while ((result & 0xC0000000) != 0x80000000 && --boguscnt >= 0);
+	while ((result & 0xC0000000) != 0x80000000 && --boguscnt > 0);
+	if (boguscnt == 0)
+		return 0;
+	if ((result & 0xffff) == 0xffff)
+		return 0;
 	return result & 0xffff;
 }
 
@@ -557,48 +817,70 @@
 
 	/* Do we ever need to reset the chip??? */
 
+	COMPAT_MOD_INC_USE_COUNT;
+
 	retval = request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev);
-	if (retval)
+	if (retval) {
+		COMPAT_MOD_DEC_USE_COUNT;
 		return retval;
+	}
 
 	/* Disable the Rx and Tx, and reset the chip. */
 	writel(0, ioaddr + GenCtrl);
 	writel(1, ioaddr + PCIDeviceConfig);
 	if (debug > 1)
 		printk(KERN_DEBUG "%s: netdev_open() irq %d.\n",
-			   dev->name, dev->irq);
+		       dev->name, dev->irq);
 	/* Allocate the various queues, failing gracefully. */
 	if (np->tx_done_q == 0)
 		np->tx_done_q = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->tx_done_q_dma);
 	if (np->rx_done_q == 0)
-		np->rx_done_q = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->rx_done_q_dma);
+		np->rx_done_q = pci_alloc_consistent(np->pci_dev, sizeof(struct rx_done_desc) * DONE_Q_SIZE, &np->rx_done_q_dma);
 	if (np->tx_ring == 0)
 		np->tx_ring = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->tx_ring_dma);
 	if (np->rx_ring == 0)
 		np->rx_ring = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->rx_ring_dma);
-	if (np->tx_done_q == 0  ||  np->rx_done_q == 0
-		|| np->rx_ring == 0 ||  np->tx_ring == 0) {
+	if (np->tx_done_q == 0 || np->rx_done_q == 0
+		|| np->rx_ring == 0 || np->tx_ring == 0) {
 		if (np->tx_done_q)
 			pci_free_consistent(np->pci_dev, PAGE_SIZE,
-								np->tx_done_q, np->tx_done_q_dma);
+					    np->tx_done_q, np->tx_done_q_dma);
 		if (np->rx_done_q)
-			pci_free_consistent(np->pci_dev, PAGE_SIZE,
-								np->rx_done_q, np->rx_done_q_dma);
+			pci_free_consistent(np->pci_dev, sizeof(struct rx_done_desc) * DONE_Q_SIZE,
+					    np->rx_done_q, np->rx_done_q_dma);
 		if (np->tx_ring)
 			pci_free_consistent(np->pci_dev, PAGE_SIZE,
-								np->tx_ring, np->tx_ring_dma);
+					    np->tx_ring, np->tx_ring_dma);
 		if (np->rx_ring)
 			pci_free_consistent(np->pci_dev, PAGE_SIZE,
-								np->rx_ring, np->rx_ring_dma);
+					    np->rx_ring, np->rx_ring_dma);
+		COMPAT_MOD_DEC_USE_COUNT;
 		return -ENOMEM;
 	}
 
 	init_ring(dev);
 	/* Set the size of the Rx buffers. */
-	writel((np->rx_buf_sz<<16) | 0xA000, ioaddr + RxDescQCtrl);
-
+	writel((np->rx_buf_sz << RxBufferLenShift) |
+	       (0 << RxMinDescrThreshShift) |
+	       RxPrefetchMode | RxVariableQ |
+	       RxDescSpace4,
+	       ioaddr + RxDescQCtrl);
+
+#ifdef ZEROCOPY
+	/* Set Tx descriptor to type 0 and spacing to 64 bytes. */
+	writel((2 << TxHiPriFIFOThreshShift) |
+	       (0 << TxPadLenShift) |
+	       (4 << TxDMABurstSizeShift) |
+	       TxDescSpace64 | TxDescType0,
+	       ioaddr + TxDescCtrl);
+#else  /* not ZEROCOPY */
 	/* Set Tx descriptor to type 1 and padding to 0 bytes. */
-	writel(0x02000401, ioaddr + TxDescCtrl);
+	writel((2 << TxHiPriFIFOThreshShift) |
+	       (0 << TxPadLenShift) |
+	       (4 << TxDMABurstSizeShift) |
+	       TxDescSpaceUnlim | TxDescType1,
+	       ioaddr + TxDescCtrl);
+#endif /* not ZEROCOPY */
 
 #if defined(ADDR_64BITS) && defined(__alpha__)
 	/* XXX We really need a 64-bit PCI dma interfaces too... -DaveM */
@@ -613,17 +895,34 @@
 	writel(np->tx_ring_dma, ioaddr + TxRingPtr);
 
 	writel(np->tx_done_q_dma, ioaddr + TxCompletionAddr);
-	writel(np->rx_done_q_dma, ioaddr + RxCompletionAddr);
+#ifdef full_rx_status
+	writel(np->rx_done_q_dma |
+	       RxComplType3 |
+	       (0 << RxComplThreshShift),
+	       ioaddr + RxCompletionAddr);
+#else  /* not full_rx_status */
+#ifdef csum_rx_status
+	writel(np->rx_done_q_dma |
+	       RxComplType2 |
+	       (0 << RxComplThreshShift),
+	       ioaddr + RxCompletionAddr);
+#else  /* not csum_rx_status */
+	writel(np->rx_done_q_dma |
+	       RxComplType0 |
+	       (0 << RxComplThreshShift),
+	       ioaddr + RxCompletionAddr);
+#endif /* not csum_rx_status */
+#endif /* not full_rx_status */
 
 	if (debug > 1)
-		printk(KERN_DEBUG "%s:  Filling in the station address.\n", dev->name);
+		printk(KERN_DEBUG "%s: Filling in the station address.\n", dev->name);
 
 	/* Fill both the unused Tx SA register and the Rx perfect filter. */
 	for (i = 0; i < 6; i++)
 		writeb(dev->dev_addr[i], ioaddr + StationAddr + 5-i);
 	for (i = 0; i < 16; i++) {
 		u16 *eaddrs = (u16 *)dev->dev_addr;
-		long setup_frm = ioaddr + 0x56000 + i*16;
+		long setup_frm = ioaddr + PerfFilterTable + i * 16;
 		writew(cpu_to_be16(eaddrs[2]), setup_frm); setup_frm += 4;
 		writew(cpu_to_be16(eaddrs[1]), setup_frm); setup_frm += 4;
 		writew(cpu_to_be16(eaddrs[0]), setup_frm); setup_frm += 8;
@@ -631,116 +930,93 @@
 
 	/* Initialize other registers. */
 	/* Configure the PCI bus bursts and FIFO thresholds. */
-	np->tx_mode = 0;			/* Initialized when TxMode set. */
+	np->tx_mode = 0x0C04;		/* modified when link is up. */
 	np->tx_threshold = 4;
 	writel(np->tx_threshold, ioaddr + TxThreshold);
-	writel(interrupt_mitigation, ioaddr + IntrTimerCtrl);
 
-	if (dev->if_port == 0)
-		dev->if_port = np->default_port;
+	interrupt_mitigation &= 0x1f;
+	np->intr_mitigation = interrupt_mitigation;
+	writel(np->intr_mitigation, ioaddr + IntrTimerCtrl);
 
+	netif_start_if(dev);
 	netif_start_queue(dev);
 
 	if (debug > 1)
-		printk(KERN_DEBUG "%s:  Setting the Rx and Tx modes.\n", dev->name);
+		printk(KERN_DEBUG "%s: Setting the Rx and Tx modes.\n", dev->name);
 	set_rx_mode(dev);
 
-	np->advertising = mdio_read(dev, np->phys[0], 4);
-	check_duplex(dev, 1);
+	np->advertising = mdio_read(dev, np->phys[0], MII_ADVERTISE);
+	check_duplex(dev);
+
+	/* Enable GPIO interrupts on link change */
+	writel(0x0f00ff00, ioaddr + GPIOCtrl);
 
 	/* Set the interrupt mask and enable PCI interrupts. */
-	writel(IntrRxDone | IntrRxEmpty | IntrRxPCIErr |
-		   IntrTxDone | IntrTxEmpty | IntrTxPCIErr |
-		   StatsMax | LinkChange | IntrNormalSummary | IntrAbnormalSummary
-		   | 0x0010 , ioaddr + IntrEnable);
+	writel(IntrRxDone | IntrRxEmpty | IntrDMAErr |
+	       IntrTxDone | IntrStatsMax | IntrLinkChange |
+	       IntrNormalSummary | IntrAbnormalSummary |
+	       IntrRxGFPDead | IntrNoTxCsum | IntrTxBadID,
+	       ioaddr + IntrEnable);
 	writel(0x00800000 | readl(ioaddr + PCIDeviceConfig),
-		   ioaddr + PCIDeviceConfig);
+	       ioaddr + PCIDeviceConfig);
 
-	/* Enable the Rx and Tx units. */
+#ifdef HAS_FIRMWARE
+	/* Load Rx/Tx firmware into the frame processors */
+	for (i = 0; i < FIRMWARE_RX_SIZE * 2; i++)
+		writel(cpu_to_le32(firmware_rx[i]), ioaddr + RxGfpMem + i * 4);
+	for (i = 0; i < FIRMWARE_TX_SIZE * 2; i++)
+		writel(cpu_to_le32(firmware_tx[i]), ioaddr + TxGfpMem + i * 4);
+	/* Enable the Rx and Tx units, and the Rx/Tx frame processors. */
+	writel(0x003F, ioaddr + GenCtrl);
+#else  /* not HAS_FIRMWARE */
+	/* Enable the Rx and Tx units only. */
 	writel(0x000F, ioaddr + GenCtrl);
+#endif /* not HAS_FIRMWARE */
 
 	if (debug > 2)
 		printk(KERN_DEBUG "%s: Done netdev_open().\n",
-			   dev->name);
-
-	/* Set the timer to check for link beat. */
-	init_timer(&np->timer);
-	np->timer.expires = jiffies + 3*HZ;
-	np->timer.data = (unsigned long)dev;
-	np->timer.function = &netdev_timer;				/* timer handler */
-	add_timer(&np->timer);
+		       dev->name);
 
 	return 0;
 }
 
-static void check_duplex(struct net_device *dev, int startup)
+
+static void check_duplex(struct net_device *dev)
 {
 	struct netdev_private *np = dev->priv;
-	long ioaddr = dev->base_addr;
-	int new_tx_mode ;
+	u16 reg0;
 
-	new_tx_mode = 0x0C04 | (np->tx_flowctrl ? 0x0800:0)
-		| (np->rx_flowctrl ? 0x0400:0);
-	if (np->medialock) {
-		if (np->full_duplex)
-			new_tx_mode |= 2;
-	} else {
-		int mii_reg5 = mdio_read(dev, np->phys[0], 5);
-		int negotiated =  mii_reg5 & np->advertising;
-		int duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040;
-		if (duplex)
-			new_tx_mode |= 2;
-		if (np->full_duplex != duplex) {
-			np->full_duplex = duplex;
-			if (debug > 1)
-				printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d"
-					   " negotiated capability %4.4x.\n", dev->name,
-					   duplex ? "full" : "half", np->phys[0], negotiated);
-		}
-	}
-	if (new_tx_mode != np->tx_mode) {
-		np->tx_mode = new_tx_mode;
-		writel(np->tx_mode | 0x8000, ioaddr + TxMode);
-		writel(np->tx_mode, ioaddr + TxMode);
-	}
-}
+	mdio_write(dev, np->phys[0], MII_ADVERTISE, np->advertising);
+	mdio_write(dev, np->phys[0], MII_BMCR, BMCR_RESET);
+	udelay(500);
+	while (mdio_read(dev, np->phys[0], MII_BMCR) & BMCR_RESET);
 
-static void netdev_timer(unsigned long data)
-{
-	struct net_device *dev = (struct net_device *)data;
-	struct netdev_private *np = dev->priv;
-	long ioaddr = dev->base_addr;
-	int next_tick = 60*HZ;		/* Check before driver release. */
+	reg0 = mdio_read(dev, np->phys[0], MII_BMCR);
 
-	if (debug > 3) {
-		printk(KERN_DEBUG "%s: Media selection timer tick, status %8.8x.\n",
-			   dev->name, (int)readl(ioaddr + IntrStatus));
-	}
-	check_duplex(dev, 0);
-#if ! defined(final_version)
-	/* This is often falsely triggered. */
-	if (readl(ioaddr + IntrStatus) & 1) {
-		int new_status = readl(ioaddr + IntrStatus);
-		/* Bogus hardware IRQ: Fake an interrupt handler call. */
-		if (new_status & 1) {
-			printk(KERN_ERR "%s: Interrupt blocked, status %8.8x/%8.8x.\n",
-				   dev->name, new_status, (int)readl(ioaddr + IntrStatus));
-			intr_handler(dev->irq, dev, 0);
-		}
+	if (np->autoneg) {
+		reg0 |= BMCR_ANENABLE | BMCR_ANRESTART;
+	} else {
+		reg0 &= ~(BMCR_ANENABLE | BMCR_ANRESTART);
+		if (np->speed100)
+			reg0 |= BMCR_SPEED100;
+		if (np->full_duplex)
+			reg0 |= BMCR_FULLDPLX;
+		printk(KERN_DEBUG "%s: Link forced to %sMbit %s-duplex\n",
+		       dev->name,
+		       np->speed100 ? "100" : "10",
+		       np->full_duplex ? "full" : "half");
 	}
-#endif
-
-	np->timer.expires = jiffies + next_tick;
-	add_timer(&np->timer);
+	mdio_write(dev, np->phys[0], MII_BMCR, reg0);
 }
 
+
 static void tx_timeout(struct net_device *dev)
 {
 	struct netdev_private *np = dev->priv;
 	long ioaddr = dev->base_addr;
 
 	printk(KERN_WARNING "%s: Transmit timed out, status %8.8x,"
-		   " resetting...\n", dev->name, (int)readl(ioaddr + IntrStatus));
+	       " resetting...\n", dev->name, (int)readl(ioaddr + IntrStatus));
 
 #ifndef __alpha__
 	{
@@ -756,21 +1032,20 @@
 #endif
 
 	/* Perhaps we should reinitialize the hardware here. */
-	dev->if_port = 0;
 	/* Stop and restart the chip's Tx processes . */
 
 	/* Trigger an immediate transmit demand. */
 
 	dev->trans_start = jiffies;
 	np->stats.tx_errors++;
-	return;
+	netif_wake_queue(dev);
 }
 
 
 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
 static void init_ring(struct net_device *dev)
 {
-	struct netdev_private *np = (struct netdev_private *)dev->priv;
+	struct netdev_private *np = dev->priv;
 	int i;
 
 	np->tx_full = 0;
@@ -810,7 +1085,14 @@
 
 	for (i = 0; i < TX_RING_SIZE; i++) {
 		np->tx_info[i].skb = NULL;
-		np->tx_info[i].mapping = 0;
+		np->tx_info[i].first_mapping = 0;
+#ifdef ZEROCOPY
+		{
+			int j;
+			for (j = 0; j < MAX_STARFIRE_FRAGS; j++)
+				np->tx_info[i].frag_mapping[j] = 0;
+		}
+#endif /* ZEROCOPY */
 		np->tx_ring[i].status = 0;
 	}
 	return;
@@ -820,6 +1102,11 @@
 {
 	struct netdev_private *np = dev->priv;
 	unsigned int entry;
+#ifdef ZEROCOPY
+	int i;
+#endif
+
+	kick_tx_timer(dev, tx_timeout, TX_TIMEOUT);
 
 	/* Caution: the write order is important here, set the field
 	   with the "ownership" bits last. */
@@ -827,26 +1114,87 @@
 	/* Calculate the next Tx descriptor entry. */
 	entry = np->cur_tx % TX_RING_SIZE;
 
+#if defined(ZEROCOPY) && defined(HAS_FIRMWARE) && defined(HAS_BROKEN_FIRMWARE)
+	{
+		int has_bad_length = 0;
+
+		if (skb_first_frag_len(skb) == 1)
+			has_bad_length = 1;
+		else {
+			for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
+				if (skb_shinfo(skb)->frags[i].size == 1) {
+					has_bad_length = 1;
+					break;
+				}
+		}
+
+		if (has_bad_length)
+			skb_checksum_help(skb);
+	}
+#endif /* ZEROCOPY && HAS_FIRMWARE && HAS_BROKEN_FIRMWARE */
+
 	np->tx_info[entry].skb = skb;
-	np->tx_info[entry].mapping =
-		pci_map_single(np->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE);
+	np->tx_info[entry].first_mapping =
+		pci_map_single(np->pci_dev, skb->data, skb_first_frag_len(skb), PCI_DMA_TODEVICE);
+
+	np->tx_ring[entry].first_addr = cpu_to_le32(np->tx_info[entry].first_mapping);
+#ifdef ZEROCOPY
+	np->tx_ring[entry].first_len = cpu_to_le32(skb_first_frag_len(skb));
+	np->tx_ring[entry].total_len = cpu_to_le32(skb->len);
+	/* Add "| TxDescIntr" to generate Tx-done interrupts. */
+	np->tx_ring[entry].status = cpu_to_le32(TxDescID | TxCRCEn);
+	np->tx_ring[entry].nbufs = cpu_to_le32(skb_shinfo(skb)->nr_frags + 1);
+#else  /* not ZEROCOPY */
+	/* Add "| TxDescIntr" to generate Tx-done interrupts. */
+	np->tx_ring[entry].status = cpu_to_le32(skb->len | TxDescID | TxCRCEn | 1 << 16);
+#endif /* not ZEROCOPY */
+
+	if (entry >= TX_RING_SIZE-1)		 /* Wrap ring */
+		np->tx_ring[entry].status |= cpu_to_le32(TxRingWrap | TxDescIntr);
+
+#ifdef ZEROCOPY
+	if (skb->ip_summed == CHECKSUM_HW)
+		np->tx_ring[entry].status |= cpu_to_le32(TxCalTCP);
+#endif /* ZEROCOPY */
 
-	np->tx_ring[entry].addr = cpu_to_le32(np->tx_info[entry].mapping);
-	/* Add  "| TxDescIntr" to generate Tx-done interrupts. */
-	np->tx_ring[entry].status = cpu_to_le32(skb->len | TxDescID);
 	if (debug > 5) {
-		printk(KERN_DEBUG "%s: Tx #%d slot %d  %8.8x %8.8x.\n",
-			   dev->name, np->cur_tx, entry,
-			   le32_to_cpu(np->tx_ring[entry].status),
-			   le32_to_cpu(np->tx_ring[entry].addr));
+#ifdef ZEROCOPY
+		printk(KERN_DEBUG "%s: Tx #%d slot %d status %8.8x nbufs %d len %4.4x/%4.4x.\n",
+		       dev->name, np->cur_tx, entry,
+		       le32_to_cpu(np->tx_ring[entry].status),
+		       le32_to_cpu(np->tx_ring[entry].nbufs),
+		       le32_to_cpu(np->tx_ring[entry].first_len),
+		       le32_to_cpu(np->tx_ring[entry].total_len));
+#else  /* not ZEROCOPY */
+		printk(KERN_DEBUG "%s: Tx #%d slot %d status %8.8x.\n",
+		       dev->name, np->cur_tx, entry,
+		       le32_to_cpu(np->tx_ring[entry].status));
+#endif /* not ZEROCOPY */
+	}
+
+#ifdef ZEROCOPY
+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+		skb_frag_t *this_frag = &skb_shinfo(skb)->frags[i];
+
+		/* we already have the proper value in entry */
+		np->tx_info[entry].frag_mapping[i] =
+			pci_map_single(np->pci_dev, page_address(this_frag->page) + this_frag->page_offset, this_frag->size, PCI_DMA_TODEVICE);
+
+		np->tx_ring[entry].frag[i].addr = cpu_to_le32(np->tx_info[entry].frag_mapping[i]);
+		np->tx_ring[entry].frag[i].len = cpu_to_le32(this_frag->size);
+		if (debug > 5) {
+			printk(KERN_DEBUG "%s: Tx #%d frag %d len %4.4x.\n",
+			       dev->name, np->cur_tx, i,
+			       le32_to_cpu(np->tx_ring[entry].frag[i].len));
+		}
 	}
+#endif /* ZEROCOPY */
+
 	np->cur_tx++;
-#if 1
-	if (entry >= TX_RING_SIZE-1) {		 /* Wrap ring */
-		np->tx_ring[entry].status |= cpu_to_le32(TxRingWrap | TxDescIntr);
+
+	if (entry >= TX_RING_SIZE-1)		 /* Wrap ring */
 		entry = -1;
-	}
-#endif
+	entry++;
 
 	/* Non-x86: explicitly flush descriptor cache lines here. */
 	/* Ensure everything is written back above before the transmit is
@@ -854,18 +1202,15 @@
 	wmb();
 
 	/* Update the producer index. */
-	writel(++entry, dev->base_addr + TxProducerIdx);
+	writel(entry * (sizeof(struct starfire_tx_desc) / 8), dev->base_addr + TxProducerIdx);
 
 	if (np->cur_tx - np->dirty_tx >= TX_RING_SIZE - 1) {
 		np->tx_full = 1;
 		netif_stop_queue(dev);
 	}
+
 	dev->trans_start = jiffies;
 
-	if (debug > 4) {
-		printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n",
-			   dev->name, np->cur_tx, entry);
-	}
 	return 0;
 }
 
@@ -877,24 +1222,25 @@
 	struct netdev_private *np;
 	long ioaddr;
 	int boguscnt = max_interrupt_work;
+	int consumer;
+	int tx_status;
 
 #ifndef final_version			/* Can never occur. */
 	if (dev == NULL) {
-		printk (KERN_ERR "Netdev interrupt handler(): IRQ %d for unknown "
-				"device.\n", irq);
+		printk (KERN_ERR "Netdev interrupt handler(): IRQ %d for unknown device.\n", irq);
 		return;
 	}
 #endif
 
 	ioaddr = dev->base_addr;
-	np = (struct netdev_private *)dev->priv;
+	np = dev->priv;
 
 	do {
 		u32 intr_status = readl(ioaddr + IntrClear);
 
 		if (debug > 4)
 			printk(KERN_DEBUG "%s: Interrupt status %4.4x.\n",
-				   dev->name, intr_status);
+			       dev->name, intr_status);
 
 		if (intr_status == 0)
 			break;
@@ -905,77 +1251,99 @@
 		/* Scavenge the skbuff list based on the Tx-done queue.
 		   There are redundant checks here that may be cleaned up
 		   after the driver has proven to be reliable. */
-		{
-			int consumer = readl(ioaddr + TxConsumerIdx);
-			int tx_status;
-			if (debug > 4)
-				printk(KERN_DEBUG "%s: Tx Consumer index is %d.\n",
-					   dev->name, consumer);
+		consumer = readl(ioaddr + TxConsumerIdx);
+		if (debug > 4)
+			printk(KERN_DEBUG "%s: Tx Consumer index is %d.\n",
+			       dev->name, consumer);
 #if 0
-			if (np->tx_done >= 250  || np->tx_done == 0)
-				printk(KERN_DEBUG "%s: Tx completion entry %d is %8.8x, "
-					   "%d is %8.8x.\n", dev->name,
-					   np->tx_done, le32_to_cpu(np->tx_done_q[np->tx_done].status),
-					   (np->tx_done+1) & (DONE_Q_SIZE-1),
-					   le32_to_cpu(np->tx_done_q[(np->tx_done+1)&(DONE_Q_SIZE-1)].status));
+		if (np->tx_done >= 250 || np->tx_done == 0)
+			printk(KERN_DEBUG "%s: Tx completion entry %d is %8.8x, %d is %8.8x.\n",
+			       dev->name, np->tx_done,
+			       le32_to_cpu(np->tx_done_q[np->tx_done].status),
+			       (np->tx_done+1) & (DONE_Q_SIZE-1),
+			       le32_to_cpu(np->tx_done_q[(np->tx_done+1)&(DONE_Q_SIZE-1)].status));
 #endif
-			while ((tx_status = le32_to_cpu(np->tx_done_q[np->tx_done].status))
-				   != 0) {
-				if (debug > 4)
-					printk(KERN_DEBUG "%s: Tx completion entry %d is %8.8x.\n",
-						   dev->name, np->tx_done, tx_status);
-				if ((tx_status & 0xe0000000) == 0xa0000000) {
-					np->stats.tx_packets++;
-				} else if ((tx_status & 0xe0000000) == 0x80000000) {
-					struct sk_buff *skb;
-					u16 entry = tx_status; 		/* Implicit truncate */
-					entry >>= 3;
 
-					skb = np->tx_info[entry].skb;
-					pci_unmap_single(np->pci_dev,
-							 np->tx_info[entry].mapping,
-							 skb->len, PCI_DMA_TODEVICE);
+		while ((tx_status = le32_to_cpu(np->tx_done_q[np->tx_done].status)) != 0) {
+			if (debug > 4)
+				printk(KERN_DEBUG "%s: Tx completion entry %d is %8.8x.\n",
+				       dev->name, np->tx_done, tx_status);
+			if ((tx_status & 0xe0000000) == 0xa0000000) {
+				np->stats.tx_packets++;
+			} else if ((tx_status & 0xe0000000) == 0x80000000) {
+				struct sk_buff *skb;
+#ifdef ZEROCOPY
+				int i;
+#endif /* ZEROCOPY */
+				u16 entry = tx_status;		/* Implicit truncate */
+				entry /= sizeof(struct starfire_tx_desc);
+
+				skb = np->tx_info[entry].skb;
+				np->tx_info[entry].skb = NULL;
+				pci_unmap_single(np->pci_dev,
+						 np->tx_info[entry].first_mapping,
+						 skb_first_frag_len(skb),
+						 PCI_DMA_TODEVICE);
+				np->tx_info[entry].first_mapping = 0;
 
-					/* Scavenge the descriptor. */
-					dev_kfree_skb_irq(skb);
-					np->tx_info[entry].skb = NULL;
-					np->tx_info[entry].mapping = 0;
-					np->dirty_tx++;
+#ifdef ZEROCOPY
+				for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+					pci_unmap_single(np->pci_dev,
+							 np->tx_info[entry].frag_mapping[i],
+							 skb_shinfo(skb)->frags[i].size,
+							 PCI_DMA_TODEVICE);
+					np->tx_info[entry].frag_mapping[i] = 0;
 				}
-				np->tx_done_q[np->tx_done].status = 0;
-				np->tx_done = (np->tx_done+1) & (DONE_Q_SIZE-1);
+#endif /* ZEROCOPY */
+
+				/* Scavenge the descriptor. */
+				dev_kfree_skb_irq(skb);
+
+				np->dirty_tx++;
 			}
-			writew(np->tx_done, ioaddr + CompletionQConsumerIdx + 2);
+			np->tx_done_q[np->tx_done].status = 0;
+			np->tx_done = (np->tx_done+1) & (DONE_Q_SIZE-1);
 		}
+		writew(np->tx_done, ioaddr + CompletionQConsumerIdx + 2);
+
 		if (np->tx_full && np->cur_tx - np->dirty_tx < TX_RING_SIZE - 4) {
 			/* The ring is no longer full, wake the queue. */
 			np->tx_full = 0;
 			netif_wake_queue(dev);
 		}
 
+		/* Stats overflow */
+		if (intr_status & IntrStatsMax) {
+			get_stats(dev);
+		}
+
+		/* Media change interrupt. */
+		if (intr_status & IntrLinkChange)
+			netdev_media_change(dev);
+
 		/* Abnormal error summary/uncommon events handlers. */
 		if (intr_status & IntrAbnormalSummary)
 			netdev_error(dev, intr_status);
 
 		if (--boguscnt < 0) {
 			printk(KERN_WARNING "%s: Too much work at interrupt, "
-				   "status=0x%4.4x.\n",
-				   dev->name, intr_status);
+			       "status=0x%4.4x.\n",
+			       dev->name, intr_status);
 			break;
 		}
 	} while (1);
 
 	if (debug > 4)
 		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
-			   dev->name, (int)readl(ioaddr + IntrStatus));
+		       dev->name, (int)readl(ioaddr + IntrStatus));
 
 #ifndef final_version
 	/* Code that should never be run!  Remove after testing.. */
 	{
 		static int stopit = 10;
-		if (!netif_running(dev)  &&  --stopit < 0) {
+		if (!netif_running(dev) && --stopit < 0) {
 			printk(KERN_ERR "%s: Emergency stop, looping startup interrupt.\n",
-				   dev->name);
+			       dev->name);
 			free_irq(irq, dev);
 		}
 	}
@@ -992,83 +1360,99 @@
 
 	if (np->rx_done_q == 0) {
 		printk(KERN_ERR "%s:  rx_done_q is NULL!  rx_done is %d. %p.\n",
-			   dev->name, np->rx_done, np->tx_done_q);
+		       dev->name, np->rx_done, np->tx_done_q);
 		return 0;
 	}
 
 	/* If EOP is set on the next entry, it's a new packet. Send it up. */
 	while ((desc_status = le32_to_cpu(np->rx_done_q[np->rx_done].status)) != 0) {
+		struct sk_buff *skb;
+		u16 pkt_len;
+		int entry;
+
 		if (debug > 4)
-			printk(KERN_DEBUG "  netdev_rx() status of %d was %8.8x.\n",
-				   np->rx_done, desc_status);
+			printk(KERN_DEBUG "  netdev_rx() status of %d was %8.8x.\n", np->rx_done, desc_status);
 		if (--boguscnt < 0)
 			break;
 		if ( ! (desc_status & RxOK)) {
 			/* There was a error. */
 			if (debug > 2)
-				printk(KERN_DEBUG "  netdev_rx() Rx error was %8.8x.\n",
-					   desc_status);
+				printk(KERN_DEBUG "  netdev_rx() Rx error was %8.8x.\n", desc_status);
 			np->stats.rx_errors++;
 			if (desc_status & RxFIFOErr)
 				np->stats.rx_fifo_errors++;
-		} else {
-			struct sk_buff *skb;
-			u16 pkt_len = desc_status;			/* Implicitly Truncate */
-			int entry = (desc_status >> 16) & 0x7ff;
+			goto next_rx;
+		}
+
+		pkt_len = desc_status;	/* Implicitly Truncate */
+		entry = (desc_status >> 16) & 0x7ff;
 
 #ifndef final_version
-			if (debug > 4)
-				printk(KERN_DEBUG "  netdev_rx() normal Rx pkt length %d"
-					   ", bogus_cnt %d.\n",
-					   pkt_len, boguscnt);
+		if (debug > 4)
+			printk(KERN_DEBUG "  netdev_rx() normal Rx pkt length %d, bogus_cnt %d.\n", pkt_len, boguscnt);
 #endif
-			/* Check if the packet is long enough to accept without copying
-			   to a minimally-sized skbuff. */
-			if (PKT_SHOULD_COPY(pkt_len)
-				&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
-				skb->dev = dev;
-				skb_reserve(skb, 2);	/* 16 byte align the IP header */
-				pci_dma_sync_single(np->pci_dev,
-						    np->rx_info[entry].mapping,
-						    pkt_len, PCI_DMA_FROMDEVICE);
+		/* Check if the packet is long enough to accept without copying
+		   to a minimally-sized skbuff. */
+		if (pkt_len < rx_copybreak
+		    && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+			skb->dev = dev;
+			skb_reserve(skb, 2);	/* 16 byte align the IP header */
+			pci_dma_sync_single(np->pci_dev,
+					    np->rx_info[entry].mapping,
+					    pkt_len, PCI_DMA_FROMDEVICE);
 #if HAS_IP_COPYSUM			/* Call copy + cksum if available. */
-				eth_copy_and_sum(skb, np->rx_info[entry].skb->tail, pkt_len, 0);
-				skb_put(skb, pkt_len);
+			eth_copy_and_sum(skb, np->rx_info[entry].skb->tail, pkt_len, 0);
+			skb_put(skb, pkt_len);
 #else
-				memcpy(skb_put(skb, pkt_len), np->rx_info[entry].skb->tail,
-					   pkt_len);
+			memcpy(skb_put(skb, pkt_len), np->rx_info[entry].skb->tail, pkt_len);
 #endif
-			} else {
-				char *temp;
+		} else {
+			char *temp;
 
-				pci_unmap_single(np->pci_dev, np->rx_info[entry].mapping, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
-				skb = np->rx_info[entry].skb;
-				temp = skb_put(skb, pkt_len);
-				np->rx_info[entry].skb = NULL;
-				np->rx_info[entry].mapping = 0;
-			}
-#ifndef final_version				/* Remove after testing. */
-			/* You will want this info for the initial debug. */
-			if (debug > 5)
-				printk(KERN_DEBUG "  Rx data %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:"
-					   "%2.2x %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x %2.2x%2.2x "
-					   "%d.%d.%d.%d.\n",
-					   skb->data[0], skb->data[1], skb->data[2], skb->data[3],
-					   skb->data[4], skb->data[5], skb->data[6], skb->data[7],
-					   skb->data[8], skb->data[9], skb->data[10],
-					   skb->data[11], skb->data[12], skb->data[13],
-					   skb->data[14], skb->data[15], skb->data[16],
-					   skb->data[17]);
-#endif
-			skb->protocol = eth_type_trans(skb, dev);
-#ifdef full_rx_status
-			if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x01000000)
-				skb->ip_summed = CHECKSUM_UNNECESSARY;
+			pci_unmap_single(np->pci_dev, np->rx_info[entry].mapping, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
+			skb = np->rx_info[entry].skb;
+			temp = skb_put(skb, pkt_len);
+			np->rx_info[entry].skb = NULL;
+			np->rx_info[entry].mapping = 0;
+		}
+#ifndef final_version			/* Remove after testing. */
+		/* You will want this info for the initial debug. */
+		if (debug > 5)
+			printk(KERN_DEBUG "  Rx data %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:"
+			       "%2.2x %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x %2.2x%2.2x "
+			       "%d.%d.%d.%d.\n",
+			       skb->data[0], skb->data[1], skb->data[2], skb->data[3],
+			       skb->data[4], skb->data[5], skb->data[6], skb->data[7],
+			       skb->data[8], skb->data[9], skb->data[10],
+			       skb->data[11], skb->data[12], skb->data[13],
+			       skb->data[14], skb->data[15], skb->data[16],
+			       skb->data[17]);
 #endif
-			netif_rx(skb);
-			dev->last_rx = jiffies;
-			np->stats.rx_packets++;
+		skb->protocol = eth_type_trans(skb, dev);
+#if defined(full_rx_status) || defined(csum_rx_status)
+		if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x01000000) {
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+		}
+		/*
+		 * This feature doesn't seem to be working, at least
+		 * with the two firmware versions I have. If the GFP sees
+		 * a fragment, it either ignores it completely, or reports
+		 * "bad checksum" on it.
+		 *
+		 * Maybe I missed something -- corrections are welcome.
+		 * Until then, the printk stays. :-) -Ion
+		 */
+		else if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x00400000) {
+			skb->ip_summed = CHECKSUM_HW;
+			skb->csum = le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0xffff;
+			printk(KERN_DEBUG "%s: checksum_hw, status2 = %x\n", dev->name, np->rx_done_q[np->rx_done].status2);
 		}
+#endif
+		netif_rx(skb);
+		dev->last_rx = jiffies;
+		np->stats.rx_packets++;
+
+next_rx:
 		np->cur_rx++;
 		np->rx_done_q[np->rx_done].status = 0;
 		np->rx_done = (np->rx_done + 1) & (DONE_Q_SIZE-1);
@@ -1083,10 +1467,10 @@
 			skb = dev_alloc_skb(np->rx_buf_sz);
 			np->rx_info[entry].skb = skb;
 			if (skb == NULL)
-				break;			/* Better luck next round. */
+				break;	/* Better luck next round. */
 			np->rx_info[entry].mapping =
 				pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
-			skb->dev = dev;			/* Mark as being used by this device. */
+			skb->dev = dev;	/* Mark as being used by this device. */
 			np->rx_ring[entry].rxaddr =
 				cpu_to_le32(np->rx_info[entry].mapping | RxDescValid);
 		}
@@ -1096,42 +1480,94 @@
 		writew(entry, dev->base_addr + RxDescQIdx);
 	}
 
-	if (debug > 5
-		|| memcmp(np->pad0, np->pad0 + 1, sizeof(np->pad0) -1))
-		printk(KERN_DEBUG "  exiting netdev_rx() status of %d was %8.8x %d.\n",
-			   np->rx_done, desc_status,
-			   memcmp(np->pad0, np->pad0 + 1, sizeof(np->pad0) -1));
+	if (debug > 5)
+		printk(KERN_DEBUG "  exiting netdev_rx() status of %d was %8.8x.\n",
+		       np->rx_done, desc_status);
 
 	/* Restart Rx engine if stopped. */
 	return 0;
 }
 
-static void netdev_error(struct net_device *dev, int intr_status)
+
+static void netdev_media_change(struct net_device *dev)
 {
 	struct netdev_private *np = dev->priv;
+	long ioaddr = dev->base_addr;
+	u16 reg0, reg1, reg4, reg5;
+	u32 new_tx_mode;
 
-	if (intr_status & LinkChange) {
-		printk(KERN_NOTICE "%s: Link changed: Autonegotiation advertising"
-			   " %4.4x  partner %4.4x.\n", dev->name,
-			   mdio_read(dev, np->phys[0], 4),
-			   mdio_read(dev, np->phys[0], 5));
-		check_duplex(dev, 0);
-	}
-	if (intr_status & StatsMax) {
-		get_stats(dev);
+	/* reset status first */
+	mdio_read(dev, np->phys[0], MII_BMCR);
+	mdio_read(dev, np->phys[0], MII_BMSR);
+
+	reg0 = mdio_read(dev, np->phys[0], MII_BMCR);
+	reg1 = mdio_read(dev, np->phys[0], MII_BMSR);
+
+	if (reg1 & BMSR_LSTATUS) {
+		/* link is up */
+		if (reg0 & BMCR_ANENABLE) {
+			/* autonegotiation is enabled */
+			reg4 = mdio_read(dev, np->phys[0], MII_ADVERTISE);
+			reg5 = mdio_read(dev, np->phys[0], MII_LPA);
+			if (reg4 & ADVERTISE_100FULL && reg5 & LPA_100FULL) {
+				np->speed100 = 1;
+				np->full_duplex = 1;
+			} else if (reg4 & ADVERTISE_100HALF && reg5 & LPA_100HALF) {
+				np->speed100 = 1;
+				np->full_duplex = 0;
+			} else if (reg4 & ADVERTISE_10FULL && reg5 & LPA_10FULL) {
+				np->speed100 = 0;
+				np->full_duplex = 1;
+			} else {
+				np->speed100 = 0;
+				np->full_duplex = 0;
+			}
+		} else {
+			/* autonegotiation is disabled */
+			if (reg0 & BMCR_SPEED100)
+				np->speed100 = 1;
+			else
+				np->speed100 = 0;
+			if (reg0 & BMCR_FULLDPLX)
+				np->full_duplex = 1;
+			else
+				np->full_duplex = 0;
+		}
+		printk(KERN_DEBUG "%s: Link is up, running at %sMbit %s-duplex\n",
+		       dev->name,
+		       np->speed100 ? "100" : "10",
+		       np->full_duplex ? "full" : "half");
+
+		new_tx_mode = np->tx_mode & ~0x2;	/* duplex setting */
+		if (np->full_duplex)
+			new_tx_mode |= 2;
+		if (np->tx_mode != new_tx_mode) {
+			np->tx_mode = new_tx_mode;
+			writel(np->tx_mode | 0x8000, ioaddr + TxMode);
+			writel(np->tx_mode, ioaddr + TxMode);
+		}
+	} else {
+		printk(KERN_DEBUG "%s: Link is down\n", dev->name);
 	}
+}
+
+
+static void netdev_error(struct net_device *dev, int intr_status)
+{
+	struct netdev_private *np = dev->priv;
+
 	/* Came close to underrunning the Tx FIFO, increase threshold. */
-	if (intr_status & IntrTxDataLow)
+	if (intr_status & IntrTxDataLow) {
 		writel(++np->tx_threshold, dev->base_addr + TxThreshold);
-	if ((intr_status &
-		 ~(IntrAbnormalSummary|LinkChange|StatsMax|IntrTxDataLow|1)) && debug)
+		printk(KERN_NOTICE "%s: Increasing Tx FIFO threshold to %d bytes\n",
+		       dev->name, np->tx_threshold * 16);
+	}
+	if ((intr_status & ~(IntrNormalMask | IntrAbnormalSummary | IntrLinkChange | IntrStatsMax | IntrTxDataLow | IntrPCIPad)) && debug)
 		printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n",
-			   dev->name, intr_status);
-	/* Hmmmmm, it's not clear how to recover from PCI faults. */
-	if (intr_status & IntrTxPCIErr)
+		       dev->name, intr_status);
+	/* Hmmmmm, it's not clear how to recover from DMA faults. */
+	if (intr_status & IntrDMAErr)
 		np->stats.tx_fifo_errors++;
-	if (intr_status & IntrRxPCIErr)
-		np->stats.rx_fifo_errors++;
 }
 
 static struct net_device_stats *get_stats(struct net_device *dev)
@@ -1146,12 +1582,13 @@
 	np->stats.tx_aborted_errors =
 		readl(ioaddr + 0x57024) + readl(ioaddr + 0x57028);
 	np->stats.tx_window_errors = readl(ioaddr + 0x57018);
-	np->stats.collisions = readl(ioaddr + 0x57004) + readl(ioaddr + 0x57008);
+	np->stats.collisions =
+		readl(ioaddr + 0x57004) + readl(ioaddr + 0x57008);
 
 	/* The chip only need report frame silently dropped. */
-	np->stats.rx_dropped	   += readw(ioaddr + RxDMAStatus);
+	np->stats.rx_dropped += readw(ioaddr + RxDMAStatus);
 	writew(0, ioaddr + RxDMAStatus);
-	np->stats.rx_crc_errors	   = readl(ioaddr + 0x5703C);
+	np->stats.rx_crc_errors = readl(ioaddr + 0x5703C);
 	np->stats.rx_frame_errors = readl(ioaddr + 0x57040);
 	np->stats.rx_length_errors = readl(ioaddr + 0x57058);
 	np->stats.rx_missed_errors = readl(ioaddr + 0x5707C);
@@ -1192,19 +1629,17 @@
 	struct dev_mc_list *mclist;
 	int i;
 
-	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
-		/* Unconditionally log net taps. */
-		printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
+	if (dev->flags & IFF_PROMISC) {	/* Set promiscuous. */
 		rx_mode = AcceptBroadcast|AcceptAllMulticast|AcceptAll|AcceptMyPhys;
 	} else if ((dev->mc_count > multicast_filter_limit)
-			   ||  (dev->flags & IFF_ALLMULTI)) {
+		   || (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to match, or accept all multicasts. */
 		rx_mode = AcceptBroadcast|AcceptAllMulticast|AcceptMyPhys;
 	} else if (dev->mc_count <= 15) {
-		/* Use the 16 element perfect filter. */
-		long filter_addr = ioaddr + 0x56000 + 1*16;
-		for (i = 1, mclist = dev->mc_list; mclist  &&  i <= dev->mc_count;
-			 i++, mclist = mclist->next) {
+		/* Use the 16 element perfect filter, skip first entry. */
+		long filter_addr = ioaddr + PerfFilterTable + 1 * 16;
+		for (i = 1, mclist = dev->mc_list; mclist && i <= dev->mc_count;
+		     i++, mclist = mclist->next) {
 			u16 *eaddrs = (u16 *)mclist->dmi_addr;
 			writew(cpu_to_be16(eaddrs[2]), filter_addr); filter_addr += 4;
 			writew(cpu_to_be16(eaddrs[1]), filter_addr); filter_addr += 4;
@@ -1224,7 +1659,10 @@
 		memset(mc_filter, 0, sizeof(mc_filter));
 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
 			 i++, mclist = mclist->next) {
-			set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 23, mc_filter);
+			int bit_nr = ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 23;
+			__u32 *fptr = (__u32 *) &mc_filter[(bit_nr >> 4) & ~1];
+
+			*fptr |= cpu_to_le32(1 << (bit_nr & 31));
 		}
 		/* Clear the perfect filter list. */
 		filter_addr = ioaddr + 0x56000 + 1*16;
@@ -1260,15 +1698,17 @@
 			switch (data[1]) {
 			case 0:
 				if (value & 0x9000)	/* Autonegotiation. */
-					np->medialock = 0;
+					np->autoneg = 1;
 				else {
 					np->full_duplex = (value & 0x0100) ? 1 : 0;
-					np->medialock = 1;
+					np->autoneg = 0;
 				}
 				break;
-			case 4: np->advertising = value; break;
+			case 4:
+				np->advertising = value;
+				break;
 			}
-			check_duplex(dev, 0);
+			check_duplex(dev);
 		}
 		mdio_write(dev, data[0] & 0x1f, data[1] & 0x1f, data[2]);
 		return 0;
@@ -1284,8 +1724,7 @@
 	int i;
 
 	netif_stop_queue(dev);
-
-	del_timer_sync(&np->timer);
+	netif_stop_if(dev);
 
 	if (debug > 1) {
 		printk(KERN_DEBUG "%s: Shutting down ethercard, Intr status %4.4x.\n",
@@ -1305,15 +1744,15 @@
 			   np->tx_ring_dma);
 		for (i = 0; i < 8 /* TX_RING_SIZE is huge! */; i++)
 			printk(KERN_DEBUG " #%d desc. %8.8x %8.8x -> %8.8x.\n",
-				   i, le32_to_cpu(np->tx_ring[i].status),
-				   le32_to_cpu(np->tx_ring[i].addr),
-				   le32_to_cpu(np->tx_done_q[i].status));
+			       i, le32_to_cpu(np->tx_ring[i].status),
+			       le32_to_cpu(np->tx_ring[i].first_addr),
+			       le32_to_cpu(np->tx_done_q[i].status));
 		printk(KERN_DEBUG "  Rx ring at %8.8x -> %p:\n",
-			   np->rx_ring_dma, np->rx_done_q);
+		       np->rx_ring_dma, np->rx_done_q);
 		if (np->rx_done_q)
 			for (i = 0; i < 8 /* RX_RING_SIZE */; i++) {
 				printk(KERN_DEBUG " #%d desc. %8.8x -> %8.8x\n",
-					   i, le32_to_cpu(np->rx_ring[i].rxaddr), le32_to_cpu(np->rx_done_q[i].status));
+				       i, le32_to_cpu(np->rx_ring[i].rxaddr), le32_to_cpu(np->rx_done_q[i].status));
 		}
 	}
 #endif /* __i386__ debugging only */
@@ -1332,16 +1771,32 @@
 	}
 	for (i = 0; i < TX_RING_SIZE; i++) {
 		struct sk_buff *skb = np->tx_info[i].skb;
-		if (skb != NULL) {
-			pci_unmap_single(np->pci_dev,
-					 np->tx_info[i].mapping,
-					 skb->len, PCI_DMA_TODEVICE);
-			dev_kfree_skb(skb);
-		}
+#ifdef ZEROCOPY
+		int j;
+#endif /* ZEROCOPY */
+		if (skb == NULL)
+			continue;
+		pci_unmap_single(np->pci_dev,
+				 np->tx_info[i].first_mapping,
+				 skb_first_frag_len(skb), PCI_DMA_TODEVICE);
+		np->tx_info[i].first_mapping = 0;
+		dev_kfree_skb(skb);
 		np->tx_info[i].skb = NULL;
-		np->tx_info[i].mapping = 0;
+#ifdef ZEROCOPY
+		for (j = 0; j < MAX_STARFIRE_FRAGS; j++)
+			if (np->tx_info[i].frag_mapping[j]) {
+				pci_unmap_single(np->pci_dev,
+						 np->tx_info[i].frag_mapping[j],
+						 skb_shinfo(skb)->frags[j].size,
+						 PCI_DMA_TODEVICE);
+				np->tx_info[i].frag_mapping[j] = 0;
+			} else
+				break;
+#endif /* ZEROCOPY */
 	}
 
+	COMPAT_MOD_DEC_USE_COUNT;
+
 	return 0;
 }
 
@@ -1350,7 +1805,7 @@
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct netdev_private *np;
-	
+
 	if (!dev)
 		BUG();
 
@@ -1358,7 +1813,7 @@
 
 	unregister_netdev(dev);
 	iounmap((char *)dev->base_addr);
-	pci_release_regions (pdev);
+	pci_release_regions(pdev);
 
 	if (np->tx_done_q)
 		pci_free_consistent(np->pci_dev, PAGE_SIZE,
@@ -1380,7 +1835,7 @@
 
 
 static struct pci_driver starfire_driver = {
-	name:		"starfire",
+	name:		DRV_NAME,
 	probe:		starfire_init_one,
 	remove:		starfire_remove_one,
 	id_table:	starfire_pci_tbl,
@@ -1409,10 +1864,9 @@
 
 /*
  * Local variables:
- *  compile-command: "gcc -DMODULE -Wall -Wstrict-prototypes -O6 -c starfire.c"
- *  simple-compile-command: "gcc -DMODULE -O6 -c starfire.c"
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 4
+ *  compile-command: "gcc -DMODULE -Wall -Wstrict-prototypes -O2 -c starfire.c"
+ *  simple-compile-command: "gcc -DMODULE -O2 -c starfire.c"
+ *  c-basic-offset: 8
+ *  tab-width: 8
  * End:
  */
diff -u --recursive --new-file v2.4.5/linux/drivers/net/sun3lance.c linux/drivers/net/sun3lance.c
--- v2.4.5/linux/drivers/net/sun3lance.c	Wed Apr 18 14:40:04 2001
+++ linux/drivers/net/sun3lance.c	Wed Jun 20 11:10:53 2001
@@ -70,6 +70,7 @@
 static int lance_debug = 1;
 #endif
 MODULE_PARM(lance_debug, "i");
+MODULE_PARM_DESC(lance_debug, "SUN3 Lance debug level (0-3)");
 
 #define	DPRINTK(n,a) \
 	do {  \
diff -u --recursive --new-file v2.4.5/linux/drivers/net/sundance.c linux/drivers/net/sundance.c
--- v2.4.5/linux/drivers/net/sundance.c	Fri Apr 20 11:54:22 2001
+++ linux/drivers/net/sundance.c	Thu Jun 21 14:28:39 2001
@@ -18,6 +18,11 @@
 	http://www.scyld.com/network/sundance.html
 */
 
+#define DRV_NAME	"sundance"
+#define DRV_VERSION	"1.01"
+#define DRV_RELDATE	"4/09/00"
+
+
 /* The user-configurable values.
    These may be modified when a driver module is loaded.*/
 
@@ -85,6 +90,8 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
+#include <linux/ethtool.h>
+#include <asm/uaccess.h>
 #include <asm/processor.h>		/* Processor type for cache alignment. */
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -93,7 +100,7 @@
 
 /* These identify the driver base version and may not be removed. */
 static char version[] __devinitdata =
-KERN_INFO "sundance.c:v1.01 4/09/00  Written by Donald Becker\n"
+KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE "  Written by Donald Becker\n"
 KERN_INFO "  http://www.scyld.com/network/sundance.html\n";
 
 /* Condensed operations for readability. */
@@ -109,6 +116,12 @@
 MODULE_PARM(rx_copybreak, "i");
 MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM_DESC(max_interrupt_work, "Sundance Alta maximum events handled per interrupt");
+MODULE_PARM_DESC(mtu, "Sundance Alta MTU (all boards)");
+MODULE_PARM_DESC(debug, "Sundance Alta debug level (0-5)");
+MODULE_PARM_DESC(rx_copybreak, "Sundance Alta copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(options, "Sundance Alta: Bits 0-3: media type, bit 17: full duplex");
+MODULE_PARM_DESC(full_duplex, "Sundance Alta full duplex setting(s) (1)");
 
 /*
 				Theory of Operation
@@ -346,6 +359,7 @@
 	int mii_cnt;						/* MII device addresses. */
 	u16 advertising;					/* NWay media advertisement */
 	unsigned char phys[MII_CNT];		/* MII device addresses, only first one used. */
+	struct pci_dev *pci_dev;
 };
 
 /* The station address location in the EEPROM. */
@@ -366,7 +380,7 @@
 static void netdev_error(struct net_device *dev, int intr_status);
 static void set_rx_mode(struct net_device *dev);
 static struct net_device_stats *get_stats(struct net_device *dev);
-static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static int  netdev_close(struct net_device *dev);
 
 
@@ -400,7 +414,7 @@
 		return -ENOMEM;
 	SET_MODULE_OWNER(dev);
 
-	if (pci_request_regions(pdev, "sundance"))
+	if (pci_request_regions(pdev, DRV_NAME))
 		goto err_out_netdev;
 
 #ifdef USE_IO_OPS
@@ -422,6 +436,7 @@
 	np = dev->priv;
 	np->chip_id = chip_idx;
 	np->drv_flags = pci_id_tbl[chip_idx].drv_flags;
+	np->pci_dev = pdev;
 	spin_lock_init(&np->lock);
 
 	if (dev->mem_start)
@@ -447,7 +462,7 @@
 	dev->stop = &netdev_close;
 	dev->get_stats = &get_stats;
 	dev->set_multicast_list = &set_rx_mode;
-	dev->do_ioctl = &mii_ioctl;
+	dev->do_ioctl = &netdev_ioctl;
 	dev->tx_timeout = &tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
 	pci_set_drvdata(pdev, dev);
@@ -725,18 +740,16 @@
 	printk(KERN_WARNING "%s: Transmit timed out, status %2.2x,"
 		   " resetting...\n", dev->name, readb(ioaddr + TxStatus));
 
-#ifndef __alpha__
 	{
 		int i;
-		printk(KERN_DEBUG "  Rx ring %8.8x: ", (int)np->rx_ring);
+		printk(KERN_DEBUG "  Rx ring %p: ", np->rx_ring);
 		for (i = 0; i < RX_RING_SIZE; i++)
 			printk(" %8.8x", (unsigned int)np->rx_ring[i].status);
-		printk("\n"KERN_DEBUG"  Tx ring %8.8x: ", (int)np->tx_ring);
+		printk("\n"KERN_DEBUG"  Tx ring %p: ", np->tx_ring);
 		for (i = 0; i < TX_RING_SIZE; i++)
 			printk(" %4.4x", np->tx_ring[i].status);
 		printk("\n");
 	}
-#endif
 
 	/* Perhaps we should reinitialize the hardware here. */
 	dev->if_port = 0;
@@ -1156,11 +1169,37 @@
 	writeb(rx_mode, ioaddr + RxMode);
 }
 
-static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+{
+	struct netdev_private *np = dev->priv;
+	u32 ethcmd;
+		
+	if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
+		return -EFAULT;
+
+        switch (ethcmd) {
+        case ETHTOOL_GDRVINFO: {
+		struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
+		strcpy(info.driver, DRV_NAME);
+		strcpy(info.version, DRV_VERSION);
+		strcpy(info.bus_info, np->pci_dev->slot_name);
+		if (copy_to_user(useraddr, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+
+        }
+	
+	return -EOPNOTSUPP;
+}
+
+static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	u16 *data = (u16 *)&rq->ifr_data;
 
 	switch(cmd) {
+	case SIOCETHTOOL:
+		return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
 	case SIOCDEVPRIVATE:		/* Get the address of the PHY in use. */
 		data[0] = ((struct netdev_private *)dev->priv)->phys[0] & 0x1f;
 		/* Fall Through */
@@ -1258,7 +1297,7 @@
 }
 
 static struct pci_driver sundance_driver = {
-	name:		"sundance",
+	name:		DRV_NAME,
 	id_table:	sundance_pci_tbl,
 	probe:		sundance_probe1,
 	remove:		sundance_remove1,
diff -u --recursive --new-file v2.4.5/linux/drivers/net/sungem.c linux/drivers/net/sungem.c
--- v2.4.5/linux/drivers/net/sungem.c	Thu Apr 26 22:17:25 2001
+++ linux/drivers/net/sungem.c	Wed Jun 20 21:00:55 2001
@@ -1,4 +1,4 @@
-/* $Id: sungem.c,v 1.13 2001/04/20 08:16:28 davem Exp $
+/* $Id: sungem.c,v 1.17 2001/06/17 09:22:46 jgarzik Exp $
  * sungem.c: Sun GEM ethernet driver.
  *
  * Copyright (C) 2000, 2001 David S. Miller (davem@redhat.com)
@@ -49,6 +49,7 @@
 MODULE_AUTHOR("David S. Miller (davem@redhat.com)");
 MODULE_DESCRIPTION("Sun GEM Gbit ethernet driver");
 MODULE_PARM(gem_debug, "i");
+MODULE_PARM_DESC(gem_debug, "(ignored)");
 
 #define GEM_MODULE_NAME	"gem"
 #define PFX GEM_MODULE_NAME ": "
@@ -564,6 +565,7 @@
 
 		gp->net_stats.rx_packets++;
 		gp->net_stats.rx_bytes += len;
+		gp->dev->last_rx = jiffies;
 
 	next:
 		entry = NEXT_RX(entry);
@@ -1615,12 +1617,17 @@
 	unsigned long gemreg_base, gemreg_len;
 	struct net_device *dev;
 	struct gem *gp;
-	int i;
+	int i, err;
 
 	if (gem_version_printed++ == 0)
 		printk(KERN_INFO "%s", version);
 
-	pci_enable_device(pdev);
+	err = pci_enable_device(pdev);
+	if (err) {
+		printk(KERN_ERR PFX "Cannot enable MMIO operation, "
+		       "aborting.\n");
+		return err;
+	}
 	pci_set_master(pdev);
 
 	gemreg_base = pci_resource_start(pdev, 0);
@@ -1645,16 +1652,7 @@
 		goto err_out_free_netdev;
 	}
 
-	if (pci_enable_device(pdev)) {
-		printk(KERN_ERR PFX "Cannot enable MMIO operation, "
-		       "aborting.\n");
-		goto err_out_free_mmio_res;
-	}
-
-	pci_set_master(pdev);
-
 	gp = dev->priv;
-	memset(gp, 0, sizeof(*gp));
 
 	gp->pdev = pdev;
 	dev->base_addr = (long) pdev;
@@ -1732,14 +1730,6 @@
 
 }
 
-static void gem_suspend(struct pci_dev *pdev)
-{
-}
-
-static void gem_resume(struct pci_dev *pdev)
-{
-}
-
 static void __devexit gem_remove_one(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
@@ -1767,8 +1757,6 @@
 	id_table:	gem_pci_tbl,
 	probe:		gem_init_one,
 	remove:		gem_remove_one,
-	suspend:	gem_suspend,
-	resume:		gem_resume,
 };
 
 static int __init gem_init(void)
diff -u --recursive --new-file v2.4.5/linux/drivers/net/sunhme.c linux/drivers/net/sunhme.c
--- v2.4.5/linux/drivers/net/sunhme.c	Sun May 20 11:32:07 2001
+++ linux/drivers/net/sunhme.c	Wed Jun 20 11:10:53 2001
@@ -72,6 +72,7 @@
 
 /* accept MAC address of the form macaddr=0x08,0x00,0x20,0x30,0x40,0x50 */
 MODULE_PARM(macaddr, "6i");
+MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set");
 
 static struct happy_meal *root_happy_dev;
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/tlan.c linux/drivers/net/tlan.c
--- v2.4.5/linux/drivers/net/tlan.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/tlan.c	Wed Jun 20 11:13:18 2001
@@ -194,6 +194,11 @@
 MODULE_PARM(speed, "1-" __MODULE_STRING(MAX_TLAN_BOARDS) "i");
 MODULE_PARM(debug, "i");
 MODULE_PARM(bbuf, "i");
+MODULE_PARM_DESC(aui, "ThunderLAN use AUI port(s) (0-1)");
+MODULE_PARM_DESC(duplex, "ThunderLAN duplex setting(s) (0-default, 1-half, 2-full)");
+MODULE_PARM_DESC(speed, "ThunderLAN port speen setting(s) (0,10,100)");
+MODULE_PARM_DESC(debug, "ThunderLAN debug mask");
+MODULE_PARM_DESC(bbuf, "ThunderLAN use big buffer (0-1)");
 EXPORT_NO_SYMBOLS;
 
 /* Define this to enable Link beat monitoring */
@@ -917,13 +922,13 @@
 			data[0] = phy;
 
 		case SIOCDEVPRIVATE+1: /* Read MII register */
-			TLan_MiiReadReg(dev, data[0], data[1], &data[3]);
+			TLan_MiiReadReg(dev, data[0] & 0x1f, data[1] & 0x1f, &data[3]);
 			return 0;
 		
 		case SIOCDEVPRIVATE+2: /* Write MII register */
 			if (!capable(CAP_NET_ADMIN))
 				return -EPERM;
-			TLan_MiiWriteReg(dev, data[0], data[1], data[2]);
+			TLan_MiiWriteReg(dev, data[0] & 0x1f, data[1] & 0x1f, data[2]);
 			return 0;
 		default:
 			return -EOPNOTSUPP;
diff -u --recursive --new-file v2.4.5/linux/drivers/net/tokenring/ibmtr.c linux/drivers/net/tokenring/ibmtr.c
--- v2.4.5/linux/drivers/net/tokenring/ibmtr.c	Tue Mar 20 12:05:00 2001
+++ linux/drivers/net/tokenring/ibmtr.c	Tue Jun 12 11:06:54 2001
@@ -1185,7 +1185,7 @@
 				isa_writeb(~CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);
 				isa_writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
 
-			  skip_reset:
+			  skip_reset:;
 			} /* SRB response */
 
 			if (status & ASB_FREE_INT) { /* ASB response */
diff -u --recursive --new-file v2.4.5/linux/drivers/net/tokenring/lanstreamer.c linux/drivers/net/tokenring/lanstreamer.c
--- v2.4.5/linux/drivers/net/tokenring/lanstreamer.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/tokenring/lanstreamer.c	Wed Jun 20 11:13:18 2001
@@ -1808,25 +1808,11 @@
 #endif
 #endif
 
-static void streamer_suspend(struct pci_dev *pdev) {
-#if STREAMER_DEBUG
-  printk("lanstreamer::streamer_suspend entry pdev %p\n",pdev);
-#endif
-}
-
-static void streamer_resume(struct pci_dev *pdev) {
-#if STREAMER_DEBUG
-  printk("lanstreamer::streamer_resume entry pdev %p\n",pdev);
-#endif
-}
-
 static struct pci_driver streamer_pci_driver = {
   name:       "lanstreamer",
   id_table:   streamer_pci_tbl,
   probe:      streamer_init_one,
   remove:     streamer_remove_one,
-  suspend:    streamer_suspend,
-  resume:     streamer_resume,
 };
 
 static int __init streamer_init_module(void) {
diff -u --recursive --new-file v2.4.5/linux/drivers/net/tokenring/olympic.c linux/drivers/net/tokenring/olympic.c
--- v2.4.5/linux/drivers/net/tokenring/olympic.c	Sun May 20 12:11:38 2001
+++ linux/drivers/net/tokenring/olympic.c	Wed Jun 20 11:13:18 2001
@@ -49,6 +49,8 @@
  * 04/09/01 - Couple of bug fixes to the dma unmaps and ejecting the
  *	      adapter when live does not take the system down with it.
  * 
+ * 06/02/01 - Clean up, copy skb for small packets
+ *
  *  To Do:
  *
  *	     Complete full Cardbus / hot-swap support.
@@ -64,7 +66,10 @@
 
 #define OLYMPIC_DEBUG 0
 
+
+#include <linux/config.h>
 #include <linux/module.h>
+
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
@@ -99,8 +104,8 @@
  * Official releases will only have an a.b.c version number format. 
  */
 
-static char *version = 
-"Olympic.c v0.9.C 4/18/01 - Peter De Schrijver & Mike Phillips" ; 
+static char version[] __devinitdata = 
+"Olympic.c v0.9.7 6/02/01 - Peter De Schrijver & Mike Phillips" ; 
 
 static char *open_maj_error[]  = {"No error", "Lobe Media Test", "Physical Insertion",
 				   "Address Verification", "Neighbor Notification (Ring Poll)",
@@ -116,6 +121,9 @@
 
 /* Module paramters */
 
+MODULE_AUTHOR("Mike Phillips <mikep@linuxtr.net>") ; 
+MODULE_DESCRIPTION("Olympic PCI/Cardbus Chipset Driver \n") ; 
+
 /* Ring Speed 0,4,16,100 
  * 0 = Autosense         
  * 4,16 = Selected speed only, no autosense
@@ -157,7 +165,8 @@
 };
 MODULE_DEVICE_TABLE(pci,olympic_pci_tbl) ; 
 
-static int __init olympic_probe(struct pci_dev *pdev, const struct pci_device_id *ent); 
+
+static int olympic_probe(struct pci_dev *pdev, const struct pci_device_id *ent); 
 static int olympic_init(struct net_device *dev);
 static int olympic_open(struct net_device *dev);
 static int olympic_xmit(struct sk_buff *skb, struct net_device *dev);
@@ -172,7 +181,7 @@
 static void olympic_asb_bh(struct net_device *dev) ; 
 static int olympic_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data) ; 
 
-static int __init olympic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	struct net_device *dev ; 
 	struct olympic_private *olympic_priv;
@@ -239,6 +248,7 @@
 	dev->set_multicast_list=&olympic_set_rx_mode;
 	dev->get_stats=&olympic_get_stats ;
 	dev->set_mac_address=&olympic_set_mac_address ;  
+	SET_MODULE_OWNER(dev) ; 
 
 	pci_set_drvdata(pdev,dev) ; 
 	register_netdev(dev) ; 
@@ -253,10 +263,10 @@
 	return  0 ;
 }
 
-static int __init olympic_init(struct net_device *dev)
+static int __devinit olympic_init(struct net_device *dev)
 {
     	struct olympic_private *olympic_priv;
-	__u8 *olympic_mmio, *init_srb,*adapter_addr;
+	u8 *olympic_mmio, *init_srb,*adapter_addr;
 	unsigned long t; 
 	unsigned int uaa_addr;
 
@@ -268,7 +278,7 @@
 
 	writel(readl(olympic_mmio+BCTL) | BCTL_SOFTRESET,olympic_mmio+BCTL);
 	t=jiffies;
-	while((readl(olympic_priv->olympic_mmio+BCTL)) & BCTL_SOFTRESET) {
+	while((readl(olympic_mmio+BCTL)) & BCTL_SOFTRESET) {
 		schedule();		
 		if(jiffies-t > 40*HZ) {
 			printk(KERN_ERR "IBM PCI tokenring card not responding.\n");
@@ -381,7 +391,7 @@
 static int olympic_open(struct net_device *dev) 
 {
 	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;
-	__u8 *olympic_mmio=olympic_priv->olympic_mmio,*init_srb;
+	u8 *olympic_mmio=olympic_priv->olympic_mmio,*init_srb;
 	unsigned long flags, t;
 	char open_error[255] ; 
 	int i, open_finished = 1 ;
@@ -632,10 +642,10 @@
 #endif
 
 	if (olympic_priv->olympic_network_monitor) { 
-		__u8 *oat ; 
-		__u8 *opt ; 
-		oat = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ; 
-		opt = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr) ; 
+		u8 *oat ; 
+		u8 *opt ; 
+		oat = (u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ; 
+		opt = (u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr) ; 
 
 		printk("%s: Node Address: %02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, 
 			readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)), 
@@ -659,7 +669,6 @@
 	}
 	
 	netif_start_queue(dev);
-	MOD_INC_USE_COUNT ;
 	return 0;
 	
 }	
@@ -673,12 +682,16 @@
  *	This means that we may process the frame before we receive the end
  *	of frame interrupt. This is why we always test the status instead
  *	of blindly processing the next frame.
+ *
+ *	We also remove the last 4 bytes from the packet as well, these are
+ *	just token ring trailer info and upset protocols that don't check 
+ *	their own length, i.e. SNA. 
  *	
  */
 static void olympic_rx(struct net_device *dev)
 {
 	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;
-	__u8 *olympic_mmio=olympic_priv->olympic_mmio;
+	u8 *olympic_mmio=olympic_priv->olympic_mmio;
 	struct olympic_rx_status *rx_status;
 	struct olympic_rx_desc *rx_desc ; 
 	int rx_ring_last_received,length, buffer_cnt, cpy_length, frag_len;
@@ -688,7 +701,7 @@
 	rx_status=&(olympic_priv->olympic_rx_status_ring[(olympic_priv->rx_status_last_received + 1) & (OLYMPIC_RX_RING_SIZE - 1)]) ; 
  
 	while (rx_status->status_buffercnt) { 
-                __u32 l_status_buffercnt;
+                u32 l_status_buffercnt;
 
 		olympic_priv->rx_status_last_received++ ;
 		olympic_priv->rx_status_last_received &= (OLYMPIC_RX_RING_SIZE -1);
@@ -742,36 +755,50 @@
 			   	   	   If only one buffer is used we can simply swap the buffers around.
 			   	   	   If more than one then we must use the new buffer and copy the information
 			   	   	   first. Ideally all frames would be in a single buffer, this can be tuned by
-                               	   	   altering the buffer size. */
+                               	   	   altering the buffer size. If the length of the packet is less than
+					   1500 bytes we're going to copy it over anyway to stop packets getting
+					   dropped from sockets with buffers small than our pkt_buf_sz. */
 				
  					if (buffer_cnt==1) {
 						olympic_priv->rx_ring_last_received++ ; 
 						olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1);
 						rx_ring_last_received = olympic_priv->rx_ring_last_received ;
-						skb2=olympic_priv->rx_ring_skb[rx_ring_last_received] ; 
-						/* unmap buffer */
-						pci_unmap_single(olympic_priv->pdev,
-							le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer), 
-							olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; 
-						skb_put(skb2,length);
-						skb2->protocol = tr_type_trans(skb2,dev);
-						olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer = 
-							cpu_to_le32(pci_map_single(olympic_priv->pdev, skb->data, 
-							olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE));
-						olympic_priv->olympic_rx_ring[rx_ring_last_received].res_length = 
-							cpu_to_le32(olympic_priv->pkt_buf_sz); 
-						olympic_priv->rx_ring_skb[rx_ring_last_received] = skb ; 
-						netif_rx(skb2) ; 
+						if (length > 1500) { 
+							skb2=olympic_priv->rx_ring_skb[rx_ring_last_received] ; 
+							/* unmap buffer */
+							pci_unmap_single(olympic_priv->pdev,
+								le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer), 
+								olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; 
+							skb_put(skb2,length-4);
+							skb2->protocol = tr_type_trans(skb2,dev);
+							olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer = 
+								cpu_to_le32(pci_map_single(olympic_priv->pdev, skb->data, 
+								olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE));
+							olympic_priv->olympic_rx_ring[rx_ring_last_received].res_length = 
+								cpu_to_le32(olympic_priv->pkt_buf_sz); 
+							olympic_priv->rx_ring_skb[rx_ring_last_received] = skb ; 
+							netif_rx(skb2) ; 
+						} else { 
+							pci_dma_sync_single(olympic_priv->pdev,
+								le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer),
+								olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; 
+							memcpy(skb_put(skb,length-4),olympic_priv->rx_ring_skb[rx_ring_last_received]->data,length-4) ; 
+							skb->protocol = tr_type_trans(skb,dev) ; 
+							netif_rx(skb) ; 
+						} 
 					} else {
 						do { /* Walk the buffers */ 
 							olympic_priv->rx_ring_last_received++ ; 
 							olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1);
 							rx_ring_last_received = olympic_priv->rx_ring_last_received ; 
+							pci_dma_sync_single(olympic_priv->pdev,
+								le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer),
+								olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; 
 							rx_desc = &(olympic_priv->olympic_rx_ring[rx_ring_last_received]);
 							cpy_length = (i == 1 ? frag_len : le32_to_cpu(rx_desc->res_length)); 
 							memcpy(skb_put(skb, cpy_length), olympic_priv->rx_ring_skb[rx_ring_last_received]->data, cpy_length) ;
 						} while (--i) ; 
-		
+						skb_trim(skb,skb->len-4) ; 
 						skb->protocol = tr_type_trans(skb,dev);
 						netif_rx(skb) ; 
 					} 
@@ -799,9 +826,9 @@
 {
 	struct net_device *dev= (struct net_device *)dev_id;
 	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;
-	__u8 *olympic_mmio=olympic_priv->olympic_mmio;
-	__u32 sisr;
-	__u8 *adapter_check_area ; 
+	u8 *olympic_mmio=olympic_priv->olympic_mmio;
+	u32 sisr;
+	u8 *adapter_check_area ; 
 	
 	/* 
 	 *  Read sisr but don't reset it yet. 
@@ -855,7 +882,7 @@
 			netif_stop_queue(dev);
 			printk(KERN_WARNING "%s: Adapter Check Interrupt Raised, 8 bytes of information follow:\n", dev->name);
 			writel(readl(olympic_mmio+LAPWWO),olympic_mmio+LAPA);
-			adapter_check_area = (__u8 *)(olympic_mmio+LAPWWO) ; 
+			adapter_check_area = (u8 *)(olympic_mmio+LAPWWO) ; 
 			printk(KERN_WARNING "%s: Bytes %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, readb(adapter_check_area+0), readb(adapter_check_area+1), readb(adapter_check_area+2), readb(adapter_check_area+3), readb(adapter_check_area+4), readb(adapter_check_area+5), readb(adapter_check_area+6), readb(adapter_check_area+7)) ; 
 			/* The adapter is effectively dead, clean up and exit */
 			for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {
@@ -880,7 +907,6 @@
 				sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE, PCI_DMA_TODEVICE);
 
 			free_irq(dev->irq, dev) ;
-			MOD_DEC_USE_COUNT ;
 			dev->stop = NULL ;  
 			spin_unlock(&olympic_priv->olympic_lock) ; 
 			return ; 
@@ -921,7 +947,7 @@
 static int olympic_xmit(struct sk_buff *skb, struct net_device *dev) 
 {
 	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;
-	__u8 *olympic_mmio=olympic_priv->olympic_mmio;
+	u8 *olympic_mmio=olympic_priv->olympic_mmio;
 	unsigned long flags ; 
 
 	spin_lock_irqsave(&olympic_priv->olympic_lock, flags);
@@ -952,7 +978,7 @@
 static int olympic_close(struct net_device *dev) 
 {
 	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;
-    	__u8 *olympic_mmio=olympic_priv->olympic_mmio,*srb;
+    	u8 *olympic_mmio=olympic_priv->olympic_mmio,*srb;
 	unsigned long t,flags;
 	int i;
 
@@ -1027,7 +1053,6 @@
 #endif
 	free_irq(dev->irq,dev);
 
-	MOD_DEC_USE_COUNT ; 
 	return 0;
 	
 }
@@ -1035,9 +1060,9 @@
 static void olympic_set_rx_mode(struct net_device *dev) 
 {
 	struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv ; 
-   	__u8 *olympic_mmio = olympic_priv->olympic_mmio ; 
-	__u8 options = 0; 
-	__u8 *srb;
+   	u8 *olympic_mmio = olympic_priv->olympic_mmio ; 
+	u8 options = 0; 
+	u8 *srb;
 	struct dev_mc_list *dmi ; 
 	unsigned char dev_mc_address[4] ; 
 	int i ; 
@@ -1103,8 +1128,8 @@
 static void olympic_srb_bh(struct net_device *dev) 
 { 
 	struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv ; 
-   	__u8 *olympic_mmio = olympic_priv->olympic_mmio ; 
-	__u8 *srb;
+   	u8 *olympic_mmio = olympic_priv->olympic_mmio ; 
+	u8 *srb;
 
 	writel(olympic_priv->srb,olympic_mmio+LAPA);
 	srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800));
@@ -1277,22 +1302,22 @@
 static void olympic_arb_cmd(struct net_device *dev)
 {
 	struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv;
-    	__u8 *olympic_mmio=olympic_priv->olympic_mmio;
-	__u8 *arb_block, *asb_block, *srb  ; 
-	__u8 header_len ; 
-	__u16 frame_len, buffer_len ;
+    	u8 *olympic_mmio=olympic_priv->olympic_mmio;
+	u8 *arb_block, *asb_block, *srb  ; 
+	u8 header_len ; 
+	u16 frame_len, buffer_len ;
 	struct sk_buff *mac_frame ;  
-	__u8 *buf_ptr ;
-	__u8 *frame_data ;  
-	__u16 buff_off ; 
-	__u16 lan_status = 0, lan_status_diff  ; /* Initialize to stop compiler warning */
-	__u8 fdx_prot_error ; 
-	__u16 next_ptr;
+	u8 *buf_ptr ;
+	u8 *frame_data ;  
+	u16 buff_off ; 
+	u16 lan_status = 0, lan_status_diff  ; /* Initialize to stop compiler warning */
+	u8 fdx_prot_error ; 
+	u16 next_ptr;
 	int i ; 
 
-	arb_block = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->arb) ; 
-	asb_block = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->asb) ; 
-	srb = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->srb) ; 
+	arb_block = (u8 *)(olympic_priv->olympic_lap + olympic_priv->arb) ; 
+	asb_block = (u8 *)(olympic_priv->olympic_lap + olympic_priv->asb) ; 
+	srb = (u8 *)(olympic_priv->olympic_lap + olympic_priv->srb) ; 
 	writel(readl(olympic_mmio+LAPA),olympic_mmio+LAPWWO);
 
 	if (readb(arb_block+0) == ARB_RECEIVE_DATA) { /* Receive.data, MAC frames */
@@ -1421,7 +1446,6 @@
 			free_irq(dev->irq,dev);
 			dev->stop=NULL;
 			printk(KERN_WARNING "%s: Adapter has been closed \n", dev->name) ; 
-			MOD_DEC_USE_COUNT ; 
 		} /* If serious error */
 		
 		if (olympic_priv->olympic_message_level) { 
@@ -1489,10 +1513,10 @@
 static void olympic_asb_bh(struct net_device *dev) 
 {
 	struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv ; 
-	__u8 *arb_block, *asb_block ; 
+	u8 *arb_block, *asb_block ; 
 
-	arb_block = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->arb) ; 
-	asb_block = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->asb) ; 
+	arb_block = (u8 *)(olympic_priv->olympic_lap + olympic_priv->arb) ; 
+	asb_block = (u8 *)(olympic_priv->olympic_lap + olympic_priv->asb) ; 
 
 	if (olympic_priv->asb_queued == 1) {   /* Dropped through the first time */
 
@@ -1529,7 +1553,7 @@
 static int olympic_change_mtu(struct net_device *dev, int mtu) 
 {
 	struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv;
-	__u16 max_mtu ; 
+	u16 max_mtu ; 
 
 	if (olympic_priv->olympic_ring_speed == 4)
 		max_mtu = 4500 ; 
@@ -1551,8 +1575,8 @@
 {
 	struct net_device *dev = (struct net_device *)data ; 
 	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;
-	__u8 *oat = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ; 
-	__u8 *opt = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr) ; 
+	u8 *oat = (u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ; 
+	u8 *opt = (u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr) ; 
 	int size = 0 ; 
 	int len=0;
 	off_t begin=0;
@@ -1672,7 +1696,8 @@
 	unregister_trdev(dev) ; 
 	iounmap(olympic_priv->olympic_mmio) ; 
 	iounmap(olympic_priv->olympic_lap) ; 
-	pci_release_regions(pdev) ; 	
+	pci_release_regions(pdev) ;
+	pci_set_drvdata(pdev,NULL) ;  	
 	kfree(dev) ; 
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/tokenring/olympic.h linux/drivers/net/tokenring/olympic.h
--- v2.4.5/linux/drivers/net/tokenring/olympic.h	Wed Apr 18 11:39:21 2001
+++ linux/drivers/net/tokenring/olympic.h	Wed Jun 20 11:13:18 2001
@@ -214,43 +214,43 @@
 /* xxxx These structures are all little endian in hardware. */
 
 struct olympic_tx_desc {
-	__u32 buffer;
-	__u32 status_length;
+	u32 buffer;
+	u32 status_length;
 };
 
 struct olympic_tx_status {
-	__u32 status;
+	u32 status;
 };
 
 struct olympic_rx_desc {
-	__u32 buffer;
-	__u32 res_length; 
+	u32 buffer;
+	u32 res_length; 
 };
 
 struct olympic_rx_status {
-	__u32 fragmentcnt_framelen;
-	__u32 status_buffercnt;
+	u32 fragmentcnt_framelen;
+	u32 status_buffercnt;
 };
 /* xxxx END These structures are all little endian in hardware. */
 /* xxxx There may be more, but I'm pretty sure about these */
 
 struct mac_receive_buffer {
-	__u16 next ; 
-	__u8 padding ; 
-	__u8 frame_status ;
-	__u16 buffer_length ; 
-	__u8 frame_data ; 
+	u16 next ; 
+	u8 padding ; 
+	u8 frame_status ;
+	u16 buffer_length ; 
+	u8 frame_data ; 
 };
 
 struct olympic_private {
 	
-	__u16 srb;      /* be16 */
-	__u16 trb;      /* be16 */
-	__u16 arb;      /* be16 */
-	__u16 asb;      /* be16 */
+	u16 srb;      /* be16 */
+	u16 trb;      /* be16 */
+	u16 arb;      /* be16 */
+	u16 asb;      /* be16 */
 
-	__u8 *olympic_mmio;
-	__u8 *olympic_lap;
+	u8 *olympic_mmio;
+	u8 *olympic_lap;
 	struct pci_dev *pdev ; 
 	char *olympic_card_name ; 
 
@@ -274,47 +274,47 @@
 	int tx_ring_free, tx_ring_last_status, rx_ring_last_received,rx_status_last_received, free_tx_ring_entries;
 
 	struct net_device_stats olympic_stats ;
-	__u16 olympic_lan_status ;
-	__u8 olympic_ring_speed ;
-	__u16 pkt_buf_sz ; 
-	__u8 olympic_receive_options, olympic_copy_all_options,olympic_message_level, olympic_network_monitor;  
-	__u16 olympic_addr_table_addr, olympic_parms_addr ; 
-	__u8 olympic_laa[6] ; 
-	__u32 rx_ring_dma_addr;
-	__u32 rx_status_ring_dma_addr;
-	__u32 tx_ring_dma_addr;
-	__u32 tx_status_ring_dma_addr;
+	u16 olympic_lan_status ;
+	u8 olympic_ring_speed ;
+	u16 pkt_buf_sz ; 
+	u8 olympic_receive_options, olympic_copy_all_options,olympic_message_level, olympic_network_monitor;  
+	u16 olympic_addr_table_addr, olympic_parms_addr ; 
+	u8 olympic_laa[6] ; 
+	u32 rx_ring_dma_addr;
+	u32 rx_status_ring_dma_addr;
+	u32 tx_ring_dma_addr;
+	u32 tx_status_ring_dma_addr;
 };
 
 struct olympic_adapter_addr_table {
 
-	__u8 node_addr[6] ; 
-	__u8 reserved[4] ; 
-	__u8 func_addr[4] ; 
+	u8 node_addr[6] ; 
+	u8 reserved[4] ; 
+	u8 func_addr[4] ; 
 } ; 
 
 struct olympic_parameters_table { 
 	
-	__u8  phys_addr[4] ; 
-	__u8  up_node_addr[6] ; 
-	__u8  up_phys_addr[4] ; 
-	__u8  poll_addr[6] ; 
-	__u16 reserved ; 
-	__u16 acc_priority ; 
-	__u16 auth_source_class ; 
-	__u16 att_code ; 
-	__u8  source_addr[6] ; 
-	__u16 beacon_type ; 
-	__u16 major_vector ; 
-	__u16 lan_status ; 
-	__u16 soft_error_time ; 
- 	__u16 reserved1 ; 
-	__u16 local_ring ; 
-	__u16 mon_error ; 
-	__u16 beacon_transmit ; 
-	__u16 beacon_receive ; 
-	__u16 frame_correl ; 
-	__u8  beacon_naun[6] ; 
-	__u32 reserved2 ; 
-	__u8  beacon_phys[4] ; 	
+	u8  phys_addr[4] ; 
+	u8  up_node_addr[6] ; 
+	u8  up_phys_addr[4] ; 
+	u8  poll_addr[6] ; 
+	u16 reserved ; 
+	u16 acc_priority ; 
+	u16 auth_source_class ; 
+	u16 att_code ; 
+	u8  source_addr[6] ; 
+	u16 beacon_type ; 
+	u16 major_vector ; 
+	u16 lan_status ; 
+	u16 soft_error_time ; 
+ 	u16 reserved1 ; 
+	u16 local_ring ; 
+	u16 mon_error ; 
+	u16 beacon_transmit ; 
+	u16 beacon_receive ; 
+	u16 frame_correl ; 
+	u8  beacon_naun[6] ; 
+	u32 reserved2 ; 
+	u8  beacon_phys[4] ; 	
 }; 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/tokenring/smctr.c linux/drivers/net/tokenring/smctr.c
--- v2.4.5/linux/drivers/net/tokenring/smctr.c	Wed May 16 10:31:27 2001
+++ linux/drivers/net/tokenring/smctr.c	Thu Jun 21 14:28:39 2001
@@ -59,6 +59,10 @@
 #include <linux/skbuff.h>
 #include <linux/trdevice.h>
 
+#if BITS_PER_LONG == 64
+#error FIXME: driver does not support 64-bit platforms
+#endif
+
 #include "smctr.h"               /* Our Stuff */
 #include "smctr_firmware.h"      /* SMC adapter firmware */
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/tulip/21142.c linux/drivers/net/tulip/21142.c
--- v2.4.5/linux/drivers/net/tulip/21142.c	Wed May 16 10:25:39 2001
+++ linux/drivers/net/tulip/21142.c	Wed Jun 20 11:15:44 2001
@@ -84,7 +84,7 @@
 			tp->csr6 &= 0x00D5;
 			tp->csr6 |= new_csr6;
 			outl(0x0301, ioaddr + CSR12);
-			tulip_restart_rxtx(tp, tp->csr6);
+			tulip_restart_rxtx(tp);
 		}
 		next_tick = 3*HZ;
 	}
@@ -117,7 +117,7 @@
 	udelay(100);
 	outl(csr14, ioaddr + CSR14);
 	tp->csr6 = 0x82420000 | (tp->sym_advertise & 0x0040 ? FullDuplex : 0);
-	tulip_outl_csr(tp, tp->csr6, CSR6);
+	outl(tp->csr6, ioaddr + CSR6);
 	if (tp->mtable  &&  tp->mtable->csr15dir) {
 		outl(tp->mtable->csr15dir, ioaddr + CSR15);
 		outl(tp->mtable->csr15val, ioaddr + CSR15);
@@ -201,12 +201,12 @@
 			outl(1, ioaddr + CSR13);
 		}
 #if 0							/* Restart shouldn't be needed. */
-		tulip_outl_csr(tp, tp->csr6 | csr6_sr, CSR6);
+		outl(tp->csr6 | RxOn, ioaddr + CSR6);
 		if (tulip_debug > 2)
 			printk(KERN_DEBUG "%s:  Restarting Tx and Rx, CSR5 is %8.8x.\n",
 				   dev->name, inl(ioaddr + CSR5));
 #endif
-		tulip_outl_csr(tp, tp->csr6 | csr6_st | csr6_sr, CSR6);
+		tulip_start_rxtx(tp);
 		if (tulip_debug > 2)
 			printk(KERN_DEBUG "%s:  Setting CSR6 %8.8x/%x CSR12 %8.8x.\n",
 				   dev->name, tp->csr6, inl(ioaddr + CSR6),
@@ -252,7 +252,7 @@
 		tp->csr6 = 0x83860000;
 		outl(0x0003FF7F, ioaddr + CSR14);
 		outl(0x0301, ioaddr + CSR12);
-		tulip_restart_rxtx(tp, tp->csr6);
+		tulip_restart_rxtx(tp);
 	}
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/tulip/ChangeLog linux/drivers/net/tulip/ChangeLog
--- v2.4.5/linux/drivers/net/tulip/ChangeLog	Sat May 19 18:02:45 2001
+++ linux/drivers/net/tulip/ChangeLog	Wed Jun 20 11:19:02 2001
@@ -1,3 +1,70 @@
+2001-06-16  Jeff Garzik  <jgarzik@mandrakesoft.com>
+
+	* tulip.h, tulip_core.c:
+	Integrate MMIO support from devel branch, but default
+	it to off for stable kernel and driver series.
+
+2001-06-16  Jeff Garzik  <jgarzik@mandrakesoft.com>
+
+	* tulip_core.c (tulip_init_one):
+	Free descriptor rings on error.
+
+2001-06-16  Jeff Garzik  <jgarzik@mandrakesoft.com>
+
+	* tulip_core.c (tulip_mwi_config, tulip_init_one):
+	Large update to csr0 bus configuration code.  This is not stable
+	yet, so it is only conditionally enabled, via CONFIG_TULIP_MWI.
+
+2001-06-16  Jeff Garzik  <jgarzik@mandrakesoft.com>
+
+	* tulip_core.c:
+	Initialize timer in tulip_init_one and tulip_down,
+	not in tulip_up.
+
+2001-06-14  Jeff Garzik  <jgarzik@mandrakesoft.com>
+
+	* tulip_core.c:
+	- Update tulip_suspend, tulip_resume for new PCI PM API.
+	- Surround suspend/resume code with CONFIG_PM.
+
+2001-06-12  Jeff Golds  <jgolds@resilience.com>
+
+	* tulip_core.c:
+	- Reset sw ring ptrs in tulip_up.  Fixes PM resume case.
+	- Clean rx and tx rings on device down.
+
+2001-06-05  David Miller  <davem@redhat.com>
+
+	* tulip_core (set_rx_mode):  Do not use set_bit
+	on an integer variable.  Also fix endianness issue.
+
+2001-06-04  Jeff Garzik  <jgarzik@mandrakesoft.com>
+
+	* interrupt.c:
+	Simplify rx processing when CONFIG_NET_HW_FLOWCONTROL is
+	active, and in the process fix a bug where flow control
+	and low load caused rx not to be acknowledged properly.
+
+2001-06-01  Jeff Garzik  <jgarzik@mandrakesoft.com>
+
+	* tulip.h:
+	- Remove tulip_outl_csr helper, redundant.
+	- Add tulip_start_rxtx inline helper.
+	- tulip_stop_rxtx helper: Add synchronization. Always use current
+	  csr6 value, instead of tp->csr6 value or value passed as arg.
+	- tulip_restart_rxtx helper: Add synchronization. Always
+	  use tp->csr6 for desired mode, not value passed as arg.
+	- New RxOn, TxOn, RxTx constants for csr6 modes.
+	- Remove now-redundant constants csr6_st, csr6_sr.
+
+	* 21142.c, interrupt.c, media.c, pnic.c, tulip_core.c:
+	Update for above rxtx helper changes.
+
+	* interrupt.c:
+	- whitespace cleanup around #ifdef CONFIG_NET_HW_FLOWCONTROL,
+	  convert tabs to spaces.
+	- Move tp->stats.rx_missed_errors update outside the ifdef.
+
 2001-05-18  Jeff Garzik  <jgarzik@mandrakesoft.com>
 
 	* tulip_core.c: Added ethtool support.
diff -u --recursive --new-file v2.4.5/linux/drivers/net/tulip/interrupt.c linux/drivers/net/tulip/interrupt.c
--- v2.4.5/linux/drivers/net/tulip/interrupt.c	Sun May 20 12:11:38 2001
+++ linux/drivers/net/tulip/interrupt.c	Wed Jun 20 11:15:44 2001
@@ -328,21 +328,11 @@
 
 		if (csr5 & (RxIntr | RxNoBuf)) {
 #ifdef CONFIG_NET_HW_FLOWCONTROL
-                        if (tp->fc_bit) {
-                                if (test_bit(tp->fc_bit, &netdev_fc_xoff)) {
-                                        tulip_refill_rx(dev);
-                                } else {
-                                        tulip_refill_rx(dev);
-                                        rx += tulip_rx(dev);
-                                }
-                        } else {        /* not in fc mode */
-                                rx += tulip_rx(dev);
-                                tulip_refill_rx(dev);
-                        }
-#else
-			rx += tulip_rx(dev);
-			tulip_refill_rx(dev);
+                        if ((!tp->fc_bit) ||
+			    (!test_bit(tp->fc_bit, &netdev_fc_xoff)))
 #endif
+				rx += tulip_rx(dev);
+			tulip_refill_rx(dev);
 		}
 
 		if (csr5 & (TxNoBuf | TxDied | TxIntr | TimerInt)) {
@@ -418,7 +408,7 @@
 					printk(KERN_WARNING "%s: The transmitter stopped."
 						   "  CSR5 is %x, CSR6 %x, new CSR6 %x.\n",
 						   dev->name, csr5, inl(ioaddr + CSR6), tp->csr6);
-				tulip_restart_rxtx(tp, tp->csr6);
+				tulip_restart_rxtx(tp);
 			}
 			spin_unlock(&tp->lock);
 		}
@@ -434,7 +424,7 @@
 				else
 					tp->csr6 |= 0x00200000;  /* Store-n-forward. */
 				/* Restart the transmit process. */
-				tulip_restart_rxtx(tp, tp->csr6);
+				tulip_restart_rxtx(tp);
 				outl(0, ioaddr + CSR1);
 			}
 			if (csr5 & (RxDied | RxNoBuf)) {
@@ -444,16 +434,15 @@
 				}
 			}
 			if (csr5 & RxDied) {		/* Missed a Rx frame. */
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-                                if (tp->fc_bit && !test_bit(tp->fc_bit, &netdev_fc_xoff)) {
-                                        tp->stats.rx_errors++;
-                                        tulip_outl_csr(tp, tp->csr6 | csr6_st | csr6_sr, CSR6);
-                                }
                                 tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
+#ifdef CONFIG_NET_HW_FLOWCONTROL
+				if (tp->fc_bit && !test_bit(tp->fc_bit, &netdev_fc_xoff)) {
+					tp->stats.rx_errors++;
+					tulip_start_rxtx(tp);
+				}
 #else
 				tp->stats.rx_errors++;
-				tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
-				tulip_outl_csr(tp, tp->csr6 | csr6_st | csr6_sr, CSR6);
+				tulip_start_rxtx(tp);
 #endif
 			}
 			/*
diff -u --recursive --new-file v2.4.5/linux/drivers/net/tulip/media.c linux/drivers/net/tulip/media.c
--- v2.4.5/linux/drivers/net/tulip/media.c	Wed May 16 10:25:39 2001
+++ linux/drivers/net/tulip/media.c	Wed Jun 20 11:15:44 2001
@@ -411,7 +411,6 @@
   */
 int tulip_check_duplex(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
 	struct tulip_private *tp = dev->priv;
 	unsigned int bmsr, lpa, negotiated, new_csr6;
 
@@ -442,11 +441,8 @@
 	else		     new_csr6 &= ~FullDuplex;
 
 	if (new_csr6 != tp->csr6) {
-		if (inl(ioaddr + CSR6) & (csr6_st | csr6_sr))
-			tulip_restart_rxtx(tp, new_csr6);
-		else
-			outl(new_csr6, ioaddr + CSR6);
 		tp->csr6 = new_csr6;
+		tulip_restart_rxtx(tp);
 
 		if (tulip_debug > 0)
 			printk(KERN_INFO "%s: Setting %s-duplex based on MII"
diff -u --recursive --new-file v2.4.5/linux/drivers/net/tulip/pnic.c linux/drivers/net/tulip/pnic.c
--- v2.4.5/linux/drivers/net/tulip/pnic.c	Sat May 19 18:02:45 2001
+++ linux/drivers/net/tulip/pnic.c	Wed Jun 20 11:15:44 2001
@@ -45,7 +45,7 @@
 		if (tp->csr6 != new_csr6) {
 			tp->csr6 = new_csr6;
 			/* Restart Tx */
-			tulip_restart_rxtx(tp, tp->csr6);
+			tulip_restart_rxtx(tp);
 			dev->trans_start = jiffies;
 		}
 	}
@@ -69,7 +69,7 @@
 			return;
 		if (! tp->nwayset  ||  jiffies - dev->trans_start > 1*HZ) {
 			tp->csr6 = 0x00420000 | (tp->csr6 & 0x0000fdff);
-			tulip_outl_csr(tp, tp->csr6, CSR6);
+			outl(tp->csr6, ioaddr + CSR6);
 			outl(0x30, ioaddr + CSR12);
 			outl(0x0201F078, ioaddr + 0xB8); /* Turn on autonegotiation. */
 			dev->trans_start = jiffies;
@@ -148,7 +148,7 @@
 			if (tp->csr6 != new_csr6) {
 				tp->csr6 = new_csr6;
 				/* Restart Tx */
-				tulip_restart_rxtx(tp, tp->csr6);
+				tulip_restart_rxtx(tp);
 				dev->trans_start = jiffies;
 				if (tulip_debug > 1)
 					printk(KERN_INFO "%s: Changing PNIC configuration to %s "
diff -u --recursive --new-file v2.4.5/linux/drivers/net/tulip/timer.c linux/drivers/net/tulip/timer.c
--- v2.4.5/linux/drivers/net/tulip/timer.c	Tue Apr  3 10:19:43 2001
+++ linux/drivers/net/tulip/timer.c	Wed Jun 20 11:15:44 2001
@@ -158,7 +158,7 @@
 				       medianame[tp->mtable->mleaf[tp->cur_index].media]);
 			tulip_select_media(dev, 0);
 			/* Restart the transmit process. */
-			tulip_restart_rxtx(tp, tp->csr6);
+			tulip_restart_rxtx(tp);
 			next_tick = (24*HZ)/10;
 			break;
 		}
diff -u --recursive --new-file v2.4.5/linux/drivers/net/tulip/tulip.h linux/drivers/net/tulip/tulip.h
--- v2.4.5/linux/drivers/net/tulip/tulip.h	Sun May 20 12:11:38 2001
+++ linux/drivers/net/tulip/tulip.h	Wed Jun 20 11:19:02 2001
@@ -22,6 +22,7 @@
 #include <linux/spinlock.h>
 #include <linux/netdevice.h>
 #include <linux/timer.h>
+#include <linux/delay.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 
@@ -30,6 +31,14 @@
 /* undefine, or define to various debugging levels (>4 == obscene levels) */
 #define TULIP_DEBUG 1
 
+/* undefine USE_IO_OPS for MMIO, define for PIO */
+#ifdef CONFIG_TULIP_MMIO
+# undef USE_IO_OPS
+#else
+# define USE_IO_OPS 1
+#endif
+
+
 
 struct tulip_chip_table {
 	char *chip_name;
@@ -139,10 +148,13 @@
 enum tulip_mode_bits {
 	TxThreshold		= (1 << 22),
 	FullDuplex		= (1 << 9),
+	TxOn			= 0x2000,
 	AcceptBroadcast		= 0x0100,
 	AcceptAllMulticast	= 0x0080,
 	AcceptAllPhys		= 0x0040,
 	AcceptRunt		= 0x0008,
+	RxOn			= 0x0002,
+	RxTx			= (TxOn | RxOn),
 };
 
 
@@ -219,7 +231,6 @@
 	 *   (1,1)   *    1024   *   160   *
 	 ***********************************/
 
-	csr6_st = (1<<13),   /* Transmit conrol: 1 = transmit, 0 = stop */
 	csr6_fc = (1<<12),   /* Forces a collision in next transmission (for testing in loopback mode) */
 	csr6_om_int_loop = (1<<10), /* internal (FIFO) loopback flag */
 	csr6_om_ext_loop = (1<<11), /* external (PMD) loopback flag */
@@ -231,7 +242,6 @@
 	csr6_if = (1<<4),    /* Inverse Filtering, rejects only addresses in address table: can't be set */
 	csr6_pb = (1<<3),    /* Pass Bad Frames, (1) causes even bad frames to be passed on */
 	csr6_ho = (1<<2),    /* Hash-only filtering mode: can't be set */
-	csr6_sr = (1<<1),    /* Start(1)/Stop(0) Receive */
 	csr6_hp = (1<<0),    /* Hash/Perfect Receive Filtering Mode: can't be set */
 
 	csr6_mask_capture = (csr6_sc | csr6_ca),
@@ -434,21 +444,48 @@
 extern u16 t21041_csr14[];
 extern u16 t21041_csr15[];
 
+#ifndef USE_IO_OPS
+#undef inb
+#undef inw
+#undef inl
+#undef outb
+#undef outw
+#undef outl
+#define inb(addr) readb((void*)(addr))
+#define inw(addr) readw((void*)(addr))
+#define inl(addr) readl((void*)(addr))
+#define outb(val,addr) writeb((val), (void*)(addr))
+#define outw(val,addr) writew((val), (void*)(addr))
+#define outl(val,addr) writel((val), (void*)(addr))
+#endif /* !USE_IO_OPS */
 
-static inline void tulip_outl_csr (struct tulip_private *tp, u32 newValue, enum tulip_offsets offset)
+
+
+static inline void tulip_start_rxtx(struct tulip_private *tp)
 {
-	outl (newValue, tp->base_addr + offset);
+	long ioaddr = tp->base_addr;
+	outl(tp->csr6 | RxTx, ioaddr + CSR6);
+	barrier();
+	(void) inl(ioaddr + CSR6); /* mmio sync */
 }
 
-static inline void tulip_stop_rxtx(struct tulip_private *tp, u32 csr6mask)
+static inline void tulip_stop_rxtx(struct tulip_private *tp)
 {
-	tulip_outl_csr(tp, csr6mask & ~(csr6_st | csr6_sr), CSR6);
+	long ioaddr = tp->base_addr;
+	u32 csr6 = inl(ioaddr + CSR6);
+
+	if (csr6 & RxTx) {
+		outl(csr6 & ~RxTx, ioaddr + CSR6);
+		barrier();
+		(void) inl(ioaddr + CSR6); /* mmio sync */
+	}
 }
 
-static inline void tulip_restart_rxtx(struct tulip_private *tp, u32 csr6mask)
+static inline void tulip_restart_rxtx(struct tulip_private *tp)
 {
-	tulip_outl_csr(tp, csr6mask | csr6_sr, CSR6);
-	tulip_outl_csr(tp, csr6mask | csr6_st | csr6_sr, CSR6);
+	tulip_stop_rxtx(tp);
+	udelay(5);
+	tulip_start_rxtx(tp);
 }
 
 #endif /* __NET_TULIP_H__ */
diff -u --recursive --new-file v2.4.5/linux/drivers/net/tulip/tulip_core.c linux/drivers/net/tulip/tulip_core.c
--- v2.4.5/linux/drivers/net/tulip/tulip_core.c	Sun May 20 12:11:38 2001
+++ linux/drivers/net/tulip/tulip_core.c	Wed Jun 20 11:19:02 2001
@@ -1,4 +1,4 @@
-/* tulip_core.c: A DEC 21040-family ethernet driver for Linux. */
+/* tulip_core.c: A DEC 21x4x-family ethernet driver for Linux. */
 
 /*
 	Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
@@ -15,8 +15,8 @@
 */
 
 #define DRV_NAME	"tulip"
-#define DRV_VERSION	"0.9.15-pre2"
-#define DRV_RELDATE	"May 16, 2001"
+#define DRV_VERSION	"0.9.15-pre5"
+#define DRV_RELDATE	"June 16, 2001"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -276,7 +276,7 @@
 
 	/* On some chip revs we must set the MII/SYM port before the reset!? */
 	if (tp->mii_cnt  ||  (tp->mtable  &&  tp->mtable->has_mii))
-		tulip_outl_csr (tp, 0x00040000, CSR6);
+		outl(0x00040000, ioaddr + CSR6);
 
 	/* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
 	outl(0x00000001, ioaddr + CSR0);
@@ -291,6 +291,11 @@
 	if (tulip_debug > 1)
 		printk(KERN_DEBUG "%s: tulip_up(), irq==%d.\n", dev->name, dev->irq);
 
+	outl(tp->rx_ring_dma, ioaddr + CSR3);
+	outl(tp->tx_ring_dma, ioaddr + CSR4);
+	tp->cur_rx = tp->cur_tx = 0;
+	tp->dirty_rx = tp->dirty_tx = 0;
+
 	if (tp->chip_id == PNIC2) {
 		u32 addr_high = (dev->dev_addr[1]<<8) + (dev->dev_addr[0]<<0);
 		/* This address setting does not appear to impact chip operation?? */
@@ -340,9 +345,6 @@
 		tp->cur_tx++;
 	}
 
-	outl(tp->rx_ring_dma, ioaddr + CSR3);
-	outl(tp->tx_ring_dma, ioaddr + CSR4);
-
 	tp->saved_if_port = dev->if_port;
 	if (dev->if_port == 0)
 		dev->if_port = tp->default_port;
@@ -409,7 +411,7 @@
 				printk(KERN_INFO "%s: Using MII transceiver %d, status "
 					   "%4.4x.\n",
 					   dev->name, tp->phys[0], tulip_mdio_read(dev, tp->phys[0], 1));
-			tulip_outl_csr(tp, csr6_mask_defstate, CSR6);
+			outl(csr6_mask_defstate, ioaddr + CSR6);
 			tp->csr6 = csr6_mask_hdcap;
 			dev->if_port = 11;
 			outl(0x0000, ioaddr + CSR13);
@@ -455,26 +457,26 @@
 		tulip_select_media(dev, 1);
 
 	/* Start the chip's Tx to process setup frame. */
-	tulip_outl_csr(tp, tp->csr6, CSR6);
-	tulip_outl_csr(tp, tp->csr6 | csr6_st, CSR6);
+	tulip_stop_rxtx(tp);
+	barrier();
+	udelay(5);
+	outl(tp->csr6 | TxOn, ioaddr + CSR6);
 
 	/* Enable interrupts by setting the interrupt mask. */
 	outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR5);
 	outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
-	tulip_outl_csr(tp, tp->csr6 | csr6_st | csr6_sr, CSR6);
+	tulip_start_rxtx(tp);
 	outl(0, ioaddr + CSR2);		/* Rx poll demand */
 
 	if (tulip_debug > 2) {
-		printk(KERN_DEBUG "%s: Done tulip_open(), CSR0 %8.8x, CSR5 %8.8x CSR6 %8.8x.\n",
+		printk(KERN_DEBUG "%s: Done tulip_up(), CSR0 %8.8x, CSR5 %8.8x CSR6 %8.8x.\n",
 			   dev->name, inl(ioaddr + CSR0), inl(ioaddr + CSR5),
 			   inl(ioaddr + CSR6));
 	}
+
 	/* Set the timer to switch to check for link beat and perhaps switch
 	   to an alternate media type. */
-	init_timer(&tp->timer);
 	tp->timer.expires = RUN_AT(next_tick);
-	tp->timer.data = (unsigned long)dev;
-	tp->timer.function = tulip_tbl[tp->chip_id].media_timer;
 	add_timer(&tp->timer);
 }
 
@@ -626,7 +628,7 @@
         if (tp->fc_bit && test_bit(tp->fc_bit,&netdev_fc_xoff))
                 printk("BUG tx_timeout restarting rx when fc on\n");
 #endif
-	tulip_restart_rxtx(tp, tp->csr6);
+	tulip_restart_rxtx(tp);
 	/* Trigger an immediate transmit demand. */
 	outl(0, ioaddr + CSR1);
 
@@ -645,8 +647,6 @@
 	struct tulip_private *tp = (struct tulip_private *)dev->priv;
 	int i;
 
-	tp->cur_rx = tp->cur_tx = 0;
-	tp->dirty_rx = tp->dirty_tx = 0;
 	tp->susp_rx = 0;
 	tp->ttimer = 0;
 	tp->nir = 0;
@@ -742,6 +742,41 @@
 	return 0;
 }
 
+static void tulip_release_unconsumed_tx_buffers(struct tulip_private *tp)
+{
+	unsigned int dirty_tx;
+
+	for (dirty_tx = tp->dirty_tx ; tp->cur_tx - dirty_tx > 0;
+		dirty_tx++) {
+		int entry = dirty_tx % TX_RING_SIZE;
+		int status = le32_to_cpu(tp->tx_ring[entry].status);
+
+		if (status > 0)
+			break;		/* It has been Txed */
+
+		/* Check for Rx filter setup frames. */
+		if (tp->tx_buffers[entry].skb == NULL) {
+			/* test because dummy frames not mapped */
+			if (tp->tx_buffers[entry].mapping)
+				pci_unmap_single(tp->pdev,
+					tp->tx_buffers[entry].mapping,
+					sizeof(tp->setup_frame),
+					PCI_DMA_TODEVICE);
+			continue;
+		}
+		tp->stats.tx_errors++;
+
+		pci_unmap_single(tp->pdev, tp->tx_buffers[entry].mapping,
+				tp->tx_buffers[entry].skb->len,
+				PCI_DMA_TODEVICE);
+
+		/* Free the original skb. */
+		dev_kfree_skb_irq(tp->tx_buffers[entry].skb);
+		tp->tx_buffers[entry].skb = NULL;
+		tp->tx_buffers[entry].mapping = 0;
+	}
+}
+
 static void tulip_down (struct net_device *dev)
 {
 	long ioaddr = dev->base_addr;
@@ -756,7 +791,13 @@
 	outl (0x00000000, ioaddr + CSR7);
 
 	/* Stop the Tx and Rx processes. */
-	tulip_stop_rxtx(tp, inl(ioaddr + CSR6));
+	tulip_stop_rxtx(tp);
+
+	/* prepare receive buffers */
+	tulip_refill_rx(dev);
+
+	/* release any unconsumed transmit buffers */
+	tulip_release_unconsumed_tx_buffers(tp);
 
 	/* 21040 -- Leave the card in 10baseT state. */
 	if (tp->chip_id == DC21040)
@@ -767,6 +808,10 @@
 
 	spin_unlock_irqrestore (&tp->lock, flags);
 
+	init_timer(&tp->timer);
+	tp->timer.data = (unsigned long)dev;
+	tp->timer.function = tulip_tbl[tp->chip_id].media_timer;
+
 	dev->if_port = tp->saved_if_port;
 
 	/* Leave the driver in snooze, not sleep, mode. */
@@ -1108,7 +1153,7 @@
 				else
 					filterbit = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
 				filterbit &= 0x3f;
-				set_bit(filterbit, mc_filter);
+				mc_filter[filterbit >> 5] |= cpu_to_le32(1 << (filterbit & 31));
 				if (tulip_debug > 2) {
 					printk(KERN_INFO "%s: Added filter for %2.2x:%2.2x:%2.2x:"
 						   "%2.2x:%2.2x:%2.2x  %8.8x bit %d.\n", dev->name,
@@ -1193,95 +1238,96 @@
 		spin_unlock_irqrestore(&tp->lock, flags);
 	}
 
-	/* Can someone explain to me what the OR here is supposed to accomplish???? */
-	tulip_outl_csr(tp, csr6 | 0x0000, CSR6);
+	outl(csr6, ioaddr + CSR6);
 }
 
+#ifdef CONFIG_TULIP_MWI
 static void __devinit tulip_mwi_config (struct pci_dev *pdev,
 					struct net_device *dev)
 {
 	struct tulip_private *tp = dev->priv;
-	u8 pci_cacheline;
+	u8 cache;
 	u16 pci_command, new_command;
-	unsigned mwi = 1;
+	u32 csr0;
 	
 	if (tulip_debug > 3)
 		printk(KERN_DEBUG "%s: tulip_mwi_config()\n", pdev->slot_name);
 
-	/* get a sane cache line size, if possible */
-	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &pci_cacheline);
-	if (pci_cacheline < (SMP_CACHE_BYTES / 4))
-		pci_cacheline = SMP_CACHE_BYTES / 4;
-	if (pci_cacheline > TULIP_MAX_CACHE_LINE)
-		pci_cacheline = TULIP_MAX_CACHE_LINE;
-	switch (pci_cacheline) {
-	case 8:
-	case 16:
-	case 32: break;
-	default: pci_cacheline = TULIP_MIN_CACHE_LINE; break;
+	tp->csr0 = 0;
+
+	/* check for sane cache line size. from acenic.c. */
+	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache);
+	if ((cache << 2) != SMP_CACHE_BYTES) {
+		printk(KERN_WARNING "%s: PCI cache line size set incorrectly "
+		       "(%i bytes) by BIOS/FW, correcting to %i\n",
+		       pdev->slot_name, (cache << 2), SMP_CACHE_BYTES);
+		pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
+				      SMP_CACHE_BYTES >> 2);
+		udelay(5);
 	}
-	pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, pci_cacheline);
 
-	/* read back the result.  if zero, or if a buggy chip rev,
-	 * disable MWI
+	/* read cache line size again, hardware may not have accepted
+	 * our cache line size change
 	 */
-	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &pci_cacheline);
-	if (!pci_cacheline || (tp->chip_id == DC21143 && tp->revision == 65))
-		mwi = 0;
-
-	/* re-clamp cache line values to ones supported by tulip */
-	/* From this point forward, 'pci_cacheline' is really
-	 * the value used for csr0 cache alignment and
-	 * csr0 programmable burst length
-	 */
-	switch (pci_cacheline) {
-	case 0:
-	case 8:
-	case 16:
-	case 32: break;
-	default: pci_cacheline = TULIP_MIN_CACHE_LINE; break;
-	}
+	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache);
+	if (!cache)
+		goto out;
+
+	/* if we have any cache line size at all, we can do MRM */
+	csr0 |= MRM;
+	
+	/* ...and barring hardware bugs, MWI */
+	if (!(tp->chip_id == DC21143 && tp->revision == 65))
+		csr0 |= MWI;
 
 	/* set or disable MWI in the standard PCI command bit.
 	 * Check for the case where  mwi is desired but not available
 	 */
 	pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-	if (mwi)	new_command = pci_command | PCI_COMMAND_INVALIDATE;
+	if (csr0 & MWI)	new_command = pci_command | PCI_COMMAND_INVALIDATE;
 	else		new_command = pci_command & ~PCI_COMMAND_INVALIDATE;
 	if (new_command != pci_command) {
 		pci_write_config_word(pdev, PCI_COMMAND, new_command);
+		udelay(5);
 		pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-		if ((new_command != pci_command) && mwi &&
-		    ((pci_command & PCI_COMMAND_INVALIDATE) == 0))
-			mwi = 0;
+		if ((csr0 & MWI) && (!(pci_command & PCI_COMMAND_INVALIDATE)))
+			csr0 &= ~MWI;
 	}
 
-	tp->csr0 = MRL | MRM;	
-
-	/* if no PCI cache line size, bail out with minimal
-	 * burst size and cache alignment of 8 dwords.
-	 * We always want to have some sort of limit.
+	/* assign per-cacheline-size cache alignment and
+	 * burst length values
 	 */
-	if (!pci_cacheline) {
-		tp->csr0 |= (8 << BurstLenShift) | (1 << CALShift);
+	switch (cache) {
+	case 8:
+		csr0 |= MRL | (1 << CALShift) | (16 << BurstLenShift);
+		break;
+	case 16:
+		csr0 |= MRL | (2 << CALShift) | (16 << BurstLenShift);
+		break;
+	case 32:
+		csr0 |= MRL | (3 << CALShift) | (32 << BurstLenShift);
+		break;
+	default:
 		goto out;
 	}
+
+	tp->csr0 = csr0;
+	goto out;
 	
-	/* finally, build the csr0 value */
-	if (mwi)
-		tp->csr0 |= MWI;
-	tp->csr0 |= (pci_cacheline << BurstLenShift);
-	switch (pci_cacheline) {
-	case 8:  tp->csr0 |= (1 << CALShift);
-	case 16: tp->csr0 |= (2 << CALShift);
-	case 32: tp->csr0 |= (3 << CALShift);
+early_out:
+	if (csr0 & MWI) {
+		pci_command &= ~PCI_COMMAND_INVALIDATE;
+		pci_write_config_word(pdev, PCI_COMMAND, pci_command);
+		csr0 &= ~MWI;
 	}
+	tp->csr0 = csr0 | (8 << BurstLenShift) | (1 << CALShift);
 
 out:
 	if (tulip_debug > 2)
-		printk(KERN_DEBUG "%s: MWI config mwi=%d, cacheline=%d, csr0=%08x\n",
-		       pdev->slot_name, mwi, pci_cacheline, tp->csr0);
+		printk(KERN_DEBUG "%s: MWI config cacheline=%d, csr0=%08x\n",
+		       pdev->slot_name, cache, csr0);
 }
+#endif
 
 static int __devinit tulip_init_one (struct pci_dev *pdev,
 				     const struct pci_device_id *ent)
@@ -1402,6 +1448,13 @@
 	if (pci_request_regions (pdev, "tulip"))
 		goto err_out_free_netdev;
 
+#ifndef USE_IO_OPS
+	ioaddr = (unsigned long) ioremap (pci_resource_start (pdev, 1),
+					  tulip_tbl[chip_idx].io_size);
+	if (!ioaddr)
+		goto err_out_free_res;
+#endif
+
 	pci_set_master(pdev);
 
 	pci_read_config_byte (pdev, PCI_REVISION_ID, &chip_rev);
@@ -1417,7 +1470,7 @@
 					   sizeof(struct tulip_tx_desc) * TX_RING_SIZE,
 					   &tp->rx_ring_dma);
 	if (!tp->rx_ring)
-		goto err_out_free_res;
+		goto err_out_mtable;
 	tp->tx_ring = (struct tulip_tx_desc *)(tp->rx_ring + RX_RING_SIZE);
 	tp->tx_ring_dma = tp->rx_ring_dma + sizeof(struct tulip_rx_desc) * RX_RING_SIZE;
 
@@ -1429,15 +1482,20 @@
 	tp->csr0 = csr0;
 	spin_lock_init(&tp->lock);
 	spin_lock_init(&tp->mii_lock);
+	init_timer(&tp->timer);
+	tp->timer.data = (unsigned long)dev;
+	tp->timer.function = tulip_tbl[tp->chip_id].media_timer;
 
 	dev->base_addr = ioaddr;
 	dev->irq = irq;
 
+#ifdef CONFIG_TULIP_MWI
 	if (!force_csr0 && (tp->flags & HAS_PCI_MWI))
 		tulip_mwi_config (pdev, dev);
+#endif
 
 	/* Stop the chip's Tx and Rx processes. */
-	tulip_stop_rxtx(tp, inl(ioaddr + CSR6));
+	tulip_stop_rxtx(tp);
 
 	/* Clear the missed-packet counter. */
 	inl(ioaddr + CSR8);
@@ -1600,7 +1658,7 @@
 	dev->set_multicast_list = set_rx_mode;
 
 	if (register_netdev(dev))
-		goto err_out_mtable;
+		goto err_out_free_ring;
 
 	printk(KERN_INFO "%s: %s rev %d at %#3lx,",
 	       dev->name, tulip_tbl[chip_idx].chip_name, chip_rev, ioaddr);
@@ -1631,7 +1689,7 @@
 		outl(0x00000000, ioaddr + CSR13);
 		outl(0xFFFFFFFF, ioaddr + CSR14);
 		outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */
-		tulip_outl_csr(tp, inl(ioaddr + CSR6) | csr6_fd, CSR6);
+		outl(inl(ioaddr + CSR6) | csr6_fd, ioaddr + CSR6);
 		outl(0x0000EF01, ioaddr + CSR13);
 		break;
 	case DC21040:
@@ -1647,10 +1705,10 @@
 	case DC21142:
 	case PNIC2:
 		if (tp->mii_cnt  ||  tulip_media_cap[dev->if_port] & MediaIsMII) {
-			tulip_outl_csr(tp, csr6_mask_defstate, CSR6);
+			outl(csr6_mask_defstate, ioaddr + CSR6);
 			outl(0x0000, ioaddr + CSR13);
 			outl(0x0000, ioaddr + CSR14);
-			tulip_outl_csr(tp, csr6_mask_hdcap, CSR6);
+			outl(csr6_mask_hdcap, ioaddr + CSR6);
 		} else
 			t21142_start_nway(dev);
 		break;
@@ -1658,21 +1716,21 @@
 		if ( ! tp->mii_cnt) {
 			tp->nway = 1;
 			tp->nwayset = 0;
-			tulip_outl_csr(tp, csr6_ttm | csr6_ca, CSR6);
+			outl(csr6_ttm | csr6_ca, ioaddr + CSR6);
 			outl(0x30, ioaddr + CSR12);
-			tulip_outl_csr(tp, 0x0001F078, CSR6);
-			tulip_outl_csr(tp, 0x0201F078, CSR6); /* Turn on autonegotiation. */
+			outl(0x0001F078, ioaddr + CSR6);
+			outl(0x0201F078, ioaddr + CSR6); /* Turn on autonegotiation. */
 		}
 		break;
 	case MX98713:
 	case COMPEX9881:
-		tulip_outl_csr(tp, 0x00000000, CSR6);
+		outl(0x00000000, ioaddr + CSR6);
 		outl(0x000711C0, ioaddr + CSR14); /* Turn on NWay. */
 		outl(0x00000001, ioaddr + CSR13);
 		break;
 	case MX98715:
 	case MX98725:
-		tulip_outl_csr(tp, 0x01a80000, CSR6);
+		outl(0x01a80000, ioaddr + CSR6);
 		outl(0xFFFFFFFF, ioaddr + CSR14);
 		outl(0x00001000, ioaddr + CSR12);
 		break;
@@ -1686,18 +1744,31 @@
 
 	return 0;
 
+err_out_free_ring:
+	pci_free_consistent (pdev,
+			     sizeof (struct tulip_rx_desc) * RX_RING_SIZE +
+			     sizeof (struct tulip_tx_desc) * TX_RING_SIZE,
+			     tp->rx_ring, tp->rx_ring_dma);
+
 err_out_mtable:
 	if (tp->mtable)
 		kfree (tp->mtable);
+#ifndef USE_IO_OPS
+	iounmap((void *)ioaddr);
+#endif
+
 err_out_free_res:
 	pci_release_regions (pdev);
+
 err_out_free_netdev:
 	kfree (dev);
 	return -ENODEV;
 }
 
 
-static void tulip_suspend (struct pci_dev *pdev)
+#ifdef CONFIG_PM
+
+static int tulip_suspend (struct pci_dev *pdev, u32 state)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 
@@ -1706,10 +1777,11 @@
 		tulip_down (dev);
 		/* pci_power_off(pdev, -1); */
 	}
+	return 0;
 }
 
 
-static void tulip_resume(struct pci_dev *pdev)
+static int tulip_resume(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 
@@ -1721,8 +1793,11 @@
 		tulip_up (dev);
 		netif_device_attach (dev);
 	}
+	return 0;
 }
 
+#endif /* CONFIG_PM */
+
 
 static void __devexit tulip_remove_one (struct pci_dev *pdev)
 {
@@ -1740,6 +1815,9 @@
 	unregister_netdev (dev);
 	if (tp->mtable)
 		kfree (tp->mtable);
+#ifndef USE_IO_OPS
+	iounmap((void *)dev->base_addr);
+#endif
 	kfree (dev);
 	pci_release_regions (pdev);
 	pci_set_drvdata (pdev, NULL);
@@ -1753,8 +1831,10 @@
 	id_table:	tulip_pci_tbl,
 	probe:		tulip_init_one,
 	remove:		tulip_remove_one,
+#ifdef CONFIG_PM
 	suspend:	tulip_suspend,
 	resume:		tulip_resume,
+#endif /* CONFIG_PM */
 };
 
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/tun.c linux/drivers/net/tun.c
--- v2.4.5/linux/drivers/net/tun.c	Wed Apr 18 14:40:06 2001
+++ linux/drivers/net/tun.c	Mon Jun 11 19:15:27 2001
@@ -12,7 +12,7 @@
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  *  GNU General Public License for more details.
  *
- *  $Id: tun.c,v 1.3 2000/10/23 10:01:25 maxk Exp $
+ *  $Id: tun.c,v 1.12 2001/03/08 03:29:27 maxk Exp $
  */
 
 /*
@@ -20,15 +20,16 @@
  *    Modifications for 2.3.99-pre5 kernel.
  */
 
-#define TUN_VER "1.3"
+#define TUN_VER "1.4"
 
+#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/malloc.h>
 #include <linux/poll.h>
 #include <linux/fcntl.h>
 #include <linux/init.h>
@@ -56,28 +57,14 @@
 /* Net device open. */
 static int tun_net_open(struct net_device *dev)
 {
-#ifdef TUN_DEBUG  
-	struct tun_struct *tun = (struct tun_struct *)dev->priv;
-
-	DBG(KERN_INFO "%s: tun_net_open\n", tun->name);
-#endif
-
 	netif_start_queue(dev);
-
 	return 0;
 }
 
 /* Net device close. */
 static int tun_net_close(struct net_device *dev)
 {
-#ifdef TUN_DEBUG  
-	struct tun_struct *tun = (struct tun_struct *)dev->priv;
-
-	DBG(KERN_INFO "%s: tun_net_close\n", tun->name);
-#endif
-
 	netif_stop_queue(dev);
-
 	return 0;
 }
 
@@ -88,38 +75,46 @@
 
 	DBG(KERN_INFO "%s: tun_net_xmit %d\n", tun->name, skb->len);
 
-	/* Queue frame */
-	skb_queue_tail(&tun->txq, skb);
-	if (skb_queue_len(&tun->txq) >= TUN_TXQ_SIZE)
-		netif_stop_queue(dev);
+	/* Drop packet if interface is not attached */
+	if (!tun->attached)
+		goto drop;
+
+	/* Queue packet */
+	if (!(tun->flags & TUN_ONE_QUEUE)) {
+		/* Normal queueing mode.
+		 * Packet scheduler handles dropping. */
+		if (skb_queue_len(&tun->readq) >= TUN_READQ_SIZE)
+			netif_stop_queue(dev);
+	} else {
+		/* Single queue mode.
+		 * Driver handles dropping itself. */
+		if (skb_queue_len(&tun->readq) >= dev->tx_queue_len)
+			goto drop;
+	}
+	skb_queue_tail(&tun->readq, skb);
 
+	/* Notify and wake up reader process */
 	if (tun->flags & TUN_FASYNC)
 		kill_fasync(&tun->fasync, SIGIO, POLL_IN);
-
-	/* Wake up process */ 
 	wake_up_interruptible(&tun->read_wait);
+	return 0;
 
+drop:
+	tun->stats.tx_dropped++;
+	kfree_skb(skb);
 	return 0;
 }
 
 static void tun_net_mclist(struct net_device *dev)
 {
-#ifdef TUN_DEBUG
-	struct tun_struct *tun = (struct tun_struct *)dev->priv;
-
-	DBG(KERN_INFO "%s: tun_net_mclist\n", tun->name);
-#endif
-
 	/* Nothing to do for multicast filters. 
-	 * We always accept all frames.
-	 */
+	 * We always accept all frames. */
 	return;
 }
 
 static struct net_device_stats *tun_net_stats(struct net_device *dev)
 {
 	struct tun_struct *tun = (struct tun_struct *)dev->priv;
-
 	return &tun->stats;
 }
 
@@ -170,15 +165,19 @@
 static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
 {  
 	struct tun_struct *tun = (struct tun_struct *)file->private_data;
+	unsigned int mask = POLLOUT | POLLWRNORM;
+
+	if (!tun)
+		return -EBADFD;
 
 	DBG(KERN_INFO "%s: tun_chr_poll\n", tun->name);
 
 	poll_wait(file, &tun->read_wait, wait);
  
-	if (skb_queue_len(&tun->txq))
-		return POLLIN | POLLRDNORM;
+	if (skb_queue_len(&tun->readq))
+		mask |= POLLIN | POLLRDNORM;
 
-	return POLLOUT | POLLWRNORM;
+	return mask;
 }
 
 /* Get packet from user space buffer(already verified) */
@@ -189,9 +188,6 @@
 	register int len = count;
 	struct sk_buff *skb;
 
-	if (len > TUN_MAX_FRAME)
-		return -EINVAL;
-
 	if (!(tun->flags & TUN_NO_PI)) {
 		if ((len -= sizeof(pi)) < 0)
 			return -EINVAL;
@@ -222,7 +218,6 @@
 	if (tun->flags & TUN_NOCHECKSUM)
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
  
-	skb->dev->last_rx = jiffies;
 	netif_rx(skb);
    
 	tun->stats.rx_packets++;
@@ -237,10 +232,10 @@
 {
 	struct tun_struct *tun = (struct tun_struct *)file->private_data;
 
-	DBG(KERN_INFO "%s: tun_chr_write %d\n", tun->name, count);
+	if (!tun)
+		return -EBADFD;
 
-	if (!(tun->flags & TUN_IFF_SET))
-		return -EBUSY;
+	DBG(KERN_INFO "%s: tun_chr_write %d\n", tun->name, count);
 
 	if (verify_area(VERIFY_READ, buf, count))
 		return -EFAULT;
@@ -291,14 +286,17 @@
 	struct sk_buff *skb;
 	ssize_t ret = 0;
 
+	if (!tun)
+		return -EBADFD;
+
 	DBG(KERN_INFO "%s: tun_chr_read\n", tun->name);
 
 	add_wait_queue(&tun->read_wait, &wait);
 	while (count) {
 		current->state = TASK_INTERRUPTIBLE;
 
-		/* Read frames from device queue */
-		if (!(skb=skb_dequeue(&tun->txq))) {
+		/* Read frames from the queue */
+		if (!(skb=skb_dequeue(&tun->readq))) {
 			if (file->f_flags & O_NONBLOCK) {
 				ret = -EAGAIN;
 				break;
@@ -334,50 +332,83 @@
 	return -ESPIPE;
 }
 
-static int tun_set_iff(struct tun_struct *tun, unsigned long arg)
+static int tun_set_iff(struct file *file, struct ifreq *ifr)
 {
-	struct ifreq ifr;
-	char *mask;
+	struct tun_struct *tun;
+	struct net_device *dev;
+	int err;
+
+	dev = __dev_get_by_name(ifr->ifr_name);
+	if (dev) {
+		/* Device exist */
+		tun = dev->priv;
+
+		if (dev->init != tun_net_init || tun->attached)
+			return -EBUSY;
+
+		/* Check permissions */
+		if (tun->owner != -1)
+			if (current->euid != tun->owner && !capable(CAP_NET_ADMIN))
+				return -EPERM;
+	} else {
+		char *name;
+
+		/* Allocate new device */
+		if (!(tun = kmalloc(sizeof(struct tun_struct), GFP_KERNEL)) )
+			return -ENOMEM;
+		memset(tun, 0, sizeof(struct tun_struct));
+
+		skb_queue_head_init(&tun->readq);
+		init_waitqueue_head(&tun->read_wait);
+
+		tun->owner = -1;
+		tun->dev.init = tun_net_init;
+		tun->dev.priv = tun;
+
+		err = -EINVAL;
+
+		/* Set dev type */
+		if (ifr->ifr_flags & IFF_TUN) {
+			/* TUN device */
+			tun->flags |= TUN_TUN_DEV;
+			name = "tun%d";
+		} else if (ifr->ifr_flags & IFF_TAP) {
+			/* TAP device */
+			tun->flags |= TUN_TAP_DEV;
+			name = "tap%d";
+		} else 
+			goto failed;
+   
+		if (*ifr->ifr_name)
+			name = ifr->ifr_name;
 
-	if (copy_from_user(&ifr, (void *)arg, sizeof(ifr)))
-		return -EFAULT;
-	ifr.ifr_name[IFNAMSIZ-1] = '\0';
+		if ((err = dev_alloc_name(&tun->dev, name)) < 0)
+			goto failed;
+		if ((err = register_netdevice(&tun->dev)))
+			goto failed;
+	
+		MOD_INC_USE_COUNT;
 
-	if (tun->flags & TUN_IFF_SET)
-		return -EEXIST;
+		tun->name = tun->dev.name;
+	}
 
-	/* Set dev type */
-	if (ifr.ifr_flags & IFF_TUN) {
-		/* TUN device */
-		tun->flags |= TUN_TUN_DEV;
-		mask = "tun%d";
-	} else if (ifr.ifr_flags & IFF_TAP) {
-		/* TAP device */
-		tun->flags |= TUN_TAP_DEV;
-		mask = "tap%d";
-	} else 
-		return -EINVAL;
-   
-	if (ifr.ifr_flags & IFF_NO_PI)
+	DBG(KERN_INFO "%s: tun_set_iff\n", tun->name);
+
+	if (ifr->ifr_flags & IFF_NO_PI)
 		tun->flags |= TUN_NO_PI;
 
-	if (*ifr.ifr_name)
-		strcpy(tun->dev.name, ifr.ifr_name);
-	else
-		strcpy(tun->dev.name, mask);
-
-	/* Register net device */
-	if (register_netdev(&tun->dev))
-		return -EBUSY;
-
-	tun->flags |= TUN_IFF_SET;
-	strcpy(tun->name, tun->dev.name);
-
-	/* Return iface info to the user space */
-	strcpy(ifr.ifr_name, tun->dev.name);
-	copy_to_user((void *)arg, &ifr, sizeof(ifr));
+	if (ifr->ifr_flags & IFF_ONE_QUEUE)
+		tun->flags |= TUN_ONE_QUEUE;
+
+	file->private_data = tun;
+	tun->attached = 1;
+
+	strcpy(ifr->ifr_name, tun->name);
+	return 0;
 
-	return 0;   
+failed:
+	kfree(tun);
+	return err;
 }
 
 static int tun_chr_ioctl(struct inode *inode, struct file *file, 
@@ -385,14 +416,33 @@
 {
 	struct tun_struct *tun = (struct tun_struct *)file->private_data;
 
-	DBG(KERN_INFO "%s: tun_chr_ioctl\n", tun->name);
+	if (cmd == TUNSETIFF && !tun) {
+		struct ifreq ifr;
+		int err;
+
+		if (copy_from_user(&ifr, (void *)arg, sizeof(ifr)))
+			return -EFAULT;
+		ifr.ifr_name[IFNAMSIZ-1] = '\0';
 
-	switch (cmd) {
-	case TUNSETIFF:
-		return tun_set_iff(tun, arg); 
+		rtnl_lock();
+		err = tun_set_iff(file, &ifr);
+		rtnl_unlock();
 
+		if (err)
+			return err;
+
+		copy_to_user((void *)arg, &ifr, sizeof(ifr));
+		return 0;
+	}
+
+	if (!tun)
+		return -EBADFD;
+
+	DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->name, cmd);
+
+	switch (cmd) {
 	case TUNSETNOCSUM:
-		/* Disable/Enable checksum on net iface */
+		/* Disable/Enable checksum */
 		if (arg)
 			tun->flags |= TUN_NOCHECKSUM;
 		else
@@ -402,6 +452,24 @@
 		    tun->name, arg ? "disabled" : "enabled");
 		break;
 
+	case TUNSETPERSIST:
+		/* Disable/Enable persist mode */
+		if (arg)
+			tun->flags |= TUN_PERSIST;
+		else
+			tun->flags &= ~TUN_PERSIST;
+
+		DBG(KERN_INFO "%s: persist %s\n",
+		    tun->name, arg ? "disabled" : "enabled");
+		break;
+
+	case TUNSETOWNER:
+		/* Set owner of the device */
+		tun->owner = (uid_t) arg;
+
+		DBG(KERN_INFO "%s: owner set to %d\n", tun->owner);
+		break;
+
 #ifdef TUN_DEBUG
 	case TUNSETDEBUG:
 		tun->debug = arg;
@@ -420,14 +488,22 @@
 	struct tun_struct *tun = (struct tun_struct *)file->private_data;
 	int ret;
 
+	if (!tun)
+		return -EBADFD;
+
 	DBG(KERN_INFO "%s: tun_chr_fasync %d\n", tun->name, on);
 
 	if ((ret = fasync_helper(fd, file, on, &tun->fasync)) < 0)
 		return ret; 
  
-	if (on)
+	if (on) {
 		tun->flags |= TUN_FASYNC;
-	else 
+		if (!file->f_owner.pid) {
+			file->f_owner.pid  = current->pid;
+			file->f_owner.uid  = current->uid;
+			file->f_owner.euid = current->euid;
+		}
+	} else 
 		tun->flags &= ~TUN_FASYNC;
 
 	return 0;
@@ -435,25 +511,8 @@
 
 static int tun_chr_open(struct inode *inode, struct file * file)
 {
-	struct tun_struct *tun = NULL; 
-
 	DBG1(KERN_INFO "tunX: tun_chr_open\n");
-
-	tun = kmalloc(sizeof(struct tun_struct), GFP_KERNEL);
-	if (tun == NULL)
-		return -ENOMEM;
-
-	memset(tun, 0, sizeof(struct tun_struct));
-	file->private_data = tun;
-
-	skb_queue_head_init(&tun->txq);
-	init_waitqueue_head(&tun->read_wait);
-
-	sprintf(tun->name, "tunX");
-
-	tun->dev.init = tun_net_init;
-	tun->dev.priv = tun;
-
+	file->private_data = NULL;
 	return 0;
 }
 
@@ -461,22 +520,30 @@
 {
 	struct tun_struct *tun = (struct tun_struct *)file->private_data;
 
-	DBG(KERN_INFO "%s: tun_chr_close\n", tun->name);
+	if (!tun)
+		return 0;
 
-	if (tun->flags & TUN_IFF_SET) {
-		rtnl_lock();
-		dev_close(&tun->dev);
-		rtnl_unlock();
+	DBG(KERN_INFO "%s: tun_chr_close\n", tun->name);
 
-		/* Drop TX queue */
-		skb_queue_purge(&tun->txq);
+	tun_chr_fasync(-1, file, 0);
 
-		unregister_netdev(&tun->dev);
-	}
+	rtnl_lock();
 
-	kfree(tun);
+	/* Detach from net device */
 	file->private_data = NULL;
+	tun->attached = 0;
+
+	/* Drop read queue */
+	skb_queue_purge(&tun->readq);
+
+	if (!(tun->flags & TUN_PERSIST)) {
+		dev_close(&tun->dev);
+		unregister_netdevice(&tun->dev);
+		kfree(tun);
+		MOD_DEC_USE_COUNT;
+	}
 
+	rtnl_unlock();
 	return 0;
 }
 
@@ -494,15 +561,15 @@
 
 static struct miscdevice tun_miscdev=
 {
-        TUN_MINOR,
-        "net/tun",
-        &tun_fops
+	TUN_MINOR,
+	"net/tun",
+	&tun_fops
 };
 
 int __init tun_init(void)
 {
 	printk(KERN_INFO "Universal TUN/TAP device driver %s " 
-	       "(C)1999-2000 Maxim Krasnyansky\n", TUN_VER);
+	       "(C)1999-2001 Maxim Krasnyansky\n", TUN_VER);
 
 	if (misc_register(&tun_miscdev)) {
 		printk(KERN_ERR "tun: Can't register misc device %d\n", TUN_MINOR);
diff -u --recursive --new-file v2.4.5/linux/drivers/net/via-rhine.c linux/drivers/net/via-rhine.c
--- v2.4.5/linux/drivers/net/via-rhine.c	Fri Apr 20 11:54:23 2001
+++ linux/drivers/net/via-rhine.c	Wed Jun 20 11:15:44 2001
@@ -1,6 +1,6 @@
 /* via-rhine.c: A Linux Ethernet device driver for VIA Rhine family chips. */
 /*
-	Written 1998-2000 by Donald Becker.
+	Written 1998-2001 by Donald Becker.
 
 	This software may be used and distributed according to the terms of
 	the GNU General Public License (GPL), incorporated herein by reference.
@@ -58,6 +58,12 @@
 	
 	LK1.1.7:
 	- Manfred Spraul: added reset into tx_timeout
+
+	LK1.1.9:
+	- Urban Widmark: merges from Beckers 1.10 version
+	                 (media selection + eeprom reload)
+	- David Vrabel:  merges from D-Link "1.11" version
+	                 (disable WOL and PME on startup)
 */
 
 
@@ -75,6 +81,11 @@
    Both 'options[]' and 'full_duplex[]' should exist for driver
    interoperability.
    The media type is usually passed in 'options[]'.
+   The default is autonegotation for speed and duplex.
+     This should rarely be overridden.
+   Use option values 0x10/0x20 for 10Mbps, 0x100,0x200 for 100Mbps.
+   Use option values 0x10 and 0x100 for forcing half duplex fixed speed.
+   Use option values 0x20 and 0x200 for forcing full duplex operation.
 */
 #define MAX_UNITS 8		/* More are supported, limit only on options */
 static int options[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
@@ -104,6 +115,9 @@
 
 #define PKT_BUF_SZ		1536			/* Size of each temporary Rx buffer.*/
 
+/* max time out delay time */
+#define W_MAX_TIMEOUT	0x0FFFU
+
 
 #if !defined(__OPTIMIZE__)  ||  !defined(__KERNEL__)
 #warning  You must compile this file with the correct options!
@@ -132,9 +146,10 @@
 
 /* These identify the driver base version and may not be removed. */
 static char version[] __devinitdata =
-KERN_INFO "via-rhine.c:v1.08b-LK1.1.8  4/17/2000  Written by Donald Becker\n"
+KERN_INFO "via-rhine.c:v1.10-LK1.1.9  05/31/2001  Written by Donald Becker\n"
 KERN_INFO "  http://www.scyld.com/network/via-rhine.html\n";
 
+static char shortname[] __devinitdata = "via-rhine";
 
 
 /* This driver was written to use PCI memory space, however most versions
@@ -165,7 +180,11 @@
 MODULE_PARM(rx_copybreak, "i");
 MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
-
+MODULE_PARM_DESC(max_interrupt_work, "VIA Rhine maximum events handled per interrupt");
+MODULE_PARM_DESC(debug, "VIA Rhine debug level (0-7)");
+MODULE_PARM_DESC(rx_copybreak, "VIA Rhine copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(options, "VIA Rhine: Bits 0-3: media type, bit 17: full duplex");
+MODULE_PARM_DESC(full_duplex, "VIA Rhine full duplex setting(s) (1)");
 
 /*
 				Theory of Operation
@@ -244,6 +263,9 @@
 Preliminary VT86C100A manual from http://www.via.com.tw/
 http://www.scyld.com/expert/100mbps.html
 http://www.scyld.com/expert/NWay.html
+ftp://ftp.via.com.tw/public/lan/Products/NIC/VT86C100A/Datasheet/VT86C100A03.pdf
+ftp://ftp.via.com.tw/public/lan/Products/NIC/VT6102/Datasheet/VT6102_021.PDF
+
 
 IVc. Errata
 
@@ -256,7 +278,6 @@
 */
 
 
-
 /* This table drives the PCI probe routines.  It's mostly boilerplate in all
    of the drivers, and will likely be provided by some future kernel.
    Note the matching code -- the first table entry matchs all 56** cards but
@@ -320,9 +341,9 @@
 	StationAddr=0x00, RxConfig=0x06, TxConfig=0x07, ChipCmd=0x08,
 	IntrStatus=0x0C, IntrEnable=0x0E,
 	MulticastFilter0=0x10, MulticastFilter1=0x14,
-	RxRingPtr=0x18, TxRingPtr=0x1C,
+	RxRingPtr=0x18, TxRingPtr=0x1C, GFIFOTest=0x54,
 	MIIPhyAddr=0x6C, MIIStatus=0x6D, PCIBusConfig=0x6E,
-	MIICmd=0x70, MIIRegAddr=0x71, MIIData=0x72,
+	MIICmd=0x70, MIIRegAddr=0x71, MIIData=0x72, MACRegEEcsr=0x74,
 	Config=0x78, ConfigA=0x7A, RxMissed=0x7C, RxCRCErrs=0x7E,
 	StickyHW=0x83, WOLcrClr=0xA4, WOLcgClr=0xA7, PwrcsrClr=0xAC,
 };
@@ -448,24 +469,29 @@
 static int  via_rhine_close(struct net_device *dev);
 static inline void clear_tally_counters(long ioaddr);
 
-static void wait_for_reset(struct net_device *dev)
+static void wait_for_reset(struct net_device *dev, char *name)
 {
+	struct netdev_private *np = dev->priv;
 	long ioaddr = dev->base_addr;
+	int chip_id = np->chip_id;
 	int i;
 
+	/* 3043 may need long delay after reset (dlink) */
+	if (chip_id == VT3043 || chip_id == VT86C100A)
+		udelay(100);
+
 	i = 0;
 	do {
 		udelay(5);
 		i++;
 		if(i > 2000) {
-			printk(KERN_ERR "%s: reset did not complete in 10 ms.\n",
-					dev->name);
+			printk(KERN_ERR "%s: reset did not complete in 10 ms.\n", name);
 			break;
 		}
 	} while(readw(ioaddr + ChipCmd) & CmdReset);
 	if (debug > 1)
 		printk(KERN_INFO "%s: reset finished after %d microseconds.\n",
-				dev->name, 5*i);
+			   name, 5*i);
 }
 
 static int __devinit via_rhine_init_one (struct pci_dev *pdev,
@@ -515,13 +541,12 @@
 
 	dev = alloc_etherdev(sizeof(*np));
 	if (dev == NULL) {
-		printk (KERN_ERR "init_ethernet failed for card #%d\n",
-			card_idx);
+		printk (KERN_ERR "init_ethernet failed for card #%d\n", card_idx);
 		goto err_out;
 	}
 	SET_MODULE_OWNER(dev);
 	
-	if (pci_request_regions(pdev, "via-rhine"))
+	if (pci_request_regions(pdev, shortname))
 		goto err_out_free_netdev;
 
 #ifndef USE_IO
@@ -534,13 +559,50 @@
 	}
 #endif
 
-	/* Ideally we would read the EEPROM but access may be locked. */
-	for (i = 0; i < 6; i++)
-		dev->dev_addr[i] = readb(ioaddr + StationAddr + i);
+	/* D-Link provided reset code (with comment additions) */
+	if (via_rhine_chip_info[chip_id].drv_flags & HasWOL) {
+		unsigned char byOrgValue;
+
+		/* clear sticky bit before reset & read ethernet address */
+		byOrgValue = readb(ioaddr + StickyHW);
+		byOrgValue = byOrgValue & 0xFC;
+		writeb(byOrgValue, ioaddr + StickyHW);
+
+		/* (bits written are cleared?) */
+		/* disable force PME-enable */
+		writeb(0x80, ioaddr + WOLcgClr);
+		/* disable power-event config bit */
+		writeb(0xFF, ioaddr + WOLcrClr);
+		/* clear power status (undocumented in vt6102 docs?) */
+		writeb(0xFF, ioaddr + PwrcsrClr);
+	}
 
 	/* Reset the chip to erase previous misconfiguration. */
 	writew(CmdReset, ioaddr + ChipCmd);
-	wait_for_reset(dev);
+	wait_for_reset(dev, shortname);
+
+	/* Reload the station address from the EEPROM. */
+	writeb(0x20, ioaddr + MACRegEEcsr);
+	/* Typically 2 cycles to reload. */
+	for (i = 0; i < 150; i++)
+		if (! (readb(ioaddr + MACRegEEcsr) & 0x20))
+			break;
+	for (i = 0; i < 6; i++)
+		dev->dev_addr[i] = readb(ioaddr + StationAddr + i);
+
+	if (!is_valid_ether_addr(dev->dev_addr)) {
+		printk(KERN_ERR "Invalid MAC address for card #%d\n", card_idx);
+		goto err_out_unmap;
+	}
+
+	if (chip_id == VT6102) {
+		/*
+		 * for 3065D, EEPROM reloaded will cause bit 0 in MAC_REG_CFGA
+		 * turned on.  it makes MAC receive magic packet
+		 * automatically. So, we turn it off. (D-Link)
+		 */
+		writeb(readb(ioaddr + ConfigA) & 0xFE, ioaddr + ConfigA);
+	}
 
 	dev->base_addr = ioaddr;
 	dev->irq = pdev->irq;
@@ -563,8 +625,11 @@
 	if (card_idx < MAX_UNITS  &&  full_duplex[card_idx] > 0)
 		np->full_duplex = 1;
 
-	if (np->full_duplex)
+	if (np->full_duplex) {
+		printk(KERN_INFO "%s: Set to forced full duplex, autonegotiation"
+			   " disabled.\n", dev->name);
 		np->duplex_lock = 1;
+	}
 
 	/* The chip-specific entries in the device structure. */
 	dev->open = via_rhine_open;
@@ -611,6 +676,24 @@
 		np->mii_cnt = phy_idx;
 	}
 
+	/* Allow forcing the media type. */
+	if (option > 0) {
+		if (option & 0x220)
+			np->full_duplex = 1;
+		np->default_port = option & 0x3ff;
+		if (np->default_port & 0x330) {
+			/* FIXME: shouldn't someone check this variable? */
+			/* np->medialock = 1; */
+			printk(KERN_INFO "  Forcing %dMbs %s-duplex operation.\n",
+				   (option & 0x300 ? 100 : 10),
+				   (option & 0x220 ? "full" : "half"));
+			if (np->mii_cnt)
+				mdio_write(dev, np->phys[0], 0,
+						   ((option & 0x300) ? 0x2000 : 0) |  /* 100mbps? */
+						   ((option & 0x220) ? 0x0100 : 0));  /* Full duplex? */
+		}
+	}
+
 	return 0;
 
 err_out_unmap:
@@ -890,7 +973,7 @@
 		return i;
 	alloc_rbufs(dev);
 	alloc_tbufs(dev);
-	wait_for_reset(dev);
+	wait_for_reset(dev, dev->name);
 	init_registers(dev);
 	if (debug > 2)
 		printk(KERN_DEBUG "%s: Done via_rhine_open(), status %4.4x "
@@ -997,7 +1080,7 @@
 	alloc_rbufs(dev);
 
 	/* Reinitialize the hardware. */
-	wait_for_reset(dev);
+	wait_for_reset(dev, dev->name);
 	init_registers(dev);
 	
 	spin_unlock(&np->lock);
@@ -1388,7 +1471,9 @@
 		memset(mc_filter, 0, sizeof(mc_filter));
 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
 			 i++, mclist = mclist->next) {
-			set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26, mc_filter);
+			int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
+
+			mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
 		}
 		writel(mc_filter[0], ioaddr + MulticastFilter0);
 		writel(mc_filter[1], ioaddr + MulticastFilter1);
@@ -1445,7 +1530,7 @@
 			   dev->name, readw(ioaddr + ChipCmd));
 
 	/* Switch to loopback mode to avoid hardware races. */
-	writeb(np->tx_thresh | 0x01, ioaddr + TxConfig);
+	writeb(np->tx_thresh | 0x02, ioaddr + TxConfig);
 
 	/* Disable interrupts by clearing the interrupt mask. */
 	writew(0x0000, ioaddr + IntrEnable);
diff -u --recursive --new-file v2.4.5/linux/drivers/net/wan/comx-hw-mixcom.c linux/drivers/net/wan/comx-hw-mixcom.c
--- v2.4.5/linux/drivers/net/wan/comx-hw-mixcom.c	Mon Dec 11 13:38:29 2000
+++ linux/drivers/net/wan/comx-hw-mixcom.c	Wed Jun 27 17:10:55 2001
@@ -487,15 +487,18 @@
 	struct mixcom_privdata *hw = ch->HW_privdata;
 	struct proc_dir_entry *procfile = ch->procdir->subdir;
 	unsigned long flags; 
+	int ret = -ENODEV;
 
-	if (!dev->base_addr || !dev->irq) return -ENODEV;
+	if (!dev->base_addr || !dev->irq)
+		goto err_ret;
 
 
 	if(hw->channel==1) {
 		if(!TWIN(dev) || !(COMX_CHANNEL(TWIN(dev))->init_status & 
 		    IRQ_ALLOCATED)) {
 			printk(KERN_ERR "%s: channel 0 not yet initialized\n",dev->name);
-			return -EAGAIN;
+			ret = -EAGAIN;
+			goto err_ret;
 		}
 	}
 
@@ -503,28 +506,29 @@
 	/* Is our hw present at all ? Not checking for channel 0 if it is already 
 	   open */
 	if(hw->channel!=0 || !(ch->init_status & IRQ_ALLOCATED)) {
-		if (check_region(dev->base_addr, MIXCOM_IO_EXTENT)) {
-			return -EAGAIN;
+		if (!request_region(dev->base_addr, MIXCOM_IO_EXTENT, dev->name)) {
+			ret = -EAGAIN;
+			goto err_ret;
 		}
 		if (mixcom_probe(dev)) {
-			return -ENODEV;
+			ret = -ENODEV;
+			goto err_release_region;
 		}
 	}
 
-	save_flags(flags); cli();
-
-	if(hw->channel==1) {
-		request_region(dev->base_addr, MIXCOM_IO_EXTENT, dev->name);
-	} 
-
 	if(hw->channel==0 && !(ch->init_status & IRQ_ALLOCATED)) {
 		if (request_irq(dev->irq, MIXCOM_interrupt, 0, 
 		    dev->name, (void *)dev)) {
 			printk(KERN_ERR "MIXCOM: unable to obtain irq %d\n", dev->irq);
-			return -EAGAIN;
+			ret = -EAGAIN;
+			goto err_release_region;
 		}
+	}
+
+	save_flags(flags); cli();
+
+	if(hw->channel==0 && !(ch->init_status & IRQ_ALLOCATED)) {
 		ch->init_status|=IRQ_ALLOCATED;
-		request_region(dev->base_addr, MIXCOM_IO_EXTENT, dev->name);
 		mixcom_board_on(dev);
 	}
 
@@ -560,6 +564,13 @@
 	}
 
 	return 0;
+	
+err_restore_flags:
+	restore_flags(flags);
+err_release_region:
+	release_region(dev->base_addr, MIXCOM_IO_EXTENT);
+err_ret:
+	return ret;
 }
 
 static int MIXCOM_close(struct net_device *dev)
diff -u --recursive --new-file v2.4.5/linux/drivers/net/wan/comx-proto-fr.c linux/drivers/net/wan/comx-proto-fr.c
--- v2.4.5/linux/drivers/net/wan/comx-proto-fr.c	Sat Mar  3 10:55:48 2001
+++ linux/drivers/net/wan/comx-proto-fr.c	Wed Jun 27 17:10:55 2001
@@ -503,6 +503,8 @@
 
 	if (dev != fr->master) {
 		struct sk_buff *newskb=skb_clone(skb, GFP_ATOMIC);
+		if (!newskb)
+			return -ENOMEM;
 		newskb->dev=fr->master;
 		dev_queue_xmit(newskb);
 		ch->stats.tx_bytes += skb->len;
@@ -701,7 +703,7 @@
 	} else {
 		printk(KERN_ERR "comxfr_write_proc: internal error, filename %s\n", 
 			entry->name);
-		return -EBADF;
+		count = -EBADF;
 	}
 
 	free_page((unsigned long)page);
@@ -960,30 +962,27 @@
 }
 
 static struct comx_protocol fr_master_protocol = {
-	"frad", 
-	VERSION,
-	ARPHRD_FRAD, 
-	fr_master_init, 
-	fr_exit, 
-	NULL 
+	name:		"frad", 
+	version:	VERSION,
+	encap_type:	ARPHRD_FRAD, 
+	line_init:	fr_master_init, 
+	line_exit:	fr_exit, 
 };
 
 static struct comx_protocol fr_slave_protocol = {
-	"ietf-ip", 
-	VERSION,
-	ARPHRD_DLCI, 
-	fr_slave_init, 
-	fr_exit, 
-	NULL 
+	name:		"ietf-ip", 
+	version:	VERSION,
+	encap_type:	ARPHRD_DLCI, 
+	line_init:	fr_slave_init, 
+	line_exit:	fr_exit, 
 };
 
 static struct comx_hardware fr_dlci = { 
-	"dlci", 
-	VERSION,
-	dlci_init, 
-	dlci_exit, 
-	dlci_dump, 
-	NULL 
+	name:		"dlci", 
+	version:	VERSION,
+	hw_init:	dlci_init, 
+	hw_exit:	dlci_exit, 
+	hw_dump:	dlci_dump, 
 };
 
 #ifdef MODULE
diff -u --recursive --new-file v2.4.5/linux/drivers/net/wan/cosa.c linux/drivers/net/wan/cosa.c
--- v2.4.5/linux/drivers/net/wan/cosa.c	Tue Mar  6 19:44:36 2001
+++ linux/drivers/net/wan/cosa.c	Wed Jun 27 17:10:55 2001
@@ -1046,15 +1046,15 @@
 	    __get_user(code, &(d->code)))
 		return -EFAULT;
 
-	if (d->addr < 0 || d->addr > COSA_MAX_FIRMWARE_SIZE)
+	if (addr < 0 || addr > COSA_MAX_FIRMWARE_SIZE)
 		return -EINVAL;
-	if (d->len < 0 || d->len > COSA_MAX_FIRMWARE_SIZE)
+	if (len < 0 || len > COSA_MAX_FIRMWARE_SIZE)
 		return -EINVAL;
 
 	/* If something fails, force the user to reset the card */
 	cosa->firmware_status &= ~(COSA_FW_RESET|COSA_FW_DOWNLOAD);
 
-	if ((i=download(cosa, d->code, len, addr)) < 0) {
+	if ((i=download(cosa, code, len, addr)) < 0) {
 		printk(KERN_NOTICE "cosa%d: microcode download failed: %d\n",
 			cosa->num, i);
 		return -EIO;
diff -u --recursive --new-file v2.4.5/linux/drivers/net/wan/hdlc.c linux/drivers/net/wan/hdlc.c
--- v2.4.5/linux/drivers/net/wan/hdlc.c	Wed Apr 18 14:40:07 2001
+++ linux/drivers/net/wan/hdlc.c	Tue Jun 12 11:06:54 2001
@@ -1082,7 +1082,9 @@
 			}
 			break;
 
-		default:		/* to be defined */
+		default:
+			/* to be defined */
+			break;
 		}
 
 		dev_kfree_skb(skb);
diff -u --recursive --new-file v2.4.5/linux/drivers/net/wan/lapbether.c linux/drivers/net/wan/lapbether.c
--- v2.4.5/linux/drivers/net/wan/lapbether.c	Wed Apr 18 14:40:07 2001
+++ linux/drivers/net/wan/lapbether.c	Wed Jun 27 17:10:55 2001
@@ -89,7 +89,7 @@
  */
 static int lapbeth_check_devices(struct net_device *dev)
 {
-	struct lapbethdev *lapbeth, *lapbeth_prev;
+	struct lapbethdev *lapbeth, *lapbeth_prev, *lapbeth_next;
 	int result = 0;
 	unsigned long flags;
 
@@ -98,7 +98,8 @@
 
 	lapbeth_prev = NULL;
 
-	for (lapbeth = lapbeth_devices; lapbeth != NULL; lapbeth = lapbeth->next) {
+	for (lapbeth = lapbeth_devices; lapbeth != NULL; lapbeth = lapbeth_next) {
+		lapbeth_next = lapbeth->next;
 		if (!dev_get(lapbeth->ethname)) {
 			if (lapbeth_prev)
 				lapbeth_prev->next = lapbeth->next;
@@ -112,8 +113,8 @@
 			dev_put(lapbeth->ethdev);
 			kfree(lapbeth);
 		}
-
-		lapbeth_prev = lapbeth;
+		else
+			lapbeth_prev = lapbeth;
 	}
 
 	restore_flags(flags);
diff -u --recursive --new-file v2.4.5/linux/drivers/net/wan/lmc/lmc_main.c linux/drivers/net/wan/lmc/lmc_main.c
--- v2.4.5/linux/drivers/net/wan/lmc/lmc_main.c	Sun Mar 25 18:24:31 2001
+++ linux/drivers/net/wan/lmc/lmc_main.c	Wed Jun 27 17:10:55 2001
@@ -507,7 +507,12 @@
                             break;
                     }
                     
-                    LMC_COPY_FROM_USER(data, xc.data, xc.len);
+                    if(copy_from_user(data, xc.data, xc.len))
+                    {
+                    	kfree(data);
+                    	ret = -ENOMEM;
+                    	break;
+                    }
 
                     printk("%s: Starting load of data Len: %d at 0x%p == 0x%p\n", dev->name, xc.len, xc.data, data);
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/wan/sdla_fr.c linux/drivers/net/wan/sdla_fr.c
--- v2.4.5/linux/drivers/net/wan/sdla_fr.c	Fri Apr 20 11:54:22 2001
+++ linux/drivers/net/wan/sdla_fr.c	Tue Jun 12 11:06:54 2001
@@ -4435,7 +4435,8 @@
 		trigger_fr_poll(dev);
 		
 		break;
-	default:  // ARP's and RARP's -- Shouldn't happen.
+	default:
+		break; // ARP's and RARP's -- Shouldn't happen.
 	}
 
 	return 0;	
diff -u --recursive --new-file v2.4.5/linux/drivers/net/wan/sdla_x25.c linux/drivers/net/wan/sdla_x25.c
--- v2.4.5/linux/drivers/net/wan/sdla_x25.c	Fri Apr 20 11:54:22 2001
+++ linux/drivers/net/wan/sdla_x25.c	Tue Jun 12 11:06:54 2001
@@ -3108,7 +3108,7 @@
 	case 0x08:	/* modem failure */
 #ifndef MODEM_NOT_LOG
 		printk(KERN_INFO "%s: modem failure!\n", card->devname);
-#endif MODEM_NOT_LOG
+#endif /* MODEM_NOT_LOG */
 		api_oob_event(card,mb);
 		break;
 
diff -u --recursive --new-file v2.4.5/linux/drivers/net/wan/syncppp.c linux/drivers/net/wan/syncppp.c
--- v2.4.5/linux/drivers/net/wan/syncppp.c	Tue May 22 10:23:16 2001
+++ linux/drivers/net/wan/syncppp.c	Wed Jun 27 17:10:55 2001
@@ -147,7 +147,7 @@
 static char *sppp_ipcp_type_name (u8 type);
 static void sppp_print_bytes (u8 *p, u16 len);
 
-static int debug = 0;
+static int debug;
 
 
 /*
@@ -518,8 +518,10 @@
 		}
 		/* Send Configure-Ack packet. */
 		sp->pp_loopcnt = 0;
-		sppp_cp_send (sp, PPP_LCP, LCP_CONF_ACK,
-				h->ident, len-4, h+1);
+		if (sp->lcp.state != LCP_STATE_OPENED) {
+			sppp_cp_send (sp, PPP_LCP, LCP_CONF_ACK,
+					h->ident, len-4, h+1);
+		}
 		/* Change the state. */
 		switch (sp->lcp.state) {
 		case LCP_STATE_CLOSED:
@@ -535,7 +537,9 @@
 			sp->ipcp.state = IPCP_STATE_CLOSED;
 			/* Initiate renegotiation. */
 			sppp_lcp_open (sp);
-			/* An ACK has already been sent. */
+			/* Send ACK after our REQ in attempt to break loop */
+			sppp_cp_send (sp, PPP_LCP, LCP_CONF_ACK,
+					h->ident, len-4, h+1);
 			sp->lcp.state = LCP_STATE_ACK_SENT;
 			break;
 		}
@@ -1388,25 +1392,21 @@
 	return 0;
 }
 
-
-struct packet_type sppp_packet_type=
-{
-	0,
-	NULL,
-	sppp_rcv,
-	NULL,
-	NULL
+struct packet_type sppp_packet_type = {
+	type:	__constant_htons(ETH_P_WAN_PPP),
+	func:	sppp_rcv,
 };
 
-
+static const char banner[] __initdata = 
+	KERN_INFO "Cronyx Ltd, Synchronous PPP and CISCO HDLC (c) 1994\n"
+	KERN_INFO "Linux port (c) 1998 Building Number Three Ltd & "
+		  "Jan \"Yenya\" Kasprzak.\n";
 
 static int __init sync_ppp_init(void)
 {
 	if(debug)
 		debug=PP_DEBUG;
-	printk(KERN_INFO "Cronyx Ltd, Synchronous PPP and CISCO HDLC (c) 1994\n");
-	printk(KERN_INFO "Linux port (c) 1998 Building Number Three Ltd & Jan \"Yenya\" Kasprzak.\n");
-	sppp_packet_type.type=htons(ETH_P_WAN_PPP);	
+	printk(banner);
 	dev_add_pack(&sppp_packet_type);
 	return 0;
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/net/wd.c linux/drivers/net/wd.c
--- v2.4.5/linux/drivers/net/wd.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/wd.c	Wed Jun 20 11:10:53 2001
@@ -449,6 +449,10 @@
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_WD_CARDS) "i");
 MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_WD_CARDS) "i");
 MODULE_PARM(mem_end, "1-" __MODULE_STRING(MAX_WD_CARDS) "i");
+MODULE_PARM_DESC(io, "WD80x3 I/O base address(es)");
+MODULE_PARM_DESC(irq, "WD80x3 IRQ number(s) (ignored for PureData boards)");
+MODULE_PARM_DESC(mem, "WD80x3 memory base address(es)(ignored for PureData boards)");
+MODULE_PARM_DESC(mem_end, "WD80x3 memory end address(es)");
 
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
diff -u --recursive --new-file v2.4.5/linux/drivers/net/winbond-840.c linux/drivers/net/winbond-840.c
--- v2.4.5/linux/drivers/net/winbond-840.c	Fri Apr 20 11:54:23 2001
+++ linux/drivers/net/winbond-840.c	Thu Jun 21 14:28:39 2001
@@ -1,4 +1,4 @@
-/* winbond-840.c: A Linux PCI network adapter skeleton device driver. */
+/* winbond-840.c: A Linux PCI network adapter device driver. */
 /*
 	Written 1998-2001 by Donald Becker.
 
@@ -38,6 +38,11 @@
 		descriptors. Remove cpu_to_le32, enable BE descriptors.
 */
 
+#define DRV_NAME	"winbond-840"
+#define DRV_VERSION	"1.01"
+#define DRV_RELDATE	"5/15/2000"
+
+
 /* Automatically extracted configuration info:
 probe-func: winbond840_probe
 config-in: tristate 'Winbond W89c840 Ethernet support' CONFIG_WINBOND_840
@@ -122,13 +127,15 @@
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/ethtool.h>
+#include <asm/uaccess.h>
 #include <asm/processor.h>		/* Processor type for cache alignment. */
 #include <asm/bitops.h>
 #include <asm/io.h>
 
 /* These identify the driver base version and may not be removed. */
 static char version[] __devinitdata =
-KERN_INFO "winbond-840.c:v1.01 (2.4 port) 5/15/2000  Donald Becker <becker@scyld.com>\n"
+KERN_INFO DRV_NAME ".c:v" DRV_VERSION " (2.4 port) " DRV_RELDATE "  Donald Becker <becker@scyld.com>\n"
 KERN_INFO "  http://www.scyld.com/network/drivers.html\n";
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
@@ -139,6 +146,12 @@
 MODULE_PARM(multicast_filter_limit, "i");
 MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM_DESC(max_interrupt_work, "winbond-840 maximum events handled per interrupt");
+MODULE_PARM_DESC(debug, "winbond-840 debug level (0-6)");
+MODULE_PARM_DESC(rx_copybreak, "winbond-840 copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(multicast_filter_limit, "winbond-840 maximum number of filtered multicast addresses");
+MODULE_PARM_DESC(options, "winbond-840: Bits 0-3: media type, bit 17: full duplex");
+MODULE_PARM_DESC(full_duplex, "winbond-840 full duplex setting(s) (1)");
 
 /*
 				Theory of Operation
@@ -366,7 +379,7 @@
 static inline unsigned ether_crc(int length, unsigned char *data);
 static void set_rx_mode(struct net_device *dev);
 static struct net_device_stats *get_stats(struct net_device *dev);
-static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static int  netdev_close(struct net_device *dev);
 
 
@@ -399,7 +412,7 @@
 		return -ENOMEM;
 	SET_MODULE_OWNER(dev);
 
-	if (pci_request_regions(pdev, "winbond-840"))
+	if (pci_request_regions(pdev, DRV_NAME))
 		goto err_out_netdev;
 
 #ifdef USE_IO_OPS
@@ -453,7 +466,7 @@
 	dev->stop = &netdev_close;
 	dev->get_stats = &get_stats;
 	dev->set_multicast_list = &set_rx_mode;
-	dev->do_ioctl = &mii_ioctl;
+	dev->do_ioctl = &netdev_ioctl;
 	dev->tx_timeout = &tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
@@ -826,7 +839,7 @@
 		C000	32  longwords		0400 4 longwords
 	   Wait the specified 50 PCI cycles after a reset by initializing
 	   Tx and Rx queues and the address filter list. */
-#if defined(__powerpc__)		/* Big-endian */
+#if defined(__powerpc__) || defined(__sparc__)		/* Big-endian */
 	writel(0x00100080 | 0xE010, ioaddr + PCIBusCfg);
 #elif defined(__alpha__)
 	writel(0xE010, ioaddr + PCIBusCfg);
@@ -871,13 +884,12 @@
 	printk(KERN_WARNING "%s: Transmit timed out, status %8.8x,"
 		   " resetting...\n", dev->name, (int)readl(ioaddr + IntrStatus));
 
-#ifndef __alpha__
 	{
 		int i;
-		printk(KERN_DEBUG "  Rx ring %8.8x: ", (int)np->rx_ring);
+		printk(KERN_DEBUG "  Rx ring %p: ", np->rx_ring);
 		for (i = 0; i < RX_RING_SIZE; i++)
 			printk(" %8.8x", (unsigned int)np->rx_ring[i].status);
-		printk("\n"KERN_DEBUG"  Tx ring %8.8x: ", (int)np->tx_ring);
+		printk("\n"KERN_DEBUG"  Tx ring %p: ", np->tx_ring);
 		for (i = 0; i < TX_RING_SIZE; i++)
 			printk(" %8.8x", np->tx_ring[i].status);
 		printk("\n");
@@ -886,7 +898,6 @@
 				np->cur_tx, np->dirty_tx, np->tx_full,np->tx_q_bytes);
 	printk(KERN_DEBUG "Tx Descriptor addr %xh.\n",readl(ioaddr+0x4C));
 
-#endif
 	spin_lock_irq(&np->lock);
 	/*
 	 * Under high load dirty_tx and the internal tx descriptor pointer
@@ -1312,11 +1323,37 @@
 	writel(np->csr6, ioaddr + NetworkConfig);
 }
 
-static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+{
+	struct netdev_private *np = dev->priv;
+	u32 ethcmd;
+		
+	if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
+		return -EFAULT;
+
+        switch (ethcmd) {
+        case ETHTOOL_GDRVINFO: {
+		struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
+		strcpy(info.driver, DRV_NAME);
+		strcpy(info.version, DRV_VERSION);
+		strcpy(info.bus_info, np->pci_dev->slot_name);
+		if (copy_to_user(useraddr, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+
+        }
+	
+	return -EOPNOTSUPP;
+}
+
+static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	u16 *data = (u16 *)&rq->ifr_data;
 
 	switch(cmd) {
+	case SIOCETHTOOL:
+		return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
 	case SIOCDEVPRIVATE:		/* Get the address of the PHY in use. */
 		data[0] = ((struct netdev_private *)dev->priv)->phys[0] & 0x1f;
 		/* Fall Through */
@@ -1337,7 +1374,6 @@
 {
 	long ioaddr = dev->base_addr;
 	struct netdev_private *np = dev->priv;
-	int i;
 
 	netif_stop_queue(dev);
 
@@ -1360,6 +1396,8 @@
 
 #ifdef __i386__
 	if (debug > 2) {
+		int i;
+
 		printk("\n"KERN_DEBUG"  Tx ring at %8.8x:\n",
 			   (int)np->tx_ring);
 		for (i = 0; i < TX_RING_SIZE; i++)
@@ -1403,7 +1441,7 @@
 }
 
 static struct pci_driver w840_driver = {
-	name:		"winbond-840",
+	name:		DRV_NAME,
 	id_table:	w840_pci_tbl,
 	probe:		w840_probe1,
 	remove:		w840_remove1,
diff -u --recursive --new-file v2.4.5/linux/drivers/net/wireless/Config.in linux/drivers/net/wireless/Config.in
--- v2.4.5/linux/drivers/net/wireless/Config.in	Mon May  7 19:42:14 2001
+++ linux/drivers/net/wireless/Config.in	Wed Jun 20 11:13:18 2001
@@ -2,21 +2,26 @@
 # Wireless LAN device configuration
 #
 
-###tristate '  Hermes chipset support' CONFIG_NET_ORINOCO
-###dep_tristate '    PCMCIA Hermes support (Orinoco/WavelanIEEE/PrismII/Symbol 802.11b cards)' CONFIG_PCMCIA_HERMES $CONFIG_NET_ORINOCO $CONFIG_PCMCIA
+if [ "$CONFIG_ISA" = "y" -o "$CONFIG_PCI" = "y" ]; then
+   tristate '  Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards' CONFIG_AIRO
+fi
 
 if [ "$CONFIG_ALL_PPC" = "y" ]; then
    tristate '  Apple Airport support (built-in)' CONFIG_APPLE_AIRPORT
 fi
 
 # If Pcmcia is compiled in, offer Pcmcia cards...
-if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then
+if [ "$CONFIG_PCMCIA" != "n" ]; then
    comment 'Wireless Pcmcia cards support' 
 
-   dep_tristate '  Hermes support (Orinoco/WavelanIEEE/PrismII/Symbol 802.11b cards)' CONFIG_PCMCIA_HERMES $CONFIG_PCMCIA
+   tristate '  Hermes support (Orinoco/WavelanIEEE/PrismII/Symbol 802.11b cards)' CONFIG_PCMCIA_HERMES
+   tristate '  Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards' CONFIG_AIRO_CS
+fi
 
-# If one of the Pcmcia cards above is enabled, activate Pcmcia network support
-   if [ "$CONFIG_PCMCIA_HERMES" = "y" ]; then
-      define_bool CONFIG_PCMCIA_NETCARD y
-   fi
+# yes, this works even when no drivers are selected
+if [ "$CONFIG_ISA" = "y" -o "$CONFIG_PCI" = "y" -o \
+     "$CONFIG_ALL_PPC" = "y" -o "$CONFIG_PCMCIA" != "n" ]; then
+   define_bool CONFIG_NET_WIRELESS y
+else
+   define_bool CONFIG_NET_WIRELESS n
 fi
diff -u --recursive --new-file v2.4.5/linux/drivers/net/wireless/Makefile linux/drivers/net/wireless/Makefile
--- v2.4.5/linux/drivers/net/wireless/Makefile	Mon May  7 19:42:14 2001
+++ linux/drivers/net/wireless/Makefile	Wed Jun 20 11:13:18 2001
@@ -4,7 +4,7 @@
 # Makefile for the Linux Wireless network device drivers.
 #
 
-O_TARGET := orinoco_drvs.o
+O_TARGET := wireless_net.o
 
 obj-y		:=
 obj-m		:=
@@ -12,16 +12,12 @@
 obj-		:=
 
 # Things that need to export symbols
-export-objs	:= orinoco.o hermes.o
+export-objs	:= airo.o orinoco.o hermes.o
 
-# ISA Bus cards
-
-# PCI bus cards
-
-# Other cards
+obj-$(CONFIG_PCMCIA_HERMES)	+= orinoco_cs.o orinoco.o hermes.o
 obj-$(CONFIG_APPLE_AIRPORT)	+= airport.o orinoco.o hermes.o
 
-# 16-bit Pcmcia wireless client drivers
-obj-$(CONFIG_PCMCIA_HERMES)	+= orinoco_cs.o orinoco.o hermes.o
+obj-$(CONFIG_AIRO)		+= airo.o
+obj-$(CONFIG_AIRO_CS)		+= airo_cs.o airo.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/drivers/net/wireless/airo.c linux/drivers/net/wireless/airo.c
--- v2.4.5/linux/drivers/net/wireless/airo.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/wireless/airo.c	Wed Jun 20 11:10:53 2001
@@ -0,0 +1,4321 @@
+/*======================================================================
+
+    Aironet driver for 4500 and 4800 series cards
+
+    This code is released under both the GPL version 2 and BSD licenses.
+    Either license may be used.  The respective licenses are found at
+    the end of this file.
+
+    This code was developed by Benjamin Reed <breed@users.sourceforge.net>
+    including portions of which come from the Aironet PC4500
+    Developer's Reference Manual and used with permission.  Copyright
+    (C) 1999 Benjamin Reed.  All Rights Reserved.  Permission to use
+    code in the Developer's manual was granted for this driver by
+    Aironet.  Major code contributions were received from Javier Achirica
+    and Jean Tourrilhes <jt@hpl.hp.com>.  Code was also integrated from
+    the Cisco Aironet driver for Linux.
+    
+======================================================================*/
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <asm/segment.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/malloc.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/in.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/ioport.h>
+#include <linux/config.h>
+#include <linux/pci.h>
+
+#ifdef CONFIG_PCI
+static struct pci_device_id card_ids[] = __devinitdata {
+	{ 0x14b9, 1, PCI_ANY_ID, PCI_ANY_ID, },
+	{ 0x14b9, 0x4500, PCI_ANY_ID, PCI_ANY_ID },
+	{ 0x14b9, 0x4800, PCI_ANY_ID, PCI_ANY_ID, },
+	{ 0x14b9, 0x0340, PCI_ANY_ID, PCI_ANY_ID, },
+	{ 0x14b9, 0x0350, PCI_ANY_ID, PCI_ANY_ID, },
+	{ 0, } 
+};
+MODULE_DEVICE_TABLE(pci, card_ids);
+
+static int airo_pci_probe(struct pci_dev *, const struct pci_device_id *);
+static void airo_pci_remove(struct pci_dev *);
+
+static struct pci_driver airo_driver = {
+	name:     "airo",
+	id_table: card_ids,
+	probe:    airo_pci_probe,
+	remove:   airo_pci_remove,
+};
+#endif /* CONFIG_PCI */
+
+/* Include Wireless Extension definition and check version - Jean II */
+#include <linux/wireless.h>
+#if WIRELESS_EXT < 9
+#warning "Wireless extension v9 or newer required - please upgrade your kernel"
+#undef WIRELESS_EXT
+#endif
+#define WIRELESS_SPY		// enable iwspy support
+#define CISCO_EXT		// enable Cisco extensions
+
+#ifdef CISCO_EXT
+#include <linux/delay.h>
+#endif
+
+/* As you can see this list is HUGH!
+   I really don't know what a lot of these counts are about, but they
+   are all here for completeness.  If the IGNLABEL macro is put in
+   infront of the label, that statistic will not be included in the list
+   of statistics in the /proc filesystem */
+
+#define IGNLABEL 0&(int)
+static char *statsLabels[] = {
+	"RxOverrun",
+	IGNLABEL "RxPlcpCrcErr",
+	IGNLABEL "RxPlcpFormatErr",
+	IGNLABEL "RxPlcpLengthErr",
+	"RxMacCrcErr",
+	"RxMacCrcOk",
+	"RxWepErr",
+	"RxWepOk",
+	"RetryLong",
+	"RetryShort",
+	"MaxRetries",
+	"NoAck",
+	"NoCts",
+	"RxAck",
+	"RxCts",
+	"TxAck",
+	"TxRts",
+	"TxCts",
+	"TxMc",
+	"TxBc",
+	"TxUcFrags",
+	"TxUcPackets",
+	"TxBeacon",
+	"RxBeacon",
+	"TxSinColl",
+	"TxMulColl",
+	"DefersNo",
+	"DefersProt",
+	"DefersEngy",
+	"DupFram",
+	"RxFragDisc",
+	"TxAged",
+	"RxAged",
+	"LostSync-MaxRetry",
+	"LostSync-MissedBeacons",
+	"LostSync-ArlExceeded",
+	"LostSync-Deauth",
+	"LostSync-Disassoced",
+	"LostSync-TsfTiming",
+	"HostTxMc",
+	"HostTxBc",
+	"HostTxUc",
+	"HostTxFail",
+	"HostRxMc",
+	"HostRxBc",
+	"HostRxUc",
+	"HostRxDiscard",
+	IGNLABEL "HmacTxMc",
+	IGNLABEL "HmacTxBc",
+	IGNLABEL "HmacTxUc",
+	IGNLABEL "HmacTxFail",
+	IGNLABEL "HmacRxMc",
+	IGNLABEL "HmacRxBc",
+	IGNLABEL "HmacRxUc",
+	IGNLABEL "HmacRxDiscard",
+	IGNLABEL "HmacRxAccepted",
+	"SsidMismatch",
+	"ApMismatch",
+	"RatesMismatch",
+	"AuthReject",
+	"AuthTimeout",
+	"AssocReject",
+	"AssocTimeout",
+	IGNLABEL "ReasonOutsideTable",
+	IGNLABEL "ReasonStatus1",
+	IGNLABEL "ReasonStatus2",
+	IGNLABEL "ReasonStatus3",
+	IGNLABEL "ReasonStatus4",
+	IGNLABEL "ReasonStatus5",
+	IGNLABEL "ReasonStatus6",
+	IGNLABEL "ReasonStatus7",
+	IGNLABEL "ReasonStatus8",
+	IGNLABEL "ReasonStatus9",
+	IGNLABEL "ReasonStatus10",
+	IGNLABEL "ReasonStatus11",
+	IGNLABEL "ReasonStatus12",
+	IGNLABEL "ReasonStatus13",
+	IGNLABEL "ReasonStatus14",
+	IGNLABEL "ReasonStatus15",
+	IGNLABEL "ReasonStatus16",
+	IGNLABEL "ReasonStatus17",
+	IGNLABEL "ReasonStatus18",
+	IGNLABEL "ReasonStatus19",
+	"RxMan",
+	"TxMan",
+	"RxRefresh",
+	"TxRefresh",
+	"RxPoll",
+	"TxPoll",
+	"HostRetries",
+	"LostSync-HostReq",
+	"HostTxBytes",
+	"HostRxBytes",
+	"ElapsedUsec",
+	"ElapsedSec",
+	"LostSyncBetterAP",
+	"PrivacyMismatch",
+	"Jammed",
+	"DiscRxNotWepped",
+	"PhyEleMismatch",
+	(char*)-1 };
+#ifndef RUN_AT
+#define RUN_AT(x) (jiffies+(x))
+#endif
+
+
+/* These variables are for insmod, since it seems that the rates
+   can only be set in setup_card.  Rates should be a comma separated
+   (no spaces) list of rates (up to 8). */
+
+static int rates[8];
+static int basic_rate;
+static char *ssids[3];
+
+static int io[4];
+static int irq[4];
+
+static
+int maxencrypt /* = 0 */; /* The highest rate that the card can encrypt at.
+		       0 means no limit.  For old cards this was 4 */
+
+static int auto_wep /* = 0 */; /* If set, it tries to figure out the wep mode */
+static int aux_bap /* = 0 */; /* Checks to see if the aux ports are needed to read
+		    the bap, needed on some older cards and buses. */   
+static int adhoc;
+
+static int proc_uid /* = 0 */;
+
+static int proc_gid /* = 0 */;
+
+static int airo_perm = 0555;
+
+static int proc_perm = 0644;
+
+MODULE_AUTHOR("Benjamin Reed");
+MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet \
+                   cards.  Direct support for ISA/PCI cards and support \
+		   for PCMCIA when used with airo_cs.");
+MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340");
+MODULE_PARM(io,"1-4i");
+MODULE_PARM(irq,"1-4i");
+MODULE_PARM(basic_rate,"i");
+MODULE_PARM(rates,"1-8i");
+MODULE_PARM(ssids,"1-3s");
+MODULE_PARM(auto_wep,"i");
+MODULE_PARM_DESC(auto_wep, "If non-zero, the driver will keep looping through \
+the authentication options until an association is made.  The value of \
+auto_wep is number of the wep keys to check.  A value of 2 will try using \
+the key at index 0 and index 1.");
+MODULE_PARM(aux_bap,"i");
+MODULE_PARM_DESC(aux_bap, "If non-zero, the driver will switch into a mode \
+than seems to work better for older cards with some older buses.  Before \
+switching it checks that the switch is needed.");
+MODULE_PARM(maxencrypt, "i");
+MODULE_PARM_DESC(maxencrypt, "The maximum speed that the card can do \
+encryption.  Units are in 512kbs.  Zero (default) means there is no limit. \
+Older cards used to be limited to 2mbs (4).");
+MODULE_PARM(adhoc, "i");
+MODULE_PARM_DESC(adhoc, "If non-zero, the card will start in adhoc mode.");
+
+MODULE_PARM(proc_uid, "i");
+MODULE_PARM_DESC(proc_uid, "The uid that the /proc files will belong to.");
+MODULE_PARM(proc_gid, "i");
+MODULE_PARM_DESC(proc_gid, "The gid that the /proc files will belong to.");
+MODULE_PARM(airo_perm, "i");
+MODULE_PARM_DESC(airo_perm, "The permission bits of /proc/[driver/]aironet.");
+MODULE_PARM(proc_perm, "i");
+MODULE_PARM_DESC(proc_perm, "The permission bits of the files in /proc");
+
+#include <asm/uaccess.h>
+
+#define min(x,y) ((x<y)?x:y)
+
+/* This is a kind of sloppy hack to get this information to OUT4500 and
+   IN4500.  I would be extremely interested in the situation where this
+   doesnt work though!!! */
+static int do8bitIO = 0;
+
+/* Return codes */
+#define SUCCESS 0
+#define ERROR -1
+#define NO_PACKET -2
+
+/* Commands */
+#define NOP 0x0010
+#define MAC_ENABLE 0x0001
+#define MAC_DISABLE 0x0002
+#define CMD_ACCESS 0x0021
+#define CMD_ALLOCATETX 0x000a
+#define CMD_TRANSMIT 0x000b
+#define HOSTSLEEP 0x85
+#define CMD_SETMODE 0x0009
+#define CMD_ENABLEAUX 0x0111
+#define CMD_SOFTRESET 0x0004
+
+/* Registers */
+#define COMMAND 0x00
+#define PARAM0 0x02
+#define PARAM1 0x04
+#define PARAM2 0x06
+#define STATUS 0x08
+#define RESP0 0x0a
+#define RESP1 0x0c
+#define RESP2 0x0e
+#define LINKSTAT 0x10
+#define SELECT0 0x18
+#define OFFSET0 0x1c
+#define RXFID 0x20
+#define TXALLOCFID 0x22
+#define TXCOMPLFID 0x24
+#define DATA0 0x36
+#define EVSTAT 0x30
+#define EVINTEN 0x32
+#define EVACK 0x34
+#define SWS0 0x28
+#define SWS1 0x2a
+#define SWS2 0x2c
+#define SWS3 0x2e
+#define AUXPAGE 0x3A
+#define AUXOFF 0x3C
+#define AUXDATA 0x3E
+
+/* BAP selectors */
+#define BAP0 0 // Used for receiving packets
+#define BAP1 2 // Used for xmiting packets and working with RIDS
+
+/* Flags */
+#define COMMAND_BUSY 0x8000
+
+#define BAP_BUSY 0x8000
+#define BAP_ERR 0x4000
+#define BAP_DONE 0x2000
+
+#define PROMISC 0xffff
+#define NOPROMISC 0x0000
+
+#define EV_CMD 0x10
+#define EV_CLEARCOMMANDBUSY 0x4000
+#define EV_RX 0x01
+#define EV_TX 0x02
+#define EV_TXEXC 0x04
+#define EV_ALLOC 0x08
+#define EV_LINK 0x80
+#define EV_AWAKE 0x100
+#define EV_UNKNOWN 0x800
+#define STATUS_INTS ( EV_AWAKE | EV_LINK | EV_TXEXC | EV_TX | EV_RX | EV_UNKNOWN)
+
+/* The RIDs */
+#define RID_CAPABILITIES 0xFF00
+#define RID_CONFIG     0xFF10
+#define RID_SSID       0xFF11
+#define RID_APLIST     0xFF12
+#define RID_DRVNAME    0xFF13
+#define RID_ETHERENCAP 0xFF14
+#define RID_WEP_TEMP   0xFF15
+#define RID_WEP_PERM   0xFF16
+#define RID_MODULATION 0xFF17
+#define RID_ACTUALCONFIG 0xFF20 /*readonly*/
+#define RID_LEAPUSERNAME 0xFF23
+#define RID_LEAPPASSWORD 0xFF24
+#define RID_STATUS     0xFF50
+#define RID_STATS      0xFF68
+#define RID_STATSDELTA 0xFF69
+#define RID_STATSDELTACLEAR 0xFF6A
+
+/*
+ * Rids and endian-ness:  The Rids will always be in cpu endian, since
+ * this all the patches from the big-endian guys end up doing that.
+ * so all rid access should use the read/writeXXXRid routines.
+ */
+
+/* This structure came from an email sent to me from an engineer at
+   aironet for inclusion into this driver */
+typedef struct {
+	u16 len;
+	u16 kindex;
+	u8 mac[6];
+	u16 klen;
+	u8 key[16];
+} WepKeyRid;
+
+/* These structures are from the Aironet's PC4500 Developers Manual */
+typedef struct {
+	u16 len;
+	u8 ssid[32];
+} Ssid;
+
+typedef struct {
+	u16 len;
+	Ssid ssids[3];
+} SsidRid;
+
+typedef struct {
+        u16 len;
+        u16 modulation;
+#define MOD_DEFAULT 0
+#define MOD_CCK 1
+#define MOD_MOK 2
+} ModulationRid;
+
+typedef struct {
+	u16 cmd;
+	u16 parm0;
+	u16 parm1;
+	u16 parm2;
+} Cmd;
+
+typedef struct {
+	u16 status;
+	u16 rsp0;
+	u16 rsp1;
+	u16 rsp2;
+} Resp;
+
+typedef struct {
+	u16 len; /* sizeof(ConfigRid) */
+	u16 opmode; /* operating mode */
+#define MODE_STA_IBSS 0
+#define MODE_STA_ESS 1
+#define MODE_AP 2
+#define MODE_AP_RPTR 3
+#define MODE_ETHERNET_HOST (0<<8) /* rx payloads converted */
+#define MODE_LLC_HOST (1<<8) /* rx payloads left as is */
+#define MODE_AIRONET_EXTEND (1<<9) /* enable Aironet extenstions */
+#define MODE_AP_INTERFACE (1<<10) /* enable ap interface extensions */
+#define MODE_ANTENNA_ALIGN (1<<11) /* enable antenna alignment */
+#define MODE_ETHER_LLC (1<<12) /* enable ethernet LLC */
+#define MODE_LEAF_NODE (1<<13) /* enable leaf node bridge */
+#define MODE_CF_POLLABLE (1<<14) /* enable CF pollable */
+	u16 rmode; /* receive mode */
+#define RXMODE_BC_MC_ADDR 0
+#define RXMODE_BC_ADDR 1 /* ignore multicasts */
+#define RXMODE_ADDR 2 /* ignore multicast and broadcast */
+#define RXMODE_RFMON 3 /* wireless monitor mode */
+#define RXMODE_RFMON_ANYBSS 4
+#define RXMODE_LANMON 5 /* lan style monitor -- data packets only */
+#define RXMODE_DISABLE_802_3_HEADER (1<<8) /* disables 802.3 header on rx */
+#define RXMODE_NORMALIZED_RSSI (1<<9) /* return normalized RSSI */
+	u16 fragThresh;
+	u16 rtsThres;
+	u8 macAddr[6];
+	u8 rates[8];
+	u16 shortRetryLimit;
+	u16 longRetryLimit;
+	u16 txLifetime; /* in kusec */
+	u16 rxLifetime; /* in kusec */
+	u16 stationary;
+	u16 ordering;
+	u16 u16deviceType; /* for overriding device type */
+	u16 cfpRate;
+	u16 cfpDuration;
+	u16 _reserved1[3];
+	/*---------- Scanning/Associating ----------*/
+	u16 scanMode;
+#define SCANMODE_ACTIVE 0
+#define SCANMODE_PASSIVE 1
+#define SCANMODE_AIROSCAN 2
+	u16 probeDelay; /* in kusec */
+	u16 probeEnergyTimeout; /* in kusec */
+        u16 probeResponseTimeout;
+	u16 beaconListenTimeout;
+	u16 joinNetTimeout;
+	u16 authTimeout;
+	u16 authType;
+#define AUTH_OPEN 0x1
+#define AUTH_ENCRYPT 0x101
+#define AUTH_SHAREDKEY 0x102
+#define AUTH_ALLOW_UNENCRYPTED 0x200
+	u16 associationTimeout;
+	u16 specifiedApTimeout;
+	u16 offlineScanInterval;
+	u16 offlineScanDuration;
+	u16 linkLossDelay;
+	u16 maxBeaconLostTime;
+	u16 refreshInterval;
+#define DISABLE_REFRESH 0xFFFF
+	u16 _reserved1a[1];
+	/*---------- Power save operation ----------*/
+	u16 powerSaveMode;
+#define POWERSAVE_CAM 0
+#define POWERSAVE_PSP 1
+#define POWERSAVE_PSPCAM 2
+	u16 sleepForDtims;
+	u16 listenInterval;
+	u16 fastListenInterval;
+	u16 listenDecay;
+	u16 fastListenDelay;
+	u16 _reserved2[2];
+	/*---------- Ap/Ibss config items ----------*/
+	u16 beaconPeriod;
+	u16 atimDuration;
+	u16 hopPeriod;
+	u16 channelSet;
+	u16 channel;
+	u16 dtimPeriod;
+	u16 bridgeDistance;
+	u16 radioID;
+	/*---------- Radio configuration ----------*/
+	u16 radioType;
+#define RADIOTYPE_DEFAULT 0
+#define RADIOTYPE_802_11 1
+#define RADIOTYPE_LEGACY 2
+	u8 rxDiversity;
+	u8 txDiversity;
+	u16 txPower;
+#define TXPOWER_DEFAULT 0
+	u16 rssiThreshold;
+#define RSSI_DEFAULT 0
+        u16 modulation;
+	u16 shortPreamble;
+	u16 homeProduct;
+	u16 radioSpecific;
+	/*---------- Aironet Extensions ----------*/
+	u8 nodeName[16];
+	u16 arlThreshold;
+	u16 arlDecay;
+	u16 arlDelay;
+	u16 _reserved4[1];
+	/*---------- Aironet Extensions ----------*/
+	u16 magicAction;
+#define MAGIC_ACTION_STSCHG 1
+#define MACIC_ACTION_RESUME 2
+#define MAGIC_IGNORE_MCAST (1<<8)
+#define MAGIC_IGNORE_BCAST (1<<9)
+#define MAGIC_SWITCH_TO_PSP (0<<10)
+#define MAGIC_STAY_IN_CAM (1<<10)
+	u16 magicControl;
+	u16 autoWake;
+} ConfigRid;
+
+typedef struct {
+	u16 len;
+	u8 mac[6];
+	u16 mode;
+	u16 errorCode;
+	u16 sigQuality;
+	u16 SSIDlen;
+	char SSID[32];
+	char apName[16];
+	char bssid[4][6];
+	u16 beaconPeriod;
+	u16 dimPeriod;
+	u16 atimDuration;
+	u16 hopPeriod;
+	u16 channelSet;
+	u16 channel;
+	u16 hopsToBackbone;
+	u16 apTotalLoad;
+	u16 generatedLoad;
+	u16 accumulatedArl;
+	u16 signalQuality;
+	u16 currentXmitRate;
+	u16 apDevExtensions;
+	u16 normalizedSignalStrength;
+	u16 _reserved[10];
+} StatusRid;
+
+typedef struct {
+	u16 len;
+	u16 spacer;
+	u32 vals[100];
+} StatsRid;
+	
+
+typedef struct {
+	u16 len;
+	u8 ap[4][6];
+} APListRid;
+
+typedef struct {
+	u16 len;
+	char oui[3];
+	u16 prodNum;
+	char manName[32];
+	char prodName[16];
+	char prodVer[8];
+	char factoryAddr[6];
+	char aironetAddr[6];
+	u16 radioType;
+	u16 country;
+	char callid[6];
+	char supportedRates[8];
+	char rxDiversity;
+	char txDiversity;
+	u16 txPowerLevels[8];
+	u16 hardVer;
+	u16 hardCap;
+	u16 tempRange;
+	u16 softVer;
+	u16 softSubVer;
+	u16 interfaceVer;
+	u16 softCap;
+	u16 bootBlockVer;
+	u16 requiredHard;
+} CapabilityRid;
+
+#define TXCTL_TXOK (1<<1) /* report if tx is ok */
+#define TXCTL_TXEX (1<<2) /* report if tx fails */
+#define TXCTL_802_3 (0<<3) /* 802.3 packet */
+#define TXCTL_802_11 (1<<3) /* 802.11 mac packet */
+#define TXCTL_ETHERNET (0<<4) /* payload has ethertype */
+#define TXCTL_LLC (1<<4) /* payload is llc */
+#define TXCTL_RELEASE (0<<5) /* release after completion */
+#define TXCTL_NORELEASE (1<<5) /* on completion returns to host */
+
+#define BUSY_FID 0x10000
+
+#ifdef CISCO_EXT
+#define AIROMAGIC	0xa55a
+#define AIROIOCTL	SIOCDEVPRIVATE
+#define AIROIDIFC 	AIROIOCTL + 1
+
+/* Ioctl constants to be used in airo_ioctl.command */
+
+#define	AIROGCAP  		0	// Capability rid
+#define AIROGCFG		1       // USED A LOT 
+#define AIROGSLIST		2	// System ID list 
+#define AIROGVLIST		3       // List of specified AP's
+#define AIROGDRVNAM		4	//  NOTUSED
+#define AIROGEHTENC		5	// NOTUSED
+#define AIROGWEPKTMP		6
+#define AIROGWEPKNV		7
+#define AIROGSTAT		8
+#define AIROGSTATSC32		9
+#define AIROGSTATSD32		10
+
+/* Leave gap of 40 commands after AIROGSTATSD32 for future */
+
+#define AIROPCAP               	AIROGSTATSD32 + 40
+#define AIROPVLIST              AIROPCAP      + 1
+#define AIROPSLIST		AIROPVLIST    + 1
+#define AIROPCFG		AIROPSLIST    + 1
+#define AIROPSIDS		AIROPCFG      + 1
+#define AIROPAPLIST		AIROPSIDS     + 1
+#define AIROPMACON		AIROPAPLIST   + 1	/* Enable mac  */
+#define AIROPMACOFF		AIROPMACON    + 1 	/* Disable mac */
+#define AIROPSTCLR		AIROPMACOFF   + 1
+#define AIROPWEPKEY		AIROPSTCLR    + 1
+#define AIROPWEPKEYNV		AIROPWEPKEY   + 1
+#define AIROPLEAPPWD            AIROPWEPKEYNV + 1
+#define AIROPLEAPUSR            AIROPLEAPPWD  + 1
+
+/* Flash codes */
+
+#define AIROFLSHRST	       AIROPWEPKEYNV  + 40
+#define AIROFLSHGCHR           AIROFLSHRST    + 1
+#define AIROFLSHSTFL           AIROFLSHGCHR   + 1
+#define AIROFLSHPCHR           AIROFLSHSTFL   + 1
+#define AIROFLPUTBUF           AIROFLSHPCHR   + 1
+#define AIRORESTART            AIROFLPUTBUF   + 1
+
+#define FLASHSIZE	32768
+
+typedef struct aironet_ioctl {
+	unsigned short command;	// What to do
+	unsigned short len;		// Len of data
+	unsigned char *data;		// d-data
+} aironet_ioctl;
+#endif /* CISCO_EXT */
+
+#ifdef WIRELESS_EXT
+// Frequency list (map channels to frequencies)
+const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
+				2447, 2452, 2457, 2462, 2467, 2472, 2484 };
+
+// A few details needed for WEP (Wireless Equivalent Privacy)
+#define MAX_KEY_SIZE 13			// 128 (?) bits
+#define MIN_KEY_SIZE  5			// 40 bits RC4 - WEP
+#define MAX_KEYS      4			// 4 different keys
+typedef struct wep_key_t {
+	u16	len;
+	u8	key[16];	/* 40-bit and 104-bit keys */
+} wep_key_t;
+#endif /* WIRELESS_EXT */
+
+static const char version[] = "airo.c 0.2 (Ben Reed & Javier Achirica)";
+
+struct airo_info;
+
+static int get_dec_u16( char *buffer, int *start, int limit );
+static void OUT4500( struct airo_info *, u16 register, u16 value );
+static unsigned short IN4500( struct airo_info *, u16 register );
+static u16 setup_card(struct airo_info*, u8 *mac, ConfigRid *);
+static void enable_interrupts(struct airo_info*);
+static void disable_interrupts(struct airo_info*);
+static u16 issuecommand(struct airo_info*, Cmd *pCmd, Resp *pRsp);
+static int bap_setup(struct airo_info*, u16 rid, u16 offset, int whichbap);
+static int aux_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen, 
+			int whichbap);
+static int fast_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen, 
+			 int whichbap);
+static int bap_write(struct airo_info*, const u16 *pu16Src, int bytelen,
+		     int whichbap);
+static int PC4500_accessrid(struct airo_info*, u16 rid, u16 accmd);
+static int PC4500_readrid(struct airo_info*, u16 rid, void *pBuf, int len);
+static int PC4500_writerid(struct airo_info*, u16 rid, const void
+			   *pBuf, int len);
+static int do_writerid( struct airo_info*, u16 rid, const void *rid_data, 
+			int len );
+static u16 transmit_allocate(struct airo_info*, int lenPayload);
+static int transmit_802_3_packet(struct airo_info*, u16 TxFid, char
+				 *pPacket, int len);
+
+static void airo_interrupt( int irq, void* dev_id, struct pt_regs
+			    *regs);
+static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+#ifdef WIRELESS_EXT
+struct iw_statistics *airo_get_wireless_stats (struct net_device *dev);
+#endif /* WIRELESS_EXT */
+#ifdef CISCO_EXT
+static int readrids(struct net_device *dev, aironet_ioctl *comp);
+static int writerids(struct net_device *dev, aironet_ioctl *comp);
+int flashcard(struct net_device *dev, aironet_ioctl *comp);
+#endif /* CISCO_EXT */
+
+struct airo_info {
+	struct net_device_stats	stats;
+	int open;
+	struct net_device             *dev;
+	/* Note, we can have MAX_FIDS outstanding.  FIDs are 16-bits, so we
+	   use the high bit to mark wether it is in use. */
+#define MAX_FIDS 6
+	int                           fids[MAX_FIDS];
+	int registered;
+	ConfigRid config;
+	u16 authtype; // Used with auto_wep 
+	char keyindex; // Used with auto wep
+	char defindex; // Used with auto wep
+	struct timer_list timer;
+	struct proc_dir_entry *proc_entry;
+	struct airo_info *next;
+        spinlock_t bap0_lock;
+        spinlock_t bap1_lock;
+        spinlock_t aux_lock;
+        spinlock_t cmd_lock;
+        int flags;
+#define FLAG_PROMISC   0x01
+#define FLAG_RADIO_OFF 0x02
+	int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen, 
+			int whichbap);
+	int (*header_parse)(struct sk_buff*, unsigned char *);
+#ifdef WIRELESS_EXT
+	int			need_commit;	// Need to set config
+	struct iw_statistics	wstats;		// wireless stats
+#ifdef WIRELESS_SPY
+	int			spy_number;
+	u_char			spy_address[IW_MAX_SPY][6];
+	struct iw_quality	spy_stat[IW_MAX_SPY];
+#endif /* WIRELESS_SPY */
+#endif /* WIRELESS_EXT */
+};
+
+static inline int bap_read(struct airo_info *ai, u16 *pu16Dst, int bytelen, 
+			   int whichbap) {
+	return ai->bap_read(ai, pu16Dst, bytelen, whichbap);
+}
+
+static int setup_proc_entry( struct net_device *dev,
+			     struct airo_info *apriv );
+static int takedown_proc_entry( struct net_device *dev,
+				struct airo_info *apriv );
+
+static int readWepKeyRid(struct airo_info*ai, WepKeyRid *wkr, int temp) {
+	int rc = PC4500_readrid(ai, temp ? RID_WEP_TEMP : RID_WEP_PERM, 
+				wkr, sizeof(*wkr));
+	
+	wkr->len = le16_to_cpu(wkr->len);
+	wkr->kindex = le16_to_cpu(wkr->kindex);
+	wkr->klen = le16_to_cpu(wkr->klen);
+	return rc;
+}
+/* In the writeXXXRid routines we copy the rids so that we don't screwup
+ * the originals when we endian them... */
+static int writeWepKeyRid(struct airo_info*ai, WepKeyRid *pwkr, int perm) {
+	int rc;
+	WepKeyRid wkr = *pwkr;
+
+	wkr.len = cpu_to_le16(wkr.len);
+	wkr.kindex = cpu_to_le16(wkr.kindex);
+	wkr.klen = cpu_to_le16(wkr.klen);
+	rc = do_writerid(ai, RID_WEP_TEMP, &wkr, sizeof(wkr));
+	if (rc!=SUCCESS) printk(KERN_ERR "airo:  WEP_TEMP set %x\n", rc); 
+	if (perm) {
+		rc = do_writerid(ai, RID_WEP_PERM, &wkr, sizeof(wkr));
+		if (rc!=SUCCESS) {
+			printk(KERN_ERR "airo:  WEP_PERM set %x\n", rc);
+		}
+	}
+	return rc;
+}
+
+static int readSsidRid(struct airo_info*ai, SsidRid *ssidr) {
+	int i;
+	int rc = PC4500_readrid(ai, RID_SSID, ssidr, sizeof(*ssidr));
+
+	ssidr->len = le16_to_cpu(ssidr->len);
+	for(i = 0; i < 3; i++) {
+		ssidr->ssids[i].len = le16_to_cpu(ssidr->ssids[i].len);
+	}
+	return rc;
+}
+static int writeSsidRid(struct airo_info*ai, SsidRid *pssidr) {
+	int rc;
+	int i;
+	SsidRid ssidr = *pssidr;
+
+	ssidr.len = cpu_to_le16(ssidr.len);
+	for(i = 0; i < 3; i++) {
+		ssidr.ssids[i].len = cpu_to_le16(ssidr.ssids[i].len);
+	}
+	rc = do_writerid(ai, RID_SSID, &ssidr, sizeof(ssidr));
+	return rc;
+}
+static int readConfigRid(struct airo_info*ai, ConfigRid *cfgr) {
+	int rc = PC4500_readrid(ai, RID_ACTUALCONFIG, cfgr, sizeof(*cfgr));
+	u16 *s;
+	
+	for(s = &cfgr->len; s <= &cfgr->rtsThres; s++) *s = le16_to_cpu(*s);
+
+	for(s = &cfgr->shortRetryLimit; s <= &cfgr->radioType; s++)
+		*s = le16_to_cpu(*s);
+
+	for(s = &cfgr->txPower; s <= &cfgr->radioSpecific; s++)
+		*s = le16_to_cpu(*s);
+	
+	for(s = &cfgr->arlThreshold; s <= &cfgr->autoWake; s++)
+		*s = le16_to_cpu(*s);
+	
+	return rc;
+}
+static int writeConfigRid(struct airo_info*ai, ConfigRid *pcfgr) {
+	u16 *s;
+	ConfigRid cfgr = *pcfgr;
+	
+	for(s = &cfgr.len; s <= &cfgr.rtsThres; s++) *s = cpu_to_le16(*s);
+
+	for(s = &cfgr.shortRetryLimit; s <= &cfgr.radioType; s++)
+		*s = cpu_to_le16(*s);
+
+	for(s = &cfgr.txPower; s <= &cfgr.radioSpecific; s++)
+		*s = cpu_to_le16(*s);
+	
+	for(s = &cfgr.arlThreshold; s <= &cfgr.autoWake; s++)
+		*s = cpu_to_le16(*s);
+	
+	return do_writerid( ai, RID_CONFIG, &cfgr, sizeof(cfgr));
+}
+static int readStatusRid(struct airo_info*ai, StatusRid *statr) {
+	int rc = PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr));
+	u16 *s;
+
+	statr->len = le16_to_cpu(statr->len);
+	for(s = &statr->mode; s <= &statr->SSIDlen; s++) *s = le16_to_cpu(*s);
+
+	for(s = &statr->beaconPeriod; s <= &statr->_reserved[9]; s++)
+		*s = le16_to_cpu(*s);
+
+	return rc;
+}
+static int readAPListRid(struct airo_info*ai, APListRid *aplr) {
+	int rc =  PC4500_readrid(ai, RID_APLIST, aplr, sizeof(*aplr));
+	aplr->len = le16_to_cpu(aplr->len);
+	return rc;
+}
+static int writeAPListRid(struct airo_info*ai, APListRid *aplr) {
+	int rc;
+	aplr->len = cpu_to_le16(aplr->len);
+	rc = do_writerid(ai, RID_APLIST, aplr, sizeof(*aplr));
+	return rc;
+}
+static int readCapabilityRid(struct airo_info*ai, CapabilityRid *capr) {
+	int rc = PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr));
+	u16 *s;
+	
+	capr->len = le16_to_cpu(capr->len);
+	capr->prodNum = le16_to_cpu(capr->prodNum);
+	capr->radioType = le16_to_cpu(capr->radioType);
+	capr->country = le16_to_cpu(capr->country);
+	for(s = &capr->txPowerLevels[0]; s <= &capr->requiredHard; s++)
+		*s = le16_to_cpu(*s);
+	return rc;
+}
+static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid) {
+	int rc = PC4500_readrid(ai, rid, sr, sizeof(*sr));
+	u32 *i;
+
+	sr->len = le16_to_cpu(sr->len);
+	for(i = &sr->vals[0]; i <= &sr->vals[99]; i++) *i = le32_to_cpu(*i);
+	return rc;
+}
+
+static int airo_open(struct net_device *dev) {
+	struct airo_info *info = dev->priv;
+
+	enable_interrupts(info);
+
+	netif_start_queue(dev);
+	return 0;
+}
+
+static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {
+	s16 len;
+	s16 retval = 0;
+	u16 status;
+	u32 flags;
+	s8 *buffer;
+	int i,j;
+	struct airo_info *priv = (struct airo_info*)dev->priv;
+	u32 *fids = priv->fids;
+	
+	if ( skb == NULL ) {
+		printk( KERN_ERR "airo:  skb == NULL!!!\n" );
+		return 0;
+	}
+	
+	/* Find a vacant FID */
+	spin_lock_irqsave(&priv->bap1_lock, flags);
+	for( j = 0, i = -1; j < MAX_FIDS; j++ ) {
+		if ( !( fids[j] & 0xffff0000 ) ) {
+			if ( i == -1 ) i = j;
+			else break;
+		}
+	}
+	if ( j == MAX_FIDS ) netif_stop_queue(dev);
+	if ( i == -1 ) {
+		retval = -EBUSY;
+		goto tx_done;
+	}
+	
+	len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; /* check min length*/
+	buffer = skb->data;
+	
+	status = transmit_802_3_packet( priv, 
+					fids[i],
+					skb->data, len );
+	
+	if ( status == SUCCESS ) {
+                /* Mark fid as used & save length for later */
+		fids[i] |= (len << 16); 
+		dev->trans_start = jiffies;
+	} else {
+		priv->stats.tx_errors++;
+	}
+ tx_done:
+	spin_unlock_irqrestore(&priv->bap1_lock, flags);
+	dev_kfree_skb(skb);
+	return 0;
+}
+
+static struct net_device_stats *airo_get_stats(struct net_device *dev) {
+	return &(((struct airo_info*)dev->priv)->stats);
+}
+
+static int enable_MAC( struct airo_info *ai, Resp *rsp );
+static void disable_MAC(struct airo_info *ai);
+
+static void airo_set_multicast_list(struct net_device *dev) {
+	struct airo_info *ai = (struct airo_info*)dev->priv;
+	Cmd cmd;
+	Resp rsp;
+	  
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd=CMD_SETMODE;
+	cmd.parm0=(dev->flags&IFF_PROMISC) ? PROMISC : NOPROMISC;
+	issuecommand(ai, &cmd, &rsp);
+
+	if ((dev->flags&IFF_ALLMULTI)||dev->mc_count>0) {
+		/* Turn on multicast.  (Should be already setup...) */
+	}
+}
+
+static int airo_set_mac_address(struct net_device *dev, void *p)
+{
+	struct airo_info *ai = (struct airo_info*)dev->priv;
+	struct sockaddr *addr = p;
+	ConfigRid cfg;
+
+	readConfigRid (ai, &cfg);
+	memcpy (cfg.macAddr, addr->sa_data, dev->addr_len);
+	writeConfigRid (ai, &cfg);
+	memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
+	return 0;
+}
+
+static int airo_change_mtu(struct net_device *dev, int new_mtu)
+{
+	if ((new_mtu < 68) || (new_mtu > 2400))
+		return -EINVAL;
+	dev->mtu = new_mtu;
+	return 0;
+}
+
+
+static int airo_close(struct net_device *dev) { 
+	struct airo_info *ai = (struct airo_info*)dev->priv;
+
+	netif_stop_queue(dev);
+	disable_interrupts( ai );
+	return 0;
+}
+
+static void del_airo_dev( struct net_device *dev );
+
+void stop_airo_card( struct net_device *dev, int freeres ) 
+{
+	struct airo_info *ai = (struct airo_info*)dev->priv;
+	takedown_proc_entry( dev, ai );
+	if (ai->registered) {
+		unregister_netdev( dev );
+		ai->registered = 0;
+	}
+	disable_interrupts(ai);
+	free_irq( dev->irq, dev );
+	if (auto_wep) del_timer_sync(&ai->timer);
+	if (freeres) {
+		/* PCMCIA frees this stuff, so only for PCI and ISA */
+	        release_region( dev->base_addr, 64 );
+        }
+	del_airo_dev( dev );
+	kfree( dev );
+}
+
+static int add_airo_dev( struct net_device *dev ); 
+
+struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia )
+{
+	struct net_device *dev;
+	struct airo_info *ai;
+	int i, rc;
+	
+	/* Create the network device object. */
+        dev = alloc_etherdev(sizeof(*ai));
+        if (!dev) {
+		printk(KERN_ERR "airo:  Couldn't alloc_etherdev\n");
+		return NULL;
+        }
+	ai = dev->priv;
+	ai->registered = 1;
+        ai->dev = dev;
+	ai->bap0_lock = SPIN_LOCK_UNLOCKED;
+	ai->bap1_lock = SPIN_LOCK_UNLOCKED;
+	ai->aux_lock = SPIN_LOCK_UNLOCKED;
+	ai->cmd_lock = SPIN_LOCK_UNLOCKED;
+	ai->header_parse = dev->hard_header_parse;
+	rc = add_airo_dev( dev );
+	if (rc)
+		goto err_out_free;
+	
+	/* The Airo-specific entries in the device structure. */
+	dev->hard_start_xmit = &airo_start_xmit;
+	dev->get_stats = &airo_get_stats;
+	dev->set_multicast_list = &airo_set_multicast_list;
+	dev->set_mac_address = &airo_set_mac_address;
+	dev->do_ioctl = &airo_ioctl;
+#ifdef WIRELESS_EXT
+	dev->get_wireless_stats = airo_get_wireless_stats;
+#endif /* WIRELESS_EXT */
+	dev->change_mtu = &airo_change_mtu;
+	dev->open = &airo_open;
+	dev->stop = &airo_close;
+	dev->irq = irq;
+	dev->base_addr = port;
+	
+	rc = register_netdev(dev);
+	if (rc)
+		goto err_out_unlink;
+	
+	rc = request_irq( dev->irq, airo_interrupt, 
+			  SA_SHIRQ | SA_INTERRUPT, dev->name, dev );
+	if (rc) {
+		printk(KERN_ERR "airo: register interrupt %d failed, rc %d\n", irq, rc );
+		goto err_out_unregister;
+	}
+	if (!is_pcmcia) {
+		if (!request_region( dev->base_addr, 64, dev->name )) {
+			rc = -EBUSY;
+			goto err_out_irq;
+		}
+	}
+	
+	if ( setup_card( ai, dev->dev_addr, &ai->config) != SUCCESS ) {
+		printk( KERN_ERR "airo: MAC could not be enabled\n" );
+		rc = -EIO;
+		goto err_out_res;
+	}
+
+	printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n",
+		dev->name,
+		dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+		dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
+
+	/* Allocate the transmit buffers */
+	for( i = 0; i < MAX_FIDS; i++ )
+		ai->fids[i] = transmit_allocate( ai, 2312 );
+
+	setup_proc_entry( dev, dev->priv ); /* XXX check for failure */
+	netif_start_queue(dev);
+	SET_MODULE_OWNER(dev);
+	return dev;
+
+err_out_res:
+	if (!is_pcmcia)
+	        release_region( dev->base_addr, 64 );
+err_out_irq:
+	free_irq(dev->irq, dev);
+err_out_unregister:
+	unregister_netdev(dev);
+err_out_unlink:
+	del_airo_dev(dev);
+err_out_free:
+	kfree(dev);
+	return NULL;
+}
+
+int waitbusy (struct airo_info *ai) {
+	int delay = 0;
+	while ((IN4500 (ai, COMMAND) & COMMAND_BUSY) & (delay < 10000)) {
+		udelay (10);
+		if (++delay % 20)
+			OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
+	}  
+	return delay < 10000;
+}
+
+int reset_airo_card( struct net_device *dev ) {
+	int i, flags;
+	struct airo_info *ai = (struct airo_info*)dev->priv;
+
+	disable_MAC(ai);
+	spin_lock_irqsave(&ai->cmd_lock, flags);
+	waitbusy (ai);
+	OUT4500(ai,COMMAND,CMD_SOFTRESET);
+	set_current_state (TASK_UNINTERRUPTIBLE);
+	schedule_timeout (HZ/5);
+	waitbusy (ai);
+	set_current_state (TASK_UNINTERRUPTIBLE);
+	schedule_timeout (HZ/5);
+	spin_unlock_irqrestore(&ai->cmd_lock, flags);
+	if ( setup_card(ai, dev->dev_addr, &(ai)->config) != SUCCESS ) {
+		printk( KERN_ERR "airo: MAC could not be enabled\n" );
+		return -1;
+	} else {
+		printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n",
+			dev->name,
+			dev->dev_addr[0],
+			dev->dev_addr[1],
+			dev->dev_addr[2],
+			dev->dev_addr[3],
+			dev->dev_addr[4],
+			dev->dev_addr[5]
+			);
+		/* Allocate the transmit buffers */
+		for( i = 0; i < MAX_FIDS; i++ )
+			ai->fids[i] = transmit_allocate( ai, 2312 );
+	}
+	enable_interrupts( ai );
+	netif_wake_queue(dev);
+	return 0;
+}
+
+int wll_header_parse(struct sk_buff *skb, unsigned char *haddr)
+{
+	memcpy(haddr, skb->mac.raw + 10, ETH_ALEN);
+	return ETH_ALEN;
+}
+
+static void airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) {
+	struct net_device *dev = (struct net_device *)dev_id;
+	u16 status;
+	u16 fid;
+	struct airo_info *apriv = (struct airo_info *)dev->priv;
+	u16 savedInterrupts;
+	
+
+	if (!netif_device_present(dev))
+		return;
+	
+	status = IN4500( apriv, EVSTAT );
+	if ( !status || status == 0xffff ) return;
+	
+	if ( status & EV_AWAKE ) {
+		OUT4500( apriv, EVACK, EV_AWAKE );
+		OUT4500( apriv, EVACK, EV_AWAKE );
+	}
+	
+	savedInterrupts = IN4500( apriv, EVINTEN );
+	OUT4500( apriv, EVINTEN, 0 );
+	
+	if ( status & EV_LINK ) {
+		/* The link status has changed, if you want to put a
+		   monitor hook in, do it here.  (Remember that
+		   interrupts are still disabled!)
+		*/
+		u16 newStatus = IN4500(apriv, LINKSTAT);
+		/* Here is what newStatus means: */
+#define NOBEACON 0x8000 /* Loss of sync - missed beacons */
+#define MAXRETRIES 0x8001 /* Loss of sync - max retries */
+#define MAXARL 0x8002 /* Loss of sync - average retry level exceeded*/
+#define FORCELOSS 0x8003 /* Loss of sync - host request */
+#define TSFSYNC 0x8004 /* Loss of sync - TSF synchronization */
+#define DEAUTH 0x8100 /* Deauthentication (low byte is reason code) */
+#define DISASS 0x8200 /* Disassociation (low byte is reason code) */
+#define ASSFAIL 0x8400 /* Association failure (low byte is reason
+			  code) */
+#define AUTHFAIL 0x0300 /* Authentication failure (low byte is reason
+			   code) */
+#define ASSOCIATED 0x0400 /* Assocatied */
+#define RC_RESERVED 0 /* Reserved return code */
+#define RC_NOREASON 1 /* Unspecified reason */
+#define RC_AUTHINV 2 /* Previous authentication invalid */
+#define RC_DEAUTH 3 /* Deauthenticated because sending station is
+		       leaving */
+#define RC_NOACT 4 /* Disassociated due to inactivity */
+#define RC_MAXLOAD 5 /* Disassociated because AP is unable to handle
+			all currently associated stations */
+#define RC_BADCLASS2 6 /* Class 2 frame received from
+			  non-Authenticated station */
+#define RC_BADCLASS3 7 /* Class 3 frame received from
+			  non-Associated station */
+#define RC_STATLEAVE 8 /* Disassociated because sending station is
+			  leaving BSS */
+#define RC_NOAUTH 9 /* Station requesting (Re)Association is not
+		       Authenticated with the responding station */
+		if (newStatus != ASSOCIATED) {
+			if (auto_wep && !timer_pending(&apriv->timer)) {
+				apriv->timer.expires = RUN_AT(HZ*3);
+	      			add_timer(&apriv->timer);
+			}
+		}
+	}
+	
+	/* Check to see if there is something to receive */
+	if ( status & EV_RX  ) {
+		struct sk_buff *skb = NULL;
+		int flags;
+		u16 fc, len, hdrlen = 0;
+		struct {
+			u16 status, len;
+			u8 rssi[2];
+		} hdr;
+
+		fid = IN4500( apriv, RXFID );
+
+		/* Get the packet length */
+	        spin_lock_irqsave(&apriv->bap0_lock, flags);
+		if (dev->type == ARPHRD_IEEE80211) {
+			bap_setup (apriv, fid, 4, BAP0);
+			bap_read (apriv, (u16*)&hdr, sizeof(hdr), BAP0);
+			/* Bad CRC. Ignore packet */
+			if (le16_to_cpu(hdr.status) == 2) {
+				apriv->stats.rx_crc_errors++;
+				apriv->stats.rx_errors++;
+				hdr.len = 0;
+			}
+		} else {
+			bap_setup (apriv, fid, 6, BAP0);
+			bap_read (apriv, (u16*)&hdr.len, 4, BAP0);
+		}
+		len = le16_to_cpu(hdr.len);
+
+		if (len > 2312) {
+			apriv->stats.rx_length_errors++;
+			apriv->stats.rx_errors++;
+			printk( KERN_ERR 
+				"airo: Bad size %d\n", len );
+			len = 0;
+		}
+		if (len) {
+			if (dev->type == ARPHRD_IEEE80211) {
+				bap_setup (apriv, fid, 0x14, BAP0);
+				bap_read (apriv, (u16*)&fc, sizeof(fc), BAP0);
+				if ((le16_to_cpu(fc) & 0x300) == 0x300)
+					hdrlen = 30;
+				else
+					hdrlen = 24;
+			} else
+				hdrlen = 12;
+
+			skb = dev_alloc_skb( len + hdrlen + 2 );
+			if ( !skb ) {
+				apriv->stats.rx_dropped++;
+				len = 0;
+			}
+		}
+		if (len) {
+			u16 *buffer;
+			buffer = (u16*)skb_put (skb, len + hdrlen);
+			if (dev->type == ARPHRD_IEEE80211) {
+				u16 gap, tmpbuf[4];
+				buffer[0] = fc;
+				bap_read (apriv, buffer + 1, hdrlen - 2, BAP0);
+				if (hdrlen == 24)
+					bap_read (apriv, tmpbuf, 6, BAP0);
+
+				bap_read (apriv, &gap, sizeof(gap), BAP0);
+				gap = le16_to_cpu(gap);
+				if (gap && gap <= 8)
+					bap_read (apriv, tmpbuf, gap, BAP0);
+
+				bap_read (apriv, buffer + hdrlen/2, len, BAP0);
+			} else {
+		                bap_setup (apriv, fid, 0x38, BAP0);
+				bap_read (apriv, buffer,len + hdrlen,BAP0);
+			}
+#ifdef WIRELESS_SPY
+			if (apriv->spy_number > 0) {
+				int i;
+				char *sa;
+
+				sa = (char*)buffer + ((dev->type == ARPHRD_IEEE80211) ? 10 : 6);
+
+				for (i=0; i<apriv->spy_number; i++)
+					if (!memcmp(sa,apriv->spy_address[i],6))
+					{
+						apriv->spy_stat[i].qual = hdr.rssi[0];
+						apriv->spy_stat[i].level = hdr.rssi[1];
+						apriv->spy_stat[i].noise = 0;
+						apriv->spy_stat[i].updated = 3;
+						break;
+					}
+			}
+#endif /* WIRELESS_SPY  */
+			apriv->stats.rx_packets++;
+			apriv->stats.rx_bytes += len + hdrlen;
+			dev->last_rx = jiffies;
+			skb->dev = dev;
+			skb->ip_summed = CHECKSUM_NONE;
+			if (dev->type == ARPHRD_IEEE80211) {
+				skb->mac.raw = skb->data;
+				skb_pull (skb, hdrlen);
+				skb->pkt_type = PACKET_OTHERHOST;
+				skb->protocol = htons(ETH_P_802_2);
+			} else
+				skb->protocol = eth_type_trans( skb, dev );
+
+			netif_rx( skb );
+		}
+		spin_unlock_irqrestore(&apriv->bap0_lock, flags);
+	}
+
+	/* Check to see if a packet has been transmitted */
+	if (  status & ( EV_TX|EV_TXEXC ) ) {
+		int i;
+		int len = 0;
+		int full = 1;
+		int index = -1;
+		
+		fid = IN4500(apriv, TXCOMPLFID);
+		
+		for( i = 0; i < MAX_FIDS; i++ ) {
+			if (!(apriv->fids[i] & 0xffff0000)) full = 0;
+			if ( ( apriv->fids[i] & 0xffff ) == fid ) {
+				len = apriv->fids[i] >> 16;
+				index = i;
+				/* Set up to be used again */
+				apriv->fids[i] &= 0xffff; 
+			}
+		}
+		if (full) netif_wake_queue(dev);
+		if (index==-1) {
+			printk( KERN_ERR
+				"airo: Unallocated FID was used to xmit\n" );
+		}
+		if ( status & EV_TX ) {
+			apriv->stats.tx_packets++;
+			if(index!=-1)
+				apriv->stats.tx_bytes += len;
+		} else {
+			apriv->stats.tx_errors++;
+		}
+	}
+	if ( status & ~STATUS_INTS ) 
+		printk( KERN_WARNING 
+			"airo: Got weird status %x\n", 
+			status & ~STATUS_INTS );
+	OUT4500( apriv, EVACK, status & STATUS_INTS );
+	OUT4500( apriv, EVINTEN, savedInterrupts );
+	
+	/* done.. */
+	return;     
+}
+
+/*
+ *  Routines to talk to the card
+ */
+
+/*
+ *  This was originally written for the 4500, hence the name
+ *  NOTE:  If use with 8bit mode and SMP bad things will happen!
+ *         Why would some one do 8 bit IO in an SMP machine?!?
+ */
+static void OUT4500( struct airo_info *ai, u16 reg, u16 val ) {
+	if ( !do8bitIO )
+		outw( val, ai->dev->base_addr + reg );
+	else {
+		outb( val & 0xff, ai->dev->base_addr + reg );
+		outb( val >> 8, ai->dev->base_addr + reg + 1 );
+	}
+}
+
+static u16 IN4500( struct airo_info *ai, u16 reg ) {
+	unsigned short rc;
+	
+	if ( !do8bitIO )
+		rc = inw( ai->dev->base_addr + reg );
+	else {
+		rc = inb( ai->dev->base_addr + reg );
+		rc += ((int)inb( ai->dev->base_addr + reg + 1 )) << 8;
+	}
+	return rc;
+}
+
+static int enable_MAC( struct airo_info *ai, Resp *rsp ) {
+        Cmd cmd;
+
+        if (ai->flags&FLAG_RADIO_OFF) return SUCCESS;
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd = MAC_ENABLE;
+	return issuecommand(ai, &cmd, rsp);
+}
+
+static void disable_MAC( struct airo_info *ai ) {
+        Cmd cmd;
+	Resp rsp;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd = MAC_DISABLE; // disable in case already enabled
+	issuecommand(ai, &cmd, &rsp);
+}
+
+static void enable_interrupts( struct airo_info *ai ) {
+	/* Reset the status register */
+	u16 status = IN4500( ai, EVSTAT );
+	OUT4500( ai, EVACK, status );
+	/* Enable the interrupts */
+	OUT4500( ai, EVINTEN, STATUS_INTS );
+	/* Note there is a race condition between the last two lines that
+	   I dont know how to get rid of right now... */
+}
+
+static void disable_interrupts( struct airo_info *ai ) {
+	OUT4500( ai, EVINTEN, 0 );
+}
+
+static u16 setup_card(struct airo_info *ai, u8 *mac, 
+		      ConfigRid *config)
+{
+	Cmd cmd; 
+	Resp rsp;
+	ConfigRid cfg;
+	int status;
+	int i;
+	SsidRid mySsid;
+	u16 lastindex;
+	WepKeyRid wkr;
+	int rc;
+
+	memset( &mySsid, 0, sizeof( mySsid ) );
+
+	/* The NOP is the first step in getting the card going */
+	cmd.cmd = NOP;
+	cmd.parm0 = cmd.parm1 = cmd.parm2 = 0;
+	if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
+		return ERROR;
+	}
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd = MAC_DISABLE; // disable in case already enabled
+	if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
+		return ERROR;
+	}
+	
+	// Let's figure out if we need to use the AUX port
+	cmd.cmd = CMD_ENABLEAUX;
+	if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
+		printk(KERN_ERR "airo: Error checking for AUX port\n");
+		return ERROR;
+	}
+	if (!aux_bap || rsp.status & 0xff00) {
+		ai->bap_read = fast_bap_read;
+		printk(KERN_DEBUG "airo: Doing fast bap_reads\n");
+	} else {
+		ai->bap_read = aux_bap_read;
+		printk(KERN_DEBUG "airo: Doing AUX bap_reads\n");
+	}
+	if ( config->len ) {
+		cfg = *config;
+	} else {
+		// general configuration (read/modify/write)
+		status = readConfigRid(ai, &cfg);
+		if ( status != SUCCESS ) return ERROR;
+		cfg.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
+    
+		/* Save off the MAC */
+		for( i = 0; i < 6; i++ ) {
+			mac[i] = cfg.macAddr[i];
+		}
+
+		/* Check to see if there are any insmod configured 
+		   rates to add */
+		if ( rates ) {
+			int i = 0;
+			if ( rates[0] ) memset(cfg.rates,0,sizeof(cfg.rates));
+			for( i = 0; i < 8 && rates[i]; i++ ) {
+				cfg.rates[i] = rates[i];
+			}    
+		}
+		if ( basic_rate > 0 ) {
+			int i;
+			for( i = 0; i < 8; i++ ) {
+				if ( cfg.rates[i] == basic_rate ||
+				     !cfg.rates ) {
+					cfg.rates[i] = basic_rate | 0x80;
+					break;
+				}
+			}
+		}
+		cfg.authType = ai->authtype;
+		*config = cfg;
+	}
+	
+	/* Setup the SSIDs if present */
+	if ( ssids[0] ) {
+		int i = 0;
+		for( i = 0; i < 3 && ssids[i]; i++ ) {
+			mySsid.ssids[i].len = strlen(ssids[i]);
+			if ( mySsid.ssids[i].len > 32 ) 
+				mySsid.ssids[i].len = 32;
+			memcpy(mySsid.ssids[i].ssid, ssids[i],
+			       mySsid.ssids[i].len);
+			mySsid.ssids[i].len = mySsid.ssids[i].len;
+		}
+	}
+	
+	status = writeConfigRid(ai, &cfg);
+	if ( status != SUCCESS ) return ERROR;
+	
+	/* Set up the SSID list */
+	status = writeSsidRid(ai, &mySsid);
+	if ( status != SUCCESS ) return ERROR;
+	
+	/* Grab the initial wep key, we gotta save it for auto_wep */
+	rc = readWepKeyRid(ai, &wkr, 1);
+	if (rc == SUCCESS) do {
+		lastindex = wkr.kindex;
+		if (wkr.kindex == 0xffff) {
+			ai->defindex = wkr.mac[0];
+		}
+		rc = readWepKeyRid(ai, &wkr, 0);
+	} while(lastindex != wkr.kindex);
+	
+	if (auto_wep && !timer_pending(&ai->timer)) {
+		ai->timer.expires = RUN_AT(HZ*3);
+		add_timer(&ai->timer);
+	}
+	return SUCCESS;
+}
+
+static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
+        // Im really paranoid about letting it run forever!
+	int max_tries = 600000;  
+        int rc = SUCCESS;
+	int flags;
+
+	spin_lock_irqsave(&ai->cmd_lock, flags);
+	OUT4500(ai, PARAM0, pCmd->parm0);
+	OUT4500(ai, PARAM1, pCmd->parm1);
+	OUT4500(ai, PARAM2, pCmd->parm2);
+	OUT4500(ai, COMMAND, pCmd->cmd);
+	while ( max_tries-- &&
+		(IN4500(ai, EVSTAT) & EV_CMD) == 0) {
+		if ( IN4500(ai, COMMAND) == pCmd->cmd) { 
+			// PC4500 didn't notice command, try again
+			OUT4500(ai, COMMAND, pCmd->cmd);
+		}
+	}
+	if ( max_tries == -1 ) {
+		printk( KERN_ERR 
+			"airo: Max tries exceeded when issueing command\n" );
+                rc = ERROR;
+                goto done;
+	}
+	// command completed
+	pRsp->status = IN4500(ai, STATUS);
+	pRsp->rsp0 = IN4500(ai, RESP0);
+	pRsp->rsp1 = IN4500(ai, RESP1);
+	pRsp->rsp2 = IN4500(ai, RESP2);
+	
+	// clear stuck command busy if necessary
+	if (IN4500(ai, COMMAND) & COMMAND_BUSY) {
+		OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
+	}
+	// acknowledge processing the status/response
+	OUT4500(ai, EVACK, EV_CMD);
+ done:
+	spin_unlock_irqrestore(&ai->cmd_lock, flags);
+	return rc;
+}
+
+/* Sets up the bap to start exchange data.  whichbap should
+ * be one of the BAP0 or BAP1 defines.  Locks should be held before
+ * calling! */
+static int bap_setup(struct airo_info *ai, u16 rid, u16 offset, int whichbap )
+{
+	int timeout = 50;
+	int max_tries = 3;
+	
+	OUT4500(ai, SELECT0+whichbap, rid);
+	OUT4500(ai, OFFSET0+whichbap, offset);
+	while (1) {
+		int status = IN4500(ai, OFFSET0+whichbap);
+		if (status & BAP_BUSY) {
+                        /* This isn't really a timeout, but its kinda
+			   close */
+			if (timeout--) { 
+				continue;
+			}
+		} else if ( status & BAP_ERR ) {
+			/* invalid rid or offset */
+			printk( KERN_ERR "airo: BAP error %x %d\n", 
+				status, whichbap );
+			return ERROR;
+		} else if (status & BAP_DONE) { // success
+			return SUCCESS;
+		}
+		if ( !(max_tries--) ) {
+			printk( KERN_ERR 
+				"airo: BAP setup error too many retries\n" );
+			return ERROR;
+		}
+		// -- PC4500 missed it, try again
+		OUT4500(ai, SELECT0+whichbap, rid);
+		OUT4500(ai, OFFSET0+whichbap, offset);
+		timeout = 50;
+	}
+}
+
+/* should only be called by aux_bap_read.  This aux function and the
+   following use concepts not documented in the developers guide.  I
+   got them from a patch given to my by Aironet */
+static u16 aux_setup(struct airo_info *ai, u16 page,
+		     u16 offset, u16 *len)
+{
+	u16 next;
+
+	OUT4500(ai, AUXPAGE, page);
+	OUT4500(ai, AUXOFF, 0);
+	next = IN4500(ai, AUXDATA);
+	*len = IN4500(ai, AUXDATA)&0xff;
+	if (offset != 4) OUT4500(ai, AUXOFF, offset);
+	return next;
+}
+
+/* requires call to bap_setup() first */
+static int aux_bap_read(struct airo_info *ai, u16 *pu16Dst,
+			int bytelen, int whichbap) 
+{
+	u16 len;
+	u16 page;
+	u16 offset;
+	u16 next;
+	int words;
+	int i;
+	int flags;
+
+	spin_lock_irqsave(&ai->aux_lock, flags);
+	page = IN4500(ai, SWS0+whichbap);
+	offset = IN4500(ai, SWS2+whichbap);
+	next = aux_setup(ai, page, offset, &len);
+	words = (bytelen+1)>>1;
+
+	for (i=0; i<words;) {
+		int count;
+		count = (len>>1) < (words-i) ? (len>>1) : (words-i);
+		if ( !do8bitIO ) 
+			insw( ai->dev->base_addr+DATA0+whichbap, 
+			      pu16Dst+i,count );
+		else
+			insb( ai->dev->base_addr+DATA0+whichbap, 
+			      pu16Dst+i, count << 1 );
+		i += count;
+		if (i<words) {
+			next = aux_setup(ai, next, 4, &len);
+		}
+	}
+	spin_unlock_irqrestore(&ai->aux_lock, flags);
+	return SUCCESS;
+}
+
+
+/* requires call to bap_setup() first */
+static int fast_bap_read(struct airo_info *ai, u16 *pu16Dst, 
+			 int bytelen, int whichbap)
+{
+	bytelen = (bytelen + 1) & (~1); // round up to even value
+	if ( !do8bitIO ) 
+		insw( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen>>1 );
+	else
+		insb( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen );
+	return SUCCESS;
+}
+
+/* requires call to bap_setup() first */
+static int bap_write(struct airo_info *ai, const u16 *pu16Src, 
+		     int bytelen, int whichbap)
+{
+	bytelen = (bytelen + 1) & (~1); // round up to even value
+	if ( !do8bitIO ) 
+		outsw( ai->dev->base_addr+DATA0+whichbap, 
+		       pu16Src, bytelen>>1 );
+	else
+		outsb( ai->dev->base_addr+DATA0+whichbap, pu16Src, bytelen );
+	return SUCCESS;
+}
+
+static int PC4500_accessrid(struct airo_info *ai, u16 rid, u16 accmd)
+{
+	Cmd cmd; /* for issuing commands */
+	Resp rsp; /* response from commands */
+	u16 status;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd = accmd;
+	cmd.parm0 = rid;
+	status = issuecommand(ai, &cmd, &rsp);
+	if (status != 0) return status;
+	if ( (rsp.status & 0x7F00) != 0) {
+		return (accmd << 8) + (rsp.rsp0 & 0xFF);
+	}
+	return 0;
+}
+
+/*  Note, that we are using BAP1 which is also used by transmit, so
+ *  we must get a lock. */
+static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len)
+{
+	u16 status;
+        int flags;
+        int rc = SUCCESS;
+
+	spin_lock_irqsave(&ai->bap1_lock, flags);
+	if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != SUCCESS) {
+                rc = status;
+                goto done;
+        }
+	if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
+		rc = ERROR;
+                goto done;
+        }
+	// read the rid length field
+	bap_read(ai, pBuf, 2, BAP1);
+	// length for remaining part of rid
+	len = min(len, le16_to_cpu(*(u16*)pBuf)) - 2;
+	
+	if ( len <= 2 ) {
+		printk( KERN_ERR 
+			"airo: Rid %x has a length of %d which is too short\n",
+			(int)rid,
+			(int)len );
+		rc = ERROR;
+                goto done;
+	}
+	// read remainder of the rid
+	if (bap_setup(ai, rid, 2, BAP1) != SUCCESS) {
+                rc = ERROR;
+                goto done;
+        }
+	rc = bap_read(ai, ((u16*)pBuf)+1, len, BAP1);
+ done:
+	spin_unlock_irqrestore(&ai->bap1_lock, flags);
+	return rc;
+}
+
+/*  Note, that we are using BAP1 which is also used by transmit, so
+ *  make sure this isnt called when a transmit is happening */
+static int PC4500_writerid(struct airo_info *ai, u16 rid, 
+			   const void *pBuf, int len)
+{
+	u16 status;
+        int flags;
+	int rc = SUCCESS;
+
+	spin_lock_irqsave(&ai->bap1_lock, flags);
+	// --- first access so that we can write the rid data
+	if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != 0) {
+                rc = status;
+                goto done;
+        }
+	// --- now write the rid data
+	if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
+                rc = ERROR;
+                goto done;
+        }
+	bap_write(ai, pBuf, len, BAP1);
+	// ---now commit the rid data
+	rc = PC4500_accessrid(ai, rid, 0x100|CMD_ACCESS);
+ done:
+	spin_unlock_irqrestore(&ai->bap1_lock, flags);
+        return rc;
+}
+
+/* Allocates a FID to be used for transmitting packets.  We only use
+   one for now. */
+static u16 transmit_allocate(struct airo_info *ai, int lenPayload)
+{
+	Cmd cmd;
+	Resp rsp;
+	u16 txFid;
+	u16 txControl;
+        int flags;
+
+	cmd.cmd = CMD_ALLOCATETX;
+	cmd.parm0 = lenPayload;
+	if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return 0;
+	if ( (rsp.status & 0xFF00) != 0) return 0;
+	/* wait for the allocate event/indication
+	 * It makes me kind of nervous that this can just sit here and spin,
+	 * but in practice it only loops like four times. */
+	while ( (IN4500(ai, EVSTAT) & EV_ALLOC) == 0) ;
+	// get the allocated fid and acknowledge
+	txFid = IN4500(ai, TXALLOCFID);
+	OUT4500(ai, EVACK, EV_ALLOC);
+  
+	/*  The CARD is pretty cool since it converts the ethernet packet
+	 *  into 802.11.  Also note that we don't release the FID since we
+	 *  will be using the same one over and over again. */
+	/*  We only have to setup the control once since we are not
+	 *  releasing the fid. */
+	txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_3
+		| TXCTL_ETHERNET | TXCTL_NORELEASE);
+	spin_lock_irqsave(&ai->bap1_lock, flags);
+	if (bap_setup(ai, txFid, 0x0008, BAP1) != SUCCESS) {
+		spin_unlock_irqrestore(&ai->bap1_lock, flags);
+		return ERROR;
+	}
+	bap_write(ai, &txControl, sizeof(txControl), BAP1);
+	spin_unlock_irqrestore(&ai->bap1_lock, flags);
+
+	return txFid;
+}
+
+/* In general BAP1 is dedicated to transmiting packets.  However,
+   since we need a BAP when accessing RIDs, we also use BAP1 for that.
+   Make sure the BAP1 spinlock is held when this is called. */
+static int transmit_802_3_packet(struct airo_info *ai, u16 txFid, 
+				 char *pPacket, int len)
+{
+	u16 payloadLen;
+	Cmd cmd;
+	Resp rsp;
+	
+	if (len < 12) {
+		printk( KERN_WARNING "Short packet %d\n", len );
+		return ERROR;
+	}
+	
+	// packet is destination[6], source[6], payload[len-12]
+	// write the payload length and dst/src/payload
+	if (bap_setup(ai, txFid, 0x0036, BAP1) != SUCCESS) return ERROR;
+	/* The hardware addresses aren't counted as part of the payload, so
+	 * we have to subtract the 12 bytes for the addresses off */
+	payloadLen = cpu_to_le16(len-12);
+	bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
+	bap_write(ai, (const u16*)pPacket, len, BAP1);
+	// issue the transmit command
+	memset( &cmd, 0, sizeof( cmd ) );
+	cmd.cmd = CMD_TRANSMIT;
+	cmd.parm0 = txFid;
+	if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
+	if ( (rsp.status & 0xFF00) != 0) return ERROR;
+	return SUCCESS;
+}
+
+/*
+ *  This is the proc_fs routines.  It is a bit messier than I would
+ *  like!  Feel free to clean it up!
+ */
+
+/*
+ *  Unfortunately sometime between 2.0 and 2.2 the proc interface changed...
+ *  Unfortunately I dont know when it was...
+ *  Im guessing it is sometime around 0x20155...  Anybody know?
+ */
+
+static ssize_t proc_read( struct file *file,
+			  char *buffer,
+			  size_t len,
+			  loff_t *offset);
+
+static ssize_t proc_write( struct file *file,
+			   const char *buffer,
+			   size_t len,
+			   loff_t *offset );
+static int proc_close( struct inode *inode, struct file *file );
+
+static int proc_stats_open( struct inode *inode, struct file *file );
+static int proc_statsdelta_open( struct inode *inode, struct file *file );
+static int proc_status_open( struct inode *inode, struct file *file );
+static int proc_SSID_open( struct inode *inode, struct file *file );
+static int proc_APList_open( struct inode *inode, struct file *file );
+static int proc_config_open( struct inode *inode, struct file *file );
+static int proc_wepkey_open( struct inode *inode, struct file *file );
+
+static struct file_operations proc_statsdelta_ops = {
+	read:           proc_read,
+	open:           proc_statsdelta_open,
+	release:        proc_close
+};
+
+static struct file_operations proc_stats_ops = {
+	read:           proc_read,
+	open:           proc_stats_open,
+	release:        proc_close
+};
+
+static struct file_operations proc_status_ops = {
+	read:            proc_read,
+	open:            proc_status_open,
+	release:         proc_close
+};
+
+static struct file_operations proc_SSID_ops = {
+	read:          proc_read,
+	write:         proc_write,
+	open:          proc_SSID_open,
+	release:       proc_close
+};
+
+static struct file_operations proc_APList_ops = {
+	read:          proc_read,
+	write:         proc_write,
+	open:          proc_APList_open,
+	release:       proc_close
+};
+
+static struct file_operations proc_config_ops = {
+	read:          proc_read,
+	write:         proc_write,
+	open:          proc_config_open,
+	release:       proc_close
+};
+
+static struct file_operations proc_wepkey_ops = {
+	read:          proc_read,
+	write:         proc_write,
+	open:          proc_wepkey_open,
+	release:       proc_close
+};
+
+static struct proc_dir_entry *airo_entry = 0;
+
+struct proc_data {
+	int release_buffer;
+	int readlen;
+	char *rbuffer;
+	int writelen;
+	int maxwritelen;
+	char *wbuffer;
+	void (*on_close) (struct inode *, struct file *);
+};
+
+static int setup_proc_entry( struct net_device *dev,
+			     struct airo_info *apriv ) {
+	struct proc_dir_entry *entry;
+	/* First setup the device directory */
+	apriv->proc_entry = create_proc_entry(dev->name,
+					      S_IFDIR|airo_perm,
+					      airo_entry);
+        apriv->proc_entry->uid = proc_uid;
+        apriv->proc_entry->gid = proc_gid;
+
+	/* Setup the StatsDelta */
+	entry = create_proc_entry("StatsDelta",
+				  S_IFREG | (S_IRUGO&proc_perm),
+				  apriv->proc_entry);
+        entry->uid = proc_uid;
+        entry->gid = proc_gid;
+	entry->data = dev;
+/*	This is what was needed right up to the last few versions
+        of 2.3:
+	entry->ops = &proc_inode_statsdelta_ops;
+*/
+	entry->proc_fops = &proc_statsdelta_ops;
+	
+	/* Setup the Stats */
+	entry = create_proc_entry("Stats",
+				  S_IFREG | (S_IRUGO&proc_perm),
+				  apriv->proc_entry);
+        entry->uid = proc_uid;
+        entry->gid = proc_gid;
+	entry->data = dev;
+	entry->proc_fops = &proc_stats_ops;
+	
+	/* Setup the Status */
+	entry = create_proc_entry("Status",
+				  S_IFREG | (S_IRUGO&proc_perm),
+				  apriv->proc_entry);
+        entry->uid = proc_uid;
+        entry->gid = proc_gid;
+	entry->data = dev;
+	entry->proc_fops = &proc_status_ops;
+	
+	/* Setup the Config */
+	entry = create_proc_entry("Config",
+				  S_IFREG | proc_perm,
+				  apriv->proc_entry);
+        entry->uid = proc_uid;
+        entry->gid = proc_gid;
+	entry->data = dev;
+	entry->proc_fops = &proc_config_ops;
+
+	/* Setup the SSID */
+	entry = create_proc_entry("SSID",
+				  S_IFREG | proc_perm,
+				  apriv->proc_entry);
+        entry->uid = proc_uid;
+        entry->gid = proc_gid;
+	entry->data = dev;
+	entry->proc_fops = &proc_SSID_ops;
+
+	/* Setup the APList */
+	entry = create_proc_entry("APList",
+				  S_IFREG | proc_perm,
+				  apriv->proc_entry);
+        entry->uid = proc_uid;
+        entry->gid = proc_gid;
+	entry->data = dev;
+	entry->proc_fops = &proc_APList_ops;
+
+	/* Setup the WepKey */
+	entry = create_proc_entry("WepKey",
+				  S_IFREG | proc_perm,
+				  apriv->proc_entry);
+        entry->uid = proc_uid;
+        entry->gid = proc_gid;
+	entry->data = dev;
+	entry->proc_fops = &proc_wepkey_ops;
+
+	return 0;
+}
+
+static int takedown_proc_entry( struct net_device *dev,
+				struct airo_info *apriv ) {
+	if ( !apriv->proc_entry->namelen ) return 0;
+	remove_proc_entry("Stats",apriv->proc_entry);
+	remove_proc_entry("StatsDelta",apriv->proc_entry);
+	remove_proc_entry("Status",apriv->proc_entry);
+	remove_proc_entry("Config",apriv->proc_entry);
+	remove_proc_entry("SSID",apriv->proc_entry);
+	remove_proc_entry("APList",apriv->proc_entry);
+	remove_proc_entry("WepKey",apriv->proc_entry);
+	remove_proc_entry(dev->name,airo_entry);
+	return 0;
+}
+
+/*
+ *  What we want from the proc_fs is to be able to efficiently read
+ *  and write the configuration.  To do this, we want to read the
+ *  configuration when the file is opened and write it when the file is
+ *  closed.  So basically we allocate a read buffer at open and fill it
+ *  with data, and allocate a write buffer and read it at close.
+ */
+
+/*
+ *  The read routine is generic, it relies on the preallocated rbuffer
+ *  to supply the data.
+ */
+static ssize_t proc_read( struct file *file,
+			  char *buffer,
+			  size_t len,
+			  loff_t *offset )
+{
+	int i;
+	int pos;
+	struct proc_data *priv = (struct proc_data*)file->private_data;
+	
+	if( !priv->rbuffer ) return -EINVAL;
+	
+	pos = *offset;
+	for( i = 0; i+pos < priv->readlen && i < len; i++ ) {
+		if (put_user( priv->rbuffer[i+pos], buffer+i ))
+			return -EFAULT;
+	}
+	*offset += i;
+	return i;
+}
+
+/*
+ *  The write routine is generic, it fills in a preallocated rbuffer
+ *  to supply the data.
+ */
+static ssize_t proc_write( struct file *file,
+			   const char *buffer,
+			   size_t len,
+			   loff_t *offset ) 
+{
+	int i;
+	int pos;
+	struct proc_data *priv = (struct proc_data*)file->private_data;
+	
+	if ( !priv->wbuffer ) {
+		return -EINVAL;
+	}
+	
+	pos = *offset;
+	
+	for( i = 0; i + pos <  priv->maxwritelen &&
+		     i < len; i++ ) {
+		if (get_user( priv->wbuffer[i+pos], buffer + i ))
+			return -EFAULT;
+	}
+	if ( i+pos > priv->writelen ) priv->writelen = i+file->f_pos;
+	*offset += i;
+	return i;
+}
+
+static int proc_status_open( struct inode *inode, struct file *file ) {
+	struct proc_data *data;
+	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct net_device *dev = dp->data;
+	struct airo_info *apriv = (struct airo_info *)dev->priv;
+	CapabilityRid cap_rid;
+	StatusRid status_rid;
+	
+	MOD_INC_USE_COUNT;
+	
+	dp = inode->u.generic_ip;
+	
+	if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
+		return -ENOMEM;
+	memset(file->private_data, 0, sizeof(struct proc_data));
+	data = (struct proc_data *)file->private_data;
+	if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
+		kfree (file->private_data);
+		return -ENOMEM;
+	}
+	
+	readStatusRid(apriv, &status_rid);
+	readCapabilityRid(apriv, &cap_rid);
+	
+	sprintf( data->rbuffer, "Mode: %x\n"
+		 "Signal Strength: %d\n"
+		 "Signal Quality: %d\n"
+		 "SSID: %-.*s\n"
+		 "AP: %-.16s\n"
+		 "Freq: %d\n"
+		 "BitRate: %dmbs\n"
+		 "Driver Version: %s\n"
+		 "Device: %s\nManufacturer: %s\nFirmware Version: %s\n"
+		 "Radio type: %x\nCountry: %x\nHardware Version: %x\n"
+		 "Software Version: %x\nSoftware Subversion: %x\n"
+		 "Boot block version: %x\n",
+		 (int)status_rid.mode,
+		 (int)status_rid.normalizedSignalStrength,
+		 (int)status_rid.signalQuality,
+		 (int)status_rid.SSIDlen,
+		 status_rid.SSID,
+		 status_rid.apName,
+		 (int)status_rid.channel,
+		 (int)status_rid.currentXmitRate/2,
+		 version,
+		 cap_rid.prodName,
+		 cap_rid.manName,
+		 cap_rid.prodVer,
+		 cap_rid.radioType,
+		 cap_rid.country,
+		 cap_rid.hardVer,
+		 (int)cap_rid.softVer,
+		 (int)cap_rid.softSubVer,
+		 (int)cap_rid.bootBlockVer );
+	data->readlen = strlen( data->rbuffer );
+	return 0;
+}
+
+static int proc_stats_rid_open(struct inode*, struct file*, u16);
+static int proc_statsdelta_open( struct inode *inode, 
+				 struct file *file ) {
+	if (file->f_mode&FMODE_WRITE) {
+		return proc_stats_rid_open(inode, file, RID_STATSDELTACLEAR);
+	}
+	return proc_stats_rid_open(inode, file, RID_STATSDELTA);
+}
+
+static int proc_stats_open( struct inode *inode, struct file *file ) {
+	return proc_stats_rid_open(inode, file, RID_STATS);
+}
+
+static int proc_stats_rid_open( struct inode *inode, 
+				struct file *file,
+				u16 rid ) {
+	struct proc_data *data;
+	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct net_device *dev = dp->data;
+	struct airo_info *apriv = (struct airo_info *)dev->priv;
+	StatsRid stats;
+	int i, j;
+	int *vals = stats.vals;
+	MOD_INC_USE_COUNT;
+	
+	
+	dp = inode->u.generic_ip;
+	
+	if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
+		return -ENOMEM;
+	memset(file->private_data, 0, sizeof(struct proc_data));
+	data = (struct proc_data *)file->private_data;
+	if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) {
+		kfree (file->private_data);
+		return -ENOMEM;
+	}
+	
+	readStatsRid(apriv, &stats, rid);
+	
+        j = 0;
+	for(i=0; (int)statsLabels[i]!=-1 && 
+		    i*4<stats.len; i++){
+		if (!statsLabels[i]) continue;
+		if (j+strlen(statsLabels[i])+16>4096) {
+			printk(KERN_WARNING
+			       "airo: Potentially disasterous buffer overflow averted!\n");
+			break;
+		}
+		j+=sprintf(data->rbuffer+j, "%s: %d\n", statsLabels[i], vals[i]);
+	}
+	if (i*4>=stats.len){
+		printk(KERN_WARNING
+		       "airo: Got a short rid\n");
+	}
+	data->readlen = j;
+	return 0;
+}
+
+static int get_dec_u16( char *buffer, int *start, int limit ) {
+	u16 value;
+	int valid = 0;
+	for( value = 0; buffer[*start] >= '0' &&
+		     buffer[*start] <= '9' &&
+		     *start < limit; (*start)++ ) {
+		valid = 1;
+		value *= 10;
+		value += buffer[*start] - '0';
+	}
+	if ( !valid ) return -1;
+	return value;
+}
+
+static void checkThrottle(ConfigRid *config) {
+	int i;
+/* Old hardware had a limit on encryption speed */
+	if (config->authType != AUTH_OPEN && maxencrypt) {
+		for(i=0; i<8; i++) {
+			if (config->rates[i] > maxencrypt) {
+				config->rates[i] = 0;
+			}
+		}
+	}
+}
+
+static void proc_config_on_close( struct inode *inode, struct file *file ) {
+	struct proc_data *data = file->private_data;
+	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct net_device *dev = dp->data;
+	struct airo_info *ai = (struct airo_info*)dev->priv;
+	ConfigRid config;
+	Resp rsp;
+	char *line;
+	int need_reset = 0;
+	
+	if ( !data->writelen ) return;
+	dp = (struct proc_dir_entry *) inode->u.generic_ip;
+	
+	disable_MAC(ai);
+	readConfigRid(ai, &config);
+
+	line = data->wbuffer;
+	while( line[0] ) {
+/*** Mode processing */
+		if ( !strncmp( line, "Mode: ", 6 ) ) {
+			line += 6;
+			config.rmode &= 0xfe00;
+			if ( line[0] == 'a' ) {
+				config.opmode = 0;
+			} else {
+				config.opmode = 1;
+				if ( line[0] == 'r' )
+					config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
+				else if ( line[0] == 'y' )
+					config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER;
+			}
+			if (config.rmode & RXMODE_DISABLE_802_3_HEADER) {
+				dev->type = ARPHRD_IEEE80211;
+				dev->hard_header_parse = wll_header_parse;
+			} else if (dev->type == ARPHRD_IEEE80211) {
+				dev->type = ARPHRD_ETHER;
+				dev->hard_header_parse = ai->header_parse;
+				need_reset = 1;
+			}
+		}
+		
+/*** Radio status */
+		else if (!strncmp(line,"Radio: ", 7)) {
+			line += 7;
+			if (!strncmp(line,"off",3)) {
+				ai->flags |= FLAG_RADIO_OFF;
+			} else {
+				ai->flags &= ~FLAG_RADIO_OFF;
+			}
+		}
+/*** NodeName processing */
+		else if ( !strncmp( line, "NodeName: ", 10 ) ) {
+			int j;
+			
+			line += 10;
+			memset( config.nodeName, 0, 16 );
+/* Do the name, assume a space between the mode and node name */
+			for( j = 0; j < 16 && line[j] != '\n'; j++ ) {
+				config.nodeName[j] = line[j];
+			}
+		} 
+		
+/*** PowerMode processing */
+		else if ( !strncmp( line, "PowerMode: ", 11 ) ) {
+			line += 11;
+			if ( !strncmp( line, "PSPCAM", 6 ) ) {
+				config.powerSaveMode = POWERSAVE_PSPCAM;
+			} else if ( !strncmp( line, "PSP", 3 ) ) {
+				config.powerSaveMode = POWERSAVE_PSP;
+			} else {
+				config.powerSaveMode = POWERSAVE_CAM;
+			}	
+		} else if ( !strncmp( line, "DataRates: ", 11 ) ) {
+			int v, i = 0, k = 0; /* i is index into line, 
+						k is index to rates */
+			
+			line += 11;
+			while((v = get_dec_u16(line, &i, 3))!=-1) {
+				config.rates[k++] = (u8)v;
+				line += i + 1;
+				i = 0;
+			}
+		} else if ( !strncmp( line, "Channel: ", 9 ) ) {
+			int v, i = 0;
+			line += 9;
+			v = get_dec_u16(line, &i, i+3);
+			if ( v != -1 ) 
+				config.channelSet = (u16)v;
+		} else if ( !strncmp( line, "XmitPower: ", 11 ) ) {
+			int v, i = 0;
+			line += 11;
+			v = get_dec_u16(line, &i, i+3);
+			if ( v != -1 ) config.txPower = (u16)v;
+		} else if ( !strncmp( line, "WEP: ", 5 ) ) {
+			line += 5;
+			switch( line[0] ) {
+			case 's':
+				config.authType = (u16)AUTH_SHAREDKEY;
+				break;
+			case 'e':
+				config.authType = (u16)AUTH_ENCRYPT;
+				break;
+			default:
+				config.authType = (u16)AUTH_OPEN;
+				break;
+			}
+		} else if ( !strncmp( line, "LongRetryLimit: ", 16 ) ) {
+			int v, i = 0;
+			
+			line += 16;
+			v = get_dec_u16(line, &i, 3);
+			v = (v<0) ? 0 : ((v>255) ? 255 : v);
+			config.longRetryLimit = (u16)v;
+		} else if ( !strncmp( line, "ShortRetryLimit: ", 17 ) ) {
+			int v, i = 0;
+			
+			line += 17;
+			v = get_dec_u16(line, &i, 3);
+			v = (v<0) ? 0 : ((v>255) ? 255 : v);
+			config.shortRetryLimit = (u16)v;
+		} else if ( !strncmp( line, "RTSThreshold: ", 14 ) ) {
+			int v, i = 0;
+			
+			line += 14;
+			v = get_dec_u16(line, &i, 4);
+			v = (v<0) ? 0 : ((v>2312) ? 2312 : v);
+			config.rtsThres = (u16)v;
+		} else if ( !strncmp( line, "TXMSDULifetime: ", 16 ) ) {
+			int v, i = 0;
+			
+			line += 16;
+			v = get_dec_u16(line, &i, 5);
+			v = (v<0) ? 0 : v;
+			config.txLifetime = (u16)v;
+		} else if ( !strncmp( line, "RXMSDULifetime: ", 16 ) ) {
+			int v, i = 0;
+			
+			line += 16;
+			v = get_dec_u16(line, &i, 5);
+			v = (v<0) ? 0 : v;
+			config.rxLifetime = (u16)v;
+		} else if ( !strncmp( line, "TXDiversity: ", 13 ) ) {
+			config.txDiversity = 
+				(line[13]=='l') ? 1 :
+				((line[13]=='r')? 2: 3);
+		} else if ( !strncmp( line, "RXDiversity: ", 13 ) ) {
+			config.rxDiversity = 
+				(line[13]=='l') ? 1 :
+				((line[13]=='r')? 2: 3);
+		} else if ( !strncmp( line, "FragThreshold: ", 15 ) ) {
+			int v, i = 0;
+			
+			line += 15;
+			v = get_dec_u16(line, &i, 4);
+			v = (v<256) ? 256 : ((v>2312) ? 2312 : v);
+			v = v & 0xfffe; /* Make sure its even */
+			config.fragThresh = (u16)v;
+		} else if (!strncmp(line, "Modulation: ", 12)) {
+			line += 12;
+			switch(*line) {
+			case 'd':  config.modulation=MOD_DEFAULT; break;
+			case 'c':  config.modulation=MOD_CCK; break;
+			case 'm':  config.modulation=MOD_MOK; break;
+			default:
+				printk( KERN_WARNING "airo: Unknown modulation\n" );
+			}
+		} else {
+			printk( KERN_WARNING "Couldn't figure out %s\n", line );
+		}
+		while( line[0] && line[0] != '\n' ) line++;
+		if ( line[0] ) line++;
+	}
+	checkThrottle(&config);
+	ai->config = config;
+	if (need_reset) {
+		APListRid APList_rid;
+		SsidRid SSID_rid;
+
+		readAPListRid(ai, &APList_rid);
+		readSsidRid(ai, &SSID_rid);
+		reset_airo_card(dev);
+		writeSsidRid(ai, &SSID_rid);
+		writeAPListRid(ai, &APList_rid);
+	}
+	writeConfigRid(ai, &config);
+	enable_MAC(ai, &rsp);
+}
+
+static int proc_config_open( struct inode *inode, struct file *file ) {
+	struct proc_data *data;
+	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct net_device *dev = dp->data;
+	struct airo_info *ai = (struct airo_info*)dev->priv;
+	ConfigRid config;
+	int i;
+	
+	MOD_INC_USE_COUNT;
+	
+	dp = (struct proc_dir_entry *) inode->u.generic_ip;
+	
+	if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
+		return -ENOMEM;
+	memset(file->private_data, 0, sizeof(struct proc_data));
+	data = (struct proc_data *)file->private_data;
+	if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
+		kfree (file->private_data);
+		return -ENOMEM;
+	}
+	if ((data->wbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
+		kfree (data->rbuffer);
+		kfree (file->private_data);
+		return -ENOMEM;
+	}
+	memset( data->wbuffer, 0, 2048 );
+	data->maxwritelen = 2048;
+	data->on_close = proc_config_on_close;
+	
+	readConfigRid(ai, &config);
+	
+	i = sprintf( data->rbuffer, 
+		     "Mode: %s\n"
+		     "Radio: %s\n"
+		     "NodeName: %-16s\n"
+		     "PowerMode: %s\n"
+		     "DataRates: %d %d %d %d %d %d %d %d\n"
+		     "Channel: %d\n"
+		     "XmitPower: %d\n",
+		     config.opmode == 0 ? "adhoc" : 
+		     config.opmode == 1 ? "ESS" :
+		     config.opmode == 2 ? "AP" : 
+		     config.opmode == 3 ? "AP RPTR" : "Error",
+		     ai->flags&FLAG_RADIO_OFF ? "off" : "on",
+		     config.nodeName,
+		     config.powerSaveMode == 0 ? "CAM" :
+		     config.powerSaveMode == 1 ? "PSP" :
+		     config.powerSaveMode == 2 ? "PSPCAM" : "Error",
+		     (int)config.rates[0],
+		     (int)config.rates[1],
+		     (int)config.rates[2],
+		     (int)config.rates[3],
+		     (int)config.rates[4],
+		     (int)config.rates[5],
+		     (int)config.rates[6],
+		     (int)config.rates[7],
+		     (int)config.channelSet,
+		     (int)config.txPower
+		);
+	sprintf( data->rbuffer + i,
+		 "LongRetryLimit: %d\n"
+		 "ShortRetryLimit: %d\n"
+		 "RTSThreshold: %d\n"
+		 "TXMSDULifetime: %d\n"
+		 "RXMSDULifetime: %d\n"
+		 "TXDiversity: %s\n"
+		 "RXDiversity: %s\n"
+		 "FragThreshold: %d\n"
+		 "WEP: %s\n"
+		 "Modulation: %s\n",
+		 (int)config.longRetryLimit,
+		 (int)config.shortRetryLimit,
+		 (int)config.rtsThres,
+		 (int)config.txLifetime,
+		 (int)config.rxLifetime,
+		 config.txDiversity == 1 ? "left" :
+		 config.txDiversity == 2 ? "right" : "both",
+		 config.rxDiversity == 1 ? "left" :
+		 config.rxDiversity == 2 ? "right" : "both",
+		 (int)config.fragThresh,
+		 config.authType == AUTH_ENCRYPT ? "encrypt" :
+		 config.authType == AUTH_SHAREDKEY ? "shared" : "open",
+		 config.modulation == 0 ? "default" :
+		 config.modulation == MOD_CCK ? "cck" :
+		 config.modulation == MOD_MOK ? "mok" : "error"
+		);
+	data->readlen = strlen( data->rbuffer );
+	return 0;
+}
+
+static void proc_SSID_on_close( struct inode *inode, struct file *file ) {
+	struct proc_data *data = (struct proc_data *)file->private_data;
+	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct net_device *dev = dp->data;
+	struct airo_info *ai = (struct airo_info*)dev->priv;
+	SsidRid SSID_rid;
+	int i;
+	int offset = 0;
+	
+	if ( !data->writelen ) return;
+	
+	memset( &SSID_rid, 0, sizeof( SSID_rid ) );
+	
+	for( i = 0; i < 3; i++ ) {
+		int j;
+		for( j = 0; j+offset < data->writelen && j < 32 &&
+			     data->wbuffer[offset+j] != '\n'; j++ ) {
+			SSID_rid.ssids[i].ssid[j] = data->wbuffer[offset+j];
+		}
+		if ( j == 0 ) break;
+		SSID_rid.ssids[i].len = j;
+		offset += j;
+		while( data->wbuffer[offset] != '\n' && 
+		       offset < data->writelen ) offset++;
+		offset++;
+	}
+	writeSsidRid(ai, &SSID_rid);
+}
+
+inline static u8 hexVal(char c) {
+	if (c>='0' && c<='9') return c -= '0';
+	if (c>='a' && c<='f') return c -= 'a'-10;
+	if (c>='A' && c<='F') return c -= 'A'-10;
+	return 0;
+}
+
+static void proc_APList_on_close( struct inode *inode, struct file *file ) {
+	struct proc_data *data = (struct proc_data *)file->private_data;
+	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct net_device *dev = dp->data;
+	struct airo_info *ai = (struct airo_info*)dev->priv;
+	APListRid APList_rid;
+	int i;
+	
+	if ( !data->writelen ) return;
+	
+	memset( &APList_rid, 0, sizeof(APList_rid) );
+	APList_rid.len = sizeof(APList_rid);
+	
+	for( i = 0; i < 4 && data->writelen >= (i+1)*6*3; i++ ) {
+		int j;
+		for( j = 0; j < 6*3 && data->wbuffer[j+i*6*3]; j++ ) {
+			switch(j%3) {
+			case 0:
+				APList_rid.ap[i][j/3]=
+					hexVal(data->wbuffer[j+i*6*3])<<4;
+				break;
+			case 1:
+				APList_rid.ap[i][j/3]|=
+					hexVal(data->wbuffer[j+i*6*3]);
+				break;
+			}
+		}
+	}
+	writeAPListRid(ai, &APList_rid);
+}
+
+/* This function wraps PC4500_writerid with a MAC disable */
+static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data,
+			int len ) {
+	int rc;
+	Resp rsp;
+	
+	disable_MAC(ai);
+	rc = PC4500_writerid(ai, rid, rid_data, len);
+	enable_MAC(ai, &rsp);
+	return rc;
+}
+
+/* Returns the length of the key at the index.  If index == 0xffff
+ * the index of the transmit key is returned.  If the key doesn't exist,
+ * -1 will be returned.
+ */
+static int get_wep_key(struct airo_info *ai, u16 index) {
+	WepKeyRid wkr;
+	int rc;
+	u16 lastindex;
+
+	rc = readWepKeyRid(ai, &wkr, 1);
+	if (rc == SUCCESS) do {
+		lastindex = wkr.kindex;
+		if (wkr.kindex == index) {
+			if (index == 0xffff) {
+				return wkr.mac[0];
+			}
+			return wkr.klen;
+		}
+		readWepKeyRid(ai, &wkr, 0);
+	} while(lastindex != wkr.kindex);
+	return -1;
+}
+
+static int set_wep_key(struct airo_info *ai, u16 index,
+		       const char *key, u16 keylen, int perm ) {
+	static const unsigned char macaddr[6] = { 0x01, 0, 0, 0, 0, 0 };
+	WepKeyRid wkr;
+
+	memset(&wkr, 0, sizeof(wkr));
+	if (keylen == 0) {
+// We are selecting which key to use
+		wkr.len = sizeof(wkr);
+		wkr.kindex = 0xffff;
+		wkr.mac[0] = (char)index;
+		if (perm) printk(KERN_INFO "Setting transmit key to %d\n", index);
+		if (perm) ai->defindex = (char)index;
+	} else {
+// We are actually setting the key
+		wkr.len = sizeof(wkr);
+		wkr.kindex = index;
+		wkr.klen = keylen;
+		memcpy( wkr.key, key, keylen );
+		memcpy( wkr.mac, macaddr, 6 );
+		printk(KERN_INFO "Setting key %d\n", index);
+	}
+	
+	writeWepKeyRid(ai, &wkr, perm);
+	return 0;
+}
+
+static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
+	struct proc_data *data;
+	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct net_device *dev = dp->data;
+	struct airo_info *ai = (struct airo_info*)dev->priv;
+	int i;
+	char key[16];
+	u16 index = 0;
+	int j = 0;
+
+	memset(key, 0, sizeof(key));
+	
+	dp = (struct proc_dir_entry *) inode->u.generic_ip;
+	data = (struct proc_data *)file->private_data;
+	if ( !data->writelen ) return;
+	
+	if (data->wbuffer[0] >= '0' && data->wbuffer[0] <= '3' &&
+	    (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
+		index = data->wbuffer[0] - '0';
+		if (data->wbuffer[1] == '\n') {
+			set_wep_key(ai, index, 0, 0, 1);
+			return;
+		}
+		j = 2;
+	} else {
+		printk(KERN_ERR "airo:  WepKey passed invalid key index\n");
+		return;
+	}
+
+	for( i = 0; i < 16*3 && data->wbuffer[i+j]; i++ ) {
+		switch(i%3) {
+		case 0:
+			key[i/3] = hexVal(data->wbuffer[i+j])<<4;
+			break;
+		case 1:
+			key[i/3] |= hexVal(data->wbuffer[i+j]);
+			break;
+		}
+	}
+	set_wep_key(ai, index, key, i/3, 1);
+}
+
+static int proc_wepkey_open( struct inode *inode, struct file *file ) {
+	struct proc_data *data;
+	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct net_device *dev = dp->data;
+	struct airo_info *ai = (struct airo_info*)dev->priv;
+	char *ptr;
+	WepKeyRid wkr;
+	u16 lastindex;
+	int j=0;
+	int rc;
+	
+	MOD_INC_USE_COUNT;
+	
+	dp = (struct proc_dir_entry *) inode->u.generic_ip;
+	
+	if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
+		return -ENOMEM;
+	memset(file->private_data, 0, sizeof(struct proc_data));
+	memset(&wkr, 0, sizeof(wkr));
+	data = (struct proc_data *)file->private_data;
+	if ((data->rbuffer = kmalloc( 180, GFP_KERNEL )) == NULL) {
+		kfree (file->private_data);
+		return -ENOMEM;
+	}
+	memset(data->rbuffer, 0, 180);
+	data->writelen = 0;
+	data->maxwritelen = 80;
+	if ((data->wbuffer = kmalloc( 80, GFP_KERNEL )) == NULL) {
+		kfree (data->rbuffer);
+		kfree (file->private_data);
+		return -ENOMEM;
+	}
+	memset( data->wbuffer, 0, 80 );
+	data->on_close = proc_wepkey_on_close;
+	
+	ptr = data->rbuffer;
+	strcpy(ptr, "No wep keys\n");
+	rc = readWepKeyRid(ai, &wkr, 1);
+	if (rc == SUCCESS) do {
+		lastindex = wkr.kindex;
+		if (wkr.kindex == 0xffff) {
+			j += sprintf(ptr+j, "Tx key = %d\n",
+				     (int)wkr.mac[0]);
+		} else {
+			j += sprintf(ptr+j, "Key %d set with length = %d\n",
+				     (int)wkr.kindex, (int)wkr.klen);
+		}
+		readWepKeyRid(ai, &wkr, 0);
+	} while((lastindex != wkr.kindex) && (j < 180-30));
+
+	data->readlen = strlen( data->rbuffer );
+	return 0;
+}
+
+static int proc_SSID_open( struct inode *inode, struct file *file ) {
+	struct proc_data *data;
+	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct net_device *dev = dp->data;
+	struct airo_info *ai = (struct airo_info*)dev->priv;
+	int i;
+	char *ptr;
+	SsidRid SSID_rid;
+
+	MOD_INC_USE_COUNT;
+	
+	dp = (struct proc_dir_entry *) inode->u.generic_ip;
+	
+	if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
+		return -ENOMEM;
+	memset(file->private_data, 0, sizeof(struct proc_data));
+	data = (struct proc_data *)file->private_data;
+	if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
+		kfree (file->private_data);
+		return -ENOMEM;
+	}
+	data->writelen = 0;
+	data->maxwritelen = 33*3;
+	if ((data->wbuffer = kmalloc( 33*3, GFP_KERNEL )) == NULL) {
+		kfree (data->rbuffer);
+		kfree (file->private_data);
+		return -ENOMEM;
+	}
+	memset( data->wbuffer, 0, 33*3 );
+	data->on_close = proc_SSID_on_close;
+	
+	readSsidRid(ai, &SSID_rid);
+	ptr = data->rbuffer;
+	for( i = 0; i < 3; i++ ) {
+		int j;
+		if ( !SSID_rid.ssids[i].len ) break;
+		for( j = 0; j < 32 && 
+			     j < SSID_rid.ssids[i].len && 
+			     SSID_rid.ssids[i].ssid[j]; j++ ) {
+			*ptr++ = SSID_rid.ssids[i].ssid[j]; 
+		}
+		*ptr++ = '\n';
+	}
+	*ptr = '\0';
+	data->readlen = strlen( data->rbuffer );
+	return 0;
+}
+
+static int proc_APList_open( struct inode *inode, struct file *file ) {
+	struct proc_data *data;
+	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct net_device *dev = dp->data;
+	struct airo_info *ai = (struct airo_info*)dev->priv;
+	int i;
+	char *ptr;
+	APListRid APList_rid;
+
+	MOD_INC_USE_COUNT;
+	
+	dp = (struct proc_dir_entry *) inode->u.generic_ip;
+	
+	if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
+		return -ENOMEM;
+	memset(file->private_data, 0, sizeof(struct proc_data));
+	data = (struct proc_data *)file->private_data;
+	if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
+		kfree (file->private_data);
+		return -ENOMEM;
+	}
+	data->writelen = 0;
+	data->maxwritelen = 4*6*3;
+	if ((data->wbuffer = kmalloc( data->maxwritelen, GFP_KERNEL )) == NULL) {
+		kfree (data->rbuffer);
+		kfree (file->private_data);
+		return -ENOMEM;
+	}
+	memset( data->wbuffer, 0, data->maxwritelen );
+	data->on_close = proc_APList_on_close;
+	
+	readAPListRid(ai, &APList_rid);
+	ptr = data->rbuffer;
+	for( i = 0; i < 4; i++ ) {
+// We end when we find a zero MAC
+		if ( !*(int*)APList_rid.ap[i] &&
+		     !*(int*)&APList_rid.ap[i][2]) break;
+		ptr += sprintf(ptr, "%02x:%02x:%02x:%02x:%02x:%02x\n",
+			       (int)APList_rid.ap[i][0],
+			       (int)APList_rid.ap[i][1],
+			       (int)APList_rid.ap[i][2],
+			       (int)APList_rid.ap[i][3],
+			       (int)APList_rid.ap[i][4],
+			       (int)APList_rid.ap[i][5]);
+	}
+	if (i==0) ptr += sprintf(ptr, "Not using specific APs\n");
+
+	*ptr = '\0';
+	data->readlen = strlen( data->rbuffer );
+	return 0;
+}
+
+static int proc_close( struct inode *inode, struct file *file ) 
+{
+	struct proc_data *data = (struct proc_data *)file->private_data;
+	if ( data->on_close != NULL ) data->on_close( inode, file );
+	MOD_DEC_USE_COUNT;
+	if ( data->rbuffer ) kfree( data->rbuffer );
+	if ( data->wbuffer ) kfree( data->wbuffer );
+	kfree( data );
+	return 0;
+}
+
+static struct net_device_list {
+	struct net_device *dev;
+	struct net_device_list *next;
+} *airo_devices = 0;
+
+/* Since the card doesnt automatically switch to the right WEP mode,
+   we will make it do it.  If the card isn't associated, every secs we
+   will switch WEP modes to see if that will help.  If the card is
+   associated we will check every minute to see if anything has
+   changed. */
+static void timer_func( u_long data ) {
+	struct net_device *dev = (struct net_device*)data;
+	struct airo_info *apriv = (struct airo_info *)dev->priv;
+	u16 linkstat = IN4500(apriv, LINKSTAT);
+	
+	if (linkstat != 0x400 ) {
+/* We don't have a link so try changing the authtype */
+		ConfigRid config = apriv->config;
+
+		switch(apriv->authtype) {
+		case AUTH_ENCRYPT:
+/* So drop to OPEN */
+			config.authType = AUTH_OPEN;
+			apriv->authtype = AUTH_OPEN;
+			break;
+		case AUTH_SHAREDKEY:
+			if (apriv->keyindex < auto_wep) {
+				set_wep_key(apriv, apriv->keyindex, 0, 0, 0);
+				config.authType = AUTH_SHAREDKEY;
+				apriv->authtype = AUTH_SHAREDKEY;
+				apriv->keyindex++;
+			} else {
+			        /* Drop to ENCRYPT */
+				apriv->keyindex = 0;
+				set_wep_key(apriv, apriv->defindex, 0, 0, 0);
+				config.authType = AUTH_ENCRYPT;
+				apriv->authtype = AUTH_ENCRYPT;
+			}
+			break;
+		default:  /* We'll escalate to SHAREDKEY */
+			config.authType = AUTH_SHAREDKEY;
+			apriv->authtype = AUTH_SHAREDKEY;
+		}
+		checkThrottle(&config);
+		writeConfigRid(apriv, &config);
+
+/* Schedule check to see if the change worked */
+		apriv->timer.expires = RUN_AT(HZ*3);
+		add_timer(&apriv->timer);
+	}
+}
+
+static int add_airo_dev( struct net_device *dev ) {
+	struct net_device_list *node = kmalloc( sizeof( *node ), GFP_KERNEL );
+	if ( !node )
+		return -ENOMEM;
+
+	if ( auto_wep ) {
+		struct airo_info *apriv=dev->priv;
+		struct timer_list *timer = &apriv->timer;
+			
+		timer->function = timer_func;
+		timer->data = (u_long)dev;
+		init_timer(timer);
+		apriv->authtype = AUTH_SHAREDKEY;
+	}
+		
+	node->dev = dev;
+	node->next = airo_devices;
+	airo_devices = node;
+
+	return 0;
+}
+
+static void del_airo_dev( struct net_device *dev ) {
+	struct net_device_list **p = &airo_devices;
+	while( *p && ( (*p)->dev != dev ) )
+		p = &(*p)->next;
+	if ( *p && (*p)->dev == dev )
+		*p = (*p)->next; 
+}
+
+#ifdef CONFIG_PCI
+static int __devinit airo_pci_probe(struct pci_dev *pdev, 
+				    const struct pci_device_id *pent)
+{
+	pdev->driver_data = init_airo_card(pdev->irq, 
+					   pdev->resource[2].start, 0);
+	if (!pdev->driver_data) {
+		return -ENODEV;
+	}
+	return 0;
+}
+
+static void __devexit airo_pci_remove(struct pci_dev *pdev)
+{
+	stop_airo_card(pdev->driver_data, 1);
+}
+
+#endif
+
+static int __init airo_init_module( void )
+{
+	int i, rc = 0, have_isa_dev = 0;
+	
+	airo_entry = create_proc_entry("aironet",
+				       S_IFDIR | airo_perm,
+				       proc_root_driver);
+        airo_entry->uid = proc_uid;
+        airo_entry->gid = proc_gid;
+	
+	for( i = 0; i < 4 && io[i] && irq[i]; i++ ) {
+		printk( KERN_INFO 
+			"airo:  Trying to configure ISA adapter at irq=%d io=0x%x\n",
+			irq[i], io[i] );
+		if (init_airo_card( irq[i], io[i], 0 ))
+			have_isa_dev = 1;
+	}
+	
+#ifdef CONFIG_PCI
+	printk( KERN_INFO "airo:  Probing for PCI adapters\n" );
+	rc = pci_module_init(&airo_driver);
+	printk( KERN_INFO "airo:  Finished probing for PCI adapters\n" );
+#endif
+
+	/* arguably, we should clean up and error exit if pci_module_init
+	 * fails with an error other than -ENODEV, instead of proceeding,
+	 * if ISA devs are present.
+	 */
+	if (have_isa_dev)
+		return 0;
+	if (rc && (rc != -ENODEV))
+		return rc;
+	return 0;
+}
+
+static void __exit airo_cleanup_module( void )
+{
+	while( airo_devices ) {
+		printk( KERN_INFO "airo: Unregistering %s\n", airo_devices->dev->name );
+		stop_airo_card( airo_devices->dev, 1 );
+	}
+	remove_proc_entry("aironet", proc_root_driver);
+}
+
+#ifdef WIRELESS_EXT
+/*
+ * Initial Wireless Extension code for Aironet driver by :
+ *	Jean Tourrilhes <jt@hpl.hp.com> - HPL - 17 November 00
+ */
+#ifndef IW_ENCODE_NOKEY
+#define IW_ENCODE_NOKEY         0x0800  /* Key is write only, so not present */
+#define IW_ENCODE_MODE  (IW_ENCODE_DISABLED | IW_ENCODE_RESTRICTED | IW_ENCODE_OPEN)
+#endif /* IW_ENCODE_NOKEY */
+#endif /* WIRELESS_EXT */
+
+/*
+ * This defines the configuration part of the Wireless Extensions
+ * Note : irq and spinlock protection will occur in the subroutines
+ *
+ * TODO :
+ *	o Check input value more carefully and fill correct values in range
+ *	o Implement : POWER, SPY, APLIST
+ *	o Optimise when adapter is closed (aggregate changes, commit later)
+ *	o Test and shakeout the bugs (if any)
+ *
+ * Jean II
+ *
+ * Javier Achirica did a great job of merging code from the unnamed CISCO
+ * developer that added support for flashing the card.
+ */
+static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	int rc = 0;
+#ifdef WIRELESS_EXT
+	struct airo_info *local = (struct airo_info*) dev->priv;
+	struct iwreq *wrq = (struct iwreq *) rq;
+	ConfigRid config;		/* Configuration info */
+	CapabilityRid cap_rid;		/* Card capability info */
+	StatusRid status_rid;		/* Card status info */
+	int i;
+
+#ifdef CISCO_EXT
+	if (cmd != SIOCGIWPRIV && cmd != AIROIOCTL && cmd != AIROIDIFC)
+#endif /* CISCO_EXT */
+	{
+		/* If the command read some stuff, we better get it out of
+		 * the card first... */
+		if(IW_IS_GET(cmd))
+			readStatusRid(local, &status_rid);
+		if(IW_IS_GET(cmd) || (cmd == SIOCSIWRATE) || (cmd == SIOCSIWENCODE))
+			readCapabilityRid(local, &cap_rid);
+		/* Get config in all cases, because SET will just modify it */
+		readConfigRid(local, &config);
+	}
+#endif /* WIRELESS_EXT */
+
+	switch (cmd) {
+#ifdef WIRELESS_EXT
+		// Get name
+	case SIOCGIWNAME:
+		strcpy(wrq->u.name, "IEEE 802.11-DS");
+		break;
+
+		// Set frequency/channel
+	case SIOCSIWFREQ:
+		/* If setting by frequency, convert to a channel */
+		if((wrq->u.freq.e == 1) &&
+		   (wrq->u.freq.m >= (int) 2.412e8) &&
+		   (wrq->u.freq.m <= (int) 2.487e8)) {
+			int f = wrq->u.freq.m / 100000;
+			int c = 0;
+			while((c < 14) && (f != frequency_list[c]))
+				c++;
+			/* Hack to fall through... */
+			wrq->u.freq.e = 0;
+			wrq->u.freq.m = c + 1;
+		}
+		/* Setting by channel number */
+		if((wrq->u.freq.m > 1000) || (wrq->u.freq.e > 0))
+			rc = -EOPNOTSUPP;
+		else {
+			int channel = wrq->u.freq.m;
+			/* We should do a better check than that,
+			 * based on the card capability !!! */
+			if((channel < 1) || (channel > 16)) {
+				printk(KERN_DEBUG "%s: New channel value of %d is invalid!\n", dev->name, wrq->u.freq.m);
+				rc = -EINVAL;
+			} else {
+				/* Yes ! We can set it !!! */
+				config.channelSet = (u16)(channel - 1);
+				local->need_commit = 1;
+			}
+		}
+		break;
+
+		// Get frequency/channel
+	case SIOCGIWFREQ:
+#ifdef WEXT_USECHANNELS
+		wrq->u.freq.m = ((int)status_rid.channel) + 1;
+		wrq->u.freq.e = 0;
+#else
+		{
+			int f = (int)status_rid.channel;
+			wrq->u.freq.m = frequency_list[f] * 100000;
+			wrq->u.freq.e = 1;
+		}
+#endif
+		break;
+
+		// Set desired network name (ESSID)
+	case SIOCSIWESSID:
+		if (wrq->u.data.pointer) {
+			char	essid[IW_ESSID_MAX_SIZE + 1];
+			SsidRid SSID_rid;		/* SSIDs */
+
+			/* Reload the list of current SSID */
+			readSsidRid(local, &SSID_rid);
+
+			/* Check if we asked for `any' */
+			if(wrq->u.data.flags == 0) {
+				/* Just send an empty SSID list */
+				memset(&SSID_rid, 0, sizeof(SSID_rid));
+			} else {
+				int	index = (wrq->u.data.flags &
+						 IW_ENCODE_INDEX) - 1;
+
+				/* Check the size of the string */
+				if(wrq->u.data.length > IW_ESSID_MAX_SIZE+1) {
+					rc = -E2BIG;
+					break;
+				}
+				/* Check if index is valid */
+				if((index < 0) || (index >= 4)) {
+					rc = -EINVAL;
+					break;
+				}
+
+				/* Set the SSID */
+				memset(essid, 0, sizeof(essid));
+				copy_from_user(essid,
+					       wrq->u.data.pointer,
+					       wrq->u.data.length);
+				memcpy(SSID_rid.ssids[index].ssid, essid,
+				       sizeof(essid) - 1);
+				SSID_rid.ssids[index].len = wrq->u.data.length - 1;
+			}
+			/* Write it to the card */
+			writeSsidRid(local, &SSID_rid);
+		}
+		break;
+
+		// Get current network name (ESSID)
+	case SIOCGIWESSID:
+		if (wrq->u.data.pointer) {
+			char essid[IW_ESSID_MAX_SIZE + 1];
+
+			/* Note : if wrq->u.data.flags != 0, we should
+			 * get the relevant SSID from the SSID list... */
+
+			/* Get the current SSID */
+			memcpy(essid, status_rid.SSID, status_rid.SSIDlen);
+			essid[status_rid.SSIDlen] = '\0';
+			/* If none, we may want to get the one that was set */
+
+			/* Push it out ! */
+			wrq->u.data.length = strlen(essid) + 1;
+			wrq->u.data.flags = 1; /* active */
+			if (copy_to_user(wrq->u.data.pointer, essid, sizeof(essid)))
+				rc = -EFAULT;
+		}
+		break;
+
+	case SIOCSIWAP:
+		if (wrq->u.ap_addr.sa_family != ARPHRD_ETHER)
+			rc = -EINVAL;
+		else {
+			APListRid APList_rid;
+
+			memset(&APList_rid, 0, sizeof(APList_rid));
+			APList_rid.len = sizeof(APList_rid);
+			memcpy(APList_rid.ap[0], wrq->u.ap_addr.sa_data, 6);
+			writeAPListRid(local, &APList_rid);
+			local->need_commit = 1;
+		}
+		break;
+
+		// Get current Access Point (BSSID)
+	case SIOCGIWAP:
+		/* Tentative. This seems to work, wow, I'm lucky !!! */
+		memcpy(wrq->u.ap_addr.sa_data, status_rid.bssid[0], 6);
+		wrq->u.ap_addr.sa_family = ARPHRD_ETHER;
+		break;
+
+		// Set desired station name
+	case SIOCSIWNICKN:
+		if (wrq->u.data.pointer) {
+			char	name[16 + 1];
+
+			/* Check the size of the string */
+			if(wrq->u.data.length > 16 + 1) {
+				rc = -E2BIG;
+				break;
+			}
+			memset(name, 0, sizeof(name));
+			copy_from_user(name, wrq->u.data.pointer, wrq->u.data.length);
+			memcpy(config.nodeName, name, 16);
+			local->need_commit = 1;
+		}
+		break;
+
+		// Get current station name
+	case SIOCGIWNICKN:
+		if (wrq->u.data.pointer) {
+			char name[IW_ESSID_MAX_SIZE + 1];
+
+			strncpy(name, config.nodeName, 16);
+			name[16] = '\0';
+			wrq->u.data.length = strlen(name) + 1;
+			if (copy_to_user(wrq->u.data.pointer, name, sizeof(name)))
+				rc = -EFAULT;
+		}
+		break;
+
+		// Set the desired bit-rate
+	case SIOCSIWRATE:
+	{
+		/* First : get a valid bit rate value */
+		u8	brate = 0;
+		int	i;
+
+		/* Which type of value ? */
+		if((wrq->u.bitrate.value < 8) &&
+		   (wrq->u.bitrate.value >= 0)) {
+			/* Setting by rate index */
+			/* Find value in the magic rate table */
+			brate = cap_rid.supportedRates[wrq->u.bitrate.value];
+		} else {
+			/* Setting by frequency value */
+			u8	normvalue = (u8) (wrq->u.bitrate.value/500000);
+
+			/* Check if rate is valid */
+			for(i = 0 ; i < 8 ; i++) {
+				if(normvalue == cap_rid.supportedRates[i]) {
+					brate = normvalue;
+					break;
+				}
+			}
+		}
+		/* -1 designed the max rate (mostly auto mode) */
+		if(wrq->u.bitrate.value == -1) {
+			/* Get the highest available rate */
+			for(i = 0 ; i < 8 ; i++) {
+				if(cap_rid.supportedRates[i] == 0)
+					break;
+			}
+			if(i != 0)
+				brate = cap_rid.supportedRates[i - 1];
+		}
+		/* Check that it is valid */
+		if(brate == 0) {
+			rc = -EINVAL;
+			break;
+		}
+
+		/* Now, check if we want a fixed or auto value */
+		if(wrq->u.bitrate.fixed == 0) {
+			/* Fill all the rates up to this max rate */
+			memset(config.rates, 0, 8);
+			for(i = 0 ; i < 8 ; i++) {
+				config.rates[i] = cap_rid.supportedRates[i];
+				if(config.rates[i] == brate)
+					break;
+			}
+			local->need_commit = 1;
+		} else {
+			/* Fixed mode */
+			/* One rate, fixed */
+			memset(config.rates, 0, 8);
+			config.rates[0] = brate;
+			local->need_commit = 1;
+		}
+		break;
+	}
+
+	// Get the current bit-rate
+	case SIOCGIWRATE:
+	{
+		int brate = status_rid.currentXmitRate;
+		wrq->u.bitrate.value = brate * 500000;
+		/* If more than one rate, set auto */
+		wrq->u.rts.fixed = (config.rates[1] == 0);
+	}
+	break;
+
+	// Set the desired RTS threshold
+	case SIOCSIWRTS:
+	{
+		int rthr = wrq->u.rts.value;
+		if(wrq->u.rts.disabled)
+			rthr = 2312;
+		if((rthr < 0) || (rthr > 2312)) {
+			rc = -EINVAL;
+		} else {
+			config.rtsThres = rthr;
+			local->need_commit = 1;
+		}
+	}
+	break;
+
+	// Get the current RTS threshold
+	case SIOCGIWRTS:
+		wrq->u.rts.value = config.rtsThres;
+		wrq->u.rts.disabled = (wrq->u.rts.value >= 2312);
+		wrq->u.rts.fixed = 1;
+		break;
+
+		// Set the desired fragmentation threshold
+	case SIOCSIWFRAG:
+	{
+		int fthr = wrq->u.frag.value;
+		if(wrq->u.frag.disabled)
+			fthr = 2312;
+		if((fthr < 256) || (fthr > 2312)) {
+			rc = -EINVAL;
+		} else {
+			fthr &= ~0x1;	/* Get an even value */
+			config.fragThresh = (u16)fthr;
+			local->need_commit = 1;
+		}
+	}
+	break;
+
+	// Get the current fragmentation threshold
+	case SIOCGIWFRAG:
+		wrq->u.frag.value = config.fragThresh;
+		wrq->u.frag.disabled = (wrq->u.frag.value >= 2312);
+		wrq->u.frag.fixed = 1;
+		break;
+
+		// Set mode of operation
+	case SIOCSIWMODE:
+		switch(wrq->u.mode) {
+		case IW_MODE_ADHOC:
+			config.opmode = MODE_STA_IBSS;
+			local->need_commit = 1;
+			break;
+		case IW_MODE_INFRA:
+			config.opmode = MODE_STA_ESS;
+			local->need_commit = 1;
+			break;
+		case IW_MODE_MASTER:
+			config.opmode = MODE_AP;
+			local->need_commit = 1;
+			break;
+		case IW_MODE_REPEAT:
+			config.opmode = MODE_AP_RPTR;
+			local->need_commit = 1;
+			break;
+		default:
+			rc = -EINVAL;
+		}
+		break;
+
+		// Get mode of operation
+	case SIOCGIWMODE:
+		/* If not managed, assume it's ad-hoc */
+		switch (config.opmode & 0xFF) {
+		case MODE_STA_ESS:
+			wrq->u.mode = IW_MODE_INFRA;
+			break;
+		case MODE_AP:
+			wrq->u.mode = IW_MODE_MASTER;
+			break;
+		case MODE_AP_RPTR:
+			wrq->u.mode = IW_MODE_REPEAT;
+			break;
+		default:
+			wrq->u.mode = IW_MODE_ADHOC;
+		}
+		break;
+
+		// Set WEP keys and mode
+	case SIOCSIWENCODE:
+		/* Is WEP supported ? */
+		/* Older firmware doesn't support this...
+		if(!(cap_rid.softCap & 2)) {
+			rc = -EOPNOTSUPP;
+			break;
+		} */
+		/* Basic checking: do we have a key to set ? */
+		if (wrq->u.encoding.pointer != (caddr_t) 0) {
+			wep_key_t key;
+			int index = (wrq->u.encoding.flags & IW_ENCODE_INDEX) - 1;
+			int current_index = get_wep_key(local, 0xffff);
+			/* Check the size of the key */
+			if (wrq->u.encoding.length > MAX_KEY_SIZE) {
+				rc = -EINVAL;
+				break;
+			}
+			/* Check the index (none -> use current) */
+			if ((index < 0) || (index >= MAX_KEYS))
+				index = current_index;
+			/* Set the length */
+			if (wrq->u.encoding.length > MIN_KEY_SIZE)
+				key.len = MAX_KEY_SIZE;
+			else
+				if (wrq->u.encoding.length > 0)
+					key.len = MIN_KEY_SIZE;
+				else
+					/* Disable the key */
+					key.len = 0;
+			/* Check if the key is not marked as invalid */
+			if(!(wrq->u.encoding.flags & IW_ENCODE_NOKEY)) {
+				/* Cleanup */
+				memset(key.key, 0, MAX_KEY_SIZE);
+				/* Copy the key in the driver */
+				if(copy_from_user(key.key,
+						  wrq->u.encoding.pointer,
+						  wrq->u.encoding.length)) {
+					key.len = 0;
+					rc = -EFAULT;
+					break;
+				}
+				/* Send the key to the card */
+				set_wep_key(local, index, key.key,
+					    key.len, 1);
+			}
+			/* WE specify that if a valid key is set, encryption
+			 * should be enabled (user may turn it off later)
+			 * This is also how "iwconfig ethX key on" works */
+			if((index == current_index) && (key.len > 0) &&
+			   (config.authType == AUTH_OPEN)) {
+				config.authType = AUTH_ENCRYPT;
+				local->need_commit = 1;
+			}
+		} else {
+			/* Do we want to just set the transmit key index ? */
+			int index = (wrq->u.encoding.flags & IW_ENCODE_INDEX) - 1;
+			if ((index >= 0) && (index < MAX_KEYS)) {
+				set_wep_key(local, index, 0, 0, 1);
+			} else
+				/* Don't complain if only change the mode */
+				if(!wrq->u.encoding.flags & IW_ENCODE_MODE) {
+					rc = -EINVAL;
+					break;
+				}
+		}
+		/* Read the flags */
+		if(wrq->u.encoding.flags & IW_ENCODE_DISABLED)
+			config.authType = AUTH_OPEN;	// disable encryption
+		if(wrq->u.encoding.flags & IW_ENCODE_RESTRICTED)
+			config.authType = AUTH_SHAREDKEY;	// Only Both
+		if(wrq->u.encoding.flags & IW_ENCODE_OPEN)
+			config.authType = AUTH_ENCRYPT;	// Only Wep
+		/* Commit the changes if needed */
+		if(wrq->u.encoding.flags & IW_ENCODE_MODE)
+			local->need_commit = 1;
+		break;
+
+		// Get the WEP keys and mode
+	case SIOCGIWENCODE:
+		/* Is it supported ? */
+		if(!(cap_rid.softCap & 2)) {
+			rc = -EOPNOTSUPP;
+			break;
+		}
+		// Only super-user can see WEP key
+		if (!capable(CAP_NET_ADMIN)) {
+			rc = -EPERM;
+			break;
+		}
+
+		// Basic checking...
+		if (wrq->u.encoding.pointer != (caddr_t) 0) {
+			char zeros[16];
+			int index = (wrq->u.encoding.flags & IW_ENCODE_INDEX) - 1;
+
+			memset(zeros,0, sizeof(zeros));
+			/* Check encryption mode */
+			wrq->u.encoding.flags = IW_ENCODE_NOKEY;
+			/* Is WEP enabled ??? */
+			switch(config.authType)	{
+			case AUTH_ENCRYPT:
+				wrq->u.encoding.flags |= IW_ENCODE_OPEN;
+				break;
+			case AUTH_SHAREDKEY:
+				wrq->u.encoding.flags |= IW_ENCODE_RESTRICTED;
+				break;
+			default:
+			case AUTH_OPEN:
+				wrq->u.encoding.flags |= IW_ENCODE_DISABLED;
+				break;
+			}
+
+			/* Which key do we want ? -1 -> tx index */
+			if((index < 0) || (index >= MAX_KEYS))
+				index = get_wep_key(local, 0xffff);
+			wrq->u.encoding.flags |= index + 1;
+			/* Copy the key to the user buffer */
+			wrq->u.encoding.length = get_wep_key(local, index);
+			if (wrq->u.encoding.length > 16) {
+				wrq->u.encoding.length=0;
+			}
+
+			if(copy_to_user(wrq->u.encoding.pointer, zeros,
+					wrq->u.encoding.length))
+				rc = -EFAULT;
+		}
+		break;
+
+#if WIRELESS_EXT > 9
+		// Get the current Tx-Power
+	case SIOCGIWTXPOW:
+		wrq->u.txpower.value = config.txPower;
+		wrq->u.txpower.fixed = 1;	/* No power control */
+		wrq->u.txpower.disabled = (local->flags & FLAG_RADIO_OFF);
+		wrq->u.txpower.flags = IW_TXPOW_MWATT;
+		break;
+	case SIOCSIWTXPOW:
+		if (wrq->u.txpower.disabled) {
+			local->flags |= FLAG_RADIO_OFF;
+			local->need_commit = 1;
+			break;
+		}
+		if (wrq->u.txpower.flags != IW_TXPOW_MWATT) {
+			rc = -EINVAL;
+			break;
+		}
+		local->flags &= ~FLAG_RADIO_OFF;
+		rc = -EINVAL;
+		for (i = 0; cap_rid.txPowerLevels[i] && (i < 8); i++)
+			if ((wrq->u.txpower.value==cap_rid.txPowerLevels[i])) {
+				config.txPower = wrq->u.txpower.value;
+				local->need_commit = 1;
+				rc = 0;
+				break;
+			}
+		break;
+#endif /* WIRELESS_EXT > 9 */
+
+#if WIRELESS_EXT > 10
+	case SIOCGIWRETRY:
+		wrq->u.retry.disabled = 0;
+		if ((wrq->u.retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME)
+			wrq->u.retry.value = (int)config.txLifetime * 1024;
+		else {
+			wrq->u.retry.value = (int)config.shortRetryLimit;
+			wrq->u.retry.flags = IW_RETRY_LIMIT;
+		}
+		break;
+
+	case SIOCSIWRETRY: 
+		if (wrq->u.retry.disabled) {
+			config.shortRetryLimit = 0;
+			config.longRetryLimit = 0;
+			config.txLifetime = 0;
+			local->need_commit = 1;
+			break;
+		}
+		if ((wrq->u.retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
+			config.txLifetime = (wrq->u.retry.value + 500) / 1024;
+			local->need_commit = 1;
+		} else if ((wrq->u.retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIMIT) {
+			config.shortRetryLimit = config.longRetryLimit = wrq->u.retry.value;
+			local->need_commit = 1;
+		}
+		break;
+#endif /* WIRELESS_EXT > 10 */
+
+		// Get range of parameters
+	case SIOCGIWRANGE:
+		if (wrq->u.data.pointer) {
+			struct iw_range range;
+			int		i;
+			int		k;
+
+			wrq->u.data.length = sizeof(range);
+			/* Should adapt depending on max rate */
+			range.throughput = 1.6 * 1024 * 1024;
+			range.min_nwid = 0x0000;
+			range.max_nwid = 0x0000;
+			range.num_channels = 14;
+			/* Should be based on cap_rid.country to give only
+			 * what the current card support */
+			k = 0;
+			for(i = 0; i < 14; i++) {
+				range.freq[k].i = i + 1; /* List index */
+				range.freq[k].m = frequency_list[i] * 100000;
+				range.freq[k++].e = 1;	/* Values in table in MHz -> * 10^5 * 10 */
+			}
+			range.num_frequency = k;
+
+			/* Hum... Should put the right values there */
+			range.max_qual.qual = 10;
+			range.max_qual.level = 100;
+			range.max_qual.noise = 0;
+			range.sensitivity = 65535;
+
+			for(i = 0 ; i < 8 ; i++) {
+				range.bitrate[i] = cap_rid.supportedRates[i] * 500000;
+				if(range.bitrate[i] == 0)
+					break;
+			}
+			range.num_bitrates = i;
+
+			range.min_rts = 0;
+			range.max_rts = 2312;
+			range.min_frag = 256;
+			range.max_frag = 2312;
+
+			if(cap_rid.softCap & 2) {
+				// WEP: RC4 40 bits
+				range.encoding_size[0] = 5;
+				// RC4 ~128 bits
+				if (cap_rid.softCap & 0x100) {
+					range.encoding_size[1] = 13;
+					range.num_encoding_sizes = 2;
+				} else
+					range.num_encoding_sizes = 1;
+				range.max_encoding_tokens = 4;	// 4 keys
+			} else {
+				range.num_encoding_sizes = 0;
+				range.max_encoding_tokens = 0;
+			}
+#if WIRELESS_EXT > 9
+			range.min_pmp = 0;
+			range.max_pmp = 5000000;	/* 5 secs */
+			range.min_pmt = 0;
+			range.max_pmt = 65535 * 1024;	/* ??? */
+			range.pmp_flags = IW_POWER_PERIOD;
+			range.pmt_flags = IW_POWER_TIMEOUT;
+			range.pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
+
+			/* Transmit Power - values are in mW */
+			for(i = 0 ; i < 8 ; i++) {
+				range.txpower[i] = cap_rid.txPowerLevels[i];
+				if(range.txpower[i] == 0)
+					break;
+			}
+			range.num_txpower = i;
+			range.txpower_capa = IW_TXPOW_MWATT;
+#endif /* WIRELESS_EXT > 9 */
+#if WIRELESS_EXT > 10
+			range.we_version_source = 11;
+			range.we_version_compiled = WIRELESS_EXT;
+			range.retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
+			range.retry_flags = IW_RETRY_LIMIT;
+			range.r_time_flags = IW_RETRY_LIFETIME;
+			range.min_retry = 1;
+			range.max_retry = 65535;
+			range.min_r_time = 1024;
+			range.max_r_time = 65535 * 1024;
+#endif /* WIRELESS_EXT > 10 */
+
+			if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
+				rc = -EFAULT;
+		}
+		break;
+
+	case SIOCGIWPOWER:
+	{
+		int mode = config.powerSaveMode;
+		if ((wrq->u.power.disabled = (mode == POWERSAVE_CAM)))
+			break;
+		if ((wrq->u.power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
+			wrq->u.power.value = (int)config.fastListenDelay * 1024;
+			wrq->u.power.flags = IW_POWER_TIMEOUT;
+		} else {
+			wrq->u.power.value = (int)config.fastListenInterval * 1024;
+			wrq->u.power.flags = IW_POWER_PERIOD;
+		}
+		if ((config.rmode & 0xFF) == RXMODE_ADDR)
+			wrq->u.power.flags |= IW_POWER_UNICAST_R;
+		else
+			wrq->u.power.flags |= IW_POWER_ALL_R;
+	}
+	break;
+
+	case SIOCSIWPOWER: 
+		if (wrq->u.power.disabled) {
+			if ((config.rmode & 0xFF) >= RXMODE_RFMON) {
+				rc = -EINVAL;
+				break;
+			}
+			config.powerSaveMode = POWERSAVE_CAM;
+			config.rmode &= 0xFF00;
+			config.rmode |= RXMODE_BC_MC_ADDR;
+			local->need_commit = 1;
+			break;
+		}
+		if ((wrq->u.power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
+			config.fastListenDelay = (wrq->u.power.value + 500) / 1024;
+			config.powerSaveMode = POWERSAVE_PSPCAM;
+			local->need_commit = 1;
+		} else if ((wrq->u.power.flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
+			config.fastListenInterval = config.listenInterval = (wrq->u.power.value + 500) / 1024;
+			config.powerSaveMode = POWERSAVE_PSPCAM;
+			local->need_commit = 1;
+		}
+		switch (wrq->u.power.flags & IW_POWER_MODE) {
+		case IW_POWER_UNICAST_R:
+			if ((config.rmode & 0xFF) >= RXMODE_RFMON) {
+				rc = -EINVAL;
+				break;
+			}
+			config.rmode &= 0xFF00;
+			config.rmode |= RXMODE_ADDR;
+			local->need_commit = 1;
+			break;
+		case IW_POWER_ALL_R:
+			if ((config.rmode & 0xFF) >= RXMODE_RFMON) {
+				rc = -EINVAL;
+				break;
+			}
+			config.rmode &= 0xFF00;
+			config.rmode |= RXMODE_BC_MC_ADDR;
+			local->need_commit = 1;
+		case IW_POWER_ON:
+			break;
+		default:
+			rc = -EINVAL;
+		}
+		break;
+
+	case SIOCGIWSENS:
+		wrq->u.sens.value = config.rssiThreshold;
+		wrq->u.sens.disabled = (wrq->u.sens.value == 0);
+		wrq->u.sens.fixed = 1;
+		break;
+
+	case SIOCSIWSENS:
+		config.rssiThreshold = wrq->u.sens.disabled ? RSSI_DEFAULT : wrq->u.sens.value;
+		local->need_commit = 1;
+		break;
+
+	case SIOCGIWAPLIST:
+		if (wrq->u.data.pointer) {
+			int i;
+			struct sockaddr s[4];
+
+			for (i = 0; i < 4; i++) {
+				memcpy(s[i].sa_data, status_rid.bssid[i], 6);
+				s[i].sa_family = ARPHRD_ETHER;
+			}
+			wrq->u.data.length = 4;
+			if (copy_to_user(wrq->u.data.pointer, &s, sizeof(s)))
+				rc = -EFAULT;
+		}
+		break;
+
+#ifdef WIRELESS_SPY
+		// Set the spy list
+	case SIOCSIWSPY:
+		if (wrq->u.data.length > IW_MAX_SPY)
+		{
+			rc = -E2BIG;
+			break;
+		}
+		local->spy_number = wrq->u.data.length;
+		if (local->spy_number > 0)
+		{
+			struct sockaddr address[IW_MAX_SPY];
+			int i;
+
+			if (copy_from_user(address, wrq->u.data.pointer,
+					   sizeof(struct sockaddr) * local->spy_number)) {
+				rc = -EFAULT;
+				break;
+			}
+			for (i=0; i<local->spy_number; i++)
+				memcpy(local->spy_address[i], address[i].sa_data, 6);
+			memset(local->spy_stat, 0, sizeof(struct iw_quality) * IW_MAX_SPY);
+		}
+		break;
+
+		// Get the spy list
+	case SIOCGIWSPY:
+		wrq->u.data.length = local->spy_number;
+		if ((local->spy_number > 0) && (wrq->u.data.pointer))
+		{
+			struct sockaddr address[IW_MAX_SPY];
+			int i;
+			rc = verify_area(VERIFY_WRITE, wrq->u.data.pointer, (sizeof(struct iw_quality)+sizeof(struct sockaddr)) * IW_MAX_SPY);
+			if (rc)
+				break;
+			for (i=0; i<local->spy_number; i++)
+			{
+				memcpy(address[i].sa_data, local->spy_address[i], 6);
+				address[i].sa_family = AF_UNIX;
+			}
+			copy_to_user(wrq->u.data.pointer, address, sizeof(struct sockaddr) * local->spy_number);
+			copy_to_user(wrq->u.data.pointer + (sizeof(struct sockaddr)*local->spy_number), local->spy_stat, sizeof(struct iw_quality) * local->spy_number);
+			for (i=0; i<local->spy_number; i++)
+				local->spy_stat[i].updated = 0;
+		}
+		break;
+#endif /* WIRELESS_SPY */
+
+#ifdef CISCO_EXT
+	case SIOCGIWPRIV:
+		if(wrq->u.data.pointer)
+		{
+			struct iw_priv_args   priv[] =
+			{ /* cmd, set_args, get_args, name */
+				{ AIROIOCTL, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl), IW_PRIV_TYPE_BYTE | 2047, "airoioctl" },
+				{ AIROIDIFC, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl), IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "airoidifc" },
+			};
+
+			/* Set the number of ioctl available */
+			wrq->u.data.length = 2;
+
+			/* Copy structure to the user buffer */
+			if(copy_to_user(wrq->u.data.pointer, (u_char *) priv,
+					sizeof(priv)))
+				rc = -EFAULT;
+		}
+		break;
+#endif /* CISCO_EXT */
+#endif /* WIRELESS_EXT */
+
+#ifdef CISCO_EXT
+	case AIROIDIFC:
+	{
+		int val = AIROMAGIC;
+		aironet_ioctl com;
+		if (copy_from_user(&com,rq->ifr_data,sizeof(com)))
+			rc = -EFAULT;
+		else if (copy_to_user(com.data,(char *)&val,sizeof(val)))
+			rc = -EFAULT;
+	}
+	break;
+  
+	case AIROIOCTL:
+		/* Get the command struct and hand it off for evaluation by 
+		 * the proper subfunction
+		 */
+	{
+		aironet_ioctl com;
+		copy_from_user(&com,rq->ifr_data,sizeof(com));
+
+		/* Seperate R/W functions bracket legality here
+		 */
+		if ( com.command <= AIROGSTATSD32 )
+			rc = readrids(dev,&com);
+		else if ( com.command >= AIROPCAP && com.command <= AIROPLEAPUSR )
+			rc = writerids(dev,&com);
+		else if ( com.command >= AIROFLSHRST && com.command <= AIRORESTART )
+			rc = flashcard(dev,&com);
+		else
+			rc = -EINVAL;      /* Bad command in ioctl */
+	}
+	break;
+#endif /* CISCO_EXT */
+
+	// All other calls are currently unsupported
+	default:
+		rc = -EOPNOTSUPP;
+	}
+
+#ifdef WIRELESS_EXT
+	/* Some of the "SET" function may have modified some of the
+	 * parameters. It's now time to commit them in the card */
+	if(local->need_commit) {
+		/* A classical optimisation here is to not commit any change
+		 * if the card is not "opened". This is what we do in
+		 * wvlan_cs (see for details).
+		 * For that, we would need to have the config RID saved in
+		 * the airo_info struct and make sure to not re-read it if
+		 * local->need_commit != 0. Then, you need to patch "open"
+		 * to do the final commit of all parameters...
+		 * Jean II */
+		Resp rsp;
+
+		disable_MAC(local);
+		local->config = config;	/* ???? config is local !!! */
+		checkThrottle(&config);
+		writeConfigRid(local, &config);
+		enable_MAC(local, &rsp);
+
+		local->need_commit = 0;
+	}
+#endif /* WIRELESS_EXT */
+
+	return(rc);
+}
+
+#ifdef WIRELESS_EXT
+/*
+ * Get the Wireless stats out of the driver
+ * Note : irq and spinlock protection will occur in the subroutines
+ *
+ * TODO :
+ *	o Check if work in Ad-Hoc mode (otherwise, use SPY, as in wvlan_cs)
+ *	o Find the noise level
+ *	o Convert values to dBm
+ *	o Fill out discard.misc with something interesting
+ *
+ * Jean
+ */
+struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
+{
+	struct airo_info *local = (struct airo_info*) dev->priv;
+	StatusRid status_rid;
+	StatsRid stats_rid;
+	int *vals = stats_rid.vals;
+
+	/* Get stats out of the card */
+	readStatusRid(local, &status_rid);
+	readStatsRid(local, &stats_rid, RID_STATS);
+
+	/* The status */
+	local->wstats.status = status_rid.mode;
+
+	/* Signal quality and co. But where is the noise level ??? */
+	local->wstats.qual.qual = status_rid.signalQuality;
+	local->wstats.qual.level = status_rid.normalizedSignalStrength;
+	local->wstats.qual.noise = 0;
+	local->wstats.qual.updated = 3;
+
+	/* Packets discarded in the wireless adapter due to wireless
+	 * specific problems */
+	local->wstats.discard.nwid = vals[56] + vals[57] + vals[58];/* SSID Mismatch */
+	local->wstats.discard.code = vals[6];/* RxWepErr */
+	local->wstats.discard.misc = vals[1] + vals[2] + vals[3] + vals[4] + vals[30] + vals[32];
+	return (&local->wstats);
+}
+#endif /* WIRELESS_EXT */
+
+#ifdef CISCO_EXT
+/*
+ * This just translates from driver IOCTL codes to the command codes to 
+ * feed to the radio's host interface. Things can be added/deleted 
+ * as needed.  This represents the READ side of control I/O to 
+ * the card
+ */
+static int readrids(struct net_device *dev, aironet_ioctl *comp) {
+	unsigned short ridcode;
+	unsigned char iobuf[2048]; 
+
+	switch(comp->command)
+	{
+	case AIROGCAP:      ridcode = RID_CAPABILITIES; break;
+	case AIROGCFG:      ridcode = RID_CONFIG;       break;
+	case AIROGSLIST:    ridcode = RID_SSID;         break;
+	case AIROGVLIST:    ridcode = RID_APLIST;       break;
+	case AIROGDRVNAM:   ridcode = RID_DRVNAME;      break;
+	case AIROGEHTENC:   ridcode = RID_ETHERENCAP;   break;
+	case AIROGWEPKTMP:  ridcode = RID_WEP_TEMP;
+		/* Only super-user can read WEP keys */
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+		break;
+	case AIROGWEPKNV:   ridcode = RID_WEP_PERM;
+		/* Only super-user can read WEP keys */
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+		break;
+	case AIROGSTAT:     ridcode = RID_STATUS;       break;
+	case AIROGSTATSD32: ridcode = RID_STATSDELTA;   break;
+	case AIROGSTATSC32: ridcode = RID_STATS;        break;
+	default:
+		return -EINVAL;  
+		break;
+	}
+
+	PC4500_readrid((struct airo_info *)dev->priv,ridcode,iobuf,sizeof(iobuf));
+	/* get the count of bytes in the rid  docs say 1st 2 bytes is it.
+	 * then return it to the user 
+	 * 9/22/2000 Honor user given length
+	 */
+
+	if (copy_to_user(comp->data, iobuf, min (comp->len, sizeof(iobuf))))
+		return -EFAULT;
+	return 0;
+}
+
+/*
+ * Danger Will Robinson write the rids here
+ */
+
+static int writerids(struct net_device *dev, aironet_ioctl *comp) {
+	int  ridcode;
+	Resp      rsp;
+	static int (* writer)(struct airo_info *, u16 rid, const void *, int);
+	unsigned char iobuf[2048]; 
+
+	/* Only super-user can write RIDs */
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	ridcode = 0;
+	writer = do_writerid;
+
+	switch(comp->command)
+	{
+	case AIROPSIDS:     ridcode = RID_SSID;         break;
+	case AIROPCAP:      ridcode = RID_CAPABILITIES; break;
+	case AIROPAPLIST:   ridcode = RID_APLIST;       break;
+	case AIROPCFG:      ridcode = RID_CONFIG;       break;
+	case AIROPWEPKEYNV: ridcode = RID_WEP_PERM;     break;
+	case AIROPLEAPUSR:  ridcode = RID_LEAPUSERNAME; break;
+	case AIROPLEAPPWD:  ridcode = RID_LEAPPASSWORD; break;
+	case AIROPWEPKEY:   ridcode = RID_WEP_TEMP; writer = PC4500_writerid;
+		break;
+
+		/* this is not really a rid but a command given to the card 
+		 * same with MAC off
+		 */
+	case AIROPMACON:
+		if (enable_MAC(dev->priv, &rsp) != 0)
+			return -EIO;
+		return 0;
+
+		/* 
+		 * Evidently this code in the airo driver does not get a symbol
+		 * as disable_MAC. it's probably so short the compiler does not gen one.
+		 */
+	case AIROPMACOFF:
+		disable_MAC(dev->priv);
+		return 0;
+
+		/* This command merely clears the counts does not actually store any data
+		 * only reads rid. But as it changes the cards state, I put it in the
+		 * writerid routines.
+		 */
+	case AIROPSTCLR:
+		ridcode = RID_STATSDELTACLEAR;
+
+		PC4500_readrid(dev->priv,ridcode,iobuf,sizeof(iobuf));
+
+		if (copy_to_user(comp->data,iobuf,min(comp->len,sizeof(iobuf))))
+			return -EFAULT;
+		return 0;
+
+	default:
+		return -EOPNOTSUPP;	/* Blarg! */
+	}
+	if(comp->len > sizeof(iobuf))
+		return -EINVAL;
+
+	copy_from_user(iobuf,comp->data,comp->len);
+	if((*writer)((struct airo_info *)dev->priv, ridcode, iobuf,comp->len))
+		return -EIO;
+	return 0;
+}
+
+/*****************************************************************************
+ * Ancillary flash / mod functions much black magic lurkes here              *
+ *****************************************************************************
+ */
+
+/* 
+ * Flash command switch table
+ */
+
+int flashcard(struct net_device *dev, aironet_ioctl *comp) {
+	int z;
+	int cmdreset(struct airo_info *);
+	int setflashmode(struct airo_info *);
+	int flashgchar(struct airo_info *,int,int);
+	int flashpchar(struct airo_info *,int,int);
+	int flashputbuf(struct airo_info *, unsigned short *);
+	int flashrestart(struct airo_info *,struct net_device *);
+	unsigned short * flashbuffer;
+
+	/* Only super-user can modify flash */
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	switch(comp->command)
+	{
+	case AIROFLSHRST:
+		return cmdreset((struct airo_info *)dev->priv);
+
+	case AIROFLSHSTFL:
+		return setflashmode((struct airo_info *)dev->priv);
+
+	case AIROFLSHGCHR: /* Get char from aux */
+		if(comp->len != sizeof(int))
+			return -EINVAL;
+		copy_from_user(&z,comp->data,comp->len);
+		return flashgchar((struct airo_info *)dev->priv,z,8000);
+
+	case AIROFLSHPCHR: /* Send char to card. */
+		if(comp->len != sizeof(int))
+			return -EINVAL;
+		copy_from_user(&z,comp->data,comp->len);
+		return flashpchar((struct airo_info *)dev->priv,z,8000);
+
+	case AIROFLPUTBUF: /* Send 32k to card */
+		if(comp->len > FLASHSIZE)
+			return -EINVAL;
+		if ((flashbuffer = kmalloc (FLASHSIZE, GFP_KERNEL)) == NULL)
+			return -ENOMEM;
+		if(copy_from_user(flashbuffer,comp->data,comp->len)) {
+			kfree (flashbuffer);
+			return -EINVAL;
+		}
+
+		flashputbuf((struct airo_info *)dev->priv,flashbuffer);
+		kfree (flashbuffer);
+		return 0;
+
+	case AIRORESTART:
+		if(flashrestart((struct airo_info *)dev->priv,dev))
+			return -EIO;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+#define FLASH_COMMAND  0x7e7e
+
+/* 
+ * STEP 1)
+ * Disable MAC and do soft reset on 
+ * card. 
+ */
+
+int cmdreset(struct airo_info *ai) {
+	int flags;
+
+	disable_MAC(ai);
+
+	spin_lock_irqsave(&ai->cmd_lock, flags);
+	if(!waitbusy (ai)){
+		printk(KERN_INFO "Waitbusy hang before RESET\n");
+		return -EBUSY;
+	}
+    
+	OUT4500(ai,COMMAND,CMD_SOFTRESET);
+
+	set_current_state (TASK_UNINTERRUPTIBLE);
+	schedule_timeout (HZ);          /* WAS 600 12/7/00 */
+
+	if(!waitbusy (ai)){
+		printk(KERN_INFO "Waitbusy hang AFTER RESET\n");
+		return -EBUSY;
+	}
+	spin_unlock_irqrestore(&ai->cmd_lock, flags);
+	return 0;
+}
+
+/* STEP 2)
+ * Put the card in legendary flash 
+ * mode
+ */
+
+int setflashmode (struct airo_info *ai) {
+	int flags;
+
+	spin_lock_irqsave(&ai->cmd_lock, flags);
+	OUT4500(ai, SWS0, FLASH_COMMAND);
+	OUT4500(ai, SWS1, FLASH_COMMAND);
+	OUT4500(ai, SWS0, FLASH_COMMAND);
+	OUT4500(ai, COMMAND,0x10);
+	set_current_state (TASK_UNINTERRUPTIBLE);
+	schedule_timeout (HZ/2); /* 500ms delay */
+	spin_unlock_irqrestore(&ai->cmd_lock, flags);
+  
+	if(!waitbusy(ai)) {
+		printk(KERN_INFO "Waitbusy hang after setflash mode\n");
+		return -EIO;
+	}
+	return 0;
+}
+
+/* Put character to SWS0 wait for dwelltime 
+ * x 50us for  echo . 
+ */
+
+int flashpchar(struct airo_info *ai,int byte,int dwelltime) {
+	int echo;
+	int waittime;
+
+	byte |= 0x8000;
+
+	if(dwelltime == 0 )
+		dwelltime = 200;
+  
+	waittime=dwelltime;
+
+	/* Wait for busy bit d15 to go false indicating buffer empty */
+	while ((IN4500 (ai, SWS0) & 0x8000) && waittime > 0) {
+		udelay (50);
+		waittime -= 50;
+	}
+
+	/* timeout for busy clear wait */
+	if(waittime <= 0 ){
+		printk(KERN_INFO "flash putchar busywait timeout! \n");
+		return -EBUSY;
+	}
+
+	/* Port is clear now write byte and wait for it to echo back */
+	do {
+		OUT4500(ai,SWS0,byte);
+		udelay(50);
+		dwelltime -= 50;
+		echo = IN4500(ai,SWS1);
+	} while (dwelltime >= 0 && echo != byte);
+
+	OUT4500(ai,SWS1,0);
+
+	return (echo == byte) ? 0 : -EIO;
+}
+
+/*
+ * Get a character from the card matching matchbyte
+ * Step 3)
+ */
+int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){
+	int           rchar;
+	unsigned char rbyte=0;
+
+	do {
+		rchar = IN4500(ai,SWS1);
+    
+		if(dwelltime && !(0x8000 & rchar)){
+			dwelltime -= 10;
+			mdelay(10);
+			continue;
+		}
+		rbyte = 0xff & rchar;
+
+		if( (rbyte == matchbyte) && (0x8000 & rchar) ){
+			OUT4500(ai,SWS1,0);
+			return 0;
+		}
+		if( rbyte == 0x81 || rbyte == 0x82 || rbyte == 0x83 || rbyte == 0x1a || 0xffff == rchar)
+			break;
+		OUT4500(ai,SWS1,0);
+
+	}while(dwelltime > 0);
+	return -EIO;
+}
+
+/* 
+ * Transfer 32k of firmware data from user buffer to our buffer and 
+ * send to the card 
+ */
+
+int flashputbuf(struct airo_info *ai, unsigned short *bufp){
+	int            nwords;
+
+	/* Write stuff */
+	OUT4500(ai,AUXPAGE,0x100);
+	OUT4500(ai,AUXOFF,0);
+
+	for(nwords=0;nwords != FLASHSIZE / 2;nwords++){
+		OUT4500(ai,AUXDATA,bufp[nwords] & 0xffff);
+	}
+  
+	OUT4500(ai,SWS0,0x8000);
+
+	return 0;
+}
+
+/*
+ *
+ */
+int flashrestart(struct airo_info *ai,struct net_device *dev){
+	int    i,status;
+
+	set_current_state (TASK_UNINTERRUPTIBLE);
+	schedule_timeout (HZ);          /* Added 12/7/00 */
+	status = setup_card(ai, dev->dev_addr,&((struct airo_info*)dev->priv)->config);
+
+	for( i = 0; i < MAX_FIDS; i++ ) {
+		ai->fids[i] = transmit_allocate( ai, 2312 );
+	}
+
+	set_current_state (TASK_UNINTERRUPTIBLE);
+	schedule_timeout (HZ);          /* Added 12/7/00 */
+	return status;
+}
+#endif /* CISCO_EXT */
+
+/*
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+    as published by the Free Software Foundation; either version 2
+    of the License, or (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    In addition:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. The name of the author may not be used to endorse or promote
+       products derived from this software without specific prior written
+       permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.    
+*/
+
+module_init(airo_init_module);
+module_exit(airo_cleanup_module);
diff -u --recursive --new-file v2.4.5/linux/drivers/net/wireless/airo_cs.c linux/drivers/net/wireless/airo_cs.c
--- v2.4.5/linux/drivers/net/wireless/airo_cs.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/wireless/airo_cs.c	Wed Jun 20 11:10:53 2001
@@ -0,0 +1,691 @@
+/*======================================================================
+
+    Aironet driver for 4500 and 4800 series cards
+
+    This code is released under both the GPL version 2 and BSD licenses.
+    Either license may be used.  The respective licenses are found at
+    the end of this file.
+
+    This code was developed by Benjamin Reed <breed@users.sourceforge.net>
+    including portions of which come from the Aironet PC4500
+    Developer's Reference Manual and used with permission.  Copyright
+    (C) 1999 Benjamin Reed.  All Rights Reserved.  Permission to use
+    code in the Developer's manual was granted for this driver by
+    Aironet.
+
+    In addition this module was derived from dummy_cs.
+    The initial developer of dummy_cs is David A. Hinds
+    <dhinds@hyper.stanford.edu>.  Portions created by David A. Hinds
+    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.    
+    
+======================================================================*/
+
+#include <linux/config.h>
+#ifdef __IN_PCMCIA_PACKAGE__
+#include <pcmcia/k_compat.h>
+#endif
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/malloc.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/netdevice.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
+
+/*
+   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
+   you do not define PCMCIA_DEBUG at all, all the debug code will be
+   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
+   be present but disabled -- but it can then be enabled for specific
+   modules at load time with a 'pc_debug=#' option to insmod.
+*/
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+MODULE_PARM(pc_debug, "i");
+static char *version = "$Revision: 1.1.18.1 $";
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
+#else
+#define DEBUG(n, args...)
+#endif
+
+/*====================================================================*/
+
+/* Parameters that can be set with 'insmod' */
+
+/* The old way: bit map of interrupts to choose from */
+/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
+static u_int irq_mask = 0xdeb8;
+/* Newer, simpler way of listing specific interrupts */
+static int irq_list[4] = { -1 };
+
+MODULE_AUTHOR("Benjamin Reed");
+MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet \
+                   cards.  This is the module that links the PCMCIA card \
+		   with the airo module.");
+MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
+MODULE_PARM(irq_mask, "i");
+MODULE_PARM(irq_list, "1-4i");
+
+/*====================================================================*/
+
+/*
+   The event() function is this driver's Card Services event handler.
+   It will be called by Card Services when an appropriate card status
+   event is received.  The config() and release() entry points are
+   used to configure or release a socket, in response to card
+   insertion and ejection events.  They are invoked from the airo_cs
+   event handler. 
+*/
+
+struct net_device *init_airo_card( int, int, int );
+void stop_airo_card( struct net_device *, int );
+int reset_airo_card( struct net_device * );
+
+static void airo_config(dev_link_t *link);
+static void airo_release(u_long arg);
+static int airo_event(event_t event, int priority,
+		       event_callback_args_t *args);
+
+/*
+   The attach() and detach() entry points are used to create and destroy
+   "instances" of the driver, where each instance represents everything
+   needed to manage one actual PCMCIA card.
+*/
+
+static dev_link_t *airo_attach(void);
+static void airo_detach(dev_link_t *);
+
+/*
+   You'll also need to prototype all the functions that will actually
+   be used to talk to your device.  See 'pcmem_cs' for a good example
+   of a fully self-sufficient driver; the other drivers rely more or
+   less on other parts of the kernel.
+*/
+
+/*
+   The dev_info variable is the "key" that is used to match up this
+   device driver with appropriate cards, through the card configuration
+   database.
+*/
+
+static dev_info_t dev_info = "airo_cs";
+
+/*
+   A linked list of "instances" of the  aironet device.  Each actual
+   PCMCIA card corresponds to one device instance, and is described
+   by one dev_link_t structure (defined in ds.h).
+
+   You may not want to use a linked list for this -- for example, the
+   memory card driver uses an array of dev_link_t pointers, where minor
+   device numbers are used to derive the corresponding array index.
+*/
+
+static dev_link_t *dev_list = NULL;
+
+/*
+   A dev_link_t structure has fields for most things that are needed
+   to keep track of a socket, but there will usually be some device
+   specific information that also needs to be kept track of.  The
+   'priv' pointer in a dev_link_t structure can be used to point to
+   a device-specific private data structure, like this.
+
+   A driver needs to provide a dev_node_t structure for each device
+   on a card.  In some cases, there is only one device per card (for
+   example, ethernet cards, modems).  In other cases, there may be
+   many actual or logical devices (SCSI adapters, memory cards with
+   multiple partitions).  The dev_node_t structures need to be kept
+   in a linked list starting at the 'dev' field of a dev_link_t
+   structure.  We allocate them in the card's private data structure,
+   because they generally shouldn't be allocated dynamically.
+
+   In this case, we also provide a flag to indicate if a device is
+   "stopped" due to a power management event, or card ejection.  The
+   device IO routines can use a flag like this to throttle IO to a
+   card that is not ready to accept it.
+*/
+   
+typedef struct local_info_t {
+	dev_node_t	node;
+	struct net_device *eth_dev;
+} local_info_t;
+
+/*====================================================================*/
+
+static void cs_error(client_handle_t handle, int func, int ret)
+{
+	error_info_t err = { func, ret };
+	CardServices(ReportError, handle, &err);
+}
+
+/*======================================================================
+  
+  This bit of code is used to avoid unregistering network devices
+  at inappropriate times.  2.2 and later kernels are fairly picky
+  about when this can happen.
+  
+  ======================================================================*/
+
+static void flush_stale_links(void)
+{
+	dev_link_t *link, *next;
+	for (link = dev_list; link; link = next) {
+		next = link->next;
+		if (link->state & DEV_STALE_LINK)
+			airo_detach(link);
+	}
+}
+ 
+/*======================================================================
+  
+  airo_attach() creates an "instance" of the driver, allocating
+  local data structures for one device.  The device is registered
+  with Card Services.
+  
+  The dev_link structure is initialized, but we don't actually
+  configure the card at this point -- we wait until we receive a
+  card insertion event.
+  
+  ======================================================================*/
+
+static dev_link_t *airo_attach(void)
+{
+	client_reg_t client_reg;
+	dev_link_t *link;
+	local_info_t *local;
+	int ret, i;
+	
+	DEBUG(0, "airo_attach()\n");
+	flush_stale_links();
+	
+	/* Initialize the dev_link_t structure */
+	link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+	if (!link) {
+		printk(KERN_ERR "airo_cs: no memory for new device\n");
+		return NULL;
+	}
+	memset(link, 0, sizeof(struct dev_link_t));
+	link->release.function = &airo_release;
+	link->release.data = (u_long)link;
+	
+	/* Interrupt setup */
+	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+	link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
+	if (irq_list[0] == -1)
+		link->irq.IRQInfo2 = irq_mask;
+	else
+		for (i = 0; i < 4; i++)
+			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.Handler = NULL;
+	
+	/*
+	  General socket configuration defaults can go here.  In this
+	  client, we assume very little, and rely on the CIS for almost
+	  everything.  In most clients, many details (i.e., number, sizes,
+	  and attributes of IO windows) are fixed by the nature of the
+	  device, and can be hard-wired here.
+	*/
+	link->conf.Attributes = 0;
+	link->conf.Vcc = 50;
+	link->conf.IntType = INT_MEMORY_AND_IO;
+	
+	/* Allocate space for private device-specific data */
+	local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
+	memset(local, 0, sizeof(local_info_t));
+	link->priv = local;
+	
+	/* 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 = &airo_event;
+	client_reg.Version = 0x0210;
+	client_reg.event_callback_args.client_data = link;
+	ret = CardServices(RegisterClient, &link->handle, &client_reg);
+	if (ret != 0) {
+		cs_error(link->handle, RegisterClient, ret);
+		airo_detach(link);
+		return NULL;
+	}
+	
+	return link;
+} /* airo_attach */
+
+/*======================================================================
+  
+  This deletes a driver "instance".  The device is de-registered
+  with Card Services.  If it has been released, all local data
+  structures are freed.  Otherwise, the structures will be freed
+  when the device is released.
+  
+  ======================================================================*/
+
+static void airo_detach(dev_link_t *link)
+{
+	dev_link_t **linkp;
+	
+	DEBUG(0, "airo_detach(0x%p)\n", link);
+	
+	/* Locate device structure */
+	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+		if (*linkp == link) break;
+	if (*linkp == NULL)
+		return;
+	
+	del_timer(&link->release);
+	if ( link->state & DEV_CONFIG ) {
+		airo_release( (int)link );
+		if ( link->state & DEV_STALE_CONFIG ) {
+			link->state |= DEV_STALE_LINK;
+			return;
+		}
+	}
+	
+	if ( ((local_info_t*)link->priv)->eth_dev ) {
+		stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 );
+	}
+	((local_info_t*)link->priv)->eth_dev = 0;   
+	
+	/* Break the link with Card Services */
+	if (link->handle)
+		CardServices(DeregisterClient, link->handle);
+	
+	
+	
+	/* Unlink device structure, free pieces */
+	*linkp = link->next;
+	if (link->priv) {
+		kfree(link->priv);
+	}
+	kfree(link);
+	
+} /* airo_detach */
+
+/*======================================================================
+  
+  airo_config() is scheduled to run after a CARD_INSERTION event
+  is received, to configure the PCMCIA socket, and to make the
+  device available to the system.
+  
+  ======================================================================*/
+
+#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 airo_config(dev_link_t *link)
+{
+	client_handle_t handle;
+	tuple_t tuple;
+	cisparse_t parse;
+	local_info_t *dev;
+	int last_fn, last_ret;
+	u_char buf[64];
+	win_req_t req;
+	memreq_t map;
+	
+	handle = link->handle;
+	dev = link->priv;
+
+	DEBUG(0, "airo_config(0x%p)\n", link);
+	
+	/*
+	  This reads the card's CONFIG tuple to find its configuration
+	  registers.
+	*/
+	tuple.DesiredTuple = CISTPL_CONFIG;
+	tuple.Attributes = 0;
+	tuple.TupleData = buf;
+	tuple.TupleDataMax = sizeof(buf);
+	tuple.TupleOffset = 0;
+	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];
+	
+	/* Configure card */
+	link->state |= DEV_CONFIG;
+	
+	/*
+	  In this loop, we scan the CIS for configuration table entries,
+	  each of which describes a valid card configuration, including
+	  voltage, IO window, memory window, and interrupt settings.
+	  
+	  We make no assumptions about the card to be configured: we use
+	  just the information available in the CIS.  In an ideal world,
+	  this would work for any PCMCIA card, but it requires a complete
+	  and accurate CIS.  In practice, a driver usually "knows" most of
+	  these things without consulting the CIS, and most client drivers
+	  will only use the CIS to fill in implementation-defined details.
+	*/
+	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	CS_CHECK(GetFirstTuple, handle, &tuple);
+	while (1) {
+		cistpl_cftable_entry_t dflt = { 0 };
+		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+		CFG_CHECK(GetTupleData, handle, &tuple);
+		CFG_CHECK(ParseTuple, handle, &tuple, &parse);
+		
+		if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
+		if (cfg->index == 0) goto next_entry;
+		link->conf.ConfigIndex = cfg->index;
+		
+		/* Does this card need audio output? */
+		if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+			link->conf.Attributes |= CONF_ENABLE_SPKR;
+			link->conf.Status = CCSR_AUDIO_ENA;
+		}
+		
+		/* Use power settings for Vcc and Vpp if present */
+		/*  Note that the CIS values need to be rescaled */
+		if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM))
+			link->conf.Vcc = cfg->vcc.param[CISTPL_POWER_VNOM]/10000;
+		else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM))
+			link->conf.Vcc = dflt.vcc.param[CISTPL_POWER_VNOM]/10000;
+		
+		if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
+			link->conf.Vpp1 = link->conf.Vpp2 =
+				cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
+		else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
+			link->conf.Vpp1 = link->conf.Vpp2 =
+				dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
+		
+		/* Do we need to allocate an interrupt? */
+		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+			link->conf.Attributes |= CONF_ENABLE_IRQ;
+		
+		/* IO window settings */
+		link->io.NumPorts1 = link->io.NumPorts2 = 0;
+		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+			cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+			link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+			if (!(io->flags & CISTPL_IO_8BIT))
+				link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+			if (!(io->flags & CISTPL_IO_16BIT))
+				link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+			link->io.BasePort1 = io->win[0].base;
+			link->io.NumPorts1 = io->win[0].len;
+			if (io->nwin > 1) {
+				link->io.Attributes2 = link->io.Attributes1;
+				link->io.BasePort2 = io->win[1].base;
+				link->io.NumPorts2 = io->win[1].len;
+			}
+		}
+		
+		/* This reserves IO space but doesn't actually enable it */
+		CFG_CHECK(RequestIO, link->handle, &link->io); 
+		
+		/*
+		  Now set up a common memory window, if needed.  There is room
+		  in the dev_link_t structure for one memory window handle,
+		  but if the base addresses need to be saved, or if multiple
+		  windows are needed, the info should go in the private data
+		  structure for this device.
+		  
+		  Note that the memory window base is a physical address, and
+		  needs to be mapped to virtual space with ioremap() before it
+		  is used.
+		*/
+		if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
+			cistpl_mem_t *mem =
+				(cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
+			req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
+			req.Base = mem->win[0].host_addr;
+			req.Size = mem->win[0].len;
+			req.AccessSpeed = 0;
+			link->win = (window_handle_t)link->handle;
+			CFG_CHECK(RequestWindow, &link->win, &req);
+			map.Page = 0; map.CardOffset = mem->win[0].card_addr;
+			CFG_CHECK(MapMemPage, link->win, &map);
+		}
+		/* If we got this far, we're cool! */
+		break;
+		
+	next_entry:
+		CS_CHECK(GetNextTuple, handle, &tuple);
+	}
+	
+    /*
+      Allocate an interrupt line.  Note that this does not assign a
+      handler to the interrupt, unless the 'Handler' member of the
+      irq structure is initialized.
+    */
+	if (link->conf.Attributes & CONF_ENABLE_IRQ)
+		CS_CHECK(RequestIRQ, link->handle, &link->irq);
+	
+	/*
+	  This actually configures the PCMCIA socket -- setting up
+	  the I/O windows and the interrupt mapping, and putting the
+	  card and host interface into "Memory and IO" mode.
+	*/
+	CS_CHECK(RequestConfiguration, link->handle, &link->conf);
+	((local_info_t*)link->priv)->eth_dev = 
+		init_airo_card( link->irq.AssignedIRQ,
+				link->io.BasePort1, 1 );
+	if (!((local_info_t*)link->priv)->eth_dev) goto cs_failed;
+	
+	/*
+	  At this point, the dev_node_t structure(s) need to be
+	  initialized and arranged in a linked list at link->dev.
+	*/
+	strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
+	dev->node.major = dev->node.minor = 0;
+	link->dev = &dev->node;
+	
+	/* Finally, report what we've done */
+	printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d",
+	       dev->node.dev_name, link->conf.ConfigIndex,
+	       link->conf.Vcc/10, link->conf.Vcc%10);
+	if (link->conf.Vpp1)
+		printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
+	if (link->conf.Attributes & CONF_ENABLE_IRQ)
+		printk(", irq %d", link->irq.AssignedIRQ);
+	if (link->io.NumPorts1)
+		printk(", io 0x%04x-0x%04x", link->io.BasePort1,
+		       link->io.BasePort1+link->io.NumPorts1-1);
+	if (link->io.NumPorts2)
+		printk(" & 0x%04x-0x%04x", link->io.BasePort2,
+		       link->io.BasePort2+link->io.NumPorts2-1);
+	if (link->win)
+		printk(", mem 0x%06lx-0x%06lx", req.Base,
+		       req.Base+req.Size-1);
+	printk("\n");
+	
+	link->state &= ~DEV_CONFIG_PENDING;
+	return;
+	
+ cs_failed:
+	cs_error(link->handle, last_fn, last_ret);
+	airo_release((u_long)link);
+	
+} /* airo_config */
+
+/*======================================================================
+  
+  After a card is removed, airo_release() will unregister the
+  device, and release the PCMCIA configuration.  If the device is
+  still open, this will be postponed until it is closed.
+  
+  ======================================================================*/
+
+static void airo_release(u_long arg)
+{
+	dev_link_t *link = (dev_link_t *)arg;
+	
+	DEBUG(0, "airo_release(0x%p)\n", link);
+	
+	/*
+	  If the device is currently in use, we won't release until it
+	  is actually closed, because until then, we can't be sure that
+	  no one will try to access the device or its data structures.
+	*/
+	if (link->open) {
+		DEBUG(1, "airo_cs: release postponed, '%s' still open\n",
+		      link->dev->dev_name);
+		link->state |= DEV_STALE_CONFIG;
+		return;
+	}
+	
+	/* Unlink the device chain */
+	link->dev = NULL;
+	
+	/*
+	  In a normal driver, additional code may be needed to release
+	  other kernel data structures associated with this device. 
+	*/
+	
+	/* Don't bother checking to see if these succeed or not */
+	if (link->win)
+		CardServices(ReleaseWindow, link->win);
+	CardServices(ReleaseConfiguration, link->handle);
+	if (link->io.NumPorts1)
+		CardServices(ReleaseIO, link->handle, &link->io);
+	if (link->irq.AssignedIRQ)
+		CardServices(ReleaseIRQ, link->handle, &link->irq);
+	link->state &= ~DEV_CONFIG;
+	
+} /* airo_release */
+
+/*======================================================================
+  
+  The card status event handler.  Mostly, this schedules other
+  stuff to run after an event is received.
+
+  When a CARD_REMOVAL event is received, we immediately set a
+  private flag to block future accesses to this device.  All the
+  functions that actually access the device should check this flag
+  to make sure the card is still present.
+  
+  ======================================================================*/
+
+static int airo_event(event_t event, int priority,
+		      event_callback_args_t *args)
+{
+	dev_link_t *link = args->client_data;
+	local_info_t *local = link->priv;
+	
+	DEBUG(1, "airo_event(0x%06x)\n", event);
+	
+	switch (event) {
+	case CS_EVENT_CARD_REMOVAL:
+		link->state &= ~DEV_PRESENT;
+		if (link->state & DEV_CONFIG) {
+			netif_device_detach(local->eth_dev);
+			mod_timer(&link->release, jiffies + HZ/20);
+		}
+		break;
+	case CS_EVENT_CARD_INSERTION:
+		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+		airo_config(link);
+		break;
+	case CS_EVENT_PM_SUSPEND:
+		link->state |= DEV_SUSPEND;
+		/* Fall through... */
+	case CS_EVENT_RESET_PHYSICAL:
+		if (link->state & DEV_CONFIG) {
+			netif_device_detach(local->eth_dev);
+			CardServices(ReleaseConfiguration, link->handle);
+		}
+		break;
+	case CS_EVENT_PM_RESUME:
+		link->state &= ~DEV_SUSPEND;
+		/* Fall through... */
+	case CS_EVENT_CARD_RESET:
+		if (link->state & DEV_CONFIG) {
+			CardServices(RequestConfiguration, link->handle, &link->conf);
+			reset_airo_card(local->eth_dev);
+			netif_device_attach(local->eth_dev);
+		}
+		break;
+	}
+	return 0;
+} /* airo_event */
+
+/*====================================================================*/
+
+static int airo_cs_init(void)
+{
+	servinfo_t serv;
+	DEBUG(0, "%s\n", version);
+	CardServices(GetCardServicesInfo, &serv);
+	if (serv.Revision != CS_RELEASE_CODE) {
+		printk(KERN_NOTICE "airo_cs: Card Services release "
+		       "does not match!\n");
+		return -1;
+	}
+	register_pcmcia_driver(&dev_info, &airo_attach, &airo_detach);
+	return 0;
+}
+
+static void airo_cs_cleanup(void)
+{
+	DEBUG(0, "airo_cs: unloading\n");
+	unregister_pcmcia_driver(&dev_info);
+	while (dev_list != NULL) {
+		if (dev_list->state & DEV_CONFIG)
+			airo_release((u_long)dev_list);
+		airo_detach(dev_list);
+	}
+}
+
+/*
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+    as published by the Free Software Foundation; either version 2
+    of the License, or (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    In addition:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. The name of the author may not be used to endorse or promote
+       products derived from this software without specific prior written
+       permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.    
+*/
+
+module_init(airo_cs_init);
+module_exit(airo_cs_cleanup);
diff -u --recursive --new-file v2.4.5/linux/drivers/net/wireless/hermes.c linux/drivers/net/wireless/hermes.c
--- v2.4.5/linux/drivers/net/wireless/hermes.c	Mon May  7 19:42:14 2001
+++ linux/drivers/net/wireless/hermes.c	Mon Jun 11 19:15:27 2001
@@ -32,9 +32,10 @@
 
 #include "hermes.h"
 
+/* These are maximum timeouts. Most often, card wil react much faster */
 #define CMD_BUSY_TIMEOUT (100) /* In iterations of ~1us */
 #define CMD_INIT_TIMEOUT (50000) /* in iterations of ~10us */
-#define CMD_COMPL_TIMEOUT (10000) /* in iterations of ~10us */
+#define CMD_COMPL_TIMEOUT (20000) /* in iterations of ~10us */
 #define ALLOC_COMPL_TIMEOUT (1000) /* in iterations of ~10us */
 #define BAP_BUSY_TIMEOUT (500) /* In iterations of ~1us */
 #define BAP_ERROR_RETRY (10) /* How many times to retry a BAP seek when there is an error */
@@ -141,6 +142,12 @@
 	/* No need to explicitly handle the timeout - hermes_issue_cmd() will
 	   probably return -EBUSY */
 
+	/* According to the documentation, EVSTAT may contain
+	   obsolete event occurrence information.  We have to acknowledge
+	   it by writing EVACK. */
+	reg = hermes_read_regn(hw, EVSTAT);
+	hermes_write_regn(hw, EVACK, reg);
+
 	/* We don't use hermes_docmd_wait here, because the reset wipes
 	   the magic constant in SWSUPPORT0 away, and it gets confused */
 	err = hermes_issue_cmd(hw, HERMES_CMD_INIT, 0);
@@ -323,8 +330,10 @@
 		reg = hermes_read_reg(hw, oreg);
 	}
 
-	if (reg & HERMES_OFFSET_BUSY)
+	if (reg & HERMES_OFFSET_BUSY) {
+		DEBUG(0,"hermes_bap_seek: returning ETIMEDOUT...\n");
 		return -ETIMEDOUT;
+	}
 
 	/* For some reason, seeking the BAP seems to randomly fail somewhere
 	   (firmware bug?). We retry a few times before giving up. */
diff -u --recursive --new-file v2.4.5/linux/drivers/net/wireless/hermes.h linux/drivers/net/wireless/hermes.h
--- v2.4.5/linux/drivers/net/wireless/hermes.h	Mon May  7 19:42:14 2001
+++ linux/drivers/net/wireless/hermes.h	Mon Jun 11 19:15:27 2001
@@ -166,7 +166,6 @@
 #define		HERMES_RID_CNF_NICKNAME		(0xfc0e)
 #define		HERMES_RID_CNF_WEP_ON		(0xfc20)
 #define		HERMES_RID_CNF_MWO_ROBUST	(0xfc25)
-#define		HERMES_RID_CNF_PRISM2_WEP_ON	(0xfc28)
 #define		HERMES_RID_CNF_MULTICAST_LIST	(0xfc80)
 #define		HERMES_RID_CNF_CREATEIBSS	(0xfc81)
 #define		HERMES_RID_CNF_FRAG_THRESH	(0xfc82)
@@ -177,6 +176,7 @@
 #define		HERMES_RID_CNF_TX_KEY		(0xfcb1)
 #define		HERMES_RID_CNF_TICKTIME		(0xfce0)
 
+#define		HERMES_RID_CNF_PRISM2_WEP_ON	(0xfc28)
 #define		HERMES_RID_CNF_PRISM2_TX_KEY	(0xfc23)
 #define		HERMES_RID_CNF_PRISM2_KEY0	(0xfc24)
 #define		HERMES_RID_CNF_PRISM2_KEY1	(0xfc25)
diff -u --recursive --new-file v2.4.5/linux/drivers/net/wireless/orinoco.c linux/drivers/net/wireless/orinoco.c
--- v2.4.5/linux/drivers/net/wireless/orinoco.c	Mon May  7 19:42:14 2001
+++ linux/drivers/net/wireless/orinoco.c	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-/* orinoco.c 0.05	- (formerly known as dldwd_cs.c and orinoco_cs.c)
+/* orinoco.c 0.06	- (formerly known as dldwd_cs.c and orinoco_cs.c)
  *
  * A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
  * as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
@@ -144,10 +144,32 @@
  *	  (note : the memcmp bug was mine - fixed)
  *	o Remove set_retry stuff, no firmware support it (bloat--).
  *
+ * v0.05d -> v0.06 - 25/5/2001 - Jean II
+ *		Original patch from "Hong Lin" <alin@redhat.com>,
+ *		"Ian Kinner" <ikinner@redhat.com>
+ *		and "David Smith" <dsmith@redhat.com>
+ *	o Init of priv->tx_rate_ctrl in firmware specific section.
+ *	o Prism2/Symbol rate, upto should be 0xF and not 0x15. Doh !
+ *	o Spectrum card always need cor_reset (for every reset)
+ *	o Fix cor_reset to not loose bit 7 in the register
+ *	o flush_stale_links to remove zombie Pcmcia instances
+ *	o Ack previous hermes event before reset
+ *		Me (with my little hands)
+ *	o Allow orinoco.c to call cor_reset via priv->card_reset_handler
+ *	o Add priv->need_card_reset to toggle this feature
+ *	o Fix various buglets when setting WEP in Symbol firmware
+ *	  Now, encryption is fully functional on Symbol cards. Youpi !
+ *
+ * v0.06 -> v0.06b - 25/5/2001 - Jean II
+ *	o IBSS on Symbol use port_mode = 4. Please don't ask...
+ *
+ * v0.06b -> v0.06c - 29/5/2001 - Jean II
+ *	o Show first spy address in /proc/net/wireless for IBSS mode as well
+ *
  * TODO - Jean II
  *	o inline functions (lot's of candidate, need to reorder code)
  *	o Test PrismII/Symbol cards & firmware versions
- *	o Mini-PCI support
+ *	o Mini-PCI support (some people have reported success - JII)
  */
 
 #include <linux/module.h>
@@ -180,7 +202,7 @@
 #include "hermes.h"
 #include "orinoco.h"
 
-static char *version = "orinoco.c 0.05d (David Gibson <hermes@gibson.dropbear.id.au> and others)";
+static char *version = "orinoco.c 0.06c (David Gibson <hermes@gibson.dropbear.id.au> and others)";
 
 /* Level of debugging. Used in the macros in orinoco.h */
 #ifdef ORINOCO_DEBUG
@@ -369,7 +391,11 @@
 			priv->port_type = 3;
 			priv->allow_ibss = 0;
 		} else {
-			priv->port_type = 1;
+			/* Symbol is different here */
+			if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
+				priv->port_type = 4;
+			else
+				priv->port_type = 1;
 			priv->allow_ibss = 1;
 		}
 		break;
@@ -441,10 +467,15 @@
 
 	TRACE_ENTER(priv->ndev.name);
 
+	/* Stop other people bothering us */
 	dldwd_lock(priv);
-
 	__dldwd_stop_irqs(priv);
 
+	/* Check if we need a card reset */
+	if((priv->need_card_reset) && (priv->card_reset_handler != NULL))
+		priv->card_reset_handler(priv);
+
+	/* Do standard firmware reset if we can */
 	err = __dldwd_hw_reset(priv);
 	if (err)
 		goto out;
@@ -594,7 +625,8 @@
 {
 	hermes_t *hw = &priv->hw;
 	int err = 0;
-	int	extra_wep_flag = 0;
+	int	master_wep_flag;
+	int	auth_flag;
 
 	switch (priv->firmware_type) {
 	case FIRMWARE_TYPE_LUCENT: /* Lucent style WEP */
@@ -614,24 +646,29 @@
 
 	case FIRMWARE_TYPE_PRISM2: /* Prism II style WEP */
 	case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
+		master_wep_flag = 0;		/* Off */
 		if (priv->wep_on) {
 			char keybuf[LARGE_KEY_SIZE+1];
 			int keylen;
 			int i;
-			
+
+			/* Fudge around firmware weirdness */
+			keylen = priv->keys[priv->tx_key].len;
+
 			/* Write all 4 keys */
 			for(i = 0; i < MAX_KEYS; i++) {
-				keylen = priv->keys[i].len;
-				keybuf[keylen] = '\0';
-				memcpy(keybuf, priv->keys[i].data, keylen);
+				memset(keybuf, 0, sizeof(keybuf));
+				memcpy(keybuf, priv->keys[i].data,
+				       priv->keys[i].len);
 				err = hermes_write_ltv(hw, USER_BAP,
 						       HERMES_RID_CNF_PRISM2_KEY0 + i,
-						       HERMES_BYTES_TO_RECLEN(keylen + 1),
-						       &keybuf);
+						       HERMES_BYTES_TO_RECLEN(keylen),
+						       keybuf);
 				if (err)
 					return err;
 			}
 
+			/* Write the index of the key used in transmission */
 			err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PRISM2_TX_KEY,
 						   priv->tx_key);
 			if (err)
@@ -642,30 +679,29 @@
 			if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL) {
 				/* Symbol cards : set the authentication :
 				 * 0 -> no encryption, 1 -> open,
-				 * 2 -> shared key, 3 -> shared key 128bit */
-				if(priv->wep_restrict) {
-					if(priv->keys[priv->tx_key].len >
-					   SMALL_KEY_SIZE)
-						extra_wep_flag = 3;
-					else
-						extra_wep_flag = 2;
-				} else
-					extra_wep_flag = 1;
-				err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_SYMBOL_AUTH_TYPE, priv->wep_restrict);
+				 * 2 -> shared key
+				 * 3 -> shared key 128 -> AP only */
+				if(priv->wep_restrict)
+					auth_flag = 2;
+				else
+					auth_flag = 1;
+				err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_SYMBOL_AUTH_TYPE, auth_flag);
 				if (err)
 					return err;
+				/* Master WEP setting is always 3 */
+				master_wep_flag = 3;
 			} else {
 				/* Prism2 card : we need to modify master
 				 * WEP setting */
 				if(priv->wep_restrict)
-					extra_wep_flag = 2;
+					master_wep_flag = 3;
 				else
-					extra_wep_flag = 0;
+					master_wep_flag = 1;
 			}
 		}
 		
 		/* Master WEP setting : on/off */
-		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PRISM2_WEP_ON, (priv->wep_on | extra_wep_flag));
+		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PRISM2_WEP_ON, master_wep_flag);
 		if (err)
 			return err;	
 		break;
@@ -1182,9 +1218,11 @@
 	
 	dldwd_lock(priv);
 
+	/* Do standard firmware reset */
 	err = hermes_reset(hw);
 	if (err != 0) {
-		printk(KERN_ERR "%s: failed to reset hardware\n", dev->name);
+		printk(KERN_ERR "%s: failed to reset hardware (err = %d)\n",
+		       dev->name, err);
 		goto out;
 	}
 	
@@ -1209,6 +1247,8 @@
 		/* Lucent MAC : 00:60:1D:* & 00:02:2D:* */
 
 		priv->firmware_type = FIRMWARE_TYPE_LUCENT;
+		priv->tx_rate_ctrl = 0x3;	/* 11 Mb/s auto */
+		priv->need_card_reset = 0;
 		priv->broken_reset = 0;
 		priv->broken_allocate = 0;
 		priv->has_port3 = 1;		/* Still works in 7.28 */
@@ -1229,6 +1269,8 @@
 		/* Some D-Link cards report vendor 0x02... */
 
 		priv->firmware_type = FIRMWARE_TYPE_PRISM2;
+		priv->tx_rate_ctrl = 0xF;	/* 11 Mb/s auto */
+		priv->need_card_reset = 0;
 		priv->broken_reset = 0;
 		priv->broken_allocate = 0;
 		priv->has_port3 = 1;
@@ -1248,9 +1290,12 @@
 			/* Intel MAC : 00:02:B3:* */
 			/* 3Com MAC : 00:50:DA:* */
 
-			/* FIXME : probably need to use SYMBOL_***ARY_VER
-			 * to get proper firmware version */
+			/* FIXME : we need to get Symbol firmware revision.
+			 * I tried to use SYMBOL_***ARY_VER, but it didn't
+			 * returned anything proper... */
 			priv->firmware_type = FIRMWARE_TYPE_SYMBOL;
+			priv->tx_rate_ctrl = 0xF;	/* 11 Mb/s auto */
+			priv->need_card_reset = 1;
 			priv->broken_reset = 0;
 			priv->broken_allocate = 1;
 			priv->has_port3 = 1;
@@ -1268,6 +1313,8 @@
 		/* To check - Should cover Samsung & Compaq */
 
 		priv->firmware_type = FIRMWARE_TYPE_PRISM2;
+		priv->tx_rate_ctrl = 0xF;	/* 11 Mb/s auto */
+		priv->need_card_reset = 0;
 		priv->broken_reset = 0;
 		priv->broken_allocate = 0;
 		priv->has_port3 = 1;
@@ -1284,6 +1331,8 @@
 		/* D-Link MAC : 00:40:05:* */
 
 		priv->firmware_type = FIRMWARE_TYPE_PRISM2;
+		priv->tx_rate_ctrl = 0xF;	/* 11 Mb/s auto */
+		priv->need_card_reset = 0;
 		priv->broken_reset = 0;
 		priv->broken_allocate = 0;
 		priv->has_port3 = 1;
@@ -1300,6 +1349,8 @@
 		vendor_str = "UNKNOWN";
 
 		priv->firmware_type = 0;
+		priv->tx_rate_ctrl = 0x3;		/* Hum... */
+		priv->need_card_reset = 0;
 		priv->broken_reset = 0;
 		priv->broken_allocate = 0;
 		priv->has_port3 = 0;
@@ -1314,7 +1365,7 @@
 	printk(KERN_INFO "%s: Firmware ID %02X vendor 0x%x (%s) version %d.%02d\n",
 	       dev->name, priv->firmware_info.id, priv->firmware_info.vendor,
 	       vendor_str, priv->firmware_info.major, priv->firmware_info.minor);
-	
+
 	if (priv->has_port3)
 		printk(KERN_INFO "%s: Ad-hoc demo mode supported.\n", dev->name);
 	if (priv->has_ibss)
@@ -1393,9 +1444,6 @@
 		goto out;
 	}
 
-	/* Set initial bitrate control*/
-	priv->tx_rate_ctrl = 3;
-
 	/* Power management setup */
 	if (priv->has_pm) {
 		priv->pm_on = 0;
@@ -1466,7 +1514,7 @@
 
 	dldwd_lock(priv);
 
-	if (priv->port_type == 3) {
+	if (priv->iw_mode == IW_MODE_ADHOC) {
 		memset(&wstats->qual, 0, sizeof(wstats->qual));
 #ifdef WIRELESS_SPY
 		/* If a spy address is defined, we report stats of the
@@ -1709,7 +1757,7 @@
 {
 	dldwd_priv_t *priv = dev->priv;
 	int err = 0;
-	int ptype;
+	int mode;
 	struct iw_range range;
 	int numrates;
 	int i, k;
@@ -1723,7 +1771,7 @@
 	rrq->length = sizeof(range);
 
 	dldwd_lock(priv);
-	ptype = priv->port_type;
+	mode = priv->iw_mode;
 	dldwd_unlock(priv);
 
 	memset(&range, 0, sizeof(range));
@@ -1755,7 +1803,7 @@
 
 	range.sensitivity = 3;
 
-	if ((ptype == 3) && (priv->spy_number == 0)){
+	if ((mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){
 		/* Quality stats meaningless in ad-hoc mode */
 		range.max_qual.qual = 0;
 		range.max_qual.level = 0;
@@ -2253,7 +2301,7 @@
 		switch(brate) {
 		case 0:
 			fixed = 0x0;
-			upto = 0x15;
+			upto = 0xF;
 			break;
 		case 2:
 			fixed = 0x1;
@@ -2269,7 +2317,7 @@
 			break;
 		case 22:
 			fixed = 0x8;
-			upto = 0x15;
+			upto = 0xF;
 			break;
 		default:
 			fixed = 0x0;
@@ -2881,6 +2929,7 @@
 		if (wrq->u.data.pointer) {
 			struct iw_priv_args privtab[] = {
 				{ SIOCDEVPRIVATE + 0x0, 0, 0, "force_reset" },
+				{ SIOCDEVPRIVATE + 0x1, 0, 0, "card_reset" },
 				{ SIOCDEVPRIVATE + 0x2,
 				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
 				  0, "set_port3" },
@@ -2917,6 +2966,20 @@
 		dldwd_reset(priv);
 		break;
 
+	case SIOCDEVPRIVATE + 0x1: /* card_reset */
+		DEBUG(1, "%s: SIOCDEVPRIVATE + 0x1 (card_reset)\n",
+		      dev->name);
+		if (! capable(CAP_NET_ADMIN)) {
+			err = -EPERM;
+			break;
+		}
+		
+		printk(KERN_DEBUG "%s: Forcing card reset!\n", dev->name);
+		if(priv->card_reset_handler != NULL)
+			priv->card_reset_handler(priv);
+		dldwd_reset(priv);
+		break;
+
 	case SIOCDEVPRIVATE + 0x2: /* set_port3 */
 		DEBUG(1, "%s: SIOCDEVPRIVATE + 0x2 (set_port3)\n",
 		      dev->name);
@@ -3495,6 +3558,7 @@
 	ndev->priv = priv;
 
 	/* Setup up default routines */
+	priv->card_reset_handler = NULL;	/* Caller may override */
 	ndev->init = dldwd_init;
 	ndev->open = NULL;		/* Caller *must* override */
 	ndev->stop = NULL;
diff -u --recursive --new-file v2.4.5/linux/drivers/net/wireless/orinoco.h linux/drivers/net/wireless/orinoco.h
--- v2.4.5/linux/drivers/net/wireless/orinoco.h	Mon May  7 19:42:14 2001
+++ linux/drivers/net/wireless/orinoco.h	Mon Jun 11 19:15:27 2001
@@ -44,6 +44,8 @@
 
 typedef struct dldwd_priv {
 	void* card;	/* Pointer to card dependant structure */
+	/* card dependant extra reset code (i.e. bus/interface specific */
+	int (*card_reset_handler)(struct dldwd_priv *);
 
 	spinlock_t lock;
 	long state;
@@ -72,7 +74,7 @@
 	int has_mwo;
 	int has_pm;
 	int has_preamble;
-	int broken_reset, broken_allocate;
+	int need_card_reset, broken_reset, broken_allocate;
 	uint16_t channel_mask;
 
 	/* Current configuration */
diff -u --recursive --new-file v2.4.5/linux/drivers/net/wireless/orinoco_cs.c linux/drivers/net/wireless/orinoco_cs.c
--- v2.4.5/linux/drivers/net/wireless/orinoco_cs.c	Mon May  7 19:42:14 2001
+++ linux/drivers/net/wireless/orinoco_cs.c	Wed Jun 20 11:13:18 2001
@@ -1,4 +1,4 @@
-/* orinoco_cs.c 0.05	- (formerly known as dldwd_cs.c)
+/* orinoco_cs.c 0.06	- (formerly known as dldwd_cs.c)
  *
  * A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
  * as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
@@ -50,7 +50,8 @@
 	struct dldwd_priv  priv;
 } dldwd_card_t;
 
-static char *version = "orinoco_cs.c 0.05 (David Gibson <hermes@gibson.dropbear.id.au> and others)";
+static char version[] __initdata =
+"orinoco_cs.c 0.06 (David Gibson <hermes@gibson.dropbear.id.au> and others)";
 
 /*====================================================================*/
 
@@ -166,6 +167,70 @@
 	return 0;
 }
 
+/*
+ * Do a soft reset of the Pcmcia card using the Configuration Option Register
+ * Can't do any harm, and actually may do some good on some cards...
+ * In fact, this seem necessary for Spectrum cards...
+ */
+static int
+dldwd_cs_cor_reset(dldwd_priv_t *priv)
+{
+	dldwd_card_t* card = (dldwd_card_t *)priv->card;
+	dev_link_t *link = &card->link;
+	conf_reg_t reg;
+	u_long default_cor; 
+
+	TRACE_ENTER(priv->ndev.name);
+
+	/* Doing it if hardware is gone is guaranteed crash */
+	if(!priv->hw_ready)
+		return(0);
+
+	/* Save original COR value */
+	reg.Function = 0;
+	reg.Action = CS_READ;
+	reg.Offset = CISREG_COR;
+	reg.Value = 0;
+	CardServices(AccessConfigurationRegister, link->handle, &reg);
+	default_cor = reg.Value;
+
+	DEBUG(2, "dldwd : dldwd_cs_cor_reset() : cor=0x%lX\n", default_cor);
+
+	/* Soft-Reset card */
+	reg.Action = CS_WRITE;
+	reg.Offset = CISREG_COR;
+	reg.Value = (default_cor | COR_SOFT_RESET);
+	CardServices(AccessConfigurationRegister, link->handle, &reg);
+
+	/* Wait until the card has acknowledged our reset */
+	mdelay(1);
+
+	/* Restore original COR configuration index */
+	reg.Value = (default_cor & ~COR_SOFT_RESET);
+	CardServices(AccessConfigurationRegister, link->handle, &reg);
+
+	/* Wait until the card has finished restarting */
+	mdelay(1);
+
+	TRACE_EXIT(priv->ndev.name);
+
+	return(0);
+}
+
+/* Remove zombie instances (card removed, detach pending) */
+static void
+flush_stale_links(void)
+{
+	dev_link_t *link, *next;
+	TRACE_ENTER("dldwd");
+	for (link = dev_list; link; link = next) {
+		next = link->next;
+		if (link->state & DEV_STALE_LINK)
+			dldwd_cs_detach(link);
+	}
+	TRACE_EXIT("dldwd");
+}
+
 /*======================================================================
   dldwd_cs_attach() creates an "instance" of the driver, allocating
   local data structures for one device.  The device is registered
@@ -187,6 +252,8 @@
 	int ret, i;
 
 	TRACE_ENTER("dldwd");
+	/* A bit of cleanup */
+	flush_stale_links();
 
 	/* Allocate space for private device-specific data */
 	card = kmalloc(sizeof(*card), GFP_KERNEL);
@@ -237,6 +304,7 @@
 	/* Overrides */
 	ndev->open = dldwd_cs_open;
 	ndev->stop = dldwd_cs_stop;
+	priv->card_reset_handler = dldwd_cs_cor_reset;
 
 	/* Register with Card Services */
 	link->next = dev_list;
@@ -320,45 +388,6 @@
 	TRACE_EXIT("dldwd");
 }				/* dldwd_cs_detach */
 
-/*
- * Do a soft reset of the Pcmcia card using the Configuration Option Register
- * Can't do any harm, and actually may do some good on some cards...
- */
-static int
-dldwd_cs_cor_reset(dev_link_t *link)
-{
-	conf_reg_t reg;
-	u_long default_cor; 
-
-	/* Save original COR value */
-	reg.Function = 0;
-	reg.Action = CS_READ;
-	reg.Offset = CISREG_COR;
-	reg.Value = 0;
-	CardServices(AccessConfigurationRegister, link->handle, &reg);
-	default_cor = reg.Value;
-
-	DEBUG(2, "dldwd : dldwd_cs_cor_reset() : cor=0x%lX\n", default_cor);
-
-	/* Soft-Reset card */
-	reg.Action = CS_WRITE;
-	reg.Offset = CISREG_COR;
-	reg.Value = (default_cor | COR_SOFT_RESET);
-	CardServices(AccessConfigurationRegister, link->handle, &reg);
-
-	/* Wait until the card has acknowledged our reset */
-	mdelay(1);
-
-	/* Restore original COR configuration index */
-	reg.Value = (default_cor & COR_CONFIG_MASK);
-	CardServices(AccessConfigurationRegister, link->handle, &reg);
-
-	/* Wait until the card has finished restarting */
-	mdelay(1);
-
-	return(0);
-}
-
 /*======================================================================
   dldwd_cs_config() is scheduled to run after a CARD_INSERTION event
   is received, to configure the PCMCIA socket, and to make the
@@ -556,10 +585,6 @@
 	ndev->base_addr = link->io.BasePort1;
 	ndev->irq = link->irq.AssignedIRQ;
 
-	/* Do a Pcmcia soft reset of the card (optional) */
-	if(reset_cor)
-		dldwd_cs_cor_reset(link);
-
 	/* register_netdev will give us an ethX name */
 	ndev->name[0] = '\0';
 	/* Tell the stack we exist */
@@ -586,9 +611,6 @@
 		       link->io.BasePort2 + link->io.NumPorts2 - 1);
 	printk("\n");
 
-	/* Allow /proc & ioctls to act */
-	priv->hw_ready = 1;
-	
 	/* And give us the proc nodes for debugging */
 	if (dldwd_proc_dev_init(priv) != 0) {
 		printk(KERN_ERR "orinoco_cs: Failed to create /proc node for %s\n",
@@ -599,6 +621,13 @@
 	/* Note to myself : this replace MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT */
 	SET_MODULE_OWNER(ndev);
 	
+	/* Allow cor_reset, /proc & ioctls to act */
+	priv->hw_ready = 1;
+	
+	/* Do a Pcmcia soft reset of the card (optional) */
+	if(reset_cor)
+		dldwd_cs_cor_reset(priv);
+
 	/*
 	   At this point, the dev_node_t structure(s) need to be
 	   initialized and arranged in a linked list at link->dev.
@@ -748,9 +777,8 @@
 
 	TRACE_ENTER("dldwd");
 
-	printk(KERN_INFO "dldwd: David's Less Dodgy WaveLAN/IEEE Driver\n");
-
-	DEBUG(0, "%s\n", version);
+	printk(KERN_INFO "dldwd: David's Less Dodgy WaveLAN/IEEE Driver\n"
+	       KERN_INFO "%s\n", version);
 
 	CardServices(GetCardServicesInfo, &serv);
 	if (serv.Revision != CS_RELEASE_CODE) {
diff -u --recursive --new-file v2.4.5/linux/drivers/net/yellowfin.c linux/drivers/net/yellowfin.c
--- v2.4.5/linux/drivers/net/yellowfin.c	Wed May 16 10:25:39 2001
+++ linux/drivers/net/yellowfin.c	Wed Jun 20 11:13:18 2001
@@ -36,6 +36,12 @@
 	
 */
 
+#define DRV_NAME	"yellowfin"
+#define DRV_VERSION	"1.05+LK1.1.3"
+#define DRV_RELDATE	"May 10, 2001"
+
+#define PFX DRV_NAME ": "
+
 /* The user-configurable values.
    These may be modified when a driver module is loaded.*/
 
@@ -108,6 +114,8 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/ethtool.h>
+#include <asm/uaccess.h>
 #include <asm/processor.h>		/* Processor type for cache alignment. */
 #include <asm/unaligned.h>
 #include <asm/bitops.h>
@@ -115,9 +123,9 @@
 
 /* These identify the driver base version and may not be removed. */
 static char version[] __devinitdata =
-KERN_INFO "yellowfin.c:v1.05  1/09/2001  Written by Donald Becker <becker@scyld.com>\n"
+KERN_INFO DRV_NAME ".c:v1.05  1/09/2001  Written by Donald Becker <becker@scyld.com>\n"
 KERN_INFO "  http://www.scyld.com/network/yellowfin.html\n"
-KERN_INFO "  (unofficial 2.4.x port, LK1.1.3, May 10, 2001)\n";
+KERN_INFO "  (unofficial 2.4.x port, " DRV_VERSION ", " DRV_RELDATE ")\n";
 
 /* Condensed operations for readability. */
 #define virt_to_le32desc(addr)  cpu_to_le32(virt_to_bus(addr))
@@ -146,6 +154,13 @@
 MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM(gx_fix, "i");
+MODULE_PARM_DESC(max_interrupt_work, "G-NIC maximum events handled per interrupt");
+MODULE_PARM_DESC(mtu, "G-NIC MTU (all boards)");
+MODULE_PARM_DESC(debug, "G-NIC debug level (0-7)");
+MODULE_PARM_DESC(rx_copybreak, "G-NIC copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(options, "G-NIC: Bits 0-3: media type, bit 17: full duplex");
+MODULE_PARM_DESC(full_duplex, "G-NIC full duplex setting(s) (1)");
+MODULE_PARM_DESC(gx_fix, "G-NIC: enable GX server chipset bug workaround (0-1)");
 
 /*
 				Theory of Operation
@@ -369,7 +384,7 @@
 static int read_eeprom(long ioaddr, int location);
 static int mdio_read(long ioaddr, int phy_id, int location);
 static void mdio_write(long ioaddr, int phy_id, int location, int value);
-static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static int yellowfin_open(struct net_device *dev);
 static void yellowfin_timer(unsigned long data);
 static void yellowfin_tx_timeout(struct net_device *dev);
@@ -407,7 +422,7 @@
 
 	dev = alloc_etherdev(sizeof(*np));
 	if (!dev) {
-		printk (KERN_ERR "yellowfin: cannot allocate ethernet device\n");
+		printk (KERN_ERR PFX "cannot allocate ethernet device\n");
 		return -ENOMEM;
 	}
 	SET_MODULE_OWNER(dev);
@@ -474,7 +489,7 @@
 	dev->stop = &yellowfin_close;
 	dev->get_stats = &yellowfin_get_stats;
 	dev->set_multicast_list = &set_rx_mode;
-	dev->do_ioctl = &mii_ioctl;
+	dev->do_ioctl = &netdev_ioctl;
 	dev->tx_timeout = yellowfin_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
@@ -1330,13 +1345,39 @@
 	outw(cfg_value | 0x1000, ioaddr + Cnfg);
 }
 
-static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+{
+	struct yellowfin_private *np = dev->priv;
+	u32 ethcmd;
+		
+	if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
+		return -EFAULT;
+
+        switch (ethcmd) {
+        case ETHTOOL_GDRVINFO: {
+		struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
+		strcpy(info.driver, DRV_NAME);
+		strcpy(info.version, DRV_VERSION);
+		strcpy(info.bus_info, np->pci_dev->slot_name);
+		if (copy_to_user(useraddr, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+
+        }
+	
+	return -EOPNOTSUPP;
+}
+
+static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct yellowfin_private *np = dev->priv;
 	long ioaddr = dev->base_addr;
 	u16 *data = (u16 *)&rq->ifr_data;
 
 	switch(cmd) {
+	case SIOCETHTOOL:
+		return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
 	case SIOCDEVPRIVATE:		/* Get the address of the PHY in use. */
 		data[0] = np->phys[0] & 0x1f;
 		/* Fall Through */
@@ -1390,7 +1431,7 @@
 
 
 static struct pci_driver yellowfin_driver = {
-	name:		"yellowfin",
+	name:		DRV_NAME,
 	id_table:	yellowfin_pci_tbl,
 	probe:		yellowfin_init_one,
 	remove:		yellowfin_remove_one,
diff -u --recursive --new-file v2.4.5/linux/drivers/nubus/nubus.c linux/drivers/nubus/nubus.c
--- v2.4.5/linux/drivers/nubus/nubus.c	Sun Dec  3 17:48:19 2000
+++ linux/drivers/nubus/nubus.c	Wed Jun 27 17:10:55 2001
@@ -574,7 +574,7 @@
 		/* Now clobber the whole thing */
 		if (size > sizeof(mode) - 1)
 			size = sizeof(mode) - 1;
-		memset(&mode, sizeof(mode), 0);
+		memset(&mode, 0, sizeof(mode));
 		nubus_get_rsrc_mem(&mode, &ent, size);
 		printk (KERN_INFO "      %02X: (%02X) %s\n", ent.type,
 			mode.id, mode.name);
diff -u --recursive --new-file v2.4.5/linux/drivers/parport/ChangeLog linux/drivers/parport/ChangeLog
--- v2.4.5/linux/drivers/parport/ChangeLog	Tue May 22 19:54:04 2001
+++ linux/drivers/parport/ChangeLog	Mon Jun 11 19:15:27 2001
@@ -1,3 +1,9 @@
+2001-06-05  Tim Waugh  <twaugh@redhat.com>
+
+	* parport_pc.c (parport_pc_unregister_port): New exported function.
+	Do the opposite of parport_pc_probe_port.
+	(cleanup_module): Use it.
+
 2001-05-22  Juan Quintela  <quintela@mandrakesoft.com>
 
 	* parport_amiga.c: Set printk levels.
diff -u --recursive --new-file v2.4.5/linux/drivers/parport/parport_pc.c linux/drivers/parport/parport_pc.c
--- v2.4.5/linux/drivers/parport/parport_pc.c	Tue May 22 19:54:04 2001
+++ linux/drivers/parport/parport_pc.c	Mon Jun 11 19:15:27 2001
@@ -2349,6 +2349,28 @@
 	return p;
 }
 
+void parport_pc_unregister_port (struct parport *p)
+{
+	struct parport_pc_private *priv = p->private_data;
+	struct parport_operations *ops = p->ops;
+	if (p->dma != PARPORT_DMA_NONE)
+		free_dma(p->dma);
+	if (p->irq != PARPORT_IRQ_NONE)
+		free_irq(p->irq, p);
+	release_region(p->base, 3);
+	if (p->size > 3)
+		release_region(p->base + 3, p->size - 3);
+	if (p->modes & PARPORT_MODE_ECP)
+		release_region(p->base_hi, 3);
+	parport_proc_unregister(p);
+	if (priv->dma_buf)
+		pci_free_consistent(priv->dev, PAGE_SIZE,
+				    priv->dma_buf,
+				    priv->dma_handle);
+	kfree (p->private_data);
+	parport_unregister_port(p);
+	kfree (ops); /* hope no-one cached it */
+}
 
 #ifdef CONFIG_PCI
 /* Via support maintained by Jeff Garzik <jgarzik@mandrakesoft.com> */
@@ -2816,6 +2838,7 @@
 
 /* Exported symbols. */
 EXPORT_SYMBOL (parport_pc_probe_port);
+EXPORT_SYMBOL (parport_pc_unregister_port);
 
 #ifdef MODULE
 static int io[PARPORT_PC_MAX_PORTS+1] = { [0 ... PARPORT_PC_MAX_PORTS] = 0 };
@@ -2883,27 +2906,9 @@
 
 	while (p) {
 		tmp = p->next;
-		if (p->modes & PARPORT_MODE_PCSPP) { 
-			struct parport_pc_private *priv = p->private_data;
-			struct parport_operations *ops = p->ops;
-			if (p->dma != PARPORT_DMA_NONE)
-				free_dma(p->dma);
-			if (p->irq != PARPORT_IRQ_NONE)
-				free_irq(p->irq, p);
-			release_region(p->base, 3);
-			if (p->size > 3)
-				release_region(p->base + 3, p->size - 3);
-			if (p->modes & PARPORT_MODE_ECP)
-				release_region(p->base_hi, 3);
-			parport_proc_unregister(p);
-			if (priv->dma_buf)
-				pci_free_consistent(priv->dev, PAGE_SIZE,
-						    priv->dma_buf,
-						    priv->dma_handle);
-			kfree (p->private_data);
-			parport_unregister_port(p);
-			kfree (ops); /* hope no-one cached it */
-		}
+		if (p->modes & PARPORT_MODE_PCSPP)
+			parport_pc_unregister_port (p);
+
 		p = tmp;
 	}
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/parport/parport_sunbpp.c linux/drivers/parport/parport_sunbpp.c
--- v2.4.5/linux/drivers/parport/parport_sunbpp.c	Tue May 22 19:54:04 2001
+++ linux/drivers/parport/parport_sunbpp.c	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-/* $Id: parport_sunbpp.c,v 1.11 2001/02/13 01:16:58 davem Exp $
+/* $Id: parport_sunbpp.c,v 1.12 2001/05/26 03:01:42 davem Exp $
  * Parallel-port routines for Sun architecture
  * 
  * Author: Derrick J. Brashear <shadow@dementia.org>
diff -u --recursive --new-file v2.4.5/linux/drivers/pci/Makefile linux/drivers/pci/Makefile
--- v2.4.5/linux/drivers/pci/Makefile	Sat May 19 17:49:14 2001
+++ linux/drivers/pci/Makefile	Tue Jun 12 11:08:46 2001
@@ -13,8 +13,12 @@
 
 export-objs := pci.o
 
-obj-$(CONFIG_PCI) += pci.o quirks.o compat.o names.o setup-res.o
+obj-$(CONFIG_PCI) += pci.o quirks.o compat.o names.o
 obj-$(CONFIG_PROC_FS) += proc.o
+
+ifndef CONFIG_SPARC64
+obj-$(CONFIG_PCI) += setup-res.o
+endif
 
 #
 # Some architectures use the generic PCI setup functions
diff -u --recursive --new-file v2.4.5/linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- v2.4.5/linux/drivers/pci/pci.c	Sat May 19 17:43:06 2001
+++ linux/drivers/pci/pci.c	Tue Jun 12 16:47:56 2001
@@ -229,49 +229,120 @@
 }
 
 /**
- * pci_set_power_state - Set power management state of a device.
- * @dev: PCI device for which PM is set
- * @new_state: new power management statement (0 == D0, 3 == D3, etc.)
- *
- *  Set power management state of a device.  For transitions from state D3
- *  it isn't as straightforward as one could assume since many devices forget
- *  their configuration space during wakeup.  Returns old power state.
+ * pci_set_power_state - Set the power state of a PCI device
+ * @dev: PCI device to be suspended
+ * @state: Power state we're entering
+ *
+ * Transition a device to a new power state, using the Power Management 
+ * Capabilities in the device's config space.
+ *
+ * RETURN VALUE: 
+ * -EINVAL if trying to enter a lower state than we're already in.
+ * 0 if we're already in the requested state.
+ * -EIO if device does not support PCI PM.
+ * 0 if we can successfully change the power state.
  */
+
 int
-pci_set_power_state(struct pci_dev *dev, int new_state)
+pci_set_power_state(struct pci_dev *dev, int state)
 {
-	u32 base[5], romaddr;
-	u16 pci_command, pwr_command;
-	u8  pci_latency, pci_cacheline;
-	int i, old_state;
-	int pm = pci_find_capability(dev, PCI_CAP_ID_PM);
+	int pm;
+	u16 pmcsr;
 
-	if (!pm)
-		return 0;
-	pci_read_config_word(dev, pm + PCI_PM_CTRL, &pwr_command);
-	old_state = pwr_command & PCI_PM_CTRL_STATE_MASK;
-	if (old_state == new_state)
-		return old_state;
-	DBG("PCI: %s goes from D%d to D%d\n", dev->slot_name, old_state, new_state);
-	if (old_state == 3) {
-		pci_read_config_word(dev, PCI_COMMAND, &pci_command);
-		pci_write_config_word(dev, PCI_COMMAND, pci_command & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
-		for (i = 0; i < 5; i++)
-			pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + i*4, &base[i]);
-		pci_read_config_dword(dev, PCI_ROM_ADDRESS, &romaddr);
-		pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
-		pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &pci_cacheline);
-		pci_write_config_word(dev, pm + PCI_PM_CTRL, new_state);
-		for (i = 0; i < 5; i++)
-			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + i*4, base[i]);
-		pci_write_config_dword(dev, PCI_ROM_ADDRESS, romaddr);
+	/* bound the state we're entering */
+	if (state > 3) state = 3;
+
+	/* Validate current state:
+	 * Can enter D0 from any state, but if we can only go deeper 
+	 * to sleep if we're already in a low power state
+	 */
+	if (state > 0 && dev->current_state > state)
+		return -EINVAL;
+	else if (dev->current_state == state) 
+		return 0;        /* we're already there */
+
+	/* find PCI PM capability in list */
+	pm = pci_find_capability(dev, PCI_CAP_ID_PM);
+	
+	/* abort if the device doesn't support PM capabilities */
+	if (!pm) return -EIO; 
+
+	/* check if this device supports the desired state */
+	if (state == 1 || state == 2) {
+		u16 pmc;
+		pci_read_config_word(dev,pm + PCI_PM_PMC,&pmc);
+		if (state == 1 && !(pmc & PCI_PM_CAP_D1)) return -EIO;
+		else if (state == 2 && !(pmc & PCI_PM_CAP_D2)) return -EIO;
+	}
+
+	/* If we're in D3, force entire word to 0, since we can't access the
+	 * PCI config space for the device
+	 */
+	if (dev->current_state == 3)
+		pmcsr = 0;
+	else {
+		pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
+		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+		pmcsr |= state;
+	}
+
+	/* enter specified state */
+	pci_write_config_word(dev, pm + PCI_PM_CTRL, pmcsr);
+
+	dev->current_state = state;
+
+	return 0;
+}
+
+/**
+ * pci_save_state - save the PCI configuration space of a device before suspending
+ * @dev - PCI device that we're dealing with
+ * @buffer - buffer to hold config space context
+ *
+ * @buffer must be large enough to hold the entire PCI 2.2 config space 
+ * (>= 64 bytes).
+ */
+int
+pci_save_state(struct pci_dev *dev, u32 *buffer)
+{
+	int i;
+	if (buffer) {
+		/* XXX: 100% dword access ok here? */
+		for (i = 0; i < 16; i++)
+			pci_read_config_dword(dev, i * 4,&buffer[i]);
+	}
+	return 0;
+}
+
+/** 
+ * pci_restore_state - Restore the saved state of a PCI device
+ * @dev - PCI device that we're dealing with
+ * @buffer - saved PCI config space
+ *
+ */
+int 
+pci_restore_state(struct pci_dev *dev, u32 *buffer)
+{
+	int i;
+
+	if (buffer) {
+		for (i = 0; i < 16; i++)
+			pci_write_config_dword(dev,i * 4, buffer[i]);
+	}
+	/*
+	 * otherwise, write the context information we know from bootup.
+	 * This works around a problem where warm-booting from Windows
+	 * combined with a D3(hot)->D0 transition causes PCI config
+	 * header data to be forgotten.
+	 */	
+	else {
+		for (i = 0; i < 6; i ++)
+			pci_write_config_dword(dev,
+					       PCI_BASE_ADDRESS_0 + (i * 4),
+					       dev->resource[i].start);
 		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
-		pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, pci_cacheline);
-		pci_write_config_byte(dev, PCI_LATENCY_TIMER, pci_latency);
-		pci_write_config_word(dev, PCI_COMMAND, pci_command);
-	} else
-		pci_write_config_word(dev, pm + PCI_PM_CTRL, (pwr_command & ~PCI_PM_CTRL_STATE_MASK) | new_state);
-	return old_state;
+	}
+	return 0;
 }
 
 /**
@@ -314,6 +385,48 @@
 	}
 }
 
+/**
+ * pci_enable_wake - enable device to generate PME# when suspended
+ * @dev - PCI device to operate on
+ * @enable - Flag to enable or disable generation
+ * 
+ * Set the bits in the device's PM Capabilities to generate PME# when
+ * the system is suspended. 
+ *
+ * -EIO is returned if device doesn't have PM Capabilities. 
+ * -EINVAL is returned if device supports it, but can't generate wake events.
+ * 0 if operation is successful.
+ * 
+ */
+int pci_enable_wake(struct pci_dev *dev, u32 state, int enable)
+{
+	int pm;
+	u16 value;
+
+	/* find PCI PM capability in list */
+	pm = pci_find_capability(dev, PCI_CAP_ID_PM);
+	if (!pm) return -EIO; /* this device cannot poweroff - up to bridge to cut power */
+
+	/* make sure device supports wake events (from any state) */
+	pci_read_config_word(dev,pm+PCI_PM_PMC,&value);
+
+	if (!(value & PCI_PM_CAP_PME_MASK)) return -EINVAL; /* doesn't support wake events */
+
+	/* 
+	 * XXX - We're assuming that device can generate wake events from whatever 
+	 * state it may be entering. 
+	 * We're not actually checking what state we're going into to.
+	 */
+	pci_read_config_word(dev, pm + PCI_PM_CTRL, &value);
+
+	if (enable) value |= PCI_PM_CTRL_PME_STATUS;
+	else value &= ~PCI_PM_CTRL_PME_STATUS;
+
+	pci_write_config_word(dev, pm + PCI_PM_CTRL, value);
+	
+	return 0;
+}
+
 int
 pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge)
 {
@@ -1272,40 +1385,41 @@
  * easily implement them (ie just have a suspend function that calls
  * the pci_set_power_state() function).
  */
-static int pci_pm_suspend_device(struct pci_dev *dev)
+static int pci_pm_suspend_device(struct pci_dev *dev, u32 state)
 {
+	int error = 0;
 	if (dev) {
 		struct pci_driver *driver = dev->driver;
 		if (driver && driver->suspend)
-			driver->suspend(dev);
+			error = driver->suspend(dev,state);
 	}
-	return 0;
+	return error;
 }
 
 static int pci_pm_resume_device(struct pci_dev *dev)
 {
+	int error = 0;
 	if (dev) {
 		struct pci_driver *driver = dev->driver;
 		if (driver && driver->resume)
-			driver->resume(dev);
+			error = driver->resume(dev);
 	}
-	return 0;
+	return error;
 }
 
-
 /* take care to suspend/resume bridges only once */
 
-static int pci_pm_suspend_bus(struct pci_bus *bus)
+static int pci_pm_suspend_bus(struct pci_bus *bus, u32 state)
 {
 	struct list_head *list;
 
 	/* Walk the bus children list */
 	list_for_each(list, &bus->children) 
-		pci_pm_suspend_bus(pci_bus_b(list));
+		pci_pm_suspend_bus(pci_bus_b(list),state);
 
 	/* Walk the device children list */
 	list_for_each(list, &bus->devices)
-		pci_pm_suspend_device(pci_dev_b(list));
+		pci_pm_suspend_device(pci_dev_b(list),state);
 	return 0;
 }
 
@@ -1323,15 +1437,15 @@
 	return 0;
 }
 
-static int pci_pm_suspend(void)
+static int pci_pm_suspend(u32 state)
 {
 	struct list_head *list;
 	struct pci_bus *bus;
 
 	list_for_each(list, &pci_root_buses) {
 		bus = pci_bus_b(list);
-		pci_pm_suspend_bus(bus);
-		pci_pm_suspend_device(bus->self);
+		pci_pm_suspend_bus(bus,state);
+		pci_pm_suspend_device(bus->self,state);
 	}
 	return 0;
 }
@@ -1349,14 +1463,16 @@
 	return 0;
 }
 
-static int pci_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
+static int 
+pci_pm_callback(struct pm_dev *pm_device, pm_request_t rqst, void *data)
 {
 	switch (rqst) {
 	case PM_SUSPEND:
-		return pci_pm_suspend();
+		return pci_pm_suspend((u32)data);
 	case PM_RESUME:
 		return pci_pm_resume();
-	}	
+	default: break;
+	}
 	return 0;
 }
 #endif
@@ -1741,7 +1857,6 @@
 
 __setup("pci=", pci_setup);
 
-
 EXPORT_SYMBOL(pci_read_config_byte);
 EXPORT_SYMBOL(pci_read_config_word);
 EXPORT_SYMBOL(pci_read_config_dword);
@@ -1761,7 +1876,6 @@
 EXPORT_SYMBOL(pci_find_subsys);
 EXPORT_SYMBOL(pci_set_master);
 EXPORT_SYMBOL(pci_set_dma_mask);
-EXPORT_SYMBOL(pci_set_power_state);
 EXPORT_SYMBOL(pci_assign_resource);
 EXPORT_SYMBOL(pci_register_driver);
 EXPORT_SYMBOL(pci_unregister_driver);
@@ -1774,6 +1888,11 @@
 EXPORT_SYMBOL(pci_insert_device);
 EXPORT_SYMBOL(pci_remove_device);
 #endif
+
+EXPORT_SYMBOL(pci_set_power_state);
+EXPORT_SYMBOL(pci_save_state);
+EXPORT_SYMBOL(pci_restore_state);
+EXPORT_SYMBOL(pci_enable_wake);
 
 /* Obsolete functions */
 
diff -u --recursive --new-file v2.4.5/linux/drivers/pci/pci.ids linux/drivers/pci/pci.ids
--- v2.4.5/linux/drivers/pci/pci.ids	Sat May 19 17:49:14 2001
+++ linux/drivers/pci/pci.ids	Wed Jun 20 21:00:55 2001
@@ -3893,6 +3893,7 @@
 14e2  INFOLIBRIA
 14e3  AMTELCO
 14e4  BROADCOM Corporation
+	1644  Tigon3
 14e5  Pixelfusion Ltd
 14e6  SHINING Technology Inc
 14e7  3CX
@@ -4599,13 +4600,18 @@
 		11d4 0048  SoundMAX Integrated Digital Audio
 	2426  82801AB AC'97 Modem
 	2428  82801AB PCI Bridge
-	2440  82820 820 (Camino 2) Chipset ISA Bridge (ICH2)
-	2442  82820 820 (Camino 2) Chipset USB (Hub A)
-	2443  82820 820 (Camino 2) Chipset SMBus
-	2444  82820 820 (Camino 2) Chipset USB (Hub B)
-	2449  82820 820 (Camino 2) Chipset Ethernet
-	244b  82820 820 (Camino 2) Chipset IDE U100
-	244e  82820 820 (Camino 2) Chipset PCI
+	2440  82801BA ISA Bridge (ICH2)
+	2442  82801BA(M) USB (Hub A)
+	2443  82801BA(M) SMBus
+	2444  82801BA(M) USB (Hub B)
+	2445  82801BA(M) AC'97 Audio
+	2446  82801BA(M) AC'97 Modem
+	2448  82801BA PCI
+	2449  82801BA(M) Ethernet
+	244a  82801BAM IDE U100
+	244b  82801BA IDE U100
+	244c  82801BAM ISA Bridge (ICH2)
+	244e  82801BAM PCI
 	2500  82820 820 (Camino) Chipset Host Bridge (MCH)
 		1043 801c  P3C-2000 system chipset
 	2501  82820 820 (Camino) Chipset Host Bridge (MCH)
diff -u --recursive --new-file v2.4.5/linux/drivers/pci/quirks.c linux/drivers/pci/quirks.c
--- v2.4.5/linux/drivers/pci/quirks.c	Sat May 19 17:43:06 2001
+++ linux/drivers/pci/quirks.c	Wed Jun 20 11:16:01 2001
@@ -17,6 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/delay.h>
 
 #undef DEBUG
 
@@ -267,6 +268,9 @@
 /*
  * VIA 686A/B: If an IO-APIC is active, we need to route all on-chip
  * devices to the external APIC.
+ *
+ * TODO: When we have device-specific interrupt routers,
+ * this code will go away from quirks.
  */
 static void __init quirk_via_ioapic(struct pci_dev *dev)
 {
@@ -277,6 +281,9 @@
 	else
 		tmp = 0x1f; /* all known bits (4-0) routed to external APIC */
 		
+	printk(KERN_INFO "PCI: %sbling Via external APIC routing\n",
+	       tmp == 0 ? "Disa" : "Ena");
+
 	/* Offset 0x58: External APIC IRQ output control */
 	pci_write_config_byte (dev, 0x58, tmp);
 }
@@ -285,6 +292,56 @@
 
 
 /*
+ * Via 686A/B:  The PCI_INTERRUPT_LINE register for the on-chip
+ * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature:
+ * when written, it makes an internal connection to the PIC.
+ * For these devices, this register is defined to be 4 bits wide.
+ * Normally this is fine.  However for IO-APIC motherboards, or
+ * non-x86 architectures (yes Via exists on PPC among other places),
+ * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get
+ * interrupts delivered properly.
+ *
+ * TODO: When we have device-specific interrupt routers,
+ * quirk_via_irqpic will go away from quirks.
+ */
+
+/*
+ * FIXME: it is questionable that quirk_via_acpi
+ * is needed.  It shows up as an ISA bridge, and does not
+ * support the PCI_INTERRUPT_LINE register at all.  Therefore
+ * it seems like setting the pci_dev's 'irq' to the
+ * value of the ACPI SCI interrupt is only done for convenience.
+ *	-jgarzik
+ */
+static void __init quirk_via_acpi(struct pci_dev *d)
+{
+	/*
+	 * VIA ACPI device: SCI IRQ line in PCI config byte 0x42
+	 */
+	u8 irq;
+	pci_read_config_byte(d, 0x42, &irq);
+	irq &= 0xf;
+	if (irq && (irq != 2))
+		d->irq = irq;
+}
+
+static void __init quirk_via_irqpic(struct pci_dev *dev)
+{
+	u8 irq, new_irq = dev->irq & 0xf;
+
+	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
+
+	if (new_irq != irq) {
+		printk(KERN_INFO "PCI: Via IRQ fixup for %s, from %d to %d\n",
+		       dev->slot_name, irq, new_irq);
+
+		udelay(15);
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
+	}
+}
+
+
+/*
  * PIIX3 USB: We have to disable USB interrupts that are
  * hardwired to PIRQD# and may be shared with an
  * external device.
@@ -372,6 +429,11 @@
 #ifdef CONFIG_X86_IO_APIC 
 	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686,	quirk_via_ioapic },
 #endif
+	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_3,	quirk_via_acpi },
+	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_4,	quirk_via_acpi },
+	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_2,	quirk_via_irqpic },
+	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_5,	quirk_via_irqpic },
+	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_6,	quirk_via_irqpic },
 
 	{ 0 }
 };
diff -u --recursive --new-file v2.4.5/linux/drivers/pcmcia/cs.c linux/drivers/pcmcia/cs.c
--- v2.4.5/linux/drivers/pcmcia/cs.c	Fri Feb 16 16:02:36 2001
+++ linux/drivers/pcmcia/cs.c	Wed Jun 20 11:19:02 2001
@@ -1,6 +1,6 @@
 /*======================================================================
 
-    PCMCIA Card Services -- core services
+    Kernel Card Services -- core services
 
     cs.c 1.271 2000/10/02 20:27:49
     
@@ -90,11 +90,11 @@
 #define OPTIONS PCI_OPT CB_OPT PM_OPT
 #endif
 
-static const char *release = "Linux PCMCIA Card Services " CS_RELEASE;
+static const char *release = "Linux Kernel Card Services " CS_RELEASE;
 static const char *options = "options: " OPTIONS;
 
 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
-MODULE_DESCRIPTION("Linux PCMCIA Card Services " CS_RELEASE
+MODULE_DESCRIPTION("Linux Kernel Card Services " CS_RELEASE
 		   "\n  options:" OPTIONS);
 
 /*====================================================================*/
@@ -2416,7 +2416,7 @@
 
 static void __exit exit_pcmcia_cs(void)
 {
-    printk(KERN_INFO "unloading PCMCIA Card Services\n");
+    printk(KERN_INFO "unloading Kernel Card Services\n");
 #ifdef CONFIG_PROC_FS
     if (proc_pccard) {
 	remove_proc_entry("pccard", proc_bus);
diff -u --recursive --new-file v2.4.5/linux/drivers/pcmcia/pci_socket.c linux/drivers/pcmcia/pci_socket.c
--- v2.4.5/linux/drivers/pcmcia/pci_socket.c	Fri Apr  6 10:51:19 2001
+++ linux/drivers/pcmcia/pci_socket.c	Tue Jun 12 16:52:14 2001
@@ -218,16 +218,18 @@
 	dev->driver_data = 0;
 }
 
-static void cardbus_suspend (struct pci_dev *dev)
+static int cardbus_suspend (struct pci_dev *dev, u32 state)
 {
 	pci_socket_t *socket = (pci_socket_t *) dev->driver_data;
 	pcmcia_suspend_socket (socket->pcmcia_socket);
+	return 0;
 }
 
-static void cardbus_resume (struct pci_dev *dev)
+static int cardbus_resume (struct pci_dev *dev)
 {
 	pci_socket_t *socket = (pci_socket_t *) dev->driver_data;
 	pcmcia_resume_socket (socket->pcmcia_socket);
+	return 0;
 }
 
 
diff -u --recursive --new-file v2.4.5/linux/drivers/pcmcia/yenta.c linux/drivers/pcmcia/yenta.c
--- v2.4.5/linux/drivers/pcmcia/yenta.c	Fri Apr  6 10:51:19 2001
+++ linux/drivers/pcmcia/yenta.c	Wed Jun 20 11:21:33 2001
@@ -642,10 +642,11 @@
 	/* MAGIC NUMBERS! Fixme */
 	config_writeb(socket, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4);
 	config_writeb(socket, PCI_LATENCY_TIMER, 168);
-	config_writeb(socket, PCI_SEC_LATENCY_TIMER, 176);
-	config_writeb(socket, PCI_PRIMARY_BUS, dev->bus->number);
-	config_writeb(socket, PCI_SECONDARY_BUS, dev->subordinate->number);
-	config_writeb(socket, PCI_SUBORDINATE_BUS, dev->subordinate->number);
+	config_writel(socket, PCI_PRIMARY_BUS,
+		(176 << 24) |			   /* sec. latency timer */
+		(dev->subordinate->subordinate << 16) | /* subordinate bus */
+		(dev->subordinate->secondary << 8) |  /* secondary bus */
+		dev->subordinate->primary);		   /* primary bus */
 
 	/*
 	 * Set up the bridging state:
diff -u --recursive --new-file v2.4.5/linux/drivers/sbus/audio/Makefile linux/drivers/sbus/audio/Makefile
--- v2.4.5/linux/drivers/sbus/audio/Makefile	Fri Dec 29 14:07:22 2000
+++ linux/drivers/sbus/audio/Makefile	Mon Jun 11 19:15:27 2001
@@ -11,8 +11,8 @@
 
 obj-$(CONFIG_SPARCAUDIO)		+= audio.o
 obj-$(CONFIG_SPARCAUDIO_AMD7930)	+= amd7930.o
-obj-$(CONFIG_SPARCAUDIO_CS4231)		+= cs4231.o
 obj-$(CONFIG_SPARCAUDIO_DBRI)		+= dbri.o
+obj-$(CONFIG_SPARCAUDIO_CS4231)		+= cs4231.o
 obj-$(CONFIG_SPARCAUDIO_DUMMY)		+= dmy.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/drivers/sbus/audio/amd7930.c linux/drivers/sbus/audio/amd7930.c
--- v2.4.5/linux/drivers/sbus/audio/amd7930.c	Sun Feb 18 19:49:54 2001
+++ linux/drivers/sbus/audio/amd7930.c	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-/* $Id: amd7930.c,v 1.26 2001/02/13 01:16:59 davem Exp $
+/* $Id: amd7930.c,v 1.27 2001/05/21 01:25:22 davem Exp $
  * drivers/sbus/audio/amd7930.c
  *
  * Copyright (C) 1996,1997 Thomas K. Dyas (tdyas@eden.rutgers.edu)
@@ -107,7 +107,7 @@
 static __u8  linear2mulaw(__u16 data);
 static __u16 mulaw2linear(__u8 data);
 
-#if defined (AMD79C30_ISDN) && defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x200ff 
+#if defined (AMD79C30_ISDN)
 #include "../../isdn/hisax/hisax.h"
 #include "../../isdn/hisax/isdnl1.h"
 #include "../../isdn/hisax/foreign.h"
@@ -1131,7 +1131,7 @@
  *
  */
 
-#if defined (AMD79C30_ISDN) && defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x200ff 
+#if defined (AMD79C30_ISDN)
 static int amd7930_get_irqnum(int dev)
 {
 	struct amd7930_info *info;
@@ -1659,9 +1659,8 @@
 	return 0;
 }
 
-#ifdef MODULE
 /* Detach from an amd7930 chip given the device structure. */
-static void amd7930_detach(struct sparcaudio_driver *drv)
+static void __exit amd7930_detach(struct sparcaudio_driver *drv)
 {
 	struct amd7930_info *info = (struct amd7930_info *)drv->private;
 
@@ -1672,14 +1671,9 @@
 	sbus_iounmap(info->regs, info->regs_size);
 	kfree(drv->private);
 }
-#endif
 
 /* Probe for the amd7930 chip and then attach the driver. */
-#ifdef MODULE
-int init_module(void)
-#else
-int __init amd7930_init(void)
-#endif
+static int __init amd7930_init(void)
 {
 	struct sbus_bus *sbus;
 	struct sbus_dev *sdev;
@@ -1710,8 +1704,7 @@
 	return (num_drivers > 0) ? 0 : -EIO;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void __exit amd7930_exit(void)
 {
 	register int i;
 
@@ -1720,8 +1713,9 @@
 		num_drivers--;
 	}
 }
-#endif
 
+module_init(amd7930_init);
+module_exit(amd7930_exit);
 
 /*************************************************************/
 /*                 Audio format conversion                   */
diff -u --recursive --new-file v2.4.5/linux/drivers/sbus/audio/audio.c linux/drivers/sbus/audio/audio.c
--- v2.4.5/linux/drivers/sbus/audio/audio.c	Sun Feb 18 19:49:54 2001
+++ linux/drivers/sbus/audio/audio.c	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-/* $Id: audio.c,v 1.58 2001/02/13 01:16:59 davem Exp $
+/* $Id: audio.c,v 1.60 2001/05/21 09:05:05 davem Exp $
  * drivers/sbus/audio/audio.c
  *
  * Copyright 1996 Thomas K. Dyas (tdyas@noc.rutgers.edu)
@@ -32,10 +32,11 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/soundcard.h>
-#include <linux/version.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/delay.h>
+#include <linux/poll.h>
 #include <asm/pgtable.h>
+#include <asm/uaccess.h>
 
 #include <asm/audioio.h>
 
@@ -73,24 +74,6 @@
 static struct sparcaudio_driver *drivers[SPARCAUDIO_MAX_DEVICES];
 static devfs_handle_t devfs_handle;
  
-/* This crap to be pulled off into a local include file */
-#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE < 0x20100
-
-#define COPY_IN(arg, get) verify_area(VERIFY_READ, (void *)arg, sizeof(long)); memcpy_fromfs(&get, (long *)arg, sizeof(get));
-#define COPY_OUT(arg, ret) verify_area(VERIFY_WRITE, (void *)arg, sizeof(long)); memcpy_tofs((long *)arg, &ret, sizeof(ret));
-#define copy_to_user memcpy_tofs
-#define copy_from_user memcpy_fromfs
-#define signal_pending(x) (((x)->signal) & ~((x)->blocked))
-
-#else
-
-#include <asm/uaccess.h>
-#include <linux/poll.h>
-#define COPY_IN(arg, get) get_user(get, (int *)arg)
-#define COPY_OUT(arg, ret) put_user(ret, (int *)arg)
-#define sparcaudio_select sparcaudio_poll
-
-#endif
 
 void sparcaudio_output_done(struct sparcaudio_driver * drv, int status)
 {
@@ -215,37 +198,6 @@
  *	VFS layer interface
  */
 
-#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE < 0x20100
-static int sparcaudio_select(struct inode * inode, struct file * file,
-			    int sel_type, select_table * wait)
-{
-        struct sparcaudio_driver *drv = drivers[(MINOR(inode->i_rdev) >>
-                                                 SPARCAUDIO_DEVICE_SHIFT)];
-  
-        switch (sel_type) {
-        case SEL_IN:
-                if (((!file->f_flags & O_NONBLOCK) && drv->input_count) ||
-                    (drv->input_size > drv->buffer_size)) {
-                        dprintk(("read ready: c%d o%d\n",
-                                 drv->input_count, drv->input_offset));
-                        return 1;
-                }
-                select_wait(&drv->input_read_wait, wait);
-                break;
-        case SEL_OUT:
-                dprintk(("sel out: c%d o%d p%d\n",
-                         drv->output_count, drv->output_offset, drv->playing_count));
-                if ((drv->output_count + drv->playing_count) < (drv->num_output_buffers))
-                        return 1;
-                select_wait(&drv->output_write_wait, wait);
-                break;
-        case SEL_EX:
-                break;
-        };
-
-        return 0;
-}
-#else
 static unsigned int sparcaudio_poll(struct file *file, poll_table * wait)
 {
         unsigned int mask = 0;
@@ -264,29 +216,16 @@
         }
         return mask;
 }
-#endif
 
-#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE < 0x20100
-static int sparcaudio_lseek(struct inode * inode, struct file * file,
-			    off_t offset, int origin)
-#else
-static loff_t sparcaudio_lseek(struct file * file, loff_t offset, int origin)
-#endif
+static loff_t sparcaudio_llseek(struct file * file, loff_t offset, int origin)
 {
 	return -ESPIPE;
 }
 
-#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE < 0x20100
-static int sparcaudio_read(struct inode * inode, struct file * file,
-			   char *buf, int count)
-#else
 static ssize_t sparcaudio_read(struct file * file, char *buf, 
                                size_t count, loff_t *ppos)
-#endif
 {
-#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x200ff
         struct inode *inode = file->f_dentry->d_inode;
-#endif
         struct sparcaudio_driver *drv = drivers[(MINOR(inode->i_rdev) >>
                                                  SPARCAUDIO_DEVICE_SHIFT)];
         int bytes_to_copy, bytes_read = 0, err;
@@ -358,17 +297,10 @@
         restore_flags(flags);
 }
 
-#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE < 0x20100
-static int sparcaudio_write(struct inode * inode, struct file * file,
-			    const char *buf, int count)
-#else
 static ssize_t sparcaudio_write(struct file * file, const char *buf,
                                 size_t count, loff_t *ppos)
-#endif
 {
-#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x200ff
         struct inode *inode = file->f_dentry->d_inode;
-#endif
         struct sparcaudio_driver *drv = drivers[(MINOR(inode->i_rdev) >>
                                                  SPARCAUDIO_DEVICE_SHIFT)];
         int bytes_written = 0, bytes_to_copy, err;
@@ -499,7 +431,7 @@
 
         switch (cmd) {
         case SOUND_MIXER_WRITE_RECLEV:
-                if(COPY_IN(arg, k))
+                if (get_user(k, (int *)arg))
                         return -EFAULT;
         iretry:
                 oprintk(("setting input volume (0x%x)", k));
@@ -531,9 +463,9 @@
                         oprintk((" try 0x%x\n", k));
                         goto iretry;
                 }
-                return COPY_OUT(arg, i);
+                return put_user(i, (int *)arg);
         case SOUND_MIXER_WRITE_VOLUME:
-                if(COPY_IN(arg, k))
+                if (get_user(k, (int *)arg))
                         return -EFAULT;
                 if (drv->ops->get_output_muted && drv->ops->set_output_muted) {
                         i = drv->ops->get_output_muted(drv);
@@ -546,9 +478,9 @@
                 if (drv->ops->get_output_muted) 
                         i = drv->ops->get_output_muted(drv);
                 k = 0x6464 * (1 - i);
-                return COPY_OUT(arg, k);
+                return put_user(k, (int *)arg);
         case SOUND_MIXER_WRITE_PCM:
-                if(COPY_IN(arg, k))
+                if (get_user(k, (int *)arg))
                         return -EFAULT;
         oretry:
                 oprintk(("setting output volume (0x%x)\n", k));
@@ -582,25 +514,25 @@
                         oprintk((" try 0x%x\n", k));
                         goto oretry;
                 }
-                return COPY_OUT(arg, i);
+                return put_user(i, (int *)arg);
         case SOUND_MIXER_READ_SPEAKER:
                 k = OSS_PORT_AUDIO(drv, AUDIO_SPEAKER);
-                return COPY_OUT(arg, k);
+                return put_user(k, (int *)arg);
         case SOUND_MIXER_READ_MIC:
                 k = OSS_IPORT_AUDIO(drv, AUDIO_MICROPHONE);
-                return COPY_OUT(arg, k);
+                return put_user(k, (int *)arg);
         case SOUND_MIXER_READ_CD:
                 k = OSS_IPORT_AUDIO(drv, AUDIO_CD);
-                return COPY_OUT(arg, k);
+                return put_user(k, (int *)arg);
         case SOUND_MIXER_READ_LINE:
                 k = OSS_IPORT_AUDIO(drv, AUDIO_LINE_IN);
-                return COPY_OUT(arg, k);
+                return put_user(k, (int *)arg);
         case SOUND_MIXER_READ_LINE1:
                 k = OSS_PORT_AUDIO(drv, AUDIO_HEADPHONE);
-                return COPY_OUT(arg, k);
+                return put_user(k, (int *)arg);
         case SOUND_MIXER_READ_LINE2:
                 k = OSS_PORT_AUDIO(drv, AUDIO_LINE_OUT);
-                return COPY_OUT(arg, k);
+                return put_user(k, (int *)arg);
 
         case SOUND_MIXER_WRITE_MIC:
         case SOUND_MIXER_WRITE_CD:
@@ -608,7 +540,7 @@
         case SOUND_MIXER_WRITE_LINE1:
         case SOUND_MIXER_WRITE_LINE2:
         case SOUND_MIXER_WRITE_SPEAKER:
-                if(COPY_IN(arg, k))
+                if (get_user(k, (int *)arg))
                         return -EFAULT;
                 OSS_TWIDDLE_IPORT(drv, cmd, SOUND_MIXER_WRITE_LINE, AUDIO_LINE_IN, k);
                 OSS_TWIDDLE_IPORT(drv, cmd, SOUND_MIXER_WRITE_MIC, AUDIO_MICROPHONE, k);
@@ -617,7 +549,7 @@
                 OSS_TWIDDLE_PORT(drv, cmd, SOUND_MIXER_WRITE_SPEAKER, AUDIO_SPEAKER, k);
                 OSS_TWIDDLE_PORT(drv, cmd, SOUND_MIXER_WRITE_LINE1, AUDIO_HEADPHONE, k);
                 OSS_TWIDDLE_PORT(drv, cmd, SOUND_MIXER_WRITE_LINE2, AUDIO_LINE_OUT, k);
-                return COPY_OUT(arg, k);
+                return put_user(k, (int *)arg);
         case SOUND_MIXER_READ_RECSRC: 
                 if (drv->ops->get_input_port)
                         i = drv->ops->get_input_port(drv);
@@ -627,11 +559,11 @@
                 if (i & AUDIO_LINE_IN) j = SOUND_MASK_LINE;
                 if (i & AUDIO_MICROPHONE) j = SOUND_MASK_MIC;
     
-                return COPY_OUT(arg, j);
+                return put_user(j, (int *)arg);
   case SOUND_MIXER_WRITE_RECSRC: 
           if (!drv->ops->set_input_port)
                   return -EINVAL;
-          if(COPY_IN(arg, k))
+          if (get_user(k, (int *)arg))
                   return -EFAULT;
 
           /* only one should ever be selected */
@@ -641,7 +573,7 @@
           oprintk(("setting inport to %d\n", j));
           i = drv->ops->set_input_port(drv, j);
     
-          return COPY_OUT(arg, i);
+          return put_user(i, (int *)arg);
         case SOUND_MIXER_READ_RECMASK: 
                 if (drv->ops->get_input_ports)
                         i = drv->ops->get_input_ports(drv);
@@ -650,10 +582,10 @@
                 if (i & AUDIO_LINE_IN) j |= SOUND_MASK_LINE;
                 if (i & AUDIO_CD) j |= SOUND_MASK_CD;
     
-                return COPY_OUT(arg, j);
+                return put_user(j, (int *)arg);
         case SOUND_MIXER_READ_CAPS: /* mixer capabilities */
                 i = SOUND_CAP_EXCL_INPUT;
-                return COPY_OUT(arg, i);
+                return put_user(i, (int *)arg);
 
         case SOUND_MIXER_READ_DEVMASK: /* all supported devices */
                 if (drv->ops->get_input_ports)
@@ -676,7 +608,7 @@
 
                 if (cmd == SOUND_MIXER_READ_STEREODEVS)
                         j &= ~(MONO_DEVICES);
-                return COPY_OUT(arg, j);
+                return put_user(j, (int *)arg);
         default:
                 return -EINVAL;
         };
@@ -742,7 +674,7 @@
                 case I_GETSIG:
                 case I_GETSIG_SOLARIS:
                         j = (int) lis_get_elist_ent(drv->sd_siglist,current->pid);
-                        COPY_OUT(arg, j);
+                        put_user(j, (int *)arg);
                         retval = drv->input_count;
                         break;
 
@@ -773,7 +705,7 @@
                          * as its retval. (streamio(7I)) This should work.
                          */
                         j = (drv->input_count > 0) ? drv->input_buffer_size : 0;
-                        COPY_OUT(arg, j);
+                        put_user(j, (int *)arg);
                         retval = drv->input_count;
                         break;
 
@@ -859,11 +791,11 @@
                                 if (drv->ops->get_output_pause(drv))
                                         j |= PCM_ENABLE_OUTPUT;
                         }
-                        COPY_OUT(arg, j);
+                        put_user(j, (int *)arg);
                         break;
                 case SNDCTL_DSP_GETBLKSIZE:
                         j = drv->input_buffer_size;
-                        COPY_OUT(arg, j);
+                        put_user(j, (int *)arg);
                         break;
                 case SNDCTL_DSP_SPEED:
                         if ((!drv->ops->set_output_rate) && 
@@ -871,12 +803,12 @@
                                 retval = -EINVAL;
                                 break;
                         }
-                        COPY_IN(arg, i);
+                        get_user(i, (int *)arg)
                         tprintk(("setting speed to %d\n", i));
                         drv->ops->set_input_rate(drv, i);
                         drv->ops->set_output_rate(drv, i);
                         j = drv->ops->get_output_rate(drv);
-                        COPY_OUT(arg, j);
+                        put_user(j, (int *)arg);
                         break;
                 case SNDCTL_DSP_GETCAPS:
                         /* All Sparc audio hardware is full duplex.
@@ -884,19 +816,19 @@
                          * Pause functionality emulates trigger
                          */
                         j = DSP_CAP_DUPLEX | DSP_CAP_TRIGGER | DSP_CAP_REALTIME;
-                        COPY_OUT(arg, j);
+                        put_user(j, (int *)arg);
                         break;
                 case SNDCTL_DSP_GETFMTS:
                         if (drv->ops->get_formats) {
                                 j = drv->ops->get_formats(drv);
-                                COPY_OUT(arg, j);
+                                put_user(j, (int *)arg);
                         } else {
                                 retval = -EINVAL;
                         }
                         break;
                 case SNDCTL_DSP_SETFMT:
                         /* need to decode into encoding, precision */
-                        COPY_IN(arg, i);
+                        get_user(i, (int *)arg);
 	    
                         /* handle special case here */
                         if (i == AFMT_QUERY) {
@@ -926,7 +858,7 @@
                                                 break;
                                         };
                                 } 
-                                COPY_OUT(arg, i);
+                                put_user(i, (int *)arg);
                                 break;
                         }
 
@@ -991,7 +923,7 @@
                                 dprintk(("setting format: failed\n"));
                                 return -EINVAL;
                         }
-                        COPY_OUT(arg, i);
+                        put_user(i, (int *)arg);
                         break;
                 case SNDCTL_DSP_CHANNELS:
                         if ((!drv->ops->set_output_channels) && 
@@ -999,11 +931,11 @@
                                 retval = -EINVAL;
                                 break;
                         }
-                        COPY_IN(arg, i);
+                        get_user(i, (int *)arg);
                         drv->ops->set_input_channels(drv, i);
                         drv->ops->set_output_channels(drv, i);
                         i = drv->ops->get_output_channels(drv);
-                        COPY_OUT(arg, i);
+                        put_user(i, (int *)arg);
                         break;
                 case SNDCTL_DSP_STEREO:
                         if ((!drv->ops->set_output_channels) && 
@@ -1011,11 +943,11 @@
                                 retval = -EINVAL;
                                 break;
                         }
-                        COPY_IN(arg, i);
+                        get_user(i, (int *)arg);
                         drv->ops->set_input_channels(drv, (i + 1));
                         drv->ops->set_output_channels(drv, (i + 1));
                         i = ((drv->ops->get_output_channels(drv)) - 1);
-                        COPY_OUT(arg, i);
+                        put_user(i, (int *)arg);
                         break;
                 case SNDCTL_DSP_POST:
                 case SNDCTL_DSP_SYNC:
@@ -1761,14 +1693,14 @@
 	default:
                 eprintk(("unknown minor device number\n"));
                 retval = -EINVAL;
-	};
+	}
 	
 	return retval;
 }
 
 static struct file_operations sparcaudioctl_fops = {
 	owner:		THIS_MODULE,
-	poll:		sparcaudio_select,
+	poll:		sparcaudio_poll,
 	ioctl:		sparcaudio_ioctl,
 };
 
@@ -1960,10 +1892,10 @@
 
 static struct file_operations sparcaudio_fops = {
 	owner:		THIS_MODULE,
-	llseek:		sparcaudio_lseek,
+	llseek:		sparcaudio_llseek,
 	read:		sparcaudio_read,
 	write:		sparcaudio_write,
-	poll:		sparcaudio_select,
+	poll:		sparcaudio_poll,
 	ioctl:		sparcaudio_ioctl,
 	open:		sparcaudio_open,
 	release:	sparcaudio_release,
@@ -2032,12 +1964,10 @@
          * TODO: Make number of input/output buffers tunable parameters
          */
 
-#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x202ff
         init_waitqueue_head(&drv->open_wait);
         init_waitqueue_head(&drv->output_write_wait);
         init_waitqueue_head(&drv->output_drain_wait);
         init_waitqueue_head(&drv->input_read_wait);
-#endif
 
         drv->num_output_buffers = 8;
 	drv->output_buffer_size = (4096 * 2);
@@ -2204,20 +2134,6 @@
 		return -EIO;
 
 	devfs_handle = devfs_mk_dir (NULL, "sound", NULL);
-	
-#ifdef CONFIG_SPARCAUDIO_AMD7930
-	amd7930_init();
-#endif
-#ifdef CONFIG_SPARCAUDIO_DBRI
-        dbri_init();
-#endif
-#ifdef CONFIG_SPARCAUDIO_CS4231
-	cs4231_init();
-#endif
-#ifdef CONFIG_SPARCAUDIO_DUMMY
-	dummy_init();
-#endif
-
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/sbus/audio/cs4231.c linux/drivers/sbus/audio/cs4231.c
--- v2.4.5/linux/drivers/sbus/audio/cs4231.c	Sun Mar 25 18:14:20 2001
+++ linux/drivers/sbus/audio/cs4231.c	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-/* $Id: cs4231.c,v 1.45 2001/03/23 08:16:13 davem Exp $
+/* $Id: cs4231.c,v 1.46 2001/05/21 01:25:22 davem Exp $
  * drivers/sbus/audio/cs4231.c
  *
  * Copyright 1996, 1997, 1998, 1999 Derrick J Brashear (shadow@andrew.cmu.edu)
@@ -35,7 +35,7 @@
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/sbus.h>
-#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x200ff && defined(CONFIG_PCI)
+#ifdef CONFIG_PCI
 #define EB4231_SUPPORT
 #include <asm/ebus.h>
 #include <asm/pbm.h>
@@ -2178,9 +2178,6 @@
 static int cs4231_attach(struct sparcaudio_driver *drv, 
 			 struct sbus_dev *sdev)
 {
-#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE < 0x20100
-        struct linux_prom_irqs irq;
-#endif
         struct cs4231_chip *cs4231_chip;
         int err;
 
@@ -2367,12 +2364,32 @@
 }
 #endif
 
-/* Probe for the cs4231 chip and then attach the driver. */
-#ifdef MODULE
-int init_module(void)
-#else
-int __init cs4231_init(void)
+/* Detach from an cs4231 chip given the device structure. */
+static void __exit cs4231_detach(struct sparcaudio_driver *drv)
+{
+	struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;
+
+	cs4231_disable_interrupts(drv);
+	unregister_sparcaudio_driver(drv, 1);
+	disable_irq(cs4231_chip->irq);
+	free_irq(cs4231_chip->irq, drv);
+	if (!(cs4231_chip->status & CS_STATUS_IS_EBUS)) {
+		sbus_iounmap(cs4231_chip->regs, cs4231_chip->regs_size);
+	} else {
+#ifdef EB4231_SUPPORT
+		iounmap(cs4231_chip->regs);
+		iounmap(cs4231_chip->eb2p);
+		iounmap(cs4231_chip->eb2c);
+		disable_irq(cs4231_chip->irq2);
+		free_irq(cs4231_chip->irq2, drv);
 #endif
+	}
+	kfree(drv->private);
+}
+
+
+/* Probe for the cs4231 chip and then attach the driver. */
+static int __init cs4231_init(void)
 {
         struct sbus_bus *sbus;
         struct sbus_dev *sdev;
@@ -2414,31 +2431,7 @@
         return (num_drivers > 0) ? 0 : -EIO;
 }
 
-#ifdef MODULE
-/* Detach from an cs4231 chip given the device structure. */
-static void cs4231_detach(struct sparcaudio_driver *drv)
-{
-        struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private;
-
-	cs4231_disable_interrupts(drv);
-        unregister_sparcaudio_driver(drv, 1);
-        disable_irq(cs4231_chip->irq);
-        free_irq(cs4231_chip->irq, drv);
-        if (!(cs4231_chip->status & CS_STATUS_IS_EBUS)) {
-                sbus_iounmap(cs4231_chip->regs, cs4231_chip->regs_size);
-        } else {
-#ifdef EB4231_SUPPORT
-                iounmap(cs4231_chip->regs);
-                iounmap(cs4231_chip->eb2p);
-                iounmap(cs4231_chip->eb2c);
-                disable_irq(cs4231_chip->irq2);
-                free_irq(cs4231_chip->irq2, drv);
-#endif
-        }
-        kfree(drv->private);
-}
-
-void cleanup_module(void)
+static void __exit cs4231_exit(void)
 {
         register int i;
 
@@ -2447,8 +2440,9 @@
                 num_drivers--;
         }
 }
-#endif
 
+module_init(cs4231_init);
+module_exit(cs4231_exit);
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
diff -u --recursive --new-file v2.4.5/linux/drivers/sbus/audio/dbri.c linux/drivers/sbus/audio/dbri.c
--- v2.4.5/linux/drivers/sbus/audio/dbri.c	Sun Feb 18 19:49:55 2001
+++ linux/drivers/sbus/audio/dbri.c	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-/* $Id: dbri.c,v 1.25 2001/02/13 01:16:59 davem Exp $
+/* $Id: dbri.c,v 1.26 2001/05/21 01:25:22 davem Exp $
  * drivers/sbus/audio/dbri.c
  *
  * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de)
@@ -61,7 +61,7 @@
 #include <asm/audioio.h>
 #include "dbri.h"
 
-#if defined(DBRI_ISDN) && defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x200ff
+#if defined(DBRI_ISDN)
 #include "../../isdn/hisax/hisax.h"
 #include "../../isdn/hisax/isdnl1.h"
 #include "../../isdn/hisax/foreign.h"
@@ -2227,7 +2227,7 @@
        recv_on_pipe(dbri, 8+chan, buffer, size, callback, callback_arg);
 }
 
-#if defined(DBRI_ISDN) && defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x200ff
+#if defined(DBRI_ISDN)
 struct foreign_interface dbri_foreign_interface = {
         dbri_get_irqnum,
         dbri_get_liu_state,
@@ -2336,11 +2336,7 @@
 }
 
 /* Probe for the dbri chip and then attach the driver. */
-#ifdef MODULE
-int init_module(void)
-#else
-int __init dbri_init(void)
-#endif
+static int __init dbri_init(void)
 {
 	struct sbus_bus *sbus;
 	struct sbus_dev *sdev;
@@ -2368,8 +2364,7 @@
 	return (num_drivers > 0) ? 0 : -EIO;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void __exit dbri_exit(void)
 {
         register int i;
 
@@ -2379,8 +2374,9 @@
                 num_drivers--;
         }
 }
-#endif
 
+module_init(dbri_init);
+module_exit(dbri_exit);
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
diff -u --recursive --new-file v2.4.5/linux/drivers/sbus/audio/dmy.c linux/drivers/sbus/audio/dmy.c
--- v2.4.5/linux/drivers/sbus/audio/dmy.c	Sun Feb 18 19:49:55 2001
+++ linux/drivers/sbus/audio/dmy.c	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-/* $Id: dmy.c,v 1.7 2001/02/13 01:16:59 davem Exp $
+/* $Id: dmy.c,v 1.9 2001/05/22 23:16:10 davem Exp $
  * drivers/sbus/audio/dummy.c
  *
  * Copyright 1998 Derrick J Brashear (shadow@andrew.cmu.edu)
@@ -36,7 +36,7 @@
 static int dummy_record_gain(struct sparcaudio_driver *drv, int value, 
                             unsigned char balance);
 static int dummy_output_muted(struct sparcaudio_driver *drv, int value);
-static int dummy_attach(struct sparcaudio_driver *drv);
+static int dummy_attach(struct sparcaudio_driver *drv) __init;
 
 static int
 dummy_set_output_encoding(struct sparcaudio_driver *drv, int value)
@@ -710,25 +710,8 @@
         dummy_get_formats,
 };
 
-/* Probe for the dummy chip and then attach the driver. */
-#ifdef MODULE
-int init_module(void)
-#else
-int __init dummy_init(void)
-#endif
-{
-        num_drivers = 0;
-      
-        /* Add support here for specifying multiple dummies to attach at once. */
-        if (dummy_attach(&drivers[num_drivers]) == 0)
-                num_drivers++;
-  
-        /* Only return success if we found some dummy chips. */
-        return (num_drivers > 0) ? 0 : -EIO;
-}
-
 /* Attach to an dummy chip given its PROM node. */
-static int dummy_attach(struct sparcaudio_driver *drv)
+static int __init dummy_attach(struct sparcaudio_driver *drv)
 {
         struct dummy_chip *dummy_chip;
         int err;
@@ -768,15 +751,27 @@
         return 0;
 }
 
-#ifdef MODULE
 /* Detach from an dummy chip given the device structure. */
-static void dummy_detach(struct sparcaudio_driver *drv)
+static void __exit dummy_detach(struct sparcaudio_driver *drv)
 {
         unregister_sparcaudio_driver(drv, 2);
         kfree(drv->private);
 }
 
-void cleanup_module(void)
+/* Probe for the dummy chip and then attach the driver. */
+static int __init dummy_init(void)
+{
+	num_drivers = 0;
+      
+	/* Add support here for specifying multiple dummies to attach at once. */
+	if (dummy_attach(&drivers[num_drivers]) == 0)
+		num_drivers++;
+  
+	/* Only return success if we found some dummy chips. */
+	return (num_drivers > 0) ? 0 : -EIO;
+}
+
+static void __exit dummy_exit(void)
 {
         int i;
 
@@ -785,8 +780,9 @@
                 num_drivers--;
         }
 }
-#endif
 
+module_init(dummy_init);
+module_exit(dummy_exit);
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
diff -u --recursive --new-file v2.4.5/linux/drivers/sbus/char/aurora.h linux/drivers/sbus/char/aurora.h
--- v2.4.5/linux/drivers/sbus/char/aurora.h	Mon Dec 20 22:06:42 1999
+++ linux/drivers/sbus/char/aurora.h	Thu Jun 14 14:16:58 2001
@@ -1,4 +1,4 @@
-/*	$Id: aurora.h,v 1.5 1999/12/02 09:55:16 davem Exp $
+/*	$Id: aurora.h,v 1.6 2001/06/05 12:23:38 davem Exp $
  *	linux/drivers/sbus/char/aurora.h -- Aurora multiport driver
  *
  *	Copyright (c) 1999 by Oliver Aldulea (oli@bv.ro)
@@ -244,7 +244,7 @@
 	struct tty_struct 	* tty;
 	int			count;
 	int			blocked_open;
-	int			event;
+	long			event;
 	int			timeout;
 	int			close_delay;
 	long			session;
diff -u --recursive --new-file v2.4.5/linux/drivers/sbus/char/pcikbd.c linux/drivers/sbus/char/pcikbd.c
--- v2.4.5/linux/drivers/sbus/char/pcikbd.c	Wed May 16 10:31:27 2001
+++ linux/drivers/sbus/char/pcikbd.c	Wed Jun 20 21:00:55 2001
@@ -1,4 +1,4 @@
-/* $Id: pcikbd.c,v 1.54 2001/05/11 07:46:28 davem Exp $
+/* $Id: pcikbd.c,v 1.58 2001/06/10 06:51:03 davem Exp $
  * pcikbd.c: Ultra/AX PC keyboard support.
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
@@ -54,6 +54,7 @@
 static int pcikbd_mrcoffee = 0;
 #else
 #define pcikbd_mrcoffee 0
+extern void (*prom_keyboard)(void);
 #endif
 
 static unsigned long pcikbd_iobase = 0;
@@ -66,6 +67,9 @@
 
 static spinlock_t pcikbd_lock = SPIN_LOCK_UNLOCKED;
 
+static void pcikbd_write(int address, int data);
+static int pcikbd_wait_for_input(void);
+
 unsigned char pckbd_read_mask = KBD_STAT_OBF;
 
 extern int pcikbd_init(void);
@@ -239,7 +243,7 @@
 		e0_keys[scancode - 128];
 }
 
-int do_acknowledge(unsigned char scancode)
+static int do_acknowledge(unsigned char scancode)
 {
 	if(reply_expected) {
 		if(scancode == KBD_REPLY_ACK) {
@@ -255,10 +259,95 @@
 	return 1;
 }
 
+#ifdef __sparc_v9__
+static void pcikbd_enter_prom(void)
+{
+	pcikbd_write(KBD_DATA_REG, KBD_CMD_DISABLE);
+	if(pcikbd_wait_for_input() != KBD_REPLY_ACK)
+		printk("Prom Enter: Disable keyboard: no ACK\n");
+
+	/* Disable PC scancode translation */
+	pcikbd_write(KBD_CNTL_REG, KBD_CCMD_WRITE_MODE);
+	pcikbd_write(KBD_DATA_REG, KBD_MODE_SYS);
+	pcikbd_write(KBD_DATA_REG, KBD_CMD_ENABLE);
+	if (pcikbd_wait_for_input() != KBD_REPLY_ACK)
+		printk("Prom Enter: Enable Keyboard: no ACK\n");
+}
+#endif
+
+static void ctrl_break(void)
+{
+	extern int stop_a_enabled;
+	unsigned long timeout;
+	int status, data;
+	int mode;
+
+	if (!stop_a_enabled)
+		return;
+
+	pcikbd_write(KBD_DATA_REG, KBD_CMD_DISABLE);
+	if(pcikbd_wait_for_input() != KBD_REPLY_ACK)
+		printk("Prom Enter: Disable keyboard: no ACK\n");
+
+	/* Save current mode register settings */
+	pcikbd_write(KBD_CNTL_REG, KBD_CCMD_READ_MODE);
+	if ((mode = pcikbd_wait_for_input()) == -1)
+		printk("Prom Enter: Read Mode: no ACK\n");
+
+	/* Disable PC scancode translation */
+	pcikbd_write(KBD_CNTL_REG, KBD_CCMD_WRITE_MODE);
+	pcikbd_write(KBD_DATA_REG, mode & ~(KBD_MODE_KCC));
+	pcikbd_write(KBD_DATA_REG, KBD_CMD_ENABLE);
+	if (pcikbd_wait_for_input() != KBD_REPLY_ACK)
+		printk("Prom Enter: Enable Keyboard: no ACK\n");
+
+	/* Drop into OBP.
+	 * Note that we must flush the user windows
+	 * first before giving up control.
+	 */
+        flush_user_windows();
+	prom_cmdline();
+
+	/* Read prom's key up event (use short timeout) */
+	do {
+		timeout = 10;
+		do {
+			mdelay(1);
+			status = pcikbd_inb(pcikbd_iobase + KBD_STATUS_REG);
+			if (!(status & KBD_STAT_OBF))
+				continue;
+			data = pcikbd_inb(pcikbd_iobase + KBD_DATA_REG);
+			if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
+				continue;
+			break;
+		} while (--timeout > 0);
+	} while (timeout > 0);
+
+	/* Reenable PC scancode translation */
+	pcikbd_write(KBD_DATA_REG, KBD_CMD_DISABLE);
+	if(pcikbd_wait_for_input() != KBD_REPLY_ACK)
+		printk("Prom Leave: Disable keyboard: no ACK\n");
+
+	pcikbd_write(KBD_CNTL_REG, KBD_CCMD_WRITE_MODE);
+	pcikbd_write(KBD_DATA_REG, mode);
+	pcikbd_write(KBD_DATA_REG, KBD_CMD_ENABLE);
+	if (pcikbd_wait_for_input() != KBD_REPLY_ACK)
+		printk("Prom Leave: Enable Keyboard: no ACK\n");
+
+	/* Reset keyboard rate */
+	pcikbd_write(KBD_DATA_REG, KBD_CMD_SET_RATE);
+	if(pcikbd_wait_for_input() != KBD_REPLY_ACK)
+		printk("Prom Leave: Set rate: no ACK\n");
+	pcikbd_write(KBD_DATA_REG, 0x00);
+	if(pcikbd_wait_for_input() != KBD_REPLY_ACK)
+		printk("Prom Leave: Set rate: no ACK\n");
+}
+
 int pcikbd_translate(unsigned char scancode, unsigned char *keycode,
 		     char raw_mode)
 {
 	static int prev_scancode = 0;
+	int down = scancode & 0x80 ? 0 : 1;
 
 	if (scancode == 0xe0 || scancode == 0xe1) {
 		prev_scancode = scancode;
@@ -297,6 +386,18 @@
 
 	} else
 		*keycode = scancode;
+
+	if (*keycode == E0_BREAK) {
+		if (down)
+			return 0;
+
+		/* Handle ctrl-break event */
+		ctrl_break();
+
+		/* Send ctrl up event to the keyboard driver */
+		*keycode = 0x1d;
+	}
+
 	return 1;
 }
 
@@ -338,11 +439,11 @@
 	int retries = 3;
 	unsigned long flags;
 
-	spin_lock_irqsave(&pcikbd_lock, flags);
-
 	do {
 		unsigned long timeout = 1000;
 
+		spin_lock_irqsave(&pcikbd_lock, flags);
+
 		kb_wait();
 
 		acknowledge = 0;
@@ -350,24 +451,23 @@
 		reply_expected = 1;
 
 		pcikbd_outb(data, pcikbd_iobase + KBD_DATA_REG);
+
+		spin_unlock_irqrestore(&pcikbd_lock, flags);
+
 		do {
 			if (acknowledge)
-				goto out_ack;
+				return 1;
 			if (resend)
 				break;
 			mdelay(1);
 		} while (--timeout);
+
 		if (timeout == 0)
-			goto out_timeout;
+			break;
+
 	} while (retries-- > 0);
 
-out_timeout:
-	spin_unlock_irqrestore(&pcikbd_lock, flags);
 	return 0;
-
-out_ack:
-	spin_unlock_irqrestore(&pcikbd_lock, flags);
-	return 1;
 }
 
 void pcikbd_leds(unsigned char leds)
@@ -378,7 +478,7 @@
 		send_data(KBD_CMD_ENABLE);
 }
 
-static int __init pcikbd_wait_for_input(void)
+static int pcikbd_wait_for_input(void)
 {
 	int status, data;
 	unsigned long timeout = 1000;
@@ -401,7 +501,7 @@
 	return -1;
 }
 
-static void __init pcikbd_write(int address, int data)
+static void pcikbd_write(int address, int data)
 {
 	int status;
 
@@ -664,6 +764,8 @@
 	kd_mksound = pcikbd_kd_mksound;
 	printk("8042(speaker): iobase[%016lx]%s\n", pcibeep_iobase,
 	       edev ? "" : " (forced)");
+
+	prom_keyboard = pcikbd_enter_prom;
 #endif
 
 	disable_irq(pcikbd_irq);
diff -u --recursive --new-file v2.4.5/linux/drivers/sbus/char/sab82532.c linux/drivers/sbus/char/sab82532.c
--- v2.4.5/linux/drivers/sbus/char/sab82532.c	Thu Apr 19 08:38:49 2001
+++ linux/drivers/sbus/char/sab82532.c	Wed Jun 20 21:00:55 2001
@@ -1,8 +1,11 @@
-/* $Id: sab82532.c,v 1.58 2001/04/17 06:30:36 davem Exp $
+/* $Id: sab82532.c,v 1.62 2001/06/10 06:48:47 davem Exp $
  * sab82532.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC.
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
  *
+ * Rewrote buffer handling to use CIRC(Circular Buffer) macros.
+ *   Maxim Krasnyanskiy <maxk@qualcomm.com>
+ *
  */
 
 #include <linux/config.h>
@@ -59,6 +62,7 @@
 #undef SERIAL_DEBUG_WAIT_UNTIL_SENT
 #undef SERIAL_DEBUG_SEND_BREAK
 #undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_FIFO
 #define SERIAL_DEBUG_OVERFLOW 1
 
 /* Trace things on serial device, useful for console debugging: */
@@ -209,22 +213,23 @@
 
 	save_flags(flags); cli();
 
-	if (info->xmit_cnt <= 0)
+	if (info->xmit.head == info->xmit.tail)
 		goto out;
 
-	if (!(readb(&info->regs->r.star) & SAB82532_STAR_XFW))
+	if (!test_bit(SAB82532_XPR, &info->irqflags))
 		goto out;
 
 	info->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS);
 	writeb(info->interrupt_mask1, &info->regs->w.imr1);
-	info->all_sent = 0;
+	clear_bit(SAB82532_ALLS, &info->irqflags);
 
+	clear_bit(SAB82532_XPR, &info->irqflags);
 	for (i = 0; i < info->xmit_fifo_size; i++) {
-		u8 val = info->xmit_buf[info->xmit_tail++];
-		writeb(val, &info->regs->w.xfifo[i]);
-		info->xmit_tail &= (SERIAL_XMIT_SIZE - 1);
+		writeb(info->xmit.buf[info->xmit.tail],
+		       &info->regs->w.xfifo[i]);
+		info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
 		info->icount.tx++;
-		if (--info->xmit_cnt <= 0)
+		if (info->xmit.head == info->xmit.tail)
 			break;
 	}
 
@@ -397,20 +402,29 @@
 	if (stat->sreg.isr1 & SAB82532_ISR1_ALLS) {
 		info->interrupt_mask1 |= SAB82532_IMR1_ALLS;
 		writeb(info->interrupt_mask1, &info->regs->w.imr1);
-		info->all_sent = 1;
+		set_bit(SAB82532_ALLS, &info->irqflags);
 	}
 
 	if (!(stat->sreg.isr1 & SAB82532_ISR1_XPR))
 		return;
 
+	if (!(readb(&info->regs->r.star) & SAB82532_STAR_XFW)) {
+#ifdef SERIAL_DEBUG_FIFO
+		printk("%s: XPR, but no XFW (?)\n", __FUNCTION__);
+#endif
+		return;
+	}
+
+	set_bit(SAB82532_XPR, &info->irqflags);
+
 	if (!info->tty) {
 		info->interrupt_mask1 |= SAB82532_IMR1_XPR;
 		writeb(info->interrupt_mask1, &info->regs->w.imr1);
 		return;
 	}
 
-	if ((info->xmit_cnt <= 0) || info->tty->stopped ||
-	    info->tty->hw_stopped) {
+	if ((info->xmit.head == info->xmit.tail) ||
+	    info->tty->stopped || info->tty->hw_stopped) {
 		info->interrupt_mask1 |= SAB82532_IMR1_XPR;
 		writeb(info->interrupt_mask1, &info->regs->w.imr1);
 		return;
@@ -418,15 +432,16 @@
 
 	info->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS);
 	writeb(info->interrupt_mask1, &info->regs->w.imr1);
-	info->all_sent = 0;
+	clear_bit(SAB82532_ALLS, &info->irqflags);
 
 	/* Stuff 32 bytes into Transmit FIFO. */
+	clear_bit(SAB82532_XPR, &info->irqflags);
 	for (i = 0; i < info->xmit_fifo_size; i++) {
-		u8 val = info->xmit_buf[info->xmit_tail++];
-		writeb(val, &info->regs->w.xfifo[i]);
-		info->xmit_tail &= (SERIAL_XMIT_SIZE - 1);
+		writeb(info->xmit.buf[info->xmit.tail],
+		       &info->regs->w.xfifo[i]);
+		info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
 		info->icount.tx++;
-		if (--info->xmit_cnt <= 0)
+		if (info->xmit.head == info->xmit.tail)
 			break;
 	}
 
@@ -434,16 +449,12 @@
 	sab82532_cec_wait(info);
 	writeb(SAB82532_CMDR_XF, &info->regs->w.cmdr);
 
-	if (info->xmit_cnt < WAKEUP_CHARS)
+	if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) < WAKEUP_CHARS)
 		sab82532_sched_event(info, RS_EVENT_WRITE_WAKEUP);
 
 #ifdef SERIAL_DEBUG_INTR
 	printk("THRE...");
 #endif
-	if (info->xmit_cnt <= 0) {
-		info->interrupt_mask1 |= SAB82532_IMR1_XPR;
-		writeb(info->interrupt_mask1, &info->regs->w.imr1);
-	}
 }
 
 static void check_status(struct sab82532 *info,
@@ -620,6 +631,7 @@
 		transmit_chars(info, &status);
 
 done:
+	;
 #ifdef SERIAL_DEBUG_INTR
 	printk("end.\n");
 #endif
@@ -774,10 +786,10 @@
 		retval = -ENODEV;
 		goto errout;
 	}
-	if (info->xmit_buf)
+	if (info->xmit.buf)
 		free_page(page);
 	else
-		info->xmit_buf = (unsigned char *)page;
+		info->xmit.buf = (unsigned char *)page;
 
 #ifdef SERIAL_DEBUG_OPEN
 	printk("starting up serial port %d...", info->line);
@@ -812,11 +824,13 @@
 				SAB82532_IMR1_CSC | SAB82532_IMR1_XON |
 				SAB82532_IMR1_XPR;
 	writeb(info->interrupt_mask1, &info->regs->w.imr1);
-	info->all_sent = 1;
+	set_bit(SAB82532_ALLS, &info->irqflags);
 
 	if (info->tty)
 		clear_bit(TTY_IO_ERROR, &info->tty->flags);
-	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+	info->xmit.head = info->xmit.tail = 0;
+
+	set_bit(SAB82532_XPR, &info->irqflags);
 
 	/*
 	 * and set the speed of the serial port
@@ -856,9 +870,9 @@
 	 */
 	wake_up_interruptible(&info->delta_msr_wait);
 
-	if (info->xmit_buf) {
-		free_page((unsigned long)info->xmit_buf);
-		info->xmit_buf = 0;
+	if (info->xmit.buf) {
+		free_page((unsigned long)info->xmit.buf);
+		info->xmit.buf = 0;
 	}
 
 #ifdef CONFIG_SERIAL_CONSOLE
@@ -886,9 +900,11 @@
 	writeb(info->interrupt_mask1, &info->regs->w.imr1);
 
 	if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
-		writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_FRTS, &info->regs->rw.mode);
-		writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_RTS, &info->regs->rw.mode);
-		writeb(readb(&info->regs->rw.pvr) | info->pvr_dtr_bit, &info->regs->rw.pvr);
+		tmp = readb(&info->regs->r.mode);
+		tmp |= (SAB82532_MODE_FRTS | SAB82532_MODE_RTS);
+		writeb(tmp, &info->regs->rw.mode);
+		writeb(readb(&info->regs->rw.pvr) | info->pvr_dtr_bit,
+		       &info->regs->rw.pvr);
 	}
 
 	/* Disable break condition */
@@ -1054,18 +1070,17 @@
 	if (serial_paranoia_check(info, tty->device, "sab82532_put_char"))
 		return;
 
-	if (!tty || !info->xmit_buf)
+	if (!tty || !info->xmit.buf)
 		return;
 
 	save_flags(flags); cli();
-	if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
+	if (!CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE)) {
 		restore_flags(flags);
 		return;
 	}
 
-	info->xmit_buf[info->xmit_head++] = ch;
-	info->xmit_head &= SERIAL_XMIT_SIZE-1;
-	info->xmit_cnt++;
+	info->xmit.buf[info->xmit.head] = ch;
+	info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
 	restore_flags(flags);
 }
 
@@ -1077,8 +1092,8 @@
 	if (serial_paranoia_check(info, tty->device, "sab82532_flush_chars"))
 		return;
 
-	if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
-	    !info->xmit_buf)
+	if ((info->xmit.head == info->xmit.tail) ||
+	    tty->stopped || tty->hw_stopped || !info->xmit.buf)
 		return;
 
 	save_flags(flags); cli();
@@ -1098,42 +1113,63 @@
 	if (serial_paranoia_check(info, tty->device, "sab82532_write"))
 		return 0;
 
-	if (!tty || !info->xmit_buf || !tmp_buf)
+	if (!tty || !info->xmit.buf || !tmp_buf)
 		return 0;
 	    
-	if (from_user)
-		down(&tmp_buf_sem);
 	save_flags(flags);
-	while (1) {
-		cli();		
-		c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
-				   SERIAL_XMIT_SIZE - info->xmit_head));
-		if (c <= 0)
-			break;
+	if (from_user) {
+		down(&tmp_buf_sem);
+		while (1) {
+			int c1;
+			c = CIRC_SPACE_TO_END(info->xmit.head,
+					      info->xmit.tail,
+					      SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0)
+				break;
 
-		if (from_user) {
 			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);
-		} else
-			memcpy(info->xmit_buf + info->xmit_head, buf, c);
-		info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
-		info->xmit_cnt += c;
+			cli();
+			c1 = CIRC_SPACE_TO_END(info->xmit.head,
+					       info->xmit.tail,
+					       SERIAL_XMIT_SIZE);
+			if (c1 < c)
+				c = c1;
+			memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
+			info->xmit.head = (info->xmit.head + c) & (SERIAL_XMIT_SIZE-1);
+			restore_flags(flags);
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		up(&tmp_buf_sem);
+	} else {
+		cli();
+		while (1) {
+			c = CIRC_SPACE_TO_END(info->xmit.head,
+					      info->xmit.tail,
+					      SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0)
+				break;
+			memcpy(info->xmit.buf + info->xmit.head, buf, c);
+			info->xmit.head = (info->xmit.head + c) & (SERIAL_XMIT_SIZE-1);
+			buf += c;
+			count -= c;
+			ret += c;
+		}
 		restore_flags(flags);
-		buf += c;
-		count -= c;
-		ret += c;
 	}
-	if (from_user)
-		up(&tmp_buf_sem);
 
-	if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
+	if ((info->xmit.head != info->xmit.tail) &&
+	    !tty->stopped && !tty->hw_stopped) {
 		info->interrupt_mask1 &= ~(SAB82532_IMR1_XPR);
 		writeb(info->interrupt_mask1, &info->regs->w.imr1);
 		sab82532_start_tx(info);
@@ -1146,14 +1182,11 @@
 static int sab82532_write_room(struct tty_struct *tty)
 {
 	struct sab82532 *info = (struct sab82532 *)tty->driver_data;
-	int ret;
 
 	if (serial_paranoia_check(info, tty->device, "sab82532_write_room"))
 		return 0;
-	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
-	if (ret < 0)
-		ret = 0;
-	return ret;
+
+	return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
 }
 
 static int sab82532_chars_in_buffer(struct tty_struct *tty)
@@ -1162,18 +1195,22 @@
 				
 	if (serial_paranoia_check(info, tty->device, "sab82532_chars_in_buffer"))
 		return 0;
-	return info->xmit_cnt;
+
+	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
 }
 
 static void sab82532_flush_buffer(struct tty_struct *tty)
 {
 	struct sab82532 *info = (struct sab82532 *)tty->driver_data;
+	unsigned long flags;
 
 	if (serial_paranoia_check(info, tty->device, "sab82532_flush_buffer"))
 		return;
-	cli();
-	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-	sti();
+
+	save_flags(flags); cli();
+	info->xmit.head = info->xmit.tail = 0;
+	restore_flags(flags);
+
 	wake_up_interruptible(&tty->write_wait);
 	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
 	    tty->ldisc.write_wakeup)
@@ -1221,6 +1258,12 @@
 	
 	if (I_IXOFF(tty))
 		sab82532_send_xchar(tty, STOP_CHAR(tty));
+
+	if (tty->termios->c_cflag & CRTSCTS) {
+		u8 mode = readb(&info->regs->r.mode);
+		mode &= ~(SAB82532_MODE_FRTS | SAB82532_MODE_RTS);
+		writeb(mode, &info->regs->w.mode);
+	}
 }
 
 static void sab82532_unthrottle(struct tty_struct * tty)
@@ -1242,6 +1285,13 @@
 		else
 			sab82532_send_xchar(tty, START_CHAR(tty));
 	}
+
+	if (tty->termios->c_cflag & CRTSCTS) {
+		u8 mode = readb(&info->regs->r.mode);
+		mode &= ~(SAB82532_MODE_RTS);
+		mode |= SAB82532_MODE_FRTS;
+		writeb(mode, &info->regs->w.mode);
+	}
 }
 
 /*
@@ -1295,7 +1345,8 @@
 {
 	unsigned int result;
 
-	result = (!info->xmit_buf && info->all_sent) ? TIOCSER_TEMT : 0;
+	result = (!info->xmit.buf && test_bit(SAB82532_ALLS, &info->irqflags))
+							? TIOCSER_TEMT : 0;
 	return put_user(result, value);
 }
 
@@ -1523,8 +1574,12 @@
 	if (!(old_termios->c_cflag & CBAUD) &&
 	    (tty->termios->c_cflag & CBAUD)) {
 		writeb(readb(&info->regs->w.pvr) & ~(info->pvr_dtr_bit), &info->regs->w.pvr);
-		if (!tty->hw_stopped ||
-		    !(tty->termios->c_cflag & CRTSCTS)) {
+		if (tty->termios->c_cflag & CRTSCTS) {
+			writeb(readb(&info->regs->w.mode) & ~(SAB82532_MODE_RTS), &info->regs->w.mode);
+			writeb(readb(&info->regs->w.mode) | SAB82532_MODE_FRTS, &info->regs->w.mode);
+		} else if (test_bit(TTY_THROTTLED, &tty->flags)) {
+			writeb(readb(&info->regs->w.mode) & ~(SAB82532_MODE_FRTS | SAB82532_MODE_RTS), &info->regs->w.mode);
+		} else {
 			writeb(readb(&info->regs->w.mode) & ~(SAB82532_MODE_FRTS), &info->regs->w.mode);
 			writeb(readb(&info->regs->w.mode) | SAB82532_MODE_RTS, &info->regs->w.mode);
 		}
@@ -1654,7 +1709,6 @@
 	if (serial_paranoia_check(info,tty->device,"sab82532_wait_until_sent"))
 		return;
 
-	orig_jiffies = jiffies;
 	/*
 	 * Set the check interval to be 1/5 of the estimated time to
 	 * send a single character, and make it at least 1.  The check
@@ -1670,10 +1724,15 @@
 	if (timeout)
 	  char_time = MIN(char_time, timeout);
 #ifdef SERIAL_DEBUG_WAIT_UNTIL_SENT
-	printk("In sab82532_wait_until_sent(%d) check=%lu...", timeout, char_time);
-	printk("jiff=%lu...", jiffies);
+	printk("In sab82532_wait_until_sent(%d) check=%lu "
+	       "xmit_cnt = %ld, alls = %d (jiff=%lu)...\n",
+	       timeout, char_time,
+	       CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE),
+	       test_bit(SAB82532_ALLS, &info->irqflags), jiffies);
 #endif
-	while (info->xmit_cnt || !info->all_sent) {
+	orig_jiffies = jiffies;
+	while ((info->xmit.head != info->xmit.tail) ||
+	       !test_bit(SAB82532_ALLS, &info->irqflags)) {
 		current->state = TASK_INTERRUPTIBLE;
 		schedule_timeout(char_time);
 		if (signal_pending(current))
@@ -1682,7 +1741,9 @@
 			break;
 	}
 #ifdef SERIAL_DEBUG_WAIT_UNTIL_SENT
-	printk("xmit_cnt = %d, alls = %d (jiff=%lu)...done\n", info->xmit_cnt, info->all_sent, jiffies);
+	printk("xmit_cnt = %ld, alls = %d (jiff=%lu)...done\n",
+	       CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE),
+	       test_bit(SAB82532_ALLS, &info->irqflags), jiffies);
 #endif
 }
 
@@ -2151,7 +2212,7 @@
 
 static inline void __init show_serial_version(void)
 {
-	char *revision = "$Revision: 1.58 $";
+	char *revision = "$Revision: 1.62 $";
 	char *version, *p;
 
 	version = strchr(revision, ' ');
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/3w-xxxx.c linux/drivers/scsi/3w-xxxx.c
--- v2.4.5/linux/drivers/scsi/3w-xxxx.c	Fri Apr 27 13:59:17 2001
+++ linux/drivers/scsi/3w-xxxx.c	Wed Jun 27 17:10:55 2001
@@ -76,6 +76,20 @@
                  Make tw_setfeature() call with interrupts disabled.
                  Register interrupt handler before enabling interrupts.
                  Clear attention interrupt before draining aen queue.
+   1.02.00.005 - Allocate bounce buffers and custom queue depth for raid5 for
+                 6000 and 5000 series controllers.
+                 Reduce polling mdelays causing problems on some systems.
+                 Fix use_sg = 1 calculation bug.
+                 Check for scsi_register returning NULL.
+                 Add aen count to /proc/scsi/3w-xxxx.
+                 Remove aen code unit masking in tw_aen_complete().
+   1.02.00.006 - Remove unit from printk in tw_scsi_eh_abort(), causing
+                 possible oops.
+                 Fix possible null pointer dereference in tw_scsi_queue()
+                 if done function pointer was invalid.
+   1.02.00.007 - Fix possible null pointer dereferences in tw_ioctl().
+                 Remove check for invalid done function pointer from
+                 tw_scsi_queue().
 */
 
 #include <linux/module.h>
@@ -121,7 +135,7 @@
 };
 
 /* Globals */
-char *tw_driver_version="1.02.00.004";
+char *tw_driver_version="1.02.00.007";
 TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
 int tw_device_extension_count = 0;
 
@@ -131,7 +145,7 @@
 int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id) 
 {
 	TW_Param *param;
-	unsigned short aen, aen_code;
+	unsigned short aen;
 
 	if (tw_dev->alignment_virtual_address[request_id] == NULL) {
 		printk(KERN_WARNING "3w-xxxx: tw_aen_complete(): Bad alignment virtual address.\n");
@@ -139,10 +153,9 @@
 	}
 	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
 	aen = *(unsigned short *)(param->data);
-	aen_code = (aen & 0x0ff);
-	dprintk(KERN_NOTICE "3w-xxxx: tw_aen_complete(): Queue'd code 0x%x\n", aen_code);
+	dprintk(KERN_NOTICE "3w-xxxx: tw_aen_complete(): Queue'd code 0x%x\n", aen);
 	/* Now queue the code */
-	tw_dev->aen_queue[tw_dev->aen_tail] = aen_code;
+	tw_dev->aen_queue[tw_dev->aen_tail] = aen;
 	if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
 		tw_dev->aen_tail = TW_Q_START;
 	} else {
@@ -241,7 +254,7 @@
     
 		/* Now poll for completion */
 		for (i=0;i<imax;i++) {
-			mdelay(10);
+			mdelay(5);
 			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");
@@ -437,13 +450,21 @@
 		return 1;
 	}
 
-	if (which == 0) {
+	switch(which) {
+	case 0:
 		tw_dev->command_packet_virtual_address[request_id] = virt_addr;
-		tw_dev->command_packet_physical_address[request_id] = 
-		virt_to_bus(virt_addr);
-	} else {
+		tw_dev->command_packet_physical_address[request_id] = virt_to_bus(virt_addr);
+		break;
+	case 1:
 		tw_dev->alignment_virtual_address[request_id] = virt_addr;
 		tw_dev->alignment_physical_address[request_id] = virt_to_bus(virt_addr);
+		break;
+	case 2:
+		tw_dev->bounce_buffer[request_id] = virt_addr;
+		break;
+	default:
+		printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): case slip in tw_allocate_memory()\n");
+		return 1;
 	}
 	return 0;
 } /* End tw_allocate_memory() */
@@ -709,8 +730,8 @@
 
 		/* Register the card with the kernel SCSI layer */
 			host = scsi_register(tw_host, sizeof(TW_Device_Extension));
-			if( host == NULL)
-			{
+			if (host == NULL) {
+				printk(KERN_WARNING "3w-xxxx: tw_findcards(): scsi_register() failed for card %d.\n", numcards-1);
 				release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
 				tw_free_device_extension(tw_dev);
 				kfree(tw_dev);
@@ -788,6 +809,9 @@
 
 		if (tw_dev->alignment_virtual_address[i])
 			kfree(tw_dev->alignment_virtual_address[i]);
+
+		if (tw_dev->bounce_buffer[i])
+			kfree(tw_dev->bounce_buffer[i]);
 	}
 } /* End tw_free_device_extension() */
 
@@ -853,7 +877,7 @@
 	/* Poll for completion */
 	imax = TW_POLL_MAX_RETRIES;
 	for (i=0;i<imax;i++) {
-		mdelay(10);
+		mdelay(5);
 		status_reg_value = inl(status_reg_addr);
 		if (tw_check_bits(status_reg_value)) {
 			printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected bits.\n");
@@ -909,8 +933,10 @@
 		tw_dev->aen_queue[i] = 0;
 	}
 
-	for (i=0;i<TW_MAX_UNITS;i++)
+	for (i=0;i<TW_MAX_UNITS;i++) {
 		tw_dev->is_unit_present[i] = 0;
+		tw_dev->is_raid_five[i] = 0;
+	}
 
 	tw_dev->num_units = 0;
 	tw_dev->num_aborts = 0;
@@ -928,6 +954,8 @@
 	tw_dev->aen_tail = 0;
 	tw_dev->sector_count = 0;
 	tw_dev->max_sector_count = 0;
+	tw_dev->aen_count = 0;
+	tw_dev->num_raid_five = 0;
 	spin_lock_init(&tw_dev->tw_lock);
 	tw_dev->flags = 0;
 	return 0;
@@ -940,13 +968,14 @@
 	unsigned char request_id = 0;
 	TW_Command *command_packet;
 	TW_Param *param;
-	int i, imax, num_units = 0;
+	int i, j, imax, num_units = 0, num_raid_five = 0;
 	u32 status_reg_addr, status_reg_value;
 	u32 command_que_addr, command_que_value;
 	u32 response_que_addr;
 	TW_Response_Queue response_queue;
 	u32 param_value;
 	unsigned char *is_unit_present;
+	unsigned char *raid_level;
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units()\n");
 
@@ -1001,7 +1030,7 @@
 	/* Poll for completion */
 	imax = TW_POLL_MAX_RETRIES;
 	for(i=0; i<imax; i++) {
-		mdelay(10);
+		mdelay(5);
 		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");
@@ -1052,6 +1081,110 @@
 		printk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): No units found.\n");
 		return 1;
 	}
+
+	/* Find raid 5 arrays */
+	for (j=0;j<TW_MAX_UNITS;j++) {
+		if (tw_dev->is_unit_present[j] == 0)
+			continue;
+		command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
+		if (command_packet == NULL) {
+			printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet virtual address.\n");
+			return 1;
+		}
+		memset(command_packet, 0, sizeof(TW_Sector));
+		command_packet->byte0.opcode      = TW_OP_GET_PARAM;
+		command_packet->byte0.sgl_offset  = 2;
+		command_packet->size              = 4;
+		command_packet->request_id        = request_id;
+		command_packet->byte3.unit        = 0;
+		command_packet->byte3.host_id     = 0;
+		command_packet->status            = 0;
+		command_packet->flags             = 0;
+		command_packet->byte6.block_count = 1;
+
+		/* Now setup the param */
+		if (tw_dev->alignment_virtual_address[request_id] == NULL) {
+			printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment virtual address.\n");
+			return 1;
+		}
+		param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+		memset(param, 0, sizeof(TW_Sector));
+		param->table_id = 0x300+j; /* unit summary table */
+		param->parameter_id = 0x6; /* unit descriptor */
+		param->parameter_size_bytes = 0xc;
+		param_value = tw_dev->alignment_physical_address[request_id];
+		if (param_value == 0) {
+			printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment physical address.\n");
+			return 1;
+		}
+
+		command_packet->byte8.param.sgl[0].address = param_value;
+		command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
+
+		/* Post the command packet to the board */
+		command_que_value = tw_dev->command_packet_physical_address[request_id];
+		if (command_que_value == 0) {
+			printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet physical address.\n");
+			return 1;
+		}
+		outl(command_que_value, command_que_addr);
+
+		/* Poll for completion */
+		imax = TW_POLL_MAX_RETRIES;
+		for(i=0; i<imax; i++) {
+			mdelay(5);
+			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");
+				return 1;
+			}
+			if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
+				response_queue.value = inl(response_que_addr);
+				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");
+					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);
+					return 1;
+				}
+				found = 1;
+				break;
+			}
+		}
+		if (found == 0) {
+			/* response never received */
+			printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): No
+ response.\n");
+			return 1;
+		}
+
+		param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+		raid_level = (unsigned char *)&(param->data[1]);
+		if (*raid_level == 5) {
+			dprintk(KERN_WARNING "3w-xxxx: Found unit %d to be a raid5 unit.\n", j);
+			tw_dev->is_raid_five[j] = 1;
+			num_raid_five++;
+		}
+	}
+	tw_dev->num_raid_five = num_raid_five;
+
+	/* 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);
+			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);
+		}
+	}
   
 	return 0;
 } /* End tw_initialize_units() */
@@ -1288,12 +1421,17 @@
 		case TW_OP_SET_PARAM:
 			dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_SET_PARAM: table_id = %d, parameter_id = %d, parameter_size_bytes = %d.\n",
 			ioctl->table_id, ioctl->parameter_id, ioctl->parameter_size_bytes);
-			command_packet->byte0.opcode = TW_OP_SET_PARAM;
-			param->table_id = ioctl->table_id;
-			param->parameter_id = ioctl->parameter_id;
-			param->parameter_size_bytes = ioctl->parameter_size_bytes;
-			memcpy(param->data, ioctl->data, ioctl->parameter_size_bytes);
-			break;
+			if (ioctl->data != NULL) {
+				command_packet->byte0.opcode = TW_OP_SET_PARAM;
+				param->table_id = ioctl->table_id;
+				param->parameter_id = ioctl->parameter_id;
+				param->parameter_size_bytes = ioctl->parameter_size_bytes;
+				memcpy(param->data, ioctl->data, ioctl->parameter_size_bytes);
+				break;
+			} else {
+				printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
+				return 1;
+			}
 		case TW_OP_AEN_LISTEN:
 			dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_AEN_LISTEN.\n");
 			if (tw_dev->aen_head == tw_dev->aen_tail) {
@@ -1318,11 +1456,15 @@
 			tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
 			return 0;
 	        case TW_CMD_PACKET:
-		  memcpy(command_packet, ioctl->data, sizeof(TW_Command));
-		  command_packet->request_id = request_id;
-		  tw_post_command_packet(tw_dev, request_id);
-
-		  return 0;
+			if (ioctl->data != NULL) {
+				memcpy(command_packet, ioctl->data, sizeof(TW_Command));
+				command_packet->request_id = request_id;
+				tw_post_command_packet(tw_dev, request_id);
+				return 0;
+			} else {
+				printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
+				return 1;
+			}
 		default:
 			printk(KERN_WARNING "3w-xxxx: Unknown ioctl 0x%x.\n", opcode);
 			tw_dev->state[request_id] = TW_S_COMPLETED;
@@ -1602,10 +1744,8 @@
 		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() */
 
@@ -1763,6 +1903,7 @@
 		tw_copy_info(&info, "Max sector count:              %3d\n", tw_dev->max_sector_count);
 		tw_copy_info(&info, "Resets:                        %3d\n", tw_dev->num_resets);
 		tw_copy_info(&info, "Aborts:                        %3d\n", tw_dev->num_aborts);
+		tw_copy_info(&info, "AEN's:                         %3d\n", tw_dev->aen_count);
 	}
 	if (info.position > info.offset) {
 		return (info.position - info.offset);
@@ -1780,6 +1921,13 @@
 	int flags = 0;
 	TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata;
 
+	if (tw_dev == NULL) {
+		printk(KERN_WARNING "3w-xxxx: tw_scsi_queue(): Invalid device extension.\n");
+		SCpnt->result = (DID_ERROR << 16);
+		done(SCpnt);
+		return 0;
+	}
+
 	spin_lock_irqsave(&tw_dev->tw_lock, flags);
 	dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue()\n");
 
@@ -1790,20 +1938,6 @@
 		spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
 		return 0;
 	}
-	if (done == NULL) {
-		printk(KERN_WARNING "3w-xxxx: tw_scsi_queue(): Invalid done function.\n");
-		SCpnt->result = (DID_ERROR << 16);
-		done(SCpnt);
-		spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
-		return 0;
-	}
-	if (tw_dev == NULL) {
-		printk(KERN_WARNING "3w-xxxx: tw_scsi_queue(): Invalid device extension.\n");
-		SCpnt->result = (DID_ERROR << 16);
-		done(SCpnt);
-		spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
-		return 0;
-	}
 	
 	/* Save done function into Scsi_Cmnd struct */
 	SCpnt->scsi_done = done;
@@ -2104,7 +2238,7 @@
 	TW_Command *command_packet;
 	u32 command_que_addr, command_que_value = 0;
 	u32 lba = 0x0, num_sectors = 0x0;
-	int i;
+	int i, count = 0;
 	Scsi_Cmnd *srb;
 	struct scatterlist *sglist;
 
@@ -2161,23 +2295,45 @@
 	command_packet->byte8.io.lba = lba;
 	command_packet->byte6.block_count = num_sectors;
 
-	/* Do this if there are no sg list entries */
-	if (tw_dev->srb[request_id]->use_sg == 0) {    
-		dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): SG = 0\n");
-		command_packet->byte8.io.sgl[0].address = virt_to_bus(tw_dev->srb[request_id]->request_buffer);
-		command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen;
-	}
-
-	/* Do this if we have multiple sg list entries */
-	if (tw_dev->srb[request_id]->use_sg > 0) {
-		for (i=0;i<tw_dev->srb[request_id]->use_sg; i++) {
-			command_packet->byte8.io.sgl[i].address = virt_to_bus(sglist[i].address);
-			command_packet->byte8.io.sgl[i].length = sglist[i].length;
-			command_packet->size+=2;
+	if ((tw_dev->is_raid_five[tw_dev->srb[request_id]->target] == 0) || (srb->cmnd[0] == READ_6) || (srb->cmnd[0] == READ_10) || (tw_dev->tw_pci_dev->device == TW_DEVICE_ID2)) {
+		/* Do this if there are no sg list entries */
+		if (tw_dev->srb[request_id]->use_sg == 0) {    
+			dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): SG = 0\n");
+			command_packet->byte8.io.sgl[0].address = virt_to_bus(tw_dev->srb[request_id]->request_buffer);
+			command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen;
+		}
+
+		/* Do this if we have multiple sg list entries */
+		if (tw_dev->srb[request_id]->use_sg > 0) {
+			for (i=0;i<tw_dev->srb[request_id]->use_sg; i++) {
+				command_packet->byte8.io.sgl[i].address = virt_to_bus(sglist[i].address);
+				command_packet->byte8.io.sgl[i].length = sglist[i].length;
+				command_packet->size+=2;
+			}
+			if (tw_dev->srb[request_id]->use_sg >= 1)
+				command_packet->size-=2;
 		}
-		if (tw_dev->srb[request_id]->use_sg > 1)
-			command_packet->size-=2;
-	}
+	} else {
+                /* Do this if there are no sg list entries for raid 5 */
+                if (tw_dev->srb[request_id]->use_sg == 0) {
+			dprintk(KERN_WARNING "doing raid 5 write use_sg = 0, bounce_buffer[%d] = 0x%p\n", request_id, tw_dev->bounce_buffer[request_id]);
+			memcpy(tw_dev->bounce_buffer[request_id], tw_dev->srb[request_id]->request_buffer, tw_dev->srb[request_id]->request_bufflen);
+			command_packet->byte8.io.sgl[0].address = virt_to_bus(tw_dev->bounce_buffer[request_id]);
+			command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen;
+                }
+
+                /* Do this if we have multiple sg list entries for raid 5 */
+                if (tw_dev->srb[request_id]->use_sg > 0) {
+                        dprintk(KERN_WARNING "doing raid 5 write use_sg = %d, sglist[0].length = %d\n", tw_dev->srb[request_id]->use_sg, sglist[0].length);
+                        for (i=0;i<tw_dev->srb[request_id]->use_sg; i++) {
+                                memcpy((char *)(tw_dev->bounce_buffer[request_id])+count, sglist[i].address, sglist[i].length);
+				count+=sglist[i].length;
+                        }
+                        command_packet->byte8.io.sgl[0].address = virt_to_bus(tw_dev->bounce_buffer[request_id]);
+                        command_packet->byte8.io.sgl[0].length = count;
+                        command_packet->size = 5; /* single sgl */
+                }
+        }
 
 	/* Update SG statistics */
 	tw_dev->sgl_entries = tw_dev->srb[request_id]->use_sg;
@@ -2287,7 +2443,7 @@
 	/* Poll for completion */
 	imax = TW_POLL_MAX_RETRIES;
 	for (i=0;i<imax;i++) {
-		mdelay(10);
+		mdelay(5);
 		status_reg_value = inl(status_reg_addr);
 		if (tw_check_bits(status_reg_value)) {
 			printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected bits.\n");
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/3w-xxxx.h linux/drivers/scsi/3w-xxxx.h
--- v2.4.5/linux/drivers/scsi/3w-xxxx.h	Fri Mar  2 18:38:38 2001
+++ linux/drivers/scsi/3w-xxxx.h	Wed Jun 27 17:10:55 2001
@@ -129,9 +129,9 @@
 #define TW_COMMAND_ALIGNMENT_MASK	      0x1ff
 #define TW_INIT_MESSAGE_CREDITS		      0x100
 #define TW_INIT_COMMAND_PACKET_SIZE	      0x3
-#define TW_POLL_MAX_RETRIES        	      10000
+#define TW_POLL_MAX_RETRIES        	      20000
 #define TW_MAX_SGL_LENGTH		      62
-#define TW_Q_LENGTH			      256
+#define TW_Q_LENGTH			      16
 #define TW_Q_START			      0
 #define TW_MAX_SLOT			      32
 #define TW_MAX_PCI_BUSES		      255
@@ -262,8 +262,11 @@
 	TW_Registers		registers;
 	u32			*alignment_virtual_address[TW_Q_LENGTH];
 	u32			alignment_physical_address[TW_Q_LENGTH];
+	u32			*bounce_buffer[TW_Q_LENGTH];
 	int			is_unit_present[TW_MAX_UNITS];
+	int			is_raid_five[TW_MAX_UNITS];
 	int			num_units;
+	int			num_raid_five;
 	u32			*command_packet_virtual_address[TW_Q_LENGTH];
 	u32			command_packet_physical_address[TW_Q_LENGTH];
 	struct pci_dev		*tw_pci_dev;
@@ -286,6 +289,7 @@
 	u32			num_resets;
 	u32			sector_count;
 	u32			max_sector_count;
+	u32			aen_count;
 	struct Scsi_Host	*host;
 	spinlock_t		tw_lock;
 	unsigned char		ioctl_size[TW_Q_LENGTH];
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/NCR53c406a.c linux/drivers/scsi/NCR53c406a.c
--- v2.4.5/linux/drivers/scsi/NCR53c406a.c	Tue May 22 10:23:16 2001
+++ linux/drivers/scsi/NCR53c406a.c	Wed Jun 27 17:10:55 2001
@@ -221,7 +221,7 @@
     (void *)0xc8000
 };
 #define ADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned ))
-#endif USE_BIOS
+#endif /* USE_BIOS */
 		       
 /* possible i/o port addresses */
 static unsigned short ports[] =
@@ -244,7 +244,7 @@
     { "Copyright (C) Acculogic, Inc.\r\n2.8M Diskette Extension Bios ver 4.04.03 03/01/1993", 61, 82 },
 };
 #define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature ))
-#endif USE_BIOS
+#endif /* USE_BIOS */
 
 /* ============================================================ */
 
@@ -347,7 +347,7 @@
     
     return tmp;
 }
-#endif USE_DMA
+#endif /* USE_DMA */
 
 #if USE_PIO
 static __inline__ int NCR53c406a_pio_read(unsigned char *request, 
@@ -455,7 +455,7 @@
     }
     return 0;
 }
-#endif USE_PIO
+#endif /* USE_PIO */
 
 int  __init 
 NCR53c406a_detect(Scsi_Host_Template * tpnt){
@@ -481,7 +481,7 @@
     }
     
     DEB(printk("NCR53c406a BIOS found at %X\n", (unsigned int) bios_base););
-#endif USE_BIOS
+#endif /* USE_BIOS */
     
 #ifdef PORT_BASE
     if (!request_region(port_base, 0x10, "NCR53c406a")) /* ports already snatched */
@@ -512,7 +512,7 @@
             }
         }
     }
-#endif PORT_BASE
+#endif /* PORT_BASE */
     
     if(!port_base){		/* no ports found */
         printk("NCR53c406a: no available ports found\n");
@@ -550,7 +550,7 @@
 #if USE_DMA
         printk("NCR53c406a: No interrupts found and DMA mode defined. Giving up.\n");
         goto err_release;
-#endif USE_DMA
+#endif /* USE_DMA */
     }
     else {
         DEB(printk("NCR53c406a: Shouldn't get here!\n"));
@@ -565,7 +565,7 @@
     }
     
     DEB(printk("Allocated DMA channel %d\n", dma_chan));
-#endif USE_DMA 
+#endif /* USE_DMA */
     
     tpnt->present = 1;
     tpnt->proc_name = "NCR53c406a";
@@ -665,7 +665,7 @@
 }
 
 
-static void wait_intr() {
+static void wait_intr(void) {
     int i = jiffies + WATCHDOG;
     
     while(time_after(i,jiffies) && !(inb(STAT_REG)&0xe0)) /* wait for a pseudo-interrupt */
@@ -820,8 +820,8 @@
     printk("\n");
 #else
     printk(", pio=%02x\n", pio_status);
-#endif USE_DMA
-#endif NCR53C406A_DEBUG
+#endif /* USE_DMA */
+#endif /* NCR53C406A_DEBUG */
     
     if(int_reg & 0x80){         /* SCSI reset intr */
         rtrc(3);
@@ -840,7 +840,7 @@
         current_SC->scsi_done(current_SC);
         return;
     }
-#endif USE_PIO
+#endif /* USE_PIO */
     
     if(status & 0x20) {		/* Parity error */
         printk("NCR53c406a: Warning: parity error!\n");
@@ -885,7 +885,7 @@
 #if USE_DMA			/* No s/g support for DMA */
             NCR53c406a_dma_write(current_SC->request_buffer, 
                                  current_SC->request_bufflen);
-#endif USE_DMA
+#endif /* USE_DMA */
             outb(TRANSFER_INFO | DMA_OP, CMD_REG); 
 #if USE_PIO
             if (!current_SC->use_sg) /* Don't use scatter-gather */
@@ -900,7 +900,7 @@
                 }
             }
             REG0;
-#endif USE_PIO
+#endif /* USE_PIO */
         }
         break;
         
@@ -914,7 +914,7 @@
 #if USE_DMA			/* No s/g support for DMA */
             NCR53c406a_dma_read(current_SC->request_buffer, 
                                 current_SC->request_bufflen);
-#endif USE_DMA
+#endif /* USE_DMA */
             outb(TRANSFER_INFO | DMA_OP, CMD_REG); 
 #if USE_PIO
             if (!current_SC->use_sg) /* Don't use scatter-gather */
@@ -929,7 +929,7 @@
                 }
             }
             REG0;
-#endif USE_PIO
+#endif /* USE_PIO */
         }
         break;
         
@@ -981,7 +981,7 @@
 }
 
 #ifndef IRQ_LEV
-static int irq_probe()
+static int irq_probe(void)
 {
     int irqs, irq;
     int i;
@@ -1011,9 +1011,9 @@
     
     return irq;
 }
-#endif IRQ_LEV
+#endif /* IRQ_LEV */
 
-static void chip_init()
+static void chip_init(void)
 {
     REG1;
 #if USE_DMA
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c
--- v2.4.5/linux/drivers/scsi/aha152x.c	Tue Mar  6 19:44:37 2001
+++ linux/drivers/scsi/aha152x.c	Wed Jun 27 17:10:55 2001
@@ -1998,14 +1998,14 @@
 			if (!HOSTDATA(shpnt)->commands)
 				SETPORT(PORTA, 0);	/* turn led off */
 
-			kfree(DONE_SC->host_scribble);
-			DONE_SC->host_scribble=0;
-
 			DO_UNLOCK(flags);
 			DPRINTK(debug_done, DEBUG_LEAD "calling scsi_done(%p)\n", CMDINFO(DONE_SC), DONE_SC);
                 	DONE_SC->scsi_done(DONE_SC);
 			DPRINTK(debug_done, DEBUG_LEAD "scsi_done(%p) returned\n", CMDINFO(DONE_SC), DONE_SC);
 			DO_LOCK(flags);
+
+			kfree(DONE_SC->host_scribble);
+			DONE_SC->host_scribble=0;
 		}
 
 		DONE_SC=0;
@@ -2872,11 +2872,11 @@
 		if (!ptr->device->soft_reset) {
 			remove_SC(&DISCONNECTED_SC, ptr);
 
-			kfree(ptr->host_scribble);
-			ptr->host_scribble=0;
-
 			ptr->result =  DID_RESET << 16;
 			ptr->scsi_done(ptr);
+
+			kfree(ptr->host_scribble);
+			ptr->host_scribble=0;
 		}
 
 		ptr = next;
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/aic7xxx_old.c linux/drivers/scsi/aic7xxx_old.c
--- v2.4.5/linux/drivers/scsi/aic7xxx_old.c	Fri Apr 27 13:59:18 2001
+++ linux/drivers/scsi/aic7xxx_old.c	Tue Jun 12 11:06:54 2001
@@ -10100,7 +10100,7 @@
       } /* while(pdev=....) */
     } /* for PCI_DEVICES */
   } /* PCI BIOS present */
-#endif CONFIG_PCI
+#endif /* CONFIG_PCI */
 
 #if defined(__i386__) || defined(__alpha__)
   /*
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/constants.c linux/drivers/scsi/constants.c
--- v2.4.5/linux/drivers/scsi/constants.c	Mon Jan 15 13:08:15 2001
+++ linux/drivers/scsi/constants.c	Tue Jun 12 11:17:17 2001
@@ -689,7 +689,7 @@
 			  kdev_t dev)
 {
     int i, s;
-    int sense_class, valid, code;
+    int sense_class, valid, code, info;
     const char * error = NULL;
     
     sense_class = (sense_buffer[0] >> 4) & 0x07;
@@ -701,11 +701,14 @@
 	if(s > SCSI_SENSE_BUFFERSIZE)
 	   s = SCSI_SENSE_BUFFERSIZE;
 	
-	if (!valid)
-	    printk("[valid=0] ");
-	printk("Info fld=0x%x, ", (int)((sense_buffer[3] << 24) |
-	       (sense_buffer[4] << 16) | (sense_buffer[5] << 8) |
-	       sense_buffer[6]));
+	info = ((sense_buffer[3] << 24) | (sense_buffer[4] << 16) |
+		(sense_buffer[5] << 8) | sense_buffer[6]);
+	if (info || valid) {
+		printk("Info fld=0x%x", info);
+		if (!valid)	/* info data not according to standard */
+			printk(" (nonstd)");
+		printk(", ");
+	}
 	if (sense_buffer[2] & 0x80)
            printk( "FMK ");	/* current command has read a filemark */
 	if (sense_buffer[2] & 0x40)
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/cpqfcTSinit.c linux/drivers/scsi/cpqfcTSinit.c
--- v2.4.5/linux/drivers/scsi/cpqfcTSinit.c	Fri Apr 27 14:05:28 2001
+++ linux/drivers/scsi/cpqfcTSinit.c	Wed Jun 20 11:19:02 2001
@@ -1808,7 +1808,7 @@
 
 #ifdef MODULE
 
-Scsi_Host_Template driver_template = CPQFCTS;
+static Scsi_Host_Template driver_template = CPQFCTS;
 
 #include "scsi_module.c"
 
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/dmx3191d.c linux/drivers/scsi/dmx3191d.c
--- v2.4.5/linux/drivers/scsi/dmx3191d.c	Fri Apr 27 13:59:18 2001
+++ linux/drivers/scsi/dmx3191d.c	Wed Jun 27 17:10:55 2001
@@ -59,7 +59,7 @@
 	struct pci_dev *pdev = NULL;
 
 	if (!pci_present()) {
-		dmx3191d_printk("PCI support not enabled\n");
+		printk(KERN_WARNING "dmx3191: PCI support not enabled\n");
 		return 0;
 	}
 
@@ -75,7 +75,7 @@
 		port = pci_resource_start (pdev, 0);
 		
 		if (!request_region(port, DMX3191D_REGION, DMX3191D_DRIVER_NAME)) {
-			dmx3191d_printk("region 0x%lx-0x%lx already reserved\n",
+			printk(KERN_ERR "dmx3191: region 0x%lx-0x%lx already reserved\n",
 				port, port + DMX3191D_REGION);
 			continue;
 		}
@@ -93,7 +93,7 @@
 
 		if (request_irq(pdev->irq, dmx3191d_do_intr, SA_SHIRQ,
 				DMX3191D_DRIVER_NAME, instance)) {
-			dmx3191d_printk("irq %d not available\n", pdev->irq);
+			printk(KERN_WARNING "dmx3191: IRQ %d not available - switching to polled mode.\n", pdev->irq);
 			/* Steam powered scsi controllers run without an IRQ
 			   anyway */
 			instance->irq = IRQ_NONE;
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/dmx3191d.h linux/drivers/scsi/dmx3191d.h
--- v2.4.5/linux/drivers/scsi/dmx3191d.h	Mon Sep 18 14:12:01 2000
+++ linux/drivers/scsi/dmx3191d.h	Wed Jun 27 17:10:55 2001
@@ -20,8 +20,6 @@
 #define PCI_DEVICE_ID_DOMEX_DMX3191D	0x0001
 #endif
 
-#define dmx3191d_printk( args... )	printk(__FILE__": " ##args)
-
 #ifndef ASM
 int dmx3191d_abort(Scsi_Cmnd *);
 int dmx3191d_detect(Scsi_Host_Template *);
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/eata_dma.c linux/drivers/scsi/eata_dma.c
--- v2.4.5/linux/drivers/scsi/eata_dma.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/scsi/eata_dma.c	Wed Jun 27 17:10:55 2001
@@ -482,6 +482,7 @@
         DBG(DBG_REQSENSE, printk(KERN_DEBUG "Tried to REQUEST SENSE\n"));
 	cmd->result = DID_OK << 16;
 	done(cmd);
+	restore_flags(flags);
 
 	return(0);
     }
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/gdth.c linux/drivers/scsi/gdth.c
--- v2.4.5/linux/drivers/scsi/gdth.c	Sat May 19 17:43:06 2001
+++ linux/drivers/scsi/gdth.c	Wed Jun 20 11:19:02 2001
@@ -4639,7 +4639,7 @@
 
 #else
 
-Scsi_Host_Template driver_template = GDTH;
+static Scsi_Host_Template driver_template = GDTH;
 #include "scsi_module.c"
 #ifndef MODULE
 __setup("gdth=", option_setup);
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/hosts.c linux/drivers/scsi/hosts.c
--- v2.4.5/linux/drivers/scsi/hosts.c	Mon Oct 30 14:44:29 2000
+++ linux/drivers/scsi/hosts.c	Wed Jun 27 17:10:55 2001
@@ -168,6 +168,11 @@
     retval->loaded_as_module = 1;
     if (flag_new) {
 	shn = (Scsi_Host_Name *) kmalloc(sizeof(Scsi_Host_Name), GFP_ATOMIC);
+        if (!shn) {
+                kfree(retval);
+                printk(KERN_ERR "scsi: out of memory(2) in scsi_register.\n");
+                return NULL;
+        }
 	shn->name = kmalloc(hname_len + 1, GFP_ATOMIC);
 	if (hname_len > 0)
 	    strncpy(shn->name, hname, hname_len);
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/osst.c linux/drivers/scsi/osst.c
--- v2.4.5/linux/drivers/scsi/osst.c	Thu Jan  4 13:00:55 2001
+++ linux/drivers/scsi/osst.c	Tue Jun 12 11:09:03 2001
@@ -16,22 +16,21 @@
   Copyright 1992 - 2000 Kai Makisara
 		 email Kai.Makisara@metla.fi
 
-  $Header: /home/cvsroot/Driver/osst.c,v 1.51 2000/12/22 20:48:27 garloff Exp $
+  $Header: /home/cvsroot/Driver/osst.c,v 1.61 2001/06/03 21:55:12 riede Exp $
 
   Microscopic alterations - Rik Ling, 2000/12/21
   Last modified: Wed Feb  2 22:04:05 2000 by makisara@kai.makisara.local
   Some small formal changes - aeb, 950809
 */
 
-static const char * cvsid = "$Id: osst.c,v 1.51 2000/12/22 20:48:27 garloff Exp $";
-const char * osst_version = "0.9.4.3";
+static const char * cvsid = "$Id: osst.c,v 1.61 2001/06/03 21:55:12 riede Exp $";
+const char * osst_version = "0.9.8";
 
 /* The "failure to reconnect" firmware bug */
-#define OSST_FW_NEED_POLL_MIN 10602 /*(107A)*/
-#define OSST_FW_NEED_POLL_MAX 10708 /*(108D)*/
+#define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/
+#define OSST_FW_NEED_POLL_MAX 10704 /*(108D)*/
 #define OSST_FW_NEED_POLL(x,d) ((x) >= OSST_FW_NEED_POLL_MIN && (x) <= OSST_FW_NEED_POLL_MAX && d->host->this_id != 7)
 
-#include <linux/config.h>
 #include <linux/module.h>
 
 #include <linux/fs.h>
@@ -112,6 +111,8 @@
 
 #if DEBUG
 static int debugging = 1;
+/* uncomment define below to test error recovery */
+// #define OSST_INJECT_ERRORS 1 
 #endif
 
 #define MAX_RETRIES 0
@@ -172,7 +173,7 @@
 
 static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt);
 
-static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int file_blk);
+static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt);
 
 static int osst_write_error_recovery(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int pending);
 
@@ -202,7 +203,7 @@
 
 #if DEBUG
 	if (debugging) {
-		printk(OSST_DEB_MSG "osst%d: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n",
+		printk(OSST_DEB_MSG "osst%d:D: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n",
 		   dev, result,
 		   SRpnt->sr_cmnd[0], SRpnt->sr_cmnd[1], SRpnt->sr_cmnd[2],
 		   SRpnt->sr_cmnd[3], SRpnt->sr_cmnd[4], SRpnt->sr_cmnd[5],
@@ -222,16 +223,25 @@
 		 SRpnt->sr_cmnd[0] != MODE_SENSE &&
 		 SRpnt->sr_cmnd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
 		if (driver_byte(result) & DRIVER_SENSE) {
-			printk(KERN_WARNING "osst%d: Error with sense data: ", dev);
+			printk(KERN_WARNING "osst%d:W: Error with sense data: ", dev);
 			print_req_sense("osst", SRpnt);
 		}
-		else
+		else {
+			static	int	notyetprinted = 1;
+
 			printk(KERN_WARNING
-			     "osst%d: Error %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
+			     "osst%d:W: Error %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
 			     dev, result, suggestion(result), driver_byte(result) & DRIVER_MASK,
 			     host_byte(result));
+			if (notyetprinted) {
+				notyetprinted = 0;
+				printk(KERN_INFO
+					"osst%d:I: This error may be caused by your scsi controller,\n", dev);
+				printk(KERN_INFO
+					"osst%d:I: it has been reported with some Buslogic cards.\n", dev);
+			}
+		}
 	}
-
 	if ((sense[0] & 0x70) == 0x70 &&
 	     scode == RECOVERED_ERROR) {
 		STp->recover_count++;
@@ -244,7 +254,7 @@
 				stp = "write";
 			else
 				stp = "ioctl";
-			printk(OSST_DEB_MSG "osst%d: Recovered %s error (%d).\n", dev, stp,
+			printk(OSST_DEB_MSG "osst%d:D: Recovered %s error (%d).\n", dev, stp,
 					     os_scsi_tapes[dev]->recover_count);
 		}
 #endif
@@ -259,7 +269,6 @@
 static void osst_sleep_done (Scsi_Cmnd * SCpnt)
 {
 	unsigned int dev;
-	int remainder;
 	OS_Scsi_Tape * STp;
 
 	if ((dev = TAPE_NR(SCpnt->request.rq_dev)) < osst_template.nr_dev) {
@@ -268,15 +277,7 @@
 		    (SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
 		    (SCpnt->sense_buffer[2] & 0x40)) {
 			/* EOM at write-behind, has all been written? */
-			if ((SCpnt->sense_buffer[0] & 0x80) != 0)
-				remainder = (SCpnt->sense_buffer[3] << 24) |
-					    (SCpnt->sense_buffer[4] << 16) |
-					    (SCpnt->sense_buffer[5] << 8 ) |
-					     SCpnt->sense_buffer[6];
-			else
-				remainder = 0;
-			if ((SCpnt->sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW ||
-			    remainder > 0)
+			if ((SCpnt->sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW)
 				(STp->buffer)->midlevel_result = SCpnt->result; /* Error */
 			else
 				(STp->buffer)->midlevel_result = INT_MAX;       /* OK */
@@ -293,7 +294,7 @@
 	}
 #if DEBUG
 	else if (debugging)
-		printk(KERN_ERR "osst?: Illegal interrupt device %x\n", dev);
+		printk(OSST_DEB_MSG "osst?:D: Illegal interrupt device %x\n", dev);
 #endif
 }
 
@@ -305,11 +306,13 @@
 	unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait)
 {
 	unsigned char *bp;
-//static int inject = 0; /* FIXME - take out inject occasional read errors */
-//static int repeat = 0;
+#ifdef OSST_INJECT_ERRORS
+	static   int   inject = 0;
+	static   int   repeat = 0;
+#endif
 	if (SRpnt == NULL) {
 		if ((SRpnt = scsi_allocate_request(STp->device)) == NULL) {
-			printk(KERN_ERR "osst%d: Can't get SCSI request.\n", TAPE_NR(STp->devt));
+			printk(KERN_ERR "osst%d:E: Can't get SCSI request.\n", TAPE_NR(STp->devt));
 			if (signal_pending(current))
 				(STp->buffer)->syscall_result = (-EINTR);
 			else
@@ -341,12 +344,18 @@
 		down(SRpnt->sr_request.sem);
 		SRpnt->sr_request.sem = NULL;
 		STp->buffer->syscall_result = osst_chk_result(STp, SRpnt);
-//if ((STp->buffer)->syscall_result == 0 &&
-//    cmd[0] == READ_6 && cmd[4] && ( /* (++ inject % 83) == 29  || */
-//     (STp->first_frame_position == 240 /* or STp->read_error_frame to fail again on the block calculated above */ && ++repeat < 3))) {
-//	printk(OSST_DEB_MSG "osst%d: injecting read error\n", TAPE_NR(STp->devt));
-//	STp->buffer->last_result_fatal = 1; /* FIXME - take out inject occasional read errors */
-//}
+#ifdef OSST_INJECT_ERRORS
+		if (STp->buffer->syscall_result == 0 &&
+		    cmd[0] == READ_6 &&
+		    cmd[4] && 
+		    ( (++ inject % 83) == 29  ||
+		      (STp->first_frame_position == 240 
+			         /* or STp->read_error_frame to fail again on the block calculated above */ &&
+				 ++repeat < 3))) {
+			printk(OSST_DEB_MSG "osst%d:D: Injecting read error\n", TAPE_NR(STp->devt));
+			STp->buffer->last_result_fatal = 1;
+		}
+#endif
 	}
 	return SRpnt;
 }
@@ -356,7 +365,6 @@
 static void osst_write_behind_check(OS_Scsi_Tape *STp)
 {
 	OSST_buffer * STbuffer;
-	ST_partstat * STps;
 
 	STbuffer = STp->buffer;
 
@@ -366,7 +374,6 @@
 	else
 		STp->nbr_finished++;
 #endif
-
 	down(&(STp->sem));
 	(STp->buffer)->last_SRpnt->sr_request.sem = NULL;
 
@@ -381,21 +388,9 @@
 	scsi_release_request((STp->buffer)->last_SRpnt);
 
 	if (STbuffer->writing < STbuffer->buffer_bytes)
-#if 0
-	memcpy(STbuffer->b_data,
-	   STbuffer->b_data + STbuffer->writing,
-	   STbuffer->buffer_bytes - STbuffer->writing);
-#else
-	printk(KERN_WARNING "osst: write_behind_check: something left in buffer!\n");
-#endif
+		printk(KERN_WARNING "osst:A: write_behind_check: something left in buffer!\n");
+
 	STbuffer->buffer_bytes -= STbuffer->writing;
-	STps = &(STp->ps[STp->partition]);
-	if (STps->drv_block >= 0) {
-		if (STp->block_size == 0)
-			STps->drv_block++;
-		else
-			STps->drv_block += STbuffer->writing / STp->block_size;
-	}
 	STbuffer->writing = 0;
 
 	return;
@@ -407,7 +402,8 @@
 /*
  * Initialize the OnStream AUX
  */
-static void osst_init_aux(OS_Scsi_Tape * STp, int frame_type, int logical_blk_num)
+static void osst_init_aux(OS_Scsi_Tape * STp, int frame_type, int frame_seq_number,
+					 int logical_blk_num, int blk_sz, int blk_cnt)
 {
 	os_aux_t       *aux = STp->buffer->aux;
 	os_partition_t *par = &aux->partition;
@@ -441,9 +437,10 @@
 		dat->reserved1 = 0;
 		dat->entry_cnt = 1;
 		dat->reserved3 = 0;
-		dat->dat_list[0].blk_sz   = htonl(frame_type==OS_FRAME_TYPE_DATA?STp->block_size:0);
-		dat->dat_list[0].blk_cnt  = htons(1);
-		dat->dat_list[0].flags    = frame_type==OS_FRAME_TYPE_MARKER?OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA;
+		dat->dat_list[0].blk_sz   = htonl(blk_sz);
+		dat->dat_list[0].blk_cnt  = htons(blk_cnt);
+		dat->dat_list[0].flags    = frame_type==OS_FRAME_TYPE_MARKER?
+							OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA;
 		dat->dat_list[0].reserved = 0;
 	  case	OS_FRAME_TYPE_EOD:
 		aux->update_frame_cntr    = htonl(0);
@@ -452,27 +449,28 @@
 		par->wrt_pass_cntr        = htons(STp->wrt_pass_cntr);
 		par->first_frame_ppos     = htonl(STp->first_data_ppos);
 		par->last_frame_ppos      = htonl(STp->capacity);
-		aux->frame_seq_num        = htonl(logical_blk_num);
+		aux->frame_seq_num        = htonl(frame_seq_number);
 		aux->logical_blk_num_high = htonl(0);
 		aux->logical_blk_num      = htonl(logical_blk_num);
 		break;
 	  default: ; /* probably FILL */
 	}
-	aux->filemark_cnt = ntohl(STp->filemark_cnt);        /* FIXME -- violates ADR spec */
+	aux->filemark_cnt = ntohl(STp->filemark_cnt);
 	aux->phys_fm = ntohl(0xffffffff);
 	aux->last_mark_ppos = ntohl(STp->last_mark_ppos);
+	aux->last_mark_lbn  = ntohl(STp->last_mark_lbn);
 }
 
 /*
  * Verify that we have the correct tape frame
  */
-static int osst_verify_frame(OS_Scsi_Tape * STp, int logical_blk_num, int quiet)
+static int osst_verify_frame(OS_Scsi_Tape * STp, int frame_seq_number, int quiet)
 {
 	os_aux_t       * aux  = STp->buffer->aux;
 	os_partition_t * par  = &(aux->partition);
 	ST_partstat    * STps = &(STp->ps[STp->partition]);
-	int              i;
 	int		 dev  = TAPE_NR(STp->devt);
+	int		 blk_cnt, blk_sz, i;
 
 	if (STp->raw) {
 		if (STp->buffer->syscall_result) {
@@ -483,55 +481,70 @@
 		return 1;
 	}
 	if (STp->buffer->syscall_result) {
-		printk(KERN_INFO "osst%d: Skipping frame, read error\n", dev);
+#if DEBUG
+		printk(OSST_DEB_MSG "osst%d:D: Skipping frame, read error\n", dev);
+#endif
 		return 0;
 	}
 	if (ntohl(aux->format_id) != 0) {
-		printk(KERN_INFO "osst%d: Skipping frame, format_id %u\n", dev, ntohl(aux->format_id));
-		return 0;
+#if DEBUG
+		printk(OSST_DEB_MSG "osst%d:D: Skipping frame, format_id %u\n", dev, ntohl(aux->format_id));
+#endif
+		goto err_out;
 	}
 	if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 &&
 	    (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) {
-		printk(KERN_INFO "osst%d: Skipping frame, incorrect application signature\n", dev);
-		return 0;
+#if DEBUG
+		printk(OSST_DEB_MSG "osst%d:D: Skipping frame, incorrect application signature\n", dev);
+#endif
+		goto err_out;
 	}
 	if (par->partition_num != OS_DATA_PARTITION) {
 		if (!STp->linux_media || STp->linux_media_version != 2) {
-			printk(KERN_INFO "osst%d: Skipping frame, partition num %d\n", dev, par->partition_num);              		    return 0;
+#if DEBUG
+			printk(OSST_DEB_MSG "osst%d:D: Skipping frame, partition num %d\n",
+					    dev, par->partition_num);
+#endif
+			goto err_out;
 		}
 	}
 	if (par->par_desc_ver != OS_PARTITION_VERSION) {
-		printk(KERN_INFO "osst%d: Skipping frame, partition version %d\n", dev, par->par_desc_ver);
-		return 0;
+#if DEBUG
+		printk(OSST_DEB_MSG "osst%d:D: Skipping frame, partition version %d\n", dev, par->par_desc_ver);
+#endif
+		goto err_out;
 	}
 	if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) {
-		printk(KERN_INFO "osst%d: Skipping frame, wrt_pass_cntr %d (expected %d)\n", 
-				 dev, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);
-		return 0;
-	}
-	if (aux->frame_seq_num != aux->logical_blk_num) {
-		printk(KERN_INFO "osst%d: Skipping frame, seq != logical\n", dev);
-		return 0;
+#if DEBUG
+		printk(OSST_DEB_MSG "osst%d:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n", 
+				    dev, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);
+#endif
+		goto err_out;
 	}
 	if (aux->frame_type != OS_FRAME_TYPE_DATA &&
 	    aux->frame_type != OS_FRAME_TYPE_EOD &&
 	    aux->frame_type != OS_FRAME_TYPE_MARKER) {
 		if (!quiet)
-			printk(KERN_INFO "osst%d: Skipping frame, frame type %x\n", dev, aux->frame_type);
-		return 0;
+#if DEBUG
+			printk(OSST_DEB_MSG "osst%d:D: Skipping frame, frame type %x\n", dev, aux->frame_type);
+#endif
+		goto err_out;
 	}
 	if (aux->frame_type == OS_FRAME_TYPE_EOD &&
 	    STp->first_frame_position < STp->eod_frame_ppos) {
-		printk(KERN_INFO "osst%d: Skipping premature EOD frame %d\n", dev, STp->first_frame_position);
-		return 0;
+		printk(KERN_INFO "osst%d:I: Skipping premature EOD frame %d\n", dev,
+				 STp->first_frame_position);
+		goto err_out;
 	}
-	STp->logical_blk_in_buffer = 1;
+	STp->frame_in_buffer = 1;
 
-	if (logical_blk_num != -1 && ntohl(aux->logical_blk_num) != logical_blk_num) {
+        if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
 		if (!quiet)
-			printk(KERN_INFO "osst%d: Skipping frame, logical_blk_num %u (expected %d)\n", 
-					 dev, ntohl(aux->logical_blk_num), logical_blk_num);
-		return 0;
+#if DEBUG
+			printk(OSST_DEB_MSG "osst%d:D: Skipping frame, sequence number %u (expected %d)\n", 
+					    dev, ntohl(aux->frame_seq_num), frame_seq_number);
+#endif
+		goto err_out;
 	}
 	if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
 		STps->eof = ST_FM_HIT;
@@ -539,8 +552,8 @@
 		i = ntohl(aux->filemark_cnt);
 		if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt ||
 		    STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) {
-#if 1 //DEBUG
-			printk(OSST_DEB_MSG "osst%i: %s filemark %d at frame %d\n", dev,
+#if DEBUG
+			printk(OSST_DEB_MSG "osst%d:D: %s filemark %d at frame pos %d\n", dev,
 				  STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected",
 				  i, STp->first_frame_position - 1);
 #endif
@@ -553,9 +566,31 @@
 		STps->eof = ST_EOD_1;
 	}
 	if (aux->frame_type == OS_FRAME_TYPE_DATA) {
+                blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt);
+		blk_sz  = ntohl(aux->dat.dat_list[0].blk_sz);
+		STp->buffer->buffer_bytes = blk_cnt * blk_sz;
+		STp->buffer->read_pointer = 0;
+
+		/* See what block size was used to write file */
+		if (STp->block_size != blk_sz && blk_sz > 0) {
+			printk(KERN_INFO
+	    	"osst%d:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",
+       				dev, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k',
+				STp->block_size<1024?STp->block_size:STp->block_size/1024,
+				STp->block_size<1024?'b':'k');
+			STp->block_size            = blk_sz;
+			STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz;
+		}
 		STps->eof = ST_NOEOF;
 	}
+        STp->frame_seq_number = ntohl(aux->frame_seq_num);
+	STp->logical_blk_num  = ntohl(aux->logical_blk_num);
 	return 1;
+
+err_out:
+	if (STp->read_error_frame == 0)
+		STp->read_error_frame = STp->first_frame_position - 1;
+	return 0;
 }
 
 /*
@@ -570,7 +605,7 @@
 	int		dbg = debugging;
 	int		dev  = TAPE_NR(STp->devt);
 
-	printk(OSST_DEB_MSG "osst%d: Reached onstream wait ready\n", dev);
+	printk(OSST_DEB_MSG "osst%d:D: Reached onstream wait ready\n", dev);
 #endif
 
 	memset(cmd, 0, MAX_COMMAND_SIZE);
@@ -585,8 +620,8 @@
 	       (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8)         ) {
 #if DEBUG
 	    if (debugging) {
-		printk(OSST_DEB_MSG "osst%d: Sleeping in onstream wait ready\n", dev);
-		printk(OSST_DEB_MSG "osst%d: Turning off debugging for a while\n", dev);
+		printk(OSST_DEB_MSG "osst%d:D: Sleeping in onstream wait ready\n", dev);
+		printk(OSST_DEB_MSG "osst%d:D: Turning off debugging for a while\n", dev);
 		debugging = 0;
 	    }
 #endif
@@ -605,15 +640,15 @@
 	if ( STp->buffer->syscall_result &&
 	     osst_write_error_recovery(STp, aSRpnt, 0) ) {
 #if DEBUG
-	    printk(OSST_DEB_MSG "osst%d: Abnormal exit from onstream wait ready\n", dev);
-printk(OSST_DEB_MSG "osst%d: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", dev,
-STp->buffer->syscall_result, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
-SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
+	    printk(OSST_DEB_MSG "osst%d:D: Abnormal exit from onstream wait ready\n", dev);
+	    printk(OSST_DEB_MSG "osst%d:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", dev,
+			STp->buffer->syscall_result, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
+			SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
 #endif
 	    return (-EIO);
 	}
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d: Normal exit from onstream wait ready\n", dev);
+	printk(OSST_DEB_MSG "osst%d:D: Normal exit from onstream wait ready\n", dev);
 #endif
 	return 0;
 }
@@ -641,7 +676,7 @@
 #if DEBUG
 	int		dev  = TAPE_NR(STp->devt);
 
-	printk(OSST_DEB_MSG "osst%d: Reached onstream flush drive buffer (write filemark)\n", dev);
+	printk(OSST_DEB_MSG "osst%d:D: Reached onstream flush drive buffer (write filemark)\n", dev);
 #endif
 
 	memset(cmd, 0, MAX_COMMAND_SIZE);
@@ -668,10 +703,8 @@
 #if DEBUG
 	char	notyetprinted = 1;
 #endif
-	if ((minlast >= 0 && STp->ps[STp->partition].rw != ST_READING) ||
-	    (minlast <  0 && STp->ps[STp->partition].rw != ST_WRITING) )
-		printk(KERN_ERR "osst%i: waiting for frame without having initialized %s!\n",
-			       	dev, minlast<0?"write":"read");
+	if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)
+		printk(KERN_ERR "osst%i:A: Waiting for frame without having initialized read!\n", dev);
 
 	while (time_before (jiffies, startwait + to*HZ))
 	{ 
@@ -690,7 +723,7 @@
 #if DEBUG			
 			if (debugging || jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC)
 				printk (OSST_DEB_MSG
-					"osst%i: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
+					"osst%d:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
 					dev, curr, curr+minlast, STp->first_frame_position,
 					STp->last_frame_position, STp->cur_frames,
 					result, (jiffies-startwait)/HZ, 
@@ -701,7 +734,7 @@
 #if DEBUG
 		if (jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC && notyetprinted)
 		{
-			printk (OSST_DEB_MSG "osst%i: Wait for frame %i (>%i): %i-%i %i (%i)\n",
+			printk (OSST_DEB_MSG "osst%d:D: Wait for frame %i (>%i): %i-%i %i (%i)\n",
 				dev, curr, curr+minlast, STp->first_frame_position,
 				STp->last_frame_position, STp->cur_frames, result);
 			notyetprinted--;
@@ -711,7 +744,7 @@
 		schedule_timeout (HZ / OSST_POLL_PER_SEC);
 	}
 #if DEBUG
-	printk (OSST_DEB_MSG "osst%i: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",
+	printk (OSST_DEB_MSG "osst%d:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",
 		dev, curr, curr+minlast, STp->first_frame_position,
 		STp->last_frame_position, STp->cur_frames,
 		(jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ);
@@ -720,9 +753,9 @@
 }
 
 /*
- * Read the next OnStream tape block at the current location
+ * Read the next OnStream tape frame at the current location
  */
-static int osst_read_block(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int timeout)
+static int osst_read_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int timeout)
 {
 	unsigned char	cmd[MAX_COMMAND_SIZE];
 	Scsi_Request  * SRpnt;
@@ -746,7 +779,7 @@
 
 #if DEBUG
 	if (debugging)
-	    printk(OSST_DEB_MSG "osst%i: Reading block from OnStream tape\n", dev);
+	    printk(OSST_DEB_MSG "osst%d:D: Reading frame from OnStream tape\n", dev);
 #endif
 	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ,
 				      STp->timeout, MAX_RETRIES, TRUE);
@@ -758,11 +791,13 @@
 	    retval = 1;
 	    if (STp->read_error_frame == 0) {
 		STp->read_error_frame = STp->first_frame_position;
-		printk(OSST_DEB_MSG "osst: recording read error at %d\n", STp->read_error_frame);/*FIXME*/
+#if DEBUG
+		printk(OSST_DEB_MSG "osst%d:D: Recording read error at %d\n", dev, STp->read_error_frame);
+#endif
 	    }
 #if DEBUG
 	    if (debugging)
-		printk(OSST_DEB_MSG "osst%d: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
+		printk(OSST_DEB_MSG "osst%d:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
 		   dev,
 		   SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[1],
 		   SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[3],
@@ -774,16 +809,19 @@
 	    STp->first_frame_position++;
 #if DEBUG
 	if (debugging) {
-	   printk(OSST_DEB_MSG "osst%i: AUX: %c%c%c%c UpdFrCt#%d %s FrSeq#%d LogBlk#%d\n", dev,
+	   printk(OSST_DEB_MSG 
+		"osst%d:D: AUX: %c%c%c%c UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", dev,
 			aux->application_sig[0], aux->application_sig[1],
-			aux->application_sig[2], aux->application_sig[3], ntohl(aux->update_frame_cntr),
+			aux->application_sig[2], aux->application_sig[3], 
+			ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr),
 			aux->frame_type==1?"EOD":aux->frame_type==2?"MARK":
 			aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL", 
-			ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num) );
+			ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
+			ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) );
 	   if (aux->frame_type==2)
-		printk(OSST_DEB_MSG "osst%i: mark_cnt=%d, last_mark=%d, next_mark=%d\n", dev,
-			ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->next_mark_ppos));
-	   printk(OSST_DEB_MSG "osst%i: Exit read block from OnStream tape with code %d\n", dev, retval);
+		printk(OSST_DEB_MSG "osst%d:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", dev,
+			ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn));
+	   printk(OSST_DEB_MSG "osst%d:D: Exit read frame from OnStream tape with code %d\n", dev, retval);
 	}
 #endif
 	return (retval);
@@ -801,22 +839,22 @@
 
 	if (STps->rw != ST_READING) {         /* Initialize read operation */
 		if (STps->rw == ST_WRITING) {
-			osst_flush_write_buffer(STp, aSRpnt, 1);
+                        osst_flush_write_buffer(STp, aSRpnt);
 			osst_flush_drive_buffer(STp, aSRpnt);
 		}
 		STps->rw = ST_READING;
-		STp->logical_blk_in_buffer = 0;
+		STp->frame_in_buffer = 0;
 
 		/*
 		 *      Issue a read 0 command to get the OnStream drive
-		 *      read blocks into its buffer.
+                 *      read frames into its buffer.
 		 */
 		memset(cmd, 0, MAX_COMMAND_SIZE);
 		cmd[0] = READ_6;
 		cmd[1] = 1;
 
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%i: Start Read Ahead on OnStream tape\n", dev);
+		printk(OSST_DEB_MSG "osst%d:D: Start Read Ahead on OnStream tape\n", dev);
 #endif
 		SRpnt   = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE);
 		*aSRpnt = SRpnt;
@@ -826,7 +864,7 @@
 	return retval;
 }
 
-static int osst_get_logical_blk(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int logical_blk_num, int quiet)
+static int osst_get_logical_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int frame_seq_number, int quiet)
 {
 	ST_partstat * STps  = &(STp->ps[STp->partition]);
 	int           dev   = TAPE_NR(STp->devt);
@@ -837,16 +875,16 @@
 		      position;
 
 	/*
-	 * Search and wait for the next logical tape block
+         * Search and wait for the next logical tape frame
 	 */
 	while (1) {
 		if (cnt++ > 400) {
-			printk(KERN_WARNING "osst%d: Couldn't find logical block %d, aborting\n",
-					    dev, logical_blk_num);
+                        printk(KERN_ERR "osst%d:E: Couldn't find logical frame %d, aborting\n",
+					    dev, frame_seq_number);
 			if (STp->read_error_frame) {
 				osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0);
-#if 1 //DEBUG
-                        	printk(OSST_DEB_MSG "osst%d: Repositioning tape to bad block %d\n",
+#if DEBUG
+                        	printk(OSST_DEB_MSG "osst%d:D: Repositioning tape to bad frame %d\n",
 						    dev, STp->read_error_frame);
 #endif
 				STp->read_error_frame = 0;
@@ -855,16 +893,15 @@
 		}
 #if DEBUG
 		if (debugging)
-			printk(OSST_DEB_MSG "osst%d: Looking for block %d, attempt %d\n",
-					  dev, logical_blk_num, cnt);
+			printk(OSST_DEB_MSG "osst%d:D: Looking for frame %d, attempt %d\n",
+					  dev, frame_seq_number, cnt);
 #endif
 		if ( osst_initiate_read(STp, aSRpnt)
-		|| ( (!STp->logical_blk_in_buffer) && osst_read_block(STp, aSRpnt, 30) ) ) {
+                || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) {
 			position = osst_get_frame_position(STp, aSRpnt);
 			if (position >= 0xbae && position < 0xbb8)
 				position = 0xbb8;
 			else if (position > STp->eod_frame_ppos || ++bad == 10) {
-printk(OSST_DEB_MSG "osst%d: start again from pos %d, eod %d, bad %d\n", dev, position, STp->eod_frame_ppos, bad); /*FIXME*/
 				position = STp->read_error_frame - 1;
 			}
 			else {
@@ -872,38 +909,40 @@
 				cnt += 20;
 			}
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d: Bad block detected, positioning tape to block %d\n",
+			printk(OSST_DEB_MSG "osst%d:D: Bad frame detected, positioning tape to block %d\n",
 					 dev, position);
 #endif
 			osst_set_frame_position(STp, aSRpnt, position, 0);
 			continue;
 		}
-		if (osst_verify_frame(STp, logical_blk_num, quiet))
+		if (osst_verify_frame(STp, frame_seq_number, quiet))
 			break;
 		if (osst_verify_frame(STp, -1, quiet)) {
-			x = ntohl(STp->buffer->aux->logical_blk_num);
+			x = ntohl(STp->buffer->aux->frame_seq_num);
 			if (STp->fast_open) {
-#if 1 //DEBUG
-				printk(OSST_DEB_MSG
-				       "osst%d: Found logical block %d instead of %d after fast open\n",
-				       dev, x, logical_blk_num);
-#endif
+				printk(KERN_WARNING
+				       "osst%d:W: Found logical frame %d instead of %d after fast open\n",
+				       dev, x, frame_seq_number);
 				STp->header_ok = 0;
 				STp->read_error_frame = 0;
 				return (-EIO);
 			}
-			if (x > logical_blk_num) {
+			if (x > frame_seq_number) {
 				if (++past > 3) {
-					/* positioning backwards did not bring us to the desired block */
+					/* positioning backwards did not bring us to the desired frame */
 					position = STp->read_error_frame - 1;
 				}
-				else
+				else {
 			        	position = osst_get_frame_position(STp, aSRpnt)
-					         + logical_blk_num - x - 1;
-#if 1 //DEBUG
+					         + frame_seq_number - x - 1;
+
+					if (STp->first_frame_position >= 3000 && position < 3000)
+						position -= 10;
+				}
+#if DEBUG
                                 printk(OSST_DEB_MSG
-				       "osst%d: Found logical block %d while looking for %d: back up %d\n",
-						dev, x, logical_blk_num,
+				       "osst%d:D: Found logical frame %d while looking for %d: back up %d\n",
+						dev, x, frame_seq_number,
 					       	STp->first_frame_position - position);
 #endif
                         	osst_set_frame_position(STp, aSRpnt, position, 0);
@@ -914,22 +953,26 @@
 		}
 		if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) {
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d: Skipping config partition\n", dev);
+			printk(OSST_DEB_MSG "osst%d:D: Skipping config partition\n", dev);
 #endif
 			osst_set_frame_position(STp, aSRpnt, 0xbb8, 0);
 			cnt--;
 		}
-		STp->logical_blk_in_buffer = 0;
+		STp->frame_in_buffer = 0;
 	}
 	if (cnt > 1) {
 		STp->recover_count++;
 		STp->recover_erreg++;
+		printk(KERN_WARNING "osst%d:I: Read error at position %d recovered\n", 
+					dev, STp->read_error_frame);
  	}
-	STp->logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num);
+	STp->read_count++;
 
 #if DEBUG
 	if (debugging || STps->eof)
-		printk(OSST_DEB_MSG "osst%i: Exit get logical block (%d=>%d) from OnStream tape with code %d\n",							 dev, logical_blk_num, STp->logical_blk_num, STps->eof);
+		printk(OSST_DEB_MSG
+			"osst%d:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
+			dev, frame_seq_number, STp->frame_seq_number, STps->eof);
 #endif
 	STp->fast_open = FALSE;
 	STp->read_error_frame = 0;
@@ -938,60 +981,195 @@
 
 static int osst_seek_logical_blk(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int logical_blk_num)
 {
-	int  estimate;
-	int  retries = 0;
-	int  dev     = TAPE_NR(STp->devt);
-
+        ST_partstat * STps = &(STp->ps[STp->partition]);
+	int	dev        = TAPE_NR(STp->devt);
+	int	retries    = 0;
+	int	frame_seq_estimate, ppos_estimate, move;
+	
 	if (logical_blk_num < 0) logical_blk_num = 0;
-	/* FIXME -- this may not be valid for foreign formats */
-	if (logical_blk_num < 2980) estimate  = logical_blk_num + 10;
-	else			    estimate  = logical_blk_num + 20;
-
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d: Seeking logical block %d (now at %d)\n",
-			  dev, logical_blk_num, STp->logical_blk_num);
+	printk(OSST_DEB_MSG "osst%d:D: Seeking logical block %d (now at %d, size %d%c)\n",
+				dev, logical_blk_num, STp->logical_blk_num, 
+				STp->block_size<1024?STp->block_size:STp->block_size/1024,
+				STp->block_size<1024?'b':'k');
 #endif
+	/* Do we know where we are? */
+	if (STps->drv_block >= 0) {
+		move                = logical_blk_num - STp->logical_blk_num;
+		if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
+		move               /= (OS_DATA_SIZE / STp->block_size);
+		frame_seq_estimate  = STp->frame_seq_number + move;
+	} else
+		frame_seq_estimate  = logical_blk_num * STp->block_size / OS_DATA_SIZE;
+
+	if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10;
+	else			       ppos_estimate = frame_seq_estimate + 20;
 	while (++retries < 10) {
-	   osst_set_frame_position(STp, aSRpnt, estimate, 0);
-	   if (osst_get_logical_blk(STp, aSRpnt, logical_blk_num, 1) >= 0)
-	      return 0;
-	   if (osst_get_logical_blk(STp, aSRpnt, -1, 1) < 0)
+	   if (ppos_estimate > STp->eod_frame_ppos-2) {
+	       frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate;
+	       ppos_estimate       = STp->eod_frame_ppos - 2;
+	   }
+	   if (frame_seq_estimate < 0) {
+	       frame_seq_estimate = 0;
+	       ppos_estimate      = 10;
+	   }
+	   osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0);
+	   if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) {
+	      /* we've located the estimated frame, now does it have our block? */
+	      if (logical_blk_num <  STp->logical_blk_num ||
+	          logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) {
+		 if (STps->eof == ST_FM_HIT)
+		    move = logical_blk_num < STp->logical_blk_num? -2 : 1;
+		 else {
+		    move                = logical_blk_num - STp->logical_blk_num;
+		    if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
+		    move               /= (OS_DATA_SIZE / STp->block_size);
+		 }
+#if DEBUG
+		 printk(OSST_DEB_MSG
+			"osst%d:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
+				dev, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, 
+				STp->logical_blk_num, logical_blk_num, move);
+#endif
+		 frame_seq_estimate += move;
+		 ppos_estimate      += move;
+		 continue;
+	      } else {
+		 STp->buffer->read_pointer  = (logical_blk_num - STp->logical_blk_num) * STp->block_size;
+		 STp->buffer->buffer_bytes -= STp->buffer->read_pointer;
+		 STp->logical_blk_num       =  logical_blk_num;
+#if DEBUG
+		 printk(OSST_DEB_MSG 
+			"osst%d:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n",
+				dev, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer, 
+				STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size, 
+				STp->block_size);
+#endif
+		 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
+		 if (STps->eof == ST_FM_HIT) {
+		     STps->drv_file++;
+		     STps->drv_block = 0;
+		 } else {
+		     STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
+					  STp->logical_blk_num -
+					     (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
+					-1;
+		 }
+		 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
+		 return 0;
+	      }
+	   }
+	   if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0)
 	      goto error;
-	   if (STp->logical_blk_num != logical_blk_num)
-	      estimate += logical_blk_num - STp->logical_blk_num;
+	   /* we are not yet at the estimated frame, adjust our estimate of its physical position */
+#if DEBUG
+	   printk(OSST_DEB_MSG "osst%d:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n", 
+			   dev, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, 
+			   STp->logical_blk_num, logical_blk_num);
+#endif
+	   if (frame_seq_estimate != STp->frame_seq_number)
+	      ppos_estimate += frame_seq_estimate - STp->frame_seq_number;
 	   else
 	      break;
 	}
 error:
-	printk(KERN_WARNING "osst%d: Couldn't seek to logical block %d (at %d), %d retries\n", 
+	printk(KERN_ERR "osst%d:E: Couldn't seek to logical block %d (at %d), %d retries\n", 
 			    dev, logical_blk_num, STp->logical_blk_num, retries);
 	return (-EIO);
 }
 
-static int osst_seek_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int frame)
+/* The values below are based on the OnStream frame payload size of 32K == 2**15,
+ * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block
+ * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions
+ * inside each frame. Finaly, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
+ */
+#define OSST_FRAME_SHIFT  6
+#define OSST_SECTOR_SHIFT 9
+#define OSST_SECTOR_MASK  0x03F
+
+static int osst_get_sector(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
+{
+	int	sector;
+#if DEBUG
+	int	dev = TAPE_NR(STp->devt);
+	
+	printk(OSST_DEB_MSG 
+		"osst%d:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n",
+		dev, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
+		STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block, 
+		STp->ps[STp->partition].rw == ST_WRITING?'w':'r',
+		STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes:
+		STp->buffer->read_pointer, STp->ps[STp->partition].eof);
+#endif
+	/* do we know where we are inside a file? */
+	if (STp->ps[STp->partition].drv_block >= 0) {
+		sector = (STp->frame_in_buffer ? STp->first_frame_position-1 :
+				STp->first_frame_position) << OSST_FRAME_SHIFT;
+		if (STp->ps[STp->partition].rw == ST_WRITING)
+		       	sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
+		else
+	       		sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
+	} else {
+		sector = osst_get_frame_position(STp, aSRpnt);
+		if (sector > 0)
+			sector <<= OSST_FRAME_SHIFT;
+	}
+	return sector;
+}
+
+static int osst_seek_sector(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int sector)
 {
-	ST_partstat   * STps = &(STp->ps[STp->partition]);
-	int		r;
+        ST_partstat   * STps   = &(STp->ps[STp->partition]);
+	int		frame  = sector >> OSST_FRAME_SHIFT,
+			offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT, 
+			r;
+#if DEBUG
+	int		dev    = TAPE_NR(STp->devt);
 
+	printk(OSST_DEB_MSG "osst%d:D: Seeking sector %d in frame %d at offset %d\n",
+				dev, sector, frame, offset);
+#endif
 	if (frame < 0 || frame >= STp->capacity) return (-ENXIO);
 
 	if (frame <= STp->first_data_ppos) {
-		STp->logical_blk_num = STps->drv_file = STps->drv_block = 0;
+		STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0;
 		return (osst_set_frame_position(STp, aSRpnt, frame, 0));
 	}
-	r = osst_set_frame_position(STp, aSRpnt, frame-1, 0);
+	r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0);
 	if (r < 0) return r;
 
-	r = osst_get_logical_blk(STp, aSRpnt, -1, 1);
+	r = osst_get_logical_frame(STp, aSRpnt, -1, 1);
 	if (r < 0) return r;
 
-	if (osst_get_frame_position(STp, aSRpnt) != frame) return (-EIO);
+	if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO);
 
-	STp->logical_blk_num++;
-	STp->logical_blk_in_buffer = 0;
-	STps->drv_file  = htonl(STp->buffer->aux->filemark_cnt);
-	STps->drv_block = -1;
-	STps->eof       = ST_NOEOF;
+	if (offset) {
+		STp->logical_blk_num      += offset / STp->block_size;
+		STp->buffer->read_pointer  = offset;
+		STp->buffer->buffer_bytes -= offset;
+	} else {
+		STp->frame_seq_number++;
+		STp->frame_in_buffer       = 0;
+		STp->logical_blk_num      += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
+		STp->buffer->buffer_bytes  = STp->buffer->read_pointer = 0;
+	}
+	STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
+	if (STps->eof == ST_FM_HIT) {
+		STps->drv_file++;
+		STps->drv_block = 0;
+	} else {
+		STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
+				    STp->logical_blk_num -
+					(STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
+				  -1;
+	}
+	STps->eof       = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
+#if DEBUG
+	printk(OSST_DEB_MSG 
+		"osst%d:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n",
+		dev, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
+		STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof);
+#endif
 	return 0;
 }
 
@@ -999,38 +1177,43 @@
  * Read back the drive's internal buffer contents, as a part
  * of the write error recovery mechanism for old OnStream
  * firmware revisions.
+ * Precondition for this function to work: all frames in the
+ * drive's buffer must be of one type (DATA, MARK or EOD)!
  */
 static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
-					unsigned int block, unsigned int skip, int pending)
+					unsigned int frame, unsigned int skip, int pending)
 {
 	Scsi_Request  * SRpnt = * aSRpnt;
 	unsigned char * buffer, * p;
 	unsigned char	cmd[MAX_COMMAND_SIZE];
-	int             frames, flag, new_block, i, logical_blk_num;
-	int		dev  = TAPE_NR(STp->devt);
-	long		startwait = jiffies;
+	int             flag, new_frame, i;
+	int             nframes          = STp->cur_frames;
+	int             blks_per_frame   = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
+	int             frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
+						- (nframes + pending - 1);
+	int             logical_blk_num  = ntohl(STp->buffer->aux->logical_blk_num) 
+						- (nframes + pending - 1) * blks_per_frame;
+	int		dev              = TAPE_NR(STp->devt);
+	long		startwait        = jiffies;
 #if DEBUG
-	int		dbg = debugging;
+	int		dbg              = debugging;
 #endif
 
-	frames = STp->cur_frames;
-	if ((buffer = (unsigned char *)vmalloc((frames + pending) * OS_DATA_SIZE)) == NULL)
+	if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL)
 		return (-EIO);
 
-	logical_blk_num = STp->logical_blk_num - frames - pending;
-	printk(KERN_INFO "osst%d: Reading back %d frames from drive buffer%s\n",
-			 dev, frames, pending?" and one that was pending":"");
-
-	if (pending) {
-		osst_copy_from_buffer(STp->buffer, (p = &buffer[frames * OS_DATA_SIZE]));
-//		memcpy((p = &buffer[frames * OS_DATA_SIZE]), STp->buffer->b_data, OS_DATA_SIZE);
+	printk(KERN_INFO "osst%d:I: Reading back %d frames from drive buffer%s\n",
+			 dev, nframes, pending?" and one that was pending":"");
+
+	osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE]));
 #if DEBUG
-		if (debugging)
-			printk(OSST_DEB_MSG "osst%d: Pending logical block %d, data %x %x %x %x\n",
-					  dev, logical_blk_num + frames, p[0], p[1], p[2], p[3]);
+	if (pending && debugging)
+		printk(OSST_DEB_MSG "osst%d:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n",
+				dev, frame_seq_number + nframes,
+			       	logical_blk_num + nframes * blks_per_frame,
+			       	p[0], p[1], p[2], p[3]);
 #endif
-	}
-	for (i = 0, p = buffer; i < frames; i++, p += OS_DATA_SIZE) {
+	for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) {
 
 		memset(cmd, 0, MAX_COMMAND_SIZE);
 		cmd[0] = 0x3C;		/* Buffer Read           */
@@ -1041,63 +1224,63 @@
 		SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ,
 					    STp->timeout, MAX_RETRIES, TRUE);
 	
-		if ((STp->buffer)->syscall_result) {
-			printk(KERN_ERR "osst%d: Failed to read block back from OnStream buffer\n", dev);
+		if ((STp->buffer)->syscall_result || !SRpnt) {
+			printk(KERN_ERR "osst%d:E: Failed to read frame back from OnStream buffer\n", dev);
 			vfree((void *)buffer);
 			*aSRpnt = SRpnt;
 			return (-EIO);
 		}
 		osst_copy_from_buffer(STp->buffer, p);
-//		memcpy(p, STp->buffer->b_data, OS_DATA_SIZE);
 #if DEBUG
 		if (debugging)
-			printk(OSST_DEB_MSG "osst%d: Read back logical block %d, data %x %x %x %x\n",
-					  dev, logical_blk_num + i, p[0], p[1], p[2], p[3]);
+			printk(OSST_DEB_MSG "osst%d:D: Read back logical frame %d, data %02x %02x %02x %02x\n",
+					  dev, frame_seq_number + i, p[0], p[1], p[2], p[3]);
 #endif
 	}
 	*aSRpnt = SRpnt;
 	osst_get_frame_position(STp, aSRpnt);
 
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d: Frames left in buffer: %d\n", dev, STp->cur_frames);
+	printk(OSST_DEB_MSG "osst%d:D: Frames left in buffer: %d\n", dev, STp->cur_frames);
 #endif
 	/* Write synchronously so we can be sure we're OK again and don't have to recover recursively */
-	/* In the header we don't actually re-write the blocks that fail, just the ones after them */
+	/* In the header we don't actually re-write the frames that fail, just the ones after them */
 
-	for (flag=1, new_block=block, p=buffer, i=0; i < frames + pending; ) {
+	for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) {
 
 		if (flag) {
 			if (STp->write_type == OS_WRITE_HEADER) {
 				i += skip;
 				p += skip * OS_DATA_SIZE;
 			}
-			else if (new_block < 2990 && new_block+skip+frames+pending >= 2990)
-				new_block = 3000-i;
+			else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990)
+				new_frame = 3000-i;
 			else
-				new_block += skip;
+				new_frame += skip;
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d: Position to frame %d, write lblk %d\n",
-						dev, new_block+i, logical_blk_num+i); /* FIXME var blk sz */
+			printk(OSST_DEB_MSG "osst%d:D: Position to frame %d, write fseq %d\n",
+						dev, new_frame+i, frame_seq_number+i);
 #endif
-			osst_set_frame_position(STp, aSRpnt, new_block + i, 0);
+			osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
 			osst_wait_ready(STp, aSRpnt, 60);
 			osst_get_frame_position(STp, aSRpnt);
 			SRpnt = * aSRpnt;
 
-			if (new_block > block + 1000) {
-				printk(KERN_ERR "osst%d: Failed to find valid tape media\n", dev);
+			if (new_frame > frame + 1000) {
+				printk(KERN_ERR "osst%d:E: Failed to find writable tape media\n", dev);
 				vfree((void *)buffer);
 				return (-EIO);
 			}
 			flag = 0;
-			if ( i >= frames + pending ) break;
+			if ( i >= nframes + pending ) break;
 		}
 		osst_copy_to_buffer(STp->buffer, p);
-//		memcpy(STp->buffer->b_data, p, OS_DATA_SIZE);
 		/*
 		 * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type!
 		 */
-		osst_init_aux(STp, STp->buffer->aux->frame_type, logical_blk_num+i );
+		osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i,
+			       	logical_blk_num + i*blks_per_frame,
+			       	ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame);
 		memset(cmd, 0, MAX_COMMAND_SIZE);
 		cmd[0] = WRITE_6;
 		cmd[1] = 1;
@@ -1105,7 +1288,10 @@
 
 #if DEBUG
 		if (debugging)
-			printk(OSST_DEB_MSG "osst%d: About to attempt to write to frame %d\n", dev, new_block+i);
+			printk(OSST_DEB_MSG
+				"osst%d:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",
+				dev, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
+				p[0], p[1], p[2], p[3]);
 #endif
 		SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE,
 					    STp->timeout, MAX_WRITE_RETRIES, TRUE);
@@ -1116,9 +1302,9 @@
 			p += OS_DATA_SIZE; i++;
 
 			/* if we just sent the last frame, wait till all successfully written */
-			if ( i == frames + pending ) {
+			if ( i == nframes + pending ) {
 #if DEBUG
-				printk(OSST_DEB_MSG "osst%d: Check re-write successful\n", dev);
+				printk(OSST_DEB_MSG "osst%d:D: Check re-write successful\n", dev);
 #endif
 				memset(cmd, 0, MAX_COMMAND_SIZE);
 				cmd[0] = WRITE_FILEMARKS;
@@ -1127,8 +1313,8 @@
 							    STp->timeout, MAX_WRITE_RETRIES, TRUE);
 #if DEBUG
 				if (debugging) {
-					printk(OSST_DEB_MSG "osst%d: Sleeping in re-write wait ready\n", dev);
-					printk(OSST_DEB_MSG "osst%d: Turning off debugging for a while\n", dev);
+					printk(OSST_DEB_MSG "osst%d:D: Sleeping in re-write wait ready\n", dev);
+					printk(OSST_DEB_MSG "osst%d:D: Turning off debugging for a while\n", dev);
 					debugging = 0;
 				}
 #endif
@@ -1153,44 +1339,47 @@
 				}
 #if DEBUG
 				debugging = dbg;
-				printk(OSST_DEB_MSG "osst%d: Wait re-write finished\n", dev);
+				printk(OSST_DEB_MSG "osst%d:D: Wait re-write finished\n", dev);
 #endif
 			}
 		}
+		*aSRpnt = SRpnt;
 		if (flag) {
 			if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) == 13 &&
 			     SRpnt->sr_sense_buffer[12]         ==  0 &&
 			     SRpnt->sr_sense_buffer[13]         ==  2) {
-				printk(KERN_ERR "osst%d: Volume overflow in write error recovery\n", dev);
+				printk(KERN_ERR "osst%d:E: Volume overflow in write error recovery\n", dev);
 				vfree((void *)buffer);
 				return (-EIO);			/* hit end of tape = fail */
 			}
 			i = ((SRpnt->sr_sense_buffer[3] << 24) |
 			     (SRpnt->sr_sense_buffer[4] << 16) |
 			     (SRpnt->sr_sense_buffer[5] <<  8) |
-			      SRpnt->sr_sense_buffer[6]        ) - new_block;
+			      SRpnt->sr_sense_buffer[6]        ) - new_frame;
 			p = &buffer[i * OS_DATA_SIZE];
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d: Additional write error at %d\n", dev, new_block+i);
+			printk(OSST_DEB_MSG "osst%d:D: Additional write error at %d\n", dev, new_frame+i);
 #endif
 			osst_get_frame_position(STp, aSRpnt);
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d: reported frame positions: host = %d, tape = %d\n",
+			printk(OSST_DEB_MSG "osst%d:D: reported frame positions: host = %d, tape = %d\n",
 					  dev, STp->first_frame_position, STp->last_frame_position);
 #endif
 		}
-		*aSRpnt = SRpnt;
 	}    
+	if (!pending)
+		osst_copy_to_buffer(STp->buffer, p);	/* so buffer content == at entry in all cases */
 	vfree((void *)buffer);
 	return 0;
 }
 
 static int osst_reposition_and_retry(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
-					unsigned int block, unsigned int skip, int pending)
+					unsigned int frame, unsigned int skip, int pending)
 {
 	unsigned char	cmd[MAX_COMMAND_SIZE];
-	Scsi_Request  * SRpnt     = * aSRpnt;
+	Scsi_Request  * SRpnt;
 	int		dev       = TAPE_NR(STp->devt);
+	int		expected  = 0;
 	int		attempts  = 1000 / skip;
 	int		flag      = 1;
 	long		startwait = jiffies;
@@ -1203,23 +1392,24 @@
 #if DEBUG
 			debugging = dbg;
 #endif
-			if (block < 2990 && block+skip+STp->cur_frames+pending >= 2990)
-				block = 3000-skip;
+			if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990)
+				frame = 3000-skip;
+			expected = frame+skip+STp->cur_frames+pending;
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d: Position to frame %d, re-write from lblk %d\n",
-					  dev, block+skip, STp->logical_blk_num-STp->cur_frames-pending);
+			printk(OSST_DEB_MSG "osst%d:D: Position to fppos %d, re-write from fseq %d\n",
+					  dev, frame+skip, STp->frame_seq_number-STp->cur_frames-pending);
 #endif
-			osst_set_frame_position(STp, aSRpnt, block + skip, 1);
+			osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
 			flag = 0;
 			attempts--;
 		}
 		if (osst_get_frame_position(STp, aSRpnt) < 0) {		/* additional write error */
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d: Addl error, host %d, tape %d, buffer %d\n",
+			printk(OSST_DEB_MSG "osst%d:D: Addl error, host %d, tape %d, buffer %d\n",
 					  dev, STp->first_frame_position,
 					  STp->last_frame_position, STp->cur_frames);
 #endif
-			block = STp->last_frame_position;
+			frame = STp->last_frame_position;
 			flag = 1;
 			continue;
 		}
@@ -1230,19 +1420,19 @@
 			cmd[1] = 1;
 			cmd[4] = 1;
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d: About to write pending lblk %d at frame %d\n",
-					  dev, STp->logical_blk_num-1, STp->first_frame_position);
+			printk(OSST_DEB_MSG "osst%d:D: About to write pending fseq %d at fppos %d\n",
+					  dev, STp->frame_seq_number-1, STp->first_frame_position);
 #endif
-			SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE,
-						    STp->timeout, MAX_WRITE_RETRIES, TRUE);
+			SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE,
+						      STp->timeout, MAX_WRITE_RETRIES, TRUE);
 			*aSRpnt = SRpnt;
 
 			if (STp->buffer->syscall_result) {		/* additional write error */
 				if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) == 13 &&
 				     SRpnt->sr_sense_buffer[12]         ==  0 &&
 				     SRpnt->sr_sense_buffer[13]         ==  2) {
-					printk(OSST_DEB_MSG
-					       "osst%d: Volume overflow in write error recovery\n",
+					printk(KERN_ERR
+					       "osst%d:E: Volume overflow in write error recovery\n",
 					       dev);
 					break;				/* hit end of tape = fail */
 				}
@@ -1256,20 +1446,25 @@
 		if (STp->cur_frames == 0) {
 #if DEBUG
 			debugging = dbg;
-			printk(OSST_DEB_MSG "osst%d: Wait re-write finished\n", dev);
+			printk(OSST_DEB_MSG "osst%d:D: Wait re-write finished\n", dev);
 #endif
+			if (STp->first_frame_position != expected) {
+				printk(KERN_ERR "osst%d:A: Actual position %d - expected %d\n", 
+						dev, STp->first_frame_position, expected);
+				return (-EIO);
+			}
 			return 0;
 		}
 #if DEBUG
 		if (debugging) {
-			printk(OSST_DEB_MSG "osst%d: Sleeping in re-write wait ready\n", dev);
-			printk(OSST_DEB_MSG "osst%d: Turning off debugging for a while\n", dev);
+			printk(OSST_DEB_MSG "osst%d:D: Sleeping in re-write wait ready\n", dev);
+			printk(OSST_DEB_MSG "osst%d:D: Turning off debugging for a while\n", dev);
 			debugging = 0;
 		}
 #endif
 		schedule_timeout(HZ / 10);
 	}
-	printk(KERN_ERR "osst%d: Failed to find valid tape media\n", dev);
+	printk(KERN_ERR "osst%d:E: Failed to find valid tape media\n", dev);
 #if DEBUG
 	debugging = dbg;
 #endif
@@ -1287,7 +1482,7 @@
 	int            dev    = TAPE_NR(STp->devt);
 	int            retval = 0;
 	int            rw_state;
-	unsigned int   block, skip;
+	unsigned int  frame, skip;
 
 	rw_state = STps->rw;
 
@@ -1295,54 +1490,56 @@
 	  || SRpnt->sr_sense_buffer[12]         != 12
 	  || SRpnt->sr_sense_buffer[13]         != 0) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d: Write error recovery cannot handle %02x:%02x:%02x\n",
-			dev, SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
+		printk(OSST_DEB_MSG "osst%d:D: Write error recovery cannot handle %02x:%02x:%02x\n", dev,
+			SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
 #endif
 		return (-EIO);
 	}
-	block =	(SRpnt->sr_sense_buffer[3] << 24) |
+	frame =	(SRpnt->sr_sense_buffer[3] << 24) |
 		(SRpnt->sr_sense_buffer[4] << 16) |
 		(SRpnt->sr_sense_buffer[5] <<  8) |
 		 SRpnt->sr_sense_buffer[6];
 	skip  =  SRpnt->sr_sense_buffer[9];
  
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d: Detected physical bad block at %u, advised to skip %d\n", dev, block, skip);
+	printk(OSST_DEB_MSG "osst%d:D: Detected physical bad frame at %u, advised to skip %d\n", dev, frame, skip);
 #endif
 	osst_get_frame_position(STp, aSRpnt);
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d: reported frame positions: host = %d, tape = %d\n",
+	printk(OSST_DEB_MSG "osst%d:D: reported frame positions: host = %d, tape = %d\n",
 			dev, STp->first_frame_position, STp->last_frame_position);
 #endif
 	switch (STp->write_type) {
 	   case OS_WRITE_DATA:
 	   case OS_WRITE_EOD:
 	   case OS_WRITE_NEW_MARK:
-		printk(KERN_WARNING "osst%d: Relocating %d buffered logical blocks to physical block %u\n",
-			dev, STp->cur_frames, block + skip);
+		printk(KERN_WARNING 
+			"osst%d:I: Relocating %d buffered logical frames from position %u to %u\n",
+			dev, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip);
 		if (STp->os_fw_rev >= 10600)
-			retval = osst_reposition_and_retry(STp, aSRpnt, block, skip, pending);
+			retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending);
 		else
-			retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, block, skip, pending);
+			retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending);
+		printk(KERN_WARNING "osst%d:I: Write error%srecovered\n", dev, retval?" not ":" ");
 		break;
 	   case OS_WRITE_LAST_MARK:
-		printk(KERN_ERR "osst%d: Bad block in update last marker, fatal\n", dev);
-		osst_set_frame_position(STp, aSRpnt, block + STp->cur_frames + pending, 0);
+		printk(KERN_ERR "osst%d:E: Bad frame in update last marker, fatal\n", dev);
+		osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
 		retval = -EIO;
 		break;
 	   case OS_WRITE_HEADER:
-		printk(KERN_WARNING "osst%d: Bad block in header partition, skipped\n", dev);
-		retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, block, 1, pending);
+		printk(KERN_WARNING "osst%d:I: Bad frame in header partition, skipped\n", dev);
+		retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending);
 		break;
 	   default:
-		printk(KERN_WARNING "osst%d: Bad block in filler, ignored\n", dev);
-		osst_set_frame_position(STp, aSRpnt, block + STp->cur_frames + pending, 0);
+		printk(KERN_INFO "osst%d:I: Bad frame in filler, ignored\n", dev);
+		osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
 	}
 	osst_get_frame_position(STp, aSRpnt);
 #if DEBUG
-	printk(KERN_ERR "osst%d: Positioning complete, cur_frames %d, pos %d, tape pos %d\n", 
+	printk(OSST_DEB_MSG "osst%d:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n", 
 			dev, STp->cur_frames, STp->first_frame_position, STp->last_frame_position);
-	printk(OSST_DEB_MSG "osst%d: next logical block to write: %d\n", dev, STp->logical_blk_num);
+	printk(OSST_DEB_MSG "osst%d:D: next logical frame to write: %d\n", dev, STp->logical_blk_num);
 #endif
 	if (retval == 0) {
 		STp->recover_count++;
@@ -1360,10 +1557,12 @@
 	int     last_mark_ppos = -1;
 
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d: Reached space_over_filemarks_backwards %d %d\n", dev, mt_op, mt_count);
+	printk(OSST_DEB_MSG "osst%d:D: Reached space_over_filemarks_backwards %d %d\n", dev, mt_op, mt_count);
+#endif
+	if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
+#if DEBUG
+		printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarks_bwd\n", dev);
 #endif
-	if (osst_get_logical_blk(STp, aSRpnt, -1, 0) < 0) {
-		printk(KERN_INFO "osst%i: Couldn't get logical blk num in space_filemarks_bwd\n", dev);
 		return -EIO;
 	}
 	if (STp->linux_media_version >= 4) {
@@ -1379,12 +1578,12 @@
 		    STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos)
 
 			last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]);
-#if 1 //DEBUG
+#if DEBUG
 		if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX)
-			printk(OSST_DEB_MSG "osst%i: Filemark lookup fail due to %s\n", dev,
+			printk(OSST_DEB_MSG "osst%d:D: Filemark lookup fail due to %s\n", dev,
 			       STp->header_cache == NULL?"lack of header cache":"count out of range");
 		else
-			printk(OSST_DEB_MSG "osst%i: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
+			printk(OSST_DEB_MSG "osst%d:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
 				dev, cnt,
 				((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
 				 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] ==
@@ -1393,22 +1592,28 @@
 #endif
 		if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) {
 			osst_set_frame_position(STp, aSRpnt, last_mark_ppos, 0);
-			if (osst_get_logical_blk(STp, aSRpnt, -1, 0) < 0) {
-				printk(KERN_INFO "osst%i: Couldn't get logical blk num in space_filemarks\n", dev);
+			if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
+#if DEBUG
+				printk(OSST_DEB_MSG 
+					"osst%d:D: Couldn't get logical blk num in space_filemarks\n", dev);
+#endif
 				return (-EIO);
 			}
 			if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
-				printk(KERN_INFO "osst%i: Expected to find marker at block %d, not found\n",
+				printk(KERN_WARNING "osst%d:W: Expected to find marker at ppos %d, not found\n",
 						 dev, last_mark_ppos);
 				return (-EIO);
 			}
 			if (mt_op == MTBSFM) {
-				STp->logical_blk_num++;
-				STp->logical_blk_in_buffer = 0;
+				STp->frame_seq_number++;
+				STp->frame_in_buffer  = 0;
+				STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
 			}
 			return 0;
 		}
-		printk(KERN_INFO "osst%i: Reverting to scan filemark backwards\n", dev);
+#if DEBUG
+		printk(OSST_DEB_MSG "osst%d:D: Reverting to scan filemark backwards\n", dev);
+#endif
 	}
 	cnt = 0;
 	while (cnt != mt_count) {
@@ -1416,22 +1621,26 @@
 		if (last_mark_ppos == -1)
 			return (-EIO);
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%i: Positioning to last mark at %d\n", dev, last_mark_ppos);
+		printk(OSST_DEB_MSG "osst%d:D: Positioning to last mark at %d\n", dev, last_mark_ppos);
 #endif
 		osst_set_frame_position(STp, aSRpnt, last_mark_ppos, 0);
 		cnt++;
-		if (osst_get_logical_blk(STp, aSRpnt, -1, 0) < 0) {
-			printk(KERN_INFO "osst%i: Couldn't get logical blk num in space_filemarks\n", dev);
+		if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
+#if DEBUG
+			printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarks\n", dev);
+#endif
 			return (-EIO);
 		}
 		if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
-			printk(KERN_INFO "osst%i: Expected to find marker at block %d, not found\n", dev, last_mark_ppos);
+			printk(KERN_WARNING "osst%d:W: Expected to find marker at ppos %d, not found\n",
+					 dev, last_mark_ppos);
 			return (-EIO);
 		}
 	}
 	if (mt_op == MTBSFM) {
-		STp->logical_blk_num++;
-		STp->logical_blk_in_buffer = 0;
+		STp->frame_seq_number++;
+		STp->frame_in_buffer  = 0;
+		STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
 	}
 	return 0;
 }
@@ -1444,30 +1653,34 @@
 static int osst_space_over_filemarks_forward_slow(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
 								     int mt_op, int mt_count)
 {
-	int	dev = TAPE_NR(STp->devt);
 	int	cnt = 0;
+#if DEBUG
+	int	dev = TAPE_NR(STp->devt);
 
+	printk(OSST_DEB_MSG "osst%d:D: Reached space_over_filemarks_forward_slow %d %d\n", dev, mt_op, mt_count);
+#endif
+	if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d: Reached space_over_filemarks_forward_slow %d %d\n", dev, mt_op, mt_count);
+		printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarks_fwd\n", dev);
 #endif
-	if (osst_get_logical_blk(STp, aSRpnt, -1, 0) < 0) {
-		printk(KERN_INFO "osst%i: Couldn't get logical blk num in space_filemarks_fwd\n", dev);
 		return (-EIO);
 	}
 	while (1) {
-		if (osst_get_logical_blk(STp, aSRpnt, -1, 0) < 0) {
-			printk(KERN_INFO "osst%i: Couldn't get logical blk num in space_filemarks\n", dev);
+		if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
+#if DEBUG
+			printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarks\n", dev);
+#endif
 			return (-EIO);
 		}
 		if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
 			cnt++;
 		if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%i: space_fwd: EOD reached\n", dev);
+			printk(OSST_DEB_MSG "osst%d:D: space_fwd: EOD reached\n", dev);
 #endif
 			if (STp->first_frame_position > STp->eod_frame_ppos+1) {
 #if DEBUG
-				printk(OSST_DEB_MSG "osst%i: EOD position corrected (%d=>%d)\n",
+				printk(OSST_DEB_MSG "osst%d:D: EOD position corrected (%d=>%d)\n",
 					       	dev, STp->eod_frame_ppos, STp->first_frame_position-1);
 #endif
 				STp->eod_frame_ppos = STp->first_frame_position-1;
@@ -1476,11 +1689,12 @@
 		}
 		if (cnt == mt_count)
 			break;
-		STp->logical_blk_in_buffer = 0;
+		STp->frame_in_buffer = 0;
 	}
 	if (mt_op == MTFSF) {
-		STp->logical_blk_num++;
-		STp->logical_blk_in_buffer = 0;
+		STp->frame_seq_number++;
+		STp->frame_in_buffer  = 0;
+		STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
 	}
 	return 0;
 }
@@ -1496,10 +1710,12 @@
 		next_mark_ppos = -1;
 
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d: Reached space_over_filemarks_forward_fast %d %d\n", dev, mt_op, mt_count);
+	printk(OSST_DEB_MSG "osst%d:D: Reached space_over_filemarks_forward_fast %d %d\n", dev, mt_op, mt_count);
+#endif
+	if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
+#if DEBUG
+		printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarks_fwd\n", dev);
 #endif
-	if (osst_get_logical_blk(STp, aSRpnt, -1, 0) < 0) {
-		printk(KERN_INFO "osst%i: Couldn't get logical blk num in space_filemarks_fwd\n", dev);
 		return (-EIO);
 	}
 
@@ -1516,33 +1732,39 @@
 		     (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos)))
 
 			next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]);
-#if 1 //DEBUG
+#if DEBUG
 		if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX)
-			printk(OSST_DEB_MSG "osst%i: Filemark lookup fail due to %s\n", dev,
+			printk(OSST_DEB_MSG "osst%d:D: Filemark lookup fail due to %s\n", dev,
 			       STp->header_cache == NULL?"lack of header cache":"count out of range");
 		else
-			printk(OSST_DEB_MSG "osst%i: Filemark lookup: prev mark %d (%s), skip %d to %d\n", dev, cnt,
+			printk(OSST_DEB_MSG "osst%d:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
+			       dev, cnt,
 			       ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
 				(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] ==
 					 STp->buffer->aux->last_mark_ppos))?"match":"error",
 			       mt_count, next_mark_ppos);
 #endif
 		if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) {
-			printk(KERN_INFO "osst%i: Reverting to slow filemark space\n", dev);
+#if DEBUG
+			printk(OSST_DEB_MSG "osst%d:D: Reverting to slow filemark space\n", dev);
+#endif
 			return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
 		} else {
 			osst_set_frame_position(STp, aSRpnt, next_mark_ppos, 0);
-			if (osst_get_logical_blk(STp, aSRpnt, -1, 0) < 0) {
-				printk(KERN_INFO "osst%i: Couldn't get logical blk num in space_filemarks\n", dev);
+			if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
+#if DEBUG
+				printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarks\n",
+						 dev);
+#endif
 				return (-EIO);
 			}
 			if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
-				printk(KERN_INFO "osst%i: Expected to find marker at block %d, not found\n",
+				printk(KERN_WARNING "osst%d:W: Expected to find marker at ppos %d, not found\n",
 						 dev, next_mark_ppos);
 				return (-EIO);
 			}
 			if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) {
-				printk(KERN_INFO "osst%i: Expected to find marker %d at block %d, not %d\n",
+				printk(KERN_WARNING "osst%d:W: Expected to find marker %d at ppos %d, not %d\n",
 						 dev, cnt+mt_count, next_mark_ppos,
 						 ntohl(STp->buffer->aux->filemark_cnt));
        				return (-EIO);
@@ -1557,24 +1779,28 @@
 				break;
 			if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
 #if DEBUG
-				printk(OSST_DEB_MSG "osst%i: space_fwd: EOD reached\n", dev);
+				printk(OSST_DEB_MSG "osst%d:D: space_fwd: EOD reached\n", dev);
 #endif
 				return (-EIO);
 			}
 			if (ntohl(STp->buffer->aux->filemark_cnt) == 0) {
 				if (STp->first_mark_ppos == -1) {
-					printk(KERN_INFO "osst%i: Reverting to slow filemark space\n", dev);
+#if DEBUG
+					printk(OSST_DEB_MSG "osst%d:D: Reverting to slow filemark space\n", dev);
+#endif
 					return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
 				}
 				osst_set_frame_position(STp, aSRpnt, STp->first_mark_ppos, 0);
-				if (osst_get_logical_blk(STp, aSRpnt, -1, 0) < 0) {
-					printk(KERN_INFO
-					       "osst%i: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
+				if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
+#if DEBUG
+					printk(OSST_DEB_MSG
+					       "osst%d:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
 					       dev);
+#endif
 					return (-EIO);
 				}
 				if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
-					printk(KERN_INFO "osst%i: Expected to find filemark at %d\n",
+					printk(KERN_WARNING "osst%d:W: Expected to find filemark at %d\n",
 							 dev, STp->first_mark_ppos);
 					return (-EIO);
 				}
@@ -1588,28 +1814,35 @@
 		while (cnt != mt_count) {
 			next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos);
 			if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) {
-				printk(KERN_INFO "osst%i: Reverting to slow filemark space\n", dev);
+#if DEBUG
+				printk(OSST_DEB_MSG "osst%d:D: Reverting to slow filemark space\n", dev);
+#endif
 				return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt);
 			}
 #if DEBUG
-			else printk(OSST_DEB_MSG "osst%i: Positioning to next mark at %d\n", dev, next_mark_ppos);
+			else printk(OSST_DEB_MSG "osst%d:D: Positioning to next mark at %d\n", dev, next_mark_ppos);
 #endif
 			osst_set_frame_position(STp, aSRpnt, next_mark_ppos, 0);
 			cnt++;
-			if (osst_get_logical_blk(STp, aSRpnt, -1, 0) < 0) {
-				printk(KERN_INFO "osst%i: Couldn't get logical blk num in space_filemarks\n", dev);
+			if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
+#if DEBUG
+				printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarks\n",
+						 dev);
+#endif
 				return (-EIO);
 			}
 			if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
-				printk(KERN_INFO "osst%i: Expected to find marker at block %d, not found\n",
+				printk(KERN_WARNING "osst%d:W: Expected to find marker at ppos %d, not found\n",
 						 dev, next_mark_ppos);
 				return (-EIO);
 			}
 		}
 	}
-	if (mt_op == MTFSF) 
-		STp->logical_blk_num++;
-		STp->logical_blk_in_buffer = 0;
+	if (mt_op == MTFSF) {
+		STp->frame_seq_number++;
+		STp->frame_in_buffer  = 0;
+		STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
+	}
 	return 0;
 }
 
@@ -1639,75 +1872,22 @@
 	(STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries;
 
 	if (debugging)
-	    printk(OSST_DEB_MSG "osst%i: Setting number of retries on OnStream tape to %d\n", dev, retries);
+	    printk(OSST_DEB_MSG "osst%d:D: Setting number of retries on OnStream tape to %d\n", dev, retries);
 
 	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE);
 	*aSRpnt = SRpnt;
 
 	if ((STp->buffer)->syscall_result)
-	    printk (KERN_ERR "osst%d: Couldn't set retries to %d\n", dev, retries);
+	    printk (KERN_ERR "osst%d:D: Couldn't set retries to %d\n", dev, retries);
 }
 #endif
 
-#if 0
-static void osst_update_markers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int last_mark_ppos, int this_mark_ppos)
-{
-	int           dev = TAPE_NR(STp->devt);
-	int	      frame,
-		      reslt;
-
-	if (STp->raw) return;
-
-	STp->last_mark_ppos = this_mark_ppos;
-	if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX)
-		STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos);
-	if (STp->filemark_cnt++ == 0)
-		STp->first_mark_ppos = this_mark_ppos;
-
-	if (STp->linux_media_version >= 4) return;
-	if (last_mark_ppos == -1)          return;
-
-	STp->write_type = OS_WRITE_LAST_MARK;
-	frame = osst_get_frame_position(STp, aSRpnt);
-#if DEBUG
-	printk(OSST_DEB_MSG "osst%i: Update last_marker at frame %d\n", dev, last_mark_addr);
-	printk(OSST_DEB_MSG "osst%i: current position %d, lblk %d, tape blk %d\n",
-			  dev, frame, STp->logical_blk_num, STp->last_frame_position);
-#endif
-	osst_set_frame_position(STp, aSRpnt, last_mark_ppos, 0);
-	osst_initiate_read (STp, aSRpnt);
-	reslt = osst_read_block(STp, aSRpnt, 180);
-
-	if (reslt) {
-		printk(KERN_WARNING "osst%i: couldn't read last marker\n", dev);
-		osst_set_frame_position(STp, aSRpnt, frame, 0);
-		return;
-	}
-	if (STp->buffer->aux->frame_type  != OS_FRAME_TYPE_MARKER) {
-		printk(KERN_WARNING "osst%i: expected marker at addr %d\n", dev, last_mark_ppos);
-		osst_set_frame_position(STp, aSRpnt, frame, 0);
-		return;
-	}
-#if DEBUG
-	printk(OSST_DEB_MSG "osst%i: writing back marker\n", dev);
-#endif
-	STp->buffer->aux->next_mark_ppos = htonl(this_mark_ppos);
-	osst_set_frame_position(STp, aSRpnt, last_mark_ppos, 0);
-	STp->dirty = 1;
-	if (osst_flush_write_buffer(STp, aSRpnt, 0) ||
-	    osst_flush_drive_buffer(STp, aSRpnt)     ) {
-		printk(KERN_WARNING "osst%i: couldn't write marker back at addr %d\n", dev, last_mark_ppos);
-	}
-	osst_set_frame_position(STp, aSRpnt, frame, 0);	
-
-	return; /* FIXME -- errors should go back to user space */
-}
-#endif
 
 static int osst_write_filemark(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
 {
 	int	result;
-	int	this_mark_ppos;
+	int	this_mark_ppos = STp->first_frame_position;
+	int	this_mark_lbn  = STp->logical_blk_num;
 #if DEBUG
 	int	dev = TAPE_NR(STp->devt);
 #endif
@@ -1715,22 +1895,19 @@
 	if (STp->raw) return 0;
 
 	STp->write_type = OS_WRITE_NEW_MARK;
-	this_mark_ppos = osst_get_frame_position(STp, aSRpnt);
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%i: Writing Filemark %i at frame %d (lblk %d)\n", 
-	       dev, STp->filemark_cnt, this_mark_ppos, STp->logical_blk_num);
+	printk(OSST_DEB_MSG "osst%d:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n", 
+	       dev, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn);
 #endif
-	osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->logical_blk_num++);
-	STp->ps[STp->partition].rw = ST_WRITING;
 	STp->dirty = 1;
-	result  = osst_flush_write_buffer(STp, aSRpnt, 0);
+	result  = osst_flush_write_buffer(STp, aSRpnt);
 	result |= osst_flush_drive_buffer(STp, aSRpnt);
 	STp->last_mark_ppos = this_mark_ppos;
+	STp->last_mark_lbn  = this_mark_lbn;
 	if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX)
 		STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos);
 	if (STp->filemark_cnt++ == 0)
 		STp->first_mark_ppos = this_mark_ppos;
-//	osst_update_markers(STp, aSRpnt, STp->last_mark_addr, this_mark_addr);
 	return result;
 }
 
@@ -1744,71 +1921,67 @@
 	if (STp->raw) return 0;
 
 	STp->write_type = OS_WRITE_EOD;
-	STp->eod_frame_ppos = osst_get_frame_position(STp, aSRpnt);
+	STp->eod_frame_ppos = STp->first_frame_position;
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%i: Writing EOD at %d=>%d\n", dev, STp->logical_blk_num, STp->eod_frame_ppos);
+	printk(OSST_DEB_MSG "osst%d:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", dev,
+			STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num);
 #endif
-	osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->logical_blk_num++);
-	STp->ps[STp->partition].rw = ST_WRITING;
 	STp->dirty = 1;
 
-	result  = osst_flush_write_buffer(STp, aSRpnt, 0);	
+	result  = osst_flush_write_buffer(STp, aSRpnt);	
 	result |= osst_flush_drive_buffer(STp, aSRpnt);
-	STp->eod_frame_lfa = --(STp->logical_blk_num);
+	STp->eod_frame_lfa = --(STp->frame_seq_number);
 	return result;
 }
 
-static int osst_write_filler(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int block, int count)
+static int osst_write_filler(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int where, int count)
 {
 	int	dev = TAPE_NR(STp->devt);
 
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%i: Reached onstream write filler group %d\n", dev, block);
+	printk(OSST_DEB_MSG "osst%d:D: Reached onstream write filler group %d\n", dev, where);
 #endif
 	osst_wait_ready(STp, aSRpnt, 60 * 5);
-	osst_set_frame_position(STp, aSRpnt, block, 0);
+	osst_set_frame_position(STp, aSRpnt, where, 0);
 	STp->write_type = OS_WRITE_FILLER;
-	osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0);
 	while (count--) {
 		memcpy(STp->buffer->b_data, "Filler", 6);
 		STp->buffer->buffer_bytes = 6;
 		STp->dirty = 1;
-		if (osst_flush_write_buffer(STp, aSRpnt, 0)) {
-			printk(KERN_INFO "osst%i: Couldn't write filler frame\n", dev);
+		if (osst_flush_write_buffer(STp, aSRpnt)) {
+			printk(KERN_INFO "osst%i:I: Couldn't write filler frame\n", dev);
 			return (-EIO);
 		}
 	}
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%i: Exiting onstream write filler group\n", dev);
+	printk(OSST_DEB_MSG "osst%d:D: Exiting onstream write filler group\n", dev);
 #endif
 	return osst_flush_drive_buffer(STp, aSRpnt);
 }
 
-static int __osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int block, int count)
+static int __osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int where, int count)
 {
 	int	dev   = TAPE_NR(STp->devt);
 	int     result;
 
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%i: Reached onstream write header group %d\n", dev, block);
+	printk(OSST_DEB_MSG "osst%d:D: Reached onstream write header group %d\n", dev, where);
 #endif
 	osst_wait_ready(STp, aSRpnt, 60 * 5);
-	osst_set_frame_position(STp, aSRpnt, block, 0);
+	osst_set_frame_position(STp, aSRpnt, where, 0);
 	STp->write_type = OS_WRITE_HEADER;
-	STp->ps[STp->partition].rw = ST_WRITING;
-	osst_init_aux(STp, OS_FRAME_TYPE_HEADER, STp->logical_blk_num);
 	while (count--) {
 		osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache);
 		STp->buffer->buffer_bytes = sizeof(os_header_t);
 		STp->dirty = 1;
-		if (osst_flush_write_buffer(STp, aSRpnt, 0)) {
-			printk(KERN_INFO "osst%i: Couldn't write header frame\n", dev);
+		if (osst_flush_write_buffer(STp, aSRpnt)) {
+			printk(KERN_INFO "osst%i:I: Couldn't write header frame\n", dev);
 			return (-EIO);
 		}
 	}
 	result = osst_flush_drive_buffer(STp, aSRpnt);
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%i: Write onstream header group %s\n", dev, result?"failed":"done");
+	printk(OSST_DEB_MSG "osst%d:D: Write onstream header group %s\n", dev, result?"failed":"done");
 #endif
 	return result;
 }
@@ -1820,18 +1993,18 @@
 	int	      dev   = TAPE_NR(STp->devt);
 
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%i: Writing tape header\n", dev);
+	printk(OSST_DEB_MSG "osst%d:D: Writing tape header\n", dev);
 #endif
 	if (STp->raw) return 0;
 
 	if (STp->header_cache == NULL) {
 		if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
-			printk(KERN_ERR "osst%i: Failed to allocate header cache\n", dev);
+			printk(KERN_ERR "osst%i:E: Failed to allocate header cache\n", dev);
 			return (-ENOMEM);
 		}
 		memset(STp->header_cache, 0, sizeof(os_header_t));
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d: Allocated and cleared memory for header cache\n", dev);
+		printk(OSST_DEB_MSG "osst%d:D: Allocated and cleared memory for header cache\n", dev);
 #endif
 	}
 	if (STp->header_ok) STp->update_frame_cntr++;
@@ -1872,12 +2045,12 @@
 
 	if (locate_eod) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%i: locating back to eod frame addr %d\n", dev, STp->eod_frame_ppos);
+		printk(OSST_DEB_MSG "osst%d:D: Locating back to eod frame addr %d\n", dev, STp->eod_frame_ppos);
 #endif
 		osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0);
 	}
 	if (result)
-		printk(KERN_WARNING "osst%i: write header failed\n", dev);
+		printk(KERN_ERR "osst%i:E: Write header failed\n", dev);
 	else {
 		memcpy(STp->application_sig, "LIN4", 4);
 		STp->linux_media         = 1;
@@ -1892,15 +2065,15 @@
 	if (STp->header_cache != NULL)
 		memset(STp->header_cache, 0, sizeof(os_header_t));
 
-	STp->logical_blk_num = 0;
-	STp->logical_blk_in_buffer = 0;
+	STp->logical_blk_num = STp->frame_seq_number = 0;
+	STp->frame_in_buffer = 0;
 	STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A;
 	STp->filemark_cnt = 0;
-	STp->first_mark_ppos = STp->last_mark_ppos = -1;
+	STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
 	return osst_write_header(STp, aSRpnt, 1);
 }
 
-static int __osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int block)
+static int __osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int ppos)
 {
 	int           dev = TAPE_NR(STp->devt);
 	os_header_t * header;
@@ -1912,17 +2085,17 @@
 	if (STp->raw)
 		return 1;
 
-	if (block == 5 || block == 0xbae || STp->buffer->syscall_result) {
-		if (osst_set_frame_position(STp, aSRpnt, block, 0))
-			printk(KERN_WARNING "osst%i: Couldn't position tape\n", dev);
+	if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) {
+		if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
+			printk(KERN_WARNING "osst%i:W: Couldn't position tape\n", dev);
 		if (osst_initiate_read (STp, aSRpnt)) {
-			printk(KERN_WARNING "osst%i: Couldn't initiate read\n", dev);
+			printk(KERN_WARNING "osst%i:W: Couldn't initiate read\n", dev);
 			return 0;
 		}
 	}
-	if (osst_read_block(STp, aSRpnt, 180)) {
+	if (osst_read_frame(STp, aSRpnt, 180)) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%i: Couldn't read header frame\n", dev);
+		printk(OSST_DEB_MSG "osst%d:D: Couldn't read header frame\n", dev);
 #endif
 		return 0;
 	}
@@ -1930,7 +2103,20 @@
 	aux = STp->buffer->aux;
 	if (aux->frame_type != OS_FRAME_TYPE_HEADER) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%i: Skipping non-header frame (%d)\n", dev, block);
+		printk(OSST_DEB_MSG "osst%d:D: Skipping non-header frame (%d)\n", dev, ppos);
+#endif
+		return 0;
+	}
+	if (ntohl(aux->frame_seq_num)              != 0                   ||
+	    ntohl(aux->logical_blk_num)            != 0                   ||
+	          aux->partition.partition_num     != OS_CONFIG_PARTITION ||
+	    ntohl(aux->partition.first_frame_ppos) != 0                   ||
+	    ntohl(aux->partition.last_frame_ppos)  != 0xbb7               ) {
+#if DEBUG
+		printk(OSST_DEB_MSG "osst%d:D: Invalid header frame (%d,%d,%d,%d,%d)\n", dev,
+				ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
+			       	aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos),
+			       	ntohl(aux->partition.last_frame_ppos));
 #endif
 		return 0;
 	}
@@ -1938,51 +2124,57 @@
 	    strncmp(header->ident_str, "ADR-SEQ", 7) != 0) {
 		strncpy(id_string, header->ident_str, 7);
 		id_string[7] = 0;
-		printk(KERN_INFO "osst%i: Invalid header identification string %s\n", dev, id_string);
+#if DEBUG
+		printk(OSST_DEB_MSG "osst%d:D: Invalid header identification string %s\n", dev, id_string);
+#endif
 		return 0;
 	}
 	update_frame_cntr = ntohl(aux->update_frame_cntr);
 	if (update_frame_cntr < STp->update_frame_cntr) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%i: Skipping frame %d with update_frame_counter %d<%d\n",
-				   dev, block, update_frame_cntr, STp->update_frame_cntr);
+		printk(OSST_DEB_MSG "osst%d:D: Skipping frame %d with update_frame_counter %d<%d\n",
+				   dev, ppos, update_frame_cntr, STp->update_frame_cntr);
 #endif
 		return 0;
 	}
 	if (header->major_rev != 1 || header->minor_rev != 4 ) {
-		printk(KERN_INFO "osst%i: %s revision %d.%d detected (1.4 supported)\n", 
+#if DEBUG
+		printk(OSST_DEB_MSG "osst%d:D: %s revision %d.%d detected (1.4 supported)\n", 
 				 dev, (header->major_rev != 1 || header->minor_rev < 2 || 
 				       header->minor_rev  > 4 )? "Invalid" : "Warning:",
 				 header->major_rev, header->minor_rev);
+#endif
 		if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4)
 			return 0;
 	}
+#if DEBUG
 	if (header->pt_par_num != 1)
-		printk(KERN_INFO "osst%i: Warning: %d partitions defined, only one supported\n", 
+		printk(KERN_INFO "osst%i:W: %d partitions defined, only one supported\n", 
 				 dev, header->pt_par_num);
+#endif
 	memcpy(id_string, aux->application_sig, 4);
 	id_string[4] = 0;
 	if (memcmp(id_string, "LIN", 3) == 0) {
 		STp->linux_media = 1;
 		linux_media_version = id_string[3] - '0';
 		if (linux_media_version != 4)
-			printk(KERN_INFO "osst%i: Linux media version %d detected (current 4)\n",
+			printk(KERN_INFO "osst%i:I: Linux media version %d detected (current 4)\n",
 					 dev, linux_media_version);
 	} else {
-		printk(KERN_WARNING "osst%i: non Linux media detected (%s)\n", dev, id_string);
+		printk(KERN_WARNING "osst%i:W: Non Linux media detected (%s)\n", dev, id_string);
 		return 0;
 	}
 	if (linux_media_version < STp->linux_media_version) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%i: Skipping frame %d with linux_media_version %d\n",
-				  dev, block, linux_media_version);
+		printk(OSST_DEB_MSG "osst%d:D: Skipping frame %d with linux_media_version %d\n",
+				  dev, ppos, linux_media_version);
 #endif
 		return 0;
 	}
 	if (linux_media_version > STp->linux_media_version) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%i: Frame %d sets linux_media_version to %d\n",
-				   dev, block, linux_media_version);
+		printk(OSST_DEB_MSG "osst%d:D: Frame %d sets linux_media_version to %d\n",
+				   dev, ppos, linux_media_version);
 #endif
 		memcpy(STp->application_sig, id_string, 5);
 		STp->linux_media_version = linux_media_version;
@@ -1990,16 +2182,16 @@
 	}
 	if (update_frame_cntr > STp->update_frame_cntr) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%i: Frame %d sets update_frame_counter to %d\n",
-				   dev, block, update_frame_cntr);
+		printk(OSST_DEB_MSG "osst%d:D: Frame %d sets update_frame_counter to %d\n",
+				   dev, ppos, update_frame_cntr);
 #endif
 		if (STp->header_cache == NULL) {
 			if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
-				printk(KERN_ERR "osst%i: Failed to allocate header cache\n", dev);
+				printk(KERN_ERR "osst%i:E: Failed to allocate header cache\n", dev);
 				return 0;
 			}
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d: Allocated memory for header cache\n", dev);
+			printk(OSST_DEB_MSG "osst%d:D: Allocated memory for header cache\n", dev);
 #endif
 		}
 		osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache);
@@ -2012,19 +2204,22 @@
 		STp->filemark_cnt      = ntohl(aux->filemark_cnt);
 		STp->first_mark_ppos   = ntohl(aux->next_mark_ppos);
 		STp->last_mark_ppos    = ntohl(aux->last_mark_ppos);
+		STp->last_mark_lbn     = ntohl(aux->last_mark_lbn);
 		STp->update_frame_cntr = update_frame_cntr;
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%i: detected write pass %d, update frame counter %d, filemark counter %d\n",
+	printk(OSST_DEB_MSG "osst%d:D: Detected write pass %d, update frame counter %d, filemark counter %d\n",
 			  dev, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt);
-	printk(OSST_DEB_MSG "osst%i: first data frame on tape = %d, last = %d, eod frame = %d\n", dev,
+	printk(OSST_DEB_MSG "osst%d:D: first data frame on tape = %d, last = %d, eod frame = %d\n", dev,
 			  STp->first_data_ppos,
 			  ntohl(header->partition[0].last_frame_ppos),
 			  ntohl(header->partition[0].eod_frame_ppos));
-	printk(OSST_DEB_MSG "osst%i: first mark on tape = %d, last = %d, eod frame = %d\n", 
+	printk(OSST_DEB_MSG "osst%d:D: first mark on tape = %d, last = %d, eod frame = %d\n", 
 			  dev, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos);
 #endif
 		if (header->minor_rev < 4 && STp->linux_media_version == 4) {
-			printk(OSST_DEB_MSG "osst%i: Moving filemark list to ADR 1.4 location\n", dev);
+#if DEBUG
+			printk(OSST_DEB_MSG "osst%i:D: Moving filemark list to ADR 1.4 location\n", dev);
+#endif
 			memcpy((void *)header->dat_fm_tab.fm_tab_ent, 
 			       (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent));
 			memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list));
@@ -2048,9 +2243,8 @@
 		     header->dat_fm_tab.fm_tab_ent_sz                != 4                          ||
 		     header->dat_fm_tab.fm_tab_ent_cnt               !=
 			     htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX)))
-			printk(KERN_WARNING "osst%i: Failed consistency check ADR 1.4 format\n", dev);
+			printk(KERN_WARNING "osst%i:W: Failed consistency check ADR 1.4 format\n", dev);
 
-//		memcpy(STp->header_cache, header, sizeof(os_header_t));
 	}
 
 	return 1;
@@ -2058,7 +2252,7 @@
 
 static int osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
 {
-	int	position, block;
+	int position, ppos;
 	int	first, last;
 	int	valid = 0;
 	int	dev = TAPE_NR(STp->devt);
@@ -2073,37 +2267,37 @@
 	STp->header_ok = STp->linux_media = STp->linux_media_version = 0;
 	STp->wrt_pass_cntr = STp->update_frame_cntr = -1;
 	STp->eod_frame_ppos = STp->first_data_ppos = -1;
-	STp->first_mark_ppos = STp->last_mark_ppos = -1;
+	STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%i: Reading header\n", dev);
+	printk(OSST_DEB_MSG "osst%d:D: Reading header\n", dev);
 #endif
 
-	/* optimization for speed - if we are positioned at block 10, read second group first */	
+	/* optimization for speed - if we are positioned at ppos 10, read second group first  */	
 	/* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */
 
 	first = position==10?0xbae: 5;
 	last  = position==10?0xbb3:10;
 
-	for (block = first; block < last; block++)
-		if (__osst_analyze_headers(STp, aSRpnt, block))
+	for (ppos = first; ppos < last; ppos++)
+		if (__osst_analyze_headers(STp, aSRpnt, ppos))
 			valid = 1;
 
 	first = position==10? 5:0xbae;
 	last  = position==10?10:0xbb3;
 
-	for (block = first; block < last; block++)
-		if (__osst_analyze_headers(STp, aSRpnt, block))
+	for (ppos = first; ppos < last; ppos++)
+		if (__osst_analyze_headers(STp, aSRpnt, ppos))
 			valid = 1;
 
 	if (!valid) {
-		printk(KERN_ERR "osst%i: Failed to find valid ADRL header, new media?\n", dev);
+		printk(KERN_ERR "osst%i:E: Failed to find valid ADRL header, new media?\n", dev);
 		STp->eod_frame_ppos = STp->first_data_ppos = 0;
 		osst_set_frame_position(STp, aSRpnt, 10, 0);
 		return 0;
 	}
 	if (position <= STp->first_data_ppos) {
 		position = STp->first_data_ppos;
-		STp->ps[0].drv_file = STp->ps[0].drv_block = STp->logical_blk_num = 0;
+		STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
 	}
 	osst_set_frame_position(STp, aSRpnt, position, 0);
 	STp->header_ok = 1;
@@ -2114,18 +2308,21 @@
 static int osst_verify_position(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
 {
 	int	frame_position  = STp->first_frame_position;
+	int frame_seq_numbr = STp->frame_seq_number;
 	int	logical_blk_num = STp->logical_blk_num;
+       	int halfway_frame   = STp->frame_in_buffer;
+	int read_pointer    = STp->buffer->read_pointer;
 	int	prev_mark_ppos  = -1;
 	int	actual_mark_ppos, i, n;
-#if 1 //DEBUG
+#if DEBUG
 	int	dev = TAPE_NR(STp->devt);
 
-	printk(OSST_DEB_MSG "osst%i: Verify that the tape is really the one we think before writing\n", dev);
+	printk(OSST_DEB_MSG "osst%d:D: Verify that the tape is really the one we think before writing\n", dev);
 #endif
 	osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
-	if (osst_get_logical_blk(STp, aSRpnt, -1, 0) < 0) {
+	if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%i: Couldn't get logical blk num in verify_position\n", dev);
+		printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in verify_position\n", dev);
 #endif
 		return (-EIO);
 	}
@@ -2137,42 +2334,48 @@
 		prev_mark_ppos = frame_position - 1;  /* usually - we don't really know */
 	actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ?
 				frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos);
-	if (frame_position  != STp->first_frame_position ||
-	    logical_blk_num != STp->logical_blk_num + 1  ||
-	    prev_mark_ppos  != actual_mark_ppos           ) {
-#if 1 //DEBUG
-		printk(OSST_DEB_MSG "osst%i: Block mismatch: frame %d-%d, lblk %d-%d, mark %d-%d\n", dev,
-				  STp->first_frame_position, frame_position, STp->logical_blk_num + 1,
-				  logical_blk_num, actual_mark_ppos, prev_mark_ppos);
+	if (frame_position  != STp->first_frame_position                   ||
+	    frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) ||
+	    prev_mark_ppos  != actual_mark_ppos                            ) {
+#if DEBUG
+		printk(OSST_DEB_MSG "osst%d:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", dev,
+				  STp->first_frame_position, frame_position, 
+				  STp->frame_seq_number + (halfway_frame?0:1),
+				  frame_seq_numbr, actual_mark_ppos, prev_mark_ppos);
 #endif
 		return (-EIO);
 	}
-	STp->logical_blk_in_buffer = 0;
-	STp->logical_blk_num = logical_blk_num;
+	if (halfway_frame) {
+		/* prepare buffer for append and rewrite on top of original */
+		osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
+		STp->buffer->buffer_bytes  = read_pointer;
+		STp->ps[STp->partition].rw = ST_WRITING;
+		STp->dirty                 = 1;
+	}
+	STp->frame_in_buffer  = halfway_frame;
+	STp->frame_seq_number = frame_seq_numbr;
+	STp->logical_blk_num  = logical_blk_num;
 	return 0;
 }
 
 /* Acc. to OnStream, the vers. numbering is the following:
  * X.XX for released versions (X=digit), 
  * XXXY for unreleased versions (Y=letter)
- * Ordering 1.05 < 106A < 106a < 106B < ... < 1.06
+ * Ordering 1.05 < 106A < 106B < ...  < 106a < ... < 1.06
  * This fn makes monoton numbers out of this scheme ...
  */
 static unsigned int osst_parse_firmware_rev (const char * str)
 {
-	unsigned int rev;
 	if (str[1] == '.') {
-		rev = (str[0]-0x30)*10000
-			+(str[2]-0x30)*1000
-			+(str[3]-0x30)*100;
+		return (str[0]-'0')*10000
+			+(str[2]-'0')*1000
+			+(str[3]-'0')*100;
 	} else {
-		rev = (str[0]-0x30)*10000
-			+(str[1]-0x30)*1000
-			+(str[2]-0x30)*100 - 100;
-		rev += 2*(str[3] & 0x1f)
-			+(str[3] >= 0x60? 1: 0);
+		return (str[0]-'0')*10000
+			+(str[1]-'0')*1000
+			+(str[2]-'0')*100 - 100
+			+(str[3]-'@');
 	}
-	return rev;
 }
 
 /*
@@ -2180,9 +2383,9 @@
  */
 static int osst_configure_onstream(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt)
 {
-	int                            dev   = TAPE_NR(STp->devt);
 	unsigned char                  cmd[MAX_COMMAND_SIZE];
-	Scsi_Request                 * SRpnt = * aSRpnt;
+	int                            dev   = TAPE_NR(STp->devt);
+	Scsi_Request                    * SRpnt = * aSRpnt;
 	osst_mode_parameter_header_t * header;
 	osst_block_size_page_t       * bs;
 	osst_capabilities_page_t     * cp;
@@ -2191,21 +2394,19 @@
 
 	if (STp->ready != ST_READY) {
 #if DEBUG
-	    printk(OSST_DEB_MSG "osst%i: Not Ready\n", dev);
+	    printk(OSST_DEB_MSG "osst%d:D: Not Ready\n", dev);
 #endif
 	    return (-EIO);
 	}
 	
 	if (STp->os_fw_rev < 10600) {
-	    printk("osst%i: Old OnStream firmware revision detected (%s)\n", 
-		       dev, STp->device->rev);
-	    printk("osst%i: An upgrade to version 1.06 or above is recommended\n",
-		       dev);
+	    printk(KERN_INFO "osst%i:I: Old OnStream firmware revision detected (%s),\n", dev, STp->device->rev);
+	    printk(KERN_INFO "osst%d:I: an upgrade to version 1.06 or above is recommended\n", dev);
 	}
 
 	/*
 	 * Configure 32.5KB (data+aux) frame size.
-	 * Get the current block size from the block size mode page
+         * Get the current frame size from the block size mode page
 	 */
 	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = MODE_SENSE;
@@ -2216,13 +2417,13 @@
 	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_READ, STp->timeout, 0, TRUE);
 	if (SRpnt == NULL) {
 #if DEBUG
- 	    printk(OSST_DEB_MSG "osst: Busy\n");
+ 	    printk(OSST_DEB_MSG "osst :D: Busy\n");
 #endif
 	    return (-EBUSY);
 	}
 	*aSRpnt = SRpnt;
 	if ((STp->buffer)->syscall_result != 0) {
-	    printk (KERN_ERR "osst%i: Can't get tape block size mode page\n", dev);
+	    printk (KERN_ERR "osst%i:E: Can't get tape block size mode page\n", dev);
 	    return (-EIO);
 	}
 
@@ -2230,10 +2431,10 @@
 	bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl);
 
 #if DEBUG
-	printk(KERN_INFO "osst%i: 32KB play back: %s\n",   dev, bs->play32     ? "Yes" : "No");
-	printk(KERN_INFO "osst%i: 32.5KB play back: %s\n", dev, bs->play32_5   ? "Yes" : "No");
-	printk(KERN_INFO "osst%i: 32KB record: %s\n",      dev, bs->record32   ? "Yes" : "No");
-	printk(KERN_INFO "osst%i: 32.5KB record: %s\n",    dev, bs->record32_5 ? "Yes" : "No");
+	printk(OSST_DEB_MSG "osst%d:D: 32KB play back: %s\n",   dev, bs->play32     ? "Yes" : "No");
+	printk(OSST_DEB_MSG "osst%d:D: 32.5KB play back: %s\n", dev, bs->play32_5   ? "Yes" : "No");
+	printk(OSST_DEB_MSG "osst%d:D: 32KB record: %s\n",      dev, bs->record32   ? "Yes" : "No");
+	printk(OSST_DEB_MSG "osst%d:D: 32.5KB record: %s\n",    dev, bs->record32_5 ? "Yes" : "No");
 #endif
 
 	/*
@@ -2253,16 +2454,12 @@
 	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE);
 	*aSRpnt = SRpnt;
 	if ((STp->buffer)->syscall_result != 0) {
-	    printk (KERN_ERR "osst%i: Couldn't set tape block size mode page\n", dev);
+	    printk (KERN_ERR "osst%i:E: Couldn't set tape block size mode page\n", dev);
 	    return (-EIO);
 	}
 
-	STp->block_size = (STp->raw) ? OS_FRAME_SIZE : OS_DATA_SIZE;
-	STp->min_block  = OS_FRAME_SIZE; /* FIXME */
-	STp->max_block  = STp->block_size;
-
 #if DEBUG
-	printk(KERN_INFO "osst%i: Block Size changed to 32.5K\n", dev);
+	printk(KERN_INFO "osst%d:D: Block Size changed to 32.5K\n", dev);
 	 /*
 	 * In debug mode, we want to see as many errors as possible
 	 * to test the error recovery mechanism.
@@ -2298,7 +2495,7 @@
 	*aSRpnt = SRpnt;
 
 	if ((STp->buffer)->syscall_result != 0) {
-	    printk (KERN_ERR "osst%i: Couldn't set vendor name to %s\n", dev, 
+	    printk (KERN_ERR "osst%i:E: Couldn't set vendor name to %s\n", dev, 
 			(char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2));
 	    return (-EIO);
 	}
@@ -2313,7 +2510,7 @@
 	*aSRpnt = SRpnt;
 
 	if ((STp->buffer)->syscall_result != 0) {
-	    printk (KERN_ERR "osst%i: can't get capabilities page\n", dev);
+	    printk (KERN_ERR "osst%i:E: Can't get capabilities page\n", dev);
 	    return (-EIO);
 	}
 
@@ -2333,7 +2530,7 @@
 	*aSRpnt = SRpnt;
 
 	if ((STp->buffer)->syscall_result != 0) {
-	    printk (KERN_ERR "osst%i: can't get tape parameter page\n", dev);
+	    printk (KERN_ERR "osst%i:E: Can't get tape parameter page\n", dev);
 	    return (-EIO);
 	}
 
@@ -2344,7 +2541,7 @@
 	STp->density  = prm->density;
 	STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks);
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
+	printk(OSST_DEB_MSG "osst%d:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
 			  dev, STp->density, STp->capacity / 32, drive_buffer_size);
 #endif
 
@@ -2362,7 +2559,7 @@
 
 #if DEBUG
 	if (debugging)
-		printk(OSST_DEB_MSG "osst%d: Stepping over filemark %s.\n",
+		printk(OSST_DEB_MSG "osst%d:D: Stepping over filemark %s.\n",
 	   			  dev, forward ? "forward" : "backward");
 #endif
 
@@ -2375,7 +2572,7 @@
 	   result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1);
 
 	if (result < 0)
-	   printk(KERN_ERR "osst%d: Stepping over filemark %s failed.\n",
+	   printk(KERN_WARNING "osst%d:W: Stepping over filemark %s failed.\n",
 				dev, forward ? "forward" : "backward");
 
 	return result;
@@ -2415,7 +2612,7 @@
 		result = ((SRpnt->sr_sense_buffer[2] & 0x0f) == 3) ? -EIO : -EINVAL;
 
 	if (result == -EINVAL)
-		printk(KERN_ERR "osst%d: Can't read tape position.\n", dev);
+		printk(KERN_ERR "osst%d:E: Can't read tape position.\n", dev);
 	else {
 
 		if (result == -EIO) {	/* re-read position */
@@ -2440,7 +2637,7 @@
 		STp->cur_frames           =  (STp->buffer)->b_data[15];
 #if DEBUG
 		if (debugging) {
-			printk(OSST_DEB_MSG "osst%d: Drive Positions: host %d, tape %d%s, buffer %d\n", dev,
+			printk(OSST_DEB_MSG "osst%d:D: Drive Positions: host %d, tape %d%s, buffer %d\n", dev,
 					    STp->first_frame_position, STp->last_frame_position,
 					    ((STp->buffer)->b_data[0]&0x80)?" (BOP)":
 					    ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"",
@@ -2449,7 +2646,7 @@
 #endif
 		if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) {
 #if DEBUG
-			printk(KERN_WARNING "osst%d: Correcting read position %d, %d, %d\n", dev,
+			printk(KERN_WARNING "osst%d:D: Correcting read position %d, %d, %d\n", dev,
 					STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
 #endif
 			STp->first_frame_position = STp->last_frame_position;
@@ -2462,55 +2659,61 @@
 
 
 /* Set the tape block */
-static int osst_set_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int block, int skip)
+static int osst_set_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int ppos, int skip)
 {
 	unsigned char	scmd[MAX_COMMAND_SIZE];
 	Scsi_Request  * SRpnt;
 	ST_partstat   * STps;
 	int		result = 0;
-	int		timeout;
+	int		pp  = (ppos == 3000 && !skip)? 0 : ppos;
 	int		dev = TAPE_NR(STp->devt);
 
 	if (STp->ready != ST_READY) return (-EIO);
 
-	timeout = STp->long_timeout;
 	STps = &(STp->ps[STp->partition]);
 
-	if (block < 0 || block > STp->capacity) {
-		printk(KERN_ERR "osst%d: Reposition request %d out of range\n", dev, block);
-		block = block < 0 ? 0 : (STp->capacity - 1);
+	if (ppos < 0 || ppos > STp->capacity) {
+		printk(KERN_WARNING "osst%d:W: Reposition request %d out of range\n", dev, ppos);
+		pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1);
 		result = (-EINVAL);
 	}
+
+	do {
 #if DEBUG
-	if (debugging)
-		printk(OSST_DEB_MSG "osst%d: Setting block to %d.\n", dev, block);
+		if (debugging)
+			printk(OSST_DEB_MSG "osst%d:D: Setting ppos to %d.\n", dev, pp);
 #endif
-	memset (scmd, 0, MAX_COMMAND_SIZE);
-	scmd[0] = SEEK_10;
-	scmd[1] = 1;
-	scmd[3] = (block >> 24);
-	scmd[4] = (block >> 16);
-	scmd[5] = (block >> 8);
-	scmd[6] = block;
-	if (skip)
-		scmd[9] = 0x80;
+		memset (scmd, 0, MAX_COMMAND_SIZE);
+		scmd[0] = SEEK_10;
+		scmd[1] = 1;
+		scmd[3] = (pp >> 24);
+		scmd[4] = (pp >> 16);
+		scmd[5] = (pp >> 8);
+		scmd[6] =  pp;
+		if (skip)
+			scmd[9] = 0x80;
 
-	SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, SCSI_DATA_NONE, timeout, MAX_READY_RETRIES, TRUE);
-	if (!SRpnt)
-		return (-EBUSY);
-	*aSRpnt  = SRpnt;
+		SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, SCSI_DATA_NONE, STp->long_timeout,
+								MAX_READY_RETRIES, TRUE);
+		if (!SRpnt)
+			return (-EBUSY);
+		*aSRpnt  = SRpnt;
 
-	STp->first_frame_position = STp->last_frame_position = block;
-	STps->eof = ST_NOEOF;
-	if ((STp->buffer)->syscall_result != 0) {
+		if ((STp->buffer)->syscall_result != 0) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d: SEEK command failed.\n", dev);
+			printk(OSST_DEB_MSG "osst%d:D: SEEK command from %d to %d failed.\n",
+					dev, STp->first_frame_position, pp);
 #endif
-		result = (-EIO);
-	}
+			result = (-EIO);
+		}
+		if (pp != ppos)
+			osst_wait_ready(STp, aSRpnt, 5 * 60);
+	} while ((pp != ppos) && (pp = ppos));
+	STp->first_frame_position = STp->last_frame_position = ppos;
+	STps->eof = ST_NOEOF;
 	STps->at_sm = 0;
 	STps->rw = ST_IDLE;
-	STp->logical_blk_in_buffer = 0;
+	STp->frame_in_buffer = 0;
 	return result;
 }
 
@@ -2519,7 +2722,7 @@
 /* osst versions of st functions - augmented and stripped to suit OnStream only */
 
 /* Flush the write buffer (never need to write if variable blocksize). */
-static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int file_blk)
+static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt)
 {
 	int offset, transfer, blks = 0;
 	int result = 0;
@@ -2532,19 +2735,19 @@
 		if (SRpnt == (STp->buffer)->last_SRpnt)
 #if DEBUG
 			{ printk(OSST_DEB_MSG
-	 "osst%d: aSRpnt points to Scsi_Request that write_behind_check will release -- cleared\n", dev);
+	 "osst%d:D: aSRpnt points to Scsi_Request that write_behind_check will release -- cleared\n", dev);
 #endif
 			*aSRpnt = SRpnt = NULL;
 #if DEBUG
 			} else if (SRpnt)
 				printk(OSST_DEB_MSG
-	 "osst%d: aSRpnt does not point to Scsi_Request that write_behind_check will release -- strange\n", dev);
+	 "osst%d:D: aSRpnt does not point to Scsi_Request that write_behind_check will release -- strange\n", dev);
 #endif	
 		osst_write_behind_check(STp);
 		if ((STp->buffer)->syscall_result) {
 #if DEBUG
 			if (debugging)
-				printk(OSST_DEB_MSG "osst%d: Async write error (flush) %x.\n",
+				printk(OSST_DEB_MSG "osst%d:D: Async write error (flush) %x.\n",
 				       dev, (STp->buffer)->midlevel_result);
 #endif
 			if ((STp->buffer)->midlevel_result == INT_MAX)
@@ -2556,15 +2759,13 @@
 	result = 0;
 	if (STp->dirty == 1) {
 
+		STp->write_count++;
+		STps     = &(STp->ps[STp->partition]);
+		STps->rw = ST_WRITING;
 		offset   = STp->buffer->buffer_bytes;
+		blks     = (offset + STp->block_size - 1) / STp->block_size;
 		transfer = OS_FRAME_SIZE;
-		blks     = 1;
 		
-#if DEBUG
-		if (debugging)
-			printk(OSST_DEB_MSG "osst%d: Flushing %d bytes, Tranfering %d bytes in %d blocks.\n",
-				 dev, offset, transfer, blks);
-#endif
 		if (offset < OS_DATA_SIZE)
 			osst_zero_buffer_tail(STp->buffer);
 
@@ -2575,7 +2776,38 @@
 		memset(cmd, 0, MAX_COMMAND_SIZE);
 		cmd[0] = WRITE_6;
 		cmd[1] = 1;
-		cmd[4] = blks;
+		cmd[4] = 1;
+
+		switch	(STp->write_type) {
+		   case OS_WRITE_DATA:
+#if DEBUG
+   			if (debugging)
+				printk(OSST_DEB_MSG "osst%d:D: Writing %d blocks to frame %d, lblks %d-%d\n",
+					dev, blks, STp->frame_seq_number, 
+					STp->logical_blk_num - blks, STp->logical_blk_num - 1);
+#endif
+			osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
+				      STp->logical_blk_num - blks, STp->block_size, blks);
+			break;
+		   case OS_WRITE_EOD:
+			osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->frame_seq_number++,
+				      STp->logical_blk_num, 0, 0);
+			break;
+		   case OS_WRITE_NEW_MARK:
+			osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->frame_seq_number++,
+				      STp->logical_blk_num++, 0, blks=1);
+			break;
+		   case OS_WRITE_HEADER:
+			osst_init_aux(STp, OS_FRAME_TYPE_HEADER, 0, 0, 0, blks=0);
+			break;
+		default: /* probably FILLER */
+			osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0, 0, 0, 0);
+		}
+#if DEBUG
+		if (debugging)
+			printk(OSST_DEB_MSG "osst%d:D: Flushing %d bytes, Transfering %d bytes in %d lblocks.\n",
+			  			 dev, offset, transfer, blks);
+#endif
 
 		SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, SCSI_DATA_WRITE,
 					  STp->timeout, MAX_WRITE_RETRIES, TRUE);
@@ -2583,12 +2815,13 @@
 		if (!SRpnt)
 			return (-EBUSY);
 
-		STps = &(STp->ps[STp->partition]);
 		if ((STp->buffer)->syscall_result != 0) {
+#if DEBUG
 			printk(OSST_DEB_MSG
-				"osst%d: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n",
+				"osst%d:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n",
 				dev, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
 				SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
+#endif
 			if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
 			    (SRpnt->sr_sense_buffer[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */
 			    (SRpnt->sr_sense_buffer[2] & 0x0f) == NO_SENSE) {
@@ -2598,22 +2831,20 @@
 			}
 			else {
 				if (osst_write_error_recovery(STp, aSRpnt, 1)) {
-					printk(KERN_ERR "osst%d: Error on flush.\n", dev);
+					printk(KERN_ERR "osst%d:E: Error on flush write.\n", dev);
 					result = (-EIO);
 				}
 			}
 			STps->drv_block = (-1);
 		}
 		else {
-			if (file_blk && STps->drv_block >= 0)
-				STps->drv_block += blks;
-			STp->first_frame_position += blks;
+			STp->first_frame_position++;
 			STp->dirty = 0;
 			(STp->buffer)->buffer_bytes = 0;
 		}
 	}
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%d: Exit flush write buffer with code %d\n", dev, result);
+	printk(OSST_DEB_MSG "osst%d:D: Exit flush write buffer with code %d\n", dev, result);
 #endif
 	return result;
 }
@@ -2623,15 +2854,12 @@
    seek_next is true. */
 static int osst_flush_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int seek_next)
 {
-	int backspace, result;
-	OSST_buffer    * STbuffer;
-	ST_partstat  * STps;
+	ST_partstat   * STps;
+	int backspace = 0, result = 0;
 #if DEBUG
 	int dev = TAPE_NR(STp->devt);
 #endif
 
-	STbuffer = STp->buffer;
-
 	/*
 	 * If there was a bus reset, block further access
 	 * to this device.
@@ -2644,19 +2872,23 @@
 
 	STps = &(STp->ps[STp->partition]);
 	if (STps->rw == ST_WRITING)  /* Writing */
-		return osst_flush_write_buffer(STp, aSRpnt, 1);
+		return osst_flush_write_buffer(STp, aSRpnt);
 
 	if (STp->block_size == 0)
 		return 0;
 
 #if DEBUG
-	printk(OSST_DEB_MSG "osst%i: Reached flush (read) buffer\n", dev);
+	printk(OSST_DEB_MSG "osst%d:D: Reached flush (read) buffer\n", dev);
 #endif
-	backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size -
-		    ((STp->buffer)->read_pointer + STp->block_size - 1        ) / STp->block_size ;
-	(STp->buffer)->buffer_bytes = 0;
-	(STp->buffer)->read_pointer = 0;
-	result = 0;
+
+	if (!STp->can_bsr) {
+		backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size -
+			    ((STp->buffer)->read_pointer + STp->block_size - 1        ) / STp->block_size ;
+		(STp->buffer)->buffer_bytes = 0;
+		(STp->buffer)->read_pointer = 0;
+		STp->frame_in_buffer = 0;		/* FIXME is this relevant w. OSST? */
+	}
+
 	if (!seek_next) {
 		if (STps->eof == ST_FM_HIT) {
 			result = cross_eof(STp, aSRpnt, FALSE); /* Back over the EOF hit */
@@ -2681,6 +2913,88 @@
 	return result;
 }
 
+static int osst_write_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int synchronous)
+{
+	unsigned char	cmd[MAX_COMMAND_SIZE];
+	Scsi_Request     * SRpnt;
+	int		blks;
+#if DEBUG
+	int		dev = TAPE_NR(STp->devt);
+#endif
+
+	if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */
+#if DEBUG
+		printk(OSST_DEB_MSG "osst%d:D: Reaching config partition.\n", dev);
+#endif
+		if (osst_flush_drive_buffer(STp, aSRpnt) < 0) {
+			return (-EIO);
+		}
+		/* error recovery may have bumped us past the header partition */
+		if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) {
+#if DEBUG
+			printk(OSST_DEB_MSG "osst%d:D: Skipping over config partition.\n", dev);
+#endif
+		osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8);
+		}
+	}
+
+	if (STp->poll)
+		osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 60);
+	/* TODO: Check for an error ! */
+
+//	osst_build_stats(STp, &SRpnt);
+
+	STp->ps[STp->partition].rw = ST_WRITING;
+	STp->write_type            = OS_WRITE_DATA;
+			
+	memset(cmd, 0, MAX_COMMAND_SIZE);
+	cmd[0]   = WRITE_6;
+	cmd[1]   = 1;
+	cmd[4]   = 1;						/* one frame at a time... */
+	blks     = STp->buffer->buffer_bytes / STp->block_size;
+#if DEBUG
+	if (debugging)
+		printk(OSST_DEB_MSG "osst%d:D: Writing %d blocks to frame %d, lblks %d-%d\n", dev, blks, 
+			STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1);
+#endif
+	osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
+		      STp->logical_blk_num - blks, STp->block_size, blks);
+
+#if DEBUG
+	if (!synchronous)
+		STp->write_pending = 1;
+#endif
+	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE, STp->timeout,
+							MAX_WRITE_RETRIES, synchronous);
+	if (!SRpnt)
+		return (-EBUSY);
+	*aSRpnt = SRpnt;
+
+	if (synchronous) {
+		if (STp->buffer->syscall_result != 0) {
+#if DEBUG
+			if (debugging)
+				printk(OSST_DEB_MSG "osst%d:D: Error on write:\n", dev);
+#endif
+			if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
+			    (SRpnt->sr_sense_buffer[2] & 0x40)) {
+				if ((SRpnt->sr_sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW)
+					return (-ENOSPC);
+			}
+			else {
+				if (osst_write_error_recovery(STp, aSRpnt, 1))
+					return (-EIO);
+			}
+		}
+		else
+			STp->first_frame_position++;
+	}
+
+	STp->write_count++;
+
+	return 0;
+}
+
 
 /* Entry points to osst */
 
@@ -2692,7 +3006,6 @@
 	ssize_t i, do_count, blks, transfer;
 	int write_threshold;
 	int doing_write = 0;
-	unsigned char cmd[MAX_COMMAND_SIZE];
 	const char *b_point;
 	Scsi_Request * SRpnt = NULL;
 	OS_Scsi_Tape * STp;
@@ -2748,7 +3061,7 @@
 
 #if DEBUG
 	if (!STp->in_use) {
-		printk(OSST_DEB_MSG "osst%d: Incorrect device.\n", dev);
+		printk(OSST_DEB_MSG "osst%d:D: Incorrect device.\n", dev);
 		retval = (-EIO);
 		goto out;
 	}
@@ -2761,14 +3074,15 @@
 
 	/* Write must be integral number of blocks */
 	if (STp->block_size != 0 && (count % STp->block_size) != 0) {
-		printk(KERN_WARNING "osst%d: Write (%ld bytes) not multiple of tape block size (32k).\n",
-				       dev, (unsigned long)count);
+		printk(KERN_ERR "osst%d:E: Write (%ld bytes) not multiple of tape block size (%d%c).\n",
+				       dev, (unsigned long)count, STp->block_size<1024?
+				       STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
 		retval = (-EINVAL);
 		goto out;
 	}
 
-	if (STp->first_frame_position >= STp->capacity - 164) {
-		printk(KERN_WARNING "osst%d: Write truncated at EOM early warning (frame %d).\n",
+	if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) {
+		printk(KERN_ERR "osst%d:E: Write truncated at EOM early warning (frame %d).\n",
 				       dev, STp->first_frame_position);
 		retval = (-ENOSPC);
 		goto out;
@@ -2789,46 +3103,49 @@
 	}
 	else if (STps->rw != ST_WRITING) {
 		/* Are we totally rewriting this tape? */
-		if (!STp->header_ok || STp->first_frame_position == STp->first_data_ppos ||
-      		            (STps->drv_file == 0 && STps->drv_block == 0)) {
+		if (!STp->header_ok ||
+		    (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) ||
+		    (STps->drv_file == 0 && STps->drv_block == 0)) {
 			STp->wrt_pass_cntr++;
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d: Allocating next write pass counter: %d\n",
+			printk(OSST_DEB_MSG "osst%d:D: Allocating next write pass counter: %d\n",
 						  dev, STp->wrt_pass_cntr);
 #endif
 			osst_reset_header(STp, &SRpnt);
-			STps->drv_file = STps->drv_block = STp->logical_blk_num = 0;
+			STps->drv_file = STps->drv_block = 0;
 		}
 		/* Do we know where we'll be writing on the tape? */
 		else {
 			if ((STp->fast_open && osst_verify_position(STp, &SRpnt)) ||
 			  		STps->drv_file < 0 || STps->drv_block < 0) {
-				if (STp->first_frame_position == STp->eod_frame_ppos) {
+				if (STp->first_frame_position == STp->eod_frame_ppos) {	/* at EOD */
 			  		STps->drv_file = STp->filemark_cnt;
 			  		STps->drv_block = 0;
 				}
 				else {
 					/* We have no idea where the tape is positioned - give up */
 #if DEBUG
-					printk(OSST_DEB_MSG "osst%d: Cannot write at indeterminate position.\n", dev);
+					printk(OSST_DEB_MSG
+						"osst%d:D: Cannot write at indeterminate position.\n", dev);
 #endif
 					retval = (-EIO);
 					goto out;
 				}
       			}	  
-			if (STps->drv_file > 0 && STps->drv_file < STp->filemark_cnt) {
+			if ((STps->drv_file + STps->drv_block) > 0 && STps->drv_file < STp->filemark_cnt) {
 				STp->filemark_cnt = STps->drv_file;
-				STp->last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]);
+				STp->last_mark_ppos =
+				       	ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]);
 				printk(KERN_WARNING
-					"osst%d: Overwriting file %d with old write pass counter %d\n",
+					"osst%d:W: Overwriting file %d with old write pass counter %d\n",
 						dev, STps->drv_file, STp->wrt_pass_cntr);
 				printk(KERN_WARNING
-					"osst%d: may lead to stale data being accepted on reading back!\n",
+					"osst%d:W: may lead to stale data being accepted on reading back!\n",
 						dev);
 #if DEBUG
 				printk(OSST_DEB_MSG
-					"osst%d: resetting filemark count to %d and last mark ppos to %d\n",
-						dev, STp->filemark_cnt, STp->last_mark_ppos);
+				  "osst%d:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n",
+					dev, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn);
 #endif
 			}
 		}
@@ -2836,19 +3153,19 @@
 	}
 	if (!STp->header_ok) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d: Write cannot proceed without valid headers\n", dev);
+		printk(OSST_DEB_MSG "osst%d:D: Write cannot proceed without valid headers\n", dev);
 #endif
 		retval = (-EIO);
 		goto out;
 	}
 
 	if ((STp->buffer)->writing) {
-if (SRpnt) printk(KERN_ERR "osst%d: Not supposed to have SRpnt at line %d\n", dev, __LINE__);
+if (SRpnt) printk(KERN_ERR "osst%d:A: Not supposed to have SRpnt at line %d\n", dev, __LINE__);
 		osst_write_behind_check(STp);
 		if ((STp->buffer)->syscall_result) {
 #if DEBUG
 		if (debugging)
-			printk(OSST_DEB_MSG "osst%d: Async write error (write) %x.\n", dev,
+			printk(OSST_DEB_MSG "osst%d:D: Async write error (write) %x.\n", dev,
 						 (STp->buffer)->midlevel_result);
 #endif
 		if ((STp->buffer)->midlevel_result == INT_MAX)
@@ -2875,10 +3192,6 @@
 	}
 
 	if (!STm->do_buffer_writes) {
-#if 0
-		if (STp->block_size != 0 && (count % STp->block_size) != 0)
-			{retval=(-EIO);goto out;}   /* Write must be integral number of blocks */
-#endif
 		write_threshold = 1;
 	}
 	else
@@ -2887,37 +3200,12 @@
 		write_threshold--;
 
 	total = count;
-
-	if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d: Skipping over config partition.\n", dev);
-#endif
-		if (osst_flush_drive_buffer(STp, &SRpnt) < 0) {
-			retval = (-EIO);
-			goto out;
-		}
-		/* error recovery may have bumped us past the header partition */
-		if (osst_get_frame_position(STp, &SRpnt) < 0xbb8)
-			osst_position_tape_and_confirm(STp, &SRpnt, 0xbb8);
-	}
-	
-	if (STp->poll)
-		retval = osst_wait_frame (STp, &SRpnt, STp->first_frame_position, -50, 60);
-	/* TODO: Check for an error ! */
-	
-	memset(cmd, 0, MAX_COMMAND_SIZE);
-	cmd[0] = WRITE_6;
-	cmd[1] = 1;
-
-	STps->rw = ST_WRITING;
-	STp->write_type = OS_WRITE_DATA;
-
-#if DEBUG
-	printk(OSST_DEB_MSG "osst%d: Writing %d bytes to file %d block %d lblk %d frame %d\n",
-			  dev, count, STps->drv_file, STps->drv_block,
-			  STp->logical_blk_num, STp->first_frame_position);
+	if (debugging)
+		printk(OSST_DEB_MSG "osst%d:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n",
+				dev, count, STps->drv_file, STps->drv_block,
+				STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position);
 #endif
-
 	b_point = buf;
 	while ((STp->buffer)->buffer_bytes + count > write_threshold)
 	{
@@ -2933,85 +3221,62 @@
 			goto out;
 		}
 
-		transfer = OS_FRAME_SIZE;
-		blks     = 1;
-
-		osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->logical_blk_num++ );
-
-		cmd[2] = blks >> 16;
-		cmd[3] = blks >> 8;
-		cmd[4] = blks;
-
-		SRpnt = osst_do_scsi(SRpnt, STp, cmd, transfer, SCSI_DATA_WRITE,
-				  STp->timeout, MAX_WRITE_RETRIES, TRUE);
-		if (!SRpnt) {
-			retval = (STp->buffer)->syscall_result;
-			goto out;
-		}
+		blks = do_count / STp->block_size;
+		STp->logical_blk_num += blks;  /* logical_blk_num is incremented as data is moved from user */
+  
+		i = osst_write_frame(STp, &SRpnt, TRUE);
 
-		if ((STp->buffer)->syscall_result != 0) {
-#if DEBUG
-			if (debugging)
-				printk(OSST_DEB_MSG "osst%d: Error on write:\n", dev);
-#endif
-			if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
-			    (SRpnt->sr_sense_buffer[2] & 0x40)) {
-				if ((SRpnt->sr_sense_buffer[0] & 0x80) != 0)
-					transfer = (SRpnt->sr_sense_buffer[3] << 24) |
-						   (SRpnt->sr_sense_buffer[4] << 16) |
-						   (SRpnt->sr_sense_buffer[5] <<  8) |
-						    SRpnt->sr_sense_buffer[6];
-				else
-					transfer = 0;
-				transfer *= STp->block_size;
-				if (transfer <= do_count) {
-					filp->f_pos += do_count - transfer;
-					count -= do_count - transfer;
-					if (STps->drv_block >= 0) {
-						STps->drv_block += (do_count - transfer) / STp->block_size;
-					}
-					STps->eof = ST_EOM_OK;
-					retval = (-ENOSPC); /* EOM within current request */
-#if DEBUG
-					if (debugging)
-					      printk(OSST_DEB_MSG "osst%d: EOM with %d bytes unwritten.\n",
-								     dev, transfer);
-#endif
+		if (i == (-ENOSPC)) {
+			transfer = STp->buffer->writing;	/* FIXME -- check this logic */
+			if (transfer <= do_count) {
+				filp->f_pos += do_count - transfer;
+				count -= do_count - transfer;
+				if (STps->drv_block >= 0) {
+					STps->drv_block += (do_count - transfer) / STp->block_size;
 				}
-				else {
-					STps->eof = ST_EOM_ERROR;
-					STps->drv_block = (-1);    /* Too cautious? */
-					retval = (-EIO); /* EOM for old data */
+				STps->eof = ST_EOM_OK;
+				retval = (-ENOSPC);		/* EOM within current request */
 #if DEBUG
-					if (debugging)
-					      printk(OSST_DEB_MSG "osst%d: EOM with lost data.\n", dev);
+				if (debugging)
+				      printk(OSST_DEB_MSG "osst%d:D: EOM with %d bytes unwritten.\n",
+							     dev, transfer);
 #endif
-				}
 			}
 			else {
-				if (osst_write_error_recovery(STp, &SRpnt, 1) == 0) goto ok;
-				STps->drv_block = (-1);    /* Too cautious? */
-				retval = (-EIO);
+				STps->eof = ST_EOM_ERROR;
+				STps->drv_block = (-1);		/* Too cautious? */
+				retval = (-EIO);		/* EOM for old data */
+#if DEBUG
+				if (debugging)
+				      printk(OSST_DEB_MSG "osst%d:D: EOM with lost data.\n", dev);
+#endif
 			}
-
-			(STp->buffer)->buffer_bytes = 0;
+		}
+		else
+			retval = i;
+			
+		if (retval < 0) {
+			if (SRpnt != NULL) {
+				scsi_release_request(SRpnt);
+				SRpnt = NULL;
+			}
+			STp->buffer->buffer_bytes = 0;
 			STp->dirty = 0;
 			if (count < total)
 				retval = total - count;
 			goto out;
 		}
-		STp->first_frame_position++;
-ok:
+
 		filp->f_pos += do_count;
 		b_point += do_count;
 		count -= do_count;
 		if (STps->drv_block >= 0) {
 			STps->drv_block += blks;
 		}
-		STp->first_frame_position += blks;
-		(STp->buffer)->buffer_bytes = 0;
+		STp->buffer->buffer_bytes = 0;
 		STp->dirty = 0;
-	}
+	}  /* end while write threshold exceeded */
+
 	if (count != 0) {
 		STp->dirty = 1;
 		i = append_to_buffer(b_point, STp->buffer, count);
@@ -3019,6 +3284,11 @@
 			retval = i;
 			goto out;
 		}
+		blks = count / STp->block_size;
+		STp->logical_blk_num += blks;
+		if (STps->drv_block >= 0) {
+			STps->drv_block += blks;
+		}
 		filp->f_pos += count;
 		count = 0;
 	}
@@ -3028,41 +3298,23 @@
 		goto out;
 	}
 
-	if (STm->do_async_writes &&
-	    ((STp->buffer)->buffer_bytes >= STp->write_threshold &&
-	     (STp->buffer)->buffer_bytes >= OS_DATA_SIZE)      ) { 
+	if (STm->do_async_writes && ((STp->buffer)->buffer_bytes >= STp->write_threshold)) { 
 		/* Schedule an asynchronous write */
 		(STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
 					   STp->block_size) * STp->block_size;
 		STp->dirty = !((STp->buffer)->writing ==
 				          (STp->buffer)->buffer_bytes);
 
-		transfer = OS_FRAME_SIZE;
-		blks     = 1;
-
-		osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->logical_blk_num++ );
-
-		cmd[2] = blks >> 16;
-		cmd[3] = blks >> 8;
-		cmd[4] = blks;
-#if DEBUG
-		STp->write_pending = 1;
-#endif
-
-		SRpnt = osst_do_scsi(SRpnt, STp, cmd, transfer, SCSI_DATA_WRITE,
-				  STp->timeout, MAX_WRITE_RETRIES, FALSE);
-		if (SRpnt == NULL) {
-			retval = (STp->buffer)->syscall_result;
+		i = osst_write_frame(STp, &SRpnt, FALSE);
+		if (i < 0) {
+			retval = (-EIO);
 			goto out;
 		}
+		SRpnt = NULL;			/* Prevent releasing this request! */
 	}
-//    else if (SRpnt != NULL) {
-//	scsi_release_request(SRpnt);	/* FIXME -- this relesae no longer in st - why? */
-	SRpnt = NULL;			/* Prevent releasing this request! */
-//    }
 	STps->at_sm &= (total == 0);
 	if (total > 0)
-	STps->eof = ST_NOEOF;
+		STps->eof = ST_NOEOF;
 
 	retval = total;
 
@@ -3124,7 +3376,7 @@
 	}
 #if DEBUG
 	if (!STp->in_use) {
-		printk(OSST_DEB_MSG "osst%d: Incorrect device.\n", dev);
+		printk(OSST_DEB_MSG "osst%d:D: Incorrect device.\n", dev);
 		retval = (-EIO);
 		goto out;
 	}
@@ -3135,13 +3387,6 @@
 		goto out;
 	}
 
-	if ((count % STp->block_size) != 0) {
-		printk(KERN_WARNING "osst%d: Use multiple of %d bytes as block size (%ld requested)\n",
-			  dev, STp->block_size, (unsigned long) count);
-		retval = (-EINVAL);	/* Read must be integral number of blocks */
-		goto out;
-	}
-
 	if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED &&
 	!osst_int_ioctl(STp, &SRpnt, MTLOCK, 0))
 		STp->door_locked = ST_LOCKED_AUTO;
@@ -3154,9 +3399,15 @@
 		STps->rw = ST_IDLE;
 	}
 
+	if ((count % STp->block_size) != 0) {
+		printk(KERN_WARNING
+		    "osst%d:W: Read (%Zd bytes) not multiple of tape block size (%d%c).\n", dev, count,
+		    STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
+	}
+
 #if DEBUG
 	if (debugging && STps->eof != ST_NOEOF)
-		printk(OSST_DEB_MSG "osst%d: EOF/EOM flag up (%d). Bytes %d\n", dev,
+		printk(OSST_DEB_MSG "osst%d:D: EOF/EOM flag up (%d). Bytes %d\n", dev,
 				     STps->eof, (STp->buffer)->buffer_bytes);
 #endif
 	if ((STp->buffer)->buffer_bytes == 0 &&
@@ -3181,41 +3432,51 @@
 	}
 
 	/* Loop until enough data in buffer or a special condition found */
-	for (total = 0, special = 0; total < count && !special; ) {
+	for (total = 0, special = 0; total < count - STp->block_size + 1 && !special; ) {
 
 		/* Get new data if the buffer is empty */
 		if ((STp->buffer)->buffer_bytes == 0) {
-			special = osst_get_logical_blk(STp, &SRpnt, STp->logical_blk_num, 0);
-			STp->buffer->buffer_bytes = special ? 0 : OS_DATA_SIZE; 
-			STp->buffer->read_pointer = 0;
-			STp->logical_blk_num++;		/* block to look for next time */
-			STp->logical_blk_in_buffer = 0;
+			if (STps->eof == ST_FM_HIT)
+				break;
+			special = osst_get_logical_frame(STp, &SRpnt, STp->frame_seq_number, 0);
 			if (special < 0) { 			/* No need to continue read */
+				STp->frame_in_buffer = 0;
 				retval = special;
 				goto out;
 			}
-			STps->drv_block++;
 		}
 
 		/* Move the data from driver buffer to user buffer */
 		if ((STp->buffer)->buffer_bytes > 0) {
 #if DEBUG
 			if (debugging && STps->eof != ST_NOEOF)
-			    printk(OSST_DEB_MSG "osst%d: EOF up (%d). Left %d, needed %d.\n", dev,
+			    printk(OSST_DEB_MSG "osst%d:D: EOF up (%d). Left %d, needed %d.\n", dev,
 						 STps->eof, (STp->buffer)->buffer_bytes, count - total);
 #endif
-			transfer = (STp->buffer)->buffer_bytes < count - total ?
-				   (STp->buffer)->buffer_bytes : count - total;
+			transfer = (((STp->buffer)->buffer_bytes < count - total ?
+				     (STp->buffer)->buffer_bytes : count - total)/
+					STp->block_size) * STp->block_size; /* force multiple of block size */
 			i = from_buffer(STp->buffer, buf, transfer);
 			if (i)  {
 				retval = i;
 				goto out;
 			}
-			filp->f_pos += transfer;
-			buf += transfer;
-			total += transfer;
+			STp->logical_blk_num += transfer / STp->block_size;
+			STps->drv_block      += transfer / STp->block_size;
+			filp->f_pos          += transfer;
+			buf                  += transfer;
+			total                += transfer;
+		}
+ 
+		if ((STp->buffer)->buffer_bytes == 0) {
+#if DEBUG
+			if (debugging)
+				printk(OSST_DEB_MSG "osst%d:D: Finished with frame %d\n",
+					       	dev, STp->frame_seq_number);
+#endif
+			STp->frame_in_buffer = 0;
+			STp->frame_seq_number++;              /* frame to look for next time */
 		}
-
 	} /* for (total = 0, special = 0; total < count && !special; ) */
 
 	/* Change the eof state if no data from tape or buffer */
@@ -3253,21 +3514,21 @@
 static void osst_log_options(OS_Scsi_Tape *STp, ST_mode *STm, int dev)
 {
   printk(KERN_INFO
-"osst%d: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
+"osst%d:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
 	 dev, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
 	 STm->do_read_ahead);
   printk(KERN_INFO
-"osst%d:    can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
+"osst%d:I:    can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
 	 dev, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
   printk(KERN_INFO
-"osst%d:    defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
+"osst%d:I:    defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
 	 dev, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
 	 STp->scsi2_logical);
   printk(KERN_INFO
-"osst%d:    sysv: %d\n", dev, STm->sysv);
+"osst%d:I:    sysv: %d\n", dev, STm->sysv);
 #if DEBUG
   printk(KERN_INFO
-	 "osst%d:    debugging: %d\n",
+	 "osst%d:D:    debugging: %d\n",
 	 dev, debugging);
 #endif
 }
@@ -3286,7 +3547,7 @@
 		modes_defined = TRUE;
 #if DEBUG
 		if (debugging)
-			printk(OSST_DEB_MSG "osst%d: Initialized mode %d definition from mode 0\n",
+			printk(OSST_DEB_MSG "osst%d:D: Initialized mode %d definition from mode 0\n",
 					     dev, STp->current_mode);
 #endif
 	}
@@ -3347,23 +3608,28 @@
 	else if (code == MT_ST_WRITE_THRESHOLD) {
 		value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE;
 		if (value < 1 || value > osst_buffer_size) {
-			printk(KERN_WARNING "osst%d: Write threshold %d too small or too large.\n",
+			printk(KERN_WARNING "osst%d:W: Write threshold %d too small or too large.\n",
 					     dev, value);
 			return (-EIO);
 		}
 		STp->write_threshold = value;
-		printk(KERN_INFO "osst%d: Write threshold set to %d bytes.\n",
+		printk(KERN_INFO "osst%d:I: Write threshold set to %d bytes.\n",
 				  dev, value);
 	}
 	else if (code == MT_ST_DEF_BLKSIZE) {
 		value = (options & ~MT_ST_OPTIONS);
 		if (value == ~MT_ST_OPTIONS) {
 			STm->default_blksize = (-1);
-			printk(KERN_INFO "osst%d: Default block size disabled.\n", dev);
+			printk(KERN_INFO "osst%d:I: Default block size disabled.\n", dev);
 		}
 		else {
+			if (value < 512 || value > OS_DATA_SIZE || OS_DATA_SIZE % value) {
+				printk(KERN_WARNING "osst%d:W: Default block size cannot be set to %d.\n",
+							 dev, value);
+				return (-EINVAL);
+			}
 			STm->default_blksize = value;
-			printk(KERN_INFO "osst%d: Default block size set to %d bytes.\n",
+			printk(KERN_INFO "osst%d:I: Default block size set to %d bytes.\n",
 					  dev, STm->default_blksize);
 		}
 	}
@@ -3371,12 +3637,12 @@
 		value = (options & ~MT_ST_OPTIONS);
 		if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
 			STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
-			printk(KERN_INFO "osst%d: Long timeout set to %d seconds.\n", dev,
+			printk(KERN_INFO "osst%d:I: Long timeout set to %d seconds.\n", dev,
 					     (value & ~MT_ST_SET_LONG_TIMEOUT));
 		}
 		else {
 			STp->timeout = value * HZ;
-			printk(KERN_INFO "osst%d: Normal timeout set to %d seconds.\n", dev, value);
+			printk(KERN_INFO "osst%d:I: Normal timeout set to %d seconds.\n", dev, value);
 		}
 	}
 	else if (code == MT_ST_DEF_OPTIONS) {
@@ -3385,33 +3651,33 @@
 		if (code == MT_ST_DEF_DENSITY) {
 			if (value == MT_ST_CLEAR_DEFAULT) {
 				STm->default_density = (-1);
-				printk(KERN_INFO "osst%d: Density default disabled.\n", dev);
+				printk(KERN_INFO "osst%d:I: Density default disabled.\n", dev);
 			}
 			else {
 				STm->default_density = value & 0xff;
-				printk(KERN_INFO "osst%d: Density default set to %x\n",
+				printk(KERN_INFO "osst%d:I: Density default set to %x\n",
 						  dev, STm->default_density);
 			}
 		}
 		else if (code == MT_ST_DEF_DRVBUFFER) {
 			if (value == MT_ST_CLEAR_DEFAULT) {
 				STp->default_drvbuffer = 0xff;
-				printk(KERN_INFO "osst%d: Drive buffer default disabled.\n", dev);
+				printk(KERN_INFO "osst%d:I: Drive buffer default disabled.\n", dev);
 			}
 			else {
 				STp->default_drvbuffer = value & 7;
-				printk(KERN_INFO "osst%d: Drive buffer default set to %x\n",
+				printk(KERN_INFO "osst%d:I: Drive buffer default set to %x\n",
 						  dev, STp->default_drvbuffer);
 			}
 		}
 		else if (code == MT_ST_DEF_COMPRESSION) {
 			if (value == MT_ST_CLEAR_DEFAULT) {
 				STm->default_compression = ST_DONT_TOUCH;
-				printk(KERN_INFO "osst%d: Compression default disabled.\n", dev);
+				printk(KERN_INFO "osst%d:I: Compression default disabled.\n", dev);
 			}
 			else {
 				STm->default_compression = (value & 1 ? ST_YES : ST_NO);
-				printk(KERN_INFO "osst%d: Compression default set to %x\n",
+				printk(KERN_INFO "osst%d:I: Compression default set to %x\n",
 						  dev, (value & 1));
 			}
 		}
@@ -3433,7 +3699,7 @@
 	unsigned char cmd[MAX_COMMAND_SIZE];
 	Scsi_Request * SRpnt = * aSRpnt;
 	ST_partstat * STps;
-	int fileno, blkno, at_sm, logical_blk_num;
+	int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
 	int datalen = 0, direction = SCSI_DATA_NONE;
 	int dev = TAPE_NR(STp->devt);
 
@@ -3448,6 +3714,7 @@
 	fileno = STps->drv_file;
 	blkno = STps->drv_block;
 	at_sm = STps->at_sm;
+	frame_seq_numbr = STp->frame_seq_number;
 	logical_blk_num = STp->logical_blk_num;
 
 	memset(cmd, 0, MAX_COMMAND_SIZE);
@@ -3461,7 +3728,6 @@
 		   ioctl_result = osst_space_over_filemarks_forward_fast(STp, &SRpnt, cmd_in, arg);
 		else
 		   ioctl_result = osst_space_over_filemarks_forward_slow(STp, &SRpnt, cmd_in, arg);
-		logical_blk_num = STp->logical_blk_num;
 		if (fileno >= 0)
 		   fileno += arg;
 		blkno = 0;
@@ -3474,7 +3740,6 @@
 		if (STp->raw)
 		   return (-EIO);
 		ioctl_result = osst_space_over_filemarks_backward(STp, &SRpnt, cmd_in, arg);
-		logical_blk_num = STp->logical_blk_num;
 		if (fileno >= 0)
 		   fileno -= arg;
 		blkno = (-1);  /* We can't know the block number */
@@ -3485,7 +3750,7 @@
 	 case MTBSR:
 #if DEBUG
 		if (debugging)
-		   printk(OSST_DEB_MSG "osst%i: Skipping %lu blocks %s from logical block %d\n",
+		   printk(OSST_DEB_MSG "osst%d:D: Skipping %lu blocks %s from logical block %d\n",
 				dev, arg, cmd_in==MTFSR?"forward":"backward", logical_blk_num);
 #endif
 		if (cmd_in == MTFSR) {
@@ -3496,8 +3761,9 @@
 		   logical_blk_num -= arg;
 		   if (blkno >= 0) blkno -= arg;
 		}
-		ioctl_result = osst_seek_logical_blk(STp, &SRpnt, logical_blk_num-1);
-		STp->logical_blk_in_buffer = 0;
+		ioctl_result = osst_seek_logical_blk(STp, &SRpnt, logical_blk_num);
+		fileno = STps->drv_file;
+		blkno  = STps->drv_block;
 		at_sm &= (arg == 0);
 		goto os_bypass;
 
@@ -3509,7 +3775,7 @@
 		cmd[4] = arg;
 #if DEBUG
 		if (debugging)
-			printk(OSST_DEB_MSG "osst%d: Spacing tape forward %d setmarks.\n", dev,
+			printk(OSST_DEB_MSG "osst%d:D: Spacing tape forward %d setmarks.\n", dev,
 		cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
 #endif
 		if (arg != 0) {
@@ -3528,33 +3794,32 @@
 		if (debugging) {
 			if (cmd[2] & 0x80)
 			   ltmp = 0xff000000;
-			 ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
-			 printk(OSST_DEB_MSG "osst%d: Spacing tape backward %ld setmarks.\n",
+			ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
+			printk(OSST_DEB_MSG "osst%d:D: Spacing tape backward %ld setmarks.\n",
 						dev, (-ltmp));
 		 }
 #endif
 		 if (arg != 0) {
 			blkno = fileno = (-1);
-			 at_sm = 1;
+			at_sm = 1;
 		 }
 		 break;
 	 case MTWEOF:
 		 if ( STps->rw == ST_WRITING && !(STp->device)->was_reset)
-			 ioctl_result = osst_flush_write_buffer(STp, &SRpnt, 1);
+			ioctl_result = osst_flush_write_buffer(STp, &SRpnt);
 		 else
-			 ioctl_result = 0;
+			ioctl_result = 0;
 		 for (i=0; i<arg; i++)
-			 ioctl_result |= osst_write_filemark(STp, &SRpnt);
-		 logical_blk_num = STp->logical_blk_num;
+			ioctl_result |= osst_write_filemark(STp, &SRpnt);
 		 if (fileno >= 0) fileno += arg;
 		 if (blkno  >= 0) blkno   = 0;
 		 goto os_bypass;
 
 	 case MTWSM:
 		 if (STp->write_prot)
-			 return (-EACCES);
+			return (-EACCES);
 		 if (!STp->raw)
-			 return 0;
+			return 0;
 		 cmd[0] = WRITE_FILEMARKS;   /* FIXME -- need OS version */
 		 if (cmd_in == MTWSM)
 			 cmd[1] = 2;
@@ -3564,16 +3829,16 @@
 		 timeout = STp->timeout;
 #if DEBUG
 		 if (debugging) {
-			 if (cmd_in == MTWEOF)
-			   printk(OSST_DEB_MSG "osst%d: Writing %d filemarks.\n", dev,
+			if (cmd_in == MTWEOF)
+			   printk(OSST_DEB_MSG "osst%d:D: Writing %d filemarks.\n", dev,
 				  cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
-			 else
-			   printk(OSST_DEB_MSG "osst%d: Writing %d setmarks.\n", dev,
+			else
+			   printk(OSST_DEB_MSG "osst%d:D: Writing %d setmarks.\n", dev,
 				  cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
 		 }
 #endif
 		 if (fileno >= 0)
-			 fileno += arg;
+			fileno += arg;
 		 blkno = 0;
 		 at_sm = (cmd_in == MTWSM);
 		 break;
@@ -3594,50 +3859,49 @@
 		 if (debugging) {
 			 switch (cmd_in) {
 				 case MTUNLOAD:
-					 printk(OSST_DEB_MSG "osst%d: Unloading tape.\n", dev);
+					 printk(OSST_DEB_MSG "osst%d:D: Unloading tape.\n", dev);
 					 break;
 				 case MTLOAD:
-					 printk(OSST_DEB_MSG "osst%d: Loading tape.\n", dev);
+					 printk(OSST_DEB_MSG "osst%d:D: Loading tape.\n", dev);
 					 break;
 				 case MTRETEN:
-					 printk(OSST_DEB_MSG "osst%d: Retensioning tape.\n", dev);
+					 printk(OSST_DEB_MSG "osst%d:D: Retensioning tape.\n", dev);
 					 break;
 				 case MTOFFL:
-					 printk(OSST_DEB_MSG "osst%d: Ejecting tape.\n", dev);
+					 printk(OSST_DEB_MSG "osst%d:D: Ejecting tape.\n", dev);
 					 break;
 			 }
 		 }
 #endif
-		 fileno = blkno = at_sm = logical_blk_num = 0 ;
+       fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
 		 break;
 	 case MTNOP:
 #if DEBUG
 		 if (debugging)
-			 printk(OSST_DEB_MSG "osst%d: No op on tape.\n", dev);
+			 printk(OSST_DEB_MSG "osst%d:D: No-op on tape.\n", dev);
 #endif
 		 return 0;  /* Should do something ? */
 		 break;
 	 case MTEOM:
 #if DEBUG
 		if (debugging)
-		   printk(OSST_DEB_MSG "osst%d: Spacing to end of recorded medium.\n", dev);
+		   printk(OSST_DEB_MSG "osst%d:D: Spacing to end of recorded medium.\n", dev);
 #endif
 		osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
-		if (osst_get_logical_blk(STp, &SRpnt, -1, 0) < 0) {
+	if (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0) {
 		   ioctl_result = -EIO;
 		   goto os_bypass;
 		}
 		if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_EOD) {
 #if DEBUG
-		   printk(OSST_DEB_MSG "osst%d: No EOD frame found where expected.\n", dev);
+		   printk(OSST_DEB_MSG "osst%d:D: No EOD frame found where expected.\n", dev);
 #endif
 		   ioctl_result = -EIO;
 		   goto os_bypass;
 		}
 		ioctl_result = osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
-		logical_blk_num = STp->logical_blk_num;
-		fileno          = STp->filemark_cnt;
-		blkno  = at_sm  = 0;
+		fileno = STp->filemark_cnt;
+		blkno  = at_sm = 0;
 		goto os_bypass;
 
 	 case MTERASE:
@@ -3648,7 +3912,7 @@
 		if (i < ioctl_result) ioctl_result = i;
 		i = osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos);
 		if (i < ioctl_result) ioctl_result = i;
-		fileno = blkno = at_sm = logical_blk_num = 0 ;
+		fileno = blkno = at_sm = 0 ;
 		goto os_bypass;
 
 	 case MTREW:
@@ -3656,9 +3920,9 @@
 		cmd[1] = 1;
 #if DEBUG
 		if (debugging)
-		   printk(OSST_DEB_MSG "osst%d: Rewinding tape, Immed=%d.\n", dev, cmd[1]);
+		   printk(OSST_DEB_MSG "osst%d:D: Rewinding tape, Immed=%d.\n", dev, cmd[1]);
 #endif
-		fileno = blkno = at_sm = logical_blk_num = 0 ;
+		fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
 		break;
 
 	 case MTLOCK:
@@ -3667,8 +3931,8 @@
 		cmd[4] = SCSI_REMOVAL_PREVENT;
 #if DEBUG
 		if (debugging)
-		    printk(OSST_DEB_MSG "osst%d: Locking drive door.\n", dev);
-#endif;
+		    printk(OSST_DEB_MSG "osst%d:D: Locking drive door.\n", dev);
+#endif
 		break;
 
 	 case MTUNLOCK:
@@ -3677,8 +3941,8 @@
 		cmd[4] = SCSI_REMOVAL_ALLOW;
 #if DEBUG
 		if (debugging)
-		   printk(OSST_DEB_MSG "osst%d: Unlocking drive door.\n", dev);
-#endif;
+		   printk(OSST_DEB_MSG "osst%d:D: Unlocking drive door.\n", dev);
+#endif
 	break;
 
 	 case MTSETBLK:           /* Set block length */
@@ -3693,10 +3957,10 @@
 		   ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
 		    (arg & MT_ST_BLKSIZE_MASK) > STp->max_block ||
 		    (arg & MT_ST_BLKSIZE_MASK) > osst_buffer_size)) {
-			 printk(KERN_WARNING "osst%d: Illegal block size.\n", dev);
+			 printk(KERN_WARNING "osst%d:W: Illegal block size.\n", dev);
 			 return (-EINVAL);
 		 }
-		 return 0;  /* silently ignore if block size didn't change */
+		 return 0;  /* FIXME silently ignore if block size didn't change */
 
 	 default:
 		return (-ENOSYS);
@@ -3708,18 +3972,23 @@
 
 	if (!SRpnt) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d: Couldn't exec scsi cmd for IOCTL\n", dev);
+		printk(OSST_DEB_MSG "osst%d:D: Couldn't exec scsi cmd for IOCTL\n", dev);
 #endif
 		return ioctl_result;
 	}
 
+	if (!ioctl_result) {  /* SCSI command successful */
+		STp->frame_seq_number = frame_seq_numbr;
+		STp->logical_blk_num  = logical_blk_num;
+	}
+
 os_bypass:
 #if DEBUG
 	if (debugging)
-		printk(OSST_DEB_MSG "osst%d: IOCTL (%d) Result=%d\n", dev, cmd_in, ioctl_result);
+		printk(OSST_DEB_MSG "osst%d:D: IOCTL (%d) Result=%d\n", dev, cmd_in, ioctl_result);
 #endif
 
-	if (!ioctl_result) {  /* SCSI command successful */
+	if (!ioctl_result) {
 
 		if (cmd_in == MTFSFM) {
 			 fileno--;
@@ -3732,7 +4001,6 @@
 		STps->drv_block = blkno;
 		STps->drv_file = fileno;
 		STps->at_sm = at_sm;
-		STp->logical_blk_num = logical_blk_num;
 
 		if (cmd_in == MTLOCK)
 			 STp->door_locked = ST_LOCKED_EXPLICIT;
@@ -3752,7 +4020,7 @@
 /*      		STp->rew_at_close = (MINOR(inode->i_rdev) & 0x80) == 0;  FIXME */
 			for (i=0; i < ST_NBR_PARTITIONS; i++) {
 			    STp->ps[i].rw = ST_IDLE;
-			    STp->ps[i].last_block_valid = FALSE;
+			    STp->ps[i].last_block_valid = FALSE;/* FIXME - where else is this field maintained? */
 			}
 			STp->partition = 0;
 		}
@@ -3826,7 +4094,7 @@
 
 	if (STp->in_use) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d: Device already in use.\n", dev);
+		printk(OSST_DEB_MSG "osst%d:D: Device already in use.\n", dev);
 #endif
 		return (-EBUSY);
 	}
@@ -3841,7 +4109,7 @@
 	if (mode != STp->current_mode) {
 #if DEBUG
 		if (debugging)
-			printk(OSST_DEB_MSG "osst%d: Mode change from %d to %d.\n",
+			printk(OSST_DEB_MSG "osst%d:D: Mode change from %d to %d.\n",
 					       dev, STp->current_mode, mode);
 #endif
 		new_session = TRUE;
@@ -3863,7 +4131,7 @@
 	if (i >= osst_nbr_buffers) {
 		STp->buffer = new_tape_buffer(FALSE, need_dma_buffer);
 		if (STp->buffer == NULL) {
-			printk(KERN_WARNING "osst%d: Can't allocate tape buffer.\n", dev);
+			printk(KERN_WARNING "osst%d:W: Can't allocate tape buffer.\n", dev);
 			retval = (-EBUSY);
 			goto err_out;
 		}
@@ -3890,7 +4158,6 @@
 		STps->rw = ST_IDLE;
 	}
 	STp->ready = ST_READY;
-	STp->recover_count = 0;
 #if DEBUG
 	STp->nbr_waits = STp->nbr_finished = 0;
 #endif
@@ -3907,7 +4174,7 @@
 	    (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY &&
 	     SRpnt->sr_sense_buffer[12]        == 4         ) {
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d: Unit not ready, cause %x\n", dev, SRpnt->sr_sense_buffer[13]);
+		printk(OSST_DEB_MSG "osst%d:D: Unit not ready, cause %x\n", dev, SRpnt->sr_sense_buffer[13]);
 #endif
 		if (SRpnt->sr_sense_buffer[13] == 2) {	/* initialize command required (LOAD) */
 			memset (cmd, 0, MAX_COMMAND_SIZE);
@@ -3922,7 +4189,7 @@
 	if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
 	    (SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d: Unit wants attention\n", dev);
+		printk(OSST_DEB_MSG "osst%d:D: Unit wants attention\n", dev);
 #endif
 		STp->header_ok = 0;
 
@@ -3944,7 +4211,7 @@
 			STp->nbr_partitions = 1;  /* This guess will be updated later if necessary */
 		for (i=0; i < ST_NBR_PARTITIONS; i++) {
 			STps = &(STp->ps[i]);
-			STps->rw = ST_IDLE;
+			STps->rw = ST_IDLE;			/* FIXME - seems to be redundant... */
 			STps->eof = ST_NOEOF;
 			STps->at_sm = 0;
 			STps->last_block_valid = FALSE;
@@ -3952,6 +4219,7 @@
 			STps->drv_file = 0 ;
 		}
 		new_session = TRUE;
+		STp->recover_count = 0;
 	}
 	/*
 	 * if we have valid headers from before, and the drive/tape seem untouched,
@@ -3974,7 +4242,7 @@
 		    STp->buffer->b_data[MODE_HEADER_LENGTH + 4] != 'N' ||
 		    STp->buffer->b_data[MODE_HEADER_LENGTH + 5] != '4'  ) {
 #if DEBUG
-			printk(OSST_DEB_MSG "osst%d: signature was changed to %c%c%c%c\n", dev,
+			printk(OSST_DEB_MSG "osst%d:D: Signature was changed to %c%c%c%c\n", dev,
 			  STp->buffer->b_data[MODE_HEADER_LENGTH + 2],
 			  STp->buffer->b_data[MODE_HEADER_LENGTH + 3],
 			  STp->buffer->b_data[MODE_HEADER_LENGTH + 4],
@@ -3986,17 +4254,23 @@
 		if (STp->header_ok && i == osst_get_frame_position(STp, &SRpnt)) {
 			if (STp->door_locked == ST_UNLOCKED) {
 				if (osst_int_ioctl(STp, &SRpnt, MTLOCK, 0))
-					printk(KERN_WARNING "osst%d: Can't lock drive door\n", dev);
+					printk(KERN_INFO "osst%d:I: Can't lock drive door\n", dev);
 				else
 					STp->door_locked = ST_LOCKED_AUTO;
 			}
+			if (!STp->frame_in_buffer) {
+				STp->block_size = (STp->raw) ? OS_FRAME_SIZE : (
+					    (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE);
+				STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
+			}
+			STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size;
 			STp->fast_open = TRUE;
 			scsi_release_request(SRpnt);
 			return 0;
 		}
 #if DEBUG
 		if (i != STp->first_frame_position)
-			printk(OSST_DEB_MSG "osst%d: tape position changed from %d to %d\n",
+			printk(OSST_DEB_MSG "osst%d:D: Tape position changed from %d to %d\n",
 						dev, i, STp->first_frame_position);
 #endif
 		STp->header_ok = 0;
@@ -4020,8 +4294,8 @@
 		(STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 2;
 		(STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3;
 
-#if 1 //DEBUG
-		printk(OSST_DEB_MSG "osst%i: Applying soft reset\n", dev);
+#if DEBUG
+		printk(OSST_DEB_MSG "osst%d:D: Applying soft reset\n", dev);
 #endif
 		SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE);
 
@@ -4058,7 +4332,7 @@
 	}
 
 	if (osst_wait_ready(STp, &SRpnt, 15 * 60))		/* FIXME - not allowed with NOBLOCK */
-		 printk(KERN_WARNING "osst%i: Device did not become Ready in open\n",dev);
+		 printk(KERN_INFO "osst%i:I: Device did not become Ready in open\n",dev);
 
 	if ((STp->buffer)->syscall_result != 0) {
 		if ((STp->device)->scsi_level >= SCSI_2 &&
@@ -4087,7 +4361,7 @@
 
 	if (OS_FRAME_SIZE > (STp->buffer)->buffer_size &&
 	    !enlarge_buffer(STp->buffer, OS_FRAME_SIZE, STp->restr_dma)) {
-		printk(KERN_NOTICE "osst%d: Framesize %d too large for buffer.\n", dev,
+		printk(KERN_NOTICE "osst%d:A: Framesize %d too large for buffer.\n", dev,
 				     OS_FRAME_SIZE);
 		retval = (-EIO);
 		goto err_out;
@@ -4099,22 +4373,26 @@
 		     b_size += STp->buffer->sg[i++].length);
 		STp->buffer->aux = (os_aux_t *) (STp->buffer->sg[i].address + OS_DATA_SIZE - b_size);
 #if DEBUG
-		printk(OSST_DEB_MSG "osst%d: b_data points to %p in segment 0 at %p\n", dev,
+		printk(OSST_DEB_MSG "osst%d:D: b_data points to %p in segment 0 at %p\n", dev,
 			STp->buffer->b_data, STp->buffer->sg[0].address);
-		printk(OSST_DEB_MSG "osst%d: AUX points to %p in segment %d at %p\n", dev,
+		printk(OSST_DEB_MSG "osst%d:D: AUX points to %p in segment %d at %p\n", dev,
 			 STp->buffer->aux, i, STp->buffer->sg[i].address);
 #endif
 	} else
 		STp->buffer->aux = NULL; /* this had better never happen! */
 
-	(STp->buffer)->buffer_blocks = 1;
-	(STp->buffer)->buffer_bytes  =
-	(STp->buffer)->read_pointer  =
-	STp->logical_blk_in_buffer   = 0;
+	STp->block_size = (STp->raw) ? OS_FRAME_SIZE : (
+			     (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE);
+	STp->min_block  = 512;
+	STp->max_block  = OS_DATA_SIZE;
+	STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size;
+	STp->buffer->buffer_bytes  =
+	STp->buffer->read_pointer  =
+	STp->frame_in_buffer       = 0;
 
 #if DEBUG
 	if (debugging)
-		printk(OSST_DEB_MSG "osst%d: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n",
+		printk(OSST_DEB_MSG "osst%d:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n",
 		     dev, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size,
 		     (STp->buffer)->buffer_blocks);
 #endif
@@ -4123,7 +4401,7 @@
 		STp->write_prot = 1;
 #if DEBUG
 		if (debugging)
-			printk(OSST_DEB_MSG "osst%d: Write protected\n", dev);
+			printk(OSST_DEB_MSG "osst%d:D: Write protected\n", dev);
 #endif
 		if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) {
 			retval = (-EROFS);
@@ -4134,7 +4412,7 @@
 	if (new_session) {  /* Change the drive parameters for the new mode */
 #if DEBUG
 		if (debugging)
-	printk(OSST_DEB_MSG "osst%d: New Session\n", dev);
+	printk(OSST_DEB_MSG "osst%d:D: New Session\n", dev);
 #endif
 		STp->density_changed = STp->blksize_changed = FALSE;
 		STp->compression_changed = FALSE;
@@ -4145,7 +4423,7 @@
 	 */
 	if (STp->door_locked == ST_UNLOCKED) {
 		 if (osst_int_ioctl(STp, &SRpnt, MTLOCK, 0))
-			printk(KERN_WARNING "osst%d: Can't lock drive door\n", dev);
+			printk(KERN_INFO "osst%d:I: Can't lock drive door\n", dev);
 		 else
 			STp->door_locked = ST_LOCKED_AUTO;
 	}
@@ -4197,18 +4475,17 @@
 	STps = &(STp->ps[STp->partition]);
 
 	if ( STps->rw == ST_WRITING && !(STp->device)->was_reset) {
-		result = osst_flush_write_buffer(STp, &SRpnt, 1);
+		result = osst_flush_write_buffer(STp, &SRpnt);
 		if (result != 0 && result != (-ENOSPC))
-	  goto out;
+			goto out;
 	}
-
 	if ( STps->rw == ST_WRITING && !(STp->device)->was_reset) {
 
 #if DEBUG
 		if (debugging) {
-			printk(OSST_DEB_MSG "osst%d: File length %ld bytes.\n",
+			printk(OSST_DEB_MSG "osst%d:D: File length %ld bytes.\n",
 					       dev, (long)(filp->f_pos));
-			printk(OSST_DEB_MSG "osst%d: Async write waits %d, finished %d.\n",
+			printk(OSST_DEB_MSG "osst%d:D: Async write waits %d, finished %d.\n",
 					       dev, STp->nbr_waits, STp->nbr_finished);
 		}
 #endif
@@ -4229,7 +4506,7 @@
 
 #if DEBUG
 		if (debugging)
-			printk(OSST_DEB_MSG "osst%d: Buffer flushed, %d EOF(s) written\n",
+			printk(OSST_DEB_MSG "osst%d:D: Buffer flushed, %d EOF(s) written\n",
 					       dev, 1+STp->two_fm);
 #endif
 	}
@@ -4237,7 +4514,7 @@
 		STps = &(STp->ps[STp->partition]);
 		if (!STm->sysv || STps->rw != ST_READING) {
 			if (STp->can_bsr)
-				result = osst_flush_buffer(STp, &SRpnt, 0);
+		result = osst_flush_buffer(STp, &SRpnt, 0);	/* this is the default path */
 			else if (STps->eof == ST_FM_HIT) {
 				result = cross_eof(STp, &SRpnt, FALSE);
 					if (result) {
@@ -4263,12 +4540,24 @@
 out:
 	if (STp->rew_at_close) {
 		result2 = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
-		STps->drv_file = STps->drv_block = STp->logical_blk_num = 0;
-		if (result == 0)
+		STps->drv_file = STps->drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
+		if (result == 0 && result2 < 0)
 			result = result2;
 	}
 	if (SRpnt) scsi_release_request(SRpnt);
 
+	if (STp->recover_count) {
+		printk(KERN_INFO "osst%d:I: %d recovered errors in", dev, STp->recover_count);
+		if (STp->write_count)
+			printk(" %d frames written", STp->write_count);
+		if (STp->read_count)
+			printk(" %d frames read", STp->read_count);
+		printk("\n");
+		STp->recover_count = 0;
+	}
+	STp->write_count = 0;
+	STp->read_count  = 0;
+
 	return result;
 }
 
@@ -4322,7 +4611,7 @@
 
 #if DEBUG
 	if (debugging && !STp->in_use) {
-		printk(OSST_DEB_MSG "osst%d: Incorrect device.\n", dev);
+		printk(OSST_DEB_MSG "osst%d:D: Incorrect device.\n", dev);
 		retval = (-EIO);
 		goto out;
 	}
@@ -4359,7 +4648,7 @@
 		}
 
 		if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
-			printk(KERN_WARNING "osst%d: MTSETDRVBUFFER only allowed for root.\n", dev);
+			printk(KERN_WARNING "osst%d:W: MTSETDRVBUFFER only allowed for root.\n", dev);
 			retval = (-EPERM);
 			goto out;
 		}
@@ -4419,7 +4708,7 @@
 			if (STp->door_locked != ST_UNLOCKED &&
 			    STp->door_locked != ST_LOCK_FAILS) {
 				if (osst_int_ioctl(STp, &SRpnt, MTLOCK, 0)) {
-					printk(KERN_NOTICE "osst%d: Could not relock door after bus reset.\n",
+					printk(KERN_NOTICE "osst%d:I: Could not relock door after bus reset.\n",
 								  dev);
 					STp->door_locked = ST_UNLOCKED;
 				}
@@ -4479,7 +4768,7 @@
 	 	}
 
 		if (mtc.mt_op == MTSEEK) {
-			i = osst_seek_frame(STp, &SRpnt, mtc.mt_count);
+			i = osst_seek_sector(STp, &SRpnt, mtc.mt_count);
 			if (!STp->can_partitions)
 				STp->ps[0].rw = ST_IDLE;
 			retval = i;
@@ -4584,7 +4873,7 @@
 			retval = (-EINVAL);
 			goto out;
 		}
-		blk = osst_get_frame_position(STp, &SRpnt);
+		blk = osst_get_sector(STp, &SRpnt);
 		if (blk < 0) {
 			retval = blk;
 			goto out;
@@ -4687,7 +4976,7 @@
 		}
 	}
 	if (!tb) {
-		printk(KERN_NOTICE "osst: Can't allocate new tape buffer (nbr %d).\n",
+		printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer (nbr %d).\n",
 				   osst_nbr_buffers);
 		return NULL;
 	}
@@ -4697,10 +4986,10 @@
 #if DEBUG
 	if (debugging) {
 		printk(OSST_DEB_MSG
-			"osst: Allocated tape buffer %d (%d bytes, %d segments, dma: %d, a: %p).\n",
+			"osst :D: Allocated tape buffer %d (%d bytes, %d segments, dma: %d, a: %p).\n",
 			   osst_nbr_buffers, got, tb->sg_segs, need_dma, tb->b_data);
 		printk(OSST_DEB_MSG
-			"osst: segment sizes: first %d, last %d bytes.\n",
+			"osst :D: segment sizes: first %d, last %d bytes.\n",
 			   tb->sg[0].length, tb->sg[segs-1].length);
 	}
 #endif
@@ -4745,7 +5034,7 @@
 				order--;
 				continue;
 			}
-			printk(KERN_NOTICE "osst: Failed to enlarge buffer to %d bytes.\n",
+			printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n",
 						new_size);
 #if DEBUG
 			STbuffer->buffer_size = got;
@@ -4764,10 +5053,10 @@
 	if (debugging) {
 		for (nbr=0; osst_buffers[nbr] != STbuffer && nbr < osst_nbr_buffers; nbr++);
 			printk(OSST_DEB_MSG
-	"osst: Expanded tape buffer %d (%d bytes, %d->%d segments, dma: %d, a: %p).\n",
+			   "osst :D: Expanded tape buffer %d (%d bytes, %d->%d segments, dma: %d, a: %p).\n",
 			   nbr, got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data);
 			printk(OSST_DEB_MSG
-			   "osst: segment sizes: first %d, last %d bytes.\n",
+			   "osst :D: segment sizes: first %d, last %d bytes.\n",
 			   STbuffer->sg[0].length, STbuffer->sg[segs-1].length);
 	}
 #endif
@@ -4792,7 +5081,7 @@
 	}
 #if DEBUG
 	if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs)
-		printk(OSST_DEB_MSG "osst: Buffer at %p normalized to %d bytes (segs %d).\n",
+		printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).\n",
 			     STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs);
 #endif
 	STbuffer->sg_segs = STbuffer->orig_sg_segs;
@@ -4809,7 +5098,7 @@
 	     i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
 	offset -= st_bp->sg[i].length;
 	if (i == st_bp->sg_segs) {  /* Should never happen */
-		printk(KERN_WARNING "osst: Append_to_buffer offset overflow.\n");
+		printk(KERN_WARNING "osst :A: Append_to_buffer offset overflow.\n");
 		return (-EIO);
 	}
 	for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
@@ -4824,7 +5113,7 @@
 		offset = 0;
 	}
 	if (do_count) {  /* Should never happen */
-		printk(KERN_WARNING "osst: Append_to_buffer overflow (left %d).\n",
+		printk(KERN_WARNING "osst :A: Append_to_buffer overflow (left %d).\n",
 		       do_count);
 		return (-EIO);
 	}
@@ -4842,7 +5131,7 @@
 	     i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
 		offset -= st_bp->sg[i].length;
 	if (i == st_bp->sg_segs) {  /* Should never happen */
-		printk(KERN_WARNING "osst: From_buffer offset overflow.\n");
+		printk(KERN_WARNING "osst :A: From_buffer offset overflow.\n");
 		return (-EIO);
 	}
 	for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
@@ -4858,7 +5147,7 @@
 		offset = 0;
 	}
 	if (do_count) {  /* Should never happen */
-		printk(KERN_WARNING "osst: From_buffer overflow (left %d).\n", do_count);
+		printk(KERN_WARNING "osst :A: From_buffer overflow (left %d).\n", do_count);
 		return (-EIO);
 	}
 	return 0;
@@ -4874,10 +5163,10 @@
 	     i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
 		offset -= st_bp->sg[i].length;
 	if (i == st_bp->sg_segs) {  /* Should never happen */
-		printk(KERN_WARNING "osst: Zero_buffer offset overflow.\n");
+		printk(KERN_WARNING "osst :A: Zero_buffer offset overflow.\n");
 		return (-EIO);
 	}
-	for (do_count = OS_DATA_SIZE - st_bp->read_pointer;
+	for (do_count = OS_DATA_SIZE - st_bp->buffer_bytes;
 	     i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length - offset < do_count ?
 		      st_bp->sg[i].length - offset : do_count ;
@@ -4886,13 +5175,13 @@
 		offset = 0;
 	}
 	if (do_count) {  /* Should never happen */
-		printk(KERN_WARNING "osst: Zero_buffer overflow (left %d).\n", do_count);
+		printk(KERN_WARNING "osst :A: Zero_buffer overflow (left %d).\n", do_count);
 		return (-EIO);
 	}
 	return 0;
 }
 
-/* Copy a osst 32K block of memory into the buffer.
+/* Copy a osst 32K chunk of memory into the buffer.
    Returns zero (success) or negative error code.  */
 static int osst_copy_to_buffer(OSST_buffer *st_bp, unsigned char *ptr)
 {
@@ -4906,14 +5195,14 @@
 		ptr      += cnt;
 	}
 	if (do_count || i != st_bp->sg_segs-1) {  /* Should never happen */
-		printk(KERN_WARNING "osst: Copy_to_buffer overflow (left %d at sg %d).\n",
+		printk(KERN_WARNING "osst :A: Copy_to_buffer overflow (left %d at sg %d).\n",
 					 do_count, i);
 		return (-EIO);
 	}
 	return 0;
 }
 
-/* Copy a osst 32K block of memory from the buffer.
+/* Copy a osst 32K chunk of memory from the buffer.
    Returns zero (success) or negative error code.  */
 static int osst_copy_from_buffer(OSST_buffer *st_bp, unsigned char *ptr)
 {
@@ -4927,7 +5216,7 @@
 		ptr      += cnt;
 	}
 	if (do_count || i != st_bp->sg_segs-1) {  /* Should never happen */
-		printk(KERN_WARNING "osst: Copy_from_buffer overflow (left %d at sg %d).\n",
+		printk(KERN_WARNING "osst :A: Copy_from_buffer overflow (left %d at sg %d).\n",
 					 do_count, i);
 		return (-EIO);
 	}
@@ -4949,9 +5238,12 @@
 		osst_max_buffers = max_buffers;
   if (max_sg_segs >= OSST_FIRST_SG)
 		osst_max_sg_segs = max_sg_segs;
-  printk(KERN_INFO "osst: bufsize %d, wrt %d, max buffers %d, s/g segs %d.\n",
+#if DEBUG
+  printk(OSST_DEB_MSG "osst :D: bufsize %d, wrt %d, max buffers %d, s/g segs %d.\n",
 	 osst_buffer_size, osst_write_threshold, osst_max_buffers, osst_max_sg_segs);
-//printk(OSST_DEB_MSG "osst: sizeof(header) = %d (%s)\n",sizeof(os_header_t),sizeof(os_header_t)==OS_DATA_SIZE?"ok":"error");
+//printk(OSST_DEB_MSG "osst :D: sizeof(header) = %d (%s)\n",
+//		sizeof(os_header_t),sizeof(os_header_t)==OS_DATA_SIZE?"ok":"error");
+#endif
 }
 	
 #ifndef MODULE
@@ -4980,7 +5272,7 @@
 			}
 		}
 		if (i >= sizeof(parms) / sizeof(struct osst_dev_parm))
-			printk(KERN_WARNING "osst: illegal parameter in '%s'\n",
+			printk(KERN_INFO "osst :I: Illegal parameter in '%s'\n",
 			       stp);
 		stp = strchr(stp, ',');
 		if (stp)
@@ -5038,7 +5330,7 @@
 	OS_Scsi_Tape * tpnt;
 	ST_mode * STm;
 	ST_partstat * STps;
-	int i;
+	int i, dev;
 #ifdef CONFIG_DEVFS_FS
 	int mode;
 #endif
@@ -5059,16 +5351,17 @@
 	tpnt = (OS_Scsi_Tape *)kmalloc(sizeof(OS_Scsi_Tape), GFP_ATOMIC);
 	if (tpnt == NULL) {
 		 SDp->attached--;
-		 printk(KERN_ERR "osst: Can't allocate device descriptor.\n");
+		 printk(KERN_WARNING "osst :W: Can't allocate device descriptor.\n");
 		 return 1;
 	}
 	memset(tpnt, 0, sizeof(OS_Scsi_Tape));
 	os_scsi_tapes[i] = tpnt;
+	dev = i;
 	tpnt->capacity = 0xfffff;
 
 	/* allocate a buffer for this device */
 	if (!new_tape_buffer(TRUE, TRUE)) 
-		 printk(KERN_ERR "osst: Unable to allocate a tape buffer.\n");
+		 printk(KERN_ERR "osst :W: Unable to allocate a tape buffer.\n");
 
 #ifdef CONFIG_DEVFS_FS
 	for (mode = 0; mode < ST_NBR_MODES; ++mode) {
@@ -5131,17 +5424,12 @@
 	tpnt->long_timeout = OSST_LONG_TIMEOUT;
 
 	/* Recognize OnStream tapes */
-	printk ("osst%i: Tape driver with OnStream support osst %s\nosst%i: %s\n",
-	       i, osst_version, i, cvsid);
 	/* We don't need to test for OnStream, as this has been done in detect () */
 	tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev);
-#if DEBUG
-	printk ("osst%i: OnStream tape drive recognized, Model %s\n", i, SDp->model);
-#endif
 	tpnt->omit_blklims = 1;
 
 	tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp);
-	tpnt->logical_blk_in_buffer = 0;
+	tpnt->frame_in_buffer = 0;
 	tpnt->header_ok = 0;
 	tpnt->linux_media = 0;
 	tpnt->header_cache = NULL;
@@ -5155,7 +5443,7 @@
 		STm->do_buffer_writes = OSST_BUFFER_WRITES;
 		STm->do_read_ahead = OSST_READ_AHEAD;
 		STm->default_compression = ST_DONT_TOUCH;
-		STm->default_blksize = 32 * ST_KILOBYTE;  /* No forced size */
+		STm->default_blksize = 512;
 		STm->default_density = (-1);  /* No forced density */
 	}
 
@@ -5175,6 +5463,11 @@
 	init_MUTEX(&tpnt->lock);
 
 	osst_template.nr_dev++;
+
+	printk(KERN_INFO
+		"osst :I: Attached OnStream %.5s tape at scsi%d, channel %d, id %d, lun %d as osst%d\n",
+		SDp->model, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun, dev);
+
 	return 0;
 };
 
@@ -5183,10 +5476,7 @@
 	if (SDp->type != TYPE_TAPE) return 0;
 	if ( ! osst_supports(SDp) ) return 0;
 	
-	printk(KERN_WARNING
-		"Detected OnStream scsi tape osst%d at scsi%d, channel %d, id %d, lun %d\n",
-		osst_template.dev_noticed++,
-		SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
+	osst_template.dev_noticed++;
 	return 1;
 }
 
@@ -5205,7 +5495,7 @@
 #else
 	if (register_chrdev(MAJOR_NR,"osst",&osst_fops)) {
 #endif
-		printk(KERN_ERR "osst: Unable to get major %d for OnStream tapes\n",MAJOR_NR);
+		printk(KERN_ERR "osst :W: Unable to get major %d for OnStream tapes\n",MAJOR_NR);
 		return 1;
 	}
 	osst_registered++;
@@ -5214,12 +5504,12 @@
   if (os_scsi_tapes) return 0;
   osst_template.dev_max = OSST_MAX_TAPES;
   if (osst_template.dev_max > 128 / ST_NBR_MODES)
-	printk(KERN_INFO "osst: Only %d tapes accessible.\n", 128 / ST_NBR_MODES);
+	printk(KERN_INFO "osst :I: Only %d tapes accessible.\n", 128 / ST_NBR_MODES);
   os_scsi_tapes =
 	(OS_Scsi_Tape **)kmalloc(osst_template.dev_max * sizeof(OS_Scsi_Tape *),
 				   GFP_ATOMIC);
   if (os_scsi_tapes == NULL) {
-	printk(KERN_ERR "osst: Unable to allocate array for OnStream SCSI tapes.\n");
+	printk(KERN_ERR "osst :W: Unable to allocate array for OnStream SCSI tapes.\n");
 #ifdef CONFIG_DEVFS_FS
 	devfs_unregister_chrdev(MAJOR_NR, "osst");
 #else
@@ -5235,7 +5525,7 @@
 	(OSST_buffer **)kmalloc(osst_template.dev_max * sizeof(OSST_buffer *),
 				    GFP_ATOMIC);
   if (osst_buffers == NULL) {
-	printk(KERN_ERR "osst: Unable to allocate tape buffer pointers.\n");
+	printk(KERN_ERR "osst :W: Unable to allocate tape buffer pointers.\n");
 #ifdef CONFIG_DEVFS_FS
 	devfs_unregister_chrdev(MAJOR_NR, "osst");
 #else
@@ -5246,8 +5536,10 @@
   }
   osst_nbr_buffers = 0;
 
+  printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
+
 #if DEBUG
-  printk(OSST_DEB_MSG "osst: Buffer size %d bytes, write threshold %d bytes.\n",
+  printk(OSST_DEB_MSG "osst :D: Buffer size %d bytes, write threshold %d bytes.\n",
 	 osst_buffer_size, osst_write_threshold);
 #endif
   return 0;
@@ -5287,9 +5579,9 @@
 
 static int __init init_osst(void) 
 {
-  validate_options();
-  osst_template.module = THIS_MODULE;
-  return scsi_register_module(MODULE_SCSI_DEV, &osst_template);
+	validate_options();
+	osst_template.module = THIS_MODULE;
+	return scsi_register_module(MODULE_SCSI_DEV, &osst_template);
 }
 
 static void __exit exit_osst (void)
@@ -5325,7 +5617,7 @@
 	}
   }
   osst_template.dev_max = 0;
-  printk(KERN_INFO "osst: Unloaded.\n");
+  printk(KERN_INFO "osst :I: Unloaded.\n");
 }
 
 module_init(init_osst);
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/osst.h linux/drivers/scsi/osst.h
--- v2.4.5/linux/drivers/scsi/osst.h	Sat Dec 30 11:23:14 2000
+++ linux/drivers/scsi/osst.h	Mon Jun 11 19:15:27 2001
@@ -1,5 +1,5 @@
 /*
- *	$Header: /home/cvsroot/Driver/osst.h,v 1.9 2000/10/08 03:09:43 riede Exp $
+ *	$Header: /home/cvsroot/Driver/osst.h,v 1.11 2001/01/26 01:54:49 riede Exp $
  */
 
 #include <asm/byteorder.h>
@@ -440,7 +440,8 @@
          * Linux specific fields:
          */
          __u32          next_mark_ppos;         /* when known, points to next marker */
-         __u8           linux_specific[28];
+	 __u32		last_mark_lbn;		/* storing log_blk_num of last mark is extends ADR spec */
+         __u8           linux_specific[24];
 
         __u8            reserved_256_511[256];
 } os_aux_t;
@@ -581,6 +582,8 @@
   int min_block;
   int max_block;
   int recover_count;            /* from tape opening */
+  int write_count;
+  int read_count;
   int recover_erreg;            /* from last status call */
   /*
    * OnStream specific data
@@ -588,8 +591,9 @@
   int	   os_fw_rev;			       /* the firmware revision * 10000 */
   unsigned char  raw;                          /* flag OnStream raw access (32.5KB block size) */
   unsigned char  poll;                         /* flag that this drive needs polling (IDE|firmware) */
-  unsigned char  logical_blk_in_buffer;	       /* flag that the block as per logical_blk_num
+  unsigned char  frame_in_buffer;	       /* flag that the frame as per frame_seq_number
 						* has been read into STp->buffer and is valid */
+  int      frame_seq_number;                   /* logical frame number */
   int      logical_blk_num;                    /* logical block number */
   unsigned first_frame_position;               /* physical frame to be transfered to/from host */
   unsigned last_frame_position;                /* physical frame to be transferd to/from tape */
@@ -607,6 +611,7 @@
   int      filemark_cnt;
   int      first_mark_ppos;
   int      last_mark_ppos;
+  int      last_mark_lbn;			/* storing log_blk_num of last mark is extends ADR spec */
   int      first_data_ppos;
   int      eod_frame_ppos;
   int      eod_frame_lfa;
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/osst_options.h linux/drivers/scsi/osst_options.h
--- v2.4.5/linux/drivers/scsi/osst_options.h	Sat Dec 30 11:23:14 2000
+++ linux/drivers/scsi/osst_options.h	Mon Jun 11 19:15:27 2001
@@ -8,7 +8,7 @@
    Changed (and renamed) for OnStream SCSI drives garloff@suse.de
    2000-06-21
 
-   $Header: /home/cvsroot/Driver/osst_options.h,v 1.4 2000/06/26 01:44:01 riede Exp $
+   $Header: /home/cvsroot/Driver/osst_options.h,v 1.5 2001/01/07 22:19:15 riede Exp $
 */
 
 #ifndef _OSST_OPTIONS_H
@@ -24,7 +24,7 @@
    because of buffered reads. Should be set to zero to support also drives
    that can't space backwards over records. NOTE: The tape will be
    spaced backwards over an "accidentally" crossed filemark in any case. */
-#define OSST_IN_FILE_POS 0
+#define OSST_IN_FILE_POS 1
 
 /* The tape driver buffer size in kilobytes. */
 /* Don't change, as this is the HW blocksize */
@@ -33,7 +33,13 @@
 /* The number of kilobytes of data in the buffer that triggers an
    asynchronous write in fixed block mode. See also OSST_ASYNC_WRITES
    below. */
-#define OSST_WRITE_THRESHOLD_BLOCKS 30
+#define OSST_WRITE_THRESHOLD_BLOCKS 32
+
+/* OSST_EOM_RESERVE defines the number of frames are kept in reserve for
+ *  * write error recovery when writing near end of medium. ENOSPC is returned
+ *   * when write() is called and the tape write position is within this number
+ *    * of blocks from the tape capacity. */
+#define OSST_EOM_RESERVE 300
 
 /* The maximum number of tape buffers the driver allocates. The number
    is also constrained by the number of drives detected. Determines the
@@ -64,7 +70,7 @@
 
 /* If OSST_BUFFER_WRITES is non-zero, writes in fixed block mode are
    buffered until the driver buffer is full or asynchronous write is
-   triggered. May make detection of End-Of-Medium early enough fail. */
+   triggered. */
 #define OSST_BUFFER_WRITES 1
 
 /* If OSST_ASYNC_WRITES is non-zero, the SCSI write command may be started
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/qla1280.c linux/drivers/scsi/qla1280.c
--- v2.4.5/linux/drivers/scsi/qla1280.c	Fri Apr 27 13:59:19 2001
+++ linux/drivers/scsi/qla1280.c	Wed Jun 27 17:10:55 2001
@@ -1528,6 +1528,7 @@
     if(test_and_set_bit(QLA1280_IN_ISR_BIT, &ha->flags))
     {
         COMTRACE('X')
+        spin_unlock_irqrestore(&io_request_lock, cpu_flags);
         return;
     }
     ha->isr_count++;
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/qlogicisp.c linux/drivers/scsi/qlogicisp.c
--- v2.4.5/linux/drivers/scsi/qlogicisp.c	Fri Apr 27 13:59:19 2001
+++ linux/drivers/scsi/qlogicisp.c	Wed Jun 20 11:10:27 2001
@@ -62,8 +62,6 @@
 
 #define DEFAULT_LOOP_COUNT	1000000
 
-#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
-
 /* End Configuration section *************************************************/
 
 #include <linux/module.h>
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/qlogicpti.c linux/drivers/scsi/qlogicpti.c
--- v2.4.5/linux/drivers/scsi/qlogicpti.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/scsi/qlogicpti.c	Mon Jun 11 19:15:27 2001
@@ -819,7 +819,8 @@
 			/* Is this a red snapper? */
 			if (strcmp(sdev->prom_name, "ptisp") &&
 			    strcmp(sdev->prom_name, "PTI,ptisp") &&
-			    strcmp(sdev->prom_name, "QLGC,isp"))
+			    strcmp(sdev->prom_name, "QLGC,isp") &&
+			    strcmp(sdev->prom_name, "SUNW,isp"))
 				continue;
 
 			/* Sometimes Antares cards come up not completely
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v2.4.5/linux/drivers/scsi/scsi.c	Thu May 24 15:34:14 2001
+++ linux/drivers/scsi/scsi.c	Tue Jun 12 11:06:54 2001
@@ -2356,8 +2356,8 @@
 		/* The rest of these are not yet implemented. */
 	case MODULE_SCSI_CONST:
 	case MODULE_SCSI_IOCTL:
-		break;
 	default:
+		break;
 	}
 	return;
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/scsi_ioctl.c linux/drivers/scsi/scsi_ioctl.c
--- v2.4.5/linux/drivers/scsi/scsi_ioctl.c	Fri Apr 27 13:59:19 2001
+++ linux/drivers/scsi/scsi_ioctl.c	Mon Jun 11 19:15:27 2001
@@ -312,17 +312,17 @@
 	/* 
 	 * If there was an error condition, pass the info back to the user. 
 	 */
+	result = SRpnt->sr_result;
 	if (SRpnt->sr_result) {
 		int sb_len = sizeof(SRpnt->sr_sense_buffer);
 
 		sb_len = (sb_len > OMAX_SB_LEN) ? OMAX_SB_LEN : sb_len;
 		if (copy_to_user(cmd_in, SRpnt->sr_sense_buffer, sb_len))
-			return -EFAULT;
-	} else
+			result = -EFAULT;
+	} else {
 		if (copy_to_user(cmd_in, buf, outlen))
-			return -EFAULT;
-
-	result = SRpnt->sr_result;
+			result = -EFAULT;
+	}
 
 	SDpnt = SRpnt->sr_device;
 	scsi_release_request(SRpnt);
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/scsi_proc.c linux/drivers/scsi/scsi_proc.c
--- v2.4.5/linux/drivers/scsi/scsi_proc.c	Sat May 19 17:43:06 2001
+++ linux/drivers/scsi/scsi_proc.c	Wed Jun 27 17:10:55 2001
@@ -99,6 +99,9 @@
 	char * page;
 	char *start;
     
+	if (hpnt->hostt->proc_info == NULL)
+		ret = -ENOSYS;
+
 	if (count > PROC_BLOCK_SIZE)
 		return -EOVERFLOW;
 
@@ -110,11 +113,9 @@
 		return -EFAULT;
 	}
 
-	if (hpnt->hostt->proc_info == NULL)
-		ret = -ENOSYS;
-	else
-		ret = hpnt->hostt->proc_info(page, &start, 0, count,
-						hpnt->host_no, 1);
+	ret = hpnt->hostt->proc_info(page, &start, 0, count,
+				     hpnt->host_no, 1);
+
 	free_page((ulong) page);
 	return(ret);
 }
@@ -125,6 +126,10 @@
 	char name[10];	/* see scsi_unregister_host() */
 
 	tpnt->proc_dir = proc_mkdir(tpnt->proc_name, proc_scsi);
+        if (!tpnt->proc_dir) {
+                printk(KERN_ERR "Unable to proc_mkdir in scsi.c/build_proc_dir_entries");
+                return;
+        }
 	tpnt->proc_dir->owner = tpnt->module;
 
 	hpnt = scsi_hostlist;
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/scsi_scan.c linux/drivers/scsi/scsi_scan.c
--- v2.4.5/linux/drivers/scsi/scsi_scan.c	Sun Apr  8 10:10:01 2001
+++ linux/drivers/scsi/scsi_scan.c	Tue Jun 12 11:17:17 2001
@@ -328,8 +328,8 @@
 	}
 
 	/*
-	 * We need to increment the counter for this one device so we can track when
-	 * things are quiet.
+	 * We need to increment the counter for this one device so we can track
+	 * when things are quiet.
 	 */
 	if (hardcoded == 1) {
 		Scsi_Device *oldSDpnt = SDpnt;
@@ -485,8 +485,8 @@
 	SDpnt->type = -1;
 
 	/*
-	 * Assume that the device will have handshaking problems, and then fix this
-	 * field later if it turns out it doesn't
+	 * Assume that the device will have handshaking problems, and then fix
+	 * this field later if it turns out it doesn't
 	 */
 	SDpnt->borken = 1;
 	SDpnt->was_reset = 0;
@@ -524,9 +524,21 @@
 	SCSI_LOG_SCAN_BUS(3, printk("scsi: INQUIRY %s with code 0x%x\n",
 		SRpnt->sr_result ? "failed" : "successful", SRpnt->sr_result));
 
+	/*
+	 * Now that we don't do TEST_UNIT_READY anymore, we must be prepared
+	 * for media change conditions here, so cannot require zero result.
+	 */
 	if (SRpnt->sr_result) {
-		scsi_release_request(SRpnt);
-		return 0;	/* assume no peripheral if any sort of error */
+		if ((driver_byte(SRpnt->sr_result) & DRIVER_SENSE) != 0 &&
+		    (SRpnt->sr_sense_buffer[2] & 0xf) == UNIT_ATTENTION &&
+		    SRpnt->sr_sense_buffer[12] == 0x28 &&
+		    SRpnt->sr_sense_buffer[13] == 0) {
+			/* not-ready to ready transition - good */
+		} else {
+			/* assume no peripheral if any other sort of error */
+			scsi_release_request(SRpnt);
+			return 0;
+		}
 	}
 
 	/*
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- v2.4.5/linux/drivers/scsi/sd.c	Fri May 25 09:54:50 2001
+++ linux/drivers/scsi/sd.c	Tue Jun 12 11:17:17 2001
@@ -861,8 +861,7 @@
 		       driver_byte(the_result)
 		    );
 		if (driver_byte(the_result) & DRIVER_SENSE)
-			printk("%s : extended sense code = %1x \n",
-			       nbuff, SRpnt->sr_sense_buffer[2] & 0xf);
+			print_req_sense("sd", SRpnt);
 		else
 			printk("%s : sense not available. \n", nbuff);
 
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/sym53c416.c linux/drivers/scsi/sym53c416.c
--- v2.4.5/linux/drivers/scsi/sym53c416.c	Tue Mar  6 19:44:37 2001
+++ linux/drivers/scsi/sym53c416.c	Wed Jun 27 17:10:55 2001
@@ -6,6 +6,9 @@
  *  Changes : 
  * 
  *  Marcelo Tosatti <marcelo@conectiva.com.br> : Added io_request_lock locking
+ *  Alan Cox <alan@redhat.com> : Cleaned up code formatting
+ *				 Fixed an irq locking bug
+ *				 Added ISAPnP support
  * 
  *  LILO command line usage: sym53c416=<PORTBASE>[,<IRQ>]
  *
@@ -36,12 +39,13 @@
 #include <asm/io.h>
 #include <linux/blk.h>
 #include <linux/version.h>
+#include <linux/isapnp.h>
 #include "scsi.h"
 #include "hosts.h"
 #include "sd.h"
 #include "sym53c416.h"
 
-#define VERSION_STRING        "Version 1.0.0"
+#define VERSION_STRING        "Version 1.0.0-ac"
 
 #define TC_LOW       0x00     /* Transfer counter low        */
 #define TC_MID       0x01     /* Transfer counter mid        */
@@ -203,24 +207,24 @@
 #define MAXHOSTS 4
 
 enum phases
-  {
-  idle,
-  data_out,
-  data_in,
-  command_ph,
-  status_ph,
-  message_out,
-  message_in
-  };
+{
+	idle,
+	data_out,
+	data_in,
+	command_ph,
+	status_ph,
+	message_out,
+	message_in
+};
 
 typedef struct
-  {
-  int base;
-  int irq;
-  int scsi_id;
-  } host;
+{
+	int base;
+	int irq;
+	int scsi_id;
+} host;
 
-host hosts[MAXHOSTS] = {
+static host hosts[MAXHOSTS] = {
                        {0, 0, SYM53C416_SCSI_ID},
                        {0, 0, SYM53C416_SCSI_ID},
                        {0, 0, SYM53C416_SCSI_ID},
@@ -228,579 +232,616 @@
                        };
 
 static int host_index = 0;
-
 static char info[120];
-
 static Scsi_Cmnd *current_command = NULL;
+static int fastpio = 1;
 
-int fastpio = 1;
-
-int probeaddrs[] = {0x200, 0x220, 0x240, 0};
+static int probeaddrs[] = {0x200, 0x220, 0x240, 0};
 
 static void sym53c416_set_transfer_counter(int base, unsigned int len)
-  {
-  /* Program Transfer Counter */
-  outb(len & 0x0000FF, base + TC_LOW);
-  outb((len & 0x00FF00) >> 8, base + TC_MID);
-  outb((len & 0xFF0000) >> 16, base + TC_HIGH);
-  }
+{
+	/* Program Transfer Counter */
+	outb(len & 0x0000FF, base + TC_LOW);
+	outb((len & 0x00FF00) >> 8, base + TC_MID);
+	outb((len & 0xFF0000) >> 16, base + TC_HIGH);
+}
 
 /* Returns the number of bytes read */
 static __inline__ unsigned int sym53c416_read(int base, unsigned char *buffer, unsigned int len)
-  {
-  unsigned int orig_len = len;
-  unsigned long flags = 0;
-  unsigned int bytes_left;
-  int i;
-  int timeout = READ_TIMEOUT;
-
-  /* Do transfer */
-  save_flags(flags);
-  cli();
-  while(len && timeout)
-    {
-    bytes_left = inb(base + PIO_FIFO_CNT); /* Number of bytes in the PIO FIFO */
-    if(fastpio && bytes_left > 3)
-      {
-      insl(base + PIO_FIFO_1, buffer, bytes_left >> 2);
-      buffer += bytes_left & 0xFC;
-      len -= bytes_left & 0xFC;
-      }
-    else if(bytes_left > 0)
-      {
-      len -= bytes_left;
-      for(; bytes_left > 0; bytes_left--)
-        *(buffer++) = inb(base + PIO_FIFO_1);
-      }
-    else
-      {
-      i = jiffies + timeout;
-      restore_flags(flags);
-      while(jiffies < i && (inb(base + PIO_INT_REG) & EMPTY) && timeout)
-        if(inb(base + PIO_INT_REG) & SCI)
-          timeout = 0;
-      save_flags(flags);
-      cli();
-      if(inb(base + PIO_INT_REG) & EMPTY)
-        timeout = 0;
-      }
-    }
-  restore_flags(flags);
-  return orig_len - len;
-  }
+{
+	unsigned int orig_len = len;
+	unsigned long flags = 0;
+	unsigned int bytes_left;
+	int i;
+	int timeout = READ_TIMEOUT;
+
+	/* Do transfer */
+	save_flags(flags);
+	cli();
+	while(len && timeout)
+	{
+		bytes_left = inb(base + PIO_FIFO_CNT); /* Number of bytes in the PIO FIFO */
+		if(fastpio && bytes_left > 3)
+		{
+			insl(base + PIO_FIFO_1, buffer, bytes_left >> 2);
+			buffer += bytes_left & 0xFC;
+			len -= bytes_left & 0xFC;
+		}
+		else if(bytes_left > 0)
+		{
+			len -= bytes_left;
+			for(; bytes_left > 0; bytes_left--)
+				*(buffer++) = inb(base + PIO_FIFO_1);
+		}
+		else
+		{
+			i = jiffies + timeout;
+			restore_flags(flags);
+			while(jiffies < i && (inb(base + PIO_INT_REG) & EMPTY) && timeout)
+				if(inb(base + PIO_INT_REG) & SCI)
+					timeout = 0;
+			save_flags(flags);
+			cli();
+			if(inb(base + PIO_INT_REG) & EMPTY)
+				timeout = 0;
+		}
+	}
+	restore_flags(flags);
+	return orig_len - len;
+}
 
 /* Returns the number of bytes written */
 static __inline__ unsigned int sym53c416_write(int base, unsigned char *buffer, unsigned int len)
-  {
-  unsigned int orig_len = len;
-  unsigned long flags = 0;
-  unsigned int bufferfree;
-  unsigned int i;
-  unsigned int timeout = WRITE_TIMEOUT;
-
-  /* Do transfer */
-  save_flags(flags);
-  cli();
-  while(len && timeout)
-    {
-    bufferfree = PIO_SIZE - inb(base + PIO_FIFO_CNT);
-    if(bufferfree > len)
-      bufferfree = len;
-    if(fastpio && bufferfree > 3)
-      {
-      outsl(base + PIO_FIFO_1, buffer, bufferfree >> 2);
-      buffer += bufferfree & 0xFC;
-      len -= bufferfree & 0xFC;
-      }
-    else if(bufferfree > 0)
-      {
-      len -= bufferfree;
-      for(; bufferfree > 0; bufferfree--)
-        outb(*(buffer++), base + PIO_FIFO_1);
-      }
-    else
-      {
-      i = jiffies + timeout;
-      restore_flags(flags);
-      while(jiffies < i && (inb(base + PIO_INT_REG) & FULL) && timeout)
-        ;
-      save_flags(flags);
-      cli();
-      if(inb(base + PIO_INT_REG) & FULL)
-        timeout = 0;
-      }
-    }
-  restore_flags(flags);
-  return orig_len - len;
-  }
+{
+	unsigned int orig_len = len;
+	unsigned long flags = 0;
+	unsigned int bufferfree;
+	unsigned int i;
+	unsigned int timeout = WRITE_TIMEOUT;
+
+	/* Do transfer */
+	save_flags(flags);
+	cli();
+	while(len && timeout)
+	{
+		bufferfree = PIO_SIZE - inb(base + PIO_FIFO_CNT);
+		if(bufferfree > len)
+			bufferfree = len;
+		if(fastpio && bufferfree > 3)
+		{
+			outsl(base + PIO_FIFO_1, buffer, bufferfree >> 2);
+			buffer += bufferfree & 0xFC;
+			len -= bufferfree & 0xFC;
+		}
+		else if(bufferfree > 0)
+		{
+			len -= bufferfree;
+			for(; bufferfree > 0; bufferfree--)
+				outb(*(buffer++), base + PIO_FIFO_1);
+		}
+		else
+		{
+			i = jiffies + timeout;
+			restore_flags(flags);
+			while(jiffies < i && (inb(base + PIO_INT_REG) & FULL) && timeout)
+				;
+			save_flags(flags);
+			cli();
+			if(inb(base + PIO_INT_REG) & FULL)
+				timeout = 0;
+		}
+	}
+	restore_flags(flags);
+	return orig_len - len;
+}
 
 static void sym53c416_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
-  {
-  int base = 0;
-  int i;
-  unsigned long flags = 0;
-  unsigned char status_reg, pio_int_reg, int_reg;
-  struct scatterlist *sglist;
-  unsigned int sgcount;
-  unsigned int tot_trans = 0;
-
-  /* We search the base address of the host adapter which caused the interrupt */
-  for(i = 0; i < host_index && !base; i++)
-    if(irq == hosts[i].irq)
-      base = hosts[i].base;
-  /* If no adapter found, we cannot handle the interrupt. Leave a message */
-  /* and continue. This should never happen...                            */
-  if(!base)
-    {
-    printk("sym53c416: No host adapter defined for interrupt %d\n", irq);
-    return;
-    }
-  /* Now we have the base address and we can start handling the interrupt */
-  save_flags(flags);
-  cli();
-  status_reg = inb(base + STATUS_REG);
-  pio_int_reg = inb(base + PIO_INT_REG);
-  int_reg = inb(base + INT_REG);
-  restore_flags(flags);
-
-  /* First, we handle error conditions */
-  if(int_reg & SCI)         /* SCSI Reset */
-    {
-    printk("sym53c416: Warning: Reset received\n");
-    current_command->SCp.phase = idle;
-    current_command->result = DID_RESET << 16;
-    spin_lock_irqsave(&io_request_lock, flags);
-    current_command->scsi_done(current_command);
-    spin_unlock_irqrestore(&io_request_lock, flags);
-    return;
-    }
-  if(int_reg & ILCMD)       /* Illegal Command */
-    {
-    printk("sym53c416: Warning: Illegal Command: 0x%02x\n", inb(base + COMMAND_REG));
-    current_command->SCp.phase = idle;
-    current_command->result = DID_ERROR << 16;
-    spin_lock_irqsave(&io_request_lock, flags);
-    current_command->scsi_done(current_command);
-    spin_unlock_irqrestore(&io_request_lock, flags);
-    return;
-    }
-  if(status_reg & GE)         /* Gross Error */
-    {
-    printk("sym53c416: Warning: Gross Error\n");
-    current_command->SCp.phase = idle;
-    current_command->result = DID_ERROR << 16;
-    spin_lock_irqsave(&io_request_lock, flags);
-    current_command->scsi_done(current_command);
-    spin_unlock_irqrestore(&io_request_lock, flags);
-    return;
-    }
-  if(status_reg & PE)         /* Parity Error */
-    {
-    printk("sym53c416: Warning: Parity Error\n");
-    current_command->SCp.phase = idle;
-    current_command->result = DID_PARITY << 16;
-    spin_lock_irqsave(&io_request_lock, flags);
-    current_command->scsi_done(current_command);
-    spin_unlock_irqrestore(&io_request_lock, flags);
-    return;
-    }
-  if(pio_int_reg & (CE | OUE))
-    {
-    printk("sym53c416: Warning: PIO Interrupt Error\n");
-    current_command->SCp.phase = idle;
-    current_command->result = DID_ERROR << 16;
-    spin_lock_irqsave(&io_request_lock, flags);
-    current_command->scsi_done(current_command);
-    spin_unlock_irqrestore(&io_request_lock, flags);
-    return;
-    }
-  if(int_reg & DIS)           /* Disconnect */
-    {
-    if(current_command->SCp.phase != message_in)
-      current_command->result = DID_NO_CONNECT << 16;
-    else
-      current_command->result = (current_command->SCp.Status & 0xFF) | ((current_command->SCp.Message & 0xFF) << 8) | (DID_OK << 16);
-    current_command->SCp.phase = idle;
-
-    spin_lock_irqsave(&io_request_lock, flags);
-    current_command->scsi_done(current_command);
-    spin_unlock_irqrestore(&io_request_lock, flags);
-    return;
-    }
-  /* Now we handle SCSI phases         */
-  switch(status_reg & PHBITS)       /* Filter SCSI phase out of status reg */
-    {
-    case PHASE_DATA_OUT:
-      {
-      if(int_reg & BS)
-        {
-        current_command->SCp.phase = data_out;
-        outb(FLUSH_FIFO, base + COMMAND_REG);
-        sym53c416_set_transfer_counter(base, current_command->request_bufflen);
-        outb(TRANSFER_INFORMATION | PIO_MODE, base + COMMAND_REG);
-        if(!current_command->use_sg)
-          tot_trans = sym53c416_write(base, current_command->request_buffer, current_command->request_bufflen);
-        else
-          {
-          sgcount = current_command->use_sg;
-          sglist = current_command->request_buffer;
-          while(sgcount--)
-            {
-            tot_trans += sym53c416_write(base, sglist->address, sglist->length);
-            sglist++;
-            }
-          }
-        if(tot_trans < current_command->underflow)
-          printk("sym53c416: Warning: underflow, wrote %d bytes, request for %d bytes\n", tot_trans, current_command->underflow);
-        }
-      break;
-      }
-    case PHASE_DATA_IN:
-      {
-      if(int_reg & BS)
-        {
-        current_command->SCp.phase = data_in;
-        outb(FLUSH_FIFO, base + COMMAND_REG);
-        sym53c416_set_transfer_counter(base, current_command->request_bufflen);
-        outb(TRANSFER_INFORMATION | PIO_MODE, base + COMMAND_REG);
-        if(!current_command->use_sg)
-          tot_trans = sym53c416_read(base, current_command->request_buffer, current_command->request_bufflen);
-        else
-          {
-          sgcount = current_command->use_sg;
-          sglist = current_command->request_buffer;
-          while(sgcount--)
-            {
-            tot_trans += sym53c416_read(base, sglist->address, sglist->length);
-            sglist++;
-            }
-          }
-        if(tot_trans < current_command->underflow)
-          printk("sym53c416: Warning: underflow, read %d bytes, request for %d bytes\n", tot_trans, current_command->underflow);
-        }
-      break;
-      }
-    case PHASE_COMMAND:
-      {
-      current_command->SCp.phase = command_ph;
-      printk("sym53c416: Warning: Unknown interrupt in command phase\n");
-      break;
-      }
-    case PHASE_STATUS:
-      {
-      current_command->SCp.phase = status_ph;
-      outb(FLUSH_FIFO, base + COMMAND_REG);
-      outb(INIT_COMM_COMPLETE_SEQ, base + COMMAND_REG);
-      break;
-      }
-    case PHASE_RESERVED_1:
-    case PHASE_RESERVED_2:
-      {
-      printk("sym53c416: Warning: Reserved phase\n");
-      break;
-      }
-    case PHASE_MESSAGE_OUT:
-      {
-      current_command->SCp.phase = message_out;
-      outb(SET_ATN, base + COMMAND_REG);
-      outb(MSG_ACCEPTED, base + COMMAND_REG);
-      break;
-      }
-    case PHASE_MESSAGE_IN:
-      {
-      current_command->SCp.phase = message_in;
-      current_command->SCp.Status = inb(base + SCSI_FIFO);
-      current_command->SCp.Message = inb(base + SCSI_FIFO);
-      if(current_command->SCp.Message == SAVE_POINTERS || current_command->SCp.Message == DISCONNECT)
-        outb(SET_ATN, base + COMMAND_REG);
-      outb(MSG_ACCEPTED, base + COMMAND_REG);
-      break;
-      }
-    }
-  }
+{
+	int base = 0;
+	int i;
+	unsigned long flags = 0;
+	unsigned char status_reg, pio_int_reg, int_reg;
+	struct scatterlist *sglist;
+	unsigned int sgcount;
+	unsigned int tot_trans = 0;
+
+	/* We search the base address of the host adapter which caused the interrupt */
+	/* FIXME: should pass dev_id sensibly as hosts[i] */
+	for(i = 0; i < host_index && !base; i++)
+		if(irq == hosts[i].irq)
+			base = hosts[i].base;
+	/* If no adapter found, we cannot handle the interrupt. Leave a message */
+	/* and continue. This should never happen...                            */
+	if(!base)
+	{
+		printk(KERN_ERR "sym53c416: No host adapter defined for interrupt %d\n", irq);
+		return;
+	}
+	/* Now we have the base address and we can start handling the interrupt */
+
+	spin_lock_irqsave(&io_request_lock,flags);
+	status_reg = inb(base + STATUS_REG);
+	pio_int_reg = inb(base + PIO_INT_REG);
+	int_reg = inb(base + INT_REG);
+	spin_unlock_irqrestore(&io_request_lock, flags);
+
+	/* First, we handle error conditions */
+	if(int_reg & SCI)         /* SCSI Reset */
+	{
+		printk(KERN_DEBUG "sym53c416: Reset received\n");
+		current_command->SCp.phase = idle;
+		current_command->result = DID_RESET << 16;
+		spin_lock_irqsave(&io_request_lock, flags);
+		current_command->scsi_done(current_command);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		return;
+	}
+	if(int_reg & ILCMD)       /* Illegal Command */
+	{
+		printk(KERN_WARNING "sym53c416: Illegal Command: 0x%02x.\n", inb(base + COMMAND_REG));
+		current_command->SCp.phase = idle;
+		current_command->result = DID_ERROR << 16;
+		spin_lock_irqsave(&io_request_lock, flags);
+		current_command->scsi_done(current_command);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		return;
+	}
+	if(status_reg & GE)         /* Gross Error */
+	{
+		printk(KERN_WARNING "sym53c416: Controller reports gross error.\n");
+		current_command->SCp.phase = idle;
+		current_command->result = DID_ERROR << 16;
+		spin_lock_irqsave(&io_request_lock, flags);
+		current_command->scsi_done(current_command);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		return;
+	}
+	if(status_reg & PE)         /* Parity Error */
+	{
+		printk(KERN_WARNING "sym53c416:SCSI parity error.\n");
+		current_command->SCp.phase = idle;
+		current_command->result = DID_PARITY << 16;
+		spin_lock_irqsave(&io_request_lock, flags);
+		current_command->scsi_done(current_command);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		return;
+	}
+	if(pio_int_reg & (CE | OUE))
+	{
+		printk(KERN_WARNING "sym53c416: PIO interrupt error.\n");
+		current_command->SCp.phase = idle;
+		current_command->result = DID_ERROR << 16;
+		spin_lock_irqsave(&io_request_lock, flags);
+		current_command->scsi_done(current_command);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		return;
+	}
+	if(int_reg & DIS)           /* Disconnect */
+	{
+		if(current_command->SCp.phase != message_in)
+			current_command->result = DID_NO_CONNECT << 16;
+		else
+			current_command->result = (current_command->SCp.Status & 0xFF) | ((current_command->SCp.Message & 0xFF) << 8) | (DID_OK << 16);
+		current_command->SCp.phase = idle;
+		spin_lock_irqsave(&io_request_lock, flags);
+		current_command->scsi_done(current_command);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+		return;
+	}
+	/* Now we handle SCSI phases         */
+
+	switch(status_reg & PHBITS)       /* Filter SCSI phase out of status reg */
+	{
+		case PHASE_DATA_OUT:
+		{
+			if(int_reg & BS)
+			{
+				current_command->SCp.phase = data_out;
+				outb(FLUSH_FIFO, base + COMMAND_REG);
+				sym53c416_set_transfer_counter(base, current_command->request_bufflen);
+				outb(TRANSFER_INFORMATION | PIO_MODE, base + COMMAND_REG);
+				if(!current_command->use_sg)
+					tot_trans = sym53c416_write(base, current_command->request_buffer, current_command->request_bufflen);
+				else
+				{
+					sgcount = current_command->use_sg;
+					sglist = current_command->request_buffer;
+					while(sgcount--)
+					{
+						tot_trans += sym53c416_write(base, sglist->address, sglist->length);
+						sglist++;
+					}
+				}
+				if(tot_trans < current_command->underflow)
+					printk(KERN_WARNING "sym53c416: Underflow, wrote %d bytes, request for %d bytes.\n", tot_trans, current_command->underflow);
+			}
+			break;
+		}
+
+		case PHASE_DATA_IN:
+		{
+			if(int_reg & BS)
+			{
+				current_command->SCp.phase = data_in;
+				outb(FLUSH_FIFO, base + COMMAND_REG);
+				sym53c416_set_transfer_counter(base, current_command->request_bufflen);
+				outb(TRANSFER_INFORMATION | PIO_MODE, base + COMMAND_REG);
+				if(!current_command->use_sg)
+					tot_trans = sym53c416_read(base, current_command->request_buffer, current_command->request_bufflen);
+				else
+				{
+					sgcount = current_command->use_sg;
+					sglist = current_command->request_buffer;
+					while(sgcount--)
+					{
+						tot_trans += sym53c416_read(base, sglist->address, sglist->length);
+						sglist++;
+					}
+				}
+				if(tot_trans < current_command->underflow)
+					printk(KERN_WARNING "sym53c416: Underflow, read %d bytes, request for %d bytes.\n", tot_trans, current_command->underflow);
+			}
+			break;
+		}
+
+		case PHASE_COMMAND:
+		{
+			current_command->SCp.phase = command_ph;
+			printk(KERN_ERR "sym53c416: Unknown interrupt in command phase.\n");
+			break;
+		}
+
+		case PHASE_STATUS:
+		{
+			current_command->SCp.phase = status_ph;
+			outb(FLUSH_FIFO, base + COMMAND_REG);
+			outb(INIT_COMM_COMPLETE_SEQ, base + COMMAND_REG);
+			break;
+		}
+		
+		case PHASE_RESERVED_1:
+		case PHASE_RESERVED_2:
+		{
+			printk(KERN_ERR "sym53c416: Reserved phase occurred.\n");
+			break;
+		}
+
+		case PHASE_MESSAGE_OUT:
+		{
+			current_command->SCp.phase = message_out;
+			outb(SET_ATN, base + COMMAND_REG);
+			outb(MSG_ACCEPTED, base + COMMAND_REG);
+			break;
+		}
+
+		case PHASE_MESSAGE_IN:
+		{
+			current_command->SCp.phase = message_in;
+			current_command->SCp.Status = inb(base + SCSI_FIFO);
+			current_command->SCp.Message = inb(base + SCSI_FIFO);
+			if(current_command->SCp.Message == SAVE_POINTERS || current_command->SCp.Message == DISCONNECT)
+				outb(SET_ATN, base + COMMAND_REG);
+			outb(MSG_ACCEPTED, base + COMMAND_REG);
+			break;
+		}
+	}
+}
 
 static void sym53c416_init(int base, int scsi_id)
-  {
-  outb(RESET_CHIP, base + COMMAND_REG);
-  outb(NOOP, base + COMMAND_REG);
-  outb(0x99, base + TOM); /* Time out of 250 ms */
-  outb(0x05, base + STP);
-  outb(0x00, base + SYNC_OFFSET);
-  outb(EPC | scsi_id, base + CONF_REG_1);
-  outb(FE | SCSI2 | TBPA, base + CONF_REG_2);
-  outb(IDMRC | QTE | CDB10 | FSCSI | FCLK, base + CONF_REG_3);
-  outb(0x83 | EAN, base + CONF_REG_4);
-  outb(IE | WSE0, base + CONF_REG_5);
-  outb(0, base + FEATURE_EN);
-  }
+{
+	outb(RESET_CHIP, base + COMMAND_REG);
+	outb(NOOP, base + COMMAND_REG);
+	outb(0x99, base + TOM); /* Time out of 250 ms */
+	outb(0x05, base + STP);
+	outb(0x00, base + SYNC_OFFSET);
+	outb(EPC | scsi_id, base + CONF_REG_1);
+	outb(FE | SCSI2 | TBPA, base + CONF_REG_2);
+	outb(IDMRC | QTE | CDB10 | FSCSI | FCLK, base + CONF_REG_3);
+	outb(0x83 | EAN, base + CONF_REG_4);
+	outb(IE | WSE0, base + CONF_REG_5);
+	outb(0, base + FEATURE_EN);
+}
 
 static int sym53c416_probeirq(int base, int scsi_id)
-  {
-  int irq, irqs, i;
+{
+	int irq, irqs, i;
 
-  /* Clear interrupt register */
-  inb(base + INT_REG);
-  /* Start probing for irq's */
-  irqs = probe_irq_on();
-  /* Reinit chip */
-  sym53c416_init(base, scsi_id);
-  /* Cause interrupt */
-  outb(NOOP, base + COMMAND_REG);
-  outb(ILLEGAL, base + COMMAND_REG);
-  outb(0x07, base + DEST_BUS_ID);
-  outb(0x00, base + DEST_BUS_ID);
-  /* Wait for interrupt to occur */
-  i = jiffies + 20;
-  while(i > jiffies && !(inb(base + STATUS_REG) & SCI))
-    barrier();
-  if(i <= jiffies) /* timed out */
-    return 0;
-  /* Get occurred irq */
-  irq = probe_irq_off(irqs);
-  sym53c416_init(base, scsi_id);
-  return irq;
-  }
+	/* Clear interrupt register */
+	inb(base + INT_REG);
+	/* Start probing for irq's */
+	irqs = probe_irq_on();
+	/* Reinit chip */
+	sym53c416_init(base, scsi_id);
+	/* Cause interrupt */
+	outb(NOOP, base + COMMAND_REG);
+	outb(ILLEGAL, base + COMMAND_REG);
+	outb(0x07, base + DEST_BUS_ID);
+	outb(0x00, base + DEST_BUS_ID);
+	/* Wait for interrupt to occur */
+	i = jiffies + 20;
+	while(i > jiffies && !(inb(base + STATUS_REG) & SCI))
+		barrier();
+	if(i <= jiffies) /* timed out */
+		return 0;
+	/* Get occurred irq */
+	irq = probe_irq_off(irqs);
+	sym53c416_init(base, scsi_id);
+	return irq;
+}
 
 /* Setup: sym53c416=base,irq */
 void sym53c416_setup(char *str, int *ints)
-  {
-  int i;
+{
+	int i;
 
-  if(host_index >= MAXHOSTS)
-    {
-    printk("sym53c416.c: Too many hosts defined\n");
-    }
-  else
-    {
-    if(ints[0] < 1 || ints[0] > 2)
-      {
-      printk("sym53c416.c: Wrong number of parameters:\n");
-      printk("sym53c416.c: usage: sym53c416=<base>[,<irq>]\n");
-      }
-    else
-      {
-      for(i = 0; i < host_index && i >= 0; i++)
-        if(hosts[i].base == ints[1])
-          i = -2;
-      if(i >= 0)
-        {
-        hosts[host_index].base = ints[1];
-        hosts[host_index].irq = (ints[0] == 2)? ints[2] : 0;
-        host_index++;
-        }
-      }
-    }
-  }
+	if(host_index >= MAXHOSTS)
+	{
+		printk(KERN_WARNING "sym53c416: Too many hosts defined\n");
+		return;
+	}
+	if(ints[0] < 1 || ints[0] > 2)
+	{
+		printk(KERN_ERR "sym53c416: Wrong number of parameters:\n");
+		printk(KERN_ERR "sym53c416: usage: sym53c416=<base>[,<irq>]\n");
+		return;
+	}
+	for(i = 0; i < host_index && i >= 0; i++)
+	        if(hosts[i].base == ints[1])
+        		i = -2;
+	if(i >= 0)
+	{
+        	hosts[host_index].base = ints[1];
+        	hosts[host_index].irq = (ints[0] == 2)? ints[2] : 0;
+        	host_index++;
+	}
+}
 
 static int sym53c416_test(int base)
-  {
-  outb(RESET_CHIP, base + COMMAND_REG);
-  outb(NOOP, base + COMMAND_REG);
-  if(inb(base + COMMAND_REG) != NOOP)
-    return 0;
-  if(!inb(base + TC_HIGH) || inb(base + TC_HIGH) == 0xFF)
-    return 0;
-  if((inb(base + PIO_INT_REG) & (FULL | EMPTY | CE | OUE | FIE | EIE)) != EMPTY)
-    return 0;
-  return 1;
-  }
+{
+	outb(RESET_CHIP, base + COMMAND_REG);
+	outb(NOOP, base + COMMAND_REG);
+	if(inb(base + COMMAND_REG) != NOOP)
+		return 0;
+	if(!inb(base + TC_HIGH) || inb(base + TC_HIGH) == 0xFF)
+		return 0;
+	if((inb(base + PIO_INT_REG) & (FULL | EMPTY | CE | OUE | FIE | EIE)) != EMPTY)
+		return 0;
+	return 1;
+}
+
+
+static struct isapnp_device_id id_table[] = {
+	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+		ISAPNP_VENDOR('S','L','I'), ISAPNP_FUNCTION(0x4163), 0 },
+	{0}
+};
+
+MODULE_DEVICE_TABLE(isapnp, id_table);
 
 void sym53c416_probe(void)
-  {
-  int *base = probeaddrs;
-  int ints[2];
-
-  ints[0] = 1;
-  for(; *base; base++)
-    if(!check_region(*base, IO_RANGE) && sym53c416_test(*base))
-      {
-      ints[1] = *base;
-      sym53c416_setup(NULL, ints);
-      }
-  }
+{
+	int *base = probeaddrs;
+	int ints[2];
+
+	ints[0] = 1;
+	for(; *base; base++)
+	{
+		if(!check_region(*base, IO_RANGE) && sym53c416_test(*base))
+		{
+			ints[1] = *base;
+			sym53c416_setup(NULL, ints);
+		}
+	}
+}
 
 int sym53c416_detect(Scsi_Host_Template *tpnt)
-  {
-  unsigned long flags;
-  struct Scsi_Host * shpnt = NULL;
-  int i;
-  int count;
-
+{
+	unsigned long flags;
+	struct Scsi_Host * shpnt = NULL;
+	int i;
+	int count;
+	struct pci_dev *idev = NULL;
+	
 #ifdef MODULE
-  int ints[3];
+	int ints[3];
 
-  ints[0] = 2;
-  if(sym53c416_base)
-    {
-    ints[1] = sym53c416_base[0];
-    ints[2] = sym53c416_base[1];
-    sym53c416_setup(NULL, ints);
-    }
-  if(sym53c416_base_1)
-    {
-    ints[1] = sym53c416_base_1[0];
-    ints[2] = sym53c416_base_1[1];
-    sym53c416_setup(NULL, ints);
-    }
-  if(sym53c416_base_2)
-    {
-    ints[1] = sym53c416_base_2[0];
-    ints[2] = sym53c416_base_2[1];
-    sym53c416_setup(NULL, ints);
-    }
-  if(sym53c416_base_3)
-    {
-    ints[1] = sym53c416_base_3[0];
-    ints[2] = sym53c416_base_3[1];
-    sym53c416_setup(NULL, ints);
-    }
+	ints[0] = 2;
+	if(sym53c416_base)
+	{
+		ints[1] = sym53c416_base[0];
+		ints[2] = sym53c416_base[1];
+		sym53c416_setup(NULL, ints);
+	}
+	if(sym53c416_base_1)
+	{
+		ints[1] = sym53c416_base_1[0];
+		ints[2] = sym53c416_base_1[1];
+		sym53c416_setup(NULL, ints);
+	}
+	if(sym53c416_base_2)
+	{
+		ints[1] = sym53c416_base_2[0];
+		ints[2] = sym53c416_base_2[1];
+		sym53c416_setup(NULL, ints);
+	}
+	if(sym53c416_base_3)
+	{
+		ints[1] = sym53c416_base_3[0];
+		ints[2] = sym53c416_base_3[1];
+		sym53c416_setup(NULL, ints);
+	}
 #endif
+	printk(KERN_INFO "sym53c416.c: %s\n", VERSION_STRING);
 
-  printk("sym53c416.c: %s\n", VERSION_STRING);
-
-  sym53c416_probe();
-
-  /* Now we register and set up each host adapter found... */
-  for(count = 0, i = 0; i < host_index; i++)
-    if(!sym53c416_test(hosts[i].base))
-      printk("No sym53c416 found at address 0x%03x\n", hosts[i].base);
-    else
-      {
-      if(hosts[i].irq == 0)
-        /* We don't have an irq yet, so we should probe for one */
-        if((hosts[i].irq = sym53c416_probeirq(hosts[i].base, hosts[i].scsi_id)) == 0)
-          printk("irq autoprobing failed for sym53c416 at address 0x%03x\n", hosts[i].base);
-      if(hosts[i].irq && !check_region(hosts[i].base, IO_RANGE))
-        {
-        shpnt = scsi_register(tpnt, 0);
-        if(shpnt==NULL)
-        	continue;
-        save_flags(flags);
-        cli();
-        /* Request for specified IRQ */
-        if(request_irq(hosts[i].irq, sym53c416_intr_handle, 0, ID, NULL))
-          {
-          restore_flags(flags);
-          printk("Unable to assign IRQ %d\n", hosts[i].irq);
-          scsi_unregister(shpnt);
-          }
-        else
-          {
-          /* Inform the kernel of our IO range */
-          request_region(hosts[i].base, IO_RANGE, ID);
-          shpnt->unique_id = hosts[i].base;
-          shpnt->io_port = hosts[i].base;
-          shpnt->n_io_port = IO_RANGE;
-          shpnt->irq = hosts[i].irq;
-          shpnt->this_id = hosts[i].scsi_id;
-          sym53c416_init(hosts[i].base, hosts[i].scsi_id);
-          count++;
-          restore_flags(flags);
-          }
-        }
-      }
-  return count;
-  }
+	while((idev=isapnp_find_dev(NULL, ISAPNP_VENDOR('S','L','I'), 
+				ISAPNP_FUNCTION(0x4163), idev))!=NULL)
+	{
+		int i[3];
+		
+		if(idev->prepare(idev)<0)
+		{
+			printk(KERN_WARNING "sym53c416: unable to prepare PnP card.\n");
+			continue;
+		}
+		if(idev->activate(idev)<0)
+		{
+			printk(KERN_WARNING "sym53c416: unable to activate PnP card.\n");
+			continue;
+		}
+		
+		i[0] = 2;
+		i[1] = idev->resource[0].start;
+		i[2] = idev->irq_resource[0].start;
+		
+		printk(KERN_INFO "sym53c416: ISAPnP card found and configured at 0x%X, IRQ %d.\n",
+			i[1], i[2]);
+		sym53c416_setup(NULL, i);
+	}
+	sym53c416_probe();
+
+	/* Now we register and set up each host adapter found... */
+	for(count = 0, i = 0; i < host_index; i++)
+	{
+		if(!sym53c416_test(hosts[i].base))
+			printk(KERN_WARNING "No sym53c416 found at address 0x%03x\n", hosts[i].base);
+		else
+		{
+			if(hosts[i].irq == 0)
+			/* We don't have an irq yet, so we should probe for one */
+				if((hosts[i].irq = sym53c416_probeirq(hosts[i].base, hosts[i].scsi_id)) == 0)
+					printk(KERN_WARNING "IRQ autoprobing failed for sym53c416 at address 0x%03x\n", hosts[i].base);
+			if(hosts[i].irq && !check_region(hosts[i].base, IO_RANGE))
+			{
+				shpnt = scsi_register(tpnt, 0);
+				if(shpnt==NULL)
+					continue;
+				save_flags(flags);
+				cli();
+				/* FIXME: Request_irq with CLI is not safe */
+				/* Request for specified IRQ */
+				if(request_irq(hosts[i].irq, sym53c416_intr_handle, 0, ID, NULL))
+				{
+					restore_flags(flags);
+					printk(KERN_ERR "sym53c416: Unable to assign IRQ %d\n", hosts[i].irq);
+					scsi_unregister(shpnt);
+				}
+				else
+				{
+					/* Inform the kernel of our IO range */
+					request_region(hosts[i].base, IO_RANGE, ID);
+					shpnt->unique_id = hosts[i].base;
+					shpnt->io_port = hosts[i].base;
+					shpnt->n_io_port = IO_RANGE;
+					shpnt->irq = hosts[i].irq;
+					shpnt->this_id = hosts[i].scsi_id;
+					sym53c416_init(hosts[i].base, hosts[i].scsi_id);
+					count++;
+					restore_flags(flags);
+				}
+			}
+		}
+	}
+	return count;
+}
 
 const char *sym53c416_info(struct Scsi_Host *SChost)
-  {
-  int i;
-  int base = SChost->io_port;
-  int irq = SChost->irq;
-  int scsi_id = 0;
-  int rev = inb(base + TC_HIGH);
-
-  for(i = 0; i < host_index; i++)
-    if(hosts[i].base == base)
-      scsi_id = hosts[i].scsi_id;
-  sprintf(info, "Symbios Logic 53c416 (rev. %d) at 0x%03x, irq %d, SCSI-ID %d, %s pio", rev, base, irq, scsi_id, (fastpio)? "fast" : "slow");
-  return info;
-  }
+{
+	int i;
+	int base = SChost->io_port;
+	int irq = SChost->irq;
+	int scsi_id = 0;
+	int rev = inb(base + TC_HIGH);
+
+	for(i = 0; i < host_index; i++)
+		if(hosts[i].base == base)
+			scsi_id = hosts[i].scsi_id;
+	sprintf(info, "Symbios Logic 53c416 (rev. %d) at 0x%03x, irq %d, SCSI-ID %d, %s pio", rev, base, irq, scsi_id, (fastpio)? "fast" : "slow");
+	return info;
+}
 
 int sym53c416_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
-  {
-  int base;
-  unsigned long flags = 0;
-  int i;
-
-  /* Store base register as we can have more than one controller in the system */
-  base = SCpnt->host->io_port;
-  current_command = SCpnt;                  /* set current command                */
-  current_command->scsi_done = done;        /* set ptr to done function           */
-  current_command->SCp.phase = command_ph;  /* currect phase is the command phase */
-  current_command->SCp.Status = 0;
-  current_command->SCp.Message = 0;
-
-  save_flags(flags);
-  cli();
-  outb(SCpnt->target, base + DEST_BUS_ID); /* Set scsi id target        */
-  outb(FLUSH_FIFO, base + COMMAND_REG);    /* Flush SCSI and PIO FIFO's */
-  /* Write SCSI command into the SCSI fifo */
-  for(i = 0; i < SCpnt->cmd_len; i++)
-    outb(SCpnt->cmnd[i], base + SCSI_FIFO);
-  /* Start selection sequence */
-  outb(SEL_WITHOUT_ATN_SEQ, base + COMMAND_REG);
-  /* Now an interrupt will be generated which we will catch in out interrupt routine */
-  restore_flags(flags);
-  return 0;
-  }
+{
+	int base;
+	unsigned long flags = 0;
+	int i;
+
+	/* Store base register as we can have more than one controller in the system */
+	base = SCpnt->host->io_port;
+	current_command = SCpnt;                  /* set current command                */
+	current_command->scsi_done = done;        /* set ptr to done function           */
+	current_command->SCp.phase = command_ph;  /* currect phase is the command phase */
+	current_command->SCp.Status = 0;
+	current_command->SCp.Message = 0;
+
+	save_flags(flags);
+	cli();
+	outb(SCpnt->target, base + DEST_BUS_ID); /* Set scsi id target        */
+	outb(FLUSH_FIFO, base + COMMAND_REG);    /* Flush SCSI and PIO FIFO's */
+	/* Write SCSI command into the SCSI fifo */
+	for(i = 0; i < SCpnt->cmd_len; i++)
+		outb(SCpnt->cmnd[i], base + SCSI_FIFO);
+	/* Start selection sequence */
+	outb(SEL_WITHOUT_ATN_SEQ, base + COMMAND_REG);
+	/* Now an interrupt will be generated which we will catch in out interrupt routine */
+	restore_flags(flags);
+	return 0;
+}
 
 static void internal_done(Scsi_Cmnd *SCpnt)
-  {
-  SCpnt->SCp.Status++;
-  }
-
-int sym53c416_command(Scsi_Cmnd *SCpnt)
-  {
-  sym53c416_queuecommand(SCpnt, internal_done);
-  SCpnt->SCp.Status = 0;
-  while(!SCpnt->SCp.Status)
-    barrier();
-  return SCpnt->result;
-  }
-
-int sym53c416_abort(Scsi_Cmnd *SCpnt)
-  {
-  printk("sym53c416_abort\n");
-
-  /* We don't know how to abort for the moment */
-  return SCSI_ABORT_SNOOZE;
-  }
-
-int sym53c416_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
-  {
-  int base;
-  int scsi_id = -1;
-  int i;
-
-  printk("sym53c416_reset\n");
-  base = SCpnt->host->io_port;
-  /* search scsi_id */
-  for(i = 0; i < host_index && scsi_id != -1; i++)
-    if(hosts[i].base == base)
-      scsi_id = hosts[i].scsi_id;
-  outb(RESET_CHIP, base + COMMAND_REG);
-  outb(NOOP | PIO_MODE, base + COMMAND_REG);
-  outb(RESET_SCSI_BUS, base + COMMAND_REG);
-  sym53c416_init(base, scsi_id);
-  return SCSI_RESET_PENDING;
-  }
-
-int sym53c416_bios_param(Disk *disk, kdev_t dev, int *ip)
-  {
-  int size;
-
-  size = disk->capacity;
-  ip[0] = 64;                         /* heads                        */
-  ip[1] = 32;                         /* sectors                      */
-  if((ip[2] = size >> 11) > 1024)     /* cylinders, test for big disk */
-    {
-    ip[0] = 255;                      /* heads                        */
-    ip[1] = 63;                       /* sectors                      */
-    ip[2] = size / (255 * 63);        /* cylinders                    */
-    }
-  return 0;
-  }
+{
+	SCpnt->SCp.Status++;
+}
+
+static int sym53c416_command(Scsi_Cmnd *SCpnt)
+{
+	sym53c416_queuecommand(SCpnt, internal_done);
+	SCpnt->SCp.Status = 0;
+	while(!SCpnt->SCp.Status)
+		barrier();
+	return SCpnt->result;
+}
+
+static int sym53c416_abort(Scsi_Cmnd *SCpnt)
+{
+	//printk("sym53c416_abort\n");
+	/* We don't know how to abort for the moment */
+	return SCSI_ABORT_SNOOZE;
+}
+
+static int sym53c416_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
+{
+	int base;
+	int scsi_id = -1;	
+	int i;
+
+	//printk("sym53c416_reset\n");
+	base = SCpnt->host->io_port;
+	/* search scsi_id */
+	for(i = 0; i < host_index && scsi_id != -1; i++)
+		if(hosts[i].base == base)
+			scsi_id = hosts[i].scsi_id;
+	outb(RESET_CHIP, base + COMMAND_REG);
+	outb(NOOP | PIO_MODE, base + COMMAND_REG);
+	outb(RESET_SCSI_BUS, base + COMMAND_REG);
+	sym53c416_init(base, scsi_id);
+	return SCSI_RESET_PENDING;
+}
+
+static int sym53c416_bios_param(Disk *disk, kdev_t dev, int *ip)
+{
+	int size;
+
+	size = disk->capacity;
+	ip[0] = 64;				/* heads                        */
+	ip[1] = 32;				/* sectors                      */
+	if((ip[2] = size >> 11) > 1024)		/* cylinders, test for big disk */
+	{
+		ip[0] = 255;			/* heads                        */
+		ip[1] = 63;			/* sectors                      */
+		ip[2] = size / (255 * 63);	/* cylinders                    */
+	}
+	return 0;
+}
 
 /* Loadable module support */
 #ifdef MODULE
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/sym53c416.h linux/drivers/scsi/sym53c416.h
--- v2.4.5/linux/drivers/scsi/sym53c416.h	Mon Dec 11 13:19:20 2000
+++ linux/drivers/scsi/sym53c416.h	Wed Jun 27 17:10:55 2001
@@ -31,14 +31,14 @@
 
 #define SYM53C416_SCSI_ID 7
 
-extern int sym53c416_detect(Scsi_Host_Template *);
-extern const char *sym53c416_info(struct Scsi_Host *);
-extern int sym53c416_command(Scsi_Cmnd *);
-extern int sym53c416_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-extern int sym53c416_abort(Scsi_Cmnd *);
-extern int sym53c416_reset(Scsi_Cmnd *, unsigned int);
-extern int sym53c416_bios_param(Disk *, kdev_t, int *);
-extern void sym53c416_setup(char *str, int *ints);
+static int sym53c416_detect(Scsi_Host_Template *);
+static const char *sym53c416_info(struct Scsi_Host *);
+static int sym53c416_command(Scsi_Cmnd *);
+static int sym53c416_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int sym53c416_abort(Scsi_Cmnd *);
+static int sym53c416_reset(Scsi_Cmnd *, unsigned int);
+static int sym53c416_bios_param(Disk *, kdev_t, int *);
+static void sym53c416_setup(char *str, int *ints);
 
 #define SYM53C416 {                                          \
                   proc_name:         "sym53c416",   \
diff -u --recursive --new-file v2.4.5/linux/drivers/scsi/sym53c8xx.c linux/drivers/scsi/sym53c8xx.c
--- v2.4.5/linux/drivers/scsi/sym53c8xx.c	Fri Apr 27 13:59:19 2001
+++ linux/drivers/scsi/sym53c8xx.c	Tue Jun 12 11:06:54 2001
@@ -11564,6 +11564,7 @@
 	OUTL_DSP (NCB_SCRIPT_PHYS (np, clrack));
 	return;
 out_stuck:
+	return;
 }
 
 
diff -u --recursive --new-file v2.4.5/linux/drivers/sgi/char/linux_logo.h linux/drivers/sgi/char/linux_logo.h
--- v2.4.5/linux/drivers/sgi/char/linux_logo.h	Wed Dec 10 10:31:11 1997
+++ linux/drivers/sgi/char/linux_logo.h	Wed Dec 31 16:00:00 1969
@@ -1,909 +0,0 @@
-/* This is a linux logo to be displayed on boot.
- *
- * You can put anything here, but:
- * LINUX_LOGO_COLORS has to be less than 224
- * image size has to be 80x80
- * values have to start from0x20
- * (i.e. RGB(linux_logo_red[0],
- *	     linux_logo_green[0],
- *	     linux_logo_blue[0]) is color0x20)
- */
-
-#define LINUX_LOGO_COLORS 221
-
-unsigned char linux_logo_red[] = {
-  0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xE7, 0xE5, 0xE3,
-  0xCA, 0xD4, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xE5,
-  0xF1, 0xED, 0xEE, 0xE6, 0xC6, 0xDA, 0xDD, 0xE5,
-  0xD9, 0xC6, 0xE3, 0xD0, 0xC6, 0xBA, 0xB0, 0xB6,
-  0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xB0, 0xAD,
-  0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA0, 0x9D,
-  0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x99, 0x9A, 0x99,
-  0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D,
-  0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0x0D, 0x03,
-  0x66, 0x44, 0x24, 0x08, 0xD6, 0xE6, 0xE9, 0xE6,
-  0xE7, 0xCA, 0xDC, 0xDB, 0xD5, 0xD0, 0xC9, 0xE2,
-  0xD5, 0xC6, 0xC4, 0xB3, 0xB2, 0xB9, 0xA9, 0x9A,
-  0xB2, 0x9D, 0xE8, 0xEC, 0xF5, 0xF5, 0xF4, 0xF4,
-  0xEC, 0xEE, 0xF0, 0xF5, 0xE0, 0xD6, 0xC5, 0xC2,
-  0xD9, 0xD5, 0xD8, 0xD6, 0xF6, 0xF4, 0xED, 0xEC,
-  0xEB, 0xF1, 0xF6, 0xF5, 0xF5, 0xEE, 0xEF, 0xEC,
-  0xE7, 0xE3, 0xE6, 0xD6, 0xDD, 0xC3, 0xD6, 0xD7,
-  0xCD, 0xCA, 0xC3, 0xAC, 0x95, 0x99, 0xB7, 0xA3,
-  0x8B, 0x88, 0x95, 0x8A, 0x94, 0xD2, 0xCC, 0xC4,
-  0xA8, 0x8E, 0x8F, 0xAE, 0xB8, 0xAC, 0xB6, 0xB4,
-  0xAD, 0xA5, 0xA0, 0x9B, 0x8B, 0xA3, 0x94, 0x87,
-  0x85, 0x89, 0x53, 0x80, 0x7D, 0x7C, 0x7A, 0x78,
-  0x76, 0x71, 0x73, 0x6E, 0x6B, 0x67, 0x65, 0x62,
-  0x4B, 0x5B, 0x5F, 0x53, 0x56, 0x52, 0x4F, 0x46,
-  0x42, 0x0F, 0x75, 0x78, 0x7D, 0x72, 0x5F, 0x6E,
-  0x7A, 0x75, 0x6A, 0x58, 0x48, 0x4F, 0x00, 0x2B,
-  0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x3B, 0x11,
-  0x1D, 0x14, 0x06, 0x02, 0x00
-};
-
-unsigned char linux_logo_green[] = {
-  0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xE7, 0xE5, 0xE3,
-  0xCA, 0xD4, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xD3,
-  0xDA, 0xD4, 0xD7, 0xCC, 0xC1, 0xCC, 0xCB, 0xC9,
-  0xC5, 0xBC, 0xBC, 0xBB, 0xB7, 0xA5, 0xB0, 0xB6,
-  0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xAD, 0xAD,
-  0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA0, 0x95,
-  0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x99, 0x9A, 0x99,
-  0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D,
-  0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0x08, 0x02,
-  0x53, 0x2E, 0x19, 0x06, 0xC6, 0xC8, 0xCF, 0xBD,
-  0xB3, 0xB6, 0xB4, 0xAB, 0xA5, 0xA3, 0x9B, 0xB6,
-  0xA7, 0x99, 0x92, 0xA4, 0x9E, 0x9D, 0x98, 0x8C,
-  0x8A, 0x86, 0xCD, 0xCC, 0xC9, 0xD7, 0xCA, 0xC4,
-  0xCA, 0xC3, 0xC7, 0xC3, 0xC8, 0xB4, 0x91, 0x8E,
-  0x8A, 0x82, 0x87, 0x85, 0xBD, 0xBF, 0xB6, 0xBC,
-  0xAE, 0xB7, 0xBC, 0xB8, 0xBF, 0xB6, 0xBC, 0xB5,
-  0xAB, 0xA6, 0xAD, 0xB2, 0xA5, 0x87, 0x9C, 0x96,
-  0x95, 0x8E, 0x87, 0x8F, 0x86, 0x86, 0x8E, 0x80,
-  0x7A, 0x70, 0x7B, 0x78, 0x78, 0x7F, 0x77, 0x6F,
-  0x70, 0x76, 0x59, 0x77, 0x68, 0x64, 0x7B, 0x7C,
-  0x75, 0x6D, 0x77, 0x69, 0x65, 0x5F, 0x5B, 0x54,
-  0x4F, 0x5B, 0x39, 0x80, 0x7D, 0x7C, 0x7A, 0x78,
-  0x76, 0x71, 0x73, 0x6E, 0x6B, 0x67, 0x65, 0x62,
-  0x4B, 0x5B, 0x5F, 0x53, 0x56, 0x52, 0x4F, 0x46,
-  0x42, 0x0B, 0x69, 0x66, 0x64, 0x57, 0x4A, 0x4E,
-  0x55, 0x4B, 0x46, 0x3B, 0x30, 0x33, 0x00, 0x2B,
-  0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x29, 0x0D,
-  0x1D, 0x14, 0x06, 0x02, 0x00
-};
-
-unsigned char linux_logo_blue[] = {
-  0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xEE, 0xE5, 0xDE,
-  0xD7, 0xD3, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xB5,
-  0xB0, 0xA6, 0xAC, 0x9B, 0xB5, 0xB5, 0xAE, 0x84,
-  0x90, 0xA9, 0x81, 0x8D, 0x96, 0x86, 0xB0, 0xB6,
-  0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xA7, 0xAD,
-  0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA5, 0x87,
-  0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x9A, 0x9A, 0x99,
-  0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D,
-  0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0xC8, 0xD7,
-  0x9B, 0x8E, 0x8C, 0xB2, 0x77, 0x77, 0x4E, 0x77,
-  0x69, 0x71, 0x78, 0x6B, 0x65, 0x66, 0x64, 0x59,
-  0x5C, 0x5A, 0x48, 0x72, 0x7B, 0x6B, 0x67, 0x6E,
-  0x42, 0x5B, 0x29, 0x36, 0x25, 0x10, 0x17, 0x14,
-  0x19, 0x16, 0x13, 0x0E, 0x08, 0x2E, 0x2E, 0x3D,
-  0x24, 0x24, 0x24, 0x24, 0x13, 0x12, 0x14, 0x14,
-  0x0E, 0x08, 0x0D, 0x0F, 0x08, 0x0D, 0x0E, 0x08,
-  0x08, 0x0C, 0x06, 0x06, 0x07, 0x16, 0x07, 0x0E,
-  0x08, 0x0A, 0x07, 0x0D, 0x2D, 0x3E, 0x09, 0x4E,
-  0x68, 0x52, 0x56, 0x58, 0x4B, 0x22, 0x20, 0x20,
-  0x27, 0x39, 0x28, 0x19, 0x1E, 0x1E, 0x08, 0x06,
-  0x07, 0x09, 0x08, 0x08, 0x05, 0x1D, 0x1F, 0x17,
-  0x18, 0x06, 0x79, 0x80, 0x7D, 0x7C, 0x7A, 0x78,
-  0x76, 0x71, 0x73, 0x6E, 0x6B, 0x68, 0x65, 0x62,
-  0x4B, 0x5B, 0x5F, 0x55, 0x56, 0x52, 0x4F, 0x46,
-  0x42, 0x5A, 0x14, 0x23, 0x3D, 0x2B, 0x21, 0x14,
-  0x06, 0x04, 0x03, 0x07, 0x09, 0x13, 0x2A, 0x3A,
-  0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x07, 0x09,
-  0x1D, 0x14, 0x06, 0x02, 0x00
-};
-
-unsigned char linux_logo[] = {
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x57,
-  0x58, 0x58, 0x59, 0x5C, 0x5D, 0x5F, 0x60, 0x61,
-  0x62, 0x61, 0x61, 0x62, 0x62, 0x62, 0x63, 0x63,
-  0x61, 0x61, 0x61, 0x61, 0x61, 0x60, 0x5E, 0x5E,
-  0x5E, 0x5D, 0x5D, 0x5C, 0x5D, 0x5B, 0x58, 0x58,
-  0x58, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x58,
-  0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x57,
-  0x54, 0x56, 0x57, 0x67, 0xFC, 0xFC, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x67, 0x4C,
-  0x4A, 0x49, 0x4A, 0x49, 0x4A, 0x49, 0x49, 0x4A,
-  0x4A, 0x4B, 0x4B, 0x4B, 0x4C, 0x50, 0x51, 0x52,
-  0x54, 0x54, 0x56, 0x57, 0x57, 0x57, 0x57, 0x58,
-  0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x58, 0x56, 0x56, 0x53,
-  0x52, 0x53, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0xFB, 0xFB,
-  0x4B, 0x4B, 0x4B, 0x4A, 0x49, 0x4A, 0x4A, 0x49,
-  0x49, 0x49, 0x48, 0x49, 0x49, 0x4A, 0x4A, 0x4B,
-  0x4C, 0x4D, 0x52, 0x54, 0x56, 0x55, 0x57, 0x58,
-  0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50,
-  0x50, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF0, 0xF4, 0xFB,
-  0xFC, 0x67, 0x53, 0x50, 0x4D, 0x4C, 0x4C, 0x4C,
-  0x4B, 0x4A, 0x4A, 0x48, 0x49, 0x48, 0x48, 0x49,
-  0x49, 0x49, 0x4B, 0x4C, 0x50, 0x52, 0x53, 0x56,
-  0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x55, 0x54, 0x53, 0x51, 0x51, 0x50, 0x4C, 0x4D,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0xD2, 0xD7, 0xF5,
-  0xFC, 0xFC, 0x5D, 0x5D, 0x5C, 0x5C, 0x59, 0x58,
-  0x58, 0x56, 0x52, 0x4C, 0x4B, 0x4A, 0x4A, 0x48,
-  0x48, 0x48, 0x48, 0x48, 0x49, 0x4B, 0x4D, 0x51,
-  0x54, 0x56, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x55, 0x54,
-  0x53, 0x52, 0x51, 0x4D, 0x4D, 0x4D, 0x50, 0x50,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0x64, 0xD9, 0xF5,
-  0xF9, 0xFC, 0xFC, 0x64, 0x63, 0x62, 0x61, 0x61,
-  0x61, 0x60, 0x5E, 0x5B, 0x5A, 0x54, 0x52, 0x4C,
-  0x4B, 0x49, 0x49, 0x47, 0x47, 0x48, 0x49, 0x4B,
-  0x4C, 0x51, 0x53, 0x56, 0x57, 0x58, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x58, 0x57, 0x57, 0x55, 0x53, 0x53,
-  0x51, 0x50, 0x50, 0x50, 0x50, 0x50, 0x53, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0xF5, 0xF9, 0xFC,
-  0xFC, 0xFC, 0xFC, 0x64, 0x64, 0x64, 0x64, 0x64,
-  0x64, 0x64, 0x64, 0x63, 0x61, 0x61, 0x5E, 0x59,
-  0x55, 0x52, 0x4C, 0x4A, 0x49, 0x47, 0x48, 0x48,
-  0x49, 0x4B, 0x4D, 0x51, 0x54, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x58, 0x55, 0x54, 0x54, 0x52, 0x51,
-  0x51, 0x51, 0x51, 0x51, 0x53, 0x54, 0x59, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xF7, 0xFC, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFC, 0x60, 0x60, 0x60, 0x61,
-  0x62, 0x63, 0x64, 0x64, 0x65, 0x65, 0x64, 0x63,
-  0x61, 0x5E, 0x59, 0x56, 0x4D, 0x4B, 0x48, 0x48,
-  0x48, 0x48, 0x49, 0x4B, 0x50, 0x53, 0x56, 0x56,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x56, 0x54, 0x53, 0x52, 0x51, 0x51,
-  0x51, 0x52, 0x53, 0x55, 0x59, 0x5D, 0x5E, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFC, 0x4C, 0x4E, 0x51, 0x52,
-  0x57, 0x5A, 0x5E, 0x60, 0x61, 0x63, 0x65, 0xCB,
-  0x64, 0x64, 0x63, 0x60, 0x5C, 0x57, 0x50, 0x4B,
-  0x48, 0x47, 0x47, 0x47, 0x4A, 0x4C, 0x52, 0x53,
-  0x54, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x55, 0x54, 0x53, 0x53, 0x51, 0x52, 0x52, 0x53,
-  0x53, 0x57, 0x5A, 0x5D, 0x5E, 0x5E, 0x60, 0xFC,
-  0xFC, 0xFC, 0xFB, 0xF9, 0xFC, 0xFC, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFA, 0xF9, 0xF5, 0xFB, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0x45, 0x3F, 0x3F,
-  0x45, 0x48, 0x4B, 0x4D, 0x54, 0x5A, 0x5E, 0x61,
-  0x63, 0xCB, 0xCB, 0x65, 0x64, 0x62, 0x5E, 0x57,
-  0x50, 0x4B, 0x48, 0x47, 0x47, 0x48, 0x4B, 0x4D,
-  0x51, 0x56, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55,
-  0x54, 0x54, 0x53, 0x53, 0x52, 0x53, 0x54, 0x57,
-  0x59, 0x5C, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0xFC,
-  0xFC, 0xFA, 0xFC, 0xFA, 0xE0, 0xFC, 0xFC, 0xFC,
-  0xFB, 0xFB, 0xFB, 0xDF, 0xD8, 0xF9, 0xE0, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0x4C, 0x4A, 0x48,
-  0x48, 0x3E, 0x44, 0x43, 0x3F, 0x47, 0x4B, 0x52,
-  0x5A, 0x5E, 0x62, 0x64, 0xCB, 0xCB, 0x64, 0x61,
-  0x5E, 0x57, 0x4D, 0x49, 0x47, 0x47, 0x48, 0x4A,
-  0x4C, 0x52, 0x54, 0x56, 0x57, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55,
-  0x54, 0x53, 0x53, 0x54, 0x54, 0x55, 0x58, 0x5B,
-  0x5C, 0x5D, 0x5E, 0x5D, 0x5D, 0x5B, 0x58, 0xFC,
-  0xFC, 0xD8, 0x4C, 0x60, 0xFC, 0xF5, 0xFC, 0xFC,
-  0xFC, 0xF7, 0x5F, 0x48, 0x48, 0x2C, 0xF8, 0xF9,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x4B, 0x4A, 0x49,
-  0x49, 0x49, 0x49, 0x47, 0x3E, 0x44, 0x42, 0x3F,
-  0x3E, 0x4B, 0x54, 0x5C, 0x61, 0x64, 0xCB, 0xCB,
-  0x64, 0x61, 0x5D, 0x53, 0x4B, 0x49, 0x47, 0x47,
-  0x49, 0x4B, 0x50, 0x53, 0x56, 0x57, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x57, 0x55, 0x55, 0x54,
-  0x53, 0x53, 0x54, 0x56, 0x58, 0x5A, 0x5B, 0x5D,
-  0x5D, 0x5D, 0x5C, 0x5A, 0x54, 0x52, 0x4C, 0xFC,
-  0xF7, 0x4E, 0x2D, 0x29, 0x4E, 0xFC, 0xFC, 0xFC,
-  0xFB, 0x5F, 0x26, 0x24, 0x20, 0x2E, 0x65, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x45, 0x3F, 0x45,
-  0x3E, 0x47, 0x47, 0x47, 0x47, 0x47, 0x3E, 0x44,
-  0x43, 0x40, 0x44, 0x49, 0x51, 0x5C, 0x62, 0x64,
-  0xCB, 0xCB, 0x63, 0x60, 0x58, 0x50, 0x49, 0x48,
-  0x48, 0x48, 0x4A, 0x4D, 0x53, 0x54, 0x57, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, 0x54,
-  0x54, 0x54, 0x55, 0x57, 0x59, 0x5B, 0x5C, 0x5D,
-  0x5C, 0x5A, 0x54, 0x51, 0x4C, 0x4C, 0x54, 0xFC,
-  0xF9, 0x23, 0xDB, 0x2D, 0x23, 0xFA, 0xFB, 0xFA,
-  0xF5, 0x27, 0x21, 0xD9, 0xF8, 0x20, 0x21, 0xFB,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x5D, 0x58, 0x55,
-  0x50, 0x48, 0x45, 0x43, 0x44, 0x44, 0x45, 0x45,
-  0x3E, 0x3F, 0x43, 0x41, 0x3F, 0x48, 0x52, 0x5D,
-  0x63, 0x65, 0xCB, 0x65, 0x61, 0x5D, 0x52, 0x4B,
-  0x48, 0x47, 0x47, 0x49, 0x4C, 0x51, 0x54, 0x57,
-  0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, 0x54,
-  0x54, 0x58, 0x5A, 0x59, 0x5B, 0x5B, 0x5B, 0x5A,
-  0x55, 0x52, 0x4D, 0x4D, 0x55, 0x5B, 0x5D, 0xFC,
-  0xF1, 0xF9, 0xFC, 0xD4, 0x21, 0xCC, 0xF7, 0xF8,
-  0xF2, 0x21, 0xD9, 0xFC, 0xF2, 0xFB, 0x21, 0x45,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0xD1, 0xD0, 0xCD,
-  0xCC, 0x63, 0x5E, 0x58, 0x50, 0x47, 0x43, 0x3F,
-  0x3F, 0x3F, 0x3F, 0x3F, 0x40, 0x41, 0x3F, 0x4A,
-  0x56, 0x5E, 0x64, 0xCB, 0x65, 0x63, 0x5E, 0x56,
-  0x4C, 0x48, 0x47, 0x47, 0x49, 0x4C, 0x51, 0x54,
-  0x58, 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54,
-  0x57, 0x5A, 0x5A, 0x5C, 0x5B, 0x5A, 0x58, 0x54,
-  0x51, 0x4C, 0x55, 0x5D, 0x5D, 0x5B, 0x54, 0xFC,
-  0xF0, 0xF9, 0xFC, 0x65, 0x45, 0xCD, 0xFB, 0xFB,
-  0xF8, 0x26, 0xFB, 0xFC, 0xFC, 0xFC, 0x21, 0x27,
-  0xFB, 0xFC, 0xFC, 0xFC, 0xFB, 0xD7, 0x35, 0x34,
-  0x2F, 0x35, 0x36, 0x2F, 0x2F, 0x36, 0x2F, 0x2F,
-  0x36, 0x36, 0x35, 0x35, 0x43, 0x42, 0x41, 0x2E,
-  0x45, 0x4C, 0x5B, 0x62, 0x65, 0xCC, 0x64, 0x60,
-  0x58, 0x4D, 0x49, 0x47, 0x47, 0x49, 0x4C, 0x51,
-  0x58, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, 0x57,
-  0x58, 0x5A, 0x5A, 0x5B, 0x5A, 0x55, 0x54, 0x51,
-  0x53, 0x5C, 0x5D, 0x5D, 0x54, 0x4B, 0x4D, 0xFC,
-  0xFC, 0x44, 0xFC, 0xFB, 0x7B, 0xAB, 0xA8, 0xAE,
-  0xAB, 0x7F, 0xFC, 0xFC, 0xFB, 0xFB, 0x22, 0x2A,
-  0xFC, 0xFC, 0xFC, 0xFC, 0x36, 0x2F, 0x30, 0x30,
-  0x32, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30,
-  0x30, 0x30, 0x30, 0x30, 0x2F, 0x2F, 0x40, 0x41,
-  0x2E, 0x40, 0x48, 0x56, 0x5F, 0x64, 0xCC, 0x65,
-  0x61, 0x59, 0x50, 0x49, 0x47, 0x47, 0x49, 0x4C,
-  0x5A, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58,
-  0x5A, 0x5A, 0x5A, 0x58, 0x55, 0x52, 0x51, 0x5A,
-  0x5D, 0x5D, 0x57, 0x4C, 0x51, 0x54, 0x5D, 0xFC,
-  0xFC, 0x2A, 0xFC, 0xC9, 0xAA, 0x8B, 0x8A, 0x8C,
-  0xAB, 0x8C, 0x8C, 0xFB, 0xFB, 0x23, 0x20, 0xF1,
-  0xFC, 0xFC, 0xFC, 0x3B, 0x33, 0x33, 0x32, 0x32,
-  0x31, 0x32, 0x30, 0x32, 0x32, 0x32, 0x32, 0x30,
-  0x31, 0x31, 0x31, 0x32, 0x33, 0x33, 0x3C, 0x41,
-  0x41, 0x2E, 0x2D, 0x45, 0x4D, 0x5D, 0x63, 0xCC,
-  0x65, 0x62, 0x5D, 0x51, 0x49, 0x47, 0x47, 0x4A,
-  0x59, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, 0x58,
-  0x5A, 0x5A, 0x58, 0x55, 0x53, 0x53, 0x5C, 0x5E,
-  0x59, 0x51, 0x4E, 0x54, 0x59, 0x5E, 0x62, 0xFC,
-  0xFC, 0xDB, 0xAA, 0xA1, 0x95, 0x9C, 0x8C, 0x88,
-  0x82, 0x83, 0x83, 0x8C, 0x88, 0xAE, 0xB9, 0xFB,
-  0xFC, 0xFC, 0xFC, 0x3C, 0x3B, 0x72, 0x38, 0x33,
-  0x33, 0x33, 0x31, 0x33, 0x31, 0x31, 0x31, 0x31,
-  0x33, 0x33, 0x38, 0x33, 0x72, 0x3B, 0x44, 0x2E,
-  0x41, 0x2E, 0x2E, 0x2D, 0x43, 0x4B, 0x5B, 0x63,
-  0xCB, 0xCC, 0x63, 0x5D, 0x51, 0x49, 0x47, 0x49,
-  0x5C, 0x58, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58,
-  0x58, 0x58, 0x57, 0x53, 0x58, 0x5D, 0x5E, 0x55,
-  0x51, 0x53, 0x58, 0x5E, 0x60, 0x63, 0x64, 0xFC,
-  0xFC, 0xC0, 0xA6, 0x9D, 0x8B, 0x9C, 0x8C, 0x8C,
-  0x6E, 0x83, 0x88, 0x8C, 0x8C, 0x8C, 0x83, 0xE8,
-  0xFB, 0xFC, 0xFC, 0xFC, 0x33, 0x70, 0x70, 0x6F,
-  0x6F, 0x6F, 0x6F, 0x3A, 0x6F, 0x6D, 0x6F, 0x6F,
-  0x70, 0x6F, 0x6F, 0x70, 0x6F, 0x32, 0x5A, 0x48,
-  0x41, 0x2D, 0x2D, 0x2D, 0x2C, 0x41, 0x49, 0x5A,
-  0x62, 0xCB, 0xCB, 0x63, 0x5D, 0x50, 0x49, 0x4A,
-  0x5C, 0x58, 0x58, 0x57, 0x55, 0x57, 0x57, 0x57,
-  0x57, 0x55, 0x56, 0x59, 0x5E, 0x5C, 0x52, 0x53,
-  0x55, 0x5B, 0x5E, 0x61, 0x63, 0x64, 0x63, 0xFC,
-  0xE8, 0xBF, 0xA4, 0x99, 0x9C, 0x8C, 0x88, 0x88,
-  0x6E, 0x88, 0x8C, 0x8C, 0x8C, 0xC2, 0xA6, 0xC4,
-  0xFC, 0xFC, 0xFC, 0xFC, 0x36, 0x3A, 0x6F, 0x70,
-  0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70,
-  0x70, 0x70, 0x70, 0x70, 0x37, 0x32, 0xCD, 0x5E,
-  0x4C, 0x43, 0x2C, 0x2D, 0x2D, 0x2C, 0x2E, 0x47,
-  0x57, 0x61, 0x65, 0xCC, 0x63, 0x5C, 0x50, 0x4D,
-  0x5C, 0x5A, 0x57, 0x55, 0x55, 0x55, 0x58, 0x58,
-  0x55, 0x54, 0x5B, 0x5E, 0x5D, 0x53, 0x53, 0x55,
-  0x5D, 0x5E, 0x61, 0x61, 0x61, 0x61, 0x5E, 0xFC,
-  0xEA, 0xBE, 0xA4, 0x9B, 0x8B, 0x85, 0x8C, 0x6E,
-  0x8C, 0x8C, 0x8C, 0xA3, 0xAA, 0xA4, 0xA4, 0xE9,
-  0xFB, 0xFC, 0xFC, 0xFC, 0x36, 0x6D, 0x70, 0x73,
-  0x70, 0x70, 0x70, 0x73, 0x73, 0x73, 0x73, 0x70,
-  0x70, 0x70, 0x73, 0x70, 0x37, 0x38, 0xD1, 0xCF,
-  0x61, 0x4D, 0x44, 0x2C, 0x2D, 0x2E, 0x2C, 0x2E,
-  0x3E, 0x56, 0x61, 0xCB, 0xCC, 0x62, 0x5B, 0x57,
-  0x59, 0x58, 0x55, 0x54, 0x54, 0x55, 0x58, 0x58,
-  0x58, 0x5B, 0x5E, 0x5B, 0x53, 0x55, 0x55, 0x5C,
-  0x5E, 0x61, 0x61, 0x60, 0x5D, 0x5A, 0x4E, 0xFC,
-  0xFC, 0xEA, 0xAA, 0x9C, 0x8A, 0x85, 0x82, 0x8C,
-  0x8C, 0xA8, 0xEB, 0xA8, 0xA4, 0xA4, 0xAA, 0xFC,
-  0xFC, 0xFC, 0x64, 0xFB, 0x39, 0x31, 0x72, 0x78,
-  0x73, 0x78, 0x73, 0x74, 0x74, 0x74, 0x74, 0x73,
-  0x78, 0x70, 0x73, 0x73, 0x33, 0xCC, 0xD2, 0xD1,
-  0xCE, 0x62, 0x53, 0x3F, 0x2D, 0x2D, 0x41, 0x2C,
-  0x2E, 0x3E, 0x56, 0x62, 0xCB, 0xCB, 0x61, 0x5D,
-  0x54, 0x54, 0x54, 0x54, 0x56, 0x58, 0x58, 0x58,
-  0x5C, 0x5E, 0x5A, 0x55, 0x58, 0x58, 0x5B, 0x5E,
-  0x61, 0x5E, 0x5D, 0x5A, 0x52, 0x55, 0xCD, 0xFC,
-  0xFC, 0x34, 0xC9, 0xE8, 0xA8, 0xAE, 0xC2, 0xE8,
-  0xC3, 0xA6, 0xA7, 0xA6, 0xAA, 0x78, 0x2E, 0x42,
-  0xFC, 0xFC, 0xD2, 0x64, 0xF8, 0x31, 0x72, 0x73,
-  0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x74, 0x73,
-  0x73, 0x73, 0x73, 0x72, 0x33, 0x5C, 0x64, 0xD2,
-  0xD1, 0xCF, 0x63, 0x54, 0x3F, 0x2C, 0x41, 0x41,
-  0x2C, 0x2E, 0x47, 0x58, 0x63, 0xCB, 0xCB, 0x62,
-  0x52, 0x53, 0x53, 0x56, 0x58, 0x58, 0x5A, 0x5B,
-  0x5E, 0x5A, 0x57, 0x58, 0x58, 0x58, 0x60, 0x60,
-  0x5D, 0x5A, 0x55, 0x4E, 0x64, 0xD2, 0xD1, 0xFC,
-  0xFC, 0x41, 0x3E, 0xC1, 0xC0, 0xA3, 0xA6, 0xA7,
-  0xA7, 0xA9, 0xAA, 0xB8, 0x2E, 0x3F, 0x2C, 0x41,
-  0xFC, 0xFC, 0xF7, 0xCE, 0xCD, 0x36, 0x72, 0x73,
-  0x74, 0x75, 0x78, 0x75, 0x75, 0x75, 0x74, 0x74,
-  0x74, 0x74, 0x78, 0x72, 0x6D, 0x49, 0x59, 0xCB,
-  0xD1, 0xD1, 0xD2, 0xCB, 0x56, 0x3F, 0x2C, 0x41,
-  0x40, 0x2D, 0x2E, 0x49, 0x5B, 0x64, 0xCC, 0x64,
-  0x51, 0x53, 0x53, 0x55, 0x58, 0x59, 0x5B, 0x5E,
-  0x59, 0x58, 0x58, 0x58, 0x55, 0x60, 0x60, 0x5C,
-  0x5A, 0x53, 0x5B, 0xD0, 0xD3, 0xD3, 0xD3, 0xFB,
-  0xFC, 0x40, 0x41, 0x45, 0xC4, 0xC0, 0xBE, 0xBE,
-  0xC1, 0xC0, 0x3C, 0x47, 0x2E, 0x21, 0x22, 0x20,
-  0x65, 0xFC, 0xFC, 0xFC, 0xFC, 0x6D, 0x72, 0x75,
-  0x78, 0x76, 0x75, 0x79, 0x76, 0x76, 0x76, 0x76,
-  0x75, 0x75, 0x75, 0x72, 0x6D, 0x2E, 0x48, 0x5D,
-  0xCE, 0xD1, 0xD4, 0xD3, 0xCB, 0x56, 0x43, 0x2C,
-  0x42, 0x43, 0x2E, 0x2E, 0x4A, 0x5D, 0x64, 0x64,
-  0x50, 0x52, 0x56, 0x58, 0x5C, 0x5D, 0x5E, 0x5D,
-  0x5A, 0x58, 0x58, 0x55, 0x61, 0x60, 0x58, 0x58,
-  0x4E, 0x61, 0xD1, 0xD4, 0xD4, 0xD1, 0xEE, 0xFC,
-  0xFC, 0x2B, 0x29, 0x2E, 0x3F, 0xB0, 0xAD, 0x81,
-  0x46, 0x2D, 0x46, 0x2C, 0x24, 0x22, 0x22, 0x23,
-  0x25, 0xFC, 0xFC, 0xFC, 0xFC, 0x6E, 0x73, 0x76,
-  0x76, 0x79, 0x79, 0x79, 0x76, 0x76, 0x79, 0x76,
-  0x79, 0x79, 0x79, 0x74, 0x3F, 0x41, 0x2C, 0x48,
-  0x5F, 0xCF, 0xD5, 0xD7, 0xD6, 0xCD, 0x57, 0x40,
-  0x2E, 0x3F, 0x44, 0x2E, 0x41, 0x4C, 0x60, 0x61,
-  0x51, 0x53, 0x58, 0x5C, 0x5D, 0x5E, 0x5D, 0x5C,
-  0x58, 0x57, 0x54, 0x5F, 0x5E, 0x55, 0x55, 0x52,
-  0x64, 0xD4, 0xD5, 0xD4, 0xD1, 0x5D, 0xFA, 0xFB,
-  0xF4, 0x21, 0x24, 0x41, 0x40, 0x44, 0x2E, 0x2E,
-  0x42, 0x41, 0x2A, 0x24, 0x22, 0x22, 0x22, 0x22,
-  0x23, 0xD9, 0xFC, 0xFC, 0xFC, 0xFC, 0xE5, 0xB8,
-  0x8F, 0x8F, 0x7A, 0x8F, 0x7A, 0x8F, 0x7A, 0x8F,
-  0x8F, 0x8F, 0xB8, 0xE5, 0x3F, 0x3E, 0x43, 0x2C,
-  0x48, 0x61, 0xD1, 0xD7, 0xD9, 0xD7, 0xD0, 0x57,
-  0x41, 0x2E, 0x3E, 0x44, 0x2D, 0x40, 0x52, 0x5D,
-  0x53, 0x55, 0x59, 0x5D, 0x5E, 0x5E, 0x5D, 0x5A,
-  0x57, 0x53, 0x5E, 0x5E, 0x54, 0x53, 0x54, 0x65,
-  0xD5, 0xD6, 0xD4, 0xCE, 0x53, 0xFB, 0xF9, 0xFC,
-  0x24, 0x22, 0x23, 0x23, 0x41, 0x42, 0x2E, 0x40,
-  0x2B, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-  0x23, 0x23, 0xFC, 0xFC, 0xFC, 0xFC, 0xE7, 0xBD,
-  0xB5, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-  0x93, 0xB5, 0xC6, 0xEB, 0x2D, 0x47, 0x4A, 0x47,
-  0x2C, 0x3E, 0x61, 0xD4, 0xDC, 0xDC, 0xDA, 0xCF,
-  0x54, 0x41, 0x41, 0x3E, 0x45, 0x2C, 0x3F, 0x4A,
-  0x58, 0x5A, 0x5C, 0x5F, 0x60, 0x5E, 0x5D, 0x57,
-  0x51, 0x5D, 0x5D, 0x51, 0x53, 0x53, 0xCB, 0xD5,
-  0xD6, 0xD5, 0x63, 0x55, 0xFC, 0xFC, 0xFC, 0x2C,
-  0x23, 0x22, 0x23, 0x22, 0x20, 0x2D, 0x2C, 0x26,
-  0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-  0x22, 0x21, 0xF0, 0xFC, 0xFC, 0xFC, 0xE2, 0xC6,
-  0xB5, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-  0x93, 0x93, 0xC7, 0xE3, 0x3E, 0x2E, 0x49, 0x52,
-  0x4C, 0x41, 0x44, 0x62, 0xD6, 0xDE, 0xDE, 0xD9,
-  0xD0, 0x51, 0x2E, 0x40, 0x47, 0x44, 0x2C, 0x42,
-  0x5D, 0x5D, 0x5F, 0x60, 0x60, 0x5D, 0x57, 0x51,
-  0x58, 0x5D, 0x4E, 0x52, 0x55, 0x64, 0xD5, 0xD6,
-  0xD4, 0x61, 0x59, 0x6B, 0xFC, 0xFC, 0xFC, 0x21,
-  0x23, 0x22, 0x23, 0x22, 0x23, 0x21, 0x23, 0x22,
-  0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-  0x22, 0x21, 0x24, 0xFC, 0xFC, 0xFC, 0xE2, 0xC7,
-  0xB5, 0x90, 0x93, 0x93, 0x93, 0x90, 0x93, 0x93,
-  0x90, 0xB5, 0xC8, 0xE4, 0x5F, 0x45, 0x2E, 0x4D,
-  0x57, 0x57, 0x44, 0x43, 0x63, 0xDA, 0xDF, 0xDF,
-  0xD9, 0xCE, 0x4C, 0x2C, 0x3F, 0x3E, 0x40, 0x40,
-  0x60, 0x5E, 0x61, 0x61, 0x5E, 0x5B, 0x53, 0x52,
-  0x5C, 0x52, 0x52, 0x55, 0x61, 0xD4, 0xD5, 0xD1,
-  0x5E, 0x5B, 0x5C, 0xFB, 0xFC, 0xFC, 0x2A, 0x21,
-  0x23, 0x22, 0x23, 0x22, 0x22, 0x22, 0x23, 0x22,
-  0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-  0x22, 0x22, 0x22, 0xFB, 0xFC, 0xFC, 0xB3, 0xC8,
-  0xB5, 0x90, 0x92, 0xB5, 0x93, 0x93, 0xB5, 0x93,
-  0x92, 0xB5, 0xC8, 0xB9, 0xD0, 0x5E, 0x44, 0x40,
-  0x52, 0x58, 0x57, 0x48, 0x40, 0x63, 0xD9, 0xE0,
-  0xE0, 0xD9, 0xCB, 0x49, 0x2D, 0x3F, 0x45, 0x3F,
-  0x63, 0x61, 0x62, 0x60, 0x5E, 0x55, 0x4D, 0x59,
-  0x53, 0x4E, 0x54, 0x5D, 0xD2, 0xD4, 0xD2, 0x5E,
-  0x5C, 0x5D, 0xFC, 0xFC, 0xFC, 0xF8, 0x29, 0x23,
-  0x23, 0x23, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-  0x23, 0x22, 0x22, 0x23, 0x23, 0x23, 0x22, 0x22,
-  0x22, 0x22, 0x22, 0xF0, 0xFC, 0xFC, 0xB3, 0xC7,
-  0xB5, 0x93, 0xB5, 0x93, 0x93, 0x91, 0x93, 0x93,
-  0x91, 0xB5, 0xC7, 0xAD, 0xD6, 0xD2, 0x5E, 0x3F,
-  0x3F, 0x57, 0x57, 0x58, 0x4A, 0x41, 0x64, 0xDC,
-  0xF1, 0xDF, 0xDA, 0x61, 0x45, 0x2E, 0x43, 0x47,
-  0xCB, 0x63, 0x62, 0x5F, 0x58, 0x51, 0x53, 0x54,
-  0x4C, 0x52, 0x5C, 0xCD, 0xD3, 0xD2, 0x60, 0x5D,
-  0x5D, 0xFB, 0xFC, 0xFC, 0xFC, 0xDB, 0x49, 0x24,
-  0x21, 0x23, 0x23, 0x22, 0x26, 0x26, 0x2A, 0x24,
-  0x22, 0x23, 0x22, 0x21, 0x24, 0x26, 0x26, 0x2A,
-  0x29, 0x2B, 0x24, 0x25, 0xFC, 0xFC, 0xB3, 0xC5,
-  0x91, 0x91, 0x92, 0x91, 0x92, 0x92, 0x93, 0x93,
-  0x91, 0x93, 0xC6, 0xAD, 0xDC, 0xD9, 0xD4, 0x60,
-  0x43, 0x45, 0x58, 0x58, 0x57, 0x4B, 0x43, 0xCC,
-  0xDD, 0xF1, 0xD8, 0xD5, 0x5D, 0x43, 0x41, 0x47,
-  0xCD, 0x63, 0x62, 0x5D, 0x54, 0x4C, 0x55, 0x4B,
-  0x51, 0x58, 0x62, 0xD0, 0xD0, 0x62, 0x5D, 0x5D,
-  0x67, 0xFC, 0xFC, 0xFC, 0xFC, 0x58, 0x4E, 0x28,
-  0x2A, 0x20, 0x23, 0x22, 0x23, 0x2A, 0x23, 0x22,
-  0x22, 0x22, 0x23, 0x23, 0x25, 0x2A, 0x2E, 0x2D,
-  0x2E, 0x2E, 0x2E, 0x23, 0xFA, 0xFC, 0xB2, 0xBD,
-  0xB5, 0x90, 0x91, 0x93, 0x92, 0x90, 0x91, 0x93,
-  0x92, 0x91, 0xBD, 0xAD, 0xDE, 0xE0, 0xD8, 0xD7,
-  0x61, 0x40, 0x48, 0x58, 0x58, 0x58, 0x48, 0x44,
-  0xCF, 0xDE, 0xE0, 0xDD, 0xD0, 0x52, 0x41, 0x45,
-  0xCD, 0x63, 0x61, 0x58, 0x4D, 0x51, 0x4C, 0x4B,
-  0x54, 0x5D, 0xCC, 0xCE, 0x63, 0x61, 0x5D, 0x5D,
-  0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0x4B, 0x27, 0x21,
-  0x22, 0x22, 0x23, 0x22, 0x22, 0x24, 0x23, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x20,
-  0x27, 0x2B, 0x41, 0x2B, 0x23, 0xFC, 0xB2, 0xB6,
-  0x93, 0x90, 0x92, 0xB5, 0x92, 0x90, 0xB5, 0x90,
-  0x92, 0x93, 0xBC, 0xAD, 0xDC, 0xF1, 0xF3, 0xF0,
-  0xD9, 0x61, 0x41, 0x4A, 0x58, 0x57, 0x57, 0x44,
-  0x49, 0xD2, 0xDD, 0xD8, 0xDA, 0x63, 0x4A, 0x45,
-  0xCC, 0x63, 0x5E, 0x52, 0x4B, 0x4C, 0x49, 0x51,
-  0x5C, 0x61, 0xCD, 0x65, 0x63, 0x5E, 0x4E, 0xCF,
-  0xFB, 0xFB, 0xF0, 0xFC, 0xD2, 0x2A, 0x22, 0x23,
-  0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22,
-  0x23, 0x22, 0x26, 0x41, 0x27, 0xF9, 0x81, 0xB7,
-  0xB5, 0x91, 0x92, 0xB5, 0x91, 0xB5, 0x93, 0xB5,
-  0x93, 0xB6, 0xB7, 0xB9, 0xCB, 0xD8, 0xF3, 0xF2,
-  0xF2, 0xDB, 0x61, 0x2D, 0x51, 0x58, 0x57, 0x58,
-  0x41, 0x51, 0xD4, 0xDB, 0xDC, 0xD1, 0x5B, 0x4C,
-  0xCB, 0x62, 0x59, 0x4C, 0x4A, 0x49, 0x4B, 0x55,
-  0x60, 0x64, 0xCC, 0x64, 0x5E, 0x55, 0x60, 0xE1,
-  0xFB, 0xF8, 0xFC, 0xFC, 0x21, 0x22, 0x22, 0x23,
-  0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22,
-  0x23, 0x22, 0x21, 0x24, 0x2D, 0x21, 0xB4, 0xBB,
-  0xB6, 0xB5, 0xB6, 0xB7, 0xB7, 0xB7, 0xB7, 0xB6,
-  0xB6, 0xB6, 0xBB, 0xB9, 0x45, 0xCB, 0xDF, 0xF3,
-  0xF3, 0xF3, 0xDB, 0x5E, 0x2C, 0x51, 0x58, 0x58,
-  0x52, 0x2D, 0x5C, 0xD4, 0xD9, 0xD5, 0x63, 0x58,
-  0x64, 0x60, 0x53, 0x49, 0x4A, 0x49, 0x52, 0x5C,
-  0x63, 0xCD, 0xCD, 0x63, 0x5C, 0x4E, 0x65, 0xFC,
-  0xFC, 0xF5, 0xFC, 0xD2, 0x23, 0x22, 0x22, 0x23,
-  0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22,
-  0x23, 0x22, 0x21, 0x22, 0x25, 0x29, 0xB3, 0xC7,
-  0xB5, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6,
-  0xB6, 0xB5, 0xC7, 0xAD, 0x57, 0x3F, 0xCB, 0xF0,
-  0xF3, 0xF3, 0xF2, 0xD9, 0x58, 0x41, 0x4C, 0x58,
-  0x57, 0x47, 0x42, 0x62, 0xD4, 0xD4, 0xCC, 0x60,
-  0x63, 0x5D, 0x50, 0x47, 0x48, 0x4B, 0x58, 0x60,
-  0xCC, 0xCE, 0xCD, 0x60, 0x53, 0x5C, 0x62, 0xFB,
-  0xF9, 0xFC, 0xFC, 0x21, 0x23, 0x22, 0x22, 0x23,
-  0x22, 0x22, 0x23, 0x23, 0x23, 0x21, 0x22, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22,
-  0x23, 0x22, 0x23, 0x23, 0x22, 0x23, 0x81, 0xC7,
-  0xB7, 0xB7, 0xBC, 0xB7, 0xBC, 0xBC, 0xBC, 0xB7,
-  0xB7, 0xB7, 0xC8, 0x80, 0x58, 0x57, 0x40, 0xCE,
-  0xF3, 0xF2, 0xF2, 0xF0, 0xD5, 0x4C, 0x3F, 0x4B,
-  0x52, 0x50, 0x2D, 0x4B, 0x64, 0xD2, 0xCC, 0x61,
-  0x60, 0x58, 0x4A, 0x47, 0x47, 0x4C, 0x59, 0x64,
-  0xD0, 0xD0, 0x64, 0x59, 0x49, 0x5D, 0xFB, 0xFC,
-  0xD9, 0xFC, 0xD6, 0x23, 0x22, 0x22, 0x22, 0x23,
-  0x22, 0x22, 0x23, 0x23, 0x21, 0x21, 0x22, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22,
-  0x23, 0x22, 0x23, 0x23, 0x22, 0x23, 0xB4, 0xC8,
-  0xBD, 0xB7, 0xBD, 0xBC, 0xBD, 0xC5, 0xBC, 0xC5,
-  0xBC, 0xBD, 0xC7, 0xAC, 0x58, 0x57, 0x58, 0x2C,
-  0xD1, 0xF0, 0xF3, 0xF3, 0xE0, 0xCD, 0x45, 0x3E,
-  0x48, 0x4B, 0x3F, 0x41, 0x56, 0x64, 0x65, 0x62,
-  0x5D, 0x52, 0x47, 0x48, 0x48, 0x53, 0x60, 0xCC,
-  0xD2, 0xD0, 0x63, 0x52, 0x4E, 0x53, 0xFB, 0xFB,
-  0xFC, 0xFC, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23,
-  0x22, 0x22, 0x23, 0x23, 0x20, 0x21, 0x22, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22,
-  0x23, 0x22, 0x23, 0x22, 0x23, 0x22, 0xB4, 0xC7,
-  0xC5, 0xBC, 0xC5, 0xBD, 0xC5, 0xC5, 0xBD, 0xC5,
-  0xBC, 0xC6, 0xC7, 0xB9, 0x58, 0x57, 0x58, 0x57,
-  0x2D, 0xD4, 0xF1, 0xF2, 0xF0, 0xD9, 0x5D, 0x47,
-  0x48, 0x3F, 0x42, 0x2C, 0x48, 0x5C, 0x5F, 0x60,
-  0x58, 0x50, 0x47, 0x4A, 0x49, 0x55, 0x63, 0xD0,
-  0xD2, 0xCD, 0x5D, 0x49, 0x4E, 0xE1, 0xFC, 0xF0,
-  0xFC, 0xF8, 0x22, 0x22, 0x22, 0x23, 0x22, 0x23,
-  0x22, 0x22, 0x23, 0x20, 0x21, 0x21, 0x22, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x22,
-  0x23, 0x22, 0x23, 0x23, 0x23, 0x22, 0xC4, 0xC8,
-  0xBD, 0xBD, 0xC6, 0xBD, 0xC6, 0xC6, 0xC5, 0xC6,
-  0xBD, 0xC6, 0xC7, 0xE4, 0x54, 0x57, 0x58, 0x57,
-  0x57, 0x43, 0xD7, 0xE0, 0xF1, 0xD8, 0xCD, 0x4B,
-  0x4A, 0x47, 0x42, 0x2C, 0x3F, 0x4D, 0x58, 0x5C,
-  0x52, 0x4B, 0x48, 0x4B, 0x4A, 0x58, 0xCB, 0xD3,
-  0xD2, 0xCD, 0x58, 0x47, 0x4A, 0xFC, 0xFC, 0xFB,
-  0xFC, 0x2B, 0x22, 0x22, 0x22, 0x23, 0x22, 0x23,
-  0x22, 0x22, 0x23, 0x26, 0x21, 0x21, 0x23, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23,
-  0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0xE5, 0xC8,
-  0xBA, 0xC5, 0xC6, 0xC6, 0xC6, 0xC7, 0xC6, 0xC7,
-  0xC5, 0xC6, 0xC8, 0xE5, 0x2E, 0x54, 0x58, 0x57,
-  0x57, 0x4C, 0x4D, 0xDA, 0xD8, 0xD8, 0xD4, 0x5C,
-  0x4B, 0x4B, 0x3F, 0x42, 0x44, 0x4A, 0x51, 0x58,
-  0x4B, 0x48, 0x4B, 0x51, 0x4D, 0x5F, 0xD0, 0xD1,
-  0xD0, 0x64, 0x51, 0x44, 0x6B, 0xFC, 0xFB, 0xFC,
-  0xFC, 0x21, 0x23, 0x22, 0x22, 0x23, 0x22, 0x23,
-  0x22, 0x22, 0x23, 0x26, 0x21, 0x23, 0x23, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23,
-  0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0xE5, 0xED,
-  0xE7, 0xBA, 0xC8, 0xC6, 0xC6, 0xC6, 0xC6, 0xC7,
-  0xC7, 0xE5, 0xED, 0xE6, 0x61, 0x41, 0x52, 0x58,
-  0x58, 0x57, 0x45, 0x5E, 0xD7, 0xDD, 0xD5, 0x60,
-  0x4B, 0x4C, 0x48, 0x4D, 0x4D, 0x50, 0x4D, 0x56,
-  0x4A, 0x3E, 0x53, 0x53, 0x52, 0x63, 0xD3, 0xD0,
-  0xCE, 0x60, 0x4A, 0x45, 0xFC, 0xFC, 0xF7, 0xFC,
-  0xFC, 0x21, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23,
-  0x22, 0x23, 0x21, 0x2A, 0x20, 0x23, 0x23, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22,
-  0x23, 0x22, 0x23, 0x22, 0x21, 0x23, 0xEB, 0xF6,
-  0xF6, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED,
-  0xF6, 0xF6, 0xF6, 0xE6, 0xDB, 0x58, 0x45, 0x4B,
-  0x58, 0x57, 0x4D, 0x4B, 0x64, 0xD4, 0xD0, 0x5C,
-  0x48, 0x51, 0x4C, 0x5D, 0x5E, 0x5C, 0x56, 0x59,
-  0x3E, 0x4A, 0x58, 0x54, 0x52, 0x65, 0xD3, 0xD0,
-  0xCF, 0x5D, 0x48, 0xFC, 0xFC, 0xFC, 0xFA, 0xFC,
-  0xFC, 0x21, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23,
-  0x22, 0x23, 0x21, 0x2A, 0x21, 0x23, 0x23, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22,
-  0x23, 0x22, 0x23, 0x22, 0x21, 0x4F, 0xE6, 0xC6,
-  0xC6, 0xBD, 0xC6, 0xBD, 0xBD, 0xBD, 0xBD, 0xC6,
-  0xC5, 0xBA, 0xC7, 0xE6, 0xF2, 0xD4, 0x49, 0x4B,
-  0x3E, 0x4D, 0x52, 0x3E, 0x52, 0x63, 0x64, 0x56,
-  0x48, 0x54, 0x4D, 0x61, 0xCC, 0xCC, 0x60, 0x60,
-  0x47, 0x4D, 0x5C, 0x53, 0x58, 0xCF, 0xD1, 0xCF,
-  0xD0, 0x59, 0x45, 0xFC, 0xFC, 0xFC, 0xEF, 0xF9,
-  0xFC, 0x21, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22,
-  0x23, 0x22, 0x23, 0x2A, 0x21, 0x23, 0x23, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22,
-  0x23, 0x22, 0x23, 0x22, 0x23, 0x4F, 0xE4, 0xB9,
-  0xAF, 0x80, 0x80, 0x8E, 0x8E, 0x8E, 0x8E, 0x8F,
-  0x80, 0xB4, 0xB9, 0xE4, 0x7F, 0xDE, 0x61, 0x52,
-  0x54, 0x48, 0x3F, 0x43, 0x4D, 0x56, 0x59, 0x4B,
-  0x3E, 0x58, 0x53, 0x61, 0xD3, 0xD4, 0xCF, 0xCD,
-  0x4C, 0x58, 0x5F, 0x53, 0x5E, 0xD3, 0xD0, 0xCE,
-  0xCE, 0x52, 0x3F, 0xFC, 0xFC, 0xFC, 0xF7, 0x65,
-  0xFA, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22,
-  0x23, 0x22, 0x21, 0x2A, 0x23, 0x23, 0x23, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22,
-  0x23, 0x22, 0x23, 0x22, 0x21, 0xB1, 0xE4, 0xE6,
-  0x7C, 0xB1, 0x7C, 0xB1, 0xB2, 0xB2, 0xB3, 0x3D,
-  0xB3, 0x3C, 0xE5, 0xB3, 0xB0, 0xF1, 0xD0, 0x58,
-  0x5D, 0x4D, 0x40, 0x41, 0x48, 0x51, 0x4C, 0x3F,
-  0x3F, 0x4D, 0x5A, 0x5A, 0xD5, 0xD9, 0xD7, 0xD4,
-  0x57, 0x5E, 0x61, 0x4C, 0x63, 0xD4, 0xCF, 0xCE,
-  0xCB, 0x4D, 0x4A, 0xFC, 0xFC, 0xFC, 0xFC, 0xF0,
-  0xFB, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22,
-  0x23, 0x22, 0x23, 0x2A, 0x21, 0x23, 0x23, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22,
-  0x22, 0x23, 0x22, 0x23, 0x23, 0xB1, 0x81, 0x7D,
-  0x39, 0x35, 0x35, 0x36, 0x36, 0x36, 0x36, 0x36,
-  0x36, 0x36, 0x7C, 0xB2, 0xB0, 0xDF, 0xD2, 0x57,
-  0x60, 0x59, 0x5B, 0x59, 0x52, 0x4C, 0x4A, 0x40,
-  0x42, 0x4A, 0x53, 0x4D, 0xD2, 0xDE, 0xDE, 0xD9,
-  0x5E, 0x5E, 0x60, 0x4A, 0xCD, 0xD1, 0xCF, 0xCE,
-  0x63, 0x49, 0x5C, 0xFB, 0xE8, 0x89, 0x9F, 0xFC,
-  0xD6, 0x21, 0x21, 0x23, 0x22, 0x22, 0x23, 0x22,
-  0x23, 0x22, 0x21, 0x2A, 0x22, 0x23, 0x23, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22,
-  0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x7F, 0xB9,
-  0x71, 0x6C, 0x38, 0x38, 0x33, 0x33, 0x33, 0x38,
-  0x38, 0x71, 0xAD, 0xE4, 0xD3, 0xDA, 0xCC, 0x52,
-  0x63, 0x60, 0xCE, 0xD4, 0xCF, 0x60, 0x4C, 0x40,
-  0x3F, 0x45, 0x4B, 0x5A, 0xCB, 0xD8, 0xDE, 0xDC,
-  0x5E, 0x5E, 0x5F, 0x4C, 0xD2, 0xD2, 0xCF, 0xCF,
-  0x61, 0x45, 0x5E, 0xA7, 0x9D, 0x95, 0x8B, 0x99,
-  0xFC, 0x41, 0x21, 0x23, 0x23, 0x22, 0x23, 0x22,
-  0x23, 0x22, 0x23, 0x2A, 0x23, 0x23, 0x23, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x77, 0x77, 0xF6,
-  0xFC, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7D,
-  0x7D, 0xFC, 0x47, 0x64, 0xD0, 0xD0, 0x5D, 0x4B,
-  0x62, 0xCC, 0xD1, 0xDE, 0xDE, 0xD4, 0x5E, 0x43,
-  0x3F, 0x3E, 0x48, 0x53, 0x58, 0xDB, 0xD8, 0xDC,
-  0x5E, 0x5E, 0x5E, 0x53, 0xD4, 0xD2, 0xD0, 0xD0,
-  0x5E, 0x49, 0xA7, 0xA6, 0x89, 0x95, 0x8B, 0x9C,
-  0x9C, 0xFB, 0xD4, 0x22, 0x22, 0x22, 0x22, 0x23,
-  0x22, 0x23, 0x23, 0x2A, 0x22, 0x23, 0x23, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23,
-  0x23, 0x22, 0x23, 0x23, 0x98, 0x8C, 0x8C, 0x88,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8,
-  0xE9, 0x9C, 0x48, 0x5C, 0xD0, 0xCB, 0x48, 0x49,
-  0x5B, 0xCB, 0xCD, 0xE0, 0xF1, 0xDD, 0xD0, 0x4A,
-  0x41, 0x47, 0x45, 0x4C, 0x48, 0xD7, 0xDE, 0xDC,
-  0x5E, 0x5E, 0x5A, 0x58, 0xD1, 0xD0, 0xD0, 0xD2,
-  0x5C, 0x55, 0xA7, 0xA6, 0x87, 0x86, 0x89, 0x94,
-  0x9C, 0xA9, 0xFC, 0xF4, 0x22, 0x23, 0x22, 0x23,
-  0x22, 0x23, 0x22, 0x2A, 0x21, 0x23, 0x23, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23,
-  0x22, 0x23, 0x22, 0x23, 0xA4, 0x89, 0x8C, 0xAA,
-  0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF7,
-  0x85, 0x88, 0x8D, 0x59, 0x64, 0x63, 0x47, 0x3E,
-  0x4C, 0x60, 0x61, 0xE0, 0xF0, 0xDF, 0xD9, 0x5D,
-  0x2E, 0x3E, 0x3E, 0x47, 0x4D, 0xCD, 0xDE, 0xDC,
-  0x5D, 0x5C, 0x51, 0x5D, 0xD1, 0xD2, 0xD2, 0xD4,
-  0x5A, 0xBE, 0xA7, 0x98, 0x8A, 0x8A, 0xA0, 0x8B,
-  0x86, 0x86, 0xF7, 0xFC, 0xF7, 0x26, 0x23, 0x23,
-  0x22, 0x22, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23,
-  0x22, 0x21, 0x21, 0x21, 0xA1, 0x98, 0x9F, 0xBF,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xA7,
-  0x8C, 0x86, 0x8D, 0x59, 0x5E, 0x5D, 0x3F, 0x3E,
-  0x47, 0x53, 0x63, 0xD9, 0xF0, 0xF1, 0xDE, 0xD0,
-  0x43, 0x3E, 0x47, 0x45, 0x4A, 0x5B, 0xDC, 0xDA,
-  0x5D, 0x59, 0x49, 0x5F, 0xD1, 0xD2, 0xD3, 0xB9,
-  0xA5, 0xA7, 0x98, 0x9B, 0x96, 0x9D, 0x89, 0x89,
-  0x8B, 0x9C, 0x9D, 0xFC, 0xFC, 0xFC, 0x26, 0x22,
-  0x23, 0x23, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23,
-  0x22, 0x22, 0x29, 0x2D, 0x99, 0x99, 0xA2, 0xAA,
-  0xC4, 0xFB, 0xFC, 0xFC, 0xFC, 0xF6, 0xBF, 0xA2,
-  0x9C, 0x9C, 0x8E, 0xDC, 0xCD, 0x51, 0x41, 0x3E,
-  0x45, 0x49, 0x58, 0xCD, 0xE0, 0xE0, 0xD8, 0xDA,
-  0x4C, 0x4A, 0x45, 0x45, 0x48, 0x47, 0xDA, 0xDA,
-  0x5C, 0x58, 0x44, 0x69, 0xA9, 0x98, 0xA4, 0xA6,
-  0xA1, 0xA4, 0x99, 0x9E, 0x9D, 0x8B, 0x8A, 0x97,
-  0x87, 0x9A, 0x8A, 0xC2, 0xFC, 0xFC, 0xFC, 0x4D,
-  0x21, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x22,
-  0x21, 0x22, 0x2D, 0x34, 0xA4, 0xA2, 0xA2, 0xA9,
-  0xBF, 0xC0, 0xC3, 0xC1, 0xC0, 0xBE, 0xA6, 0x9D,
-  0x99, 0x87, 0xA2, 0xF1, 0xDC, 0x64, 0x42, 0x45,
-  0x47, 0x3E, 0x49, 0x4C, 0xDD, 0xDF, 0xD8, 0xDB,
-  0x5E, 0x4C, 0x48, 0x45, 0x45, 0x41, 0xD1, 0xD6,
-  0x5A, 0x55, 0x3F, 0xA7, 0xA1, 0x98, 0x9F, 0x99,
-  0x9F, 0x9D, 0x9A, 0x95, 0x8B, 0x97, 0x89, 0x8A,
-  0x88, 0x94, 0x9C, 0x8C, 0xFC, 0xFC, 0xFC, 0xFC,
-  0xF4, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23,
-  0x23, 0x23, 0x2C, 0x2C, 0xA8, 0xA2, 0xA4, 0xA4,
-  0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xA6, 0x98, 0x9C,
-  0x8B, 0x88, 0x98, 0x8D, 0xD8, 0xD6, 0x4E, 0x47,
-  0x47, 0x49, 0x47, 0x3F, 0xDA, 0xDD, 0xDE, 0xDD,
-  0xCC, 0x4A, 0x4B, 0x3E, 0x45, 0x43, 0x61, 0xD4,
-  0x56, 0x51, 0x44, 0xA4, 0x9B, 0x8B, 0x9C, 0x9A,
-  0xA0, 0xA2, 0x98, 0x98, 0x8B, 0x8B, 0x98, 0x98,
-  0x84, 0x8B, 0x94, 0x8A, 0xA4, 0xFC, 0xFC, 0xFC,
-  0xFC, 0xF2, 0x21, 0x22, 0x21, 0x22, 0x23, 0x22,
-  0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x23,
-  0x23, 0x22, 0x2C, 0x2D, 0xC0, 0xA4, 0xA2, 0xA4,
-  0xA4, 0xA6, 0xA6, 0xA6, 0xA4, 0xA2, 0x9F, 0x89,
-  0x8B, 0x9C, 0x9C, 0x8B, 0x68, 0xDB, 0x5F, 0x4B,
-  0x3E, 0x49, 0x4B, 0x3E, 0xCC, 0xDA, 0xDC, 0xDD,
-  0xD3, 0x49, 0x52, 0x48, 0x45, 0x45, 0x53, 0xD0,
-  0x51, 0x4A, 0x44, 0xA4, 0x9B, 0x8B, 0x9C, 0xA0,
-  0x9B, 0x86, 0x89, 0x98, 0x89, 0x8A, 0x96, 0x8A,
-  0x9C, 0x89, 0x89, 0x9C, 0x8C, 0xF6, 0xFC, 0xFC,
-  0xFC, 0xFC, 0x21, 0x22, 0x21, 0x22, 0x23, 0x22,
-  0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x23,
-  0x22, 0x21, 0x2B, 0x34, 0xC0, 0xA8, 0xA4, 0xA2,
-  0xA2, 0x98, 0xA1, 0xA0, 0x98, 0x9F, 0x95, 0x8A,
-  0x94, 0xA1, 0x8A, 0x84, 0x9B, 0x68, 0xCC, 0x49,
-  0x4A, 0x47, 0x4C, 0x4B, 0x51, 0xD3, 0xDA, 0xDC,
-  0xD5, 0x56, 0x56, 0x4A, 0x3E, 0x45, 0x48, 0x63,
-  0x4A, 0x47, 0x3E, 0xA7, 0x98, 0x9D, 0x9E, 0x8B,
-  0x95, 0x9B, 0x89, 0x86, 0x9B, 0x8B, 0x89, 0x84,
-  0x9A, 0xA1, 0x95, 0x9A, 0x8C, 0xA4, 0xFC, 0xFC,
-  0xFC, 0xFA, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22,
-  0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x23,
-  0x21, 0x23, 0x2C, 0xF6, 0xBF, 0xA9, 0xA2, 0x99,
-  0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9B, 0x87, 0x8B,
-  0x9C, 0x86, 0x9C, 0x8A, 0x87, 0x87, 0x89, 0x51,
-  0x54, 0x47, 0x4B, 0x50, 0x4B, 0xCF, 0xD6, 0xDC,
-  0xD5, 0x60, 0x54, 0x52, 0x48, 0x45, 0x40, 0x5A,
-  0x45, 0x43, 0x47, 0xA7, 0x98, 0x9B, 0x95, 0x95,
-  0x9A, 0x87, 0x98, 0x98, 0x8A, 0x86, 0x87, 0x9E,
-  0x9B, 0x95, 0x9D, 0x9D, 0x99, 0x85, 0xA6, 0xFA,
-  0xF2, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22,
-  0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x22,
-  0x21, 0x24, 0xFB, 0xF7, 0xBF, 0xA6, 0xA2, 0x99,
-  0x97, 0x89, 0x86, 0x89, 0x9C, 0x96, 0x9E, 0x94,
-  0x89, 0x99, 0x98, 0x89, 0x9E, 0x9B, 0x89, 0x8B,
-  0x58, 0x4B, 0x4A, 0x52, 0x48, 0xCC, 0xD3, 0xDA,
-  0xD3, 0x65, 0x4C, 0x58, 0x49, 0x3E, 0x2E, 0x4D,
-  0x40, 0x41, 0x45, 0xA9, 0xA1, 0x9B, 0x9E, 0x9C,
-  0x95, 0x8A, 0x94, 0x89, 0x96, 0x87, 0x9C, 0x9A,
-  0x84, 0x9D, 0x9C, 0x9E, 0x9A, 0x9C, 0x9D, 0xBB,
-  0x23, 0x23, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22,
-  0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x23, 0x23,
-  0x24, 0xFC, 0xFC, 0xF6, 0xBF, 0xA6, 0x9F, 0x99,
-  0x89, 0x95, 0x87, 0x94, 0x9D, 0x9E, 0x97, 0x9E,
-  0x95, 0x9B, 0x89, 0x95, 0x95, 0x9B, 0x89, 0x87,
-  0x5D, 0x56, 0x3E, 0x51, 0x3E, 0x60, 0xCF, 0xD3,
-  0xD2, 0xCD, 0x5C, 0x49, 0x4B, 0x3E, 0x2C, 0x48,
-  0x3E, 0x43, 0x3E, 0xA9, 0xA1, 0x9B, 0x97, 0x94,
-  0x95, 0x9A, 0x9C, 0x87, 0x87, 0x9B, 0x9C, 0x95,
-  0x9D, 0x89, 0x9A, 0x89, 0x9E, 0x9E, 0x8C, 0xA6,
-  0x20, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22,
-  0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x20, 0x40,
-  0xFC, 0xFC, 0xFC, 0xEC, 0xBE, 0xA4, 0x9F, 0x99,
-  0x95, 0x9F, 0xA0, 0x88, 0x9D, 0x8B, 0x97, 0x95,
-  0x87, 0x95, 0x96, 0x95, 0x97, 0x94, 0x94, 0x98,
-  0xD3, 0x4C, 0x47, 0x4D, 0x42, 0x4C, 0x60, 0xCC,
-  0xCE, 0xD0, 0x65, 0x4B, 0x47, 0x44, 0x2B, 0x45,
-  0x4B, 0x47, 0x49, 0xA7, 0xA1, 0x9A, 0x97, 0x89,
-  0x95, 0x97, 0x97, 0x9E, 0x89, 0x95, 0x89, 0x9C,
-  0x87, 0x95, 0x97, 0x99, 0x95, 0x99, 0x9F, 0xA4,
-  0xC4, 0x21, 0x21, 0x23, 0x21, 0x23, 0x23, 0x23,
-  0x23, 0x23, 0x23, 0x23, 0x21, 0x20, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xEA, 0xAA, 0xA6, 0xA2, 0x99,
-  0x8B, 0x9A, 0x95, 0x9E, 0x9E, 0x9A, 0x94, 0x87,
-  0x94, 0x94, 0x89, 0x94, 0x9B, 0x9B, 0xA7, 0xDC,
-  0xDB, 0x65, 0x2E, 0x3E, 0x43, 0x44, 0x49, 0x58,
-  0x63, 0xD3, 0xD3, 0x5E, 0x42, 0x42, 0x2D, 0x40,
-  0x54, 0x4C, 0x4A, 0xA7, 0xA0, 0x99, 0x9B, 0x94,
-  0xA0, 0x8A, 0x9B, 0x9D, 0x87, 0x95, 0x94, 0x8B,
-  0x8A, 0x98, 0x9C, 0x8A, 0x9B, 0x99, 0xA2, 0xA6,
-  0xBF, 0xEC, 0x2A, 0x20, 0x21, 0x23, 0x21, 0x20,
-  0x20, 0x20, 0x20, 0x4C, 0xF9, 0xFC, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xEB, 0xAA, 0xA4, 0x9F, 0x9C,
-  0x8B, 0x9B, 0x88, 0x84, 0x9E, 0x9D, 0x96, 0x94,
-  0x94, 0x9A, 0x9B, 0x9B, 0xA4, 0xD5, 0xCD, 0xDE,
-  0xF1, 0xDA, 0x4C, 0x2D, 0x41, 0x2B, 0x42, 0x4C,
-  0x5E, 0xD4, 0xD7, 0xCD, 0x49, 0x2E, 0x2E, 0x41,
-  0x5E, 0x57, 0xA7, 0xA6, 0xA7, 0xA4, 0xA2, 0x98,
-  0x9D, 0x9C, 0xA1, 0x99, 0x9D, 0x88, 0x8B, 0x9C,
-  0x8A, 0x9C, 0x9C, 0x94, 0x9C, 0x89, 0xA0, 0xA6,
-  0xAA, 0xEB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFB, 0xE9, 0xAA, 0xA6, 0xA2, 0x8B,
-  0x8B, 0x8A, 0x86, 0x9B, 0x9C, 0x98, 0xA0, 0x9B,
-  0x9B, 0x84, 0xA7, 0xB4, 0x61, 0xD1, 0xD2, 0xE0,
-  0xF1, 0xDC, 0x61, 0x2D, 0x2E, 0x3F, 0x56, 0x62,
-  0x5D, 0xD4, 0xD9, 0xD3, 0x54, 0x41, 0x41, 0x44,
-  0xCB, 0x60, 0x52, 0xA9, 0xA9, 0xA9, 0xA7, 0xA6,
-  0xA6, 0xA4, 0xA4, 0xA2, 0xA2, 0x9D, 0x95, 0x89,
-  0x9C, 0x8A, 0x9E, 0x9C, 0x8A, 0x9E, 0xA0, 0xA8,
-  0xC0, 0xE9, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xE9, 0xAA, 0xA6, 0xA0, 0x99,
-  0x9C, 0x8B, 0x9A, 0x84, 0x9B, 0x9B, 0x98, 0x98,
-  0xA9, 0xB9, 0x49, 0x57, 0xCB, 0xD4, 0xD3, 0xF1,
-  0xD8, 0xDA, 0xCE, 0x3F, 0x41, 0x4B, 0x5D, 0xCB,
-  0x5E, 0xD6, 0xDB, 0xD6, 0x5D, 0x43, 0x3F, 0x49,
-  0xD1, 0xCC, 0x4F, 0xDD, 0xC3, 0xBB, 0xBF, 0xAA,
-  0xAA, 0xA9, 0xAA, 0xA8, 0xA8, 0xA6, 0xA6, 0xA2,
-  0x9C, 0x9F, 0x9B, 0x9A, 0x9D, 0xA2, 0xA8, 0xAA,
-  0xC1, 0xEA, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xEA, 0xC0, 0xAA, 0xA6, 0xA2,
-  0xA2, 0x99, 0xA0, 0xA0, 0xA4, 0xA7, 0xA9, 0xC0,
-  0x67, 0x49, 0x54, 0x60, 0xD0, 0xD4, 0xCC, 0xDF,
-  0xD9, 0xD5, 0xD2, 0x3E, 0x47, 0x56, 0x60, 0xCD,
-  0x5D, 0xD9, 0xD9, 0xD6, 0x61, 0x3F, 0x47, 0x52,
-  0xD6, 0xD3, 0x62, 0x4D, 0x40, 0x4A, 0x57, 0xCA,
-  0xC3, 0xC1, 0xC1, 0xC0, 0xBF, 0xBF, 0xAA, 0xAA,
-  0xA6, 0xA4, 0xA4, 0xA4, 0xA6, 0xA8, 0xBE, 0xC1,
-  0xC9, 0xEB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
-  0xFC, 0xFC, 0xFC, 0xEB, 0xC3, 0xC0, 0xAA, 0xA8,
-  0xA6, 0xA6, 0xA6, 0xA9, 0xAA, 0xC0, 0xE8, 0xD0,
-  0xD2, 0x4C, 0x5E, 0x64, 0xD0, 0xD1, 0x5F, 0xD9,
-  0xD5, 0xD1, 0xD0, 0x48, 0x52, 0x5C, 0x64, 0xCD,
-  0x5C, 0xDC, 0xD7, 0xD5, 0x62, 0x3F, 0x4C, 0x53,
-  0xDA, 0xD7, 0xCE, 0x56, 0x40, 0x4B, 0x52, 0x56,
-  0xCE, 0xDF, 0x6A, 0xEB, 0xE9, 0xC9, 0xC3, 0xC0,
-  0xC0, 0xBF, 0xBE, 0xAA, 0xBF, 0xC0, 0xC3, 0xC9,
-  0xEA, 0xF6, 0xEE, 0x58, 0x57, 0x5E, 0xD6, 0xD0,
-  0xD2, 0x61, 0xCB, 0xD6, 0xD6, 0xD4, 0xDF, 0xF3,
-  0xF2, 0xDD, 0xD7, 0xEB, 0xC9, 0xC1, 0xC0, 0xBF,
-  0xAA, 0xAA, 0xAA, 0xBE, 0xC3, 0xF0, 0xD2, 0xD2,
-  0xD2, 0x51, 0x62, 0xCC, 0xD0, 0xCC, 0x61, 0xD3,
-  0xCF, 0xCE, 0xD2, 0x48, 0x5A, 0x61, 0xCC, 0xCE,
-  0x5F, 0xD9, 0xD5, 0xD1, 0x63, 0x44, 0x56, 0x56,
-  0xDC, 0xD9, 0xD4, 0x5E, 0x42, 0x4A, 0x4C, 0x57,
-  0x5D, 0xD8, 0xE0, 0xD8, 0xDC, 0xCB, 0x66, 0xEC,
-  0xE8, 0xC3, 0xC3, 0xC3, 0xC3, 0xC9, 0xE8, 0xEA,
-  0xF6, 0x50, 0x3E, 0x58, 0x57, 0x5A, 0xD6, 0xD4,
-  0xCC, 0x4B, 0x53, 0x5C, 0x64, 0xD1, 0xDF, 0xF3,
-  0xF1, 0xDE, 0xD9, 0xF6, 0xEB, 0xC9, 0xC1, 0xC1,
-  0xC0, 0xC0, 0xC1, 0xC9, 0xF0, 0xD6, 0xCD, 0xD6,
-  0xD3, 0x53, 0xCB, 0xCF, 0xCD, 0x5F, 0x5F, 0xCE,
-  0xCF, 0xCD, 0xD0, 0x47, 0x5F, 0xCB, 0xCE, 0xCD,
-  0x63, 0xD6, 0xD3, 0xD1, 0x63, 0x3F, 0x58, 0x58,
-  0xDB, 0xDC, 0xDA, 0x65, 0x3E, 0x49, 0x49, 0x4D,
-  0x49, 0xDC, 0xDF, 0xE0, 0xDE, 0xD5, 0x47, 0x47,
-  0x46, 0x6B, 0xEB, 0xEA, 0xE9, 0xEA, 0xEB, 0xF6,
-  0xD0, 0x57, 0x57, 0x47, 0x47, 0x5B, 0xD4, 0xD4,
-  0xCD, 0x44, 0x3E, 0x4B, 0x50, 0x4B, 0x51, 0xD5,
-  0xDB, 0xD8, 0xDE, 0x4B, 0xF6, 0xF6, 0xEA, 0xE9,
-  0xE8, 0xEA, 0xEB, 0x67, 0x5E, 0xCC, 0xD6, 0xDC,
-  0xD5, 0x58, 0xCE, 0xCE, 0x62, 0x50, 0xCC, 0xD3,
-  0xD2, 0xCD, 0xCD, 0x4B, 0x64, 0xCE, 0xCE, 0x64,
-  0xCC, 0xD3, 0xD2, 0xD2, 0x61, 0x47, 0x5D, 0x5C,
-  0xDD, 0xDD, 0xD9, 0xD1, 0x4C, 0x47, 0x49, 0x4A,
-  0x4B, 0xD1, 0xD8, 0xE0, 0xDF, 0xDD, 0x5D, 0x4A,
-  0x48, 0x52, 0x51, 0x3F, 0xF6, 0xEC, 0xE0, 0xE0,
-  0xD3, 0x5E, 0x5F, 0x50, 0x4B, 0x50, 0xCB, 0xCE,
-  0x64, 0x45, 0x4C, 0x57, 0x57, 0x58, 0x52, 0xD6,
-  0xD3, 0xDE, 0xDF, 0xD1, 0x3E, 0x4B, 0xF6, 0xF6,
-  0xEC, 0x66, 0x53, 0x43, 0x56, 0xD1, 0xD9, 0xDE,
-  0xD4, 0x5E, 0xCE, 0xCC, 0x5B, 0x2C, 0xD4, 0xD5,
-  0xD2, 0xD0, 0x63, 0x5D, 0xCD, 0xD0, 0xCD, 0x5E,
-  0xD0, 0xCF, 0xCE, 0xD2, 0x5E, 0x50, 0x60, 0x5D,
-  0xDE, 0xDD, 0xDC, 0xD7, 0x5D, 0x45, 0x47, 0x3E,
-  0x4B, 0x5E, 0xDE, 0xDF, 0xE0, 0xD8, 0xCF, 0x3E,
-  0x45, 0x51, 0x58, 0x42, 0xCB, 0xDA, 0xDE, 0xD8,
-  0xD2, 0x61, 0xCC, 0xCF, 0xD6, 0xDA, 0xDA, 0xD5,
-  0xD0, 0x50, 0x44, 0x57, 0x57, 0x58, 0x45, 0xD1,
-  0xD1, 0xD7, 0xDF, 0xDF, 0xD7, 0xCF, 0x64, 0x60,
-  0xCE, 0xCE, 0xCE, 0x63, 0xCF, 0xDA, 0xDE, 0xD9,
-  0xCF, 0x63, 0xCD, 0x63, 0x4D, 0x4B, 0xD6, 0xD5,
-  0xCE, 0xD3, 0x60, 0xCB, 0xD0, 0xD0, 0x65, 0x47,
-  0xD0, 0xCC, 0xCC, 0xD1, 0x59, 0x5D, 0x63, 0x5E,
-  0xDD, 0xDD, 0xDE, 0xDC, 0xCB, 0x40, 0x48, 0x45,
-  0x3E, 0x3E, 0xD9, 0xDF, 0xE0, 0xDF, 0xDA, 0x51,
-  0x4C, 0x48, 0x56, 0x4C, 0x5B, 0xD2, 0xDA, 0xDB,
-  0xCB, 0x5F, 0xD0, 0xCC, 0xDC, 0xF0, 0xF3, 0xE0,
-  0xDD, 0xCC, 0x41, 0x50, 0x57, 0x57, 0x4B, 0x5D,
-  0xD3, 0xD1, 0xDE, 0xDF, 0xDE, 0xD7, 0xD0, 0xD0,
-  0xD5, 0xD6, 0xD6, 0xCE, 0xD7, 0xDC, 0xDA, 0xD5,
-  0x60, 0x63, 0x64, 0x5E, 0x47, 0x61, 0xD5, 0xD2,
-  0xCF, 0xD0, 0x59, 0xCD, 0xD1, 0xCF, 0x61, 0x4D,
-  0xCC, 0xCE, 0xCD, 0xD0, 0x52, 0x61, 0x64, 0x60,
-  0xDA, 0xDE, 0xDE, 0xDD, 0xD1, 0x4B, 0x4A, 0x45,
-  0x3E, 0x41, 0xCD, 0xDE, 0xE0, 0xF1, 0xDE, 0x63,
-  0x4A, 0x4A, 0x4A, 0x4B, 0x50, 0xCB, 0xD4, 0xD7,
-  0x5E, 0x54, 0x62, 0xD3, 0xD4, 0xF0, 0xF3, 0xF3,
-  0xF2, 0xDE, 0x61, 0x40, 0x49, 0x56, 0x4D, 0x3E,
-  0x4B, 0xCE, 0xD9, 0xD8, 0xD9, 0xD5, 0xCF, 0xD2,
-  0xD6, 0xD6, 0xD1, 0xD1, 0xD7, 0xD5, 0xCF, 0xD0,
-  0x54, 0x64, 0x63, 0x56, 0x2C, 0xCB, 0xD1, 0xCC,
-  0xD3, 0xCD, 0x54, 0xCF, 0xD1, 0xCE, 0x5E, 0x5C,
-  0xCE, 0xCE, 0xCE, 0xCB, 0x4B, 0x63, 0xCC, 0x61,
-  0xD4, 0xDC, 0xDE, 0xDE, 0xDA, 0x5D, 0x45, 0x45,
-  0x48, 0x3F, 0x52, 0xD9, 0xD8, 0xDF, 0xDF, 0xD2,
-  0x52, 0x4B, 0x3E, 0x2E, 0x47, 0x60, 0xCF, 0xD3,
-  0x59, 0x48, 0x50, 0x5E, 0xCC, 0xDE, 0xF2, 0xF2,
-  0xF3, 0xF3, 0xDD, 0x5D, 0x3E, 0x48, 0x47, 0x47,
-  0x58, 0xD1, 0xDA, 0xDA, 0xD5, 0xD1, 0xCD, 0xD2,
-  0xD3, 0xCF, 0xD3, 0xD1, 0xCD, 0xD3, 0xD2, 0x5E,
-  0x52, 0x64, 0x60, 0x4B, 0x45, 0x61, 0xCD, 0xD3,
-  0xD3, 0x64, 0x61, 0xD0, 0xD0, 0x64, 0x45, 0x63,
-  0xD0, 0xCE, 0xD0, 0x60, 0x56, 0xCB, 0xCC, 0x62,
-  0xCE, 0xDA, 0xDE, 0xD8, 0xDD, 0xCC, 0x45, 0x49,
-  0x3E, 0x47, 0x42, 0xD1, 0xDC, 0xD8, 0xD8, 0xD3,
-  0x5D, 0x4C, 0x49, 0x3F, 0x47, 0x59, 0xCD, 0xCF,
-  0x59, 0x2E, 0x48, 0x47, 0x52, 0x63, 0xF0, 0xF2,
-  0xF3, 0xF3, 0xF2, 0xDA, 0x52, 0x4B, 0x52, 0x58,
-  0x5E, 0x63, 0xD0, 0xD0, 0xD0, 0xCF, 0xCE, 0xCE,
-  0xCF, 0x65, 0x61, 0xD6, 0xD6, 0xD6, 0xCB, 0x4B,
-  0x61, 0x62, 0x5D, 0x43, 0x4B, 0x61, 0xD0, 0xD4,
-  0xD1, 0x61, 0xCE, 0xD2, 0xCD, 0x5E, 0x4A, 0xCE,
-  0xD0, 0xCC, 0xD0, 0x59, 0x61, 0xCC, 0xCC, 0x62,
-  0xD1, 0xD5, 0xDE, 0xD8, 0xDD, 0xCF, 0x4B, 0x4A,
-  0x45, 0x3E, 0x2D, 0xCB, 0xDC, 0xDE, 0xD8, 0xD5,
-  0x60, 0x54, 0x51, 0x4C, 0x4D, 0x5C, 0xCC, 0xCE,
-  0x5A, 0x2C, 0x50, 0x53, 0x3E, 0x59, 0xD8, 0xF3,
-  0xF2, 0xF3, 0xF3, 0xE0, 0x5E, 0x4A, 0x4C, 0x53,
-  0x5E, 0x63, 0xCC, 0xCC, 0xCC, 0xCD, 0xCF, 0xD3,
-  0x62, 0x53, 0xD6, 0xD6, 0xD6, 0xD6, 0x5B, 0x48,
-  0x64, 0x63, 0x59, 0x44, 0x57, 0x63, 0xD2, 0xD3,
-  0xD0, 0x5E, 0xD0, 0xD1, 0xCB, 0x58, 0x4C, 0xCF,
-  0xCF, 0xCE, 0xCE, 0x57, 0x63, 0xCC, 0xCD, 0x57,
-};
-
diff -u --recursive --new-file v2.4.5/linux/drivers/sound/aci.c linux/drivers/sound/aci.c
--- v2.4.5/linux/drivers/sound/aci.c	Fri Apr 13 20:26:07 2001
+++ linux/drivers/sound/aci.c	Tue Jun 12 10:56:11 2001
@@ -45,6 +45,8 @@
  *        ioctl bugfix, and integration of solo-mode into OSS-API,
  *        added (OSS-limited) equalizer support, return value bugfix,
  *        changed param aci_reset to reset, new params: ide, wss.
+ *   2001-04-20  Robert Siemer
+ *        even more cleanups...
  */
 
 #include <linux/kernel.h>
@@ -95,17 +97,19 @@
 MODULE_PARM_DESC(wss,"change between ACI/WSS-mixer; use 0 and 1 - untested"
 		 " default: do nothing; for PCM1-pro only");
 
+#if DEBUG
 static void print_bits(unsigned char c)
 {
 	int j;
 	printk(KERN_DEBUG "aci: ");
 
 	for (j=7; j>=0; j--) {
-		printk(KERN_DEBUG "%d", (c >> j) & 0x1);
+		printk("%d", (c >> j) & 0x1);
 	}
 
-	printk(KERN_DEBUG "\n");
+	printk("\n");
 }
+#endif
 
 /*
  * This busy wait code normally requires less than 15 loops and
@@ -269,12 +273,12 @@
 	int buf;
 
 	/* left channel */
-	if ((buf=aci_indexed_cmd(0xf0, left_index))<0)
+	if ((buf=aci_indexed_cmd(ACI_STATUS, left_index))<0)
 		return buf;
 	vol = SCALE(0x20, 100, buf < 0x20 ? 0x20-buf : 0);
 	
 	/* right channel */
-	if ((buf=aci_indexed_cmd(0xf0, right_index))<0)
+	if ((buf=aci_indexed_cmd(ACI_STATUS, right_index))<0)
 		return buf;
 	vol |= SCALE(0x20, 100, buf < 0x20 ? 0x20-buf : 0) << 8;
 
@@ -342,12 +346,12 @@
 	unsigned int vol;
 
 	/* left channel */
-	if ((buf=aci_indexed_cmd(0xf0, left_index))<0)
+	if ((buf=aci_indexed_cmd(ACI_STATUS, left_index))<0)
 		return buf;
 	vol = eq_aci2oss(buf);
 	
 	/* right channel */
-	if ((buf=aci_indexed_cmd(0xf0, right_index))<0)
+	if ((buf=aci_indexed_cmd(ACI_STATUS, right_index))<0)
 		return buf;
 	vol |= eq_aci2oss(buf) << 8;
 
@@ -399,7 +403,7 @@
 			if (vol > 100)
 				vol = 100;
 			vol = SCALE(100, 3, vol);
-			if ((buf=aci_write_cmd(0x03, vol))<0)
+			if ((buf=aci_write_cmd(ACI_WRITE_IGAIN, vol))<0)
 				return buf;
 			aci_micpreamp = vol;
 			vol = SCALE(3, 100, vol);
@@ -416,7 +420,7 @@
 				vol = 1;
 			else
 				vol = 0;
-			if ((buf=aci_write_cmd(0x0f, vol))<0)
+			if ((buf=aci_write_cmd(ACI_SET_POWERAMP, vol))<0)
 				return buf;
 			aci_amp = vol;
 			if (aci_amp)
@@ -433,7 +437,7 @@
 		/* unset solo when RECSRC for PCM is requested */
 		if (aci_idcode[1]=='B' || aci_idcode[1]=='C') {
 			vol = !(buf & SOUND_MASK_PCM);
-			if ((buf=aci_write_cmd(0xd2, vol))<0)
+			if ((buf=aci_write_cmd(ACI_SET_SOLOMODE, vol))<0)
 				return buf;
 			aci_solo = vol;
 		}
@@ -502,7 +506,8 @@
 		case 'B': /* PCM12 */
 		case 'C': /* PCM20 radio */
 			if (aci_version >= 0xb0) {
-				if ((vol=aci_rw_cmd(0xf0, 0x00, -1))<0)
+				if ((vol=aci_rw_cmd(ACI_STATUS,
+						    ACI_S_GENERAL, -1))<0)
 					return vol;
 				if (vol & 0x20)
 					buf |= SOUND_MASK_PCM;
@@ -555,7 +560,8 @@
 		if (aci_idcode[1]=='B' || aci_idcode[1]=='C') {
 			/* aci_micpreamp or ACI? */
 			if (aci_version >= 0xb0) {
-				if ((buf=aci_indexed_cmd(0xf0, 0x21))<0)
+				if ((buf=aci_indexed_cmd(ACI_STATUS,
+							 ACI_S_READ_IGAIN))<0)
 					return buf;
 			}
 			else
@@ -612,17 +618,17 @@
 
 	/* force ACI into a known state */
 	for (i=0; i<3; i++)
-		if (aci_rw_cmd(0xdf, -1, -1)<0)
+		if (aci_rw_cmd(ACI_ERROR_OP, -1, -1)<0)
 			return -EFAULT;
 
 	/* official this is one aci read call: */
-	if ((aci_idcode[0]=aci_rw_cmd(0xf2, -1, -1))<0 ||
-	    (aci_idcode[1]=aci_rw_cmd(0xf2, -1, -1))<0) {
+	if ((aci_idcode[0]=aci_rw_cmd(ACI_READ_IDCODE, -1, -1))<0 ||
+	    (aci_idcode[1]=aci_rw_cmd(ACI_READ_IDCODE, -1, -1))<0) {
 		printk(KERN_ERR "aci: Failed to read idcode on 0x%03x.\n", aci_port);
 		return -EFAULT;
 	}
 
-	if ((aci_version=aci_rw_cmd(0xf1, -1, -1))<0) {
+	if ((aci_version=aci_rw_cmd(ACI_READ_VERSION, -1, -1))<0) {
 		printk(KERN_ERR "aci: Failed to read version on 0x%03x.\n", aci_port);
 		return -EFAULT;
 	}
@@ -656,22 +662,22 @@
 
 	if (reset) {
 		/* first write()s after reset fail with my PCM20 */
-		if (aci_rw_cmd(0xff, -1, -1)<0 ||
-		    aci_rw_cmd(0xdf, 0xdf, 0xdf)<0 ||
-		    aci_rw_cmd(0xdf, 0xdf, 0xdf)<0)
+		if (aci_rw_cmd(ACI_INIT, -1, -1)<0 ||
+		    aci_rw_cmd(ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP)<0 ||
+		    aci_rw_cmd(ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP)<0)
 			return -EBUSY;
 	}
 
 	/* the PCM20 is muted after reset (and reboot) */
-	if (aci_rw_cmd(0x0d, 0x00, -1)<0)
+	if (aci_rw_cmd(ACI_SET_MUTE, 0x00, -1)<0)
 		return -EBUSY;
 
 	if (ide>=0)
-		if (aci_rw_cmd(0xd0, !ide, -1)<0)
+		if (aci_rw_cmd(ACI_SET_IDE, !ide, -1)<0)
 			return -EBUSY;
 	
 	if (wss>=0 && aci_idcode[1]=='A')
-		if (aci_rw_cmd(0xd1, !!wss, -1)<0)
+		if (aci_rw_cmd(ACI_SET_WSS, !!wss, -1)<0)
 			return -EBUSY;
 
 	if (!request_region(aci_port, 3, "sound mixer (ACI)"))
diff -u --recursive --new-file v2.4.5/linux/drivers/sound/aci.h linux/drivers/sound/aci.h
--- v2.4.5/linux/drivers/sound/aci.h	Fri Apr 13 20:26:07 2001
+++ linux/drivers/sound/aci.h	Tue Jun 12 10:56:11 2001
@@ -6,9 +6,6 @@
 extern int aci_version;		/* ACI firmware version	*/
 extern int aci_rw_cmd(int write1, int write2, int write3);
 
-extern char * aci_radio_name;
-extern int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize);
-
 #define aci_indexed_cmd(a, b) aci_rw_cmd(a, b, -1)
 #define aci_write_cmd(a, b)   aci_rw_cmd(a, b, -1)
 #define aci_read_cmd(a)       aci_rw_cmd(a,-1, -1)
@@ -19,15 +16,24 @@
 
 #define RDS_REGISTER        BUSY_REGISTER
 
-#define RDS_STATUS      0x01
-#define RDS_STATIONNAME 0x02
-#define RDS_TEXT        0x03
-#define RDS_ALTFREQ     0x04
-#define RDS_TIMEDATE    0x05
-#define RDS_PI_CODE     0x06
-#define RDS_PTYTATP     0x07
-#define RDS_RESET       0x08
-#define RDS_RXVALUE     0x09
+#define ACI_SET_MUTE          0x0d
+#define ACI_SET_POWERAMP      0x0f
+#define ACI_SET_TUNERMUTE     0xa3
+#define ACI_SET_TUNERMONO     0xa4
+#define ACI_SET_IDE           0xd0
+#define ACI_SET_WSS           0xd1
+#define ACI_SET_SOLOMODE      0xd2
+#define ACI_WRITE_IGAIN       0x03
+#define ACI_WRITE_TUNE        0xa7
+#define ACI_READ_TUNERSTEREO  0xa8
+#define ACI_READ_TUNERSTATION 0xa9
+#define ACI_READ_VERSION      0xf1
+#define ACI_READ_IDCODE       0xf2
+#define ACI_INIT              0xff
+#define ACI_STATUS            0xf0
+#define     ACI_S_GENERAL     0x00
+#define     ACI_S_READ_IGAIN  0x21
+#define ACI_ERROR_OP          0xdf
 
 /*
  * The following macro SCALE can be used to scale one integer volume
@@ -47,9 +53,6 @@
  */
 
 #define SCALE(xmax,ymax,x) (((x)*(ymax)+(xmax)/2)/(xmax))
-
-extern void __exit unload_aci_rds(void);
-extern int __init attach_aci_rds(void);
 
 
 #endif  /* _ACI_H_ */
diff -u --recursive --new-file v2.4.5/linux/drivers/sound/cmpci.c linux/drivers/sound/cmpci.c
--- v2.4.5/linux/drivers/sound/cmpci.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/sound/cmpci.c	Wed Jun 27 17:10:55 2001
@@ -1,12 +1,16 @@
 /*****************************************************************************/
-
 /*
  *      cmpci.c  --  C-Media PCI audio driver.
  *
- *      Copyright (C) 1999  ChenLi Tien (cltien@home.com)
+ *      Copyright (C) 1999  ChenLi Tien (cltien@cmedia.com.tw)
+ *      		    C-media support (support@cmedia.com.tw)
  *
- *	Based on the PCI drivers by Thomas Sailer (sailer@ife.ee.ethz.ch)
+ *      Based on the PCI drivers by Thomas Sailer (sailer@ife.ee.ethz.ch)
  *
+ * 	For update, visit:
+ * 		http://members.home.net/puresoft/cmedia.html
+ * 		http://www.cmedia.com.tw
+ * 	
  *      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
@@ -57,8 +61,6 @@
  *                     reported by Johan Maes <joma@telindus.be>
  *    22.03.99   0.12  return EAGAIN instead of EBUSY when O_NONBLOCK
  *                     read/write cannot be executed
- *    20 09 99   0.13  merged the generic changes in sonicvibes since this
- *		       diverged.
  *    18.08.99   1.5   Only deallocate DMA buffer when unloading.
  *    02.09.99   1.6   Enable SPDIF LOOP
  *                     Change the mixer read back
@@ -66,47 +68,32 @@
  *                     Add support for modem, S/PDIF loop and 4 channels.
  *                     (8738 only)
  *                     Fix bug cause x11amp cannot play.
- *    $Log: cmpci.c,v $
- *    Revision 2.41  1999/10/27 02:00:05  cltien
- *    Now the fragsize for modem is activated by parameter.
- *
- *    Revision 2.40  1999/10/26 23:38:26  cltien
- *    Remove debugging message in cm_write which may cause module counter not 0.
- *
- *    Revision 2.39  1999/10/26 21:52:50  cltien
- *    I forgor too adjust mic recording volume, as it should be moved to 5MUTEMONO.
- *    Change the DYNAMIC macro to FIXEDDMA, which means static DMA buffer.
- *
- *    Revision 2.38  1999/10/08 21:59:03  cltien
- *    Set FLINKON and reset FLINKOFF for modem.
- *
- *    Revision 2.37  1999/09/28 02:57:04  cltien
- *    Add set_bus_master() to make sure bus master enabled.
- *
- *    Revision 2.36  1999/09/22 14:15:03  cltien
- *    Use open_sem to avoid multiple access to open_mode.
- *    Use wakeup in IntrClose to activate process in waiting queue.
- *
- *    Revision 2.35  1999/09/22 13:20:53  cltien
- *    Use open_mode to check if DAC in used. Also more check in IntrWrite and IntrClose. Now the modem can access DAC safely.
- *
- *    Revision 2.34  1999/09/22 03:29:57  cltien
- *    Use module count to decide which one to access the dac.
  *
+ *    Fixes:
+ *    Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *    18/05/2001 - .bss nitpicks, fix a bug in set_dac_channels where it
+ *    		   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
  *
  */
- 
+
 /*****************************************************************************/
       
-#include <linux/config.h>
+#define EXPORT_SYMTAB
 #include <linux/version.h>
+#include <linux/config.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/slab.h>
+#include <linux/malloc.h>
 #include <linux/soundcard.h>
 #include <linux/pci.h>
 #include <linux/wrapper.h>
@@ -139,6 +126,9 @@
 #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)
 
@@ -217,14 +207,14 @@
 #define CM_CFMT_STEREO     0x01
 #define CM_CFMT_16BIT      0x02
 #define CM_CFMT_MASK       0x03
-#define CM_CFMT_DACSHIFT   0   
-#define CM_CFMT_ADCSHIFT   2
+#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 };
 
-#define CM_CENABLE_RE      0x2
-#define CM_CENABLE_PE      0x1
+#define CM_ENABLE_CH1      0x2
+#define CM_ENABLE_CH0      0x1
 
 
 /* MIDI buffer sizes */
@@ -238,6 +228,8 @@
 
 #define FMODE_DMFM 0x10
 
+#define SND_DEV_DSP16   5 
+
 /* --------------------------------------------------------------------- */
 
 struct cm_state {
@@ -255,6 +247,7 @@
 
 	/* hardware resources */
 	unsigned int iosb, iobase, iosynth, iomidi, iogame, irq;
+	unsigned short deviceid;
 
         /* mixer stuff */
         struct {
@@ -275,6 +268,7 @@
 
 	struct dmabuf {
 		void *rawbuf;
+		unsigned rawphys;
 		unsigned buforder;
 		unsigned numfrag;
 		unsigned fragshift;
@@ -307,12 +301,48 @@
 		unsigned char ibuf[MIDIINBUF];
 		unsigned char obuf[MIDIOUTBUF];
 	} midi;
+	
+	/* misc stuff */
+	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
+	
+	/* spdif frame counter */
+	int	spdif_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
+
+/* 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
+
 /* --------------------------------------------------------------------- */
 
-static struct cm_state *devs = NULL;
-static unsigned long wavetable_mem = 0;
+static struct cm_state *devs;
+static unsigned long wavetable_mem;
 
 /* --------------------------------------------------------------------- */
 
@@ -361,35 +391,76 @@
 
 /* --------------------------------------------------------------------- */
 
-static void set_dmadac(struct cm_state *s, unsigned int addr, unsigned int count)
+/*
+ * 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)
 {
-	count--;
-	outl(addr, s->iobase + CODEC_CMI_CH0_FRAME1);
-	outw(count, s->iobase + CODEC_CMI_CH0_FRAME2);
-	outb(inb(s->iobase + CODEC_CMI_FUNCTRL0) & ~1, s->iobase + CODEC_CMI_FUNCTRL0);
-//	outb(inb(s->iobase + CODEC_CMI_FUNCTRL0 + 2) | 1, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+	outb((inb(addr) & mask) | value, addr);
+}
+
+static void maskw(unsigned int addr, unsigned int mask, unsigned int value)
+{
+	outw((inw(addr) & mask) | value, addr);
+}
+
+static void maskl(unsigned int addr, unsigned int mask, unsigned int value)
+{
+	outl((inl(addr) & mask) | value, addr);
+}
+
+static void set_dmadac1(struct cm_state *s, unsigned int addr, unsigned int count)
+{
+	if (addr)
+	    outl(addr, s->iobase + CODEC_CMI_CH0_FRAME1);
+	outw(count - 1, s->iobase + CODEC_CMI_CH0_FRAME2);
+	maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~1, 0);
 }
 
 static void set_dmaadc(struct cm_state *s, unsigned int addr, unsigned int count)
 {
-	count--;
+	outl(addr, s->iobase + CODEC_CMI_CH0_FRAME1);
+	outw(count - 1, s->iobase + CODEC_CMI_CH0_FRAME2);
+	maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~0, 1);
+}
+
+static void set_dmadac(struct cm_state *s, unsigned int addr, unsigned int count)
+{
 	outl(addr, s->iobase + CODEC_CMI_CH1_FRAME1);
-	outw(count, s->iobase + CODEC_CMI_CH1_FRAME2);
-	outb(inb(s->iobase + CODEC_CMI_FUNCTRL0) | 2, s->iobase + CODEC_CMI_FUNCTRL0);
-//	outb(inb(s->iobase + CODEC_CMI_FUNCTRL0 + 2) | 2, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+	outw(count - 1, s->iobase + CODEC_CMI_CH1_FRAME2);
+	maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~2, 0);
+	if (s->status & DO_DUAL_DAC)
+		set_dmadac1(s, 0, count);
+}
+
+static void set_countadc(struct cm_state *s, unsigned count)
+{
+	outw(count - 1, s->iobase + CODEC_CMI_CH0_FRAME2 + 2);
+}
+
+static void set_countdac(struct cm_state *s, unsigned count)
+{
+	outw(count - 1, s->iobase + CODEC_CMI_CH1_FRAME2 + 2);
+	if (s->status & DO_DUAL_DAC)
+	    set_countadc(s, count);
 }
 
 extern __inline__ unsigned get_dmadac(struct cm_state *s)
 {
 	unsigned int curr_addr;
 
-	if (!s->dma_dac.dmasize || !(s->enable & CM_CENABLE_PE))
-		return 0;
-
-	curr_addr = inl(s->iobase + CODEC_CMI_CH0_FRAME1);
-	curr_addr -= virt_to_bus(s->dma_dac.rawbuf);
+#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;
 }
 
@@ -397,22 +468,22 @@
 {
 	unsigned int curr_addr;
 
-	if (!s->dma_adc.dmasize || !(s->enable & CM_CENABLE_RE))
-		return 0;
-
-	curr_addr = inl(s->iobase + CODEC_CMI_CH1_FRAME1);
-	curr_addr -= virt_to_bus(s->dma_adc.rawbuf);
+#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)
@@ -420,33 +491,31 @@
 	unsigned char v;
 
 	outb(idx, s->iobase + CODEC_SB16_ADDR);
-	udelay(10);
 	v = inb(s->iobase + CODEC_SB16_DATA);
-	udelay(10);
 	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);
+	s->fmt = (s->fmt & mask) | data;
+	outb(s->fmt, s->iobase + CODEC_CMI_CHFORMAT);
+}
+
 static void set_fmt(struct cm_state *s, unsigned char mask, unsigned char data)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&s->lock, flags);
-	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);
+	set_fmt_unlocked(s,mask,data);
 	spin_unlock_irqrestore(&s->lock, flags);
-	udelay(10);
 }
 
 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 {
@@ -463,125 +532,461 @@
 	{ 22050,	(16000 + 22050) / 2,	(22050 + 32000) / 2,	2 },
 	{ 32000,	(22050 + 32000) / 2,	(32000 + 44100) / 2,	6 },
 	{ 44100,	(32000 + 44100) / 2,	(44100 + 48000) / 2,	3 },
-	{ 48000,	(44100 + 48000) /2,	48000,			7 }
+	{ 48000,	(44100 + 48000) / 2,	48000,			7 }
 };
 
-static void set_dac_rate(struct cm_state *s, unsigned rate)
+static void set_spdifout_unlocked(struct cm_state *s, unsigned rate)
+{
+	if (rate == 48000 || rate == 44100) {
+		// SPDIFI48K SPDF_ACc97
+		maskl(s->iobase + CODEC_CMI_MISC_CTRL, ~0x01008000, rate == 48000 ? 0x01008000 : 0);
+		// ENSPDOUT
+		maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2, ~0, 0x80);
+		// SPDF_1 SPD2DAC
+		maskw(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x240);
+		// CDPLAY
+		if (s->chip_version >= 39)
+			maskb(s->iobase + CODEC_CMI_MIXER1, ~0, 1);
+		s->status |= DO_SPDIF_OUT;
+	} else {
+		maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2, ~0x80, 0);
+		maskw(s->iobase + CODEC_CMI_FUNCTRL1, ~0x240, 0);
+		if (s->chip_version >= 39)
+			maskb(s->iobase + CODEC_CMI_MIXER1, ~1, 0);
+		s->status &= ~DO_SPDIF_OUT;
+	}
+}
+
+static void set_spdifout(struct cm_state *s, unsigned rate)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&s->lock, flags);
+	set_spdifout_unlocked(s,rate);
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+/* find parity for bit 4~30 */
+static unsigned parity(unsigned data)
+{
+	unsigned parity = 0;
+	int counter = 4;
+
+	data >>= 4;	// start from bit 4
+	while (counter <= 30) {
+		if (data & 1)
+			parity++;
+		data >>= 1;
+		counter++;
+	}
+	return parity & 1;
+}
+
+static void set_ac3_unlocked(struct cm_state *s, unsigned rate)
+{
+	/* enable AC3 */
+	if (rate == 48000 || rate == 44100) {
+		// mute DAC
+		maskb(s->iobase + CODEC_CMI_MIXER1, ~0, 0x40);
+		// AC3EN for 037, 0x10
+		maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, 0x10);
+		// AC3EN for 039, 0x04
+		maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, 0x04);
+		if (s->capability & CAN_AC3_HW) {
+			// SPD24SEL for 037, 0x02
+			// SPD24SEL for 039, 0x20, but cannot be set
+			maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, 0x02);
+			s->status |= DO_AC3_HW;
+			if (s->chip_version >= 39)
+				maskb(s->iobase + CODEC_CMI_MIXER1, ~1, 0);
+		 } else {
+			// SPD32SEL for 037 & 039, 0x20
+			maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, 0x20);
+			// set 176K sample rate to fix 033 HW bug
+			if (s->chip_version == 33) {
+				if (rate == 48000)
+					maskb(s->iobase + CODEC_CMI_CHFORMAT + 1, ~0, 0x08);
+				else
+					maskb(s->iobase + CODEC_CMI_CHFORMAT + 1, ~0x08, 0);
+			}
+			s->status |= DO_AC3_SW;
+		}
+	} else {
+		maskb(s->iobase + CODEC_CMI_MIXER1, ~0x40, 0);
+		maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0x32, 0);
+		maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0x24, 0);
+		maskb(s->iobase + CODEC_CMI_CHFORMAT + 1, ~0x08, 0);
+		if (s->chip_version == 33)
+			maskb(s->iobase + CODEC_CMI_CHFORMAT + 1, ~0x08, 0);
+		if (s->chip_version >= 39)
+			maskb(s->iobase + CODEC_CMI_MIXER1, ~0, 1);
+		s->status &= ~DO_AC3;
+	}
+	s->spdif_counter = 0;
+
+}
+
+static void set_ac3(struct cm_state *s, unsigned rate)
 {
 	unsigned long flags;
-	unsigned char freq = 4, val;
+
+	spin_lock_irqsave(&s->lock, flags);
+	set_spdifout_unlocked(s, rate);
+	set_ac3_unlocked(s,rate);
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+static void trans_ac3(struct cm_state *s, void *dest, const char *source, int size)
+{
+	int   i = size / 2;
+	unsigned long data;
+	unsigned long *dst = (unsigned long *) dest;
+	unsigned short *src = (unsigned short *)source;
+
+	do {
+		data = (unsigned long) *src++;
+		data <<= 12;			// ok for 16-bit data
+		if (s->spdif_counter == 2 || s->spdif_counter == 3)
+			data |= 0x40000000;	// indicate AC-3 raw data
+		if (parity(data))
+			data |= 0x80000000;	// parity
+		if (s->spdif_counter == 0)
+			data |= 3;		// preamble 'M'
+		else if (s->spdif_counter & 1)
+			data |= 5;		// odd, 'W'
+		else
+			data |= 9;		// even, 'M'
+		*dst++ = data;
+		s->spdif_counter++;
+		if (s->spdif_counter == 384)
+			s->spdif_counter = 0;
+	} while (--i);
+}
+
+static void set_adc_rate_unlocked(struct cm_state *s, unsigned rate)
+{
+	unsigned char freq = 4;
 	int	i;
 
 	if (rate > 48000)
 		rate = 48000;
-	if (rate < 5512)
-		rate = 5512;
-	for (i = 0; i < sizeof(rate_lookup) / sizeof(rate_lookup[0]); i++)
-	{
-		if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper)
-		{
+	if (rate < 8000)
+		rate = 8000;
+	for (i = 0; i < sizeof(rate_lookup) / sizeof(rate_lookup[0]); i++) {
+		if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper) {
 			rate = rate_lookup[i].rate;
 			freq = rate_lookup[i].freq;
 			break;
 	    	}
 	}
-	s->ratedac = rate;
+	s->rateadc = rate;
 	freq <<= 2;
-	spin_lock_irqsave(&s->lock, flags);
-	val = inb(s->iobase + CODEC_CMI_FUNCTRL1 + 1) & ~0x1c; 
-	outb(val | freq, s->iobase + CODEC_CMI_FUNCTRL1 + 1);
-	spin_unlock_irqrestore(&s->lock, flags);
+
+	maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~0x1c, freq);
 }
 
 static void set_adc_rate(struct cm_state *s, unsigned rate)
 {
 	unsigned long flags;
-	unsigned char freq = 4, val;
+	unsigned char freq = 4;
 	int	i;
 
 	if (rate > 48000)
 		rate = 48000;
-	if (rate < 5512)
-		rate = 5512;
-	for (i = 0; i < sizeof(rate_lookup) / sizeof(rate_lookup[0]); i++)
-	{
-		if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper)
-		{
+	if (rate < 8000)
+		rate = 8000;
+	for (i = 0; i < sizeof(rate_lookup) / sizeof(rate_lookup[0]); i++) {
+		if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper) {
 			rate = rate_lookup[i].rate;
 			freq = rate_lookup[i].freq;
 			break;
 	    	}
 	}
 	s->rateadc = rate;
+	freq <<= 2;
+
+	spin_lock_irqsave(&s->lock, flags);
+	maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~0x1c, freq);
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+static void set_dac_rate(struct cm_state *s, unsigned rate)
+{
+	unsigned long flags;
+	unsigned char freq = 4;
+	int	i;
+
+	if (rate > 48000)
+		rate = 48000;
+	if (rate < 8000)
+		rate = 8000;
+	for (i = 0; i < sizeof(rate_lookup) / sizeof(rate_lookup[0]); i++) {
+		if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper) {
+			rate = rate_lookup[i].rate;
+			freq = rate_lookup[i].freq;
+			break;
+	    	}
+	}
+	s->ratedac = rate;
 	freq <<= 5;
+
 	spin_lock_irqsave(&s->lock, flags);
-	val = inb(s->iobase + CODEC_CMI_FUNCTRL1 + 1) & ~0xe0; 
-	outb(val | freq, s->iobase + CODEC_CMI_FUNCTRL1 + 1);
+	maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~0xe0, freq);
+
+
+	if (s->curr_channels <=  2)
+		set_spdifout_unlocked(s, rate);
+	if (s->status & DO_DUAL_DAC)
+		set_adc_rate_unlocked(s, rate);
+
 	spin_unlock_irqrestore(&s->lock, flags);
 }
 
 /* --------------------------------------------------------------------- */
+static inline void reset_adc(struct cm_state *s)
+{
+	/* reset bus master */
+	outb(s->enable | CM_CH0_RESET, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+	outb(s->enable & ~CM_CH0_RESET, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+}
+
+static inline void reset_dac(struct cm_state *s)
+{
+	/* reset bus master */
+	outb(s->enable | CM_CH1_RESET, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+	outb(s->enable & ~CM_CH1_RESET, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+	if (s->status & DO_DUAL_DAC)
+		reset_adc(s);
+}
+
+static inline void pause_adc(struct cm_state *s)
+{
+	maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~0, 4);
+}
+
+static inline void pause_dac(struct cm_state *s)
+{
+	maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~0, 8);
+	if (s->status & DO_DUAL_DAC)
+		pause_adc(s);
+}
+
+extern inline void disable_adc(struct cm_state *s)
+{
+	/* disable channel */
+	s->enable &= ~CM_ENABLE_CH0;
+	outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+	reset_adc(s);
+}
+
+extern inline void disable_dac(struct cm_state *s)
+{
+	/* disable channel */
+	s->enable &= ~CM_ENABLE_CH1;
+	outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+	reset_dac(s);
+	if (s->status & DO_DUAL_DAC)
+		disable_adc(s);
+}
+
+extern inline void enable_adc(struct cm_state *s)
+{
+	if (!(s->enable & CM_ENABLE_CH0)) {
+		/* enable channel */
+		s->enable |= CM_ENABLE_CH0;
+		outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+	}
+	maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~4, 0);
+}
+
+extern inline void enable_dac_unlocked(struct cm_state *s)
+{
+	if (!(s->enable & CM_ENABLE_CH1)) {
+		/* enable channel */
+		s->enable |= CM_ENABLE_CH1;
+		outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+	}
+	maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~8, 0);
+
+	if (s->status & DO_DUAL_DAC)
+		enable_adc(s);
+}
+
+extern inline void enable_dac(struct cm_state *s)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&s->lock, flags);
+	enable_dac_unlocked(s);
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+extern inline void stop_adc_unlocked(struct cm_state *s)
+{
+	if (s->enable & CM_ENABLE_CH0) {
+		/* disable interrupt */
+		maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~1, 0);
+		disable_adc(s);
+	}
+}
 
 extern inline void stop_adc(struct cm_state *s)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&s->lock, flags);
-	/* disable channel */
-	outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-	s->enable &= ~CM_CENABLE_RE;
-	/* disable interrupt */
-	outb(inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2) & ~2, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-	/* reset */
-	outb(s->enable | CM_CH1_RESET, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-	udelay(10);
-	outb(s->enable & ~CM_CH1_RESET, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+	stop_adc_unlocked(s);
 	spin_unlock_irqrestore(&s->lock, flags);
-}	
+
+}
+
+extern inline void stop_dac_unlocked(struct cm_state *s)
+{
+	if (s->enable & CM_ENABLE_CH1) {
+		/* disable interrupt */
+		maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~2, 0);
+		disable_dac(s);
+	}
+	if (s->status & DO_DUAL_DAC)
+		stop_adc_unlocked(s);
+}
 
 extern inline void stop_dac(struct cm_state *s)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&s->lock, flags);
-	/* disable channel */
-	s->enable &= ~CM_CENABLE_PE;
-	outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-	/* disable interrupt */
-	outb(inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2) & ~1, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-	/* reset */
-	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);
+	stop_dac_unlocked(s);
 	spin_unlock_irqrestore(&s->lock, flags);
-}	
+}
 
-static void start_dac(struct cm_state *s)
+static void start_adc_unlocked(struct cm_state *s)
+{
+	if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize))
+	    && s->dma_adc.ready) {
+		/* enable interrupt */
+		maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~0, 1);
+		enable_adc(s);
+	}
+}
+
+static void start_adc(struct cm_state *s)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&s->lock, flags);
+	start_adc_unlocked(s);
+	spin_unlock_irqrestore(&s->lock, flags);
+}	
+
+static void start_dac1_unlocked(struct cm_state *s)
+{
+	if ((s->dma_adc.mapped || s->dma_adc.count > 0) && s->dma_adc.ready) {
+		/* enable interrupt */
+//		maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~0, 1);
+ 		enable_dac_unlocked(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) {
-		outb(inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2) | 1, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-		s->enable |= CM_CENABLE_PE;
-		outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+		/* enable interrupt */
+		maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~0, 2);
+		enable_dac_unlocked(s);
 	}
+		if (s->status & DO_DUAL_DAC)
+			start_dac1_unlocked(s);
+}
+
+static void start_dac(struct cm_state *s)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&s->lock, flags);
+	start_dac_unlocked(s);
 	spin_unlock_irqrestore(&s->lock, flags);
 }	
 
-static void start_adc(struct cm_state *s)
+static int prog_dmabuf(struct cm_state *s, unsigned rec);
+
+static int set_dac_channels(struct cm_state *s, int channels)
 {
 	unsigned long flags;
-
 	spin_lock_irqsave(&s->lock, flags);
-	if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) 
-	    && s->dma_adc.ready) {
-		outb(inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2) | 2, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-		s->enable |= CM_CENABLE_RE;
-		outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+
+	if ((channels > 2) && (channels <= s->max_channels)
+	 && (((s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK) == (CM_CFMT_STEREO | CM_CFMT_16BIT))) {
+	    set_spdifout_unlocked(s, 0);
+	    if (s->capability & CAN_MULTI_CH_HW) {
+		// NXCHG
+		maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~0, 0x80);
+		// CHB3D or CHB3D5C
+	       	maskb(s->iobase + CODEC_CMI_CHFORMAT + 3, ~0xa0, channels > 4 ? 0x80 : 0x20);
+		// CHB3D6C
+		maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~0x80, channels == 6 ? 0x80 : 0);
+		// ENCENTER 
+		maskb(s->iobase + CODEC_CMI_MISC_CTRL, ~0x80, channels == 6 ? 0x80 : 0);
+		s->status |= DO_MULTI_CH_HW;
+	    } else if (s->capability & CAN_DUAL_DAC) {
+		unsigned char fmtm = ~0, fmts = 0;
+		ssize_t ret;
+
+		// ENDBDAC, turn on double DAC mode
+		// XCHGDAC, CH0 -> back, CH1->front
+		maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, 0xC0);
+		s->status |= DO_DUAL_DAC;
+		// prepare secondary buffer
+
+		spin_unlock_irqrestore(&s->lock, flags);
+		ret = prog_dmabuf(s, 1);
+		spin_lock_irqsave(&s->lock, flags);
+
+		if (ret) return ret;
+		// copy the hw state
+		fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_DACSHIFT);
+		fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_ADCSHIFT);
+		// the HW only support 16-bit stereo
+		fmts |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT;
+		fmts |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT;
+		fmts |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
+		fmts |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
+		
+		set_fmt_unlocked(s, fmtm, fmts);
+		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;
+	} else {
+	    if (s->status & DO_MULTI_CH_HW) {
+		maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~0x80, 0);
+		maskb(s->iobase + CODEC_CMI_CHFORMAT + 3, ~0xa0, 0);
+		maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~0x80, 0);
+	    } else if (s->status & DO_DUAL_DAC) {
+		maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0x80, 0);
+	    }
+	    // N4SPK3D, enable 4 speaker mode (analog duplicate)
+	    if (s->speakers > 2)
+		maskb(s->iobase + CODEC_CMI_MISC_CTRL + 3, ~0, 0x04);
+	    s->status &= ~DO_MULTI_CH;
+	    s->curr_channels = s->fmt & (CM_CFMT_STEREO << CM_CFMT_DACSHIFT) ? 2 : 1;
 	}
+
 	spin_unlock_irqrestore(&s->lock, flags);
-}	
+	return s->curr_channels;
+}
 
 /* --------------------------------------------------------------------- */
 
@@ -591,7 +996,7 @@
 static void dealloc_dmabuf(struct dmabuf *db)
 {
 	struct page *pstart, *pend;
-
+	
 	if (db->rawbuf) {
 		/* undo marking the pages as reserved */
 		pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
@@ -603,8 +1008,7 @@
 	db->mapped = db->ready = 0;
 }
 
-
-/* Ch0 is used for playback, Ch1 is used for recording */
+/* Ch1 is used for playback, Ch0 is used for recording */
 
 static int prog_dmabuf(struct cm_state *s, unsigned rec)
 {
@@ -617,17 +1021,15 @@
 	unsigned char fmt;
 	unsigned long flags;
 
-	spin_lock_irqsave(&s->lock, flags);
 	fmt = s->fmt;
 	if (rec) {
-		s->enable &= ~CM_CENABLE_RE;
+		stop_adc(s);
 		fmt >>= CM_CFMT_ADCSHIFT;
 	} else {
-		s->enable &= ~CM_CENABLE_PE;
+		stop_dac(s);
 		fmt >>= CM_CFMT_DACSHIFT;
 	}
-	outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-	spin_unlock_irqrestore(&s->lock, flags);
+
 	fmt &= CM_CFMT_MASK;
 	db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
 	if (!db->rawbuf) {
@@ -638,12 +1040,13 @@
 		if (!db->rawbuf)
 			return -ENOMEM;
 		db->buforder = order;
-		if ((virt_to_bus(db->rawbuf) ^ (virt_to_bus(db->rawbuf) + (PAGE_SIZE << db->buforder) - 1)) & ~0xffff)
-			printk(KERN_DEBUG "cmpci: DMA buffer crosses 64k boundary: busaddr 0x%lx  size %ld\n", 
-			       virt_to_bus(db->rawbuf), PAGE_SIZE << db->buforder);
-		if ((virt_to_bus(db->rawbuf) + (PAGE_SIZE << db->buforder) - 1) & ~0xffffff)
-			printk(KERN_DEBUG "cmpci: DMA buffer beyond 16MB: busaddr 0x%lx  size %ld\n", 
-			       virt_to_bus(db->rawbuf), PAGE_SIZE << db->buforder);
+		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", 
+			       (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", 
+			       (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);
 		for (pstart = virt_to_page(db->rawbuf); pstart <= pend; pstart++)
@@ -670,30 +1073,22 @@
 	if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
 		db->numfrag = db->ossmaxfrags;
  	/* to make fragsize >= 4096 */
-#if 0 	
- 	if(s->modem)
- 	{
-	 	while (db->fragsize < 4096 && db->numfrag >= 4)
-		{
-			db->fragsize *= 2;
- 			db->fragshift++;
- 			db->numfrag /= 2;
- 		}
-	}
-#endif	
 	db->fragsamples = db->fragsize >> sample_shift[fmt];
 	db->dmasize = db->numfrag << db->fragshift;
 	db->dmasamples = db->dmasize >> sample_shift[fmt];
 	memset(db->rawbuf, (fmt & CM_CFMT_16BIT) ? 0 : 0x80, db->dmasize);
 	spin_lock_irqsave(&s->lock, flags);
 	if (rec) {
-		set_dmaadc(s, virt_to_bus(db->rawbuf), db->dmasize >> sample_shift[fmt]);
+		if (s->status & DO_DUAL_DAC)
+		    set_dmadac1(s, db->rawphys, db->dmasize >> sample_shift[fmt]);
+		else
+		    set_dmaadc(s, db->rawphys, db->dmasize >> sample_shift[fmt]);
 		/* program sample counts */
-		outw(db->fragsamples-1, s->iobase + CODEC_CMI_CH1_FRAME2 + 2);
+		set_countdac(s, db->fragsamples);
 	} else {
-		set_dmadac(s, virt_to_bus(db->rawbuf), db->dmasize >> sample_shift[fmt]);
+		set_dmadac(s, db->rawphys, db->dmasize >> sample_shift[fmt]);
 		/* program sample counts */
-		outw(db->fragsamples-1, s->iobase + CODEC_CMI_CH0_FRAME2 + 2);
+		set_countdac(s, db->fragsamples);
 	}
 	spin_unlock_irqrestore(&s->lock, flags);
 	db->ready = 1;
@@ -704,6 +1099,7 @@
 {
 	unsigned char c = (s->fmt & (CM_CFMT_16BIT << CM_CFMT_DACSHIFT)) ? 0 : 0x80;
 	unsigned char *buf = s->dma_dac.rawbuf;
+	unsigned char *buf1 = s->dma_adc.rawbuf;
 	unsigned bsize = s->dma_dac.dmasize;
 	unsigned bptr = s->dma_dac.swptr;
 	unsigned len = s->dma_dac.fragsize;
@@ -711,11 +1107,14 @@
 	if (bptr + len > bsize) {
 		unsigned x = bsize - bptr;
 		memset(buf + bptr, c, x);
+		if (s->status & DO_DUAL_DAC)
+			memset(buf1 + bptr, c, x);
 		bptr = 0;
 		len -= x;
 	}
 	memset(buf + bptr, c, len);
-	outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+	if (s->status & DO_DUAL_DAC)
+		memset(buf1 + bptr, c, len);
 }
 
 /* call with spinlock held! */
@@ -726,7 +1125,29 @@
 
 	/* update ADC pointer */
 	if (s->dma_adc.ready) {
-		hwptr = (s->dma_adc.dmasize - get_dmaadc(s)) % s->dma_adc.dmasize;
+	    if (s->status & DO_DUAL_DAC) {
+		hwptr = get_dmaadc(s) % s->dma_adc.dmasize;
+		diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
+		s->dma_adc.hwptr = hwptr;
+		s->dma_adc.total_bytes += diff;
+		if (s->dma_adc.mapped) {
+			s->dma_adc.count += diff;
+			if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
+				wake_up(&s->dma_adc.wait);
+		} else {
+			s->dma_adc.count -= diff;
+			if (s->dma_adc.count <= 0) {
+				pause_adc(s);
+				s->dma_adc.error++;
+			} else if (s->dma_adc.count <= (signed)s->dma_adc.fragsize && !s->dma_adc.endcleared) {
+				clear_advance(s);
+				s->dma_adc.endcleared = 1;
+			}
+			if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize)
+				wake_up(&s->dma_adc.wait);
+		}
+	    } else {
+		hwptr = get_dmaadc(s) % s->dma_adc.dmasize;
 		diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
 		s->dma_adc.hwptr = hwptr;
 		s->dma_adc.total_bytes += diff;
@@ -735,15 +1156,15 @@
 			wake_up(&s->dma_adc.wait);
 		if (!s->dma_adc.mapped) {
 			if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-				s->enable &= ~CM_CENABLE_RE;
-				outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+				pause_adc(s);
 				s->dma_adc.error++;
 			}
 		}
+	    }
 	}
 	/* update DAC pointer */
 	if (s->dma_dac.ready) {
-		hwptr = (s->dma_dac.dmasize - get_dmadac(s)) % s->dma_dac.dmasize;
+		hwptr = get_dmadac(s) % s->dma_dac.dmasize;
 		diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
 		s->dma_dac.hwptr = hwptr;
 		s->dma_dac.total_bytes += diff;
@@ -754,8 +1175,7 @@
 		} else {
 			s->dma_dac.count -= diff;
 			if (s->dma_dac.count <= 0) {
-				s->enable &= ~CM_CENABLE_PE;
-				outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+				pause_dac(s);
 				s->dma_dac.error++;
 			} else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
 				clear_advance(s);
@@ -767,6 +1187,7 @@
 	}
 }
 
+#ifdef CONFIG_SOUND_CMPCI_MIDI
 /* hold spinlock for the following! */
 static void cm_handle_midi(struct cm_state *s)
 {
@@ -796,11 +1217,13 @@
 	if (wake)
 		wake_up(&s->midi.owait);
 }
+#endif
 
 static void cm_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
         struct cm_state *s = (struct cm_state *)dev_id;
 	unsigned int intsrc, intstat;
+	unsigned char mask = 0;
 	
 	/* fastpath out, to ease interrupt sharing */
 	intsrc = inl(s->iobase + CODEC_CMI_INT_STATUS);
@@ -810,22 +1233,19 @@
 	intstat = inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2);
 	/* acknowledge interrupt */
 	if (intsrc & CM_INT_CH0)
-	{
-		outb(intstat & ~1, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-		udelay(10);
-		outb(intstat | 1, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-	}
+		mask |= 1;
 	if (intsrc & CM_INT_CH1)
-	{
-		outb(intstat & ~2, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-		udelay(10);
-		outb(intstat | 2, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-	}
+		mask |= 2;
+	outb(intstat & ~mask, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
+	outb(intstat | mask, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
 	cm_update_ptr(s);
+#ifdef CONFIG_SOUND_CMPCI_MIDI
 	cm_handle_midi(s);
+#endif
 	spin_unlock(&s->lock);
 }
 
+#ifdef CONFIG_SOUND_CMPCI_MIDI
 static void cm_midi_timer(unsigned long data)
 {
 	struct cm_state *s = (struct cm_state *)data;
@@ -837,10 +1257,11 @@
 	s->midi.timer.expires = jiffies+1;
 	add_timer(&s->midi.timer);
 }
+#endif
 
 /* --------------------------------------------------------------------- */
 
-static const char invalid_magic[] = KERN_CRIT "cmpci: invalid magic value\n";
+static const char invalid_magic[] = KERN_CRIT "cm: invalid magic value\n";
 
 #ifdef CONFIG_SOUND_CMPCI	/* support multiple chips */
 #define VALIDATE_STATE(s)
@@ -874,7 +1295,8 @@
 	[SOUND_MIXER_MIC]    = { DSP_MIX_MICVOLIDX,      DSP_MIX_MICVOLIDX,      MT_5MUTEMONO, 0x01, 0x01 },
 	[SOUND_MIXER_SYNTH]  = { DSP_MIX_FMVOLIDX_L,  	 DSP_MIX_FMVOLIDX_R,     MT_5MUTE,     0x40, 0x00 },
 	[SOUND_MIXER_VOLUME] = { DSP_MIX_MASTERVOLIDX_L, DSP_MIX_MASTERVOLIDX_R, MT_5MUTE,     0x00, 0x00 },
-	[SOUND_MIXER_PCM]    = { DSP_MIX_VOICEVOLIDX_L,  DSP_MIX_VOICEVOLIDX_R,  MT_5MUTE,     0x00, 0x00 }
+	[SOUND_MIXER_PCM]    = { DSP_MIX_VOICEVOLIDX_L,  DSP_MIX_VOICEVOLIDX_R,  MT_5MUTE,     0x00, 0x00 },
+	[SOUND_MIXER_SPEAKER]= { DSP_MIX_SPKRVOLIDX,	 DSP_MIX_SPKRVOLIDX,	 MT_5MUTEMONO, 0x01, 0x01 }
 };
 
 #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
@@ -937,7 +1359,8 @@
 	[SOUND_MIXER_MIC]    = 3,
 	[SOUND_MIXER_SYNTH]  = 4,
 	[SOUND_MIXER_VOLUME] = 5,
-	[SOUND_MIXER_PCM]    = 6
+	[SOUND_MIXER_PCM]    = 6,
+	[SOUND_MIXER_SPEAKER]= 7
 };
 
 #endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
@@ -983,9 +1406,9 @@
 	}
 	if (cmd == OSS_GETVERSION)
 		return put_user(SOUND_VERSION, (int *)arg);
-	if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
+	if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))
                 return -EINVAL;
-        if (_SIOC_DIR(cmd) == _SIOC_READ) {
+        if (_IOC_DIR(cmd) == _IOC_READ) {
                 switch (_IOC_NR(cmd)) {
                 case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
 			return put_user(mixer_recmask(s), (int *)arg);
@@ -1033,7 +1456,7 @@
 #endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
 		}
 	}
-        if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE)) 
+        if (_IOC_DIR(cmd) != (_IOC_READ|_IOC_WRITE)) 
 		return -EINVAL;
 	s->mix.modcnt++;
 	switch (_IOC_NR(cmd)) {
@@ -1100,7 +1523,7 @@
 			rl = (l < 4 ? 0 : (l - 5) / 3) & 31;
 			rr = (rl >> 2) & 7;
 			wrmixer(s, mixtable[i].left, rl<<3);
-			outb((inb(s->iobase + CODEC_CMI_MIXER2) & ~0x0e) | rr<<1, s->iobase + CODEC_CMI_MIXER2);
+			maskb(s->iobase + CODEC_CMI_MIXER2, ~0x0e, rr<<1);
 			break;
 			
 		case MT_5MUTEMONO:
@@ -1108,7 +1531,7 @@
 			rl = l < 4 ? 0 : (l - 5) / 3;
 			rr = rl >> 2;
  			wrmixer(s, mixtable[i].left, rl<<3);
-			outb((inb(s->iobase + CODEC_CMI_MIXER2) & ~0x0e) | rr<<1, s->iobase + CODEC_CMI_MIXER2);
+			maskb(s->iobase + CODEC_CMI_MIXER2, ~0x0e, rr<<1);
 			break;
 				
 		case MT_5MUTE:
@@ -1117,7 +1540,7 @@
  			wrmixer(s, mixtable[i].left, rl<<3);
 			wrmixer(s, mixtable[i].right, rr<<3);
 			break;
-				
+
 		case MT_6MUTE:
 			if (l < 6)
 				rl = 0x00;
@@ -1187,19 +1610,20 @@
 	release:	cm_release_mixdev,
 };
 
+
 /* --------------------------------------------------------------------- */
 
 static int drain_dac(struct cm_state *s, int nonblock)
 {
-        DECLARE_WAITQUEUE(wait, current);
+	DECLARE_WAITQUEUE(wait, current);
 	unsigned long flags;
 	int count, tmo;
 
 	if (s->dma_dac.mapped || !s->dma_dac.ready)
 		return 0;
+        current->state = TASK_INTERRUPTIBLE;
         add_wait_queue(&s->dma_dac.wait, &wait);
         for (;;) {
-		set_current_state(TASK_INTERRUPTIBLE);
                 spin_lock_irqsave(&s->lock, flags);
 		count = s->dma_dac.count;
                 spin_unlock_irqrestore(&s->lock, flags);
@@ -1212,10 +1636,10 @@
                         current->state = TASK_RUNNING;
                         return -EBUSY;
                 }
-		tmo = (count * HZ) / s->ratedac;
+		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) && tmo)
-			printk(KERN_DEBUG "cmpci: dma timed out??\n");
+		if (!schedule_timeout(tmo + 1))
+			printk(KERN_DEBUG "cm: dma timed out??\n");
         }
         remove_wait_queue(&s->dma_dac.wait, &wait);
         current->state = TASK_RUNNING;
@@ -1263,14 +1687,14 @@
 			if (file->f_flags & O_NONBLOCK)
 				return ret ? ret : -EAGAIN;
 			if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) {
-				printk(KERN_DEBUG "cmpci: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
+				printk(KERN_DEBUG "cm: 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);
-				stop_adc(s);
 				spin_lock_irqsave(&s->lock, flags);
-				set_dmaadc(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.dmasamples);
+				stop_adc_unlocked(s);
+				set_dmaadc(s, s->dma_adc.rawphys, s->dma_adc.dmasamples);
 				/* program sample counts */
-				outw(s->dma_adc.fragsamples-1, s->iobase + CODEC_CMI_CH1_FRAME2 + 2);
+				set_countadc(s, s->dma_adc.fragsamples);
 				s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
 				spin_unlock_irqrestore(&s->lock, flags);
 			}
@@ -1284,11 +1708,11 @@
 		spin_lock_irqsave(&s->lock, flags);
 		s->dma_adc.swptr = swptr;
 		s->dma_adc.count -= cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
 		count -= cnt;
 		buffer += cnt;
 		ret += cnt;
-		start_adc(s);
+		start_adc_unlocked(s);
+		spin_unlock_irqrestore(&s->lock, flags);
 	}
 	return ret;
 }
@@ -1310,62 +1734,113 @@
 		return ret;
 	if (!access_ok(VERIFY_READ, buffer, count))
 		return -EFAULT;
+	if (s->status & DO_DUAL_DAC) {
+		if (s->dma_adc.mapped)
+			return -ENXIO;
+		if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
+			return ret;
+		if (!access_ok(VERIFY_READ, 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
+#endif                                                        
 	while (count > 0) {
 		spin_lock_irqsave(&s->lock, flags);
 		if (s->dma_dac.count < 0) {
 			s->dma_dac.count = 0;
 			s->dma_dac.swptr = s->dma_dac.hwptr;
 		}
+		if (s->status & DO_DUAL_DAC) {
+			s->dma_adc.swptr = s->dma_dac.swptr;
+			s->dma_adc.count = s->dma_dac.count;
+			s->dma_adc.endcleared = s->dma_dac.endcleared;
+		}
 		swptr = s->dma_dac.swptr;
 		cnt = s->dma_dac.dmasize-swptr;
-		if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
-			cnt = s->dma_dac.dmasize - s->dma_dac.count;
+		if (s->status & DO_AC3_SW) {
+			if (s->dma_dac.count + 2 * cnt > s->dma_dac.dmasize)
+				cnt = (s->dma_dac.dmasize - s->dma_dac.count) / 2;
+		} else {
+			if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
+				cnt = s->dma_dac.dmasize - s->dma_dac.count;
+		}
 		spin_unlock_irqrestore(&s->lock, flags);
 		if (cnt > count)
 			cnt = count;
+		if ((s->status & DO_DUAL_DAC) && (cnt > count / 2))
+		    cnt = count / 2;
 		if (cnt <= 0) {
 			start_dac(s);
 			if (file->f_flags & O_NONBLOCK)
 				return ret ? ret : -EAGAIN;
 			if (!interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ)) {
-				printk(KERN_DEBUG "cmpci: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
+				printk(KERN_DEBUG "cm: 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);
-				stop_dac(s);
 				spin_lock_irqsave(&s->lock, flags);
-				set_dmadac(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.dmasamples);
+				stop_dac_unlocked(s);
+				set_dmadac(s, s->dma_dac.rawphys, s->dma_dac.dmasamples);
 				/* program sample counts */
-				outw(s->dma_dac.fragsamples-1, s->iobase + CODEC_CMI_CH0_FRAME2 + 2);
+				set_countdac(s, s->dma_dac.fragsamples);
 				s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
+				if (s->status & DO_DUAL_DAC)  {
+					set_dmadac1(s, s->dma_adc.rawphys, s->dma_adc.dmasamples);
+					s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
+				}
 				spin_unlock_irqrestore(&s->lock, flags);
 			}
 			if (signal_pending(current))
 				return ret ? ret : -ERESTARTSYS;
 			continue;
 		}
-		if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt))
-			return ret ? ret : -EFAULT;
-		swptr = (swptr + cnt) % s->dma_dac.dmasize;
+		if (s->status & DO_AC3_SW) {
+			// clip exceeded data, caught by 033 and 037
+			if (swptr + 2 * cnt > s->dma_dac.dmasize)
+				cnt = (s->dma_dac.dmasize - swptr) / 2;
+			trans_ac3(s, s->dma_dac.rawbuf + swptr, buffer, cnt);
+			swptr = (swptr + 2 * cnt) % s->dma_dac.dmasize;
+		} else if (s->status & DO_DUAL_DAC) {
+			int	i;
+			unsigned long *src, *dst0, *dst1;
+
+			src = (unsigned long *) buffer;
+			dst0 = (unsigned long *) (s->dma_dac.rawbuf + swptr);
+			dst1 = (unsigned long *) (s->dma_adc.rawbuf + swptr);
+			// copy left/right sample at one time
+			for (i = 0; i <= cnt / 4; i++) {
+				*dst0++ = *src++;
+				*dst1++ = *src++;
+			}
+			swptr = (swptr + cnt) % s->dma_dac.dmasize;
+		} else {
+			if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt))
+				return ret ? ret : -EFAULT;
+			swptr = (swptr + cnt) % s->dma_dac.dmasize;
+		}
 		spin_lock_irqsave(&s->lock, flags);
 		s->dma_dac.swptr = swptr;
 		s->dma_dac.count += cnt;
+		if (s->status & DO_AC3_SW)
+			s->dma_dac.count += cnt;
 		s->dma_dac.endcleared = 0;
 		spin_unlock_irqrestore(&s->lock, flags);
 		count -= cnt;
 		buffer += cnt;
 		ret += cnt;
+		if (s->status & DO_DUAL_DAC) {
+			count -= cnt;
+			buffer += cnt;
+			ret += cnt;
+		}
 		start_dac(s);
 	}
 	return ret;
 }
 
-/* No kernel lock - fine (we have our own spinlock) */
 static unsigned int cm_poll(struct file *file, struct poll_table_struct *wait)
 {
 	struct cm_state *s = (struct cm_state *)file->private_data;
@@ -1373,17 +1848,10 @@
 	unsigned int mask = 0;
 
 	VALIDATE_STATE(s);
-	if (file->f_mode & FMODE_WRITE) {
-		if (!s->dma_dac.ready && prog_dmabuf(s, 0))
-			return 0;
+	if (file->f_mode & FMODE_WRITE)
 		poll_wait(file, &s->dma_dac.wait, wait);
-	}
-	if (file->f_mode & FMODE_READ) {
-		if (!s->dma_adc.ready && prog_dmabuf(s, 1))
-			return 0;
+	if (file->f_mode & FMODE_READ)
 		poll_wait(file, &s->dma_adc.wait, wait);
-	}
-
 	spin_lock_irqsave(&s->lock, flags);
 	cm_update_ptr(s);
 	if (file->f_mode & FMODE_READ) {
@@ -1413,14 +1881,14 @@
 	VALIDATE_STATE(s);
 	lock_kernel();
 	if (vma->vm_flags & VM_WRITE) {
-		if ((ret = prog_dmabuf(s, 1)) != 0)
+		if ((ret = prog_dmabuf(s, 0)) != 0)
 			goto out;
 		db = &s->dma_dac;
 	} else if (vma->vm_flags & VM_READ) {
-		if ((ret = prog_dmabuf(s, 0)) != 0)
+		if ((ret = prog_dmabuf(s, 1)) != 0)
 			goto out;
 		db = &s->dma_adc;
-	} else 
+	} else
 		goto out;
 	ret = -EINVAL;
 	if (vma->vm_pgoff != 0)
@@ -1428,7 +1896,7 @@
 	size = vma->vm_end - vma->vm_start;
 	if (size > (PAGE_SIZE << db->buforder))
 		goto out;
-	ret = -EAGAIN;
+	ret = -EINVAL;
 	if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot))
 		goto out;
 	db->mapped = 1;
@@ -1463,13 +1931,15 @@
 		return 0;
 
 	case SNDCTL_DSP_GETCAPS:
-		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP | DSP_CAP_BIND, (int *)arg);
 		
         case SNDCTL_DSP_RESET:
 		if (file->f_mode & FMODE_WRITE) {
 			stop_dac(s);
 			synchronize_irq();
 			s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
+			if (s->status & DO_DUAL_DAC)
+				s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
 		}
 		if (file->f_mode & FMODE_READ) {
 			stop_adc(s);
@@ -1479,24 +1949,28 @@
 		return 0;
 
         case SNDCTL_DSP_SPEED:
-                if (get_user(val, (int *)arg))
+		if (get_user(val, (int *)arg))
 			return -EFAULT;
 		if (val >= 0) {
 			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
+			 	spin_lock_irqsave(&s->lock, flags);
+				stop_adc_unlocked(s);
 				s->dma_adc.ready = 0;
-				set_adc_rate(s, val);
+				set_adc_rate_unlocked(s, val);
+				spin_unlock_irqrestore(&s->lock, flags);
 			}
 			if (file->f_mode & FMODE_WRITE) {
 				stop_dac(s);
 				s->dma_dac.ready = 0;
+				if (s->status & DO_DUAL_DAC)
+					s->dma_adc.ready = 0;
 				set_dac_rate(s, val);
 			}
 		}
 		return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
-		
+
         case SNDCTL_DSP_STEREO:
-                if (get_user(val, (int *)arg))
+		if (get_user(val, (int *)arg))
 			return -EFAULT;
 		fmtd = 0;
 		fmtm = ~0;
@@ -1515,12 +1989,19 @@
 				fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
 			else
 				fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_DACSHIFT);
+			if (s->status & DO_DUAL_DAC) {
+				s->dma_adc.ready = 0;
+				if (val)
+					fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
+				else
+					fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
+			}
 		}
 		set_fmt(s, fmtm, fmtd);
 		return 0;
 
         case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, (int *)arg))
+		if (get_user(val, (int *)arg))
 			return -EFAULT;
 		if (val != 0) {
 			fmtd = 0;
@@ -1540,14 +2021,26 @@
 					fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
 				else
 					fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_DACSHIFT);
+				if (s->status & DO_DUAL_DAC) {
+					s->dma_adc.ready = 0;
+					if (val >= 2)
+						fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
+					else
+						fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
+				}
 			}
 			set_fmt(s, fmtm, fmtd);
-		}
+			if ((s->capability & CAN_MULTI_CH)
+			     && (file->f_mode & FMODE_WRITE)) {
+				val = set_dac_channels(s, val);
+				return put_user(val, (int *)arg);
+			}
+		}            
 		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_ADCSHIFT) 
 					   : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ? 2 : 1, (int *)arg);
 		
 	case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
+                return put_user(AFMT_S16_LE|AFMT_U8|AFMT_AC3, (int *)arg);
 		
 	case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
 		if (get_user(val, (int *)arg))
@@ -1566,27 +2059,47 @@
 			if (file->f_mode & FMODE_WRITE) {
 				stop_dac(s);
 				s->dma_dac.ready = 0;
-				if (val == AFMT_S16_LE)
+				if (val == AFMT_S16_LE || val == AFMT_AC3)
 					fmtd |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT;
 				else
 					fmtm &= ~(CM_CFMT_16BIT << CM_CFMT_DACSHIFT);
+				if (val == AFMT_AC3) {
+					fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
+					set_ac3(s, s->ratedac);
+				} else
+					set_ac3(s, 0);
+				if (s->status & DO_DUAL_DAC) {
+					s->dma_adc.ready = 0;
+					if (val == AFMT_S16_LE)
+						fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
+					else
+						fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
+				}
 			}
 			set_fmt(s, fmtm, fmtd);
 		}
-		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT) 
+		if (s->status & DO_AC3) return put_user(AFMT_AC3, (int *)arg);
+		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT)
 					   : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? AFMT_S16_LE : AFMT_U8, (int *)arg);
-		
+
 	case SNDCTL_DSP_POST:
                 return 0;
 
         case SNDCTL_DSP_GETTRIGGER:
 		val = 0;
-		if (file->f_mode & FMODE_READ && s->enable & CM_CENABLE_RE) 
+		if (s->status & DO_DUAL_DAC) {
+			if (file->f_mode & FMODE_WRITE &&
+			 (s->enable & CM_ENABLE_CH1) &&
+			 (s->enable & CM_ENABLE_CH0))
+				val |= PCM_ENABLE_OUTPUT;
+			return put_user(val, (int *)arg);
+		}
+		if (file->f_mode & FMODE_READ && s->enable & CM_ENABLE_CH0) 
 			val |= PCM_ENABLE_INPUT;
-		if (file->f_mode & FMODE_WRITE && s->enable & CM_CENABLE_PE) 
+		if (file->f_mode & FMODE_WRITE && s->enable & CM_ENABLE_CH1) 
 			val |= PCM_ENABLE_OUTPUT;
 		return put_user(val, (int *)arg);
-		
+
 	case SNDCTL_DSP_SETTRIGGER:
 		if (get_user(val, (int *)arg))
 			return -EFAULT;
@@ -1602,6 +2115,10 @@
 			if (val & PCM_ENABLE_OUTPUT) {
 				if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
 					return ret;
+				if (s->status & DO_DUAL_DAC) {
+					if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
+						return ret;
+				}
 				start_dac(s);
 			} else
 				stop_dac(s);
@@ -1611,22 +2128,22 @@
 	case SNDCTL_DSP_GETOSPACE:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
-		if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-			return ret;
+		if (!(s->enable & CM_ENABLE_CH1) && (val = prog_dmabuf(s, 0)) != 0)
+			return val;
 		spin_lock_irqsave(&s->lock, flags);
 		cm_update_ptr(s);
 		abinfo.fragsize = s->dma_dac.fragsize;
                 abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count;
                 abinfo.fragstotal = s->dma_dac.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
+                abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
 		spin_unlock_irqrestore(&s->lock, flags);
 		return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
 	case SNDCTL_DSP_GETISPACE:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
-		if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
-			return ret;
+		if (!(s->enable & CM_ENABLE_CH0) && (val = prog_dmabuf(s, 1)) != 0)
+			return val;
 		spin_lock_irqsave(&s->lock, flags);
 		cm_update_ptr(s);
 		abinfo.fragsize = s->dma_adc.fragsize;
@@ -1643,8 +2160,6 @@
         case SNDCTL_DSP_GETODELAY:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
-		if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		cm_update_ptr(s);
                 val = s->dma_dac.count;
@@ -1654,8 +2169,6 @@
         case SNDCTL_DSP_GETIPTR:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
-		if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
-			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		cm_update_ptr(s);
                 cinfo.bytes = s->dma_adc.total_bytes;
@@ -1669,8 +2182,6 @@
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
-		if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-			return ret;
 		spin_lock_irqsave(&s->lock, flags);
 		cm_update_ptr(s);
                 cinfo.bytes = s->dma_dac.total_bytes;
@@ -1678,6 +2189,10 @@
                 cinfo.ptr = s->dma_dac.hwptr;
 		if (s->dma_dac.mapped)
 			s->dma_dac.count &= s->dma_dac.fragsize-1;
+		if (s->status & DO_DUAL_DAC) {
+			if (s->dma_adc.mapped)
+				s->dma_adc.count &= s->dma_adc.fragsize-1;
+		}
 		spin_unlock_irqrestore(&s->lock, flags);
                 return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
 
@@ -1685,6 +2200,11 @@
 		if (file->f_mode & FMODE_WRITE) {
 			if ((val = prog_dmabuf(s, 0)))
 				return val;
+			if (s->status & DO_DUAL_DAC) {
+				if ((val = prog_dmabuf(s, 1)))
+					return val;
+				return put_user(2 * s->dma_dac.fragsize, (int *)arg);
+			}
 			return put_user(s->dma_dac.fragsize, (int *)arg);
 		}
 		if ((val = prog_dmabuf(s, 1)))
@@ -1692,7 +2212,7 @@
 		return put_user(s->dma_adc.fragsize, (int *)arg);
 
         case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, (int *)arg))
+		if (get_user(val, (int *)arg))
 			return -EFAULT;
 		if (file->f_mode & FMODE_READ) {
 			s->dma_adc.ossfragshift = val & 0xffff;
@@ -1713,6 +2233,10 @@
 				s->dma_dac.ossfragshift = 15;
 			if (s->dma_dac.ossmaxfrags < 4)
 				s->dma_dac.ossmaxfrags = 4;
+			if (s->status & DO_DUAL_DAC) {
+				s->dma_adc.ossfragshift = s->dma_dac.ossfragshift;
+				s->dma_adc.ossmaxfrags = s->dma_dac.ossmaxfrags;
+			}
 		}
 		return 0;
 
@@ -1720,14 +2244,17 @@
 		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))
+		if (get_user(val, (int *)arg))
 			return -EFAULT;
 		if (val != 1 && val != 2 && val != 4)
 			return -EINVAL;
 		if (file->f_mode & FMODE_READ)
 			s->dma_adc.subdivision = val;
-		if (file->f_mode & FMODE_WRITE)
+		if (file->f_mode & FMODE_WRITE) {
 			s->dma_dac.subdivision = val;
+			if (s->status & DO_DUAL_DAC)
+				s->dma_adc.subdivision = val;
+		}
 		return 0;
 
         case SOUND_PCM_READ_RATE:
@@ -1742,7 +2269,63 @@
         case SOUND_PCM_READ_FILTER:
 		return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
 
-        case SOUND_PCM_WRITE_FILTER:
+	case SNDCTL_DSP_GETCHANNELMASK:
+		return put_user(DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE|DSP_BIND_SPDIF, (int *)arg);
+		
+	case SNDCTL_DSP_BIND_CHANNEL:
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
+		if (val == DSP_BIND_QUERY) {
+			val = DSP_BIND_FRONT;
+			if (s->status & DO_SPDIF_OUT)
+				val |= DSP_BIND_SPDIF;
+			else {
+				if (s->curr_channels == 4)
+					val |= DSP_BIND_SURR;
+				if (s->curr_channels > 4)
+					val |= DSP_BIND_CENTER_LFE;
+			}
+		} else {
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(s);
+				s->dma_adc.ready = 0;
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(s);
+				s->dma_dac.ready = 0;
+				if (val & DSP_BIND_SPDIF) {
+					set_spdifout(s, s->ratedac);
+					set_dac_channels(s, s->fmt & (CM_CFMT_STEREO << CM_CFMT_DACSHIFT) ? 2 : 1);
+					if (!(s->status & DO_SPDIF_OUT))
+						val &= ~DSP_BIND_SPDIF;
+				} else {
+					int channels;
+					int mask;
+
+					mask = val & (DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE);
+					switch (mask) {
+					    case DSP_BIND_FRONT:
+						channels = 2;
+						break;
+					    case DSP_BIND_FRONT|DSP_BIND_SURR:
+						channels = 4;
+						break;
+					    case DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE:
+						channels = 6;
+						break;
+					    default:
+						channels = s->fmt & (CM_CFMT_STEREO << CM_CFMT_DACSHIFT) ? 2 : 1;
+						break;
+					}
+					set_dac_channels(s, channels);
+				}
+			}
+		}
+		return put_user(val, (int *)arg);
+
+	case SOUND_PCM_WRITE_FILTER:
+	case SNDCTL_DSP_MAPINBUF:
+	case SNDCTL_DSP_MAPOUTBUF:
         case SNDCTL_DSP_SETSYNCRO:
                 return -EINVAL;
 		
@@ -1788,6 +2371,12 @@
 			fmts |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT;
 		s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
 		set_dac_rate(s, 8000);
+		// clear previous multichannel, spdif, ac3 state
+		set_spdifout(s, 0);
+		if (s->deviceid == PCI_DEVICE_ID_CMEDIA_CM8738) {
+			set_ac3(s, 0);
+			set_dac_channels(s, 1);
+		}
 	}
 	set_fmt(s, fmtm, fmts);
 	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
@@ -1806,11 +2395,23 @@
 	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)
+			set_ac3(s, 0);
+		if (s->status & DO_SPDIF_OUT)
+			set_spdifout(s, 0);
 	}
 	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);
@@ -1831,6 +2432,7 @@
 	release:	cm_release,
 };
 
+#ifdef CONFIG_SOUND_CMPCI_MIDI
 /* --------------------------------------------------------------------- */
 
 static ssize_t cm_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
@@ -1847,12 +2449,9 @@
 		return -ESPIPE;
 	if (!access_ok(VERIFY_WRITE, buffer, count))
 		return -EFAULT;
-	if (count == 0)
-		return 0;
 	ret = 0;
 	add_wait_queue(&s->midi.iwait, &wait);
 	while (count > 0) {
-		set_current_state(TASK_INTERRUPTIBLE);
 		spin_lock_irqsave(&s->lock, flags);
 		ptr = s->midi.ird;
 		cnt = MIDIINBUF - ptr;
@@ -1862,14 +2461,15 @@
 		if (cnt > count)
 			cnt = count;
 		if (cnt <= 0) {
-			if (file->f_flags & O_NONBLOCK) 
+			if (file->f_flags & O_NONBLOCK)
 			{
 				if (!ret)
 					ret = -EAGAIN;
 				break;
 			}
+			__set_current_state(TASK_INTERRUPTIBLE);
 			schedule();
-			if (signal_pending(current)) 
+			if (signal_pending(current))
 			{
 				if (!ret)
 					ret = -ERESTARTSYS;
@@ -1877,7 +2477,8 @@
 			}
 			continue;
 		}
-		if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) {
+		if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt))
+		{
 			if (!ret)
 				ret = -EFAULT;
 			break;
@@ -1916,7 +2517,6 @@
 	ret = 0;
 	add_wait_queue(&s->midi.owait, &wait);
 	while (count > 0) {
-		set_current_state(TASK_INTERRUPTIBLE);
 		spin_lock_irqsave(&s->lock, flags);
 		ptr = s->midi.owr;
 		cnt = MIDIOUTBUF - ptr;
@@ -1928,11 +2528,13 @@
 		if (cnt > count)
 			cnt = count;
 		if (cnt <= 0) {
-			if (file->f_flags & O_NONBLOCK) {
+			if (file->f_flags & O_NONBLOCK)
+			{
 				if (!ret)
 					ret = -EAGAIN;
 				break;
 			}
+			__set_current_state(TASK_INTERRUPTIBLE);
 			schedule();
 			if (signal_pending(current)) {
 				if (!ret)
@@ -1941,7 +2543,8 @@
 			}
 			continue;
 		}
-		if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) {
+		if (copy_from_user(s->midi.obuf + ptr, buffer, cnt))
+		{
 			if (!ret)
 				ret = -EFAULT;
 			break;
@@ -2017,7 +2620,7 @@
 		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
 		s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
 		/* enable MPU-401 */
-		outb(inb(s->iobase + CODEC_CMI_FUNCTRL1) | 4, s->iobase + CODEC_CMI_FUNCTRL1);
+		maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 4);
 		outb(0xff, s->iomidi+1); /* reset command */
 		if (!(inb(s->iomidi+1) & 0x80))
 			inb(s->iomidi);
@@ -2040,23 +2643,24 @@
 	spin_unlock_irqrestore(&s->lock, flags);
 	s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
 	up(&s->open_sem);
+	MOD_INC_USE_COUNT;
 	return 0;
 }
 
 static int cm_midi_release(struct inode *inode, struct file *file)
 {
 	struct cm_state *s = (struct cm_state *)file->private_data;
-        DECLARE_WAITQUEUE(wait, current);
+	DECLARE_WAITQUEUE(wait, current);
 	unsigned long flags;
 	unsigned count, tmo;
 
 	VALIDATE_STATE(s);
-
 	lock_kernel();
+
 	if (file->f_mode & FMODE_WRITE) {
+		__set_current_state(TASK_INTERRUPTIBLE);
 		add_wait_queue(&s->midi.owait, &wait);
 		for (;;) {
-			set_current_state(TASK_INTERRUPTIBLE);
 			spin_lock_irqsave(&s->lock, flags);
 			count = s->midi.ocnt;
 			spin_unlock_irqrestore(&s->lock, flags);
@@ -2067,11 +2671,12 @@
 			if (file->f_flags & O_NONBLOCK) {
 				remove_wait_queue(&s->midi.owait, &wait);
 				set_current_state(TASK_RUNNING);
+				unlock_kernel();
 				return -EBUSY;
 			}
 			tmo = (count * HZ) / 3100;
 			if (!schedule_timeout(tmo ? : 1) && tmo)
-				printk(KERN_DEBUG "cmpci: midi timed out??\n");
+				printk(KERN_DEBUG "cm: midi timed out??\n");
 		}
 		remove_wait_queue(&s->midi.owait, &wait);
 		set_current_state(TASK_RUNNING);
@@ -2085,7 +2690,7 @@
 		if (!(inb(s->iomidi+1) & 0x80))
 			inb(s->iomidi);
 		/* disable MPU-401 */
-		outb(inb(s->iobase + CODEC_CMI_FUNCTRL1) & ~4, s->iobase + CODEC_CMI_FUNCTRL1);
+		maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~4, 0);
 	}
 	spin_unlock_irqrestore(&s->lock, flags);
 	up(&s->open_sem);
@@ -2103,9 +2708,11 @@
 	open:		cm_midi_open,
 	release:	cm_midi_release,
 };
+#endif
 
 /* --------------------------------------------------------------------- */
 
+#ifdef CONFIG_SOUND_CMPCI_FM
 static int cm_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
 	static const unsigned char op_offset[18] = {
@@ -2197,10 +2804,8 @@
 		outb(5, s->iosynth+2);
 		outb(arg & 1, s->iosynth+3);
 		return 0;
-
-	default:
-		return -EINVAL;
 	}
+	return -EINVAL;
 }
 
 static int cm_dmfm_open(struct inode *inode, struct file *file)
@@ -2236,6 +2841,7 @@
 	outb(1, s->iosynth+3);  /* enable OPL3 */
 	s->open_mode |= FMODE_DMFM;
 	up(&s->open_sem);
+	MOD_INC_USE_COUNT;
 	return 0;
 }
 
@@ -2267,6 +2873,7 @@
 	open:		cm_dmfm_open,
 	release:	cm_dmfm_release,
 };
+#endif /* CONFIG_SOUND_CMPCI_FM */
 
 /* --------------------------------------------------------------------- */
 
@@ -2285,46 +2892,125 @@
 	int mixch;
 	int vol;
 } initvol[] __initdata = {
-	{ SOUND_MIXER_WRITE_CD, 0x4040 },
-	{ SOUND_MIXER_WRITE_LINE, 0x4040 },
-	{ SOUND_MIXER_WRITE_MIC, 0x4040 },
-	{ SOUND_MIXER_WRITE_SYNTH, 0x4040 },
-	{ SOUND_MIXER_WRITE_VOLUME, 0x4040 },
-	{ SOUND_MIXER_WRITE_PCM, 0x4040 }
+	{ SOUND_MIXER_WRITE_CD, 0x4f4f },
+	{ SOUND_MIXER_WRITE_LINE, 0x4f4f },
+	{ SOUND_MIXER_WRITE_MIC, 0x4f4f },
+	{ SOUND_MIXER_WRITE_SYNTH, 0x4f4f },
+	{ SOUND_MIXER_WRITE_VOLUME, 0x4f4f },
+	{ SOUND_MIXER_WRITE_PCM, 0x4f4f }
 };
 
-#ifdef MODULE
-static int	spdif_loop = 0;
-static int	four_ch = 0;
-static int	rear_out = 0;
-MODULE_PARM(spdif_loop, "i");
-MODULE_PARM(four_ch, "i");
-MODULE_PARM(rear_out, "i");
+/* check chip version and capability */
+static int query_chip(struct cm_state *s)
+{
+	int ChipVersion = -1;
+	unsigned char RegValue;
+
+	// check reg 0Ch, bit 24-31
+	RegValue = inb(s->iobase + CODEC_CMI_INT_HLDCLR + 3);
+	if (RegValue == 0) {
+	    // check reg 08h, bit 24-28
+	    RegValue = inb(s->iobase + CODEC_CMI_CHFORMAT + 3);
+	    RegValue &= 0x1f;
+	    if (RegValue == 0) {
+		ChipVersion = 33;
+		s->max_channels = 4;
+		s->capability |= CAN_AC3_SW;
+		s->capability |= CAN_DUAL_DAC;
+	    } else {
+		ChipVersion = 37;
+		s->max_channels = 4;
+		s->capability |= CAN_AC3_HW;
+		s->capability |= CAN_DUAL_DAC;
+	    }
+	} else {
+	    // check reg 0Ch, bit 26
+	    if (RegValue & (1 << (26-24))) {
+		ChipVersion = 39;
+	    	if (RegValue & (1 << (24-24)))
+		    s->max_channels  = 6;
+	    	else
+		    s->max_channels = 4;
+		s->capability |= CAN_AC3_HW;
+		s->capability |= CAN_DUAL_DAC;
+		s->capability |= CAN_MULTI_CH_HW;
+	    } else {
+		ChipVersion = 55; // 4 or 6 channels
+		s->max_channels  = 6;
+		s->capability |= CAN_AC3_HW;
+		s->capability |= CAN_DUAL_DAC;
+		s->capability |= CAN_MULTI_CH_HW;
+	    }
+	}
+	// still limited to number of speakers
+	if (s->max_channels > s->speakers)
+		s->max_channels = s->speakers;
+	return ChipVersion;
+}
+
+#ifdef CONFIG_SOUND_CMPCI_MIDI
+static	int	mpu_io = CONFIG_SOUND_CMPCI_MPUIO;
 #else
+static	int	mpu_io;
+#endif
+#ifdef CONFIG_SOUND_CMPCI_FM
+static	int	fm_io = CONFIG_SOUND_CMPCI_FMIO;
+#else
+static	int	fm_io;
+#endif
+#ifdef CONFIG_SOUND_CMPCI_SPDIFINVERSE
+static	int	spdif_inverse = 1;
+#else
+static	int	spdif_inverse;
+#endif
 #ifdef CONFIG_SOUND_CMPCI_SPDIFLOOP
-static int	spdif_loop = 1;
+static	int	spdif_loop = 1;
+#else
+static	int	spdif_loop;
+#endif
+#ifdef CONFIG_SOUND_CMPCI_SPEAKERS
+static	int	speakers = CONFIG_SOUND_CMPCI_SPEAKERS;
 #else
-static int	spdif_loop = 0;
+static	int	speakers = 2;
 #endif
-#ifdef CONFIG_SOUND_CMPCI_4CH
-static int	four_ch = 1;
+#ifdef CONFIG_SOUND_CMPCI_LINE_REAR
+static	int	use_line_as_rear = 1;
 #else
-static int	four_ch = 0;
+static	int	use_line_as_rear;
 #endif
-#ifdef CONFIG_SOUND_CMPCI_REAR
-static int	rear_out = 1;
+#ifdef CONFIG_SOUND_CMPCI_LINE_BASS
+static	int	use_line_as_bass = 1;
 #else
-static int	rear_out = 0;
+static	int	use_line_as_bass;
 #endif
+#ifdef CONFIG_SOUND_CMPCI_JOYSTICK
+static	int	joystick = 1;
+#else
+static	int	joystick;
 #endif
+MODULE_PARM(mpu_io, "i");
+MODULE_PARM(fm_io, "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(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");
+MODULE_PARM_DESC(use_line_as_rear, "(1/0) Use line-in jack as rear-out");
+MODULE_PARM_DESC(use_line_as_bass, "(1/0) Use line-in jack as bass/center");
+MODULE_PARM_DESC(joystick, "(1/0) Enable joystick interface, still need joystick driver");
 
-static int __init init_cmpci(void)
+void initialize_chip(struct pci_dev *pcidev)
 {
 	struct cm_state *s;
-	struct pci_dev *pcidev = NULL;
 	mm_segment_t fs;
-	int i, val, index = 0;
-	
+	int i, val;
+	unsigned char reg_mask = 0;
 	struct {
 		unsigned short	deviceid;
 		char		*devicename;
@@ -2333,33 +3019,21 @@
 		{ PCI_DEVICE_ID_CMEDIA_CM8338A, "CM8338A" },
 		{ PCI_DEVICE_ID_CMEDIA_CM8338B, "CM8338B" },
 		{ PCI_DEVICE_ID_CMEDIA_CM8738,  "CM8738" },
+		{ PCI_DEVICE_ID_CMEDIA_CM8738B, "CM8738B" },
 	};
 	char	*devicename = "unknown";
-
-#ifdef CONFIG_PCI
-	if (!pci_present())   /* No PCI bus in this machine! */
-#endif
-		return -ENODEV;
-	printk(KERN_INFO "cmpci: version v2.41-nomodem time " __TIME__ " " __DATE__ "\n");
-#if 0
-	if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
-		printk(KERN_INFO "cmpci: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
-#endif
-	while (index < NR_DEVICE && pcidev == NULL && (
- 	       (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A, pcidev)) ||
-	       (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B, pcidev)) ||
-	       (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, pcidev)))) {
+	{
 		if (pci_enable_device(pcidev))
-			continue;
+			return;
 		if (pcidev->irq == 0)
-			continue;
-		if (!(s = kmalloc(sizeof(struct cm_state), GFP_KERNEL))) {
-			printk(KERN_WARNING "cmpci: out of memory\n");
-			continue;
+			return;
+		s = kmalloc(sizeof(*s), GFP_KERNEL);
+		if (!s) {
+			printk(KERN_WARNING "cm: out of memory\n");
+			return;
 		}
 		/* search device name */
-		for (i = 0; i < sizeof(devicetable) / sizeof(devicetable[0]); i++)
-		{
+		for (i = 0; i < sizeof(devicetable) / sizeof(devicetable[0]); i++) {
 			if (devicetable[i].deviceid == pcidev->device)
 			{
 				devicename = devicetable[i].devicename;
@@ -2376,35 +3050,96 @@
 		spin_lock_init(&s->lock);
 		s->magic = CM_MAGIC;
 		s->iobase = pci_resource_start(pcidev, 0);
-		s->iosynth = 0x388;
-		s->iomidi = 0x330;
-		spin_lock_init(&s->lock);
+		s->iosynth = fm_io;
+		s->iomidi = mpu_io;
+		s->status = 0;
+		/* range check */
+		if (speakers < 2)
+			speakers = 2;
+		else if (speakers > 6)
+			speakers = 6;
+		s->speakers = speakers;
 		if (s->iobase == 0)
-			continue;
+			return;
 		s->irq = pcidev->irq;
 
 		if (!request_region(s->iobase, CM_EXTENT_CODEC, "cmpci")) {
-			printk(KERN_ERR "cmpci: io ports %#x-%#x in use\n", s->iobase, s->iobase+CM_EXTENT_CODEC-1);
+			printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iobase, s->iobase+CM_EXTENT_CODEC-1);
 			goto err_region5;
 		}
-		if (!request_region(s->iomidi, CM_EXTENT_MIDI, "cmpci Midi")) {
-			printk(KERN_WARNING "cmpci: io ports %#x-%#x in use, midi disabled.\n", s->iomidi, s->iomidi+CM_EXTENT_MIDI-1);
+#ifdef CONFIG_SOUND_CMPCI_MIDI
+		/* disable MPU-401 */
+		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);
 			s->iomidi = 0;
+		    } else {
+		        /* set IO based at 0x330 */
+		        switch (s->iomidi) {
+		 	    case 0x330:
+				reg_mask = 0;
+				break;
+			    case 0x320:
+				reg_mask = 0x20;
+				break;
+			    case 0x310:
+				reg_mask = 0x40;
+				break;
+			    case 0x300:
+				reg_mask = 0x60;
+				break;
+			    default:
+				s->iomidi = 0;
+				break;
+		        }
+		        outb((inb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3) & ~0x60) | reg_mask, s->iobase + CODEC_CMI_LEGACY_CTRL + 3);
+			/* enable MPU-401 */
+			if (s->iomidi) {
+			    maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x04);
+			}
+		    }
 		}
-		else
-		{
-			/* set IO based at 0x330 */
-			outb(inb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3) & ~0x60, s->iobase + CODEC_CMI_LEGACY_CTRL + 3);
-		}
-		if (!request_region(s->iosynth, CM_EXTENT_SYNTH, "cmpci FM")) {
-			printk(KERN_WARNING "cmpci: io ports %#x-%#x in use, synth disabled.\n", s->iosynth, s->iosynth+CM_EXTENT_SYNTH-1);
+#endif
+#ifdef CONFIG_SOUND_CMPCI_FM
+		/* disable FM */
+		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);
 			s->iosynth = 0;
+		    } else {
+		        /* set IO based at 0x388 */
+		        switch (s->iosynth) {
+		 	    case 0x388:
+				reg_mask = 0;
+				break;
+			    case 0x3C8:
+				reg_mask = 0x01;
+				break;
+			    case 0x3E0:
+				reg_mask = 0x02;
+				break;
+			    case 0x3E8:
+				reg_mask = 0x03;
+				break;
+			    default:
+				s->iosynth = 0;
+				break;
+		        }
+		        maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~0x03, reg_mask);
+		        /* enable FM */
+			if (s->iosynth) {
+		            maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, 8);
+			}
+		    }
 		}
+#endif
+		/* enable joystick */
+		if (joystick)
+			maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x02);
 		else
-		{
-			/* enable FM */
-			outb(inb(s->iobase + CODEC_CMI_MISC_CTRL + 2) | 8, s->iobase + CODEC_CMI_MISC_CTRL);
-		}
+			maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x02, 0);
 		/* initialize codec registers */
 		outb(0, s->iobase + CODEC_CMI_INT_HLDCLR + 2);  /* disable ints */
 		outb(0, s->iobase + CODEC_CMI_FUNCTRL0 + 2); /* disable channels */
@@ -2413,21 +3148,25 @@
 
 		/* request irq */
 		if (request_irq(s->irq, cm_interrupt, SA_SHIRQ, "cmpci", s)) {
-			printk(KERN_ERR "cmpci: irq %u in use\n", s->irq);
+			printk(KERN_ERR "cm: irq %u in use\n", s->irq);
 			goto err_irq;
 		}
-		printk(KERN_INFO "cmpci: found %s adapter at io %#06x irq %u\n",
+		printk(KERN_INFO "cm: 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)
 			goto err_dev1;
 		if ((s->dev_mixer = register_sound_mixer(&cm_mixer_fops, -1)) < 0)
 			goto err_dev2;
-		if (s->iomidi && (s->dev_midi = register_sound_midi(&cm_midi_fops, -1)) < 0)
+#ifdef CONFIG_SOUND_CMPCI_MIDI
+		if ((s->dev_midi = register_sound_midi(&cm_midi_fops, -1)) < 0)
 			goto err_dev3;
-		if (s->iosynth && (s->dev_dmfm = register_sound_special(&cm_dmfm_fops, 15 /* ?? */)) < 0)
+#endif
+#ifdef CONFIG_SOUND_CMPCI_FM
+		if ((s->dev_dmfm = register_sound_special(&cm_dmfm_fops, 15 /* ?? */)) < 0)
 			goto err_dev4;
-		pci_set_master(pcidev);
+#endif
+		pci_set_master(pcidev);	/* enable bus mastering */
 		/* initialize the chips */
 		fs = get_fs();
 		set_fs(KERNEL_DS);
@@ -2440,59 +3179,78 @@
 			val = initvol[i].vol;
 			mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
 		}
-		set_fs(fs);
-		if (pcidev->device == PCI_DEVICE_ID_CMEDIA_CM8738)
-		{
+		/* 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);
+			/* 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");
+			} else {
+				/* turn off spdif-ininverse */
+				maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~1, 0);
+			}
+
 			/* enable SPDIF loop */
-			if (spdif_loop)
-			{
+			if (spdif_loop) {
+				s->status |= DO_SPDIF_LOOP;
 				/* turn on spdif-in to spdif-out */
-				outb(inb(s->iobase + CODEC_CMI_FUNCTRL1) | 0x80, s->iobase + CODEC_CMI_FUNCTRL1);
-				printk(KERN_INFO "cmpci: Enable SPDIF loop\n");
+				maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x80);
+				printk(KERN_INFO "cm: Enable SPDIF loop\n");
+			} else {
+				s->status &= ~DO_SPDIF_LOOP;
+				/* turn off spdif-in to spdif-out */
+				maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x80, 0);
 			}
-			else
-				outb(inb(s->iobase + CODEC_CMI_FUNCTRL1) & ~0x80, s->iobase + CODEC_CMI_FUNCTRL1);
-			/* enable 4 channels mode */
-			if (four_ch)
-			{
-				/* 4 channel mode (analog duplicate) */
-				outb(inb(s->iobase + CODEC_CMI_MISC_CTRL + 3) | 0x04, s->iobase + CODEC_CMI_MISC_CTRL + 3);
-				printk(KERN_INFO "cmpci: Enable 4 channels mode\n");
-				/* has separate rear-out jack ? */
-				if (rear_out)
-				{
-					/* has separate rear out jack */
-					outb(inb(s->iobase + CODEC_CMI_MIXER1) & ~0x20, s->iobase + CODEC_CMI_MIXER1);
-				}
-				else
-				{
-					outb(inb(s->iobase + CODEC_CMI_MIXER1) | 0x20, s->iobase + CODEC_CMI_MIXER1);
-					printk(KERN_INFO "cmpci: line-in routed as rear-out\n");
-				}
+			if (use_line_as_rear) {
+				s->capability |= CAN_LINE_AS_REAR;
+				s->status |= DO_LINE_AS_REAR;
+				maskb(s->iobase + CODEC_CMI_MIXER1, ~0, 0x20);
+			} else
+				maskb(s->iobase + CODEC_CMI_MIXER1, ~0x20, 0);
+			if (s->chip_version >= 39) {
+				if (use_line_as_bass) {
+					s->capability |= CAN_LINE_AS_BASS;
+					s->status |= DO_LINE_AS_BASS;
+					maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~0, 0x60);
+				} else
+					maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~0x60, 0);
 			}
-			else
-				outb(inb(s->iobase + CODEC_CMI_MISC_CTRL + 3) & ~0x04, s->iobase + CODEC_CMI_MISC_CTRL + 3);
+		} else {
+			/* 8338 will fall here */
+			s->max_channels = 2;
 		}
 		/* queue it for later freeing */
 		s->next = devs;
 		devs = s;
-		index++;
-		continue;
+		return;
 
+#ifdef CONFIG_SOUND_CMPCI_FM
+		unregister_sound_special(s->dev_dmfm);
 	err_dev4:
+#endif
+#ifdef CONFIG_SOUND_CMPCI_MIDI
 		unregister_sound_midi(s->dev_midi);
 	err_dev3:
+#endif
 		unregister_sound_mixer(s->dev_mixer);
 	err_dev2:
 		unregister_sound_dsp(s->dev_audio);
 	err_dev1:
-		printk(KERN_ERR "cmpci: cannot register misc device\n");
+		printk(KERN_ERR "cm: cannot register misc device\n");
 		free_irq(s->irq, s);
 	err_irq:
-		if(s->iosynth)
-			release_region(s->iosynth, CM_EXTENT_SYNTH);
-		if(s->iomidi)
-			release_region(s->iomidi, CM_EXTENT_MIDI);
+#ifdef CONFIG_SOUND_CMPCI_FM
+		if (s->iosynth) release_region(s->iosynth, CM_EXTENT_SYNTH);
+#endif
+#ifdef CONFIG_SOUND_CMPCI_MIDI
+		if (s->iomidi) release_region(s->iomidi, CM_EXTENT_MIDI);
+#endif
 		release_region(s->iobase, CM_EXTENT_CODEC);
 	err_region5:
 		kfree(s);
@@ -2500,15 +3258,47 @@
 	if (!devs) {
 		if (wavetable_mem)
 			free_pages(wavetable_mem, 20-PAGE_SHIFT);
+		return;
+	}
+	return;
+}
+
+static int __init init_cmpci(void)
+{
+	struct pci_dev *pcidev = NULL;
+	int index = 0;
+
+#ifdef CONFIG_PCI
+	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
+	while (index < NR_DEVICE && (
+	       (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, pcidev)))) { 
+		initialize_chip(pcidev);
+		index++;
+	}
+	while (index < NR_DEVICE && (
+ 	       (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A, pcidev)))) {
+		initialize_chip(pcidev);
+		index++;
+	}
+	while (index < NR_DEVICE && (
+	       (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B, pcidev)))) {
+		initialize_chip(pcidev);
+		index++;
 	}
 	return 0;
 }
 
 /* --------------------------------------------------------------------- */
 
-MODULE_AUTHOR("ChenLi Tien, cltien@home.com");
-MODULE_DESCRIPTION("CMPCI Audio Driver");
+MODULE_AUTHOR("ChenLi Tien, cltien@cmedia.com.tw");
+MODULE_DESCRIPTION("CM8x38 Audio Driver");
 
 static void __exit cleanup_cmpci(void)
 {
@@ -2520,28 +3310,34 @@
 		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);
 
 		release_region(s->iobase, CM_EXTENT_CODEC);
-		if(s->iomidi)
-		{
-			release_region(s->iomidi, CM_EXTENT_MIDI);
-			unregister_sound_midi(s->dev_midi);
-		}
-		if(s->iosynth)
-		{
-			release_region(s->iosynth, CM_EXTENT_SYNTH);
-			unregister_sound_special(s->dev_dmfm);
-		}
+#ifdef CONFIG_SOUND_CMPCI_MIDI
+		if (s->iomidi) release_region(s->iomidi, CM_EXTENT_MIDI);
+#endif
+#ifdef CONFIG_SOUND_CMPCI_FM
+		if (s->iosynth) release_region(s->iosynth, CM_EXTENT_SYNTH);
+#endif
 		unregister_sound_dsp(s->dev_audio);
 		unregister_sound_mixer(s->dev_mixer);
+#ifdef CONFIG_SOUND_CMPCI_MIDI
+		unregister_sound_midi(s->dev_midi);
+#endif
+#ifdef CONFIG_SOUND_CMPCI_FM
+		unregister_sound_special(s->dev_dmfm);
+#endif
 		kfree(s);
 	}
 	if (wavetable_mem)
 		free_pages(wavetable_mem, 20-PAGE_SHIFT);
-	printk(KERN_INFO "cmpci: unloading\n");
+	printk(KERN_INFO "cm: unloading\n");
 }
 
 module_init(init_cmpci);
diff -u --recursive --new-file v2.4.5/linux/drivers/sound/cs4281/cs4281m.c linux/drivers/sound/cs4281/cs4281m.c
--- v2.4.5/linux/drivers/sound/cs4281/cs4281m.c	Tue May  1 16:05:00 2001
+++ linux/drivers/sound/cs4281/cs4281m.c	Wed Jun 27 17:10:55 2001
@@ -658,7 +658,7 @@
 	       card->pBA0 + BA0_ACCTL);
 
 	// Wait for the write to occur.
-	for (count = 0; count < 10; count++) {
+	for (count = 0; count < 100; count++) {
 		// First, we want to wait for a short time.
 		udelay(25);
 		// Now, check to see if the write has completed.
@@ -946,7 +946,7 @@
 }
 
 #ifndef NOT_CS4281_PM
-void printpm(struct cs4281_state *s)
+static void printpm(struct cs4281_state *s)
 {
 	CS_DBGOUT(CS_PM, 9, printk("pm struct:\n"));
 	CS_DBGOUT(CS_PM, 9, printk("flags:0x%x u32CLKCR1_SAVE: 0%x u32SSPMValue: 0x%x\n",
@@ -967,7 +967,7 @@
 		s->pm.u32MIDCR_Save));
 
 }
-void printpipe(struct cs4281_pipeline *pl)
+static void printpipe(struct cs4281_pipeline *pl)
 {
 
 	CS_DBGOUT(CS_PM, 9, printk("pm struct:\n"));
@@ -1000,7 +1000,7 @@
 	CS_DBGOUT(CS_PM, 9, printk("u32FPDRnValue: 0x%x u32FPDRnAddress: 0x%x\n",
 		pl->u32FPDRnValue,pl->u32FPDRnAddress));
 }
-void printpipelines(struct cs4281_state *s)
+static void printpipelines(struct cs4281_state *s)
 {
 	int i;
 	for(i=0;i<CS4281_NUMBER_OF_PIPELINES;i++)
@@ -4463,9 +4463,9 @@
 	unregister_sound_midi(s->dev_midi);
 	iounmap(s->pBA1);
 	iounmap(s->pBA0);
-	kfree(s);
 	pci_set_drvdata(pci_dev,NULL);
 	list_del(&s->list);
+	kfree(s);
 	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO
 		 "cs4281: cs4281_remove()-: remove successful\n"));
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/sound/cs46xx.c linux/drivers/sound/cs46xx.c
--- v2.4.5/linux/drivers/sound/cs46xx.c	Thu May 24 15:14:08 2001
+++ linux/drivers/sound/cs46xx.c	Wed Jun 27 17:13:43 2001
@@ -50,6 +50,7 @@
  *	20010409-tw	add hercules game theatre XP amp code.
  *	20010420-tw	cleanup powerdown/up code.
  *	20010521-tw	eliminate pops, and fixes for powerdown.
+ *	20010525-tw	added fixes for thinkpads with powerdown logic.
  *
  *	Status:
  *	Playback/Capture supported from 8k-48k.
@@ -179,7 +180,7 @@
 MODULE_PARM(hercules_egpio_disable, "i");
 static unsigned long initdelay=700;  /* PM delay in millisecs */
 MODULE_PARM(initdelay, "i");
-static unsigned long powerdown=1;  /* turn on/off powerdown processing in driver */
+static unsigned long powerdown=-1;  /* turn on/off powerdown processing in driver */
 MODULE_PARM(powerdown, "i");
 #define DMABUF_DEFAULTORDER 3
 static unsigned long defaultorder=DMABUF_DEFAULTORDER;
@@ -190,6 +191,14 @@
 static int thinkpad;
 MODULE_PARM(thinkpad, "i");
 
+/*
+* set the powerdown module parm to 0 to disable all 
+* powerdown. also set thinkpad to 1 to disable powerdown, 
+* but also to enable the clkrun functionality.
+*/
+static unsigned cs_powerdown=1;
+static unsigned cs_laptop_wait=1;
+
 /* An instance of the 4610 channel */
 struct cs_channel 
 {
@@ -199,7 +208,7 @@
 };
 
 #define CS46XX_MAJOR_VERSION "1"
-#define CS46XX_MINOR_VERSION "27"
+#define CS46XX_MINOR_VERSION "28"
 
 #ifdef __ia64__
 #define CS46XX_ARCH	     	"64"	//architecture key
@@ -284,6 +293,8 @@
 		int ossmaxfrags;
 		unsigned subdivision;
 	} dmabuf;
+	/* Guard against mmap/write/read races */
+	struct semaphore sem;
 };
 
 struct cs_card {
@@ -370,8 +381,10 @@
 static loff_t cs_llseek(struct file *file, loff_t offset, int origin);
 static int cs_hardware_init(struct cs_card *card);
 static int cs46xx_powerup(struct cs_card *card, unsigned int type);
-static int cs461x_powerdown(struct cs_card *card, unsigned int type);
+static int cs461x_powerdown(struct cs_card *card, unsigned int type, int suspendflag);
 static void cs461x_clear_serial_FIFOs(struct cs_card *card, int type);
+static void cs46xx_suspend_tbl(struct pci_dev *pcidev);
+static void cs46xx_resume_tbl(struct pci_dev *pcidev);
 
 static inline unsigned ld2(unsigned int x)
 {
@@ -688,7 +701,7 @@
 {
 	struct ac97_codec *dev=card->ac97_codec[0];
 
-	CS_DBGOUT(CS_FUNCTION, 2, printk("cs46xx: cs_mute()+ %s\n",
+	CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_INFO "cs46xx: cs_mute()+ %s\n",
 		(state == CS_TRUE) ? "Muting" : "UnMuting") );
 
 	if(state == CS_TRUE)
@@ -717,7 +730,7 @@
 		cs_ac97_set(dev, (u8)BA0_AC97_MASTER_VOLUME_MONO, card->pm.u32AC97_master_volume_mono);
 		cs_ac97_set(dev, (u8)BA0_AC97_PCM_OUT_VOLUME, card->pm.u32AC97_pcm_out_volume);
 	}
-	CS_DBGOUT(CS_FUNCTION, 2, printk("cs46xx: cs_mute()-\n"));
+	CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_INFO "cs46xx: cs_mute()-\n"));
 }
 
 /* set playback sample rate */
@@ -1250,7 +1263,7 @@
 	dmabuf->SGok = 0;
 }
 
-static int prog_dmabuf(struct cs_state *state)
+static int __prog_dmabuf(struct cs_state *state)
 {
         struct dmabuf *dmabuf = &state->dmabuf;
         unsigned long flags;
@@ -1431,6 +1444,17 @@
 	return 1;
 }
 
+static int prog_dmabuf(struct cs_state *state)
+{
+	int ret;
+	
+	down(&state->sem);
+	ret = __prog_dmabuf(state);
+	up(&state->sem);
+	
+	return ret;
+}
+
 static void cs_clear_tail(struct cs_state *state)
 {
 }
@@ -2089,11 +2113,12 @@
 		return -ESPIPE;
 	if (dmabuf->mapped)
 		return -ENXIO;
-	if (!dmabuf->ready && (ret = prog_dmabuf(state)))
-		return ret;
 	if (!access_ok(VERIFY_WRITE, buffer, count))
 		return -EFAULT;
-	ret = 0;
+	
+	down(&state->sem);
+	if (!dmabuf->ready && (ret = __prog_dmabuf(state)))
+		goto out;
 
 	add_wait_queue(&state->dmabuf.wait, &wait);
 	while (count > 0) {
@@ -2101,8 +2126,8 @@
 		{
 			schedule();
 			if (signal_pending(current)) {
-				ret = ret ? ret : -ERESTARTSYS;
-				break;
+				if(!ret) ret = -ERESTARTSYS;
+				goto out;
 			}
 		}
 		spin_lock_irqsave(&state->card->lock, flags);
@@ -2122,12 +2147,20 @@
 			start_adc(state);
 			if (file->f_flags & O_NONBLOCK) {
 				if (!ret) ret = -EAGAIN;
-				break;
+				goto out;
  			}
+			up(&state->sem);
 			schedule();
 			if (signal_pending(current)) {
-				ret = ret ? ret : -ERESTARTSYS;
-				break;
+				if(!ret) ret = -ERESTARTSYS;
+				goto out;
+			}
+			down(&state->sem);
+			if (dmabuf->mapped) 
+			{
+				if(!ret)
+					ret = -ENXIO;
+				goto out;
 			}
  			continue;
 		}
@@ -2142,7 +2175,7 @@
 			(void *)((unsigned)dmabuf->rawbuf + swptr), cnt, &copied))
 		{
 			if (!ret) ret = -EFAULT;
-			break;
+			goto out;
 		}
                 swptr = (swptr + cnt) % dmabuf->dmasize;
                 spin_lock_irqsave(&card->lock, flags);
@@ -2154,6 +2187,8 @@
                 ret += copied;
                 start_adc(state);
 	}
+out:
+	up(&state->sem);
 	remove_wait_queue(&state->dmabuf.wait, &wait);
 	set_current_state(TASK_RUNNING);
 	CS_DBGOUT(CS_WAVE_READ | CS_FUNCTION, 4, 
@@ -2183,12 +2218,21 @@
 
 	if (ppos != &file->f_pos)
 		return -ESPIPE;
+
+	down(&state->sem);
 	if (dmabuf->mapped)
-		return -ENXIO;
-	if (!dmabuf->ready && (ret = prog_dmabuf(state)))
-		return ret;
+	{
+		ret = -ENXIO;
+		goto out;
+	}
+
+	if (!dmabuf->ready && (ret = __prog_dmabuf(state)))
+		goto out;
 	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
+	{
+	ret = -EFAULT;
+	goto out;
+	}
 	add_wait_queue(&state->dmabuf.wait, &wait);
 	ret = 0;
 /*
@@ -2200,8 +2244,8 @@
 		{
 			schedule();
 			if (signal_pending(current)) {
-				ret = ret ? ret : -ERESTARTSYS;
-				break;
+				if(!ret) ret = -ERESTARTSYS;
+				goto out;
 			}
 		}
 		spin_lock_irqsave(&state->card->lock, flags);
@@ -2234,18 +2278,26 @@
 			start_dac(state);
 			if (file->f_flags & O_NONBLOCK) {
 				if (!ret) ret = -EAGAIN;
-				break;
+				goto out;
  			}
+			up(&state->sem);
 			schedule();
  			if (signal_pending(current)) {
-				ret = ret ? ret : -ERESTARTSYS;
-				break;
+				if(!ret) ret = -ERESTARTSYS;
+				goto out;
  			}
+			down(&state->sem);
+			if (dmabuf->mapped)
+			{
+				if(!ret)
+					ret = -ENXIO;
+				goto out;
+			}
  			continue;
  		}
 		if (copy_from_user(dmabuf->rawbuf + swptr, buffer, cnt)) {
 			if (!ret) ret = -EFAULT;
-			return ret;
+			goto out;
 		}
 		spin_lock_irqsave(&state->card->lock, flags);
 		swptr = (swptr + cnt) % dmabuf->dmasize;
@@ -2265,6 +2317,8 @@
 		ret += cnt;
 		start_dac(state);
 	}
+out:
+	up(&state->sem);
 	remove_wait_queue(&state->dmabuf.wait, &wait);
 	set_current_state(TASK_RUNNING);
 
@@ -2352,9 +2406,9 @@
 	struct cs_card *card = (struct cs_card *)file->private_data;
 	struct cs_state *state;
 	struct dmabuf *dmabuf;
-	int ret;
+	int ret = 0;
 	unsigned long size;
-	
+
 	CS_DBGOUT(CS_FUNCTION | CS_PARMS, 2, printk("cs46xx: cs_mmap()+ file=0x%x %s %s\n", 
 		(unsigned)file, vma->vm_flags & VM_WRITE ? "VM_WRITE" : "",
 		vma->vm_flags & VM_READ ? "VM_READ" : "") );
@@ -2393,24 +2447,39 @@
  */
 	state = card->states[1];  
 	if(!(unsigned)state)
-		return -EINVAL;
+	{
+		ret = -EINVAL;
+		goto out;
+	}
 
+	down(&state->sem);	
 	dmabuf = &state->dmabuf;
 	if (cs4x_pgoff(vma) != 0)
-		return -EINVAL;
+	{
+		ret = -EINVAL;
+		goto out;
+	}
 	size = vma->vm_end - vma->vm_start;
 
 	CS_DBGOUT(CS_PARMS, 2, printk("cs46xx: cs_mmap(): size=%d\n",(unsigned)size) );
 
 	if (size > (PAGE_SIZE << dmabuf->buforder))
-		return -EINVAL;
+	{
+		ret = -EINVAL;
+		goto out;
+	}
 	if (remap_page_range(vma->vm_start, virt_to_phys(dmabuf->rawbuf),
 			     size, vma->vm_page_prot))
-		return -EAGAIN;
+	{
+		ret = -EAGAIN;
+		goto out;
+	}
 	dmabuf->mapped = 1;
 
 	CS_DBGOUT(CS_FUNCTION, 2, printk("cs46xx: cs_mmap()-\n") );
-	return 0;
+out:
+	up(&state->sem);
+	return ret;	
 }
 
 static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
@@ -3146,6 +3215,7 @@
 			if (state == NULL)
 				return -ENOMEM;
 			memset(state, 0, sizeof(struct cs_state));
+			init_MUTEX(&state->sem);
 			dmabuf = &state->dmabuf;
 			dmabuf->pbuf = (void *)get_free_page(GFP_KERNEL | GFP_DMA);
 			if(dmabuf->pbuf==NULL)
@@ -3217,6 +3287,7 @@
 			if (state == NULL)
 				return -ENOMEM;
 			memset(state, 0, sizeof(struct cs_state));
+			init_MUTEX(&state->sem);
 			dmabuf = &state->dmabuf;
 			dmabuf->pbuf = (void *)get_free_page(GFP_KERNEL | GFP_DMA);
 			if(dmabuf->pbuf==NULL)
@@ -3281,7 +3352,6 @@
 		if((ret = prog_dmabuf(state)))
 			return ret;
 	}
-
 	CS_DBGOUT(CS_OPEN | CS_FUNCTION, 2, printk("cs46xx: cs_open()- 0\n") );
 	return 0;
 }
@@ -3321,11 +3391,10 @@
 			state->card->states[state->virt] = NULL;
 			state->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
 
-			if( (tmp = cs461x_powerdown(card, CS_POWER_DAC )) )
+			if( (tmp = cs461x_powerdown(card, CS_POWER_DAC, CS_FALSE )) )
 			{
 				CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO 
 					"cs46xx: cs_release_mixdev() powerdown DAC failure (0x%x)\n",tmp) );
-				return -EIO;
 			}
 
 			/* Now turn off external AMP if needed */
@@ -3355,11 +3424,10 @@
 			state->card->states[state->virt] = NULL;
 			state->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
 
-			if( (tmp = cs461x_powerdown(card, CS_POWER_ADC )) )
+			if( (tmp = cs461x_powerdown(card, CS_POWER_ADC, CS_FALSE )) )
 			{
 				CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO 
 					"cs46xx: cs_release_mixdev() powerdown ADC failure (0x%x)\n",tmp) );
-				return -EIO;
 			}
 
 			/* Now turn off external AMP if needed */
@@ -3375,7 +3443,7 @@
 	return 0;
 }
 
-void printpm(struct cs_card *s)
+static void printpm(struct cs_card *s)
 {
 	CS_DBGOUT(CS_PM, 9, printk("pm struct:\n"));
 	CS_DBGOUT(CS_PM, 9, printk("flags:0x%x u32CLKCR1_SAVE: 0%x u32SSPMValue: 0x%x\n",
@@ -3419,8 +3487,8 @@
 void cs46xx_ac97_suspend(struct cs_card *card)
 {
 	int Count,i;
-	unsigned int tmp;
 	struct ac97_codec *dev=card->ac97_codec[0];
+	unsigned int tmp;
 
 	CS_DBGOUT(CS_PM, 9, printk("cs46xx: cs46xx_ac97_suspend()+\n"));
 
@@ -3445,7 +3513,6 @@
 * Save the ac97 volume registers as well as the current powerdown state.
 * Now, mute the all the outputs (master, headphone, and mono), as well
 * as the PCM volume, in preparation for powering down the entire part.
-*/ 
 	card->pm.u32AC97_master_volume = (u32)cs_ac97_get( dev, 
 			(u8)BA0_AC97_MASTER_VOLUME); 
 	card->pm.u32AC97_headphone_volume = (u32)cs_ac97_get(dev, 
@@ -3454,22 +3521,27 @@
 			(u8)BA0_AC97_MASTER_VOLUME_MONO); 
 	card->pm.u32AC97_pcm_out_volume = (u32)cs_ac97_get(dev, 
 			(u8)BA0_AC97_PCM_OUT_VOLUME);
-		
+*/ 
+/*
+* mute the outputs
+*/
 	cs_ac97_set(dev, (u8)BA0_AC97_MASTER_VOLUME, 0x8000);
 	cs_ac97_set(dev, (u8)BA0_AC97_HEADPHONE_VOLUME, 0x8000);
 	cs_ac97_set(dev, (u8)BA0_AC97_MASTER_VOLUME_MONO, 0x8000);
 	cs_ac97_set(dev, (u8)BA0_AC97_PCM_OUT_VOLUME, 0x8000);
 
+/*
+* save the registers that cause pops
+*/
 	card->pm.u32AC97_powerdown = (u32)cs_ac97_get(dev, (u8)AC97_POWER_CONTROL); 
 	card->pm.u32AC97_general_purpose = (u32)cs_ac97_get(dev, (u8)BA0_AC97_GENERAL_PURPOSE); 
-
 /*
 * And power down everything on the AC97 codec.
 * well, for now, only power down the DAC/ADC and MIXER VREFON components. 
 * trouble with removing VREF.
 */
 	if( (tmp = cs461x_powerdown(card, CS_POWER_DAC | CS_POWER_ADC |
-			CS_POWER_MIXVON )) )
+			CS_POWER_MIXVON, CS_TRUE )) )
 	{
 		CS_DBGOUT(CS_ERROR | CS_INIT, 1, printk(KERN_INFO 
 			"cs46xx: cs46xx_ac97_suspend() failure (0x%x)\n",tmp) );
@@ -3502,17 +3574,12 @@
 */
 	cs_ac97_set(dev, (u8)BA0_AC97_GENERAL_PURPOSE, 
 		(u16)card->pm.u32AC97_general_purpose);
-
-	cs_ac97_set(dev, (u8)AC97_POWER_CONTROL, 
-		(u16)card->pm.u32AC97_powerdown);
-	mdelay(10);
-
 /*
 * Now, while the outputs are still muted, restore the state of power
 * on the AC97 part.
 */
 	cs_ac97_set(dev, (u8)BA0_AC97_POWERDOWN, (u16)card->pm.u32AC97_powerdown);
-	mdelay(5);
+	mdelay(5 * cs_laptop_wait);
 /*
 * Restore just the first set of registers, from register number
 * 0x02 to the register number that ulHighestRegToRestore specifies.
@@ -3544,7 +3611,7 @@
 		dmabuf->ready = 0;
 		resync_dma_ptrs(card->states[1]);
 		cs_set_divisor(dmabuf);
-		if(prog_dmabuf(card->states[1]))
+		if(__prog_dmabuf(card->states[1]))
 		{
 			CS_DBGOUT(CS_PM | CS_ERROR, 1, 
 				printk("cs46xx: cs46xx_restart_part()- (-1) prog_dmabuf() dac error\n"));
@@ -3558,7 +3625,7 @@
 		dmabuf->ready = 0;
 		resync_dma_ptrs(card->states[0]);
 		cs_set_divisor(dmabuf);
-		if(prog_dmabuf(card->states[0]))
+		if(__prog_dmabuf(card->states[0]))
 		{
 			CS_DBGOUT(CS_PM | CS_ERROR, 1, 
 				printk("cs46xx: cs46xx_restart_part()- (-1) prog_dmabuf() adc error\n"));
@@ -3588,7 +3655,7 @@
 
 static void cs461x_reset(struct cs_card *card);
 static void cs461x_proc_stop(struct cs_card *card);
-int cs46xx_suspend(struct cs_card *card)
+static int cs46xx_suspend(struct cs_card *card)
 {
 	unsigned int tmp;
 	CS_DBGOUT(CS_PM | CS_FUNCTION, 4, 
@@ -3680,7 +3747,7 @@
 	return 0;
 }
 
-int cs46xx_resume(struct cs_card *card)
+static int cs46xx_resume(struct cs_card *card)
 {
 	int i;
 
@@ -3704,7 +3771,7 @@
 		{
 			CS_DBGOUT(CS_PM | CS_ERROR, 4, printk(
 				"cs46xx: cs46xx_resume()- ERROR in cs_hardware_init()\n"));
-			mdelay(10);
+			mdelay(10 * cs_laptop_wait);
 			cs461x_reset(card);
 			continue;
 		}
@@ -3789,12 +3856,13 @@
 	if(!(card->pm.flags & CS46XX_PM_IDLE))
 		loopcnt = 2000;
 	else
-		loopcnt = 500;
+		loopcnt = 500 * cs_laptop_wait;
+ 	loopcnt *= cs_laptop_wait;
 	for (count = 0; count < loopcnt; count++) {
 		/*
 		 *  First, we want to wait for a short time.
 	 	 */
-		udelay(10);
+		udelay(10 * cs_laptop_wait);
 		/*
 		 *  Now, check to see if the read has completed.
 		 *  ACCTL = 460h, DCV should be reset by now and 460h = 17h
@@ -3819,7 +3887,8 @@
 	if(!(card->pm.flags & CS46XX_PM_IDLE))
 		loopcnt = 2000;
 	else
-		loopcnt = 100;
+		loopcnt = 1000;
+ 	loopcnt *= cs_laptop_wait;
 	for (count = 0; count < loopcnt; count++) {
 		/*
 		 *  Read the AC97 status register.
@@ -3828,16 +3897,16 @@
 		 */
 		if (cs461x_peekBA0(card, BA0_ACSTS) & ACSTS_VSTS)
 			break;
-		udelay(10);
+		udelay(10 * cs_laptop_wait);
 	}
 	
 	/*
 	 *  Make sure we got valid status.
 	 */
 	if (!( (tmp=cs461x_peekBA0(card, BA0_ACSTS)) & ACSTS_VSTS)) {
-		CS_DBGOUT(CS_ERROR, 1, printk(KERN_WARNING 
-			"cs46xx: AC'97 read problem (ACSTS_VSTS), reg = 0x%x val=0x%x \n", reg, tmp));
-		CS_DBGOUT(CS_ERROR, 9, printk(KERN_WARNING "returning 0xffff\n"));
+		CS_DBGOUT(CS_ERROR, 2, printk(KERN_WARNING 
+			"cs46xx: AC'97 read problem (ACSTS_VSTS), reg = 0x%x val=0x%x 0xffff \n", 
+				reg, tmp));
 		return 0xffff;
 	}
 
@@ -3849,7 +3918,7 @@
 		"cs46xx: cs_ac97_get() reg = 0x%x, val = 0x%x, BA0_ACCAD = 0x%x\n", 
 			reg, cs461x_peekBA0(card, BA0_ACSDA),
 			cs461x_peekBA0(card, BA0_ACCAD)));
-	return (cs461x_peekBA0(card, BA0_ACSDA));
+	return(cs461x_peekBA0(card, BA0_ACSDA));
 }
 
 static void cs_ac97_set(struct ac97_codec *dev, u8 reg, u16 val)
@@ -3893,7 +3962,7 @@
 		/*
 		 *  First, we want to wait for a short time.
 		 */
-		udelay(10);
+		udelay(10 * cs_laptop_wait);
 		/*
 		 *  Now, check to see if the write has completed.
 		 *  ACCTL = 460h, DCV should be reset by now and 460h = 07h
@@ -4032,24 +4101,28 @@
 		return -ENODEV;
 	}
 match:
-	card->active_ctrl(card, -1);
-	card->amplifier_ctrl(card, -1);
 	MOD_DEC_USE_COUNT;
 	if(!CS_DEC_AND_TEST(&card->mixer_use_cnt))
 	{
 		CS_DBGOUT(CS_FUNCTION | CS_RELEASE, 4,
 			  printk(KERN_INFO "cs46xx: cs_release_mixdev()- no powerdown, usecnt>0\n"));
+		card->active_ctrl(card, -1);
+		card->amplifier_ctrl(card, -1);
 		return 0;
 	}
 /*
 * ok, no outstanding mixer opens, so powerdown.
 */
-	if( (tmp = cs461x_powerdown(card, CS_POWER_MIXVON )) )
+	if( (tmp = cs461x_powerdown(card, CS_POWER_MIXVON, CS_FALSE )) )
 	{
 		CS_DBGOUT(CS_ERROR | CS_INIT, 1, printk(KERN_INFO 
 			"cs46xx: cs_release_mixdev() powerdown MIXVON failure (0x%x)\n",tmp) );
+		card->active_ctrl(card, -1);
+		card->amplifier_ctrl(card, -1);
 		return -EIO;
 	}
+	card->active_ctrl(card, -1);
+	card->amplifier_ctrl(card, -1);
 	CS_DBGOUT(CS_FUNCTION | CS_RELEASE, 4,
 		  printk(KERN_INFO "cs46xx: cs_release_mixdev()- 0\n"));
 	return 0;
@@ -4341,14 +4414,14 @@
 }
 
 
-static int cs461x_powerdown(struct cs_card *card, unsigned int type)
+static int cs461x_powerdown(struct cs_card *card, unsigned int type, int suspendflag)
 {
 	int count;
-	unsigned int tmp=0;
+	unsigned int tmp=0,muted=0;
 
 	CS_DBGOUT(CS_FUNCTION, 4, printk(KERN_INFO 
 		"cs46xx: cs461x_powerdown()+ type=0x%x\n",type));
-	if(!powerdown)
+	if(!cs_powerdown && !suspendflag)
 	{
 		CS_DBGOUT(CS_FUNCTION, 8, printk(KERN_INFO 
 			"cs46xx: cs461x_powerdown() DISABLED exiting\n"));
@@ -4380,8 +4453,6 @@
 	type &= ~CS_POWER_MIXVON;
 	type &= ~CS_POWER_MIXVOFF;
 
-	cs_mute(card, CS_TRUE);
-
 	/*
 	 *  Power down indicated areas.
 	 */
@@ -4396,6 +4467,11 @@
 		tmp = cs_ac97_get(card->ac97_codec[0], AC97_POWER_CONTROL);
 		if (tmp & CS_AC97_POWER_CONTROL_MIXVOFF_ON)
 		{
+			if(!muted)
+			{
+				cs_mute(card, CS_TRUE);
+				muted=1;
+			}
 			tmp |= CS_AC97_POWER_CONTROL_MIXVOFF;
 			cs_ac97_set(card->ac97_codec[0], AC97_POWER_CONTROL, tmp );
 			/*
@@ -4439,6 +4515,11 @@
 		tmp = cs_ac97_get(card->ac97_codec[0], AC97_POWER_CONTROL);
 		if (tmp & CS_AC97_POWER_CONTROL_MIXVON_ON)
 		{
+			if(!muted)
+			{
+				cs_mute(card, CS_TRUE);
+				muted=1;
+			}
 			tmp |= CS_AC97_POWER_CONTROL_MIXVON;
 			cs_ac97_set(card->ac97_codec[0], AC97_POWER_CONTROL, tmp );
 			/*
@@ -4480,6 +4561,11 @@
 		tmp = cs_ac97_get(card->ac97_codec[0], AC97_POWER_CONTROL);
 		if (tmp & CS_AC97_POWER_CONTROL_ADC_ON)
 		{
+			if(!muted)
+			{
+				cs_mute(card, CS_TRUE);
+				muted=1;
+			}
 			tmp |= CS_AC97_POWER_CONTROL_ADC;
 			cs_ac97_set(card->ac97_codec[0], AC97_POWER_CONTROL, tmp );
 
@@ -4524,6 +4610,11 @@
 		tmp = cs_ac97_get(card->ac97_codec[0], AC97_POWER_CONTROL);
 		if (tmp & CS_AC97_POWER_CONTROL_DAC_ON)
 		{
+			if(!muted)
+			{
+				cs_mute(card, CS_TRUE);
+				muted=1;
+			}
 			tmp |= CS_AC97_POWER_CONTROL_DAC;
 			cs_ac97_set(card->ac97_codec[0], AC97_POWER_CONTROL, tmp );
 			/*
@@ -4557,7 +4648,8 @@
 		}
 	}
 	tmp = cs_ac97_get(card->ac97_codec[0], AC97_POWER_CONTROL);
-	cs_mute(card, CS_FALSE);
+	if(muted)
+		cs_mute(card, CS_FALSE);
 	CS_DBGOUT(CS_FUNCTION, 4, printk(KERN_INFO 
 		"cs46xx: cs461x_powerdown()- 0 tmp=0x%x\n",tmp));
 	return 0;
@@ -4566,7 +4658,7 @@
 static int cs46xx_powerup(struct cs_card *card, unsigned int type)
 {
 	int count;
-	unsigned int tmp=0;
+	unsigned int tmp=0,muted=0;
 
 	CS_DBGOUT(CS_FUNCTION, 8, printk(KERN_INFO 
 		"cs46xx: cs46xx_powerup()+ type=0x%x\n",type));
@@ -4578,7 +4670,6 @@
 	if(type & (CS_POWER_DAC | CS_POWER_ADC))
 		type |= CS_POWER_MIXVON | CS_POWER_MIXVOFF;
 
-	cs_mute(card, CS_TRUE);
 	/*
 	 *  Power up indicated areas.
 	 */
@@ -4593,6 +4684,11 @@
 		tmp = cs_ac97_get(card->ac97_codec[0], AC97_POWER_CONTROL);
 		if (!(tmp & CS_AC97_POWER_CONTROL_MIXVOFF_ON))
 		{
+			if(!muted)
+			{
+				cs_mute(card, CS_TRUE);
+				muted=1;
+			}
 			tmp &= ~CS_AC97_POWER_CONTROL_MIXVOFF;
 			cs_ac97_set(card->ac97_codec[0], AC97_POWER_CONTROL, tmp );
 			/*
@@ -4636,6 +4732,11 @@
 		tmp = cs_ac97_get(card->ac97_codec[0], AC97_POWER_CONTROL);
 		if (!(tmp & CS_AC97_POWER_CONTROL_MIXVON_ON))
 		{
+			if(!muted)
+			{
+				cs_mute(card, CS_TRUE);
+				muted=1;
+			}
 			tmp &= ~CS_AC97_POWER_CONTROL_MIXVON;
 			cs_ac97_set(card->ac97_codec[0], AC97_POWER_CONTROL, tmp );
 			/*
@@ -4677,6 +4778,11 @@
 		tmp = cs_ac97_get(card->ac97_codec[0], AC97_POWER_CONTROL);
 		if (!(tmp & CS_AC97_POWER_CONTROL_ADC_ON))
 		{
+			if(!muted)
+			{
+				cs_mute(card, CS_TRUE);
+				muted=1;
+			}
 			tmp &= ~CS_AC97_POWER_CONTROL_ADC;
 			cs_ac97_set(card->ac97_codec[0], AC97_POWER_CONTROL, tmp );
 
@@ -4721,6 +4827,11 @@
 		tmp = cs_ac97_get(card->ac97_codec[0], AC97_POWER_CONTROL);
 		if (!(tmp & CS_AC97_POWER_CONTROL_DAC_ON))
 		{
+			if(!muted)
+			{
+				cs_mute(card, CS_TRUE);
+				muted=1;
+			}
 			tmp &= ~CS_AC97_POWER_CONTROL_DAC;
 			cs_ac97_set(card->ac97_codec[0], AC97_POWER_CONTROL, tmp );
 			/*
@@ -4754,7 +4865,8 @@
 		}
 	}
 	tmp = cs_ac97_get(card->ac97_codec[0], AC97_POWER_CONTROL);
-	cs_mute(card, CS_FALSE);
+	if(muted)
+		cs_mute(card, CS_FALSE);
 	CS_DBGOUT(CS_FUNCTION, 4, printk(KERN_INFO 
 		"cs46xx: cs46xx_powerup()- 0 tmp=0x%x\n",tmp));
 	return 0;
@@ -4843,7 +4955,7 @@
 	 *  generating bit clock (so we don't try to start the PLL without an
 	 *  input clock).
 	 */
-	mdelay(5);		/* 1 should be enough ?? (and pigs might fly) */
+	mdelay(5 * cs_laptop_wait);		/* 1 should be enough ?? (and pigs might fly) */
 
 	/*
 	 *  Set the serial port timing configuration, so that
@@ -4876,7 +4988,7 @@
 	/*
          *  Wait until the PLL has stabilized.
 	 */
-	mdelay(5);		/* Again 1 should be enough ?? */
+	mdelay(5 * cs_laptop_wait);		/* Again 1 should be enough ?? */
 
 	/*
 	 *  Turn on clocking of the core so that we can setup the serial ports.
@@ -4903,7 +5015,7 @@
 	cs461x_pokeBA0(card, BA0_SERMC1, SERMC1_PTC_AC97 | SERMC1_MSPE);
 
 
-	mdelay(5);		/* Shouldnt be needed ?? */
+	mdelay(5 * cs_laptop_wait);		/* Shouldnt be needed ?? */
 	
 /*
 * If we are resuming under 2.2.x then we can not schedule a timeout.
@@ -4930,7 +5042,7 @@
 	{
 		for (count = 0; count < 100; count++) {
 		// First, we want to wait for a short time.
-			udelay(25);
+			udelay(25 * cs_laptop_wait);
 
 			if (cs461x_peekBA0(card, BA0_ACSTS) & ACSTS_CRDY)
 				break;
@@ -4978,7 +5090,7 @@
 	{
 		for (count = 0; count < 100; count++) {
 		// First, we want to wait for a short time.
-			udelay(25);
+			udelay(25 * cs_laptop_wait);
 
 			if ((cs461x_peekBA0(card, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4))
 				break;
@@ -5068,7 +5180,7 @@
 	 */
 	if(card->pm.flags & CS46XX_PM_IDLE)
 	{
-		if(!powerdown)
+		if(!cs_powerdown)
 		{
 			if( (tmp = cs46xx_powerup(card, CS_POWER_DAC | CS_POWER_ADC |
 					CS_POWER_MIXVON )) )
@@ -5081,7 +5193,7 @@
 		else
 		{
 			if( (tmp = cs461x_powerdown(card, CS_POWER_DAC | CS_POWER_ADC |
-					CS_POWER_MIXVON )) )
+					CS_POWER_MIXVON, CS_FALSE )) )
 			{
 				CS_DBGOUT(CS_ERROR | CS_INIT, 1, printk(KERN_INFO 
 					"cs46xx: cs461x_powerdown() failure (0x%x)\n",tmp) );
@@ -5148,6 +5260,7 @@
 	CS_DBGOUT(CS_FUNCTION | CS_INIT, 2,
 		  printk(KERN_INFO "cs46xx: probe()+\n"));
 
+	dma_mask = 0xffffffff;	/* this enables playback and recording */
 	if (pci_enable_device(pci_dev)) {
 		CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
 			 "cs46xx: pci_enable_device() failed\n"));
@@ -5169,8 +5282,6 @@
 		      "cs46xx: probe() architecture does not support 32bit PCI busmaster DMA\n"));
 		return -1;
 	}
-	dma_mask = 0xffffffff;	/* this enables playback and recording */
-
 	pci_read_config_word(pci_dev, PCI_SUBSYSTEM_VENDOR_ID, &ss_vendor);
 	pci_read_config_word(pci_dev, PCI_SUBSYSTEM_ID, &ss_card);
 
@@ -5239,7 +5350,31 @@
 		printk(KERN_INFO "cs46xx: Activating CLKRUN hack for Thinkpad.\n");
 		card->active_ctrl = clkrun_hack;
 	}
-	
+/*
+* The thinkpads don't work well without runtime updating on their kernel 
+* delay values (or any laptop with variable CPU speeds really).
+* so, just to be safe set the init delay to 2100.  Eliminates
+* failures on T21 Thinkpads.  remove this code when the udelay
+* and mdelay kernel code is replaced by a pm timer, or the delays
+* work well for battery and/or AC power both.
+*/
+	if(card->active_ctrl == clkrun_hack)
+	{
+		initdelay = 2100;
+		cs_laptop_wait = 5;
+	}
+	if((card->active_ctrl == clkrun_hack) && !(powerdown == 1))
+	{
+/*
+* for some currently unknown reason, powering down the DAC and ADC component
+* blocks on thinkpads causes some funky behavior... distoorrrtion and ac97 
+* codec access problems.  probably the serial clock becomes unsynced. 
+* added code to sync the chips back up, but only helped about 70% the time.
+*/
+		cs_powerdown = 0;
+	}
+	if(powerdown == 0)
+		cs_powerdown = 0;
 	card->active_ctrl(card, 1);
 
 	/* claim our iospace and irq */
@@ -5290,7 +5425,7 @@
 					unregister_sound_mixer(card->ac97_codec[j]->dev_mixer);
 					kfree (card->ac97_codec[j]);
 				}
-			mdelay(10);
+			mdelay(10 * cs_laptop_wait);
 			continue;
 		}
 		break;
@@ -5413,7 +5548,7 @@
 	 *  them.
 	 */
 	if( (tmp = cs461x_powerdown(card, CS_POWER_DAC | CS_POWER_ADC |
-			CS_POWER_MIXVON )) )
+			CS_POWER_MIXVON, CS_TRUE )) )
 	{
 		CS_DBGOUT(CS_ERROR | CS_INIT, 1, printk(KERN_INFO 
 			"cs46xx: cs461x_powerdown() failure (0x%x)\n",tmp) );
@@ -5553,21 +5688,22 @@
 	return 0;
 }
 
-static void cs46xx_suspend_tbl(struct pci_dev *pcidev)
+#if CS46XX_ACPI_SUPPORT
+static int cs46xx_suspend_tbl(struct pci_dev *pcidev, u32 state)
 {
 	struct cs_card *s = PCI_GET_DRIVER_DATA(pcidev);
 	CS_DBGOUT(CS_PM | CS_FUNCTION, 2, 
 		printk(KERN_INFO "cs46xx: cs46xx_suspend_tbl request\n"));
 	cs46xx_suspend(s);
-	return;
+	return 0;
 }
 
-static void cs46xx_resume_tbl(struct pci_dev *pcidev)
+static int cs46xx_resume_tbl(struct pci_dev *pcidev)
 {
 	struct cs_card *s = PCI_GET_DRIVER_DATA(pcidev);
 	CS_DBGOUT(CS_PM | CS_FUNCTION, 2, 
 		printk(KERN_INFO "cs46xx: cs46xx_resume_tbl request\n"));
 	cs46xx_resume(s);
-	return;
+	return 0;
 }
-
+#endif
diff -u --recursive --new-file v2.4.5/linux/drivers/sound/cs46xxpm-24.h linux/drivers/sound/cs46xxpm-24.h
--- v2.4.5/linux/drivers/sound/cs46xxpm-24.h	Wed Apr 11 19:02:38 2001
+++ linux/drivers/sound/cs46xxpm-24.h	Wed Jun 27 13:15:17 2001
@@ -36,8 +36,8 @@
 * for now (12/22/00) only enable the pm_register PM support.
 * allow these table entries to be null.
 */
-static void cs46xx_suspend_tbl(struct pci_dev *pcidev);
-static void cs46xx_resume_tbl(struct pci_dev *pcidev);
+static int cs46xx_suspend_tbl(struct pci_dev *pcidev, u32 state);
+static int cs46xx_resume_tbl(struct pci_dev *pcidev);
 #define cs_pm_register(a, b, c)  0
 #define cs_pm_unregister_all(a) 
 #define CS46XX_SUSPEND_TBL cs46xx_suspend_tbl
diff -u --recursive --new-file v2.4.5/linux/drivers/sound/gus_wave.c linux/drivers/sound/gus_wave.c
--- v2.4.5/linux/drivers/sound/gus_wave.c	Sun Nov 12 20:35:35 2000
+++ linux/drivers/sound/gus_wave.c	Tue Jun 12 11:06:54 2001
@@ -2102,6 +2102,7 @@
 			break;
 
 		default:
+			break;
 	}
 }
 
@@ -3282,6 +3283,7 @@
 		break;
 
 		default:
+			break;
 	}
 	restore_flags(flags);
 }
@@ -3423,6 +3425,7 @@
 				break;
 
 			default:
+				break;
 	}
 	status = gus_look8(0x49);	/*
 					 * Get Sampling IRQ Status
diff -u --recursive --new-file v2.4.5/linux/drivers/sound/maestro3.c linux/drivers/sound/maestro3.c
--- v2.4.5/linux/drivers/sound/maestro3.c	Sat Apr 21 10:36:30 2001
+++ linux/drivers/sound/maestro3.c	Wed Jun 27 13:15:17 2001
@@ -371,7 +371,7 @@
  * I'm not very good at laying out functions in a file :)
  */
 static int m3_notifier(struct notifier_block *nb, unsigned long event, void *buf);
-static void m3_suspend(struct pci_dev *pci_dev);
+static int m3_suspend(struct pci_dev *pci_dev, u32 state);
 static void check_suspend(struct m3_card *card);
 
 struct notifier_block m3_reboot_nb = {m3_notifier, NULL, 0};
@@ -2771,12 +2771,12 @@
 
     for(card = devs; card != NULL; card = card->next) {
         if(!card->in_suspend)
-            m3_suspend(card->pcidev); /* XXX legal? */
+            m3_suspend(card->pcidev, 3); /* XXX legal? */
     }
     return 0;
 }
 
-static void m3_suspend(struct pci_dev *pci_dev)
+static int m3_suspend(struct pci_dev *pci_dev, u32 state)
 {
     unsigned long flags;
     int i;
@@ -2823,9 +2823,11 @@
     card->in_suspend = 1;
 
     restore_flags(flags);
+
+    return 0;
 }
 
-static void m3_resume(struct pci_dev *pci_dev)
+static int m3_resume(struct pci_dev *pci_dev)
 {
     unsigned long flags;
     int index;
@@ -2904,6 +2906,8 @@
      * when we suspended
      */
     wake_up(&card->suspend_queue);
+
+    return 0;
 }
 
 MODULE_AUTHOR("Zach Brown <zab@zabbo.net>");
diff -u --recursive --new-file v2.4.5/linux/drivers/sound/pss.c linux/drivers/sound/pss.c
--- v2.4.5/linux/drivers/sound/pss.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/sound/pss.c	Tue Jun 12 11:06:54 2001
@@ -766,6 +766,7 @@
 			break;
 
 		default:
+			break;
 	}
 	return 0;
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/sound/sb_card.c linux/drivers/sound/sb_card.c
--- v2.4.5/linux/drivers/sound/sb_card.c	Tue May 22 10:23:16 2001
+++ linux/drivers/sound/sb_card.c	Wed Jun 27 17:10:55 2001
@@ -298,6 +298,11 @@
 		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
 		0,0,0,0,
 		0,1,1,-1},
+	{"Sound Blaster 16", 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00ed), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041),
+		0,0,0,0,
+		0,1,1,-1},
 	{"Sound Blaster Vibra16S", 
 		ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0051), 
 		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001),
@@ -518,6 +523,9 @@
 
 	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002b), 
 		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
+
+	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00ed), 
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), 0 },
 
 	{	ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0051), 
 		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001), 0 },
diff -u --recursive --new-file v2.4.5/linux/drivers/sound/via82cxxx_audio.c linux/drivers/sound/via82cxxx_audio.c
--- v2.4.5/linux/drivers/sound/via82cxxx_audio.c	Tue May  1 16:05:00 2001
+++ linux/drivers/sound/via82cxxx_audio.c	Wed Jun 20 11:16:01 2001
@@ -3012,7 +3012,6 @@
 {
 	int rc;
 	struct via_info *card;
-	u8 tmp;
 	static int printed_version = 0;
 
 	DPRINTK ("ENTER\n");
@@ -3107,19 +3106,6 @@
 	if (rc) {
 		printk (KERN_ERR PFX "interrupt init failed, aborting\n");
 		goto err_out_have_proc;
-	}
-
-	pci_read_config_byte (pdev, 0x3C, &tmp);
-	if ((tmp & 0x0F) != pdev->irq) {
-		printk (KERN_WARNING PFX "IRQ fixup, 0x3C==0x%02X\n", tmp);
-		udelay (15);
-		tmp &= 0xF0;
-		tmp |= pdev->irq;
-		pci_write_config_byte (pdev, 0x3C, tmp);
-		DPRINTK ("new 0x3c==0x%02x\n", tmp);
-	} else {
-		DPRINTK ("IRQ reg 0x3c==0x%02x, irq==%d\n",
-			tmp, tmp & 0x0F);
 	}
 
 	printk (KERN_INFO PFX "board #%d at 0x%04lX, IRQ %d\n",
diff -u --recursive --new-file v2.4.5/linux/drivers/sound/wavfront.c linux/drivers/sound/wavfront.c
--- v2.4.5/linux/drivers/sound/wavfront.c	Thu May 24 15:14:08 2001
+++ linux/drivers/sound/wavfront.c	Wed Jun 27 17:10:55 2001
@@ -2045,19 +2045,17 @@
 
 	switch (cmd) {
 	case SNDCTL_SYNTH_INFO:
-		memcpy (&((char *) arg)[0], &wavefront_info,
-			sizeof (wavefront_info));
+		if(copy_to_user(&((char *) arg)[0], &wavefront_info,
+			sizeof (wavefront_info)))
+			return -EFAULT;
 		return 0;
-		break;
 
 	case SNDCTL_SEQ_RESETSAMPLES:
-		printk (KERN_WARNING LOGNAME "driver cannot reset samples.\n");
+//		printk (KERN_WARNING LOGNAME "driver cannot reset samples.\n");
 		return 0; /* don't force an error */
-		break;
 
 	case SNDCTL_SEQ_PERCMODE:
 		return 0; /* don't force an error */
-		break;
 
 	case SNDCTL_SYNTH_MEMAVL:
 		if ((dev.freemem = wavefront_freemem ()) < 0) {
@@ -2069,10 +2067,11 @@
 		break;
 
 	case SNDCTL_SYNTH_CONTROL:
-		copy_from_user (&wc, arg, sizeof (wc));
-
-		if ((err = wavefront_synth_control (cmd, &wc)) == 0) {
-			copy_to_user (arg, &wc, sizeof (wc));
+		if(copy_from_user (&wc, arg, sizeof (wc)))
+			err = -EFAULT;
+		else if ((err = wavefront_synth_control (cmd, &wc)) == 0) {
+			if(copy_to_user (arg, &wc, sizeof (wc)))
+				err = -EFAULT;
 		}
 
 		return err;
diff -u --recursive --new-file v2.4.5/linux/drivers/sound/wf_midi.c linux/drivers/sound/wf_midi.c
--- v2.4.5/linux/drivers/sound/wf_midi.c	Sun Sep 17 09:45:07 2000
+++ linux/drivers/sound/wf_midi.c	Wed Jun 27 17:10:55 2001
@@ -231,6 +231,7 @@
 				break;
 		    
 			default:
+				break;
 			}
 		} else {
 			mi->m_prev_status = midic;
@@ -590,19 +591,17 @@
 	switch (cmd) {
 
 	case SNDCTL_SYNTH_INFO:
-		copy_to_user (&((char *) arg)[0],
+		if(copy_to_user (&((char *) arg)[0],
 			      &wf_mpu_synth_info[index],
-			      sizeof (struct synth_info));
-	
+			      sizeof (struct synth_info)))
+			return -EFAULT;
 		return 0;
-		break;
 	
 	case SNDCTL_SYNTH_MEMAVL:
 		return 0x7fffffff;
-		break;
 	
 	default:
-		return -(EINVAL);
+		return -EINVAL;
 	}
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/sound/ymfpci.c linux/drivers/sound/ymfpci.c
--- v2.4.5/linux/drivers/sound/ymfpci.c	Sat May 19 17:47:55 2001
+++ linux/drivers/sound/ymfpci.c	Tue Jun 12 11:06:54 2001
@@ -1829,6 +1829,7 @@
 		 * for instance we get SNDCTL_TMR_CONTINUE here.
 		 * XXX Is there sound_generic_ioctl() around?
 		 */
+		 break;
 	}
 	return -ENOTTY;
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/telephony/ixj.c linux/drivers/telephony/ixj.c
--- v2.4.5/linux/drivers/telephony/ixj.c	Sat May 19 17:47:55 2001
+++ linux/drivers/telephony/ixj.c	Wed Jun 27 17:10:55 2001
@@ -4480,9 +4480,15 @@
 	if (lcp == NULL)
 		return -ENOMEM;
 	if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_FILTER_CADENCE)))
+	{
+		kfree(lcp);
 		return -EFAULT;
+	}
 	if (lcp->filter >= 4)
+	{
+		kfree(lcp);
 		return -1;
+	}
 	j->cadence_f[lcp->filter].state = 0;
 	j->cadence_f[lcp->filter].enable = lcp->enable;
 	j->filter_en[lcp->filter] = j->cadence_f[lcp->filter].en_filter = lcp->en_filter;
@@ -4647,13 +4653,18 @@
 	}
 }
 
-static int capabilities_check(IXJ *j, struct phone_capability *pcreq)
+static int capabilities_check(IXJ *j, struct phone_capability *u_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;
 		}
@@ -4704,7 +4715,8 @@
 			return -EFAULT;
 		break;
 	case PHONE_RING_CADENCE:
-		j->ring_cadence = arg;
+		if(get_user(j->ring_cadence, (int *)arg))
+			return -EFAULT;
 		break;
 	case IXJCTL_CIDCW:
 		if(arg) {
@@ -6261,20 +6273,12 @@
 	return (((DWORD) wHi << 16) | wLo);
 }
 
-#ifndef CONFIG_PCMCIA
 #ifndef CONFIG_ISAPNP
-static int dspio[IXJMAX + 1] =
-{
-	0,
-};
-static int xio[IXJMAX + 1] =
-{
-	0,
-};
+static int dspio[IXJMAX + 1];
+static int xio[IXJMAX + 1];
 
 MODULE_PARM(dspio, "1-" __MODULE_STRING(IXJMAX) "i");
 MODULE_PARM(xio, "1-" __MODULE_STRING(IXJMAX) "i");
-#endif
 #endif
 
 void ixj_exit(void)
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/Config.in linux/drivers/usb/Config.in
--- v2.4.5/linux/drivers/usb/Config.in	Tue May 22 10:25:36 2001
+++ linux/drivers/usb/Config.in	Wed Jun 27 13:59:32 2001
@@ -53,18 +53,20 @@
    dep_tristate '  USB Kodak DC-2xx Camera support' CONFIG_USB_DC2XX $CONFIG_USB
    dep_tristate '  USB Mustek MDC800 Digital Camera support (EXPERIMENTAL)' CONFIG_USB_MDC800 $CONFIG_USB $CONFIG_EXPERIMENTAL
    dep_tristate '  USB Scanner support' CONFIG_USB_SCANNER $CONFIG_USB
-   dep_tristate '  Microtek X6USB scanner support (EXPERIMENTAL)' CONFIG_USB_MICROTEK $CONFIG_USB $CONFIG_SCSI $CONFIG_EXPERIMENTAL
+   dep_tristate '  Microtek X6USB scanner support' CONFIG_USB_MICROTEK $CONFIG_USB $CONFIG_SCSI
 
    comment 'USB Multimedia devices'
    dep_tristate '  USB IBM (Xirlink) C-it Camera support' CONFIG_USB_IBMCAM $CONFIG_USB $CONFIG_VIDEO_DEV
    dep_tristate '  USB OV511 Camera support' CONFIG_USB_OV511 $CONFIG_USB $CONFIG_VIDEO_DEV
    dep_tristate '  USB Philips Cameras' CONFIG_USB_PWC $CONFIG_USB $CONFIG_VIDEO_DEV
+   dep_tristate '  USB SE401 Camera support' CONFIG_USB_SE401 $CONFIG_USB $CONFIG_VIDEO_DEV
    dep_tristate '  D-Link USB FM radio support (EXPERIMENTAL)' CONFIG_USB_DSBR $CONFIG_USB $CONFIG_VIDEO_DEV $CONFIG_EXPERIMENTAL
    dep_tristate '  DABUSB driver' CONFIG_USB_DABUSB $CONFIG_USB
 
    comment 'USB Network adaptors'
    dep_tristate '  PLUSB Prolific USB-Network driver (EXPERIMENTAL)' CONFIG_USB_PLUSB $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
    dep_tristate '  USB ADMtek Pegasus-based ethernet device support (EXPERIMENTAL)' CONFIG_USB_PEGASUS $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
+   dep_tristate '  USB CATC NetMate-based Ethernet driver (EXPERIMENTAL)' CONFIG_USB_CATC $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
    dep_tristate '  NetChip 1080-based USB Host-to-Host Link (EXPERIMENTAL)' CONFIG_USB_NET1080 $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
 
    comment 'USB port drivers'
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/Makefile linux/drivers/usb/Makefile
--- v2.4.5/linux/drivers/usb/Makefile	Fri May 25 09:48:50 2001
+++ linux/drivers/usb/Makefile	Wed Jun 27 13:59:32 2001
@@ -62,7 +62,9 @@
 obj-$(CONFIG_USB_DABUSB)	+= dabusb.o
 obj-$(CONFIG_USB_PLUSB)		+= plusb.o
 obj-$(CONFIG_USB_OV511)		+= ov511.o
+obj-$(CONFIG_USB_SE401)		+= se401.o
 obj-$(CONFIG_USB_PEGASUS)	+= pegasus.o
+obj-$(CONFIG_USB_CATC)		+= catc.o
 obj-$(CONFIG_USB_RIO500)	+= rio500.o
 obj-$(CONFIG_USB_DSBR)		+= dsbr100.o
 obj-$(CONFIG_USB_MICROTEK)	+= microtek.o
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/acm.c linux/drivers/usb/acm.c
--- v2.4.5/linux/drivers/usb/acm.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/acm.c	Tue Jun 12 15:53:37 2001
@@ -709,8 +709,7 @@
 		return -1;
 	}
 
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 
 	return 0;
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/audio.c linux/drivers/usb/audio.c
--- v2.4.5/linux/drivers/usb/audio.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/audio.c	Tue Jun 12 15:53:37 2001
@@ -3755,8 +3755,7 @@
 static int __init usb_audio_init(void)
 {
 	usb_register(&usb_audio_driver);
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/bluetooth.c linux/drivers/usb/bluetooth.c
--- v2.4.5/linux/drivers/usb/bluetooth.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/bluetooth.c	Wed Jun 20 16:52:30 2001
@@ -1,11 +1,28 @@
 /*
- * bluetooth.c   Version 0.8
+ * bluetooth.c   Version 0.11
  *
- * Copyright (c) 2000 Greg Kroah-Hartman	<greg@kroah.com>
+ * Copyright (c) 2000, 2001 Greg Kroah-Hartman	<greg@kroah.com>
  * Copyright (c) 2000 Mark Douglas Corner	<mcorner@umich.edu>
  *
  * USB Bluetooth driver, based on the Bluetooth Spec version 1.0B
  * 
+ * (2001/06/05) Version 0.11 gkh
+ *	- Fixed problem with read urb status saying that we have shutdown,
+ *	  and that we shouldn't resubmit the urb.  Patch from unknown.
+ *
+ * (2001/05/28) Version 0.10 gkh
+ *	- Fixed problem with using data from userspace in the bluetooth_write
+ *	  function as found by the CHECKER project.
+ *	- Added a buffer to the write_urb_pool which reduces the number of
+ *	  buffers being created and destroyed for ever write.  Also cleans
+ *	  up the logic a bit.
+ *	- Added a buffer to the control_urb_pool which fixes a memory leak
+ *	  when the device is removed from the system.
+ *
+ * (2001/05/28) Version 0.9 gkh
+ *	Fixed problem with bluetooth==NULL for bluetooth_read_bulk_callback
+ *	which was found by both the CHECKER project and Mikko Rahkonen.
+ *
  * (08/04/2001) gb
  *	Identify version on module load.
  *
@@ -97,7 +114,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.8"
+#define DRIVER_VERSION "v0.11"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman, Mark Douglas Corner"
 #define DRIVER_DESC "USB Bluetooth driver"
 
@@ -260,7 +277,7 @@
 }
 
 
-static int bluetooth_ctrl_msg (struct usb_bluetooth *bluetooth, int request, int value, void *buf, int len)
+static int bluetooth_ctrl_msg (struct usb_bluetooth *bluetooth, int request, int value, const unsigned char *buf, int len)
 {
 	struct urb *urb = NULL;
 	devrequest *dr = NULL;
@@ -282,11 +299,23 @@
 		return -ENOMEM;
 	}
 
-	/* free up the last buffer that this urb used */
-	if (urb->transfer_buffer != NULL) {
-		kfree(urb->transfer_buffer);
-		urb->transfer_buffer = NULL;
+	/* keep increasing the urb transfer buffer to fit the size of the message */
+	if (urb->transfer_buffer == NULL) {
+		urb->transfer_buffer = kmalloc (len, GFP_KERNEL);
+		if (urb->transfer_buffer == NULL) {
+			err (__FUNCTION__" - out of memory");
+			return -ENOMEM;
+		}
 	}
+	if (urb->transfer_buffer_length < len) {
+		kfree (urb->transfer_buffer);
+		urb->transfer_buffer = kmalloc (len, GFP_KERNEL);
+		if (urb->transfer_buffer == NULL) {
+			err (__FUNCTION__" - out of memory");
+			return -ENOMEM;
+		}
+	}
+	memcpy (urb->transfer_buffer, buf, len);
 
 	dr->requesttype = BLUETOOTH_CONTROL_REQUEST_TYPE;
 	dr->request = request;
@@ -295,14 +324,14 @@
 	dr->length = cpu_to_le16p(&len);
 	
 	FILL_CONTROL_URB (urb, bluetooth->dev, usb_sndctrlpipe(bluetooth->dev, 0),
-			  (unsigned char*)dr, buf, len, bluetooth_ctrl_callback, bluetooth);
+			  (unsigned char*)dr, urb->transfer_buffer, len, bluetooth_ctrl_callback, bluetooth);
 
 	/* send it down the pipe */
 	status = usb_submit_urb(urb);
 	if (status)
 		dbg(__FUNCTION__ " - usb_submit_urb(control) failed with status = %d", status);
 	
-	return 0;
+	return status;
 }
 
 
@@ -401,12 +430,13 @@
 {
 	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
 	struct urb *urb = NULL;
-	unsigned char *new_buffer;
+	unsigned char *temp_buffer = NULL;
+	const unsigned char *current_buffer;
 	const unsigned char *current_position;
-	int status;
 	int bytes_sent;
 	int buffer_size;
 	int i;
+	int retval = 0;
 
 	if (!bluetooth) {
 		return -ENODEV;
@@ -436,38 +466,39 @@
 	printk ("\n");
 #endif
 
-	switch (*buf) {
+	if (from_user) {
+		temp_buffer = kmalloc (count, GFP_KERNEL);
+		if (temp_buffer == NULL) {
+			err (__FUNCTION__ "- out of memory.");
+			retval = -ENOMEM;
+			goto exit;
+		}
+		copy_from_user (temp_buffer, buf, count);
+		current_buffer = temp_buffer;
+	} else {
+		current_buffer = buf;
+	}
+
+	switch (*current_buffer) {
 		/* First byte indicates the type of packet */
 		case CMD_PKT:
 			/* dbg(__FUNCTION__ "- Send cmd_pkt len:%d", count);*/
 
 			if (in_interrupt()){
 				printk("cmd_pkt from interrupt!\n");
-				return count;
+				retval = count;
+				goto exit;
 			}
 
-			new_buffer = kmalloc (count-1, GFP_KERNEL);
-
-			if (!new_buffer) {
-				err (__FUNCTION__ "- out of memory.");
-				return -ENOMEM;
-			}
-
-			if (from_user)
-				copy_from_user (new_buffer, buf+1, count-1);
-			else
-				memcpy (new_buffer, buf+1, count-1);
-
-			if (bluetooth_ctrl_msg (bluetooth, 0x00, 0x00, new_buffer, count-1) != 0) {
-				kfree (new_buffer);
-				return 0;
+			retval = bluetooth_ctrl_msg (bluetooth, 0x00, 0x00, &current_buffer[1], count-1);
+			if (retval) {
+				goto exit;
 			}
-
-			/* need to free new_buffer somehow... FIXME */
-			return count;
+			retval = count;
+			break;
 
 		case ACL_PKT:
-			current_position = buf;
+			current_position = current_buffer;
 			++current_position;
 			--count;
 			bytes_sent = 0;
@@ -484,37 +515,25 @@
 				}
 				if (urb == NULL) {
 					dbg (__FUNCTION__ " - no free urbs");
-					return bytes_sent;
+					retval = bytes_sent;
+					goto exit;
 				}
 				
-				/* free up the last buffer that this urb used */
-				if (urb->transfer_buffer != NULL) {
-					kfree(urb->transfer_buffer);
-					urb->transfer_buffer = NULL;
-				}
 
 				buffer_size = MIN (count, bluetooth->bulk_out_buffer_size);
-				
-				new_buffer = kmalloc (buffer_size, GFP_KERNEL);
-				if (new_buffer == NULL) {
-					err(__FUNCTION__" no more kernel memory...");
-					return bytes_sent;
-				}
-
-				if (from_user)
-					copy_from_user(new_buffer, current_position, buffer_size);
-				else
-					memcpy (new_buffer, current_position, buffer_size);
+				memcpy (urb->transfer_buffer, current_position, buffer_size);
 
 				/* build up our urb */
 				FILL_BULK_URB (urb, bluetooth->dev, usb_sndbulkpipe(bluetooth->dev, bluetooth->bulk_out_endpointAddress),
-						new_buffer, buffer_size, bluetooth_write_bulk_callback, bluetooth);
+						urb->transfer_buffer, buffer_size, bluetooth_write_bulk_callback, bluetooth);
 				urb->transfer_flags |= USB_QUEUE_BULK;
 
 				/* send it down the pipe */
-				status = usb_submit_urb(urb);
-				if (status)
-					dbg(__FUNCTION__ " - usb_submit_urb(write bulk) failed with status = %d", status);
+				retval = usb_submit_urb(urb);
+				if (retval) {
+					dbg(__FUNCTION__ " - usb_submit_urb(write bulk) failed with error = %d", retval);
+					goto exit;
+				}
 #ifdef BTBUGGYHARDWARE
 				/* A workaround for the stalled data bug */
 				/* May or may not be needed...*/
@@ -527,13 +546,20 @@
 				count -= buffer_size;
 			}
 
-			return bytes_sent + 1;
+			retval = bytes_sent + 1;
+			break;
 		
 		default :
 			dbg(__FUNCTION__" - unsupported (at this time) write type");
+			retval = -EINVAL;
+			break;
 	}
 
-	return 0;
+exit:
+	if (temp_buffer != NULL)
+		kfree (temp_buffer);
+
+	return retval;
 } 
 
 
@@ -845,21 +871,6 @@
 	unsigned int packet_size;
 	int result;
 
-#ifdef BTBUGGYHARDWARE
-	if ((count == 4) && (data[0] == 0x00) && (data[1] == 0x00)
-	    && (data[2] == 0x00) && (data[3] == 0x00)) {
-		urb->actual_length = 0;
-		FILL_BULK_URB(bluetooth->read_urb, bluetooth->dev, 
-			      usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),
-			      bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, 
-			      bluetooth_read_bulk_callback, bluetooth);
-		result = usb_submit_urb(bluetooth->read_urb);
-		if (result)
-			err (__FUNCTION__ " - failed resubmitting read urb, error %d", result);
-
-		return;
-	}
-#endif
 
 	dbg(__FUNCTION__);
 
@@ -870,6 +881,10 @@
 
 	if (urb->status) {
 		dbg(__FUNCTION__ " - nonzero read bulk status received: %d", urb->status);
+		if (urb->status == -ENOENT) {                   
+			dbg(__FUNCTION__ " - URB canceled, won't reschedule");
+			return;
+		}
 		goto exit;
 	}
 
@@ -887,6 +902,21 @@
 		printk ("\n");
 	}
 #endif
+#ifdef BTBUGGYHARDWARE
+	if ((count == 4) && (data[0] == 0x00) && (data[1] == 0x00)
+	    && (data[2] == 0x00) && (data[3] == 0x00)) {
+		urb->actual_length = 0;
+		FILL_BULK_URB(bluetooth->read_urb, bluetooth->dev, 
+			      usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),
+			      bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, 
+			      bluetooth_read_bulk_callback, bluetooth);
+		result = usb_submit_urb(bluetooth->read_urb);
+		if (result)
+			err (__FUNCTION__ " - failed resubmitting read urb, error %d", result);
+
+		return;
+	}
+#endif
 	/* We add  a packet type identifier to the beginning of each
 	   HCI frame.  This makes the data in the tty look like a
 	   serial USB devices.  Each HCI frame can be broken across
@@ -934,6 +964,9 @@
 	}	
 
 exit:
+	if (!bluetooth || !bluetooth->active)
+		return;
+
 	FILL_BULK_URB(bluetooth->read_urb, bluetooth->dev, 
 		      usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),
 		      bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, 
@@ -1114,7 +1147,11 @@
 			err("No free urbs available");
 			goto probe_error;
 		}
-		urb->transfer_buffer = NULL;
+		urb->transfer_buffer = kmalloc (bluetooth->bulk_out_buffer_size, GFP_KERNEL);
+		if (urb->transfer_buffer == NULL) {
+			err("out of memory");
+			goto probe_error;
+		}
 		bluetooth->write_urb_pool[i] = urb;
 	}
 	
@@ -1156,11 +1193,17 @@
 	if (bluetooth->interrupt_in_buffer)
 		kfree (bluetooth->interrupt_in_buffer);
 	for (i = 0; i < NUM_BULK_URBS; ++i)
-		if (bluetooth->write_urb_pool[i])
+		if (bluetooth->write_urb_pool[i]) {
+			if (bluetooth->write_urb_pool[i]->transfer_buffer)
+				kfree (bluetooth->write_urb_pool[i]->transfer_buffer);
 			usb_free_urb (bluetooth->write_urb_pool[i]);
+		}
 	for (i = 0; i < NUM_CONTROL_URBS; ++i) 
-		if (bluetooth->control_urb_pool[i])
+		if (bluetooth->control_urb_pool[i]) {
+			if (bluetooth->control_urb_pool[i]->transfer_buffer)
+				kfree (bluetooth->control_urb_pool[i]->transfer_buffer);
 			usb_free_urb (bluetooth->control_urb_pool[i]);
+		}
 
 	bluetooth_table[minor] = NULL;
 
@@ -1286,8 +1329,7 @@
 		return -1;
 	}
 
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 
 	return 0;
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/catc.c linux/drivers/usb/catc.c
--- v2.4.5/linux/drivers/usb/catc.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/catc.c	Wed Jun 20 17:51:24 2001
@@ -0,0 +1,758 @@
+/*
+ *  Copyright (c) 2001 Vojtech Pavlik
+ *
+ *  CATC EL1210A NetMate USB Ethernet driver
+ *
+ *  Sponsored by SuSE
+ *
+ *  Based on the work of
+ *		Donald Becker
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or 
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * 
+ * Should you need to contact me, the author, you can do so either by
+ * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/malloc.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <asm/bitops.h>
+
+#undef DEBUG
+
+#include <linux/usb.h>
+
+/*
+ * Version information.
+ */
+
+#define DRIVER_VERSION "v2.7"
+#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@suse.cz>"
+#define DRIVER_DESC "CATC EL1210A NetMate USB Ethernet driver"
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+
+/*
+ * Some defines.
+ */ 
+
+#define STATS_UPDATE		(HZ)	/* Time between stats updates */
+#define TX_TIMEOUT		(5*HZ)	/* Max time the queue can be stopped */
+#define PKT_SZ			1536	/* Max Ethernet packet size */
+#define RX_MAX_BURST		15	/* Max packets per rx buffer (> 0, < 16) */
+#define TX_MAX_BURST		15	/* Max full sized packets per tx buffer (> 0) */
+#define CTRL_QUEUE		16	/* Max control requests in flight (power of two) */
+
+/*
+ * Control requests.
+ */
+
+enum control_requests {
+	ReadMem =	0xf1,
+	GetMac =	0xf2,
+	Reset =		0xf4,
+	SetMac =	0xf5,
+	WriteROM =	0xf8,
+	SetReg =	0xfa,
+	GetReg =	0xfb,
+	WriteMem =	0xfc,
+	ReadROM =	0xfd,
+};
+
+/*
+ * Registers.
+ */
+
+enum register_offsets {
+	TxBufCount =	0x20,
+	RxBufCount =	0x21,
+	OpModes =	0x22,
+	TxQed =		0x23,
+	RxQed =		0x24,
+	MaxBurst =	0x25,
+	RxUnit =	0x60,
+	EthStatus =	0x61,
+	StationAddr0 =	0x67,
+	EthStats =	0x69,
+	LEDCtrl =	0x81,
+};
+
+enum eth_stats {
+	TxSingleColl =	0x00,
+        TxMultiColl =	0x02,
+        TxExcessColl =	0x04,
+        RxFramErr =	0x06,
+};
+
+enum op_mode_bits {
+	Op3MemWaits =	0x03,
+	OpLenInclude =	0x08,
+	OpRxMerge =	0x10,
+	OpTxMerge =	0x20,
+	OpWin95bugfix =	0x40,
+	OpLoopback =	0x80,
+};
+
+enum rx_filter_bits {
+	RxEnable =	0x01,
+	RxPolarity =	0x02,
+	RxForceOK =	0x04,
+	RxMultiCast =	0x08,
+	RxPromisc =	0x10,
+};
+
+enum led_values {
+	LEDFast = 	0x01,
+	LEDSlow =	0x02,
+	LEDFlash =	0x03,
+	LEDPulse =	0x04,
+	LEDLink =	0x08,
+};
+
+/*
+ * The catc struct.
+ */
+
+#define CTRL_RUNNING	0
+#define RX_RUNNING	1
+#define TX_RUNNING	2
+
+struct catc {
+	struct net_device *netdev;
+	struct usb_device *usbdev;
+
+	struct net_device_stats stats;
+	unsigned long flags;
+
+	unsigned int tx_ptr, tx_idx;
+	unsigned int ctrl_head, ctrl_tail;
+	spinlock_t tx_lock, ctrl_lock;
+
+	u8 tx_buf[2][TX_MAX_BURST * (PKT_SZ + 2)];
+	u8 rx_buf[RX_MAX_BURST * (PKT_SZ + 2)];
+	u8 irq_buf[2];
+	u8 ctrl_buf[64];
+	devrequest ctrl_dr;
+
+	struct timer_list timer;
+	u8 stats_buf[8];
+	u16 stats_vals[4];
+	unsigned long last_stats;
+
+	u8 multicast[64];
+
+	struct ctrl_queue {
+		u8 dir;
+		u8 request;
+		u16 value;
+		u16 index;
+		void *buf;
+		int len;
+		void (*callback)(struct catc *catc, struct ctrl_queue *q);
+	} ctrl_queue[CTRL_QUEUE];
+
+	struct urb tx_urb, rx_urb, irq_urb, ctrl_urb;
+};
+
+/*
+ * Useful macros.
+ */
+
+#define catc_get_mac(catc, mac)				catc_ctrl_msg(catc, USB_DIR_IN,  GetMac, 0, 0, mac,  6)
+#define catc_reset(catc)				catc_ctrl_msg(catc, USB_DIR_OUT, Reset, 0, 0, NULL, 0)
+#define catc_set_reg(catc, reg, val)			catc_ctrl_msg(catc, USB_DIR_OUT, SetReg, val, reg, NULL, 0)
+#define catc_get_reg(catc, reg, buf)			catc_ctrl_msg(catc, USB_DIR_IN,  GetReg, 0, reg, buf, 1)
+#define catc_write_mem(catc, addr, buf, size)		catc_ctrl_msg(catc, USB_DIR_OUT, WriteMem, 0, addr, buf, size)
+#define catc_read_mem(catc, addr, buf, size)		catc_ctrl_msg(catc, USB_DIR_IN,  ReadMem, 0, addr, buf, size)
+
+#define catc_set_reg_async(catc, reg, val)		catc_ctrl_async(catc, USB_DIR_OUT, SetReg, val, reg, NULL, 0, NULL)
+#define catc_get_reg_async(catc, reg, cb)		catc_ctrl_async(catc, USB_DIR_IN, GetReg, 0, reg, NULL, 1, cb)
+#define catc_write_mem_async(catc, addr, buf, size)	catc_ctrl_async(catc, USB_DIR_OUT, WriteMem, 0, addr, buf, size, NULL)
+
+/*
+ * Receive routines.
+ */
+
+static void catc_rx_done(struct urb *urb)
+{
+	struct catc *catc = urb->context;
+	u8 *pkt_start = urb->transfer_buffer;
+	struct sk_buff *skb;
+	int pkt_len;
+
+	clear_bit(RX_RUNNING, &catc->flags);
+
+	if (urb->status) {
+		dbg("rx_done, status %d, length %d", urb->status, urb->actual_length);
+		return;
+	}
+
+	do {
+		pkt_len = le16_to_cpup((u16*)pkt_start);
+
+		if (pkt_len > urb->actual_length) {
+			catc->stats.rx_length_errors++;
+			catc->stats.rx_errors++;
+			break;
+		}
+
+		if (!(skb = dev_alloc_skb(pkt_len)))
+			return;
+
+		skb->dev = catc->netdev;
+		eth_copy_and_sum(skb, pkt_start + 2, pkt_len, 0);
+		skb_put(skb, pkt_len);
+
+		skb->protocol = eth_type_trans(skb, catc->netdev);
+		netif_rx(skb);
+
+		catc->stats.rx_packets++;
+		catc->stats.rx_bytes += pkt_len;
+
+		pkt_start += (((pkt_len + 1) >> 6) + 1) << 6;
+
+	} while (pkt_start - (u8 *) urb->transfer_buffer < urb->actual_length);
+
+	catc->netdev->last_rx = jiffies;
+}
+
+static void catc_irq_done(struct urb *urb)
+{
+	struct catc *catc = urb->context;
+	u8 *data = urb->transfer_buffer;
+	int status;
+
+	if (urb->status) {
+		dbg("irq_done, status %d, data %02x %02x.", urb->status, data[0], data[1]);
+		return;
+	}
+
+	if ((data[1] & 0x80) && !test_and_set_bit(RX_RUNNING, &catc->flags)) {
+		catc->rx_urb.dev = catc->usbdev;
+		if ((status = usb_submit_urb(&catc->rx_urb)) < 0) {
+			err("submit(rx_urb) status %d", status);
+			return;
+		} 
+	}
+
+	if (data[1] & 0x40)
+		dbg("link ok");
+
+	if (data[1] & 0x20) 
+		dbg("link bad");
+}
+
+/*
+ * Transmit routines.
+ */
+
+static void catc_tx_run(struct catc *catc)
+{
+	int status;
+
+	catc->tx_urb.transfer_buffer_length = catc->tx_ptr;
+	catc->tx_urb.transfer_buffer = catc->tx_buf[catc->tx_idx];
+	catc->tx_urb.dev = catc->usbdev;
+
+	if ((status = usb_submit_urb(&catc->tx_urb)) < 0)
+		err("submit(tx_urb), status %d", status);
+
+	catc->tx_idx = !catc->tx_idx;
+	catc->tx_ptr = 0;
+
+	catc->netdev->trans_start = jiffies;
+}
+
+static void catc_tx_done(struct urb *urb)
+{
+	struct catc *catc = urb->context;
+	unsigned long flags;
+
+	if (urb->status == -ECONNRESET) {
+		dbg("Tx Reset.");
+		urb->transfer_flags &= ~USB_ASYNC_UNLINK;
+		urb->status = 0;
+		catc->netdev->trans_start = jiffies;
+		catc->stats.tx_errors++;
+		clear_bit(TX_RUNNING, &catc->flags);
+		netif_wake_queue(catc->netdev);
+		return;
+	}
+
+	if (urb->status) {
+		dbg("tx_done, status %d, length %d", urb->status, urb->actual_length);
+		return;
+	}
+
+	spin_lock_irqsave(&catc->tx_lock, flags);
+
+	if (catc->tx_ptr)
+		catc_tx_run(catc);
+	else
+		clear_bit(TX_RUNNING, &catc->flags);
+
+	netif_wake_queue(catc->netdev);
+
+	spin_unlock_irqrestore(&catc->tx_lock, flags);
+}
+
+static int catc_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+	struct catc *catc = netdev->priv;
+	unsigned long flags;
+	char *tx_buf;
+
+	spin_lock_irqsave(&catc->tx_lock, flags);
+
+	catc->tx_ptr = (((catc->tx_ptr - 1) >> 6) + 1) << 6;
+	tx_buf = catc->tx_buf[catc->tx_idx] + catc->tx_ptr;
+	*((u16*)tx_buf) = cpu_to_le16p(&skb->len);
+	memcpy(tx_buf + 2, skb->data, skb->len);
+	catc->tx_ptr += skb->len + 2;
+
+	if (!test_and_set_bit(TX_RUNNING, &catc->flags))
+		catc_tx_run(catc);
+
+	if (catc->tx_ptr >= ((TX_MAX_BURST - 1) * (PKT_SZ + 2)))
+		netif_stop_queue(netdev);
+
+	spin_unlock_irqrestore(&catc->tx_lock, flags);
+
+	catc->stats.tx_bytes += skb->len;
+	catc->stats.tx_packets++;
+
+	dev_kfree_skb(skb);
+
+	return 0;
+}
+
+static void catc_tx_timeout(struct net_device *netdev)
+{
+	struct catc *catc = netdev->priv;
+
+	warn("Transmit timed out.");
+	catc->tx_urb.transfer_flags |= USB_ASYNC_UNLINK;
+	usb_unlink_urb(&catc->tx_urb);
+}
+
+/*
+ * Control messages.
+ */
+
+static int catc_ctrl_msg(struct catc *catc, u8 dir, u8 request, u16 value, u16 index, void *buf, int len)
+{
+        int retval = usb_control_msg(catc->usbdev,
+		dir ? usb_rcvctrlpipe(catc->usbdev, 0) : usb_sndctrlpipe(catc->usbdev, 0),
+		 request, 0x40 | dir, value, index, buf, len, HZ);
+        return retval < 0 ? retval : 0;
+}
+
+static void catc_ctrl_run(struct catc *catc)
+{
+	struct ctrl_queue *q = catc->ctrl_queue + catc->ctrl_tail;
+	struct usb_device *usbdev = catc->usbdev;
+	struct urb *urb = &catc->ctrl_urb;
+	devrequest *dr = &catc->ctrl_dr;
+	int status;
+
+	dr->request = q->request;
+	dr->requesttype = 0x40 | q->dir;
+	dr->value = cpu_to_le16(q->value);
+	dr->index = cpu_to_le16(q->index);
+	dr->length = cpu_to_le16(q->len);
+
+        urb->pipe = q->dir ? usb_rcvctrlpipe(usbdev, 0) : usb_sndctrlpipe(usbdev, 0);
+	urb->transfer_buffer_length = q->len;
+	urb->transfer_buffer = catc->ctrl_buf;
+	urb->setup_packet = (void *) dr;
+	urb->dev = usbdev;
+
+	if (!q->dir && q->buf && q->len)
+		memcpy(catc->ctrl_buf, q->buf, q->len);
+
+	if ((status = usb_submit_urb(&catc->ctrl_urb)))
+		err("submit(ctrl_urb) status %d", status);
+}
+
+static void catc_ctrl_done(struct urb *urb)
+{
+	struct catc *catc = urb->context;
+	struct ctrl_queue *q;
+	long flags;
+
+	if (urb->status)
+		dbg("ctrl_done, status %d, len %d.", urb->status, urb->actual_length);
+
+	spin_lock_irqsave(&catc->ctrl_lock, flags);
+
+	q = catc->ctrl_queue + catc->ctrl_tail;
+
+	if (q->dir) {
+		if (q->buf && q->len)
+			memcpy(q->buf, catc->ctrl_buf, q->len);
+		else
+			q->buf = catc->ctrl_buf;
+	}
+
+	if (q->callback)
+		q->callback(catc, q);
+
+	catc->ctrl_tail = (catc->ctrl_tail + 1) & (CTRL_QUEUE - 1);
+
+	if (catc->ctrl_head != catc->ctrl_tail)
+		catc_ctrl_run(catc);
+	else
+		clear_bit(CTRL_RUNNING, &catc->flags);
+
+	spin_unlock_irqrestore(&catc->ctrl_lock, flags);
+}
+
+static int catc_ctrl_async(struct catc *catc, u8 dir, u8 request, u16 value,
+	u16 index, void *buf, int len, void (*callback)(struct catc *catc, struct ctrl_queue *q))
+{
+	struct ctrl_queue *q;
+	int retval = 0;
+	long flags;
+
+	spin_lock_irqsave(&catc->ctrl_lock, flags);
+	
+	q = catc->ctrl_queue + catc->ctrl_head;
+
+	q->dir = dir;
+	q->request = request;
+	q->value = value;
+	q->index = index;
+	q->buf = buf;
+	q->len = len;
+	q->callback = callback;
+
+	catc->ctrl_head = (catc->ctrl_head + 1) & (CTRL_QUEUE - 1);
+
+	if (catc->ctrl_head == catc->ctrl_tail) {
+		err("ctrl queue full");
+		catc->ctrl_tail = (catc->ctrl_tail + 1) & (CTRL_QUEUE - 1);
+		retval = -1;
+	}
+
+	if (!test_and_set_bit(CTRL_RUNNING, &catc->flags))
+		catc_ctrl_run(catc);
+
+	spin_unlock_irqrestore(&catc->ctrl_lock, flags);
+
+	return retval;
+}
+
+/*
+ * Statistics.
+ */
+
+static void catc_stats_done(struct catc *catc, struct ctrl_queue *q)
+{
+	int index = q->index - EthStats;
+	u16 data, last;
+
+	catc->stats_buf[index] = *((char *)q->buf);
+
+	if (index & 1)
+		return;
+
+	data = ((u16)catc->stats_buf[index] << 8) | catc->stats_buf[index + 1];
+	last = catc->stats_vals[index >> 1];
+
+	switch (index) {
+		case TxSingleColl:
+		case TxMultiColl:
+			catc->stats.collisions += data - last;
+			break;
+		case TxExcessColl:
+			catc->stats.tx_aborted_errors += data - last;
+			catc->stats.tx_errors += data - last;
+			break;
+		case RxFramErr:
+			catc->stats.rx_frame_errors += data - last;
+			catc->stats.rx_errors += data - last;
+			break;
+	}
+
+	catc->stats_vals[index >> 1] = data;
+}
+
+static void catc_stats_timer(unsigned long data)
+{
+	struct catc *catc = (void *) data;
+	int i;
+
+	for (i = 0; i < 8; i++)
+		catc_get_reg_async(catc, EthStats + 7 - i, catc_stats_done);
+
+	mod_timer(&catc->timer, jiffies + STATS_UPDATE);
+}
+
+static struct net_device_stats *catc_get_stats(struct net_device *netdev)
+{
+	struct catc *catc = netdev->priv;
+	return &catc->stats;
+}
+
+/*
+ * Receive modes. Broadcast, Multicast, Promisc.
+ */
+
+static void catc_multicast(unsigned char *addr, u8 *multicast)
+{
+	unsigned int crc = 0xffffffff;
+	u8 byte, idx, bit;
+
+        for (idx = 0; idx < 6; idx++)
+                for (byte = *addr++, bit = 0; bit < 8; bit++, byte >>= 1)
+                        crc = (crc >> 1) ^ (((crc ^ byte) & 1) ? 0xedb88320U : 0);
+
+	multicast[(crc >> 3) & 0x3f] |= 1 << (crc & 7);
+}
+
+static void catc_set_multicast_list(struct net_device *netdev)
+{
+	struct catc *catc = netdev->priv;
+	struct dev_mc_list *mc;
+	u8 broadcast[6];
+	u8 rx = RxEnable | RxPolarity | RxMultiCast;
+	int i;
+
+	memset(broadcast, 0xff, 6);
+	memset(catc->multicast, 0, 64);
+
+	catc_multicast(broadcast, catc->multicast);
+	catc_multicast(netdev->dev_addr, catc->multicast);
+
+	if (netdev->flags & IFF_PROMISC) {
+		memset(catc->multicast, 0xff, 64);
+		rx |= RxPromisc;
+	} 
+
+	if (netdev->flags & IFF_ALLMULTI)
+		memset(catc->multicast, 0xff, 64);
+
+	for (i = 0, mc = netdev->mc_list; mc && i < netdev->mc_count; i++, mc = mc->next)
+		catc_multicast(mc->dmi_addr, catc->multicast);
+
+	catc_set_reg_async(catc, RxUnit, rx);
+	catc_write_mem_async(catc, 0xfa80, catc->multicast, 64);
+}
+
+/*
+ * Open, close.
+ */
+
+static int catc_open(struct net_device *netdev)
+{
+	struct catc *catc = netdev->priv;
+	int status;
+
+	catc->irq_urb.dev = catc->usbdev;
+	if ((status = usb_submit_urb(&catc->irq_urb)) < 0) {
+		err("submit(irq_urb) status %d", status);
+		return -1;
+	}
+
+	netif_start_queue(netdev);
+
+	mod_timer(&catc->timer, jiffies + STATS_UPDATE);
+
+	return 0;
+}
+
+static int catc_stop(struct net_device *netdev)
+{
+	struct catc *catc = netdev->priv;
+
+	netif_stop_queue(netdev);
+
+	del_timer_sync(&catc->timer);
+
+	usb_unlink_urb(&catc->rx_urb);
+	usb_unlink_urb(&catc->tx_urb);
+	usb_unlink_urb(&catc->irq_urb);
+	usb_unlink_urb(&catc->ctrl_urb);
+
+	return 0;
+}
+
+/*
+ * USB probe, disconnect.
+ */
+
+static void *catc_probe(struct usb_device *usbdev, unsigned int ifnum, const struct usb_device_id *id)
+{
+	struct net_device *netdev;
+	struct catc *catc;
+	u8 broadcast[6];
+	int i;
+
+	if (usb_set_interface(usbdev, ifnum, 1)) {
+                err("Can't set altsetting 1.");
+		return NULL;
+	}
+
+	catc = kmalloc(sizeof(struct catc), GFP_KERNEL);
+	memset(catc, 0, sizeof(struct catc));
+
+	netdev = init_etherdev(0, 0);
+
+	netdev->open = catc_open;
+	netdev->hard_start_xmit = catc_hard_start_xmit;
+	netdev->stop = catc_stop;
+	netdev->get_stats = catc_get_stats;
+	netdev->tx_timeout = catc_tx_timeout;
+	netdev->watchdog_timeo = TX_TIMEOUT;
+	netdev->set_multicast_list = catc_set_multicast_list;
+	netdev->priv = catc;
+
+	catc->usbdev = usbdev;
+	catc->netdev = netdev;
+
+	catc->tx_lock = SPIN_LOCK_UNLOCKED;
+	catc->ctrl_lock = SPIN_LOCK_UNLOCKED;
+
+	init_timer(&catc->timer);
+	catc->timer.data = (long) catc;
+	catc->timer.function = catc_stats_timer;
+
+	FILL_CONTROL_URB(&catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0),
+		NULL, NULL, 0, catc_ctrl_done, catc);
+
+	FILL_BULK_URB(&catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1),
+		NULL, 0, catc_tx_done, catc);
+
+	FILL_BULK_URB(&catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1),
+		catc->rx_buf, RX_MAX_BURST * (PKT_SZ + 2), catc_rx_done, catc);
+
+	FILL_INT_URB(&catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, 2),
+                catc->irq_buf, 2, catc_irq_done, catc, 1);
+
+	dbg("Checking memory size\n");
+
+	i = 0x12345678;
+	catc_write_mem(catc, 0x7a80, &i, 4);
+	i = 0x87654321;	
+	catc_write_mem(catc, 0xfa80, &i, 4);
+	catc_read_mem(catc, 0x7a80, &i, 4);
+
+	switch (i) {
+		case 0x12345678:
+			catc_set_reg(catc, TxBufCount, 8);
+			catc_set_reg(catc, RxBufCount, 32);
+			dbg("64k Memory\n");
+			break;
+		default:
+			warn("Couldn't detect memory size, assuming 32k");
+		case 0x87654321:
+			catc_set_reg(catc, TxBufCount, 4);
+			catc_set_reg(catc, RxBufCount, 16);
+			dbg("32k Memory\n");
+			break;
+	}
+
+	dbg("Getting MAC from SEEROM.");
+
+	catc_get_mac(catc, netdev->dev_addr);
+
+	dbg("Setting MAC into registers.");
+
+	for (i = 0; i < 6; i++)
+		catc_set_reg(catc, StationAddr0 - i, netdev->dev_addr[i]);
+
+	dbg("Filling the multicast list.");
+
+	memset(broadcast, 0xff, 8);
+	catc_multicast(broadcast, catc->multicast);
+	catc_multicast(netdev->dev_addr, catc->multicast);
+	catc_write_mem(catc, 0xfa80, catc->multicast, 64);
+
+	dbg("Clearing error counters.");
+
+	for (i = 0; i < 8; i++)
+		catc_set_reg(catc, EthStats + i, 0);
+	catc->last_stats = jiffies;
+
+	dbg("Enabling.");
+
+	catc_set_reg(catc, MaxBurst, RX_MAX_BURST);
+	catc_set_reg(catc, OpModes, OpTxMerge | OpRxMerge | OpLenInclude | Op3MemWaits);
+	catc_set_reg(catc, LEDCtrl, LEDLink);
+	catc_set_reg(catc, RxUnit, RxEnable | RxPolarity | RxMultiCast);
+
+	dbg("Init done.");
+
+	printk(KERN_INFO "%s: CATC EL1210A NetMate USB Ethernet at usb%d:%d.%d, ",
+		netdev->name, usbdev->bus->busnum, usbdev->devnum, ifnum);
+	for (i = 0; i < 5; i++) printk("%2.2x:", netdev->dev_addr[i]);
+	printk("%2.2x.\n", netdev->dev_addr[i]);
+
+	return catc;
+}
+
+static void catc_disconnect(struct usb_device *usbdev, void *dev_ptr)
+{
+	struct catc *catc = dev_ptr;
+	unregister_netdev(catc->netdev);
+	kfree(catc->netdev);
+	kfree(catc);
+}
+
+/*
+ * Module functions and tables.
+ */
+
+static struct usb_device_id catc_id_table [] = {
+	{ USB_DEVICE(0x0423, 0xa) },	/* CATC Netmate */
+	{ USB_DEVICE(0x0423, 0xc) },	/* CATC Netmate II, Belkin F5U111 */
+	{ USB_DEVICE(0x08d1, 0x1) },	/* smartBridges smartNIC */
+	{ }
+};
+
+MODULE_DEVICE_TABLE(usb, catc_id_table);
+
+static struct usb_driver catc_driver = {
+	name:		"catc",
+	probe:		catc_probe,
+	disconnect:	catc_disconnect,
+	id_table:	catc_id_table,
+};
+
+static int __init catc_init(void)
+{
+	info(DRIVER_VERSION " " DRIVER_DESC);
+	usb_register(&catc_driver);
+	return 0;
+}
+
+static void __exit catc_exit(void)
+{
+	usb_deregister(&catc_driver);
+}
+
+module_init(catc_init);
+module_exit(catc_exit);
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/dabusb.c linux/drivers/usb/dabusb.c
--- v2.4.5/linux/drivers/usb/dabusb.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/dabusb.c	Tue Jun 12 15:53:37 2001
@@ -837,8 +837,7 @@
 
 	dbg("dabusb_init: driver registered");
 
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 
 	return 0;
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/dc2xx.c linux/drivers/usb/dc2xx.c
--- v2.4.5/linux/drivers/usb/dc2xx.c	Thu May 24 14:55:51 2001
+++ linux/drivers/usb/dc2xx.c	Tue Jun 12 15:53:37 2001
@@ -499,8 +499,7 @@
 {
  	if (usb_register (&camera_driver) < 0)
  		return -1;
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/dsbr100.c linux/drivers/usb/dsbr100.c
--- v2.4.5/linux/drivers/usb/dsbr100.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/dsbr100.c	Tue Jun 12 15:53:37 2001
@@ -342,8 +342,7 @@
 		warn("couldn't register video device");
 		return -EINVAL;
 	}
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/hid.c linux/drivers/usb/hid.c
--- v2.4.5/linux/drivers/usb/hid.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/hid.c	Tue Jun 12 15:53:37 2001
@@ -1559,8 +1559,7 @@
 static int __init hid_init(void)
 {
 	usb_register(&hid_driver);
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/ibmcam.c linux/drivers/usb/ibmcam.c
--- v2.4.5/linux/drivers/usb/ibmcam.c	Thu May 24 14:55:51 2001
+++ linux/drivers/usb/ibmcam.c	Tue Jun 12 15:53:37 2001
@@ -3147,8 +3147,7 @@
 		struct usb_ibmcam *ibmcam = &cams[u];
 		memset (ibmcam, 0, sizeof(struct usb_ibmcam));
 	}
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return usb_register(&ibmcam_driver);
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/mdc800.c linux/drivers/usb/mdc800.c
--- v2.4.5/linux/drivers/usb/mdc800.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/mdc800.c	Tue Jun 12 15:53:37 2001
@@ -932,8 +932,7 @@
 	if (usb_register (&mdc800_usb_driver) < 0)
 		goto cleanup_on_fail;
 
-	info (DRIVER_VERSION " " DRIVER_AUTHOR);
-	info (DRIVER_DESC);
+	info (DRIVER_VERSION ":" DRIVER_DESC);
 
 	return 0;
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/microtek.c linux/drivers/usb/microtek.c
--- v2.4.5/linux/drivers/usb/microtek.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/microtek.c	Tue Jun 12 15:53:37 2001
@@ -1029,8 +1029,7 @@
 		MTS_DEBUG("driver registered.\n");
 	}
 
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 
 	return 0;
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/net1080.c linux/drivers/usb/net1080.c
--- v2.4.5/linux/drivers/usb/net1080.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/net1080.c	Tue Jun 12 15:53:37 2001
@@ -599,7 +599,7 @@
 	}
 #ifdef	VERBOSE
 	dbg ("no read resubmitted");
-#endif	VERBOSE
+#endif	/* VERBOSE */
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1111,8 +1111,7 @@
 	get_random_bytes (node_id, sizeof node_id);
 	node_id [0] &= 0x7f;
 
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 
 	return 0;
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/ov511.c linux/drivers/usb/ov511.c
--- v2.4.5/linux/drivers/usb/ov511.c	Thu May 24 15:24:37 2001
+++ linux/drivers/usb/ov511.c	Tue Jun 12 15:53:37 2001
@@ -337,7 +337,7 @@
 	/* IMPORTANT: This output MUST be kept under PAGE_SIZE
 	 *            or we need to get more sophisticated. */
 
-	out += sprintf (out, "driver_version  : %s\n", version);
+	out += sprintf (out, "driver_version  : %s\n", DRIVER_VERSION);
 	out += sprintf (out, "custom_id       : %d\n", ov511->customid);
 	out += sprintf (out, "model           : %s\n", ov511->desc ?
 		clist[ov511->desc].description : "unknown");
@@ -3426,8 +3426,7 @@
 	if (usb_register(&ov511_driver) < 0)
 		return -1;
 
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 
 	return 0;
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/pegasus.c linux/drivers/usb/pegasus.c
--- v2.4.5/linux/drivers/usb/pegasus.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/pegasus.c	Wed Jun 27 13:59:32 2001
@@ -53,8 +53,8 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.4.18 2001/03/18 (C) 1999-2000"
-#define DRIVER_AUTHOR "Petko Manolov <petkan@dce.bg>"
+#define DRIVER_VERSION "v0.4.19 2001/06/07 (C) 1999-2001"
+#define DRIVER_AUTHOR "Petko Manolov <pmanolov@lnxw.com>"
 #define DRIVER_DESC "ADMtek AN986 Pegasus USB Ethernet driver"
 
 #define	PEGASUS_USE_INTR
@@ -117,8 +117,7 @@
 			warn( __FUNCTION__ " status %d", urb->status);
 	}
 	pegasus->flags &= ~ETH_REGS_CHANGED;
-	if ( pegasus->flags & CTRL_URB_SLEEP ) {
-		pegasus->flags &= ~CTRL_URB_SLEEP;
+	if ( waitqueue_active(&pegasus->ctrl_wait) ) {
 		wake_up_interruptible( &pegasus->ctrl_wait );
 	}
 }
@@ -127,12 +126,19 @@
 static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
 {
 	int	ret;
+	unsigned char *buffer;
 	DECLARE_WAITQUEUE(wait, current);
 
-	while ( pegasus->flags & ETH_REGS_CHANGED ) {
-		pegasus->flags |= CTRL_URB_SLEEP;
-		interruptible_sleep_on( &pegasus->ctrl_wait );
+	buffer = kmalloc(size,GFP_KERNEL);
+	if (!buffer) {
+		err("unable to allocate memory for configuration descriptors");
+		return 0;
 	}
+	memcpy(buffer,data,size);
+	
+	while ( pegasus->flags & ETH_REGS_CHANGED )
+		interruptible_sleep_on( &pegasus->ctrl_wait );
+
 	pegasus->dr.requesttype = PEGASUS_REQT_READ;
 	pegasus->dr.request = PEGASUS_REQ_GET_REGS;
 	pegasus->dr.value = cpu_to_le16 (0);
@@ -143,11 +149,10 @@
 	FILL_CONTROL_URB( &pegasus->ctrl_urb, pegasus->usb,
 			  usb_rcvctrlpipe(pegasus->usb,0),
 			  (char *)&pegasus->dr,
-			  data, size, ctrl_callback, pegasus );
+			  buffer, size, ctrl_callback, pegasus );
 
 	add_wait_queue( &pegasus->ctrl_wait, &wait );
 	set_current_state( TASK_INTERRUPTIBLE );
-	pegasus->flags |= CTRL_URB_SLEEP;
 
 	if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) ) {
 		err( __FUNCTION__ " BAD CTRLs %d", ret);
@@ -155,21 +160,31 @@
 	}
 
 	schedule();
-	remove_wait_queue( &pegasus->ctrl_wait, &wait );
 out:
-	return	ret;
+	remove_wait_queue( &pegasus->ctrl_wait, &wait );
+	memcpy(data,buffer,size);
+	kfree(buffer);
+
+	return ret;
 }
 
 
 static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
 {
 	int	ret;
+	unsigned char *buffer;
 	DECLARE_WAITQUEUE(wait, current);
 
-	while ( pegasus->flags & ETH_REGS_CHANGED ) {
-		pegasus->flags |= CTRL_URB_SLEEP ;
-		interruptible_sleep_on( &pegasus->ctrl_wait );
+	buffer = kmalloc(size, GFP_KERNEL);
+	if (!buffer) {
+		err("unable to allocate memory for configuration descriptors");
+		return 0;
 	}
+	memcpy(buffer, data, size);
+
+	while ( pegasus->flags & ETH_REGS_CHANGED )
+		interruptible_sleep_on( &pegasus->ctrl_wait );
+
 	pegasus->dr.requesttype = PEGASUS_REQT_WRITE;
 	pegasus->dr.request = PEGASUS_REQ_SET_REGS;
 	pegasus->dr.value = cpu_to_le16 (0);
@@ -180,34 +195,42 @@
 	FILL_CONTROL_URB( &pegasus->ctrl_urb, pegasus->usb,
 			  usb_sndctrlpipe(pegasus->usb,0),
 			  (char *)&pegasus->dr,
-			  data, size, ctrl_callback, pegasus );
+			  buffer, size, ctrl_callback, pegasus );
 			  
 	add_wait_queue( &pegasus->ctrl_wait, &wait );
 	set_current_state( TASK_INTERRUPTIBLE );
-	pegasus->flags |= CTRL_URB_SLEEP;
 
 	if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) ) {
 		err( __FUNCTION__ " BAD CTRL %d", ret);
-		return	ret;
+		goto out;
 	}
-
+	
 	schedule();
+out:
 	remove_wait_queue( &pegasus->ctrl_wait, &wait );
-
-	return	ret;
+	kfree(buffer);
+	
+	return ret;
 }
 
 
 static int set_register( pegasus_t *pegasus, __u16 indx, __u8 data )
 {
 	int	ret;
+	unsigned char *buffer;
 	__u16 dat = data;
 	DECLARE_WAITQUEUE(wait, current);
 	
-	while ( pegasus->flags & ETH_REGS_CHANGED ) {
-		pegasus->flags |= CTRL_URB_SLEEP;
-		interruptible_sleep_on( &pegasus->ctrl_wait );
+	buffer = kmalloc(1, GFP_KERNEL);
+	if (!buffer) {
+		err("unable to allocate memory for configuration descriptors");
+		return 0;
 	}
+	memcpy(buffer, &data, 1);
+
+	while ( pegasus->flags & ETH_REGS_CHANGED )
+		interruptible_sleep_on( &pegasus->ctrl_wait );
+
 	pegasus->dr.requesttype = PEGASUS_REQT_WRITE;
 	pegasus->dr.request = PEGASUS_REQ_SET_REG;
 	pegasus->dr.value = cpu_to_le16p( &dat);
@@ -218,21 +241,22 @@
 	FILL_CONTROL_URB( &pegasus->ctrl_urb, pegasus->usb,
 			  usb_sndctrlpipe(pegasus->usb,0),
 			  (char *)&pegasus->dr,
-			  &data, 1, ctrl_callback, pegasus );
+			  buffer, 1, ctrl_callback, pegasus );
 
 	add_wait_queue( &pegasus->ctrl_wait, &wait );
 	set_current_state( TASK_INTERRUPTIBLE );
-	pegasus->flags |= CTRL_URB_SLEEP;
 
 	if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) ) {
 		err( __FUNCTION__ " BAD CTRL %d", ret);
-		return	ret;
+		goto out;
 	}
 
 	schedule();
+out:
 	remove_wait_queue( &pegasus->ctrl_wait, &wait );
+	kfree(buffer);
 
-	return	ret;
+	return ret;
 }
 
 
@@ -421,7 +445,7 @@
 		return 1;
 
 	if ( usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS ||
-	     usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK1 ) {
+	     usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK ) {
 		__u16	auxmode;
 
 		read_mii_word( pegasus, 0, 0x1b, &auxmode );
@@ -767,7 +791,6 @@
 	} else {
 		pegasus->eth_regs[EthCtrl0] &= ~RX_MULTICAST;
 		pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS;
-		info("%s: set Rx mode", net->name);
 	}
 
 	pegasus->flags |= ETH_REGS_CHANGE;
@@ -905,8 +928,7 @@
 
 int __init pegasus_init(void)
 {
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return usb_register( &pegasus_driver );
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/pegasus.h linux/drivers/usb/pegasus.h
--- v2.4.5/linux/drivers/usb/pegasus.h	Mon May 21 17:04:24 2001
+++ linux/drivers/usb/pegasus.h	Wed Jun 27 13:59:32 2001
@@ -128,30 +128,51 @@
 };
 
 #define	VENDOR_3COM		0x0506
-#define VENDOR_ACCTON           0x083a
-#define VENDOR_ADMTEK           0x07a6
-#define VENDOR_BILLIONTON       0x08dd
-#define VENDOR_COREGA           0x07aa
-#define VENDOR_DLINK1           0x2001
-#define VENDOR_DLINK2           0x07b8
-#define VENDOR_IODATA           0x04bb
-#define VENDOR_LANEED           0x056e
-#define VENDOR_LINKSYS          0x066b
-#define VENDOR_MELCO            0x0411
-#define VENDOR_SMARTBRIDGES	0x08d1
-#define VENDOR_SMC              0x0707
-#define VENDOR_SOHOWARE         0x15e8
+#define	VENDOR_ABOCOM		0x07b8
+#define	VENDOR_ACCTON		0x083a
+#define	VENDOR_ADMTEK		0x07a6
+#define	VENDOR_BILLIONTON	0x08dd
+#define	VENDOR_COREGA		0x07aa
+#define	VENDOR_DLINK		0x2001
+#define	VENDOR_ELSA		0x05cc
+#define	VENDOR_IODATA		0x04bb
+#define	VENDOR_LANEED		0x056e
+#define	VENDOR_LINKSYS		0x066b
+#define	VENDOR_MELCO		0x0411
+#define	VENDOR_SMARTBRIDGES	0x08d1
+#define	VENDOR_SMC		0x0707
+#define	VENDOR_SOHOWARE		0x15e8
 
 #else	/* PEGASUS_DEV */
 
 PEGASUS_DEV( "3Com USB Ethernet 3C460B", VENDOR_3COM, 0x4601,
 		DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "USB HPNA/Ethernet", VENDOR_ABOCOM, 0x110c,
+		DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA )
+PEGASUS_DEV( "USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4104,
+		DEFAULT_GPIO_RESET | HAS_HOME_PNA )
+PEGASUS_DEV( "USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4004,
+		DEFAULT_GPIO_RESET | HAS_HOME_PNA )
+PEGASUS_DEV( "USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4007,
+		DEFAULT_GPIO_RESET | HAS_HOME_PNA )
+PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x4102,
+		DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x4002,
+		DEFAULT_GPIO_RESET )
+PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400b,
+		DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400c,
+		DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0xabc1,
+		DEFAULT_GPIO_RESET )
+PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c,
+		DEFAULT_GPIO_RESET | PEGASUS_II ) 	
 PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046,
 		DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "ADMtek ADM8511 \"Pegasus II\" USB Ethernet",
 		VENDOR_ADMTEK, 0x8511,
 		DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "ADMtek AN986 \"Pegasus\" USB Ethernet (eval board)",
+PEGASUS_DEV( "ADMtek AN986 \"Pegasus\" USB Ethernet (eval. board)",
 		VENDOR_ADMTEK, 0x0986,
 		DEFAULT_GPIO_RESET | HAS_HOME_PNA )
 PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
@@ -164,24 +185,32 @@
 		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "Corega FEter USB-TX", VENDOR_COREGA, 0x0004,
 		DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK1, 0x4001,
+PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4001,
 		LINKSYS_GPIO_RESET )
-PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK1, 0x4002,
+PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4002,
 		LINKSYS_GPIO_RESET )
-PEGASUS_DEV( "D-Link DSB-650TX(PNA)", VENDOR_DLINK1, 0x4003,
+PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4102,
+		LINKSYS_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x400b,
+		LINKSYS_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x200c,
+		LINKSYS_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "D-Link DSB-650TX(PNA)", VENDOR_DLINK, 0x4003,
 		DEFAULT_GPIO_RESET | HAS_HOME_PNA )
-PEGASUS_DEV( "D-Link DSB-650", VENDOR_DLINK1, 0xabc1,
+PEGASUS_DEV( "D-Link DSB-650", VENDOR_DLINK, 0xabc1,
 		DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "D-Link DU-E10", VENDOR_DLINK2, 0xabc1,
+PEGASUS_DEV( "Elsa Micolink USB2Ethernet", VENDOR_ELSA, 0x3000,
 		DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "D-Link DU-E100", VENDOR_DLINK2, 0x4002,
-		DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "FiberLine USB", VENDOR_DLINK2, 0x4102,
-		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
 		DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x4002,
 		DEFAULT_GPIO_RESET )
+PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x400b,
+		DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "LANEED USB Ethernet LD-USB/T", VENDOR_LANEED, 0xabc1,
+		DEFAULT_GPIO_RESET )
+PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x200c,
+		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "Linksys USB10TX", VENDOR_LINKSYS, 0x2202,
 		LINKSYS_GPIO_RESET )
 PEGASUS_DEV( "Linksys USB100TX", VENDOR_LINKSYS, 0x2203,
@@ -190,8 +219,16 @@
 		LINKSYS_GPIO_RESET | HAS_HOME_PNA )
 PEGASUS_DEV( "Linksys USB Ethernet Adapter", VENDOR_LINKSYS, 0x2206,
 		LINKSYS_GPIO_RESET )
+PEGASUS_DEV( "Linksys USB USB10TX", VENDOR_LINKSYS, 0x400b,
+		LINKSYS_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "Linksys USB10TX", VENDOR_LINKSYS, 0x200c,
+		LINKSYS_GPIO_RESET | PEGASUS_II )	
 PEGASUS_DEV( "MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0001,
 		DEFAULT_GPIO_RESET )
+PEGASUS_DEV( "MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0005,
+		DEFAULT_GPIO_RESET )
+PEGASUS_DEV( "MELCO/BUFFALO LUA2-TX", VENDOR_MELCO, 0x0009,
+		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "smartNIC 2 PnP Adapter", VENDOR_SMARTBRIDGES, 0x0003,
 		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "SMC 202 USB Ethernet", VENDOR_SMC, 0x0200,
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/plusb.c linux/drivers/usb/plusb.c
--- v2.4.5/linux/drivers/usb/plusb.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/plusb.c	Tue Jun 12 15:53:37 2001
@@ -1014,8 +1014,7 @@
 
 	dbg("plusb_init: driver registered");
 
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 
 	return 0;
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/printer.c linux/drivers/usb/printer.c
--- v2.4.5/linux/drivers/usb/printer.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/printer.c	Tue Jun 12 15:53:37 2001
@@ -662,8 +662,7 @@
 {
 	if (usb_register(&usblp_driver))
 		return -1;
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/pwc-ctrl.c linux/drivers/usb/pwc-ctrl.c
--- v2.4.5/linux/drivers/usb/pwc-ctrl.c	Fri May 25 09:48:50 2001
+++ linux/drivers/usb/pwc-ctrl.c	Wed Jun 20 17:42:09 2001
@@ -236,9 +236,7 @@
 	if (ret < 0)
 		return ret;
 	if (pEntry->compressed)
-		ret = pdev->decompressor->init(pdev->release, buf, &pdev->decompress_data);
-	if (ret < 0)
-		return ret;
+		pdev->decompressor->init(pdev->release, buf, pdev->decompress_data);
 		
 	/* Set various parameters */
 	pdev->vframes = frames;
@@ -303,9 +301,7 @@
 		return ret;
 
 	if (pChoose->bandlength > 0)
-		ret = pdev->decompressor->init(pdev->release, buf, &pdev->decompress_data);
-	if (ret < 0)
-		return ret;
+		pdev->decompressor->init(pdev->release, buf, pdev->decompress_data);
 	
 	/* Set various parameters */
 	pdev->vframes = frames;
@@ -366,9 +362,7 @@
 		return ret;
 
 	if (pChoose->bandlength > 0)
-		ret = pdev->decompressor->init(pdev->release, buf, &pdev->decompress_data);
-	if (ret < 0)
-		return ret;
+		pdev->decompressor->init(pdev->release, buf, pdev->decompress_data);
 		
 	/* All set and go */
 	pdev->vframes = frames;
@@ -429,14 +423,11 @@
 			return ret;
 		}
 	}
-	/* If the video mode was not supported, we still adjust the view size,
-	   since xawtv (Again! Stupid program...) doesn't care zit about 
-	   return values.
-	 */
 	pdev->view.x = width;
 	pdev->view.y = height;
 	pwc_set_image_buffer_size(pdev);
-	Trace(TRACE_SIZE, "Set viewport to %dx%d, image size is %dx%d. Palette = %d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y, pdev->vpalette);
+	Trace(TRACE_SIZE, "Set viewport to %dx%d, image size is %dx%d, palette = %d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y, pdev->vpalette);
+Debug("bandlength = %d\n", pdev->vbandlength);	
 	return 0;
 }
 
@@ -482,22 +473,15 @@
 	pdev->image.size = pdev->image.x * pdev->image.y * factor / 4;
 	pdev->view.size  = pdev->view.x  * pdev->view.y  * factor / 4;
 
-	pdev->offset.x = (pdev->view.x - pdev->image.x) / 2;
-	pdev->offset.y = (pdev->view.y - pdev->image.y) / 2;
-	if (pdev->vpalette == VIDEO_PALETTE_YUV420 || pdev->vpalette == VIDEO_PALETTE_YUV420P) {
-		/* Align offset, or you'll get some very weird results in
-		   YUV mode... x must be multiple of 4 (to get the Y's in 
-		   place), and y even (or you'll mixup U & V).
-		 */
-		pdev->offset.x &= 0xFFFC;
-		pdev->offset.y &= 0xFFFE;	
-		/* This is the offset in the Y area, hence no factor */
-		pdev->offset.size = (pdev->offset.y * pdev->view.x + pdev->offset.x);
-	}
-	else
-		pdev->offset.size = (pdev->offset.y * pdev->view.x + pdev->offset.x) * factor / 4;
+	/* Align offset, or you'll get some very weird results in
+	   YUV420 mode... x must be multiple of 4 (to get the Y's in 
+	   place), and y even (or you'll mixup U & V). This is less of a
+	   problem for YUV420P.
+	 */
+	pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC;
+	pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE;
 	
-	/* Set buffers to gray */
+	/* Fill buffers with gray or black */
 	for (i = 0; i < MAX_IMAGES; i++) {
 		if (pdev->image_ptr[i] != NULL)
 			memset(pdev->image_ptr[i], filler, pdev->view.size);
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/pwc-if.c linux/drivers/usb/pwc-if.c
--- v2.4.5/linux/drivers/usb/pwc-if.c	Fri May 25 09:48:50 2001
+++ linux/drivers/usb/pwc-if.c	Wed Jun 20 17:42:09 2001
@@ -84,10 +84,10 @@
 
 static int default_size = PSZ_QCIF;
 static int default_fps = 10;
-static int default_palette = VIDEO_PALETTE_RGB24; /* This is normal for webcams */
+static int default_palette = VIDEO_PALETTE_YUV420P; /* This format is understood by most tools */
 static int default_fbufs = 3;   /* Default number of frame buffers */
 static int default_mbufs = 2;	/* Default number of mmap() buffers */
-       int pwc_trace = TRACE_MODULE | TRACE_FLOW;
+       int pwc_trace = TRACE_MODULE | TRACE_FLOW | TRACE_PWCX;
 static int power_save = 0;
 int pwc_preferred_compression = 2; /* 0..3 = uncompressed..high */
 
@@ -110,7 +110,7 @@
 	owner:		THIS_MODULE,
 	name:		"Philips Webcam",	/* Filled in later */
 	type:		VID_TYPE_CAPTURE,
-	hardware:	VID_HARDWARE_PWC,	/* Let's pretend for now */
+	hardware:	VID_HARDWARE_PWC,
 	open:		pwc_video_open,
 	close:		pwc_video_close,
 	read:		pwc_video_read,
@@ -321,14 +321,16 @@
 		}
 	}
 	
-	/* Allocate decompressor buffer space */
-	kbuf = vmalloc(FRAME_SIZE);
-	if (kbuf == NULL) {
-		Err("Failed to allocate compressed image buffer.\n");
-		return -ENOMEM;
+	/* Allocate decompressor table space */
+	kbuf = NULL;
+	if (pdev->decompressor != NULL) {
+		kbuf = kmalloc(pdev->decompressor->table_size, GFP_KERNEL);
+		if (kbuf == NULL) {
+			Err("Failed to allocate decompress table.\n");
+			return -ENOMEM;
+		}
 	}
-	memset(kbuf, 0, FRAME_SIZE);
-	pdev->decompress_buffer = kbuf;
+	pdev->decompress_data = kbuf;
 	
 	/* Allocate image buffer; double buffer for mmap() */
 	kbuf = rvmalloc(default_mbufs * pdev->view_max.size * 4);
@@ -361,6 +363,7 @@
 		return;
 	}
 #endif	
+
 	/* Release Iso-pipe buffers */
 	Trace(TRACE_MEMORY, "Freeing ISO buffers.\n");
 	for (i = 0; i < MAX_ISO_BUFS; i++)
@@ -368,6 +371,7 @@
 			kfree(pdev->sbuf[i].data);
 			pdev->sbuf[i].data = NULL;
 		}
+
 	/* The same for frame buffers */
 	Trace(TRACE_MEMORY, "Freeing frame buffers.\n");
 	if (pdev->fbuf != NULL) {
@@ -380,11 +384,14 @@
 		kfree(pdev->fbuf);
 		pdev->fbuf = NULL;
 	}
-	/* Intermediate decompression buffer */
+
+	/* Intermediate decompression buffer & tables */
 	Trace(TRACE_MEMORY, "Freeing decompression buffer\n");
-	if (pdev->decompress_buffer != NULL)
-		vfree(pdev->decompress_buffer);
-	pdev->decompress_buffer = NULL;
+	if (pdev->decompress_data != NULL) {
+		kfree(pdev->decompress_data);
+		pdev->decompress_data = NULL;
+	}
+	pdev->decompressor = NULL;
 
 	/* Release image buffers */
 	Trace(TRACE_MEMORY, "Freeing image buffers\n");
@@ -401,7 +408,7 @@
    the user program. The first scheme involves the ISO buffers (called thus
    since they transport ISO data from the USB controller), and not really
    interesting. Suffices to say the data from this buffer is quickly 
-   gathered in an interrupt handler (pwc_isoc_hanlder) and placed into the 
+   gathered in an interrupt handler (pwc_isoc_handler) and placed into the 
    frame buffer.
    
    The frame buffer is the second scheme, and is the central element here.
@@ -412,8 +419,8 @@
    either read() or mmap().
    
    The image buffer is the third scheme, in which frames are decompressed
-   and converted into any of the desired image formats (rgb, bgr, yuv, etc).
-   For mmap() there is more than one image buffer available.
+   and possibly converted into planar format. For mmap() there is more than
+   one image buffer available.
 
    The frame buffers provide the image buffering, in case the user process
    is a bit slow. This introduces lag and some undesired side-effects.
@@ -500,7 +507,7 @@
 /**
   \brief Reset all buffers, pointers and lists, except for the image_used[] buffer. 
   
-  If the image_used[] buffer is cleared too mmap()/VIDIOCSYNC will run into trouble.
+  If the image_used[] buffer is cleared too, mmap()/VIDIOCSYNC will run into trouble.
  */
 static void pwc_reset_buffers(struct pwc_device *pdev)
 {
@@ -589,10 +596,11 @@
 	pdev->fill_image = (pdev->fill_image + 1) % default_mbufs;
 }
 
+/* XXX: 2001-06-17: The YUV420 palette will be phased out soon */
 static int pwc_set_palette(struct pwc_device *pdev, int pal)
 {
-	if (
-            pal == VIDEO_PALETTE_YUV420
+	if (   pal == VIDEO_PALETTE_YUV420
+            || pal == VIDEO_PALETTE_YUV420P
 #if PWC_DEBUG
             || pal == VIDEO_PALETTE_RAW
 #endif
@@ -640,10 +648,7 @@
 	fbuf = pdev->fill_frame;
 	if (fbuf == NULL) {
 		Err("pwc_isoc_handler without valid fill frame.\n");
-		if (waitqueue_active(&pdev->frameq))
-			wake_up_interruptible(&pdev->frameq);
-		if (waitqueue_active(&pdev->pollq))
-			wake_up_interruptible(&pdev->pollq);
+		wake_up_interruptible(&pdev->frameq);
 		return;
 	}
 	fillptr = fbuf->data + fbuf->filled;
@@ -750,12 +755,8 @@
 			pdev->vlast_packet_size = flen;
 		} /* ..status == 0 */
 	}
-	if (awake) {
-		if (waitqueue_active(&pdev->frameq))
-			wake_up_interruptible(&pdev->frameq);
-		if (waitqueue_active(&pdev->pollq))
-			wake_up_interruptible(&pdev->pollq);
-	}
+	if (awake)
+		wake_up_interruptible(&pdev->frameq);
 }
 
 
@@ -811,6 +812,7 @@
 		while (i >= 0) {
 			if (pdev->sbuf[i].urb != NULL)
 				usb_free_urb(pdev->sbuf[i].urb);
+			pdev->sbuf[i].urb = NULL;
 			i--;
 		}
 		return ret;
@@ -842,6 +844,8 @@
 		ret = usb_submit_urb(pdev->sbuf[i].urb);
 		if (ret)
 			Err("isoc_init() submit_urb %d failed with error %d\n", i, ret);
+		else
+			Trace(TRACE_OPEN, "pwc_isoc_init(): URB submitted.\n");
 	}
 
 	/* data should stream in now */
@@ -945,10 +949,16 @@
 		}
 	}
 
+	/* Find our decompressor, if any */
+	pdev->decompressor = pwc_find_decompressor(pdev->type);
+#if PWC_DEBUG	
+	Debug("Found decompressor for %d at 0x%p\n", pdev->type, pdev->decompressor);
+#endif
+
 	/* So far, so good. Allocate memory. */
 	i = pwc_allocate_buffers(pdev);
 	if (i < 0) {
-		Trace(TRACE_OPEN, "Failed to allocate memory.\n");
+		Trace(TRACE_OPEN, "Failed to allocate buffer memory.\n");
 		up(&pdev->modlock);
 		return i;
 	}
@@ -965,12 +975,6 @@
 	pdev->sequence = 0;
 #endif
 
-	/* Find our decompressor, if any */
-	pdev->decompressor = pwc_find_decompressor(pdev->type);
-#if PWC_DEBUG	
-	Debug("Found decompressor for %d at 0x%p\n", pdev->type, pdev->decompressor);
-#endif
-
 	/* Set some defaults */
 	pdev->vsnapshot = 0;
 	if (pdev->type == 730 || pdev->type == 740)
@@ -1064,12 +1068,11 @@
 	}
 
 	pdev->vopen = 0;
-	pwc_free_buffers(pdev);
 	if (pdev->decompressor != NULL) {
-		pdev->decompressor->exit(&pdev->decompress_data);
+		pdev->decompressor->exit();
 		pdev->decompressor->unlock();
 	}
-	pdev->decompressor = NULL;
+	pwc_free_buffers(pdev);
 
 	/* wake up _disconnect() routine */
 	if (pdev->unplugged)
@@ -1078,11 +1081,20 @@
 
 /*
  *	FIXME: what about two parallel reads ????
+ *      ANSWER: Not supported. You can't open the device more than once,
+                despite what the V4L1 interface says. First, I don't see 
+                the need, second there's no mechanism of alerting the 
+                2nd/3rd/... process of events like changing image size.
+                And I don't see the point of blocking that for the 
+                2nd/3rd/... process.
+                In multi-threaded environments reading parallel from any
+                device is tricky anyhow.
  */
  
 static long pwc_video_read(struct video_device *vdev, char *buf, unsigned long count, int noblock)
 {
 	struct pwc_device *pdev;
+	DECLARE_WAITQUEUE(wait, current);
 
 	Trace(TRACE_READ, "video_read(0x%p, %p, %ld, %d) called.\n", vdev, buf, count, noblock);
 	if (vdev == NULL)
@@ -1097,20 +1109,26 @@
 
 	/* In case we're doing partial reads, we don't have to wait for a frame */
 	if (pdev->image_read_pos == 0) {
-		/* See if a frame is completed, process that */
-		if (noblock && pdev->full_frames == NULL)
-			return -EAGAIN;
+		/* Do wait queueing according to the (doc)book */
+		add_wait_queue(&pdev->frameq, &wait);
 		while (pdev->full_frames == NULL) {
-			interruptible_sleep_on(&pdev->frameq);
-			if (pdev->unplugged) {
-				Debug("pwc_video_read: Device got unplugged (2).\n");
-				return -EPIPE;
-			}
-			if (signal_pending(current))
-				return -EINTR;
-		}
- 
-		/* Decompress & convert now */
+	                if (noblock) {
+	                	remove_wait_queue(&pdev->frameq, &wait);
+	                	current->state = TASK_RUNNING;
+	                	return -EWOULDBLOCK;
+	                }
+	                if (signal_pending(current)) {
+	                	remove_wait_queue(&pdev->frameq, &wait);
+	                	current->state = TASK_RUNNING;
+	                	return -ERESTARTSYS;
+	                }
+	                schedule();
+	                current->state = TASK_INTERRUPTIBLE;
+		}
+		remove_wait_queue(&pdev->frameq, &wait);
+		current->state = TASK_RUNNING;
+	                                                                                                                                                                                
+		/* Decompress [, convert] and release frame */
 		if (pwc_handle_frame(pdev))
 			return -EFAULT;
 	}
@@ -1145,7 +1163,7 @@
 	if (pdev == NULL)
 		return -EFAULT;
 	
-	poll_wait(file, &pdev->pollq, wait);
+	poll_wait(file, &pdev->frameq, wait);
 	if (pdev->unplugged) {
 		Debug("pwc_video_poll: Device got unplugged.\n");
 		return POLLERR;
@@ -1159,6 +1177,7 @@
 static int pwc_video_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
 {
 	struct pwc_device *pdev;
+	DECLARE_WAITQUEUE(wait, current);
 	
 	if (vdev == NULL)
 		return -EFAULT;
@@ -1271,6 +1290,11 @@
 
 			/*
 			 *	FIXME:	Suppose we are mid read
+			        ANSWER: No problem: the firmware of the camera
+			                can handle brightness/contrast/etc
+			                changes at _any_ time, and the palette
+			                is used exactly once in the uncompress
+			                routine.
 			 */
 			pwc_set_brightness(pdev, p.brightness);
 			pwc_set_contrast(pdev, p.contrast);
@@ -1309,11 +1333,6 @@
 			if (copy_from_user(&vw, arg, sizeof(vw)))
 				return -EFAULT;
 
-/*
-			size = pwc_decode_size(pdev, vw.width, vw.height);
-			if (size < 0)
-				return -EINVAL;
-*/				
 			fps = (vw.flags & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT;
 			snapshot = vw.flags & PWC_FPS_SNAPSHOT;
 			if (fps == 0)
@@ -1385,11 +1404,6 @@
 				int ret;
 				
 				Trace(TRACE_OPEN, "VIDIOCMCAPTURE: changing size to please xawtv :-(.\n");
-/*
-				size = pwc_decode_size(pdev, vm.width, vm.height);
-				if (size < 0)
-					return -EINVAL;
-*/					
 				ret = pwc_try_video_mode(pdev, vm.width, vm.height, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
 				if (ret)
 					return ret;
@@ -1435,28 +1449,32 @@
 
 			Trace(TRACE_READ, "VIDIOCSYNC called (%d).\n", mbuf);
 
+			/* bounds check */
 			if (mbuf < 0 || mbuf >= default_mbufs)
 				return -EINVAL;
 			/* check if this buffer was requested anyway */
 			if (pdev->image_used[mbuf] == 0)
 				return -EINVAL;
 
-			/* We (re)use the frame-waitqueue here. That may
-			   conflict with read(), but any programmer that uses
-			   read() and mmap() simultaneously should be given 
-			   a job at Micro$oft. As janitor.
+			/* Add ourselves to the frame wait-queue.
 			   
 			   FIXME: needs auditing for safety.
+			   QUSTION: In what respect? I think that using the
+			            frameq is safe now.
 			 */
+			add_wait_queue(&pdev->frameq, &wait);
 			while (pdev->full_frames == NULL) {
-				interruptible_sleep_on(&pdev->frameq);
-				if (pdev->unplugged) {
-					Debug("VIDIOCSYNC: Device got unplugged.\n");
-					return -EPIPE;
-				}
-				if (signal_pending(current))
-					return -EINTR;
+	                	if (signal_pending(current)) {
+	                		remove_wait_queue(&pdev->frameq, &wait);
+		                	current->state = TASK_RUNNING;
+		                	return -ERESTARTSYS;
+	        	        }
+	                	schedule();
+		                current->state = TASK_INTERRUPTIBLE;
 			}
+			remove_wait_queue(&pdev->frameq, &wait);
+			current->state = TASK_RUNNING;
+				
 			/* The frame is ready. Expand in the image buffer 
 			   requested by the user. I don't care if you 
 			   mmap() 5 buffers and request data in this order: 
@@ -1537,7 +1555,6 @@
 
 	vendor_id = udev->descriptor.idVendor;
 	product_id = udev->descriptor.idProduct;
-	
 
 	if (vendor_id == 0x0471) {
 		switch (product_id) {
@@ -1612,7 +1629,6 @@
 
 	pdev->udev = udev;
 	init_waitqueue_head(&pdev->frameq);
-	init_waitqueue_head(&pdev->pollq);
 	init_waitqueue_head(&pdev->remove_ok);
 	pdev->vcompression = pwc_preferred_compression;
 
@@ -1691,7 +1707,6 @@
 			   a frame, let them return an error condition
 			 */
 			wake_up(&pdev->frameq);
-			wake_up(&pdev->pollq);
 			
 			/* Wait until we get a 'go' from _close(). This
 			   had a gigantic race condition, since we kfree()
@@ -1736,7 +1751,7 @@
 MODULE_PARM(fps, "i");
 MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30");
 MODULE_PARM(palette, "s");
-MODULE_PARM_DESC(palette, "Initial colour format of images. One of rgb24, bgr24, rgb32, bgr32, yuyv, yuv420, yuv420p");
+MODULE_PARM_DESC(palette, "Initial colour format of images. One of yuv420, yuv420p");
 MODULE_PARM(fbufs, "i");
 MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve");
 MODULE_PARM(mbufs, "i");
@@ -1786,8 +1801,10 @@
 		/* Determine default palette */
 		if (!strcmp(palette, "yuv420"))
 			default_palette = VIDEO_PALETTE_YUV420;
+		if (!strcmp(palette, "yuv420p"))
+			default_palette = VIDEO_PALETTE_YUV420P;
 		else {
-			Err("Palette not recognized: try palette=yuv420.\n");
+			Err("Palette not recognized: try palette=yuv420 or yuv420p.\n");
 			return -EINVAL;
 		}
 		Info("Default palette set to %d.\n", default_palette);
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/pwc-uncompress.c linux/drivers/usb/pwc-uncompress.c
--- v2.4.5/linux/drivers/usb/pwc-uncompress.c	Fri May 25 09:48:50 2001
+++ linux/drivers/usb/pwc-uncompress.c	Wed Jun 20 17:42:09 2001
@@ -21,6 +21,8 @@
    themselves. It also has a decompressor wrapper function.
 */
 
+#include <asm/types.h>
+
 #include "pwc.h"
 #include "pwc-uncompress.h"
 
@@ -38,7 +40,7 @@
 void pwc_register_decompressor(struct pwc_decompressor *pwcd)
 {
 	if (pwc_find_decompressor(pwcd->type) == NULL) {
-		Debug("Adding decompressor for model %d.\n", pwcd->type);
+		Trace(TRACE_PWCX, "Adding decompressor for model %d.\n", pwcd->type);
 		list_add_tail(&pwcd->pwcd_list, &pwc_decompressor_list);
 	}
 }
@@ -50,7 +52,7 @@
 	
 	find = pwc_find_decompressor(type);
 	if (find != NULL) {
-		Debug("Removing decompressor for model %d.\n", type);
+		Trace(TRACE_PWCX, "Removing decompressor for model %d.\n", type);
 		list_del(&find->pwcd_list);
 	}
 }
@@ -74,8 +76,11 @@
 int pwc_decompress(struct pwc_device *pdev)
 {
 	struct pwc_frame_buf *fbuf;
-	int n, l, c, w;
+	int n, line, col, stride;
 	void *yuv, *image, *dst;
+	u16 *src;
+	u16 *dsty, *dstu, *dstv;
+
 	
 	if (pdev == NULL)
 		return -EFAULT;
@@ -92,7 +97,7 @@
 	image = pdev->image_ptr[pdev->fill_image];
 	if (!image)
 		return -EFAULT;
-
+	
 #if PWC_DEBUG
 	/* This is a quickie */
 	if (pdev->vpalette == VIDEO_PALETTE_RAW) {
@@ -101,49 +106,78 @@
 	}
 #endif
 
-	/* Compressed formats are decompressed in decompress_buffer, then 
-	 * transformed into the desired format 
-	 */
-	yuv = pdev->decompress_buffer;
-	n = 0;
-	if (pdev->vbandlength == 0) { /* uncompressed */
-		yuv = fbuf->data + pdev->frame_header_size;  /* Skip header */
-	}
-	else {
-		if (pdev->decompressor)
-			n = pdev->decompressor->decompress(pdev->decompress_data, pdev->image.x, pdev->image.y, pdev->vbandlength, yuv, fbuf->data + pdev->frame_header_size, 0);
-		else
-			n = -ENXIO; /* No such device or address: missing decompressor */
-	}
-	if (n < 0) {
-		Err("Error in decompression engine: %d\n", n);
-		return n;
-	}
-
-	/* At this point 'yuv' always points to the uncompressed, non-scaled YUV420I data */
-	if (pdev->image.x == pdev->view.x && pdev->image.y == pdev->view.y) {
-		/* Sizes matches; make it quick */
-		switch(pdev->vpalette) {
+	yuv = fbuf->data + pdev->frame_header_size;  /* Skip header */
+	if (pdev->vbandlength == 0) { 
+		/* Uncompressed mode. We copy the data into the output buffer,
+		   using the viewport size (which may be larger than the image
+		   size). Unfortunately we have to do a bit of byte stuffing
+		   to get the desired output format/size.
+		 */
+		switch (pdev->vpalette) {
 		case VIDEO_PALETTE_YUV420:
-			memcpy(image, yuv, pdev->image.size);
+			/* Calculate byte offsets per line in image & view */
+			n   = (pdev->image.x * 3) / 2;
+			col = (pdev->view.x  * 3) / 2;
+			/* Offset into image */
+			dst = image + (pdev->view.x * pdev->offset.y + pdev->offset.x) * 3 / 2;
+			for (line = 0; line < pdev->image.y; line++) {
+				memcpy(dst, yuv, n);
+				yuv += n;
+				dst += col;
+			}
 			break;
-		}
-	}
-	else {
- 		/* Size mismatch; use viewport conversion routines */
-	 	switch(pdev->vpalette) {
-		case VIDEO_PALETTE_YUV420:
-			dst = image + pdev->offset.size;
-			w = pdev->view.x * 6;
-			c = pdev->image.x * 6;
-			for (l = 0; l < pdev->image.y; l++) {
-				memcpy(dst, yuv, c);
-				dst += w;
-				yuv += c;
+
+		case VIDEO_PALETTE_YUV420P:
+			/* 
+			 * We do some byte shuffling here to go from the 
+			 * native format to YUV420P.
+			 */
+			src = (u16 *)yuv;
+			n = pdev->view.x * pdev->view.y;
+
+			/* offset in Y plane */
+			stride = pdev->view.x * pdev->offset.y + pdev->offset.x;
+			dsty = (u16 *)(image + stride);
+
+			/* offsets in U/V planes */
+			stride = pdev->view.x * pdev->offset.y / 4 + pdev->offset.x / 2;
+			dstu = (u16 *)(image + n +         stride);
+			dstv = (u16 *)(image + n + n / 4 + stride);
+
+			/* increment after each line */
+			stride = (pdev->view.x - pdev->image.x) / 2; /* u16 is 2 bytes */
+
+			for (line = 0; line < pdev->image.y; line++) {
+				for (col = 0; col < pdev->image.x; col += 4) {
+					*dsty++ = *src++;
+					*dsty++ = *src++;
+					if (line & 1)
+						*dstv++ = *src++;
+					else
+						*dstu++ = *src++;
+				}
+				dsty += stride;
+				if (line & 1)
+					dstv += (stride >> 1);
+				else
+					dstu += (stride >> 1);
 			}
 			break;
- 		}
- 	}
+		}
+	}
+	else { 
+		/* Compressed; the decompressor routines will write the data 
+		   in interlaced or planar format immediately.
+		 */
+		if (pdev->decompressor)
+			pdev->decompressor->decompress(
+				&pdev->image, &pdev->view, &pdev->offset,
+				yuv, image, 
+				pdev->vpalette == VIDEO_PALETTE_YUV420P ? 1 : 0,
+				pdev->decompress_data, pdev->vbandlength);
+		else
+			return -ENXIO; /* No such device or address: missing decompressor */
+	}
 	return 0;
 }
 
@@ -154,4 +188,3 @@
 EXPORT_SYMBOL_NOVERS(pwc_decompressor_version);
 EXPORT_SYMBOL(pwc_register_decompressor);
 EXPORT_SYMBOL(pwc_unregister_decompressor);
-EXPORT_SYMBOL(pwc_find_decompressor);
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/pwc-uncompress.h linux/drivers/usb/pwc-uncompress.h
--- v2.4.5/linux/drivers/usb/pwc-uncompress.h	Tue May 22 10:25:36 2001
+++ linux/drivers/usb/pwc-uncompress.h	Wed Jun 20 17:42:09 2001
@@ -15,13 +15,19 @@
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
+/* This file is the bridge between the kernel module and the plugin; it
+   describes the structures and datatypes used in both modules. Any
+   significant change should be reflected by increasing the 
+   pwc_decompressor_version major number.
+ */
 #ifndef PWC_DEC_H
 #define PWC_DEC_H
 
 #include <linux/config.h>
-
 #include <linux/list.h>
 
+#include "pwc.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -33,12 +39,16 @@
  */
 struct pwc_decompressor
 {
-	int  type;	/* type of camera (645, 646, etc) */
-	int  (* init)(int release, void *buffer, void **data);	/* Initialization routine; should be called after each set_video_mode */
-	void (* exit)(void **data);	/* Cleanup routine */
-	int  (* decompress)(void *data, int width, int height, int bandlength, void *dst, void *src, int planar); /* The decompression routine itself */
-	void (* lock)(void); /* make sure module cannot be unloaded */
-	void (* unlock)(void); /* release lock on module */
+	int  type;		/* type of camera (645, 680, etc) */
+	int  table_size;	/* memory needed */
+
+	void (* init)(int release, void *buffer, void *table);	/* Initialization routine; should be called after each set_video_mode */
+	void (* exit)(void);	/* Cleanup routine */
+	void (* decompress)(struct pwc_coord *image, struct pwc_coord *view, struct pwc_coord *offset,
+                            void *src, void *dst, int planar,
+	                    void *table, int bandlength);
+	void (* lock)(void);	/* make sure module cannot be unloaded */
+	void (* unlock)(void);	/* release lock on module */
 
 	struct list_head pwcd_list;
 };
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/pwc.h linux/drivers/usb/pwc.h
--- v2.4.5/linux/drivers/usb/pwc.h	Fri May 25 09:48:50 2001
+++ linux/drivers/usb/pwc.h	Wed Jun 20 17:42:09 2001
@@ -43,6 +43,7 @@
 #define TRACE_MEMORY	0x0010
 #define TRACE_FLOW	0x0020
 #define TRACE_SIZE	0x0040
+#define TRACE_PWCX	0x0080
 #define TRACE_SEQUENCE	0x1000
 
 #define Trace(R, A...) if (pwc_trace & R) printk(KERN_DEBUG PWC_NAME " " A)
@@ -56,28 +57,10 @@
 #define TOUCAM_TRAILER_SIZE		4
 
 /* Version block */
-#define PWC_MAJOR	7
-#define PWC_MINOR	1
-#define PWC_RELEASE 	"7.1"
-
-#if defined(CONFIG_ARM)
-  #define PWC_PROCESSOR "ARM"
-#endif
-#if defined(CONFIG_M686)
-  #define PWC_PROCESSOR "PPro"
-#endif
-#if !defined(PWC_PROCESSOR)
-  #define PWC_PROCESSOR "P5"
-#endif  
-
-#if defined(__SMP__) || defined(CONFIG_SMP)
-#define PWC_SMP "(SMP)"
-#else
-#define PWC_SMP "(UP)"
-#endif
-
-#define PWC_VERSION PWC_RELEASE " " PWC_PROCESSOR " " PWC_SMP
-#define PWC_NAME "pwc"
+#define PWC_MAJOR	8
+#define PWC_MINOR	0
+#define PWC_VERSION 	"8.0"
+#define PWC_NAME 	"pwc"
 
 /* Turn certain features on/off */
 #define PWC_INT_PIPE 0
@@ -156,12 +139,12 @@
    char vsnapshot;		/* snapshot mode */
    char vsync;			/* used by isoc handler */
 
-   /* The image acquisition requires 3 to 5 steps:
+   /* The image acquisition requires 3 to 4 steps:
       1. data is gathered in short packets from the USB controller
       2. data is synchronized and packed into a frame buffer
-      3. in case data is compressed, decompress it into a separate buffer
-      4. data is optionally converted to RGB/YUV 
-      5. data is transfered to the user process
+      3a. in case data is compressed, decompress it directly into image buffer
+      3b. in case data is uncompressed, copy into image buffer with viewport
+      4. data is transfered to the user process
 
       Note that MAX_ISO_BUFS != MAX_FRAMES != MAX_IMAGES.... 
       We have in effect a back-to-back-double-buffer system.
@@ -171,11 +154,11 @@
    char iso_init;
    
    /* 2: frame */
-   struct pwc_frame_buf *fbuf;
-   struct pwc_frame_buf *empty_frames, *empty_frames_tail;
-   struct pwc_frame_buf *full_frames, *full_frames_tail;
-   struct pwc_frame_buf *read_frame;
-   struct pwc_frame_buf *fill_frame;
+   struct pwc_frame_buf *fbuf;	/* all frames */
+   struct pwc_frame_buf *empty_frames, *empty_frames_tail;	/* all empty frames */
+   struct pwc_frame_buf *full_frames, *full_frames_tail;	/* all filled frames */
+   struct pwc_frame_buf *fill_frame;	/* frame currently filled */
+   struct pwc_frame_buf *read_frame;	/* frame currently read by user process */
    int frame_size;
    int frame_header_size, frame_trailer_size;
    int drop_frames;
@@ -186,7 +169,6 @@
    /* 3: decompression */
    struct pwc_decompressor *decompressor;	/* function block with decompression routines */
    void *decompress_data;		/* private data for decompression engine */
-   void *decompress_buffer;		/* decompressed data */
 
    /* 4: image */
    /* We have an 'image' and a 'view', where 'image' is the fixed-size image
@@ -205,20 +187,11 @@
    int image_read_pos;			/* In case we read data in pieces, keep track of were we are in the imagebuffer */
    int image_used[MAX_IMAGES];		/* For MCAPTURE and SYNC */
 
-   /* Kernel specific structures. These were once moved to the end 
-      of the structure and padded with bytes after I found out
-      some of these have different sizes in different kernel versions.
-      But since this is now a source release, I don't have this problem
-      anymore.
-
-      Fortunately none of these structures are needed in the pwcx module.
-    */
    struct semaphore modlock;		/* to prevent races in video_open(), etc */
    spinlock_t ptrlock;			/* for manipulating the buffer pointers */
 
    /*** Misc. data ***/
    wait_queue_head_t frameq;		/* When waiting for a frame to finish... */
-   wait_queue_head_t pollq;		/* poll() has it's own waitqueue */
    wait_queue_head_t remove_ok;		/* When we got hot unplugged, we have to avoid a few race conditions */
 #if PWC_INT_PIPE
    void *usb_int_handler;		/* for the interrupt endpoint */
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/rio500.c linux/drivers/usb/rio500.c
--- v2.4.5/linux/drivers/usb/rio500.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/rio500.c	Tue Jun 12 15:53:37 2001
@@ -492,8 +492,7 @@
 	if (usb_register(&rio_driver) < 0)
 		return -1;
 
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 
 	return 0;
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/se401.c linux/drivers/usb/se401.c
--- v2.4.5/linux/drivers/usb/se401.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/se401.c	Wed Jun 27 13:59:32 2001
@@ -0,0 +1,1675 @@
+/*
+ * Endpoints (formerly known as AOX) se401 USB Camera Driver
+ *
+ * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org)
+ *
+ * Still somewhat based on the Linux ov511 driver.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * Thanks to Endpoints Inc. (www.endpoints.com) for making documentation on
+ * their chipset available and supporting me while writing this driver.
+ * 	- Jeroen Vreeken
+ */
+
+static const char version[] = "0.22";
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/pagemap.h>
+#include <linux/usb.h>
+#include <asm/io.h>
+#include <asm/semaphore.h>
+#include <linux/wrapper.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
+#define virt_to_page(arg)	MAP_NR(arg)
+#define vmalloc_32		vmalloc
+#endif
+
+#include "se401.h"
+
+static int flickerless=0;
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 3, 0)
+static __devinitdata struct usb_device_id device_table [] = {
+	{ USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */
+	{ USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */
+	{ USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */
+	{ USB_DEVICE(0x047d, 0x5002) },/* Kensington 6701(5/7) */
+	{ USB_DEVICE(0x047d, 0x5003) },/* Kensington 67016 */
+	{ }
+};
+
+MODULE_DEVICE_TABLE(usb, device_table);
+#endif
+
+static int video_nr = -1;
+
+MODULE_AUTHOR("Jeroen Vreeken <pe1rxq@amsat.org>");
+MODULE_DESCRIPTION("SE401 USB Camera Driver");
+MODULE_PARM(flickerless, "i");
+MODULE_PARM_DESC(flickerless, "Net frequency to adjust exposure time to (0/50/60)");
+EXPORT_NO_SYMBOLS;
+
+
+static struct usb_driver se401_driver;
+
+
+/**********************************************************************
+ *
+ * Memory management
+ *
+ * This is a shameless copy from the USB-cpia driver (linux kernel
+ * version 2.3.29 or so, I have no idea what this code actually does ;).
+ * Actually it seems to be a copy of a shameless copy of the bttv-driver.
+ * Or that is a copy of a shameless copy of ... (To the powers: is there
+ * no generic kernel-function to do this sort of stuff?)
+ *
+ * Yes, it was a shameless copy from the bttv-driver. IIRC, Alan says
+ * there will be one, but apparentely not yet -jerdfelt
+ *
+ * So I copied it again for the ov511 driver -claudio
+ *
+ * Same for the se401 driver -Jeroen
+ **********************************************************************/
+
+/* Given PGD from the address space's page table, return the kernel
+ * virtual mapping of the physical memory mapped at ADR.
+ */
+static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
+{
+	unsigned long ret = 0UL;
+	pmd_t *pmd;
+	pte_t *ptep, pte;
+
+	if (!pgd_none(*pgd)) {
+		pmd = pmd_offset(pgd, adr);
+		if (!pmd_none(*pmd)) {
+			ptep = pte_offset(pmd, adr);
+			pte = *ptep;
+			if (pte_present(pte)) {
+				ret = (unsigned long) page_address(pte_page(pte));
+				ret |= (adr & (PAGE_SIZE - 1));
+			}
+		}
+	}
+
+	return ret;
+}
+
+/* Here we want the physical address of the memory.
+ * This is used when initializing the contents of the
+ * area and marking the pages as reserved.
+ */
+static inline unsigned long kvirt_to_pa(unsigned long adr)
+{
+	unsigned long va, kva, ret;
+
+	va = VMALLOC_VMADDR(adr);
+	kva = uvirt_to_kva(pgd_offset_k(va), va);
+	ret = __pa(kva);
+	return ret;
+}
+
+static void *rvmalloc(unsigned long size)
+{
+	void *mem;
+	unsigned long adr, page;
+
+	/* Round it off to PAGE_SIZE */
+	size += (PAGE_SIZE - 1);
+	size &= ~(PAGE_SIZE - 1);
+
+	mem = vmalloc_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 = 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;
+}
+
+static void rvfree(void *mem, unsigned long size)
+{
+	unsigned long adr, page;
+
+	if (!mem)
+		return;
+
+	size += (PAGE_SIZE - 1);
+	size &= ~(PAGE_SIZE - 1);
+
+	adr=(unsigned long) mem;
+	while (size > 0) {
+		page = kvirt_to_pa(adr);
+		mem_map_unreserve(virt_to_page(__va(page)));
+		adr += PAGE_SIZE;
+		if (size > PAGE_SIZE)
+			size -= PAGE_SIZE;
+		else
+			size = 0;
+	}
+	vfree(mem);
+}
+
+
+
+/****************************************************************************
+ *
+ * /proc interface
+ *
+ ***************************************************************************/
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
+
+static struct proc_dir_entry *se401_proc_entry = NULL;
+extern struct proc_dir_entry *video_proc_entry;
+
+#define YES_NO(x) ((x) ? "yes" : "no")
+
+static int se401_read_proc(char *page, char **start, off_t off, int count,
+			   int *eof, void *data)
+{
+	char *out = page;
+	int i, len;
+	struct usb_se401 *se401 = data;
+	
+	/* Stay under PAGE_SIZE or else bla bla bla.... */
+
+	out+=sprintf(out, "driver_version  : %s\n", version);
+	out+=sprintf(out, "model           : %s\n", se401->camera_name);
+	out+=sprintf(out, "in use          : %s\n", YES_NO (se401->user));
+	out+=sprintf(out, "streaming       : %s\n", YES_NO (se401->streaming));
+	out+=sprintf(out, "button state    : %s\n", YES_NO (se401->button));
+	out+=sprintf(out, "button pressed  : %s\n", YES_NO (se401->buttonpressed));
+	out+=sprintf(out, "num_frames      : %d\n", SE401_NUMFRAMES);
+
+	out+=sprintf(out, "Sizes           :");
+	for (i=0; i<se401->sizes; i++) {
+		out+=sprintf(out, " %dx%d", se401->width[i],
+		    se401->height[i]);
+	}
+	out+=sprintf(out, "\n");
+	
+	out+=sprintf(out, "Frames total    : %d\n", se401->readcount);
+	out+=sprintf(out, "Frames read     : %d\n", se401->framecount);
+	out+=sprintf(out, "Packets dropped : %d\n", se401->dropped);
+	out+=sprintf(out, "Decoding Errors : %d\n", se401->error);
+
+	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 se401_write_proc(struct file *file, const char *buffer, 
+			    unsigned long count, void *data)
+{
+	return -EINVAL;
+}
+
+static void create_proc_se401_cam (struct usb_se401 *se401)
+{
+	char name[7];
+	struct proc_dir_entry *ent;
+
+	if (!se401_proc_entry || !se401)
+		return;
+
+	sprintf (name, "video%d", se401->vdev.minor);
+
+	ent = create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR,
+				se401_proc_entry);
+
+	if (!ent)
+		return;
+
+	ent->data = se401;
+	ent->read_proc = se401_read_proc;
+	ent->write_proc = se401_write_proc;
+	se401->proc_entry = ent;
+}
+
+static void destroy_proc_se401_cam (struct usb_se401 *se401)
+{
+	/* One to much, just to be sure :) */
+	char name[9];
+
+	if (!se401 || !se401->proc_entry)
+		return;
+	
+	sprintf(name, "video%d", se401->vdev.minor);
+	remove_proc_entry(name, se401_proc_entry);
+	se401->proc_entry = NULL;
+}
+
+static void proc_se401_create (void)
+{
+	if (video_proc_entry == NULL) {
+		err("/proc/video/ doesn't exist");
+		return;
+	}
+
+	se401_proc_entry=create_proc_entry("se401", S_IFDIR, video_proc_entry);
+
+	if (se401_proc_entry)
+		se401_proc_entry->owner = THIS_MODULE;
+	else
+		err("Unable to initialize /proc/video/se401");
+}
+
+static void proc_se401_destroy(void)
+{
+	if (se401_proc_entry == NULL)
+		return;
+
+	remove_proc_entry("se401", video_proc_entry);
+}
+#endif /* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */
+
+
+/****************************************************************************
+ *
+ * se401 register read/write functions
+ *
+ ***************************************************************************/
+
+static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req,
+			 unsigned short value, unsigned char *cp, int size)
+{
+	return usb_control_msg (
+                se401->dev,
+                set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0),
+                req,
+                (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                value,
+                0,
+                cp,
+                size,
+                HZ
+        );
+}
+
+static int se401_set_feature(struct usb_se401 *se401, unsigned short selector,
+			     unsigned short param)
+{
+	/* specs say that the selector (address) should go in the value field
+	   and the param in index, but in the logs of the windows driver they do
+	   this the other way around...
+	 */
+	return usb_control_msg (
+		se401->dev,
+		usb_sndctrlpipe(se401->dev, 0),
+		SE401_REQ_SET_EXT_FEATURE,
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		param,
+		selector,
+                NULL,
+                0,
+                HZ
+        );
+}
+
+static unsigned short se401_get_feature(struct usb_se401 *se401, 
+				        unsigned short selector)
+{
+	/* For 'set' the selecetor should be in index, not sure if the spec is
+	   wrong here to....
+	 */
+	unsigned char cp[2];
+        usb_control_msg (
+                se401->dev,
+                usb_rcvctrlpipe(se401->dev, 0),
+                SE401_REQ_GET_EXT_FEATURE,
+                USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+        	0,
+                selector,
+                cp,
+                2,
+                HZ
+        );
+	return cp[0]+cp[1]*256;
+}
+
+/****************************************************************************
+ *
+ * Camera control
+ *
+ ***************************************************************************/
+
+
+static int se401_send_pict(struct usb_se401 *se401)
+{
+	se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l);/* integration time low */
+	se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m);/* integration time mid */
+	se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h);/* integration time mid */
+	se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);/* reset level value */
+	se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain);/* red color gain */
+	se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain);/* green color gain */
+	se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain);/* blue color gain */
+	    	
+	return 0;
+}
+
+static void se401_set_exposure(struct usb_se401 *se401, int brightness)
+{
+	int integration=brightness<<5;
+	
+	if (flickerless==50) {
+		integration=integration-integration%106667;
+	}
+	if (flickerless==60) {
+		integration=integration-integration%88889;
+	}
+	se401->brightness=integration>>5;
+	se401->expose_h=(integration>>16)&0xff;
+	se401->expose_m=(integration>>8)&0xff;
+	se401->expose_l=integration&0xff;
+}
+
+static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p)
+{
+	p->brightness=se401->brightness;
+	if (se401->enhance) {
+		p->whiteness=32768;
+	} else {
+		p->whiteness=0;
+	}
+	p->colour=65535;
+	p->contrast=65535;
+	p->hue=se401->rgain<<10;
+	p->palette=se401->palette;
+	p->depth=3; /* rgb24 */
+	return 0;
+}
+
+
+static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p)
+{
+	if (p->palette != VIDEO_PALETTE_RGB24)
+		return 1;
+	se401->palette=p->palette;
+	if (p->hue!=se401->hue) {
+		se401->rgain= p->hue>>10;
+		se401->bgain= 0x40-(p->hue>>10);
+		se401->hue=p->hue;
+	}
+	if (p->brightness!=se401->brightness) {
+		se401_set_exposure(se401, p->brightness);
+	}
+	if (p->whiteness>=32768) {
+		se401->enhance=1;
+	} else {
+		se401->enhance=0;
+	}
+	se401_send_pict(se401);
+	se401_send_pict(se401);
+	return 0;
+}
+
+/*
+	Hyundai have some really nice docs about this and other sensor related
+	stuff on their homepage: www.hei.co.kr
+*/
+static void se401_auto_resetlevel(struct usb_se401 *se401)
+{
+	unsigned int ahrc, alrc;
+	int oldreset=se401->resetlevel;
+
+	/* For some reason this normally read-only register doesn't get reset
+	   to zero after reading them just once...
+	 */
+	se401_get_feature(se401, HV7131_REG_HIREFNOH); 
+	se401_get_feature(se401, HV7131_REG_HIREFNOL);
+	se401_get_feature(se401, HV7131_REG_LOREFNOH);
+	se401_get_feature(se401, HV7131_REG_LOREFNOL);
+	ahrc=256*se401_get_feature(se401, HV7131_REG_HIREFNOH) + 
+	    se401_get_feature(se401, HV7131_REG_HIREFNOL);
+	alrc=256*se401_get_feature(se401, HV7131_REG_LOREFNOH) +
+	    se401_get_feature(se401, HV7131_REG_LOREFNOL);
+
+	/* Not an exact science, but it seems to work pretty well... */
+	if (alrc > 10) {
+		while (alrc>=10 && se401->resetlevel < 63) {
+			se401->resetlevel++;
+			alrc /=2;
+		}
+	} else if (ahrc > 20) {
+		while (ahrc>=20 && se401->resetlevel > 0) {
+			se401->resetlevel--;
+			ahrc /=2;
+		}
+	}
+	if (se401->resetlevel!=oldreset)
+		se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);
+
+	return;
+}
+
+/* irq handler for snapshot button */
+static void se401_button_irq(struct urb *urb)
+{
+	struct usb_se401 *se401=urb->context;
+	
+	if (!urb) {
+		info("ohoh: null urb");
+		return;
+	}
+	if (!se401->dev) {
+		info("ohoh: device vapourished");
+		return;
+	}
+	
+	if (urb->actual_length >=2 && !urb->status) {
+		if (se401->button)
+			se401->buttonpressed=1;
+	}
+}
+
+static void se401_video_irq(struct urb *urb)
+{
+	struct usb_se401 *se401=urb->context;
+	int length=urb->actual_length;
+
+	/* ohoh... */
+	if (!se401->streaming) {
+		return;
+	}
+	if (!urb) {
+		info ("ohoh: null urb");
+		return;
+	}
+	if (!se401->dev) {
+		info ("ohoh: device vapourished");
+		return;
+	}
+
+	/* 0 sized packets happen if we are to fast, but sometimes the camera
+	   keeps sending them forever...
+	 */
+	if (length && !urb->status) {
+		se401->nullpackets=0;
+		switch(se401->scratch[se401->scratch_next].state) {
+			case BUFFER_READY:
+			case BUFFER_BUSY: {
+				se401->dropped++;
+				break;
+			}
+			case BUFFER_UNUSED: {
+				memcpy(se401->scratch[se401->scratch_next].data, (unsigned char *)urb->transfer_buffer, length);
+				se401->scratch[se401->scratch_next].state=BUFFER_READY;
+				se401->scratch[se401->scratch_next].offset=se401->bayeroffset;
+				se401->scratch[se401->scratch_next].length=length;
+				if (waitqueue_active(&se401->wq)) {
+					wake_up_interruptible(&se401->wq);
+				}
+				se401->scratch_overflow=0;
+				se401->scratch_next++;
+				if (se401->scratch_next>=SE401_NUMSCRATCH)
+					se401->scratch_next=0;;
+				break;
+			}
+		}
+		se401->bayeroffset+=length;
+		if (se401->bayeroffset>=se401->cheight*se401->cwidth) {
+			se401->bayeroffset=0;
+		}
+	} else {
+		se401->nullpackets++;
+		if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
+			if (waitqueue_active(&se401->wq)) {
+				wake_up_interruptible(&se401->wq);
+			}		
+		}
+	}
+
+	/* Resubmit urb for new data */
+	urb->status=0;
+	urb->dev=se401->dev;
+	if(usb_submit_urb(urb))
+		info("urb burned down");
+	return;
+}
+
+static void se401_send_size(struct usb_se401 *se401, int width, int height)
+{
+	int i=0;
+	int mode=0x03; /* No compression */
+	int sendheight=height;
+	int sendwidth=width;
+
+	/* JangGu compression can only be used with the camera supported sizes,
+	   but bayer seems to work with any size that fits on the sensor.
+	   We check if we can use compression with the current size with either
+	   4 or 16 times subcapturing, if not we use uncompressed bayer data
+	   but this will result in cutouts of the maximum size....
+	 */
+	while (i<se401->sizes && !(se401->width[i]==width && se401->height[i]==height))
+		i++;
+	while (i<se401->sizes) {
+		if (se401->width[i]==width*2 && se401->height[i]==height*2) {
+			sendheight=se401->height[i];
+			sendwidth=se401->width[i];
+			mode=0x40;
+		}
+		if (se401->width[i]==width*4 && se401->height[i]==height*4) {
+			sendheight=se401->height[i];
+			sendwidth=se401->width[i];
+			mode=0x42;
+		}
+		i++;
+	}
+
+	se401_sndctrl(1, se401, SE401_REQ_SET_WIDTH, sendwidth, NULL, 0);
+	se401_sndctrl(1, se401, SE401_REQ_SET_HEIGHT, sendheight, NULL, 0);
+	se401_set_feature(se401, SE401_OPERATINGMODE, mode);
+
+	if (mode==0x03) {
+		se401->format=FMT_BAYER;
+	} else {
+		se401->format=FMT_JANGGU;
+	}
+
+	return;
+}
+
+/*
+	In this function se401_send_pict is called several times,
+	for some reason (depending on the state of the sensor and the phase of
+	the moon :) doing this only in either place doesn't always work...
+*/
+static int se401_start_stream(struct usb_se401 *se401)
+{
+	urb_t *urb;
+	int err=0, i;
+	se401->streaming=1;
+
+        se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
+        se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
+
+	/* Set picture settings */
+	se401_set_feature(se401, HV7131_REG_MODE_B, 0x05);/*windowed + pix intg */
+	se401_send_pict(se401);
+
+	se401_send_size(se401, se401->cwidth, se401->cheight);
+
+	se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE, 0, NULL, 0);
+
+	/* Do some memory allocation */
+	for (i=0; i<SE401_NUMFRAMES; i++) {
+		se401->frame[i].data=se401->fbuf + i * se401->maxframesize;
+		se401->frame[i].curpix=0;
+	}
+	for (i=0; i<SE401_NUMSBUF; i++) {
+		se401->sbuf[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
+	}
+
+	se401->bayeroffset=0;
+	se401->scratch_next=0;
+	se401->scratch_use=0;
+	se401->scratch_overflow=0;
+	for (i=0; i<SE401_NUMSCRATCH; i++) {
+		se401->scratch[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
+		se401->scratch[i].state=BUFFER_UNUSED;
+	}
+
+	for (i=0; i<SE401_NUMSBUF; i++) {
+		urb=usb_alloc_urb(0);
+		if(!urb)
+			return ENOMEM;
+
+		FILL_BULK_URB(urb, se401->dev,
+			usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT),
+			se401->sbuf[i].data, SE401_PACKETSIZE,
+			se401_video_irq,
+			se401);
+		urb->transfer_flags |= USB_QUEUE_BULK;
+
+		se401->urb[i]=urb;
+
+		err=usb_submit_urb(se401->urb[i]);
+		if(err)
+			err("urb burned down");
+	}
+
+	se401->framecount=0;
+
+	return 0;
+}
+
+static int se401_stop_stream(struct usb_se401 *se401)
+{
+	int i;
+
+	if (!se401->streaming || !se401->dev)
+		return 1;
+
+	se401->streaming=0;
+
+	se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0);
+
+	se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
+	se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
+
+	for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
+		se401->urb[i]->next=NULL;
+		usb_unlink_urb(se401->urb[i]);
+		usb_free_urb(se401->urb[i]);
+		se401->urb[i]=NULL;
+		kfree(se401->sbuf[i].data);
+	}
+	for (i=0; i<SE401_NUMSCRATCH; i++) {
+		kfree(se401->scratch[i].data);
+		se401->scratch[i].data=NULL;
+	}
+
+	return 0;
+}
+
+static int se401_set_size(struct usb_se401 *se401, int width, int height)
+{
+	int wasstreaming=se401->streaming;
+	/* Check to see if we need to change */
+	if (se401->cwidth==width && se401->cheight==height)
+		return 0;
+
+	/* Check for a valid mode */
+	if (!width || !height)
+		return 1;
+	if ((width & 1) || (height & 1))
+		return 1;
+	if (width>se401->width[se401->sizes-1])
+		return 1;
+	if (height>se401->height[se401->sizes-1])
+		return 1;
+
+	/* Stop a current stream and start it again at the new size */
+	if (wasstreaming)
+		se401_stop_stream(se401);
+	se401->cwidth=width;
+	se401->cheight=height;
+	if (wasstreaming)
+		se401_start_stream(se401);
+	return 0;
+}
+
+
+/****************************************************************************
+ *
+ * Video Decoding
+ *
+ ***************************************************************************/
+
+/*
+	This shouldn't really be done in a v4l driver....
+	But it does make the image look a lot more usable.
+	Basicly it lifts the dark pixels more than the light pixels.
+*/
+static inline void enhance_picture(unsigned char *frame, int len)
+{
+	while (len--) {
+		*frame++=(((*frame^255)*(*frame^255))/255)^255;
+	}
+}
+
+static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data)
+{
+	struct se401_frame *frame=&se401->frame[se401->curframe];
+	int linelength=se401->cwidth*3;
+
+	if (frame->curlinepix >= linelength) {
+		frame->curlinepix=0;
+		frame->curline+=linelength;
+	}
+
+	/* First three are absolute, all others relative.
+	 * Format is rgb from right to left (mirrorred image), 
+	 * we flip it to get bgr from left to right. */
+	if (frame->curlinepix < 3) {
+		*(frame->curline-frame->curlinepix)=1+data*4;
+	} else {
+		*(frame->curline-frame->curlinepix)=
+		    *(frame->curline-frame->curlinepix+3)+data*4;
+	}
+	frame->curlinepix++;
+}
+
+static inline void decode_JangGu_vlc (struct usb_se401 *se401, unsigned char *data, int bit_exp, int packetlength)
+{
+	int pos=0;
+	int vlc_cod=0;
+	int vlc_size=0;
+	int vlc_data=0;
+	int bit_cur;
+	int bit;
+	data+=4;
+	while (pos < packetlength) {
+		bit_cur=8;
+		while (bit_cur && bit_exp) {
+			bit=((*data)>>(bit_cur-1))&1;
+			if (!vlc_cod) {
+				if (bit) {
+					vlc_size++;
+				} else {
+					if (!vlc_size) {
+						decode_JangGu_integrate(se401, 0);
+					} else {
+						vlc_cod=2;
+						vlc_data=0;
+					}
+				}
+			} else {
+				if (vlc_cod==2) {
+					if (!bit) vlc_data=-(1<<vlc_size)+1;
+					vlc_cod--;
+				}
+				vlc_size--;
+				vlc_data+=bit<<vlc_size;
+				if (!vlc_size) {
+					decode_JangGu_integrate(se401, vlc_data);
+					vlc_cod=0;
+				}
+			}
+			bit_cur--;
+			bit_exp--;
+		}
+		pos++;
+		data++;
+	}
+}
+
+static inline void decode_JangGu (struct usb_se401 *se401, struct se401_scratch *buffer)
+{
+	unsigned char *data=buffer->data;
+	int len=buffer->length;
+	int bit_exp=0, pix_exp=0, frameinfo=0, packetlength=0, size;
+	int datapos=0;
+
+	/* New image? */
+	if (!se401->frame[se401->curframe].curpix) {
+		se401->frame[se401->curframe].curlinepix=0;
+		se401->frame[se401->curframe].curline=
+		    se401->frame[se401->curframe].data+
+		    se401->cwidth*3-1;
+		if (se401->frame[se401->curframe].grabstate==FRAME_READY)
+			se401->frame[se401->curframe].grabstate=FRAME_GRABBING;
+		se401->vlcdatapos=0;
+	}
+	while (datapos < len) {
+		size=1024-se401->vlcdatapos;
+		if (size+datapos > len)
+			size=len-datapos;
+		memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size);
+		se401->vlcdatapos+=size;
+		packetlength=0;
+		if (se401->vlcdatapos >= 4) {
+			bit_exp=se401->vlcdata[3]+(se401->vlcdata[2]<<8);
+			pix_exp=se401->vlcdata[1]+((se401->vlcdata[0]&0x3f)<<8);
+			frameinfo=se401->vlcdata[0]&0xc0;
+			packetlength=((bit_exp+47)>>4)<<1;
+			if (packetlength > 1024) {
+				se401->vlcdatapos=0;
+				datapos=len;
+				packetlength=0;
+				se401->error++;
+				se401->frame[se401->curframe].curpix=0;
+			}
+		}
+		if (packetlength && se401->vlcdatapos >= packetlength) {
+			decode_JangGu_vlc(se401, se401->vlcdata, bit_exp, packetlength);
+			se401->frame[se401->curframe].curpix+=pix_exp*3;
+			datapos+=size-(se401->vlcdatapos-packetlength);
+			se401->vlcdatapos=0;
+			if (se401->frame[se401->curframe].curpix>=se401->cwidth*se401->cheight*3) {
+				if (se401->frame[se401->curframe].curpix==se401->cwidth*se401->cheight*3) {
+					if (se401->frame[se401->curframe].grabstate==FRAME_GRABBING) {
+						se401->frame[se401->curframe].grabstate=FRAME_DONE;
+						se401->framecount++;
+						se401->readcount++;
+					}
+					if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) {
+						se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1);
+					}
+				} else {
+					se401->error++;
+				}
+				se401->frame[se401->curframe].curpix=0;
+				datapos=len;
+			}
+		} else {
+			datapos+=size;
+		}
+	}
+}
+
+static inline void decode_bayer (struct usb_se401 *se401, struct se401_scratch *buffer)
+{
+	unsigned char *data=buffer->data;
+	int len=buffer->length;
+	int offset=buffer->offset;
+	int datasize=se401->cwidth*se401->cheight;
+	struct se401_frame *frame=&se401->frame[se401->curframe];
+
+	unsigned char *framedata=frame->data, *curline, *nextline;
+	int width=se401->cwidth;
+	int blineoffset=0, bline;
+	int linelength=width*3, i;
+	
+
+	if (frame->curpix==0) {
+		if (frame->grabstate==FRAME_READY) {
+			frame->grabstate=FRAME_GRABBING;
+		}
+		frame->curline=framedata+linelength;
+		frame->curlinepix=0;
+	}
+
+	if (offset!=frame->curpix) {
+		/* Regard frame as lost :( */
+		frame->curpix=0;
+		se401->error++;
+		return;
+	}
+
+	/* Check if we have to much data */
+	if (frame->curpix+len > datasize) {
+		len=datasize-frame->curpix;
+	}
+	if (se401->cheight%4)
+		blineoffset=1;
+	bline=frame->curpix/se401->cwidth+blineoffset;
+
+	curline=frame->curline;
+	nextline=curline+linelength;
+	if (nextline >= framedata+datasize*3)
+		nextline=curline;
+	while (len) {
+		if (frame->curlinepix>=width) {
+			frame->curlinepix-=width;
+			bline=frame->curpix/width+blineoffset;
+			curline+=linelength*2;
+			nextline+=linelength*2;
+			if (curline >= framedata+datasize*3) {
+				frame->curlinepix++;
+				curline-=3;
+				nextline-=3;
+				len--;
+				data++;
+				frame->curpix++;
+			}
+			if (nextline >= framedata+datasize*3)
+				nextline=curline;
+		}
+		if ((bline&1)) {
+			if ((frame->curlinepix&1)) {
+				*(curline+2)=*data;
+				*(curline-1)=*data;
+				*(nextline+2)=*data;
+				*(nextline-1)=*data;
+			} else {
+				*(curline+1)=
+					(*(curline+1)+*data)/2;
+				*(curline-2)=
+					(*(curline-2)+*data)/2;
+				*(nextline+1)=*data;
+				*(nextline-2)=*data;
+			}
+		} else {
+			if ((frame->curlinepix&1)) {
+				*(curline+1)=
+					(*(curline+1)+*data)/2;
+				*(curline-2)=
+					(*(curline-2)+*data)/2;
+				*(nextline+1)=*data;
+				*(nextline-2)=*data;
+			} else {
+				*curline=*data;
+				*(curline-3)=*data;
+				*nextline=*data;
+				*(nextline-3)=*data;
+			}
+		}
+		frame->curlinepix++;
+		curline-=3;
+		nextline-=3;
+		len--;
+		data++;
+		frame->curpix++;
+	}
+	frame->curline=curline;
+
+	if (frame->curpix>=datasize) {
+		/* Fix the top line */
+		framedata+=linelength;
+		for (i=0; i<linelength; i++) {
+			*--framedata=*(framedata+linelength);
+		}
+		/* Fix the left side (green is already present) */
+		for (i=0; i<se401->cheight; i++) {
+			*framedata=*(framedata+3);
+			*(framedata+1)=*(framedata+4);
+			*(framedata+2)=*(framedata+5);
+			framedata+=linelength;
+		}
+		frame->curpix=0;
+		frame->grabstate=FRAME_DONE;
+		se401->framecount++;
+		se401->readcount++;
+		if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) {
+			se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1);
+		}
+	}
+}
+
+static int se401_newframe(struct usb_se401 *se401, int framenr)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int errors=0;
+
+	while (se401->streaming &&
+	    (se401->frame[framenr].grabstate==FRAME_READY ||
+	     se401->frame[framenr].grabstate==FRAME_GRABBING) ) {
+		if(!se401->frame[framenr].curpix) {
+			errors++;
+		}
+		wait_interruptible(
+		    se401->scratch[se401->scratch_use].state!=BUFFER_READY,
+		    &se401->wq,
+		    &wait
+		);
+		if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
+			se401->nullpackets=0;
+			info("to many null length packets, restarting capture");
+			se401_stop_stream(se401);
+			se401_start_stream(se401);			
+		} else {
+			if (se401->scratch[se401->scratch_use].state!=BUFFER_READY) {
+				se401->frame[framenr].grabstate=FRAME_ERROR;
+				return -EIO;
+			}
+			se401->scratch[se401->scratch_use].state=BUFFER_BUSY;
+			if (se401->format==FMT_JANGGU) {
+				decode_JangGu(se401, &se401->scratch[se401->scratch_use]);
+			} else {
+				decode_bayer(se401, &se401->scratch[se401->scratch_use]);
+			}
+			se401->scratch[se401->scratch_use].state=BUFFER_UNUSED;
+			se401->scratch_use++;
+			if (se401->scratch_use>=SE401_NUMSCRATCH)
+				se401->scratch_use=0;
+			if (errors > SE401_MAX_ERRORS) {
+				errors=0;
+				info("to much errors, restarting capture");
+				se401_stop_stream(se401);
+				se401_start_stream(se401);
+			}
+		}
+	}
+	
+	if (se401->frame[framenr].grabstate==FRAME_DONE) 
+		if (se401->enhance)
+			enhance_picture(se401->frame[framenr].data, se401->cheight*se401->cwidth*3);
+	return 0;
+}
+
+
+/****************************************************************************
+ *
+ * Video4Linux
+ *
+ ***************************************************************************/
+
+
+static int se401_open(struct video_device *dev, int flags)
+{
+	struct usb_se401 *se401 = (struct usb_se401 *)dev;
+	int err = 0;
+
+	MOD_INC_USE_COUNT;
+	down(&se401->lock);
+
+	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=1;
+
+	up(&se401->lock);
+	
+	return 0;
+}
+
+static void se401_close(struct video_device *dev)
+{
+        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)
+		se401_stop_stream(se401);
+
+	rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES);
+	se401->user=0;
+	up(&se401->lock);
+
+        if (!se401->dev) {
+                video_unregister_device(&se401->vdev);
+		kfree(se401->width);
+		kfree(se401->height);
+                kfree(se401);
+                se401 = NULL;
+		info("device unregistered");
+	}
+
+        MOD_DEC_USE_COUNT;
+}
+
+static int se401_init_done(struct video_device *dev)
+{
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
+        create_proc_se401_cam((struct usb_se401 *)dev);
+#endif
+
+        return 0;
+}
+
+static long se401_write(struct video_device *dev, const char *buf, unsigned long
+ count, int noblock)
+{
+        return -EINVAL;
+}
+
+static int se401_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
+{
+        struct usb_se401 *se401 = (struct usb_se401 *)vdev;
+
+        if (!se401->dev)
+                return -EIO;
+
+        switch (cmd) {
+	case VIDIOCGCAP:
+	{
+		struct video_capability b;
+		strcpy(b.name, se401->camera_name);
+		b.type = VID_TYPE_CAPTURE;
+		b.channels = 1;
+		b.audios = 0;
+		b.maxwidth = se401->width[se401->sizes-1];
+		b.maxheight = se401->height[se401->sizes-1];
+		b.minwidth = se401->width[0];
+		b.minheight = se401->height[0];
+
+		if (copy_to_user(arg, &b, sizeof(b)))
+			return -EFAULT;
+
+		return 0;
+	}
+	case VIDIOCGCHAN:
+	{
+		struct video_channel v;
+
+		if (copy_from_user(&v, arg, sizeof(v)))
+			return -EFAULT;
+		if (v.channel != 0)
+			return -EINVAL;
+
+		v.flags = 0;
+		v.tuners = 0;
+		v.type = VIDEO_TYPE_CAMERA;
+		strcpy(v.name, "Camera");
+
+		if (copy_to_user(arg, &v, sizeof(v)))
+			return -EFAULT;
+
+		return 0;
+	}
+	case VIDIOCSCHAN:
+	{
+		int v;
+
+		if (copy_from_user(&v, arg, sizeof(v)))
+			return -EFAULT;
+
+		if (v != 0)
+			return -EINVAL;
+
+		return 0;
+	}
+        case VIDIOCGPICT:
+        {
+		struct video_picture p;
+
+		se401_get_pict(se401, &p);
+
+		if (copy_to_user(arg, &p, sizeof(p)))
+			return -EFAULT;
+		return 0;
+	}
+	case VIDIOCSPICT:
+	{
+		struct video_picture p;
+
+		if (copy_from_user(&p, arg, sizeof(p)))
+			return -EFAULT;
+
+		if (se401_set_pict(se401, &p))
+			return -EINVAL;
+		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 (se401_set_size(se401, vw.width, vw.height))
+			return -EINVAL;
+		
+		return 0;
+        }
+	case VIDIOCGWIN:
+	{
+		struct video_window vw;
+
+		vw.x = 0;               /* FIXME */
+		vw.y = 0;
+		vw.chromakey = 0;
+		vw.flags = 0;
+		vw.clipcount = 0;
+		vw.width = se401->cwidth;
+		vw.height = se401->cheight;
+
+		if (copy_to_user(arg, &vw, sizeof(vw)))
+			return -EFAULT;
+
+		return 0;
+	}
+	case VIDIOCGMBUF:
+	{
+		struct video_mbuf vm;
+		int i;
+
+		memset(&vm, 0, sizeof(vm));
+		vm.size = SE401_NUMFRAMES * se401->maxframesize;
+		vm.frames = SE401_NUMFRAMES;
+		for (i=0; i<SE401_NUMFRAMES; i++)
+			vm.offsets[i] = se401->maxframesize * i;
+
+		if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
+		return -EFAULT;
+
+		return 0;
+	}
+	case VIDIOCMCAPTURE:
+	{
+		struct video_mmap vm;
+
+		if (copy_from_user(&vm, arg, sizeof(vm)))
+		return -EFAULT;
+		if (vm.format != VIDEO_PALETTE_RGB24)
+			return -EINVAL;
+		if (vm.frame >= SE401_NUMFRAMES)
+			return -EINVAL;
+		if (se401->frame[vm.frame].grabstate != FRAME_UNUSED)
+			return -EBUSY;
+
+		/* Is this according to the v4l spec??? */
+		if (se401_set_size(se401, vm.width, vm.height))
+			return -EINVAL;
+		se401->frame[vm.frame].grabstate=FRAME_READY;
+
+		if (!se401->streaming)
+			se401_start_stream(se401);
+
+		/* Set the picture properties */
+		if (se401->framecount==0)
+			se401_send_pict(se401);
+		/* Calibrate the reset level after a few frames. */
+		if (se401->framecount%20==1)
+			se401_auto_resetlevel(se401);
+
+		return 0;
+	}
+	case VIDIOCSYNC:
+	{
+		int frame, ret=0;
+
+		if (copy_from_user((void *)&frame, arg, sizeof(int)))
+			return -EFAULT;
+
+		ret=se401_newframe(se401, frame);
+		se401->frame[frame].grabstate=FRAME_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:
+		return -EINVAL;
+	case VIDIOCGTUNER:
+	case VIDIOCSTUNER:
+		return -EINVAL;
+	case VIDIOCGFREQ:
+	case VIDIOCSFREQ:
+		return -EINVAL;
+	case VIDIOCGAUDIO:
+	case VIDIOCSAUDIO:
+		return -EINVAL;
+        default:
+                return -ENOIOCTLCMD;
+        } /* end switch */
+
+        return 0;
+}
+
+static long se401_read(struct video_device *dev, char *buf, unsigned long count,
+ int noblock)
+{
+	int realcount=count, ret=0;
+	struct usb_se401 *se401 = (struct usb_se401 *)dev;
+
+
+	if (se401->dev == NULL)
+		return -EIO;
+	if (realcount > se401->cwidth*se401->cheight*3)
+		realcount=se401->cwidth*se401->cheight*3;
+
+	/* Shouldn't happen: */
+	if (se401->frame[0].grabstate==FRAME_GRABBING)
+		return -EBUSY;
+	se401->frame[0].grabstate=FRAME_READY;
+	se401->frame[1].grabstate=FRAME_UNUSED;
+	se401->curframe=0;
+
+	if (!se401->streaming)
+		se401_start_stream(se401);
+
+	/* Set the picture properties */
+	if (se401->framecount==0)
+		se401_send_pict(se401);
+	/* Calibrate the reset level after a few frames. */
+	if (se401->framecount%20==1)
+		se401_auto_resetlevel(se401);
+
+	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;
+
+	return realcount;
+}
+
+static int se401_mmap(struct video_device *dev, const char *adr,
+        unsigned long size)
+{
+	struct usb_se401 *se401 = (struct usb_se401 *)dev;
+	unsigned long start = (unsigned long)adr;
+	unsigned long page, pos;
+
+	down(&se401->lock);
+	
+	if (se401->dev == NULL) {
+		up(&se401->lock);
+		return -EIO;
+	}
+	if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) {
+		up(&se401->lock);
+		return -EINVAL;
+	}
+	pos = (unsigned long)se401->fbuf;
+	while (size > 0) {
+		page = kvirt_to_pa(pos);
+		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {
+			up(&se401->lock);
+			return -EAGAIN;
+		}
+		start += PAGE_SIZE;
+		pos += PAGE_SIZE;
+		if (size > PAGE_SIZE)
+			size -= PAGE_SIZE;
+		else
+			size = 0;
+	}
+	up(&se401->lock);
+
+        return 0;
+}
+
+static struct video_device se401_template = {
+        name:           "se401 USB camera",
+        type:           VID_TYPE_CAPTURE,
+        hardware:       VID_HARDWARE_SE401,
+        open:           se401_open,
+        close:          se401_close,
+        read:           se401_read,
+        write:          se401_write,
+        ioctl:          se401_ioctl,
+        mmap:           se401_mmap,
+        initialize:     se401_init_done,
+};
+
+
+
+/***************************/
+static int se401_init(struct usb_se401 *se401)
+{
+        int i=0, rc;
+        unsigned char cp[0x40];
+	char temp[200];
+
+	/* led on */
+        se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
+
+	/* get camera descriptor */
+	rc=se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0, cp, sizeof(cp));
+	if (cp[1]!=0x41) {
+		err("Wrong descriptor type");
+		return 1;
+	}
+	sprintf (temp, "ExtraFeatures: %d", cp[3]);
+
+	se401->sizes=cp[4]+cp[5]*256;
+	se401->width=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
+	se401->height=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
+	for (i=0; i<se401->sizes; i++) {
+		    se401->width[i]=cp[6+i*4+0]+cp[6+i*4+1]*256;
+		    se401->height[i]=cp[6+i*4+2]+cp[6+i*4+3]*256;
+	}
+	sprintf (temp, "%s Sizes:", temp);
+	for (i=0; i<se401->sizes; i++) {
+		sprintf(temp, "%s %dx%d", temp, se401->width[i], se401->height[i]);
+	}
+	info("%s", temp);
+	se401->maxframesize=se401->width[se401->sizes-1]*se401->height[se401->sizes-1]*3;
+
+	rc=se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp));
+	se401->cwidth=cp[0]+cp[1]*256;
+	rc=se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp));
+	se401->cheight=cp[0]+cp[1]*256;
+
+	if (!cp[2] && SE401_FORMAT_BAYER) {
+		err("Bayer format not supported!");
+		return 1;
+	}
+	/* set output mode (BAYER) */
+        se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE, SE401_FORMAT_BAYER, NULL, 0);
+
+	rc=se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp));
+	se401->brightness=cp[0]+cp[1]*256;
+	/* some default values */
+	se401->resetlevel=0x2d;
+	se401->rgain=0x20;
+	se401->ggain=0x20;
+	se401->bgain=0x20;
+	se401_set_exposure(se401, 20000);
+	se401->palette=VIDEO_PALETTE_RGB24;
+	se401->enhance=1;
+	se401->dropped=0;
+	se401->error=0;
+	se401->framecount=0;
+	se401->readcount=0;
+
+	/* Start interrupt transfers for snapshot button */
+	se401->inturb=usb_alloc_urb(0);
+	if (!se401->inturb) {
+		info("Allocation of inturb failed");
+		return 1;
+	}
+	FILL_INT_URB(se401->inturb, se401->dev,
+	    usb_rcvintpipe(se401->dev, SE401_BUTTON_ENDPOINT),
+	    &se401->button, sizeof(se401->button),
+	    se401_button_irq,
+	    se401,
+	    HZ/10
+	);
+	if (usb_submit_urb(se401->inturb)) {
+		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);
+        se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
+	se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
+
+        return 0;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
+static void* se401_probe(struct usb_device *dev, unsigned int ifnum)
+#else
+static void* __devinit se401_probe(struct usb_device *dev, unsigned int ifnum,
+	const struct usb_device_id *id)
+#endif
+{
+        struct usb_interface_descriptor *interface;
+        struct usb_se401 *se401;
+        char *camera_name=NULL;
+
+        /* We don't handle multi-config cameras */
+        if (dev->descriptor.bNumConfigurations != 1)
+                return NULL;
+
+        interface = &dev->actconfig->interface[ifnum].altsetting[0];
+
+        /* Is it an se401? */
+        if (dev->descriptor.idVendor == 0x03e8 &&
+            dev->descriptor.idProduct == 0x0004) {
+                camera_name="Endpoints/Aox SE401";
+        } else if (dev->descriptor.idVendor == 0x0471 &&
+            dev->descriptor.idProduct == 0x030b) {
+                camera_name="Philips PCVC665K";
+        } else if (dev->descriptor.idVendor == 0x047d &&
+	    dev->descriptor.idProduct == 0x5001) {
+		camera_name="Kensington VideoCAM 67014";
+        } else if (dev->descriptor.idVendor == 0x047d &&
+	    dev->descriptor.idProduct == 0x5002) {
+		camera_name="Kensington VideoCAM 6701(5/7)";
+        } else if (dev->descriptor.idVendor == 0x047d &&
+	    dev->descriptor.idProduct == 0x5003) {
+		camera_name="Kensington VideoCAM 67016";
+	} else
+		return NULL;
+
+        /* Checking vendor/product should be enough, but what the hell */
+        if (interface->bInterfaceClass != 0x00)
+                return NULL;
+        if (interface->bInterfaceSubClass != 0x00)
+                return NULL;
+
+        /* We found one */
+        info("SE401 camera found: %s", camera_name);
+
+        if ((se401 = kmalloc(sizeof(*se401), GFP_KERNEL)) == NULL) {
+                err("couldn't kmalloc se401 struct");
+                return NULL;
+        }
+
+        memset(se401, 0, sizeof(*se401));
+
+        se401->dev = dev;
+        se401->iface = interface->bInterfaceNumber;
+        se401->camera_name = camera_name;
+
+	info("firmware version: %02x", dev->descriptor.bcdDevice & 255);
+
+        if (se401_init(se401))
+		return NULL;
+	memcpy(&se401->vdev, &se401_template, sizeof(se401_template));
+	memcpy(se401->vdev.name, se401->camera_name, strlen(se401->camera_name));
+	if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
+		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;
+
+	/* We don't want people trying to open up the device */
+	if (!se401->user)
+              video_unregister_device(&se401->vdev);
+
+        usb_driver_release_interface(&se401_driver,
+                &se401->dev->actconfig->interface[se401->iface]);
+
+        se401->dev = NULL;
+        se401->frame[0].grabstate = FRAME_ERROR;
+        se401->frame[1].grabstate = FRAME_ERROR;
+
+	se401->streaming = 0;
+
+	if (waitqueue_active(&se401->wq))
+                wake_up_interruptible(&se401->wq);
+
+	for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
+		se401->urb[i]->next = NULL;
+		usb_unlink_urb(se401->urb[i]);
+		usb_free_urb(se401->urb[i]);
+		se401->urb[i] = NULL;
+		kfree(se401->sbuf[i].data);
+	}
+	for (i=0; i<SE401_NUMSCRATCH; i++) if (se401->scratch[i].data) {
+		kfree(se401->scratch[i].data);
+	}
+	if (se401->inturb) {
+		usb_unlink_urb(se401->inturb);
+		usb_free_urb(se401->inturb);
+	}
+        info("%s disconnected", se401->camera_name);
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
+	destroy_proc_se401_cam(se401);
+#endif
+
+        /* Free the memory */
+        if (!se401->user) {
+		kfree(se401->width);
+		kfree(se401->height);
+                kfree(se401);
+                se401 = NULL;
+        }
+}
+
+
+static struct usb_driver se401_driver = {
+        name:		"se401",
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 3, 0)
+        id_table:	device_table,
+#endif
+	probe:		se401_probe,
+        disconnect:	se401_disconnect
+};
+
+
+
+/****************************************************************************
+ *
+ *  Module routines
+ *
+ ***************************************************************************/
+
+static int __init usb_se401_init(void)
+{
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
+	proc_se401_create();
+#endif
+
+	info("SE401 usb camera driver version %s registering", version);
+	if (flickerless)
+		if (flickerless!=50 && flickerless!=60) {
+			info("Invallid flickerless value, use 0, 50 or 60.");
+			return -1;
+	}
+	if (usb_register(&se401_driver) < 0)
+		return -1;
+	return 0;
+}
+
+static void __exit usb_se401_exit(void)
+{
+	usb_deregister(&se401_driver);
+	info("SE401 driver deregistered");
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
+	proc_se401_destroy();
+#endif
+}
+
+module_init(usb_se401_init);
+module_exit(usb_se401_exit);
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/se401.h linux/drivers/usb/se401.h
--- v2.4.5/linux/drivers/usb/se401.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/se401.h	Wed Jun 27 13:59:32 2001
@@ -0,0 +1,234 @@
+
+#ifndef __LINUX_se401_H
+#define __LINUX_se401_H
+
+#include <asm/uaccess.h>
+#include <linux/videodev.h>
+#include <linux/smp_lock.h>
+
+#define se401_DEBUG	/* Turn on debug messages */
+
+#ifdef se401_DEBUG
+#  define PDEBUG(level, fmt, args...) \
+if (debug >= level) info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , ## args)
+#else
+#  define PDEBUG(level, fmt, args...) do {} while(0)
+#endif
+
+/* An almost drop-in replacement for sleep_on_interruptible */
+#define wait_interruptible(test, queue, wait) \
+{ \
+	add_wait_queue(queue, wait); \
+	set_current_state(TASK_INTERRUPTIBLE); \
+	if (test) \
+		schedule(); \
+	remove_wait_queue(queue, wait); \
+	set_current_state(TASK_RUNNING); \
+	if (signal_pending(current)) \
+		break; \
+}
+
+#define SE401_REQ_GET_CAMERA_DESCRIPTOR		0x06
+#define SE401_REQ_START_CONTINUOUS_CAPTURE	0x41
+#define SE401_REQ_STOP_CONTINUOUS_CAPTURE	0x42
+#define SE401_REQ_CAPTURE_FRAME			0x43
+#define SE401_REQ_GET_BRT			0x44
+#define SE401_REQ_SET_BRT			0x45
+#define SE401_REQ_GET_WIDTH			0x4c
+#define SE401_REQ_SET_WIDTH			0x4d
+#define SE401_REQ_GET_HEIGHT			0x4e
+#define SE401_REQ_SET_HEIGHT			0x4f
+#define SE401_REQ_GET_OUTPUT_MODE		0x50
+#define SE401_REQ_SET_OUTPUT_MODE		0x51
+#define SE401_REQ_GET_EXT_FEATURE		0x52
+#define SE401_REQ_SET_EXT_FEATURE		0x53
+#define SE401_REQ_CAMERA_POWER			0x56
+#define SE401_REQ_LED_CONTROL			0x57
+#define SE401_REQ_BIOS				0xff
+
+#define SE401_BIOS_READ				0x07
+
+#define SE401_FORMAT_BAYER	0x40
+
+/* Hyundai hv7131b registers
+   7121 and 7141 should be the same (haven't really checked...) */
+/* Mode registers: */
+#define HV7131_REG_MODE_A		0x00
+#define HV7131_REG_MODE_B		0x01
+#define HV7131_REG_MODE_C		0x02
+/* Frame registers: */
+#define HV7131_REG_FRSU		0x10
+#define HV7131_REG_FRSL		0x11
+#define HV7131_REG_FCSU		0x12
+#define HV7131_REG_FCSL		0x13
+#define HV7131_REG_FWHU		0x14
+#define HV7131_REG_FWHL		0x15
+#define HV7131_REG_FWWU		0x16
+#define HV7131_REG_FWWL		0x17
+/* Timing registers: */
+#define HV7131_REG_THBU		0x20
+#define HV7131_REG_THBL		0x21
+#define HV7131_REG_TVBU		0x22
+#define HV7131_REG_TVBL		0x23
+#define HV7131_REG_TITU		0x25
+#define HV7131_REG_TITM		0x26
+#define HV7131_REG_TITL		0x27
+#define HV7131_REG_TMCD		0x28
+/* Adjust Registers: */
+#define HV7131_REG_ARLV		0x30
+#define HV7131_REG_ARCG		0x31
+#define HV7131_REG_AGCG		0x32
+#define HV7131_REG_ABCG		0x33
+#define HV7131_REG_APBV		0x34
+#define HV7131_REG_ASLP		0x54
+/* Offset Registers: */
+#define HV7131_REG_OFSR		0x50
+#define HV7131_REG_OFSG		0x51
+#define HV7131_REG_OFSB		0x52
+/* REset level statistics registers: */
+#define HV7131_REG_LOREFNOH	0x57
+#define HV7131_REG_LOREFNOL	0x58
+#define HV7131_REG_HIREFNOH	0x59
+#define HV7131_REG_HIREFNOL	0x5a
+
+/* se401 registers */
+#define SE401_OPERATINGMODE	0x2000
+
+
+/* size of usb transfers */
+#define SE401_PACKETSIZE	4096
+/* number of queued bulk transfers to use, should be about 8 */
+#define SE401_NUMSBUF		1
+/* read the usb specs for this one :) */
+#define SE401_VIDEO_ENDPOINT	1
+#define SE401_BUTTON_ENDPOINT	2
+/* number of frames supported by the v4l part */
+#define SE401_NUMFRAMES		2
+/* scratch buffers for passing data to the decoders */
+#define SE401_NUMSCRATCH	32
+/* maximum amount of data in a JangGu packet */
+#define SE401_VLCDATALEN	1024
+/* number of nul sized packets to receive before kicking the camera */
+#define SE401_MAX_NULLPACKETS	4000
+/* number of decoding errors before kicking the camera */
+#define SE401_MAX_ERRORS	200
+
+struct usb_device;
+
+struct se401_sbuf {
+	unsigned char *data;
+};
+
+enum {
+	FRAME_UNUSED,		/* Unused (no MCAPTURE) */
+	FRAME_READY,		/* Ready to start grabbing */
+	FRAME_GRABBING,		/* In the process of being grabbed into */
+	FRAME_DONE,		/* Finished grabbing, but not been synced yet */
+	FRAME_ERROR,		/* Something bad happened while processing */
+};
+
+enum {
+	FMT_BAYER,
+	FMT_JANGGU,
+};
+
+enum {
+	BUFFER_UNUSED,
+	BUFFER_READY,
+	BUFFER_BUSY,
+	BUFFER_DONE,
+};
+
+struct se401_scratch {
+	unsigned char *data;
+	volatile int state;
+	int offset;
+	int length;
+};
+
+struct se401_frame {
+	unsigned char *data;		/* Frame buffer */
+
+	volatile int grabstate;	/* State of grabbing */
+
+	unsigned char *curline;
+	int curlinepix;
+	int curpix;
+};
+
+struct usb_se401 {
+	struct video_device vdev;
+
+	/* Device structure */
+	struct usb_device *dev;
+
+	unsigned char iface;
+
+	char *camera_name;
+
+	int change;
+	int brightness;
+	int hue;
+	int rgain;
+	int ggain;
+	int bgain;
+	int expose_h;
+	int expose_m;
+	int expose_l;
+	int resetlevel;
+	
+	int enhance;
+
+	int format;
+	int sizes;
+	int *width;
+	int *height;
+	int cwidth;		/* current width */
+	int cheight;		/* current height */
+	int palette;
+	int maxframesize;
+	int cframesize;		/* current framesize */
+
+	struct semaphore lock;
+	int user;		/* user count for exclusive use */
+
+	int streaming;		/* Are we streaming video? */
+
+	char *fbuf;		/* Videodev buffer area */
+
+	urb_t *urb[SE401_NUMSBUF];
+	urb_t *inturb;
+	
+	int button;
+	int buttonpressed;
+
+	int curframe;		/* Current receiving frame */
+	struct se401_frame frame[SE401_NUMFRAMES];	
+	int readcount;
+	int framecount;
+	int error;
+	int dropped;
+
+	int scratch_next;
+	int scratch_use;
+	int scratch_overflow;
+	struct se401_scratch scratch[SE401_NUMSCRATCH];
+
+	/* Decoder specific data: */
+	unsigned char vlcdata[SE401_VLCDATALEN];
+	int vlcdatapos;
+	int bayeroffset;
+
+	struct se401_sbuf sbuf[SE401_NUMSBUF];
+
+	wait_queue_head_t wq;	/* Processes waiting */
+
+	/* proc interface */
+	struct proc_dir_entry *proc_entry;	/* /proc/se401/videoX */
+
+	int nullpackets;
+};
+
+
+#endif
+
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/Config.in linux/drivers/usb/serial/Config.in
--- v2.4.5/linux/drivers/usb/serial/Config.in	Fri Apr  6 15:51:50 2001
+++ linux/drivers/usb/serial/Config.in	Wed Jun 27 13:59:32 2001
@@ -28,6 +28,8 @@
      bool '    USB Keyspan USA-49W Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA49W
   fi
   dep_tristate '  USB MCT Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_MCT_U232 $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+  dep_tristate '  USB Prolific 2303 Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_PL2303 $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+  dep_tristate '  USB REINER SCT cyberJack pinpad/e-com chipcard reader (EXPERIMENTAL)' CONFIG_USB_SERIAL_CYBERJACK $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
   dep_tristate '  USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_OMNINET $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
 fi
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/Makefile linux/drivers/usb/serial/Makefile
--- v2.4.5/linux/drivers/usb/serial/Makefile	Mon Mar 19 17:21:54 2001
+++ linux/drivers/usb/serial/Makefile	Wed Jun 27 13:59:32 2001
@@ -18,6 +18,8 @@
 obj-$(CONFIG_USB_SERIAL_EMPEG)			+= empeg.o
 obj-$(CONFIG_USB_SERIAL_MCT_U232)		+= mct_u232.o
 obj-$(CONFIG_USB_SERIAL_EDGEPORT)		+= io_edgeport.o
+obj-$(CONFIG_USB_SERIAL_PL2303)			+= pl2303.o
+obj-$(CONFIG_USB_SERIAL_CYBERJACK)		+= cyberjack.o
  
 # Objects that export symbols.
 export-objs	:= usbserial.o
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/belkin_sa.c linux/drivers/usb/serial/belkin_sa.c
--- v2.4.5/linux/drivers/usb/serial/belkin_sa.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/serial/belkin_sa.c	Wed Jun 20 16:52:30 2001
@@ -24,6 +24,9 @@
  * -- Add support for flush commands
  * -- Add everything that is missing :)
  * 
+ * (30-May-2001 gkh
+ *	switched from using spinlock to a semaphore, which fixes lots of problems.
+ *
  * 08-Apr-2001 gb
  *	- Identify version on module load.
  *
@@ -85,7 +88,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.0.0"
+#define DRIVER_VERSION "v1.1"
 #define DRIVER_AUTHOR "William Greathouse <wgreathouse@smva.com>"
 #define DRIVER_DESC "USB Belkin Serial converter driver"
 
@@ -282,11 +285,11 @@
 
 static int  belkin_sa_open (struct usb_serial_port *port, struct file *filp)
 {
-	unsigned long flags;
+	int retval = 0;
 
 	dbg(__FUNCTION__" port %d", port->number);
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 	
 	++port->open_count;
 	MOD_INC_USE_COUNT;
@@ -299,30 +302,32 @@
 		 *       enhance buffering.  Win trace shows 16 initial read URBs.
 		 */
 		port->read_urb->dev = port->serial->dev;
-		if (usb_submit_urb(port->read_urb))
+		retval = usb_submit_urb(port->read_urb);
+		if (retval) {
 			err("usb_submit_urb(read bulk) failed");
+			goto exit;
+		}
 
 		port->interrupt_in_urb->dev = port->serial->dev;
-		if (usb_submit_urb(port->interrupt_in_urb))
+		retval = usb_submit_urb(port->interrupt_in_urb);
+		if (retval)
 			err(" usb_submit_urb(read int) failed");
 	}
 	
-	spin_unlock_irqrestore (&port->port_lock, flags);
+exit:
+	up (&port->sem);
 
-	return 0;
+	return retval;
 } /* belkin_sa_open */
 
 
 static void belkin_sa_close (struct usb_serial_port *port, struct file *filp)
 {
-	unsigned long flags;
-
 	dbg(__FUNCTION__" port %d", port->number);
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 
 	--port->open_count;
-	MOD_DEC_USE_COUNT;
 
 	if (port->open_count <= 0) {
 		/* shutdown our bulk reads and writes */
@@ -332,7 +337,8 @@
 		port->active = 0;
 	}
 	
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	up (&port->sem);
+	MOD_DEC_USE_COUNT;
 } /* belkin_sa_close */
 
 
@@ -600,8 +606,7 @@
 	usb_serial_register (&belkin_old_device);
 	usb_serial_register (&peracom_device);
 	usb_serial_register (&gocom232_device);
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/cyberjack.c linux/drivers/usb/serial/cyberjack.c
--- v2.4.5/linux/drivers/usb/serial/cyberjack.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/serial/cyberjack.c	Wed Jun 27 13:59:32 2001
@@ -0,0 +1,520 @@
+/*
+ *  REINER SCT cyberJack pinpad/e-com USB Chipcard Reader Driver
+ *
+ *  Copyright (C) 2001  REINER SCT
+ *  Author: Matthias Bruestle
+ *
+ *  Contact: linux-usb@sii.li (see MAINTAINERS)
+ *
+ *  This program is largely derived from work by the linux-usb group
+ *  and associated source files.  Please see the usb/serial files for
+ *  individual credits and copyrights.
+ *
+ *  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.
+ *
+ *  Thanks to Greg Kroah-Hartman (greg@kroah.com) for his help and
+ *  patience.
+ *
+ *  In case of problems, please write to the contact e-mail address
+ *  mentioned above.
+ */
+
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/fcntl.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+
+#ifdef CONFIG_USB_SERIAL_DEBUG
+	static int debug = 1;
+#else
+	static int debug;
+#endif
+
+#include "usb-serial.h"
+
+/*
+ * Version Information
+ */
+#define DRIVER_VERSION "v1.0"
+#define DRIVER_AUTHOR "Matthias Bruestle"
+#define DRIVER_DESC "REINER SCT cyberJack pinpad/e-com USB Chipcard Reader Driver"
+
+
+#define CYBERJACK_VENDOR_ID	0x0C4B
+#define CYBERJACK_PRODUCT_ID	0x0100
+
+/* Function prototypes */
+static int cyberjack_startup (struct usb_serial *serial);
+static void cyberjack_shutdown (struct usb_serial *serial);
+static int  cyberjack_open (struct usb_serial_port *port, struct file *filp);
+static void cyberjack_close (struct usb_serial_port *port, struct file *filp);
+static int cyberjack_write (struct usb_serial_port *port, int from_user,
+	const unsigned char *buf, int count);
+static void cyberjack_read_int_callback( struct urb *urb );
+static void cyberjack_read_bulk_callback (struct urb *urb);
+static void cyberjack_write_bulk_callback (struct urb *urb);
+
+static __devinitdata struct usb_device_id id_table [] = {
+	{ USB_DEVICE(CYBERJACK_VENDOR_ID, CYBERJACK_PRODUCT_ID) },
+	{ }			/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE (usb, id_table);
+
+struct usb_serial_device_type cyberjack_device = {
+	name:			"Reiner SCT Cyberjack USB card reader",
+	id_table:		id_table,
+	needs_interrupt_in:	MUST_HAVE,
+	needs_bulk_in:		MUST_HAVE,
+	needs_bulk_out:		MUST_HAVE,
+	num_interrupt_in:	1,
+	num_bulk_in:		1,
+	num_bulk_out:		1,
+	num_ports:		1,
+	startup:		cyberjack_startup,
+	shutdown:		cyberjack_shutdown,
+	open:			cyberjack_open,
+	close:			cyberjack_close,
+	write:			cyberjack_write,
+	read_int_callback:	cyberjack_read_int_callback,
+	read_bulk_callback:	cyberjack_read_bulk_callback,
+	write_bulk_callback:	cyberjack_write_bulk_callback,
+};
+
+struct cyberjack_private {
+	short	rdtodo;		/* Bytes still to read */
+	unsigned char	wrbuf[5*64];	/* Buffer for collecting data to write */
+	short	wrfilled;	/* Overall data size we already got */
+	short	wrsent;		/* Data akready sent */
+};
+
+/* do some startup allocations not currently performed by usb_serial_probe() */
+static int cyberjack_startup (struct usb_serial *serial)
+{
+	struct cyberjack_private *priv;
+
+	dbg (__FUNCTION__);
+
+	/* allocate the private data structure */
+	serial->port->private = kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL);
+	if (!serial->port->private)
+		return (-1); /* error */
+
+	/* set initial values */
+	priv = (struct cyberjack_private *)serial->port->private;
+	priv->rdtodo = 0;
+	priv->wrfilled = 0;
+	priv->wrsent = 0;
+
+	init_waitqueue_head(&serial->port->write_wait);
+
+	return( 0 );
+}
+
+static void cyberjack_shutdown (struct usb_serial *serial)
+{
+	int i;
+	
+	dbg (__FUNCTION__);
+
+	/* stop reads and writes on all ports */
+	for (i=0; i < serial->num_ports; ++i) {
+		while (serial->port[i].open_count > 0) {
+			cyberjack_close (&serial->port[i], NULL);
+		}
+		/* My special items, the standard routines free my urbs */
+		if (serial->port[i].private)
+			kfree(serial->port[i].private);
+	}
+}
+	
+static int  cyberjack_open (struct usb_serial_port *port, struct file *filp)
+{
+	struct cyberjack_private *priv;
+	int result = 0;
+
+	if (port_paranoia_check (port, __FUNCTION__))
+		return -ENODEV;
+
+	MOD_INC_USE_COUNT;
+
+	dbg(__FUNCTION__ " - port %d", port->number);
+
+	down (&port->sem);
+
+	++port->open_count;
+
+	if (!port->active) {
+		port->active = 1;
+		/* force low_latency on so that our tty_push actually forces
+		 * the data through, otherwise it is scheduled, and with high
+		 * data rates (like with OHCI) data can get lost.
+		 */
+		port->tty->low_latency = 1;
+
+		priv = (struct cyberjack_private *)port->private;
+		priv->rdtodo = 0;
+		priv->wrfilled = 0;
+		priv->wrsent = 0;
+
+		/* shutdown any bulk reads that might be going on */
+		usb_unlink_urb (port->write_urb);
+		usb_unlink_urb (port->read_urb);
+		usb_unlink_urb (port->interrupt_in_urb);
+
+		port->interrupt_in_urb->dev = port->serial->dev;
+		result = usb_submit_urb(port->interrupt_in_urb);
+		if (result)
+			err(" usb_submit_urb(read int) failed");
+		dbg(__FUNCTION__ " - usb_submit_urb(int urb)");
+	}
+
+	up (&port->sem);
+
+	return result;
+}
+
+static void cyberjack_close (struct usb_serial_port *port, struct file *filp)
+{
+	dbg(__FUNCTION__ " - port %d", port->number);
+
+	down (&port->sem);
+
+	--port->open_count;
+
+	if (port->open_count <= 0) {
+		/* shutdown any bulk reads that might be going on */
+		usb_unlink_urb (port->write_urb);
+		usb_unlink_urb (port->read_urb);
+		usb_unlink_urb (port->interrupt_in_urb);
+
+		port->active = 0;
+		port->open_count = 0;
+	}
+
+	up (&port->sem);
+	MOD_DEC_USE_COUNT;
+}
+
+static int cyberjack_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
+{
+	struct usb_serial *serial = port->serial;
+	struct cyberjack_private *priv = (struct cyberjack_private *)port->private;
+	int result;
+	int wrexpected;
+
+	dbg(__FUNCTION__ " - port %d", port->number);
+	dbg(__FUNCTION__ " - from_user %d", from_user);
+
+	if (count == 0) {
+		dbg(__FUNCTION__ " - write request of 0 bytes");
+		return (0);
+	}
+
+	if (port->write_urb->status == -EINPROGRESS) {
+		dbg (__FUNCTION__ " - already writing");
+		return (0);
+	}
+
+	down (&port->sem);
+
+	if( (count+priv->wrfilled)>sizeof(priv->wrbuf) ) {
+		/* To much data  for buffer. Reset buffer. */
+		priv->wrfilled=0;
+		return (0);
+	}
+
+	/* Copy data */
+	if (from_user) {
+		copy_from_user(priv->wrbuf+priv->wrfilled, buf, count);
+	} else {
+		memcpy (priv->wrbuf+priv->wrfilled, buf, count);
+	}  
+	usb_serial_debug_data (__FILE__, __FUNCTION__, count,
+		priv->wrbuf+priv->wrfilled);
+	priv->wrfilled += count;
+
+	if( priv->wrfilled >= 3 ) {
+		wrexpected = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
+		dbg(__FUNCTION__ " - expected data: %d", wrexpected);
+	} else {
+		wrexpected = sizeof(priv->wrbuf);
+	}
+
+	if( priv->wrfilled >= wrexpected ) {
+		/* We have enough data to begin transmission */
+		int length;
+
+		dbg(__FUNCTION__ " - transmitting data (frame 1)");
+		length = (wrexpected > port->bulk_out_size) ? port->bulk_out_size : wrexpected;
+
+		memcpy (port->write_urb->transfer_buffer, priv->wrbuf, length );
+		priv->wrsent=length;
+
+		/* set up our urb */
+		FILL_BULK_URB(port->write_urb, serial->dev, 
+			      usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
+			      port->write_urb->transfer_buffer, length,
+			      ((serial->type->write_bulk_callback) ? 
+			       serial->type->write_bulk_callback : 
+			       cyberjack_write_bulk_callback), 
+			      port);
+
+		/* send the data out the bulk port */
+		result = usb_submit_urb(port->write_urb);
+		if (result) {
+			err(__FUNCTION__ " - failed submitting write urb, error %d", result);
+			/* Throw away data. No better idea what to do with it. */
+			priv->wrfilled=0;
+			priv->wrsent=0;
+			up (&port->sem);
+			return 0;
+		}
+
+		dbg(__FUNCTION__ " - priv->wrsent=%d",priv->wrsent);
+		dbg(__FUNCTION__ " - priv->wrfilled=%d",priv->wrfilled);
+
+		if( priv->wrsent>=priv->wrfilled ) {
+			dbg(__FUNCTION__ " - buffer cleaned");
+			memset( priv->wrbuf, 0, sizeof(priv->wrbuf) );
+			priv->wrfilled=0;
+			priv->wrsent=0;
+		}
+	}
+
+	up (&port->sem);
+	return (count);
+} 
+
+static void cyberjack_read_int_callback( struct urb *urb )
+{
+	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+	struct cyberjack_private *priv = (struct cyberjack_private *)port->private;
+	struct usb_serial *serial;
+	unsigned char *data = urb->transfer_buffer;
+
+	dbg(__FUNCTION__ " - port %d", port->number);
+
+	/* the urb might have been killed. */
+	if (urb->status)
+		return;
+
+	if (port_paranoia_check (port, "cyberjack_read_interrupt")) return;
+
+	serial = port->serial;
+	if (serial_paranoia_check (serial, "cyberjack_read_interrupt")) return;
+
+	usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
+
+	/* React only to interrupts signaling a bulk_in transfer */
+	if( (urb->actual_length==4) && (data[0]==0x01) ) {
+		short old_rdtodo = priv->rdtodo;
+		int result;
+
+		/* This is a announcement of comming bulk_ins. */
+		unsigned short size = ((unsigned short)data[3]<<8)+data[2]+3;
+
+		if( (size>259) || (size==0) ) {
+			dbg( "Bad announced bulk_in data length: %d", size );
+			/* Dunno what is most reliable to do here. */
+			/* return; */
+		}
+
+		if( (old_rdtodo+size)<(old_rdtodo) ) {
+			dbg( "To many bulk_in urbs to do." );
+			return;
+		}
+
+		/* "+=" is probably more fault tollerant than "=" */
+		priv->rdtodo += size;
+
+		dbg(__FUNCTION__ " - rdtodo: %d", priv->rdtodo);
+
+		if( !old_rdtodo ) {
+			port->read_urb->dev = port->serial->dev;
+			result = usb_submit_urb(port->read_urb);
+			if( result )
+				err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
+			dbg(__FUNCTION__ " - usb_submit_urb(read urb)");
+		}
+	}
+}
+
+static void cyberjack_read_bulk_callback (struct urb *urb)
+{
+	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+	struct cyberjack_private *priv = (struct cyberjack_private *)port->private;
+	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
+	struct tty_struct *tty;
+	unsigned char *data = urb->transfer_buffer;
+	int i;
+	int result;
+
+	dbg(__FUNCTION__ " - port %d", port->number);
+	
+	if (!serial) {
+		dbg(__FUNCTION__ " - bad serial pointer, exiting");
+		return;
+	}
+
+	if (urb->status) {
+		usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, urb->transfer_buffer);
+		dbg(__FUNCTION__ " - nonzero read bulk status received: %d", urb->status);
+		return;
+	}
+
+	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 we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
+			if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
+				tty_flip_buffer_push(tty);
+			}
+			/* this doesn't actually push the data through unless tty->low_latency is set */
+			tty_insert_flip_char(tty, data[i], 0);
+		}
+	  	tty_flip_buffer_push(tty);
+	}
+
+	/* Reduce urbs to do by one. */
+	priv->rdtodo-=urb->actual_length;
+	/* Just to be sure */
+	if( priv->rdtodo<0 ) priv->rdtodo=0;
+
+	dbg(__FUNCTION__ " - rdtodo: %d", priv->rdtodo);
+
+	/* Continue to read if we have still urbs to do. */
+	if( priv->rdtodo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/ ) {
+		port->read_urb->dev = port->serial->dev;
+		result = usb_submit_urb(port->read_urb);
+		if (result)
+			err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
+		dbg(__FUNCTION__ " - usb_submit_urb(read urb)");
+	}
+}
+
+static void cyberjack_write_bulk_callback (struct urb *urb)
+{
+	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+	struct cyberjack_private *priv = (struct cyberjack_private *)port->private;
+	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
+
+	dbg(__FUNCTION__ " - port %d", port->number);
+	
+	if (!serial) {
+		dbg(__FUNCTION__ " - bad serial pointer, exiting");
+		return;
+	}
+
+	if (urb->status) {
+		dbg(__FUNCTION__ " - nonzero write bulk status received: %d", urb->status);
+		return;
+	}
+
+	/* only do something if we have more data to send */
+	if( priv->wrfilled ) {
+		int length, blksize, result;
+
+		if (port->write_urb->status == -EINPROGRESS) {
+			dbg (__FUNCTION__ " - already writing");
+			return;
+		}
+
+		down (&port->sem);
+
+		dbg(__FUNCTION__ " - transmitting data (frame n)");
+
+		length = ((priv->wrfilled - priv->wrsent) > port->bulk_out_size) ?
+			port->bulk_out_size : (priv->wrfilled - priv->wrsent);
+
+		memcpy (port->write_urb->transfer_buffer, priv->wrbuf + priv->wrsent,
+			length );
+		priv->wrsent+=length;
+
+		/* set up our urb */
+		FILL_BULK_URB(port->write_urb, serial->dev, 
+			      usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
+			      port->write_urb->transfer_buffer, length,
+			      ((serial->type->write_bulk_callback) ? 
+			       serial->type->write_bulk_callback : 
+			       cyberjack_write_bulk_callback), 
+			      port);
+
+		/* send the data out the bulk port */
+		result = usb_submit_urb(port->write_urb);
+		if (result) {
+			err(__FUNCTION__ " - failed submitting write urb, error %d", result);
+			/* Throw away data. No better idea what to do with it. */
+			priv->wrfilled=0;
+			priv->wrsent=0;
+			up (&port->sem);
+			queue_task(&port->tqueue, &tq_immediate);
+			mark_bh(IMMEDIATE_BH);
+			return;
+		}
+
+		dbg(__FUNCTION__ " - priv->wrsent=%d",priv->wrsent);
+		dbg(__FUNCTION__ " - priv->wrfilled=%d",priv->wrfilled);
+
+		blksize = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
+
+		if( (priv->wrsent>=priv->wrfilled) || (priv->wrsent>=blksize) ) {
+			dbg(__FUNCTION__ " - buffer cleaned");
+			memset( priv->wrbuf, 0, sizeof(priv->wrbuf) );
+			priv->wrfilled=0;
+			priv->wrsent=0;
+		}
+
+		up (&port->sem);
+		queue_task(&port->tqueue, &tq_immediate);
+		mark_bh(IMMEDIATE_BH);
+		return;
+	}
+
+	queue_task(&port->tqueue, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
+	
+	return;
+}
+
+static int __init cyberjack_init (void)
+{
+	usb_serial_register (&cyberjack_device);
+
+	info(DRIVER_VERSION " " DRIVER_AUTHOR);
+	info(DRIVER_DESC);
+
+	return 0;
+}
+
+static void __exit cyberjack_exit (void)
+{
+	usb_serial_deregister (&cyberjack_device);
+}
+
+module_init(cyberjack_init);
+module_exit(cyberjack_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/digi_acceleport.c linux/drivers/usb/serial/digi_acceleport.c
--- v2.4.5/linux/drivers/usb/serial/digi_acceleport.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/serial/digi_acceleport.c	Tue Jun 12 15:53:37 2001
@@ -2078,8 +2078,7 @@
 {
 	usb_serial_register (&digi_acceleport_2_device);
 	usb_serial_register (&digi_acceleport_4_device);
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/empeg.c linux/drivers/usb/serial/empeg.c
--- v2.4.5/linux/drivers/usb/serial/empeg.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/serial/empeg.c	Wed Jun 20 16:52:30 2001
@@ -1,10 +1,10 @@
 /*
  * USB Empeg empeg-car player driver
  *
- *	Copyright (C) 2000
+ *	Copyright (C) 2000, 2001
  *	    Gary Brubaker (xavyer@ix.netcom.com)
  *
- *	Copyright (C) 1999, 2000
+ *	Copyright (C) 1999 - 2001
  *	    Greg Kroah-Hartman (greg@kroah.com)
  *
  *	This program is free software; you can redistribute it and/or modify
@@ -13,6 +13,9 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  * 
+ * (05/30/2001) gkh
+ *	switched from using spinlock to a semaphore, which fixes lots of problems.
+ *
  * (04/08/2001) gb
  *      Identify version on module load.
  * 
@@ -71,7 +74,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.0.0"
+#define DRIVER_VERSION "v1.1"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Gary Brubaker <xavyer@ix.netcom.com>"
 #define DRIVER_DESC "USB Empeg Mark I/II Driver"
 
@@ -147,15 +150,14 @@
 static int empeg_open (struct usb_serial_port *port, struct file *filp)
 {
 	struct usb_serial *serial = port->serial;
-	unsigned long flags;
-	int result;
+	int result = 0;;
 
 	if (port_paranoia_check (port, __FUNCTION__))
 		return -ENODEV;
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 
 	++port->open_count;
 	MOD_INC_USE_COUNT;
@@ -236,9 +238,9 @@
 
 	}
 
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	up (&port->sem);
 
-	return 0;
+	return result;
 }
 
 
@@ -246,7 +248,6 @@
 {
 	struct usb_serial *serial;
 	unsigned char *transfer_buffer;
-	unsigned long flags;
 
 	if (port_paranoia_check (port, __FUNCTION__))
 		return;
@@ -257,7 +258,7 @@
 	if (!serial)
 		return;
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 
 	--port->open_count;
 
@@ -276,13 +277,12 @@
 		port->open_count = 0;
 	}
 
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	up (&port->sem);
 
 	/* Uncomment the following line if you want to see some statistics in your syslog */
 	/* info ("Bytes In = %d  Bytes Out = %d", bytes_in, bytes_out); */
 
 	MOD_DEC_USE_COUNT;
-
 }
 
 
@@ -377,7 +377,7 @@
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	spin_lock_irqsave (&write_urb_pool_lock, flags);
 
 	/* tally up the number of bytes available */
 	for (i = 0; i < NUM_URBS; ++i) {
@@ -386,7 +386,7 @@
 		}
 	} 
 
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	spin_unlock_irqrestore (&write_urb_pool_lock, flags);
 
 	dbg(__FUNCTION__ " - returns %d", room);
 
@@ -403,7 +403,7 @@
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	spin_lock_irqsave (&write_urb_pool_lock, flags);
 
 	/* tally up the number of bytes waiting */
 	for (i = 0; i < NUM_URBS; ++i) {
@@ -412,7 +412,7 @@
 		}
 	}
 
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	spin_unlock_irqrestore (&write_urb_pool_lock, flags);
 
 	dbg (__FUNCTION__ " - returns %d", chars);
 
@@ -514,15 +514,13 @@
 
 static void empeg_throttle (struct usb_serial_port *port)
 {
-	unsigned long flags;
-
 	dbg(__FUNCTION__ " - port %d", port->number);
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 
 	usb_unlink_urb (port->read_urb);
 
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	up (&port->sem);
 
 	return;
 
@@ -531,12 +529,11 @@
 
 static void empeg_unthrottle (struct usb_serial_port *port)
 {
-	unsigned long flags;
 	int result;
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 
 	port->read_urb->dev = port->serial->dev;
 
@@ -545,7 +542,7 @@
 	if (result)
 		err(__FUNCTION__ " - failed submitting read urb, error %d", result);
 
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	up (&port->sem);
 
 	return;
 
@@ -680,8 +677,7 @@
 		}
 	}
 
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 
 	return 0;
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/ftdi_sio.c linux/drivers/usb/serial/ftdi_sio.c
--- v2.4.5/linux/drivers/usb/serial/ftdi_sio.c	Thu May 24 14:55:51 2001
+++ linux/drivers/usb/serial/ftdi_sio.c	Wed Jun 20 16:52:30 2001
@@ -1,7 +1,7 @@
 /*
  * USB FTDI SIO driver
  *
- * 	Copyright (C) 1999, 2000
+ * 	Copyright (C) 1999 - 2001
  * 	    Greg Kroah-Hartman (greg@kroah.com)
  *          Bill Ryder (bryder@sgi.com)
  *
@@ -15,6 +15,9 @@
  * See http://reality.sgi.com/bryder_wellington/ftdi_sio for upto date testing info
  *     and extra documentation
  * 
+ * (31/May/2001) gkh
+ *	switched from using spinlock to a semaphore, which fixes lots of problems.
+ *
  * (23/May/2001)   Bill Ryder
  *     Added runtime debug patch (thanx Tyson D Sawyer).
  *     Cleaned up comments for 8U232
@@ -253,7 +256,7 @@
 	
 	priv = serial->port->private = kmalloc(sizeof(struct ftdi_private), GFP_KERNEL);
 	if (!priv){
-		err(__FUNCTION__"- kmalloc(%d) failed.", sizeof(struct ftdi_private));
+		err(__FUNCTION__"- kmalloc(%Zd) failed.", sizeof(struct ftdi_private));
 		return -ENOMEM;
 	}
 
@@ -271,7 +274,7 @@
 
 	priv = serial->port->private = kmalloc(sizeof(struct ftdi_private), GFP_KERNEL);
 	if (!priv){
-		err(__FUNCTION__"- kmalloc(%d) failed.", sizeof(struct ftdi_private));
+		err(__FUNCTION__"- kmalloc(%Zd) failed.", sizeof(struct ftdi_private));
 		return -ENOMEM;
 	}
 
@@ -301,13 +304,12 @@
 { /* ftdi_sio_open */
 	struct termios tmp_termios;
 	struct usb_serial *serial = port->serial;
-	unsigned long flags;	/* Used for spinlock */
-	int result;
+	int result = 0;
 	char buf[1]; /* Needed for the usb_control_msg I think */
 
 	dbg(__FUNCTION__);
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 	
 	MOD_INC_USE_COUNT;
 	++port->open_count;
@@ -315,8 +317,6 @@
 	if (!port->active){
 		port->active = 1;
 
-		spin_unlock_irqrestore (&port->port_lock, flags);
-
 		/* This will push the characters through immediately rather 
 		   than queue a task to deliver them */
 		port->tty->low_latency = 1;
@@ -352,11 +352,10 @@
 		result = usb_submit_urb(port->read_urb);
 		if (result)
 			err(__FUNCTION__ " - failed submitting read urb, error %d", result);
-	} else { /* the port was already active - so no initialisation is done */
-		spin_unlock_irqrestore (&port->port_lock, flags);
 	}
 
-	return (0);
+	up (&port->sem);
+	return result;
 } /* ftdi_sio_open */
 
 
@@ -365,15 +364,13 @@
 	struct usb_serial *serial = port->serial;
 	unsigned int c_cflag = port->tty->termios->c_cflag;
 	char buf[1];
-	unsigned long flags;
 
 	dbg( __FUNCTION__);
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 	--port->open_count;
 
 	if (port->open_count <= 0) {
-		spin_unlock_irqrestore (&port->port_lock, flags);
 		if (c_cflag & HUPCL){
 			/* Disable flow control */
 			if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
@@ -400,8 +397,6 @@
 		port->active = 0;
 		port->open_count = 0;
 	} else {  
-		spin_unlock_irqrestore (&port->port_lock, flags);
-
 		/* Send a HUP if necessary */
 		if (!(port->tty->termios->c_cflag & CLOCAL)){
 			tty_hangup(port->tty);
@@ -409,6 +404,7 @@
 		
 	}
 
+	up (&port->sem);
 	MOD_DEC_USE_COUNT;
 
 } /* ftdi_sio_close */
@@ -985,8 +981,7 @@
 	dbg(__FUNCTION__);
 	usb_serial_register (&ftdi_sio_device);
 	usb_serial_register (&ftdi_8U232AM_device);
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/io_edgeport.c linux/drivers/usb/serial/io_edgeport.c
--- v2.4.5/linux/drivers/usb/serial/io_edgeport.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/serial/io_edgeport.c	Tue Jun 12 15:53:37 2001
@@ -944,7 +944,7 @@
 	}
 
 	if (status) {
-		dbg(__FUNCTION__" - nonzero write bulk status received: %d", urb->status);
+		dbg(__FUNCTION__" - nonzero write bulk status received: %d", status);
 		return;
 	}
 
@@ -3037,8 +3037,7 @@
 	usb_serial_register (&edgeport_16dual_device);
 	usb_serial_register (&edgeport_compat_id_device);
 	usb_serial_register (&edgeport_8i_device);
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/keyspan.c linux/drivers/usb/serial/keyspan.c
--- v2.4.5/linux/drivers/usb/serial/keyspan.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/serial/keyspan.c	Wed Jun 20 16:52:30 2001
@@ -28,6 +28,9 @@
   open source projects.
 
   Change History
+    Thu May 31 11:56:42 PDT 2001 gkh
+      switched from using spinlock to a semaphore
+   
    (04/08/2001) gb
 	Identify version on module load.
    
@@ -177,8 +180,7 @@
 	usb_serial_register (&keyspan_usa28x_device);
 	usb_serial_register (&keyspan_usa49w_device);
 
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 
 	return 0;
 }
@@ -833,7 +835,6 @@
 	struct usb_serial 		*serial = port->serial;
 	const keyspan_device_details	*d_details;
 	int				i, already_active, err;
-	unsigned long flags;
 	urb_t *urb;
 
 	s_priv = (struct keyspan_serial_private *)(serial->private);
@@ -843,11 +844,11 @@
 	/*  dbg("keyspan_open called."); */
 	MOD_INC_USE_COUNT;
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 	++port->open_count;
 	already_active = port->active;
 	port->active = 1;
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	up (&port->sem);
 
 	if (already_active)
 		return 0;
@@ -887,13 +888,12 @@
 	struct usb_serial	*serial = port->serial; /* FIXME should so sanity check */
 	struct keyspan_serial_private 	*s_priv;
 	struct keyspan_port_private 	*p_priv;
-	unsigned long flags;
 
 	/*  dbg("keyspan_close called"); */
 	s_priv = (struct keyspan_serial_private *)(serial->private);
 	p_priv = (struct keyspan_port_private *)(port->private);
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 
 	if (--port->open_count <= 0) {
 		if (port->active) {
@@ -914,7 +914,7 @@
 		port->open_count = 0;
 		port->tty = 0;
 	}
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	up (&port->sem);
 
 	MOD_DEC_USE_COUNT;
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/keyspan_pda.c linux/drivers/usb/serial/keyspan_pda.c
--- v2.4.5/linux/drivers/usb/serial/keyspan_pda.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/serial/keyspan_pda.c	Wed Jun 20 16:52:30 2001
@@ -1,7 +1,7 @@
 /*
  * USB Keyspan PDA Converter driver
  *
- * Copyright (c) 1999, 2000 Greg Kroah-Hartman	<greg@kroah.com>
+ * Copyright (c) 1999 - 2001 Greg Kroah-Hartman	<greg@kroah.com>
  * Copyright (c) 1999, 2000 Brian Warner	<warner@lothar.com>
  * Copyright (c) 2000 Al Borchers		<borchers@steinerpoint.com>
  *
@@ -12,6 +12,9 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  * 
+ * (05/31/2001) gkh
+ *	switched from using spinlock to a semaphore, which fixes lots of problems.
+ *
  * (04/08/2001) gb
  *	Identify version on module load.
  * 
@@ -452,7 +455,6 @@
 	int request_unthrottle = 0;
 	int rc = 0;
 	struct keyspan_pda_private *priv;
-	unsigned long flags;
 
 	priv = (struct keyspan_pda_private *)(port->private);
 	/* guess how much room is left in the device's ring buffer, and if we
@@ -482,7 +484,6 @@
 	   finished).  Also, the tx process is not throttled. So we are
 	   ready to write. */
 
-	spin_lock_irqsave (&port->port_lock, flags);
 	count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
 
 	/* Check if we might overrun the Tx buffer.   If so, ask the
@@ -502,13 +503,12 @@
 				     2*HZ);
 		if (rc < 0) {
 			dbg(" roomquery failed");
-			spin_unlock_irqrestore (&port->port_lock, flags);
-			return rc; /* failed */
+			goto exit;
 		}
 		if (rc == 0) {
 			dbg(" roomquery returned 0 bytes");
-			spin_unlock_irqrestore (&port->port_lock, flags);
-			return -EIO; /* device didn't return any data */
+			rc = -EIO; /* device didn't return any data */
+			goto exit;
 		}
 		dbg(" roomquery says %d", room);
 		priv->tx_room = room;
@@ -525,8 +525,8 @@
 		if (from_user) {
 			if( copy_from_user(port->write_urb->transfer_buffer,
 			buf, count) ) {
-				spin_unlock_irqrestore (&port->port_lock, flags);
-				return( -EFAULT );
+				rc = -EFAULT;
+				goto exit;
 			}
 		}
 		else {
@@ -538,10 +538,10 @@
 		priv->tx_room -= count;
 
 		port->write_urb->dev = port->serial->dev;
-		if (usb_submit_urb(port->write_urb)) {
+		rc = usb_submit_urb(port->write_urb);
+		if (rc) {
 			dbg(" usb_submit_urb(write bulk) failed");
-			spin_unlock_irqrestore (&port->port_lock, flags);
-			return (0);
+			goto exit;
 		}
 	}
 	else {
@@ -557,8 +557,9 @@
 			MOD_DEC_USE_COUNT;
 	}
 
-	spin_unlock_irqrestore (&port->port_lock, flags);
-	return (count);
+	rc = count;
+exit:
+	return rc;
 }
 
 
@@ -616,11 +617,10 @@
 {
 	struct usb_serial *serial = port->serial;
 	unsigned char room;
-	int rc;
+	int rc = 0;
 	struct keyspan_pda_private *priv;
-	unsigned long flags;
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 
 	MOD_INC_USE_COUNT;
 	++port->open_count;
@@ -629,7 +629,6 @@
 		port->active = 1;
  
 		/* find out how much room is in the Tx ring */
-		spin_unlock_irqrestore (&port->port_lock, flags);
 		rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
 				     6, /* write_room */
 				     USB_TYPE_VENDOR | USB_RECIP_INTERFACE
@@ -639,7 +638,6 @@
 				     &room,
 				     1,
 				     2*HZ);
-		spin_lock_irqsave (&port->port_lock, flags);
 		if (rc < 0) {
 			dbg(__FUNCTION__" - roomquery failed");
 			goto error;
@@ -655,7 +653,6 @@
 
 		/* the normal serial device seems to always turn on DTR and RTS here,
 		   so do the same */
-		spin_unlock_irqrestore (&port->port_lock, flags);
 		if (port->tty->termios->c_cflag & CBAUD)
 			keyspan_pda_set_modem_info(serial, (1<<7) | (1<<2) );
 		else
@@ -663,19 +660,22 @@
 
 		/*Start reading from the device*/
 		port->interrupt_in_urb->dev = serial->dev;
-		if (usb_submit_urb(port->interrupt_in_urb))
+		rc = usb_submit_urb(port->interrupt_in_urb);
+		if (rc) {
 			dbg(__FUNCTION__" - usb_submit_urb(read int) failed");
-	} else {
-		spin_unlock_irqrestore (&port->port_lock, flags);
+			goto error;
+		}
+
 	}
 
 
-	return (0);
+	up (&port->sem);
+	return rc;
 error:
 	--port->open_count;
 	port->active = 0;
 	MOD_DEC_USE_COUNT;
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	up (&port->sem);
 	return rc;
 }
 
@@ -683,19 +683,15 @@
 static void keyspan_pda_close(struct usb_serial_port *port, struct file *filp)
 {
 	struct usb_serial *serial = port->serial;
-	unsigned long flags;
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 
 	--port->open_count;
-	MOD_DEC_USE_COUNT;
 
 	if (port->open_count <= 0) {
 		/* the normal serial device seems to always shut off DTR and RTS now */
-		spin_unlock_irqrestore (&port->port_lock, flags);
 		if (port->tty->termios->c_cflag & HUPCL)
 			keyspan_pda_set_modem_info(serial, 0);
-		spin_lock_irqsave (&port->port_lock, flags);
 
 		/* shutdown our bulk reads and writes */
 		usb_unlink_urb (port->write_urb);
@@ -704,7 +700,8 @@
 		port->open_count = 0;
 	}
 
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	up (&port->sem);
+	MOD_DEC_USE_COUNT;
 }
 
 
@@ -817,8 +814,7 @@
 {
 	usb_serial_register (&keyspan_pda_fake_device);
 	usb_serial_register (&keyspan_pda_device);
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/mct_u232.c linux/drivers/usb/serial/mct_u232.c
--- v2.4.5/linux/drivers/usb/serial/mct_u232.c	Thu May 24 14:55:51 2001
+++ linux/drivers/usb/serial/mct_u232.c	Wed Jun 20 16:52:30 2001
@@ -24,6 +24,9 @@
  *   Basic tests have been performed with minicom/zmodem transfers and
  *   modem dialing under Linux 2.4.0-test10 (for me it works fine).
  *
+ * 30-May-2001 Greg Kroah-Hartman
+ *	switched from using spinlock to a semaphore, which fixes lots of problems.
+ *
  * 04-May-2001 Stelian Pop
  *   - Set the maximum bulk output size for Sitecom U232-P25 model to 16 bytes
  *     instead of the device reported 32 (using 32 bytes causes many data
@@ -79,7 +82,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.0.0"
+#define DRIVER_VERSION "v1.1"
 #define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
 #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
 
@@ -391,13 +394,13 @@
 
 static int  mct_u232_open (struct usb_serial_port *port, struct file *filp)
 {
-	unsigned long flags;
 	struct usb_serial *serial = port->serial;
 	struct mct_u232_private *priv = (struct mct_u232_private *)port->private;
+	int retval = 0;
 
 	dbg(__FUNCTION__" port %d", port->number);
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 	
 	++port->open_count;
 	MOD_INC_USE_COUNT;
@@ -443,16 +446,21 @@
 		}
 
 		port->read_urb->dev = port->serial->dev;
-		if (usb_submit_urb(port->read_urb))
+		retval = usb_submit_urb(port->read_urb);
+		if (retval) {
 			err("usb_submit_urb(read bulk) failed");
+			goto exit;
+		}
 
 		port->interrupt_in_urb->dev = port->serial->dev;
-		if (usb_submit_urb(port->interrupt_in_urb))
+		retval = usb_submit_urb(port->interrupt_in_urb);
+		if (retval)
 			err(" usb_submit_urb(read int) failed");
 
 	}
 
-	spin_unlock_irqrestore (&port->port_lock, flags);
+exit:
+	up (&port->sem);
 	
 	return 0;
 } /* mct_u232_open */
@@ -460,14 +468,11 @@
 
 static void mct_u232_close (struct usb_serial_port *port, struct file *filp)
 {
-	unsigned long flags;
-
 	dbg(__FUNCTION__" port %d", port->number);
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 
 	--port->open_count;
-	MOD_DEC_USE_COUNT;
 
 	if (port->open_count <= 0) {
 		/* shutdown our bulk reads and writes */
@@ -478,8 +483,8 @@
 		port->active = 0;
 	}
 	
-	spin_unlock_irqrestore (&port->port_lock, flags);
-
+	up (&port->sem);
+	MOD_DEC_USE_COUNT;
 } /* mct_u232_close */
 
 
@@ -490,7 +495,6 @@
 			   const unsigned char *buf, int count)
 {
 	struct usb_serial *serial = port->serial;
-	unsigned long flags;
 	int result, bytes_sent, size;
 
 	dbg(__FUNCTION__ " - port %d", port->number);
@@ -513,7 +517,7 @@
 	bytes_sent = 0;
 	while (count > 0) {
 		
-		spin_lock_irqsave (&port->port_lock, flags);
+		down (&port->sem);
 		
 		size = (count > port->bulk_out_size) ? port->bulk_out_size : count;
 		
@@ -541,11 +545,11 @@
 		if (result) {
 			err(__FUNCTION__
 			    " - failed submitting write urb, error %d", result);
-			spin_unlock_irqrestore (&port->port_lock, flags);
-			return bytes_sent;
+			up (&port->sem);
+			return result;
 		}
 
-		spin_unlock_irqrestore (&port->port_lock, flags);
+		up (&port->sem);
 
 		bytes_sent += size;
 		if (write_blocking)
@@ -870,8 +874,7 @@
 	usb_serial_register (&mct_u232_device);
 	usb_serial_register (&mct_u232_sitecom_device);
 	usb_serial_register (&mct_u232_du_h3sp_device);
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/omninet.c linux/drivers/usb/serial/omninet.c
--- v2.4.5/linux/drivers/usb/serial/omninet.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/serial/omninet.c	Wed Jun 20 16:52:30 2001
@@ -10,6 +10,9 @@
  *
  * Please report both successes and troubles to the author at omninet@kroah.com
  * 
+ * (05/30/2001) gkh
+ *	switched from using spinlock to a semaphore, which fixes lots of problems.
+ *
  * (04/08/2001) gb
  *	Identify version on module load.
  *
@@ -60,7 +63,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.0.0"
+#define DRIVER_VERSION "v1.1"
 #define DRIVER_AUTHOR "Anonymous"
 #define DRIVER_DESC "USB ZyXEL omni.net LCD PLUS Driver"
 
@@ -145,8 +148,7 @@
 	struct usb_serial	*serial;
 	struct usb_serial_port	*wport;
 	struct omninet_data	*od;
-	unsigned long		flags;
-	int			result;
+	int			result = 0;
 
 	if (port_paranoia_check (port, __FUNCTION__))
 		return -ENODEV;
@@ -157,7 +159,7 @@
 	if (!serial)
 		return -ENODEV;
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 
 	MOD_INC_USE_COUNT;
 	++port->open_count;
@@ -170,7 +172,7 @@
 			err(__FUNCTION__"- kmalloc(%Zd) failed.", sizeof(struct omninet_data));
 			--port->open_count;
 			port->active = 0;
-			spin_unlock_irqrestore (&port->port_lock, flags);
+			up (&port->sem);
 			MOD_DEC_USE_COUNT;
 			return -ENOMEM;
 		}
@@ -189,9 +191,9 @@
 			err(__FUNCTION__ " - failed submitting read urb, error %d", result);
 	}
 
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	up (&port->sem);
 
-	return (0);
+	return result;
 }
 
 static void omninet_close (struct usb_serial_port *port, struct file * filp)
@@ -199,7 +201,6 @@
 	struct usb_serial 	*serial;
 	struct usb_serial_port 	*wport;
 	struct omninet_data 	*od;
-	unsigned long		flags;
 
 	if (port_paranoia_check (port, __FUNCTION__))
 		return;
@@ -210,10 +211,9 @@
 	if (!serial)
 		return;
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 
 	--port->open_count;
-	MOD_DEC_USE_COUNT;
 
 	if (port->open_count <= 0) {
 		od = (struct omninet_data *)port->private;
@@ -228,7 +228,8 @@
 			kfree(od);
 	}
 
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	up (&port->sem);
+	MOD_DEC_USE_COUNT;
 }
 
 
@@ -296,7 +297,6 @@
 	struct omninet_data 	*od 	= (struct omninet_data   *) port->private;
 	struct omninet_header	*header = (struct omninet_header *) wport->write_urb->transfer_buffer;
 
-	unsigned long		flags;
 	int			result;
 
 //	dbg("omninet_write port %d", port->number);
@@ -310,12 +310,13 @@
 		return (0);
 	}
 
-	spin_lock_irqsave (&port->port_lock, flags);
-	
 	count = (count > OMNINET_BULKOUTSIZE) ? OMNINET_BULKOUTSIZE : count;
 
 	if (from_user) {
-		copy_from_user(wport->write_urb->transfer_buffer + OMNINET_DATAOFFSET, buf, count);
+		if (copy_from_user(wport->write_urb->transfer_buffer + OMNINET_DATAOFFSET, buf, count) != 0) {
+			result = -EFAULT;
+			goto exit;
+		}
 	}
 	else {
 		memcpy (wport->write_urb->transfer_buffer + OMNINET_DATAOFFSET, buf, count);
@@ -333,16 +334,13 @@
 
 	wport->write_urb->dev = serial->dev;
 	result = usb_submit_urb(wport->write_urb);
-	if (result) {
+	if (result)
 		err(__FUNCTION__ " - failed submitting write urb, error %d", result);
-		spin_unlock_irqrestore (&port->port_lock, flags);
-		return 0;
-	}
-
-//	dbg("omninet_write returns %d", count);
+	else
+		result = count;
 
-	spin_unlock_irqrestore (&port->port_lock, flags);
-	return (count);
+exit:	
+	return result;
 }
 
 
@@ -406,8 +404,7 @@
 static int __init omninet_init (void)
 {
 	usb_serial_register (&zyxel_omninet_device);
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/pl2303.c linux/drivers/usb/serial/pl2303.c
--- v2.4.5/linux/drivers/usb/serial/pl2303.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/serial/pl2303.c	Wed Jun 27 13:59:32 2001
@@ -0,0 +1,844 @@
+/*
+ * Prolific PL2303 USB to serial adaptor driver
+ *
+ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ *
+ * Original driver for 2.2.x by anonymous
+ *
+ *	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.
+ *
+ * See Documentation/usb/usb-serial.txt for more information on using this driver
+ *
+ * 2001_Jun_06 gkh
+ *	finished porting to 2.4 format.
+ * 
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/fcntl.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+
+#ifdef CONFIG_USB_SERIAL_DEBUG
+	static int debug = 1;
+#else
+	static int debug;
+#endif
+
+#include "usb-serial.h"
+#include "pl2303.h"
+
+/*
+ * Version Information
+ */
+#define DRIVER_VERSION "v0.5"
+#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) },
+	{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
+	{ }					/* Terminating entry */
+};
+
+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 */
+static struct usb_serial_device_type pl2303_device = {
+	name:			"PL-2303",
+	id_table:		id_table,
+	needs_interrupt_in:	DONT_CARE,		/* this device must 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:	NUM_DONT_CARE,
+	num_bulk_in:		1,
+	num_bulk_out:		1,
+	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)
+{				/* 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);
+
+	if (!info) {
+		return -ENODEV;
+	}
+
+	if (!tty || !info->xmit_buf || !tmp_buf) {
+		return 0;
+	}
+
+
+	PL2303_LOCK(port,flags);
+
+
+	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);
+	} 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;
+		}
+	}
+	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;
+}
+
+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
+pl2303_set_termios (struct usb_serial_port *port, struct termios *old_termios)
+{				/* pl2303_set_termios */
+	struct usb_serial *serial = port->serial;
+	unsigned int cflag = port->tty->termios->c_cflag;
+	unsigned char buf[7] = { 0, 0, 0, 0, 0, 0, 0};
+	int baud;
+	int i;
+
+
+	dbg ("pl2303_set_termios port %d", port->number);
+
+
+	i = usb_control_msg (serial->dev, usb_rcvctrlpipe (serial->dev, 0),
+			     0x21, 0xa1, 0, 0, buf, 7, 100);
+
+	dbg ("0xa1:0x21:0:0  %d - %x %x %x %x %x %x %x", i,
+	     buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
+
+
+	i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0),
+			     1, 0x40, 0, 1, NULL, 0, 100);
+
+	dbg ("0x40:1:0:1  %d", i);
+
+
+
+	if (cflag & CSIZE) {
+		switch (cflag & CSIZE) {
+			case CS6:
+				buf[6] = 6;
+				dbg ("Setting CS6");
+				break;
+			case CS7:
+				buf[6] = 7;
+				dbg ("Setting CS7");
+				break;
+			case CS8:
+				buf[6] = 8;
+				dbg ("Setting CS8");
+				break;
+			default:
+				err ("CSIZE was set but not CS6-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;
+		default:
+			dbg ("pl2303 driver does not support the baudrate requested (fix it)");
+			break;
+	}
+
+	if (baud) {
+		buf[0] = baud & 0xff;
+		buf[1] = (baud >> 8) & 0xff;
+		buf[2] = (baud >> 16) & 0xff;
+		buf[3] = (baud >> 24) & 0xff;
+	}
+
+
+	/* For reference buf[4]=1 is 1.5 stop bits */
+
+	if (cflag & CSTOPB) {
+		buf[4] = 2;
+	}
+
+
+	if (cflag & PARENB) {
+		/* For reference buf[5]=3 is mark parity */
+		/* For reference buf[5]=4 is space parity */
+		if (cflag & PARODD) {
+			buf[5] = 1;
+		} else {
+			buf[5] = 2;
+		}
+	}
+
+	i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0),
+			     0x20, 0x21, 0, 0, buf, 7, 100);
+
+	dbg ("0x21:0x20:0:0  %d", i);
+
+	i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0),
+			     0x22, 0x21, 1, 0, NULL, 0, 100);
+
+	dbg ("0x21:0x22:1:0  %d", i);
+
+	i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0),
+			     0x22, 0x21, 3, 0, NULL, 0, 100);
+
+	dbg ("0x21:0x22:3:0  %d", i);
+
+	buf[0] = buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = buf[6] = 0;
+
+	i = usb_control_msg (serial->dev, usb_rcvctrlpipe (serial->dev, 0),
+			     0x21, 0xa1, 0, 0, buf, 7, 100);
+
+	dbg ("0xa1:0x21:0:0  %d - %x %x %x %x %x %x %x", i,
+	     buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
+
+	if (cflag & CRTSCTS) {
+
+		i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0),
+				     0x01, 0x40, 0x0, 0x41, NULL, 0, 100);
+
+		dbg ("0x40:0x1:0x0:0x41  %d", i);
+
+	}
+
+
+	return;
+}       
+
+
+static int
+pl2303_open (struct usb_serial_port *port, struct file *filp)
+{				/* pl2303_open */
+	struct termios tmp_termios;
+	struct usb_serial *serial = port->serial;
+	unsigned char buf[10];
+	int i;
+
+	dbg ("pl2303_open port %d", port->number);
+
+	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) {
+		*(port->tty->termios) = tty_std_termios;
+		port->tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	}
+
+
+	pl2303_set_termios (port, &tmp_termios);
+
+	//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);
+			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);
+			pl2303_close (port, NULL);
+
+			return -EPROTO;
+		}
+	}
+
+	return(0);
+}				/* pl2303_open */
+
+
+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;
+
+	dbg ("pl2303_close port %d", port->number);
+
+	/* shutdown our bulk reads and writes */
+	if (port->active == 1) {
+
+		if (c_cflag & HUPCL) {
+			//FIXME: Do drop DTR
+			//FIXME: Do drop RTS
+		}
+
+		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--;
+}				/* pl2303_close */
+
+
+/* do some startup allocations not currently performed by usb_serial_probe() */
+static int
+pl2303_startup (struct usb_serial *serial)
+{
+	return(0);
+}
+
+
+static int
+pl2303_ioctl (struct usb_serial_port *port, struct file *file,
+	      unsigned int cmd, unsigned long arg)
+{
+// struct usb_serial *serial = port->serial;
+// __u16 urb_value=0; /* Will hold the new flags */
+// char buf[1];
+// int  ret, mask;
+
+
+	dbg ("pl2303_sio ioctl 0x%04x", cmd);
+
+	/* Based on code from acm.c and others */
+	switch (cmd) {
+		
+		case TIOCMGET:
+			dbg ("TIOCMGET");
+
+
+			return put_user (0, (unsigned long *) arg);
+			break;
+		case TIOCMBIS:
+		case TIOCMBIC:
+		case TIOCMSET:
+			return 0;
+
+		default:
+			/* This is not an error - turns out the higher layers will do 
+			 *  some ioctls itself (see comment above)
+			 */
+			dbg ("pl2303_sio ioctl arg not supported - it was 0x%04x", cmd);
+			return(-ENOIOCTLCMD);
+			break;
+	}
+	dbg ("pl2303_ioctl returning 0");
+
+	return 0;
+}				/* pl2303_ioctl */
+
+
+static void pl2303_break_ctl(struct usb_serial_port *port,int break_state)
+{
+//FIXME
+}
+
+
+static void
+pl2303_read_int_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_int_callback");
+	//unsigned char *data = urb->transfer_buffer;
+	//int i;
+
+//ints auto restart...
+
+	if (!serial) {
+		return;
+	}
+
+	if (urb->status) {
+		urb->status = 0;
+		return;
+	}
+
+
+#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)
+{
+	struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
+	struct usb_serial *serial = get_usb_serial (port, "pl2303_read_bulk_callback");
+	struct tty_struct *tty;
+	unsigned char *data = urb->transfer_buffer;
+	int i;
+
+	if (!serial) {
+		return;
+	}
+
+// 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");
+		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");
+		}
+	}
+
+	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_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");
+
+	return;
+}
+
+
+
+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;
+	}
+
+	serial = port->serial;
+	if (serial_paranoia_check (serial, "pl2303_write_bulk_callback")) {
+		return;
+	}
+
+
+	if (urb->status) {
+		dbg ("Overflow in write");
+		dbg ("nonzero write bulk status received: %d", urb->status);
+		//need to resubmit frame;
+
+		port->write_urb->transfer_buffer_length = 1;
+
+		//Resubmit ourselves
+
+		if (usb_submit_urb (port->write_urb))
+			err ("usb_submit_urb(write bulk) failed");
+
+		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);
+
+	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);
+	return 0;
+}
+
+
+static void __exit pl2303_exit (void)
+{
+	usb_serial_deregister (&pl2303_device);
+}
+
+
+module_init(pl2303_init);
+module_exit(pl2303_exit);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/pl2303.h linux/drivers/usb/serial/pl2303.h
--- v2.4.5/linux/drivers/usb/serial/pl2303.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/serial/pl2303.h	Wed Jun 20 16:52:30 2001
@@ -0,0 +1,15 @@
+/*
+ * Prolific PL2303 USB to serial adaptor driver header file
+ *
+ *	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 PL2303_VENDOR_ID	0x067b
+#define PL2303_PRODUCT_ID	0x2303
+
+#define ATEN_VENDOR_ID		0x0557
+#define ATEN_PRODUCT_ID		0x2008
+
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/usb-serial.h linux/drivers/usb/serial/usb-serial.h
--- v2.4.5/linux/drivers/usb/serial/usb-serial.h	Fri Apr  6 15:51:52 2001
+++ linux/drivers/usb/serial/usb-serial.h	Wed Jun 20 16:52:30 2001
@@ -1,7 +1,7 @@
 /*
  * USB Serial Converter driver
  *
- *	Copyright (C) 1999, 2000
+ *	Copyright (C) 1999 - 2001
  *	    Greg Kroah-Hartman (greg@kroah.com)
  *
  *	This program is free software; you can redistribute it and/or modify
@@ -11,6 +11,9 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * (05/30/2001) gkh
+ *	added sem to port structure and removed port_lock
+ *
  * (10/05/2000) gkh
  *	Added interrupt_in_endpointAddress and bulk_in_endpointAddress to help
  *	fix bug with urb->dev not being set properly, now that the usb core
@@ -77,7 +80,7 @@
 
 	struct tq_struct	tqueue;		/* task queue for line discipline waking up */
 	int			open_count;	/* number of times this port has been opened */
-	spinlock_t		port_lock;
+	struct semaphore	sem;		/* locks this structure */
 	
 	void *			private;	/* data private to the specific port */
 };
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/usbserial.c linux/drivers/usb/serial/usbserial.c
--- v2.4.5/linux/drivers/usb/serial/usbserial.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/serial/usbserial.c	Wed Jun 20 16:52:30 2001
@@ -1,7 +1,7 @@
 /*
  * USB Serial Converter driver
  *
- * Copyright (C) 1999, 2000 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (C) 1999 - 2001 Greg Kroah-Hartman (greg@kroah.com)
  * Copyright (c) 2000 Peter Berger (pberger@brimson.com)
  * Copyright (c) 2000 Al Borchers (borchers@steinerpoint.com)
  *
@@ -15,6 +15,13 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  * 
+ * (06/06/2001) gkh
+ *	added evil hack that is needed for the prolific pl2303 device due to the
+ *	crazy way its endpoints are set up.
+ *
+ * (05/30/2001) gkh
+ *	switched from using spinlock to a semaphore, which fixes lots of problems.
+ *
  * (04/08/2001) gb
  *	Identify version on module load.
  *
@@ -284,13 +291,14 @@
 #endif
 
 #include "usb-serial.h"
+#include "pl2303.h"
 
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.0.0"
+#define DRIVER_VERSION "v1.2"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux-usb/"
-#define DRIVER_DESC "USB Serial Driver"
+#define DRIVER_DESC "USB Serial Driver core"
 
 #define MAX(a,b)	(((a)>(b))?(a):(b))
 
@@ -735,8 +743,7 @@
 static int generic_open (struct usb_serial_port *port, struct file *filp)
 {
 	struct usb_serial *serial = port->serial;
-	unsigned long flags;
-	int result;
+	int result = 0;
 
 	if (port_paranoia_check (port, __FUNCTION__))
 		return -ENODEV;
@@ -745,7 +752,7 @@
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 	
 	++port->open_count;
 	
@@ -773,20 +780,19 @@
 		}
 	}
 	
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	up (&port->sem);
 	
-	return 0;
+	return result;
 }
 
 
 static void generic_close (struct usb_serial_port *port, struct file * filp)
 {
 	struct usb_serial *serial = port->serial;
-	unsigned long flags;
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 
 	--port->open_count;
 
@@ -801,7 +807,7 @@
 		port->open_count = 0;
 	}
 
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	up (&port->sem);
 	MOD_DEC_USE_COUNT;
 }
 
@@ -809,7 +815,6 @@
 static int generic_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
 {
 	struct usb_serial *serial = port->serial;
-	unsigned long flags;
 	int result;
 
 	dbg(__FUNCTION__ " - port %d", port->number);
@@ -826,7 +831,6 @@
 			return (0);
 		}
 
-		spin_lock_irqsave (&port->port_lock, flags);
 		count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
 
 		if (from_user) {
@@ -849,14 +853,12 @@
 
 		/* send the data out the bulk port */
 		result = usb_submit_urb(port->write_urb);
-		if (result) {
+		if (result)
 			err(__FUNCTION__ " - failed submitting write urb, error %d", result);
-			spin_unlock_irqrestore (&port->port_lock, flags);
-			return 0;
-		}
+		else
+			result = count;
 
-		spin_unlock_irqrestore (&port->port_lock, flags);
-		return (count);
+		return result;
 	}
 	
 	/* no bulk out, so return 0 bytes written */
@@ -871,9 +873,10 @@
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 	
-	if (serial->num_bulk_out)
+	if (serial->num_bulk_out) {
 		if (port->write_urb->status != -EINPROGRESS)
 			room = port->bulk_out_size;
+	}
 	
 	dbg(__FUNCTION__ " - returns %d", room);
 	return (room);
@@ -887,9 +890,10 @@
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 	
-	if (serial->num_bulk_out)
+	if (serial->num_bulk_out) {
 		if (port->write_urb->status == -EINPROGRESS)
 			chars = port->write_urb->transfer_buffer_length;
+	}
 
 	dbg (__FUNCTION__ " - returns %d", chars);
 	return (chars);
@@ -1091,6 +1095,33 @@
 		}
 	}
 	
+#if defined(CONFIG_USB_SERIAL_PL2303) || defined(CONFIG_USB_SERIAL_PL2303_MODULE)
+	/* BEGIN HORRIBLE HACK FOR PL2303 */ 
+	/* this is needed due to the looney way its endpoints are set up */
+	if (ifnum == 1) {
+		if (((dev->descriptor.idVendor == PL2303_VENDOR_ID) &&
+		     (dev->descriptor.idProduct == PL2303_PRODUCT_ID)) ||
+		    ((dev->descriptor.idVendor == ATEN_VENDOR_ID) &&
+		     (dev->descriptor.idProduct == ATEN_PRODUCT_ID))) {
+			/* check out the endpoints of the other interface*/
+			interface = &dev->actconfig->interface[ifnum ^ 1];
+			iface_desc = &interface->altsetting[0];
+			for (i = 0; i < iface_desc->bNumEndpoints; ++i) {
+				endpoint = &iface_desc->endpoint[i];
+				if ((endpoint->bEndpointAddress & 0x80) &&
+				    ((endpoint->bmAttributes & 3) == 0x03)) {
+					/* we found a interrupt in endpoint */
+					dbg("found interrupt in for Prolific device on separate interface");
+					interrupt_pipe = HAS;
+					interrupt_in_endpoint[num_interrupt_in] = endpoint;
+					++num_interrupt_in;
+				}
+			}
+		}
+	}
+	/* END HORRIBLE HACK FOR PL2303 */
+#endif
+	
 	/* verify that we found all of the endpoints that we need */
 	if (!((interrupt_pipe & type->needs_interrupt_in) &&
 	      (bulk_in_pipe & type->needs_bulk_in) &&
@@ -1222,7 +1253,7 @@
 		port->magic = USB_SERIAL_PORT_MAGIC;
 		port->tqueue.routine = port_softint;
 		port->tqueue.data = port;
-		spin_lock_init (&port->port_lock);
+		init_MUTEX (&port->sem);
 	}
 	
 	/* initialize the devfs nodes for this device and let the user know what ports we are bound to */
@@ -1395,8 +1426,7 @@
 		return -1;
 	}
 
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 
 	return 0;
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/visor.c linux/drivers/usb/serial/visor.c
--- v2.4.5/linux/drivers/usb/serial/visor.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/serial/visor.c	Wed Jun 20 16:52:30 2001
@@ -1,7 +1,7 @@
 /*
  * USB HandSpring Visor driver
  *
- *	Copyright (C) 1999, 2000
+ *	Copyright (C) 1999 - 2001
  *	    Greg Kroah-Hartman (greg@kroah.com)
  *
  *	This program is free software; you can redistribute it and/or modify
@@ -11,6 +11,12 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  * 
+ * (05/30/2001) gkh
+ *	switched from using spinlock to a semaphore, which fixes lots of problems.
+ *
+ * (05/28/2000) gkh
+ *	Added initial support for the Palm m500 and Palm m505 devices.
+ *
  * (04/08/2001) gb
  *	Identify version on module load.
  *
@@ -109,7 +115,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.0.0"
+#define DRIVER_VERSION "v1.2"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
 #define DRIVER_DESC "USB HandSpring Visor driver"
 
@@ -131,8 +137,26 @@
 static void visor_read_bulk_callback	(struct urb *urb);
 
 
+static __devinitdata struct usb_device_id visor_id_table [] = {
+	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
+	{ }					/* Terminating entry */
+};
+
+static __devinitdata struct usb_device_id palm_m500_id_table [] = {
+	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
+	{ }					/* Terminating entry */
+};
+
+static __devinitdata struct usb_device_id palm_m505_id_table [] = {
+	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },
+	{ }					/* Terminating entry */
+};
+
+
 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) },
 	{ }					/* Terminating entry */
 };
 
@@ -143,7 +167,7 @@
 /* All of the device info needed for the Handspring Visor */
 struct usb_serial_device_type handspring_device = {
 	name:			"Handspring Visor",
-	id_table:		id_table,
+	id_table:		visor_id_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 */
@@ -166,6 +190,57 @@
 	read_bulk_callback:	visor_read_bulk_callback,
 };
 
+/* device info for the Palm M500 */
+struct usb_serial_device_type palm_m500_device = {
+	name:			"Palm M500",
+	id_table:		palm_m500_id_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,
+	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 Palm M505 */
+struct usb_serial_device_type palm_m505_device = {
+	name:			"Palm M505",
+	id_table:		palm_m505_id_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,
+	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,
+};
 
 #define NUM_URBS			24
 #define URB_TRANSFER_BUFFER_SIZE	768
@@ -181,15 +256,14 @@
 static int visor_open (struct usb_serial_port *port, struct file *filp)
 {
 	struct usb_serial *serial = port->serial;
-	unsigned long flags;
-	int result;
+	int result = 0;
 
 	if (port_paranoia_check (port, __FUNCTION__))
 		return -ENODEV;
 	
 	dbg(__FUNCTION__ " - port %d", port->number);
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 	
 	++port->open_count;
 	MOD_INC_USE_COUNT;
@@ -214,9 +288,9 @@
 			err(__FUNCTION__ " - failed submitting read urb, error %d", result);
 	}
 	
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	up (&port->sem);
 	
-	return 0;
+	return result;
 }
 
 
@@ -224,7 +298,6 @@
 {
 	struct usb_serial *serial;
 	unsigned char *transfer_buffer;
-	unsigned long flags;
 
 	if (port_paranoia_check (port, __FUNCTION__))
 		return;
@@ -235,7 +308,7 @@
 	if (!serial)
 		return;
 	
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 
 	--port->open_count;
 
@@ -256,7 +329,7 @@
 		port->open_count = 0;
 
 	}
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	up (&port->sem);
 
 	/* Uncomment the following line if you want to see some statistics in your syslog */
 	/* info ("Bytes In = %d  Bytes Out = %d", bytes_in, bytes_out); */
@@ -338,7 +411,7 @@
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 	
-	spin_lock_irqsave (&port->port_lock, flags);
+	spin_lock_irqsave (&write_urb_pool_lock, flags);
 
 	for (i = 0; i < NUM_URBS; ++i) {
 		if (write_urb_pool[i]->status != -EINPROGRESS) {
@@ -346,7 +419,7 @@
 		}
 	}
 	
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	spin_unlock_irqrestore (&write_urb_pool_lock, flags);
 	
 	dbg(__FUNCTION__ " - returns %d", room);
 	return (room);
@@ -361,7 +434,7 @@
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 	
-	spin_lock_irqsave (&port->port_lock, flags);
+	spin_lock_irqsave (&write_urb_pool_lock, flags);
 
 	for (i = 0; i < NUM_URBS; ++i) {
 		if (write_urb_pool[i]->status == -EINPROGRESS) {
@@ -369,7 +442,7 @@
 		}
 	}
 	
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	spin_unlock_irqrestore (&write_urb_pool_lock, flags);
 
 	dbg (__FUNCTION__ " - returns %d", chars);
 	return (chars);
@@ -451,15 +524,14 @@
 
 static void visor_throttle (struct usb_serial_port *port)
 {
-	unsigned long flags;
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 
 	usb_unlink_urb (port->read_urb);
 
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	up (&port->sem);
 
 	return;
 }
@@ -467,19 +539,18 @@
 
 static void visor_unthrottle (struct usb_serial_port *port)
 {
-	unsigned long flags;
 	int result;
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 
 	port->read_urb->dev = port->serial->dev;
 	result = usb_submit_urb(port->read_urb);
 	if (result)
 		err(__FUNCTION__ " - failed submitting read urb, error %d", result);
 
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	up (&port->sem);
 
 	return;
 }
@@ -496,6 +567,10 @@
 		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");
@@ -537,6 +612,28 @@
 		}
 	}
 
+	if (serial->dev->descriptor.idVendor == PALM_VENDOR_ID) {
+		/* Palm USB Hack */
+		response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), 
+					    PALM_GET_SOME_UNKNOWN_INFORMATION,
+					    0xc2, 0x0000, 0x0000, transfer_buffer, 
+					    0x14, 300);
+		if (response < 0) {
+			err(__FUNCTION__ " - error getting first unknown palm command");
+		} else {
+			usb_serial_debug_data (__FILE__, __FUNCTION__, 0x14, transfer_buffer);
+		}
+		response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), 
+					    PALM_GET_SOME_UNKNOWN_INFORMATION,
+					    0xc2, 0x0000, 0x0000, transfer_buffer, 
+					    0x14, 300);
+		if (response < 0) {
+			err(__FUNCTION__ " - error getting second unknown palm command");
+		} else {
+			usb_serial_debug_data (__FILE__, __FUNCTION__, 0x14, transfer_buffer);
+		}
+	}
+
 	/* ask for the number of bytes available, but ignore the response as it is broken */
 	response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_REQUEST_BYTES_AVAILABLE,
 					0xc2, 0x0000, 0x0005, transfer_buffer, 0x02, 300);
@@ -645,6 +742,8 @@
 	int i;
 
 	usb_serial_register (&handspring_device);
+	usb_serial_register (&palm_m500_device);
+	usb_serial_register (&palm_m505_device);
 	
 	/* create our write urb pool and transfer buffers */ 
 	spin_lock_init (&write_urb_pool_lock);
@@ -664,8 +763,7 @@
 		}
 	}
 
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 
 	return 0;
 }
@@ -677,6 +775,8 @@
 	unsigned long flags;
 
 	usb_serial_deregister (&handspring_device);
+	usb_serial_deregister (&palm_m500_device);
+	usb_serial_deregister (&palm_m505_device);
 
 	spin_lock_irqsave (&write_urb_pool_lock, flags);
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/visor.h linux/drivers/usb/serial/visor.h
--- v2.4.5/linux/drivers/usb/serial/visor.h	Wed Apr 18 11:49:12 2001
+++ linux/drivers/usb/serial/visor.h	Mon Jun 11 19:15:27 2001
@@ -1,7 +1,7 @@
 /*
  * USB HandSpring Visor driver
  *
- *	Copyright (C) 1999, 2000
+ *	Copyright (C) 1999 - 2001
  *	    Greg Kroah-Hartman (greg@kroah.com)
  *
  *	This program is free software; you can redistribute it and/or modify
@@ -20,6 +20,10 @@
 #define HANDSPRING_VENDOR_ID		0x082d
 #define HANDSPRING_VISOR_ID		0x0100
 
+#define PALM_VENDOR_ID			0x0830
+#define PALM_M500_ID			0x0001
+#define PALM_M505_ID			0x0002
+
 /****************************************************************************
  * Handspring Visor Vendor specific request codes (bRequest values)
  * A big thank you to Handspring for providing the following information.
@@ -69,6 +73,13 @@
 #define VISOR_FUNCTION_HOTSYNC		0x02
 #define VISOR_FUNCTION_CONSOLE		0x03
 #define VISOR_FUNCTION_REMOTE_FILE_SYS	0x04
+
+
+/****************************************************************************
+ * PALM_GET_SOME_UNKNOWN_INFORMATION is sent by the host during enumeration to
+ * get some information from the M series devices, that is currently unknown.
+ ****************************************************************************/
+#define PALM_GET_SOME_UNKNOWN_INFORMATION	0x04
 
 #endif
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/whiteheat.c linux/drivers/usb/serial/whiteheat.c
--- v2.4.5/linux/drivers/usb/serial/whiteheat.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/serial/whiteheat.c	Wed Jun 20 16:52:30 2001
@@ -11,6 +11,9 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * (05/30/2001) gkh
+ *	switched from using spinlock to a semaphore, which fixes lots of problems.
+ *
  * (04/08/2001) gb
  *	Identify version on module load.
  * 
@@ -85,7 +88,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.0.0"
+#define DRIVER_VERSION "v1.1"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
 #define DRIVER_DESC "USB ConnectTech WhiteHEAT driver"
 
@@ -251,6 +254,7 @@
 	struct usb_serial_port *port;
 	int timeout;
 	__u8 *transfer_buffer;
+	int retval = 0;
 
 	dbg(__FUNCTION__" - command %d", command);
 
@@ -263,9 +267,10 @@
 	memcpy (&transfer_buffer[1], data, datasize);
 	port->write_urb->transfer_buffer_length = datasize + 1;
 	port->write_urb->dev = serial->dev;
-	if (usb_submit_urb (port->write_urb)) {
+	retval = usb_submit_urb (port->write_urb);
+	if (retval) {
 		dbg (__FUNCTION__" - submit urb failed");
-		return -1;
+		goto exit;
 	}
 
 	/* wait for the command to complete */
@@ -276,20 +281,21 @@
 
 	if (info->command_finished == FALSE) {
 		dbg (__FUNCTION__ " - command timed out.");
-		return -1;
+		retval = -ETIMEDOUT;
+		goto exit;
 	}
 
 	if (info->command_finished == WHITEHEAT_CMD_FAILURE) {
 		dbg (__FUNCTION__ " - command failed.");
-		return -1;
+		retval = -EIO;
+		goto exit;
 	}
 
-	if (info->command_finished == WHITEHEAT_CMD_COMPLETE) {
+	if (info->command_finished == WHITEHEAT_CMD_COMPLETE)
 		dbg (__FUNCTION__ " - command completed.");
-		return 0;
-	}
 
-	return 0;
+exit:
+	return retval;
 }
 
 
@@ -298,10 +304,12 @@
 	struct whiteheat_min_set	open_command;
 	struct usb_serial_port 		*command_port;
 	struct whiteheat_private	*info;
-	int				result;
+	int				retval = 0;
 
 	dbg(__FUNCTION__" - port %d", port->number);
 
+	down (&port->sem);
+
 	++port->open_count;
 	MOD_INC_USE_COUNT;
 	
@@ -314,7 +322,8 @@
 			info = (struct whiteheat_private *)kmalloc (sizeof(struct whiteheat_private), GFP_KERNEL);
 			if (info == NULL) {
 				err(__FUNCTION__ " - out of memory");
-				return -ENOMEM;
+				retval = -ENOMEM;
+				goto error_exit;
 			}
 			
 			init_waitqueue_head(&info->wait_command);
@@ -323,27 +332,45 @@
 			command_port->read_urb->complete = command_port_read_callback;
 			command_port->read_urb->dev = port->serial->dev;
 			command_port->tty = port->tty;		/* need this to "fake" our our sanity check macros */
-			usb_submit_urb (command_port->read_urb);
+			retval = usb_submit_urb (command_port->read_urb);
+			if (retval) {
+				err(__FUNCTION__ " - failed submitting read urb, error %d", retval);
+				goto error_exit;
+			}
 		}
 		
 		/* Start reading from the device */
 		port->read_urb->dev = port->serial->dev;
-		result = usb_submit_urb(port->read_urb);
-		if (result)
-			err(__FUNCTION__ " - failed submitting read urb, error %d", result);
+		retval = usb_submit_urb(port->read_urb);
+		if (retval) {
+			err(__FUNCTION__ " - failed submitting read urb, error %d", retval);
+			goto error_exit;
+		}
 	
 		/* send an open port command */
 		/* firmware uses 1 based port numbering */
 		open_command.port = port->number - port->serial->minor + 1;
-		whiteheat_send_cmd (port->serial, WHITEHEAT_OPEN, (__u8 *)&open_command, sizeof(open_command));
+		retval = whiteheat_send_cmd (port->serial, WHITEHEAT_OPEN, (__u8 *)&open_command, sizeof(open_command));
+		if (retval)
+			goto error_exit;
 	
 		/* Need to do device specific setup here (control lines, baud rate, etc.) */
 		/* FIXME!!! */
 	}
 
 	dbg(__FUNCTION__ " - exit");
+	up (&port->sem);
 	
-	return 0;
+	return retval;
+
+error_exit:
+	--port->open_count;
+	MOD_DEC_USE_COUNT;
+
+	dbg(__FUNCTION__ " - error_exit");
+	up (&port->sem);
+	
+	return retval;
 }
 
 
@@ -353,6 +380,7 @@
 	
 	dbg(__FUNCTION__ " - port %d", port->number);
 	
+	down (&port->sem);
 	--port->open_count;
 
 	if (port->open_count <= 0) {
@@ -370,6 +398,7 @@
 		port->active = 0;
 	}
 	MOD_DEC_USE_COUNT;
+	up (&port->sem);
 }
 
 
@@ -388,18 +417,19 @@
 
 	dbg(__FUNCTION__ " -port %d", port->number);
 
+	down (&port->sem);
 	/* check that they really want us to change something */
 	if (old_termios) {
 		if ((cflag == old_termios->c_cflag) &&
 		    (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
 			dbg(__FUNCTION__ " - nothing to change...");
-			return;
+			goto exit;
 		}
 	}
 
 	if ((!port->tty) || (!port->tty->termios)) {
 		dbg(__FUNCTION__" - no tty structures");
-		return;
+		goto exit;
 	}
 	
 	/* set the port number */
@@ -466,6 +496,8 @@
 	/* now send the message to the device */
 	whiteheat_send_cmd (port->serial, WHITEHEAT_SETUP_PORT, (__u8 *)&port_settings, sizeof(port_settings));
 	
+exit:
+	up (&port->sem);
 	return;
 }
 
@@ -626,8 +658,7 @@
 {
 	usb_serial_register (&whiteheat_fake_device);
 	usb_serial_register (&whiteheat_device);
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/storage/debug.c linux/drivers/usb/storage/debug.c
--- v2.4.5/linux/drivers/usb/storage/debug.c	Fri Sep  8 16:39:12 2000
+++ linux/drivers/usb/storage/debug.c	Tue Jun 12 11:17:17 2001
@@ -302,6 +302,8 @@
 	case 0x1C00: what="defect list not found"; break;
 	case 0x2400: what="invalid field in CDB"; break;
 	case 0x2703: what="associated write protect"; break;
+	case 0x2800: what="not ready to ready transition (media change?)";
+		break;
 	case 0x2903: what="bus device reset function occurred"; break;
 	case 0x2904: what="device internal reset"; break;
 	case 0x2B00: what="copy can't execute since host can't disconnect"; 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/uhci.c linux/drivers/usb/uhci.c
--- v2.4.5/linux/drivers/usb/uhci.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/uhci.c	Tue Jun 12 17:03:01 2001
@@ -425,8 +425,7 @@
 
 	/* Only go through the hoops if it's actually linked in */
 	if (list_empty(&qh->list)) {
-		uhci_free_qh(uhci, qh);
-		return;
+		goto list;
 	}
 
 	qh->urbp = NULL;
@@ -444,6 +443,7 @@
 
 	spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
 
+list:
 	spin_lock_irqsave(&uhci->qh_remove_list_lock, flags);
 
 	/* Check to see if the remove list is empty. Set the IOC bit */
@@ -2922,15 +2922,17 @@
 }
 
 #ifdef CONFIG_PM
-static void uhci_pci_suspend(struct pci_dev *dev)
+static int uhci_pci_suspend(struct pci_dev *dev, u32 state)
 {
 	reset_hc((struct uhci *) dev->driver_data);
+	return 0;
 }
 
-static void uhci_pci_resume(struct pci_dev *dev)
+static int uhci_pci_resume(struct pci_dev *dev)
 {
 	reset_hc((struct uhci *) dev->driver_data);
 	start_hc((struct uhci *) dev->driver_data);
+	return 0;
 }
 #endif
 
@@ -2990,8 +2992,7 @@
 	if (retval)
 		goto init_failed;
 
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 
 	return 0;
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/usb-ohci.c linux/drivers/usb/usb-ohci.c
--- v2.4.5/linux/drivers/usb/usb-ohci.c	Tue May 22 13:55:49 2001
+++ linux/drivers/usb/usb-ohci.c	Wed Jun 27 13:15:17 2001
@@ -2585,15 +2585,15 @@
 
 /*-------------------------------------------------------------------------*/
 
-static void
-ohci_pci_suspend (struct pci_dev *dev)
+static int
+ohci_pci_suspend (struct pci_dev *dev, u32 state)
 {
 	ohci_t		*ohci = (ohci_t *) dev->driver_data;
 
 	if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) {
 		dbg ("can't suspend usb-%s (state is %s)", dev->slot_name,
 			hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS));
-		return;
+		return -EIO;
 	}
 
 	/* act as if usb suspend can always be used */
@@ -2605,11 +2605,13 @@
 	ohci->hc_control = OHCI_USB_SUSPEND;
 	writel (ohci->hc_control, &ohci->regs->control);
 	wait_ms (10);
+
+	return 0;
 }
 
 /*-------------------------------------------------------------------------*/
 
-static void
+static int
 ohci_pci_resume (struct pci_dev *dev)
 {
 	ohci_t		*ohci = (ohci_t *) dev->driver_data;
@@ -2620,7 +2622,7 @@
 	if (atomic_read (&ohci->resume_count) != 1) {
 		err ("concurrent PCI resumes for usb-%s", dev->slot_name);
 		atomic_dec (&ohci->resume_count);
-		return;
+		return -EBUSY;
 	}
 
 	/* did we suspend, or were we powered off? */
@@ -2653,7 +2655,7 @@
 		if (temp != OHCI_USB_RESUME) {
 			err ("controller usb-%s won't resume", dev->slot_name);
 			ohci->disabled = 1;
-			return;
+			return -EIO;
 		}
 
 		ohci->disabled = 0;
@@ -2676,6 +2678,8 @@
 
 	/* controller is operational, extra resumes are harmless */
 	atomic_dec (&ohci->resume_count);
+
+	return 0;
 }
 
 #endif	/* CONFIG_PM */
@@ -2774,8 +2778,7 @@
 #ifdef CONFIG_PMAC_PBOOK
 	pmu_register_sleep_notifier (&ohci_sleep_notifier);
 #endif  
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return ret;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/usb-ohci.h linux/drivers/usb/usb-ohci.h
--- v2.4.5/linux/drivers/usb/usb-ohci.h	Sun May 20 12:11:39 2001
+++ linux/drivers/usb/usb-ohci.h	Tue Jun 12 15:53:37 2001
@@ -116,7 +116,7 @@
 	dma_addr_t td_dma;
 	dma_addr_t data_dma;
 	__u32 unused2[2];
-} __attribute((aligned(16)));
+} __attribute((aligned(32)));	/* normally 16, iso needs 32 */
 typedef struct td td_t;
 
 #define OHCI_ED_SKIP	(1 << 14)
@@ -562,7 +562,7 @@
 {
 	ohci->td_cache = pci_pool_create ("ohci_td", ohci->ohci_dev,
 		sizeof (struct td),
-		16 /* byte alignment */,
+		32 /* byte alignment */,
 		0 /* no page-crossing issues */,
 		GFP_KERNEL | OHCI_MEM_FLAGS);
 	if (!ohci->td_cache)
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/usb-uhci.c linux/drivers/usb/usb-uhci.c
--- v2.4.5/linux/drivers/usb/usb-uhci.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/usb-uhci.c	Wed Jun 27 13:15:17 2001
@@ -2897,16 +2897,18 @@
 }
 
 #ifdef CONFIG_PM
-_static void
-uhci_pci_suspend (struct pci_dev *dev)
+_static int
+uhci_pci_suspend (struct pci_dev *dev, u32 state)
 {
 	reset_hc((uhci_t *) dev->driver_data);
+	return 0;
 }
 
-_static void
+_static int
 uhci_pci_resume (struct pci_dev *dev)
 {
 	start_hc((uhci_t *) dev->driver_data);
+	return 0;
 }
 #endif
 
@@ -3108,8 +3110,7 @@
 	}
 #endif
 	
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 
 	return retval;
 }
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/usb.c linux/drivers/usb/usb.c
--- v2.4.5/linux/drivers/usb/usb.c	Sat Apr 28 11:28:09 2001
+++ linux/drivers/usb/usb.c	Tue Jun 12 15:53:37 2001
@@ -449,7 +449,7 @@
 	 */
 	list_del(&bus->bus_list);
 
-        usbdevfs_remove_bus(bus);
+	usbdevfs_remove_bus(bus);
 
 	clear_bit(bus->busnum, busmap.busmap);
 
@@ -1869,6 +1869,7 @@
 {
 	int result;
 	__u16 status;
+	unsigned char *buffer;
 	int endp=usb_pipeendpoint(pipe)|(usb_pipein(pipe)<<7);
 
 /*
@@ -1883,9 +1884,19 @@
 	if (result < 0)
 		return result;
 
+	buffer = kmalloc(sizeof(status), GFP_KERNEL);
+	if (!buffer) {
+		err("unable to allocate memory for configuration descriptors");
+		return -ENOMEM;
+	}
+
 	result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
 		USB_REQ_GET_STATUS, USB_DIR_IN | USB_RECIP_ENDPOINT, 0, endp,
-		&status, sizeof(status), HZ * SET_TIMEOUT);
+		buffer, sizeof(status), HZ * SET_TIMEOUT);
+
+	memcpy(&status, buffer, sizeof(status));
+	kfree(buffer);
+
 	if (result < 0)
 		return result;
 
@@ -1970,10 +1981,9 @@
 {
 	int result;
 	unsigned int cfgno, length;
-	unsigned char buffer[8];
+	unsigned char *buffer;
 	unsigned char *bigbuffer;
-	struct usb_config_descriptor *desc =
-		(struct usb_config_descriptor *)buffer;
+ 	struct usb_config_descriptor *desc;
 
 	if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG) {
 		warn("too many configurations");
@@ -2002,6 +2012,13 @@
 		return -ENOMEM;
 	}
 
+	buffer = kmalloc(8, GFP_KERNEL);
+	if (!buffer) {
+		err("unable to allocate memory for configuration descriptors");
+		return -ENOMEM;
+	}
+	desc = (struct usb_config_descriptor *)buffer;
+
 	for (cfgno = 0; cfgno < dev->descriptor.bNumConfigurations; cfgno++) {
 		/* We grab the first 8 bytes so we know how long the whole */
 		/*  configuration is */
@@ -2052,8 +2069,10 @@
 		}
 	}
 
+	kfree(buffer);
 	return 0;
 err:
+	kfree(buffer);
 	dev->descriptor.bNumConfigurations = cfgno;
 	return result;
 }
@@ -2162,7 +2181,7 @@
 	dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
 
 	err = usb_get_device_descriptor(dev);
-	if (err < sizeof(dev->descriptor)) {
+	if (err < (signed)sizeof(dev->descriptor)) {
 		if (err < 0)
 			err("unable to get device descriptor (error=%d)", err);
 		else
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/usbkbd.c linux/drivers/usb/usbkbd.c
--- v2.4.5/linux/drivers/usb/usbkbd.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/usbkbd.c	Tue Jun 12 15:53:37 2001
@@ -280,8 +280,7 @@
 static int __init usb_kbd_init(void)
 {
 	usb_register(&usb_kbd_driver);
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/usbmouse.c linux/drivers/usb/usbmouse.c
--- v2.4.5/linux/drivers/usb/usbmouse.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/usbmouse.c	Tue Jun 12 15:53:37 2001
@@ -194,8 +194,7 @@
 static int __init usb_mouse_init(void)
 {
 	usb_register(&usb_mouse_driver);
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/uss720.c linux/drivers/usb/uss720.c
--- v2.4.5/linux/drivers/usb/uss720.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/uss720.c	Tue Jun 12 15:53:37 2001
@@ -659,8 +659,7 @@
 	if (usb_register(&uss720_driver) < 0)
 		return -1;
 
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/wacom.c linux/drivers/usb/wacom.c
--- v2.4.5/linux/drivers/usb/wacom.c	Mon May 21 15:02:06 2001
+++ linux/drivers/usb/wacom.c	Tue Jun 12 15:53:37 2001
@@ -415,8 +415,7 @@
 static int __init wacom_init(void)
 {
 	usb_register(&wacom_driver);
-	info(DRIVER_VERSION " " DRIVER_AUTHOR);
-	info(DRIVER_DESC);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/video/aty128fb.c linux/drivers/video/aty128fb.c
--- v2.4.5/linux/drivers/video/aty128fb.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/video/aty128fb.c	Wed Jun 20 21:00:55 2001
@@ -274,10 +274,10 @@
     struct fb_info fb_info;
     struct fb_info_aty128 *next;
     struct aty128_constants constants;  /* PLL and others      */
-    u32 regbase_phys;                   /* physical mmio       */
+    unsigned long regbase_phys;         /* physical mmio       */
     void *regbase;                      /* remapped mmio       */
-    u32 frame_buffer_phys;              /* physical fb memory  */
-    u32 frame_buffer;                   /* remaped framebuffer */
+    unsigned long frame_buffer_phys;    /* physical fb memory  */
+    void *frame_buffer;                 /* remaped framebuffer */
     u32 vram_size;                      /* onboard video ram   */
     int chip_gen;
     const struct aty128_meminfo *mem;   /* onboard mem info    */
@@ -1380,7 +1380,7 @@
 	struct fb_fix_screeninfo fix;
 
 	aty128_encode_fix(&fix, &par, info);
-        display->screen_base = (char *)info->frame_buffer;
+        display->screen_base = info->frame_buffer;
 	display->visual = fix.visual;
 	display->type = fix.type;
 	display->type_aux = fix.type_aux;
@@ -1833,7 +1833,7 @@
                                const struct aty128_chip_info *aci)
 {
 	struct fb_info_aty128 *info = NULL;
-	u32 fb_addr, reg_addr;
+	unsigned long fb_addr, reg_addr;
 	int err;
 #if !defined(CONFIG_PPC) && !defined(__sparc__)
 	char *bios_seg = NULL;
@@ -1885,7 +1885,7 @@
 
 	/* Virtualize the framebuffer */
 	info->frame_buffer_phys = fb_addr;
-	info->frame_buffer = (u32)ioremap(fb_addr, info->vram_size);
+	info->frame_buffer = ioremap(fb_addr, info->vram_size);
 
 	if (!info->frame_buffer) {
 		iounmap((void *)info->regbase);
@@ -1931,8 +1931,8 @@
 	return 0;
 
 err_out:
-	iounmap((void *)info->frame_buffer);
-	iounmap((void *)info->regbase);
+	iounmap(info->frame_buffer);
+	iounmap(info->regbase);
 err_free_info:
 	kfree(info);
 err_unmap_out:
@@ -2622,7 +2622,7 @@
                      info->vram_size);
 #endif /* CONFIG_MTRR */
         iounmap(info->regbase);
-        iounmap(&info->frame_buffer);
+        iounmap(info->frame_buffer);
 
         release_mem_region(pci_resource_start(info->pdev, 0),
                            pci_resource_len(info->pdev, 0));
diff -u --recursive --new-file v2.4.5/linux/drivers/video/atyfb.c linux/drivers/video/atyfb.c
--- v2.4.5/linux/drivers/video/atyfb.c	Wed May 16 10:31:23 2001
+++ linux/drivers/video/atyfb.c	Mon Jun 11 19:15:27 2001
@@ -3213,7 +3213,7 @@
 static void atyfb_save_palette(struct fb_info *fb, int enter)
 {
 	struct fb_info_aty *info = (struct fb_info_aty *)fb;
-	int i, tmp, scale;
+	int i, tmp;
 
 	for (i = 0; i < 256; i++) {
 		tmp = aty_ld_8(DAC_CNTL, info) & 0xfc;
@@ -3225,14 +3225,11 @@
 		aty_st_8(DAC_CNTL, tmp, info);
 		aty_st_8(DAC_MASK, 0xff, info);
 
-		scale = ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID) &&
-			(info->current_par.crtc.bpp == 16)) ? 3 : 0;
-		writeb(i << scale, &info->aty_cmap_regs->rindex);
-
+		writeb(i, &info->aty_cmap_regs->rindex);
 		atyfb_save.r[enter][i] = readb(&info->aty_cmap_regs->lut);
 		atyfb_save.g[enter][i] = readb(&info->aty_cmap_regs->lut);
 		atyfb_save.b[enter][i] = readb(&info->aty_cmap_regs->lut);
-		writeb(i << scale, &info->aty_cmap_regs->windex);
+		writeb(i, &info->aty_cmap_regs->windex);
 		writeb(atyfb_save.r[1-enter][i], &info->aty_cmap_regs->lut);
 		writeb(atyfb_save.g[1-enter][i], &info->aty_cmap_regs->lut);
 		writeb(atyfb_save.b[1-enter][i], &info->aty_cmap_regs->lut);
diff -u --recursive --new-file v2.4.5/linux/drivers/video/creatorfb.c linux/drivers/video/creatorfb.c
--- v2.4.5/linux/drivers/video/creatorfb.c	Sun Mar 25 18:14:20 2001
+++ linux/drivers/video/creatorfb.c	Tue Jun 12 11:08:46 2001
@@ -1,4 +1,4 @@
-/* $Id: creatorfb.c,v 1.34 2001/03/16 10:22:02 davem Exp $
+/* $Id: creatorfb.c,v 1.35 2001/06/08 21:48:37 davem Exp $
  * creatorfb.c: Creator/Creator3D frame buffer driver
  *
  * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz)
@@ -69,6 +69,15 @@
 #define	FFB_DAC_POFF		0x00400000UL
 #define	FFB_PROM_POFF		0x00000000UL
 #define	FFB_EXP_POFF		0x00200000UL
+#define FFB_DFB422A_POFF	0x09000000UL
+#define FFB_DFB422AD_POFF	0x09800000UL
+#define FFB_DFB24B_POFF		0x0a000000UL
+#define FFB_DFB422B_POFF	0x0b000000UL
+#define FFB_DFB422BD_POFF	0x0b800000UL
+#define FFB_SFB16Z_POFF		0x0c800000UL
+#define FFB_SFB8Z_POFF		0x0c000000UL
+#define FFB_SFB422_POFF		0x0d000000UL
+#define FFB_SFB422D_POFF	0x0d800000UL
 
 /* Draw operations */
 #define FFB_DRAWOP_DOT		0x00
@@ -330,6 +339,15 @@
 	{ FFB_DAC_VOFF,		FFB_DAC_POFF,		0x0002000 },
 	{ FFB_PROM_VOFF,	FFB_PROM_POFF,		0x0010000 },
 	{ FFB_EXP_VOFF,		FFB_EXP_POFF,		0x0002000 },
+	{ FFB_DFB422A_VOFF,	FFB_DFB422A_POFF,	0x0800000 },
+	{ FFB_DFB422AD_VOFF,	FFB_DFB422AD_POFF,	0x0800000 },
+	{ FFB_DFB24B_VOFF,	FFB_DFB24B_POFF,	0x1000000 },
+	{ FFB_DFB422B_VOFF,	FFB_DFB422B_POFF,	0x0800000 },
+	{ FFB_DFB422BD_VOFF,	FFB_DFB422BD_POFF,	0x0800000 },
+	{ FFB_SFB16Z_VOFF,	FFB_SFB16Z_POFF,	0x0800000 },
+	{ FFB_SFB8Z_VOFF,	FFB_SFB8Z_POFF,		0x0800000 },
+	{ FFB_SFB422_VOFF,	FFB_SFB422_POFF,	0x0800000 },
+	{ FFB_SFB422D_VOFF,	FFB_SFB422D_POFF,	0x0800000 },
 	{ 0,			0,			0	  }
 };
 
diff -u --recursive --new-file v2.4.5/linux/drivers/video/cyber2000fb.c linux/drivers/video/cyber2000fb.c
--- v2.4.5/linux/drivers/video/cyber2000fb.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/video/cyber2000fb.c	Wed Jun 27 13:15:17 2001
@@ -1612,14 +1612,15 @@
 	}
 }
 
-static void cyberpro_suspend(struct pci_dev *dev)
+static int cyberpro_suspend(struct pci_dev *dev, u32 state)
 {
+	return 0;
 }
 
 /*
  * Re-initialise the CyberPro hardware
  */
-static void cyberpro_resume(struct pci_dev *dev)
+static int cyberpro_resume(struct pci_dev *dev)
 {
 	struct cfb_info *cfb = (struct cfb_info *)dev->driver_data;
 
@@ -1633,6 +1634,8 @@
 		cfb->fb.var.activate = FB_ACTIVATE_NOW;
 		cyber2000fb_set_var(&cfb->fb.var, -1, &cfb->fb);
 	}
+
+	return 0;
 }
 
 static struct pci_device_id cyberpro_pci_table[] __devinitdata = {
diff -u --recursive --new-file v2.4.5/linux/drivers/video/fbcon.c linux/drivers/video/fbcon.c
--- v2.4.5/linux/drivers/video/fbcon.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/video/fbcon.c	Mon Jun 11 19:15:27 2001
@@ -2060,44 +2060,32 @@
     if (!fb)
 	return 0;
 	
-    /* Set colors if visual is PSEUDOCOLOR and we have enough colors, or for
-     * DIRECTCOLOR */
-    if ((p->visual == FB_VISUAL_PSEUDOCOLOR && depth >= 4) ||
-	p->visual == FB_VISUAL_DIRECTCOLOR) {
-	int is_truecolor = (p->visual == FB_VISUAL_DIRECTCOLOR);
-	int use_256 = (!is_truecolor && depth >= 8) ||
-		      (is_truecolor && depth >= 24);
-	int first_col = use_256 ? 32 : depth > 4 ? 16 : 0;
-	int num_cols = use_256 ? LINUX_LOGO_COLORS : 16;
-	unsigned char *red, *green, *blue;
-	
-	if (use_256) {
-	    red   = linux_logo_red;
-	    green = linux_logo_green;
-	    blue  = linux_logo_blue;
-	}
-	else {
-	    red   = linux_logo16_red;
-	    green = linux_logo16_green;
-	    blue  = linux_logo16_blue;
-	}
-
-	for( i = 0; i < num_cols; i += n ) {
-	    n = num_cols - i;
+    /*
+     * Set colors if visual is PSEUDOCOLOR and we have enough colors, or for
+     * DIRECTCOLOR
+     * We don't have to set the colors for the 16-color logo, since that logo
+     * uses the standard VGA text console palette
+     */
+    if ((p->visual == FB_VISUAL_PSEUDOCOLOR && depth >= 8) ||
+	(p->visual == FB_VISUAL_DIRECTCOLOR && depth >= 24))
+	for (i = 0; i < LINUX_LOGO_COLORS; i += n) {
+	    n = LINUX_LOGO_COLORS - i;
 	    if (n > 16)
 		/* palette_cmap provides space for only 16 colors at once */
 		n = 16;
-	    palette_cmap.start = first_col + i;
+	    palette_cmap.start = 32 + i;
 	    palette_cmap.len   = n;
 	    for( j = 0; j < n; ++j ) {
-		palette_cmap.red[j]   = (red[i+j] << 8) | red[i+j];
-		palette_cmap.green[j] = (green[i+j] << 8) | green[i+j];
-		palette_cmap.blue[j]  = (blue[i+j] << 8) | blue[i+j];
+		palette_cmap.red[j]   = (linux_logo_red[i+j] << 8) |
+					linux_logo_red[i+j];
+		palette_cmap.green[j] = (linux_logo_green[i+j] << 8) |
+					linux_logo_green[i+j];
+		palette_cmap.blue[j]  = (linux_logo_blue[i+j] << 8) |
+					linux_logo_blue[i+j];
 	    }
 	    p->fb_info->fbops->fb_set_cmap(&palette_cmap, 1, fg_console,
 					   p->fb_info);
 	}
-    }
 	
     if (depth >= 8) {
 	logo = linux_logo;
@@ -2155,15 +2143,15 @@
 		    }
 		}
 	    }
-	    else if (depth >= 15 && depth <= 23) {
-	        /* have 5..7 bits per color, using 16 color image */
+	    else if (depth >= 12 && depth <= 23) {
+	        /* have 4..7 bits per color, using 16 color image */
 		unsigned int pix;
 		src = linux_logo16;
 		bdepth = (depth+7)/8;
 		for( y1 = 0; y1 < LOGO_H; y1++ ) {
 		    dst = fb + y1*line + x*bdepth;
 		    for( x1 = 0; x1 < LOGO_W/2; x1++, src++ ) {
-			pix = (*src >> 4) | 0x10; /* upper nibble */
+			pix = *src >> 4; /* upper nibble */
 			val = (pix << redshift) |
 			      (pix << greenshift) |
 			      (pix << blueshift);
@@ -2173,7 +2161,7 @@
 			for( i = bdepth-1; i >= 0; --i )
 #endif
 			    fb_writeb (val >> (i*8), dst++);
-			pix = (*src & 0x0f) | 0x10; /* lower nibble */
+			pix = *src & 0x0f; /* lower nibble */
 			val = (pix << redshift) |
 			      (pix << greenshift) |
 			      (pix << blueshift);
@@ -2297,16 +2285,13 @@
 		}
 	    }
 	
-	    /* fill remaining planes
-	     * special case for logo_depth == 4: we used color registers 16..31,
-	     * so fill plane 4 with 1 bits instead of 0 */
+	    /* fill remaining planes */
 	    if (depth > logo_depth) {
 		for( y1 = 0; y1 < LOGO_H; y1++ ) {
 		    for( x1 = 0; x1 < LOGO_LINE; x1++ ) {
 			dst = fb + y1*line + MAP_X(x/8+x1) + logo_depth*plane;
 			for( i = logo_depth; i < depth; i++, dst += plane )
-			    *dst = (i == logo_depth && logo_depth == 4)
-				   ? 0xff : 0x00;
+			    *dst = 0x00;
 		    }
 		}
 	    }
diff -u --recursive --new-file v2.4.5/linux/drivers/video/imsttfb.c linux/drivers/video/imsttfb.c
--- v2.4.5/linux/drivers/video/imsttfb.c	Wed Apr 18 11:49:12 2001
+++ linux/drivers/video/imsttfb.c	Wed Jun 27 17:10:55 2001
@@ -6,6 +6,7 @@
  *  With additional hacking by Jeffrey Kuskin (jsk@mojave.stanford.edu)
  *  Modified by Danilo Beuche 1998
  *  Some register values added by Damien Doligez, INRIA Rocquencourt
+ *  Various cleanups by Paul Mundt (lethal@chaoticdreams.org)
  *
  *  This file was written by Ryan Nielsen (ran@krazynet.com)
  *  Most of the frame buffer device stuff was copied from atyfb.c
@@ -378,6 +379,7 @@
 #define CURSOR_DRAW_DELAY	2
 
 static int currcon = 0;
+static int inverse = 0;
 static char fontname[40] __initdata = { 0 };
 static char curblink __initdata = 1;
 static char noaccel __initdata = 0;
@@ -1235,7 +1237,6 @@
 {
 	struct fb_info_imstt *p = (struct fb_info_imstt *)info;
 	u_int bpp = fb_display[currcon].var.bits_per_pixel;
-	u_int i;
 
 	if (regno > 255)
 		return 1;
@@ -1413,7 +1414,7 @@
 	disp->type_aux = p->fix.type_aux;
 	disp->line_length = disp->var.xres * (disp->var.bits_per_pixel >> 3);
 	disp->can_soft_blank = 1;
-	disp->inverse = 0;
+	disp->inverse = inverse;
 	disp->ypanstep = 1;
 	disp->ywrapstep = 0;
 	if (accel) {
@@ -1887,7 +1888,6 @@
 	struct pci_dev *pdev = NULL;
 	struct fb_info_imstt *p;
 	unsigned long addr, size;
-	__u16 cmd;
 
 	while ((pdev = pci_find_device(PCI_VENDOR_ID_IMS, PCI_ANY_ID, pdev))) {
 		if ((pdev->class >> 16) != PCI_BASE_CLASS_DISPLAY)
@@ -1963,6 +1963,9 @@
 			curblink = 0;
 		} else if (!strncmp(this_opt, "noaccel", 7)) {
 			noaccel = 1;
+		} else if (!strncmp(this_opt, "inverse", 7)) {
+			inverse = 1;
+			fb_invert_cmaps();
 		}
 #if defined(CONFIG_PPC)
 		else if (!strncmp(this_opt, "vmode:", 6)) {
@@ -1994,16 +1997,8 @@
 }
 
 #else /* MODULE */
-
-int __init
-init_module (void)
-{
-
-	return imsttfb_init();
-}
-
-void
-cleanup_module (void)
+static void __exit
+imsttfb_exit(void)
 {
 	struct fb_info_imstt *p;
 	__u32 i;
@@ -2012,13 +2007,18 @@
 		p = fb_info_imstt_p[i];
 		if (!p)
 			continue;
+		unregister_framebuffer(&p->info);
 		iounmap(p->cmap_regs);
 		iounmap(p->dc_regs);
 		iounmap(p->frame_buffer);
-		kfree(p);
 		release_mem_region(p->frame_buffer_phys, p->board_size);
+		kfree(p);
 	}
 }
 
 #include "macmodes.c"
+
+module_init(imsttfb_init);
+module_exit(imsttfb_exit);
 #endif /* MODULE */
+
diff -u --recursive --new-file v2.4.5/linux/drivers/video/macmodes.c linux/drivers/video/macmodes.c
--- v2.4.5/linux/drivers/video/macmodes.c	Fri Mar  2 18:38:39 2001
+++ linux/drivers/video/macmodes.c	Wed Jun 27 17:10:55 2001
@@ -94,7 +94,15 @@
 	/* 1280x1024, 75 Hz, Non-Interlaced (135.00 MHz dotclock) */
 	"mac20", 75, 1280, 1024, 7408, 232, 64, 38, 1, 112, 3,
 	FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-    },
+    }, {
+	/* 1152x768, 60 Hz, Titanium PowerBook */
+	"mac21", 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6,
+	FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+    }, {
+	/* 1600x1024, 60 Hz, Non-Interlaced (112.27 MHz dotclock) */
+	"mac22", 60, 1600, 1024, 8908, 88, 104, 1, 10, 16, 1,
+	FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+    }
 
 #if 0
     /* Anyone who has timings for these? */
@@ -154,12 +162,16 @@
     { VMODE_1024_768_75V, &mac_modedb[9] },
     { VMODE_1024_768_70, &mac_modedb[8] },
     { VMODE_1024_768_60, &mac_modedb[7] },
+    /* 1152x768 */
+    { VMODE_1152_768_60, &mac_modedb[14] },
     /* 1152x870 */
     { VMODE_1152_870_75, &mac_modedb[11] },
     /* 1280x960 */
     { VMODE_1280_960_75, &mac_modedb[12] },
     /* 1280x1024 */
     { VMODE_1280_1024_75, &mac_modedb[13] },
+    /* 1600x1024 */
+    { VMODE_1600_1024_60, &mac_modedb[15] },
     { -1, NULL }
 };
 
@@ -191,6 +203,7 @@
     { 0x730, VMODE_768_576_50I },	/* PAL (Alternate) */
     { 0x73a, VMODE_1152_870_75 },	/* 3rd party 19" */
     { 0x73f, VMODE_640_480_67 },	/* no sense lines connected at all */
+    { 0xBEEF, VMODE_1600_1024_60 },	/* 22" Apple Cinema Display */
     { -1,    VMODE_640_480_60 },	/* catch-all, must be last */
 };
 
diff -u --recursive --new-file v2.4.5/linux/drivers/video/matrox/matroxfb_DAC1064.c linux/drivers/video/matrox/matroxfb_DAC1064.c
--- v2.4.5/linux/drivers/video/matrox/matroxfb_DAC1064.c	Wed Apr 11 19:21:35 2001
+++ linux/drivers/video/matrox/matroxfb_DAC1064.c	Wed Jun 27 17:10:55 2001
@@ -4,7 +4,7 @@
  *
  * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>
  *
- * Version: 1.52 2001/02/02
+ * Version: 1.53 2001/06/18
  *
  * See matroxfb_base.c for contributors.
  *
@@ -33,12 +33,14 @@
 #define DAC1064_OPT_RESERVED	0x10
 
 static void matroxfb_DAC1064_flashcursor(unsigned long ptr) {
+	unsigned long flags;
+
 #define minfo ((struct matrox_fb_info*)ptr)
-	matroxfb_DAC_lock();
+	matroxfb_DAC_lock_irqsave(flags);
 	outDAC1064(PMINFO M1064_XCURCTRL, inDAC1064(PMINFO M1064_XCURCTRL) ^ M1064_XCURCTRL_DIS ^ M1064_XCURCTRL_XGA);
 	ACCESS_FBINFO(cursor.timer.expires) = jiffies + HZ/2;
 	add_timer(&ACCESS_FBINFO(cursor.timer));
-	matroxfb_DAC_unlock();
+	matroxfb_DAC_unlock_irqrestore(flags);
 #undef minfo
 }
 
@@ -719,7 +721,8 @@
 	ACCESS_FBINFO(capable.vxres) = vxres_g100;
 	ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
 	ACCESS_FBINFO(cursor.timer.function) = matroxfb_DAC1064_flashcursor;
-	ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) != FB_ACCEL_MATROX_MGAG100;
+	ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100
+			? ACCESS_FBINFO(devflags.sgram) : 1;
 
 	ACCESS_FBINFO(primout) = &m1064;
 
diff -u --recursive --new-file v2.4.5/linux/drivers/video/matrox/matroxfb_Ti3026.c linux/drivers/video/matrox/matroxfb_Ti3026.c
--- v2.4.5/linux/drivers/video/matrox/matroxfb_Ti3026.c	Thu Aug 10 12:34:31 2000
+++ linux/drivers/video/matrox/matroxfb_Ti3026.c	Wed Jun 27 17:10:55 2001
@@ -279,12 +279,14 @@
   0x00, 0x00, TVP3026_XCURCTRL_DIS };
 
 static void matroxfb_ti3026_flashcursor(unsigned long ptr) {
+	unsigned long flags;
+
 #define minfo ((struct matrox_fb_info*)ptr)
-	matroxfb_DAC_lock();
+	matroxfb_DAC_lock_irqsave(flags);
 	outTi3026(PMINFO TVP3026_XCURCTRL, inTi3026(PMINFO TVP3026_XCURCTRL) ^ TVP3026_XCURCTRL_DIS ^ TVP3026_XCURCTRL_XGA);
 	ACCESS_FBINFO(cursor.timer.expires) = jiffies + HZ/2;
 	add_timer(&ACCESS_FBINFO(cursor.timer));
-	matroxfb_DAC_unlock();
+	matroxfb_DAC_unlock_irqrestore(flags);
 #undef minfo
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/video/matrox/matroxfb_accel.c linux/drivers/video/matrox/matroxfb_accel.c
--- v2.4.5/linux/drivers/video/matrox/matroxfb_accel.c	Thu Aug 10 12:34:31 2000
+++ linux/drivers/video/matrox/matroxfb_accel.c	Wed Jun 27 17:10:55 2001
@@ -2,9 +2,9 @@
  *
  * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
  *
- * (c) 1998,1999,2000 Petr Vandrovec <vandrove@vc.cvut.cz>
+ * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>
  *
- * Version: 1.50 2000/08/10
+ * Version: 1.51 2001/06/18
  *
  * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
  *
@@ -129,6 +129,10 @@
 	mga_outl(M_YDSTORG, curr_ydstorg(MINFO));
 	if (ACCESS_FBINFO(capable.plnwt))
 		mga_outl(M_PLNWT, -1);
+	if (ACCESS_FBINFO(capable.srcorg)) {
+		mga_outl(M_SRCORG, 0);
+		mga_outl(M_DSTORG, 0);
+	}
 	mga_outl(M_OPMODE, mopmode);
 	mga_outl(M_CXBNDRY, 0xFFFF0000);
 	mga_outl(M_YTOP, 0);
diff -u --recursive --new-file v2.4.5/linux/drivers/video/matrox/matroxfb_base.c linux/drivers/video/matrox/matroxfb_base.c
--- v2.4.5/linux/drivers/video/matrox/matroxfb_base.c	Sun Feb  4 10:05:30 2001
+++ linux/drivers/video/matrox/matroxfb_base.c	Wed Jun 27 17:10:55 2001
@@ -4,7 +4,7 @@
  *
  * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>
  *
- * Version: 1.52 2001/02/02
+ * Version: 1.53 2001/06/18
  *
  * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
  *
@@ -72,6 +72,9 @@
  *               "Ken Aaker" <kdaaker@rchland.vnet.ibm.com>
  *                     memtype extension (needed for GXT130P RS/6000 adapter)
  *
+ *               "Uns Lider" <unslider@miranda.org>
+ *                     G100 PLNWT fixes
+ *
  * (following author is not in any relation with this code, but his code
  *  is included in this driver)
  *
@@ -1409,7 +1412,7 @@
 
 #define DEVF_VIDEO64BIT		0x0001
 #define	DEVF_SWAPS		0x0002
-/* #define DEVF_recycled	0x0004 */
+#define DEVF_SRCORG		0x0004
 /* #define DEVF_recycled	0x0008 */
 #define DEVF_CROSS4MB		0x0010
 #define DEVF_TEXT4B		0x0020
@@ -1424,12 +1427,12 @@
 #define DEVF_G450DAC		0x4000
 
 #define DEVF_GCORE	(DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB | DEVF_DDC_8_2)
-#define DEVF_G2CORE	(DEVF_GCORE | DEVF_ANY_VXRES | DEVF_MAVEN_CAPABLE | DEVF_PANELLINK_CAPABLE)
+#define DEVF_G2CORE	(DEVF_GCORE | DEVF_ANY_VXRES | DEVF_MAVEN_CAPABLE | DEVF_PANELLINK_CAPABLE | DEVF_SRCORG)
 #define DEVF_G100	(DEVF_GCORE) /* no doc, no vxres... */
 #define DEVF_G200	(DEVF_G2CORE)
 #define DEVF_G400	(DEVF_G2CORE | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2)
 /* if you'll find how to drive DFP... */
-#define DEVF_G450	(DEVF_GCORE | DEVF_ANY_VXRES | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2 | DEVF_G450DAC)
+#define DEVF_G450	(DEVF_GCORE | DEVF_ANY_VXRES | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2 | DEVF_G450DAC | DEVF_SRCORG)
 
 static struct board {
 	unsigned short vendor, device, rev, svid, sid;
@@ -1556,7 +1559,7 @@
 		DEVF_G200,
 		230000,
 		&vbG200,
-		"unknown G200 (AGP)"},
+		"G200 (AGP)"},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G400_AGP,	0x80,
 		PCI_SS_VENDOR_ID_MATROX,	PCI_SS_ID_MATROX_MILLENNIUM_G400_MAX_AGP,
 		DEVF_G400,
@@ -1568,13 +1571,13 @@
 		DEVF_G400,
 		300000,
 		&vbG400,
-		"unknown G400 (AGP)"},
+		"G400 (AGP)"},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G400_AGP,	0xFF,
 		0,			0,
 		DEVF_G450,
 		500000,		/* ??? vco goes up to 900MHz... */
 		&vbG400,
-		"unknown G450 (AGP)"},
+		"G450 (AGP)"},
 #endif
 	{0,			0,				0xFF,
 		0,			0,
@@ -1611,6 +1614,7 @@
 
 	printk(KERN_INFO "matroxfb: Matrox %s detected\n", b->name);
 	ACCESS_FBINFO(capable.plnwt) = 1;
+	ACCESS_FBINFO(capable.srcorg) = b->flags & DEVF_SRCORG;
 	ACCESS_FBINFO(devflags.video64bits) = b->flags & DEVF_VIDEO64BIT;
 	if (b->flags & DEVF_TEXT4B) {
 		ACCESS_FBINFO(devflags.vgastep) = 4;
@@ -2483,7 +2487,7 @@
 	return 0;
 }
 
-static int __init initialized = 0;
+static int __initdata initialized = 0;
 
 int __init matroxfb_init(void)
 {
@@ -2495,6 +2499,7 @@
 		initialized = 1;
 		matrox_init();
 	}
+	hotplug = 1;
 	/* never return failure, user can hotplug matrox later... */
 	return 0;
 }
@@ -2526,7 +2531,7 @@
 MODULE_PARM(mtrr, "i");
 MODULE_PARM_DESC(mtrr, "This speeds up video memory accesses (0=disabled or 1) (default=1)");
 MODULE_PARM(sgram, "i");
-MODULE_PARM_DESC(sgram, "Indicates that G200/G400 has SGRAM memory (0=SDRAM, 1=SGRAM) (default=0)");
+MODULE_PARM_DESC(sgram, "Indicates that G100/G200/G400 has SGRAM memory (0=SDRAM, 1=SGRAM) (default=0)");
 MODULE_PARM(inv24, "i");
 MODULE_PARM_DESC(inv24, "Inverts clock polarity for 24bpp and loop frequency > 100MHz (default=do not invert polarity)");
 MODULE_PARM(inverse, "i");
diff -u --recursive --new-file v2.4.5/linux/drivers/video/matrox/matroxfb_base.h linux/drivers/video/matrox/matroxfb_base.h
--- v2.4.5/linux/drivers/video/matrox/matroxfb_base.h	Fri Feb  9 11:30:23 2001
+++ linux/drivers/video/matrox/matroxfb_base.h	Wed Jun 27 17:10:55 2001
@@ -492,6 +492,7 @@
 		int		cross4MB;
 		int		text;
 		int		plnwt;
+		int		srcorg;
 			      } capable;
 	struct {
 		unsigned int	size;
@@ -738,6 +739,7 @@
 
 /* G200 only */
 #define M_SRCORG	0x2CB4
+#define M_DSTORG	0x2CB8
 
 #define M_RAMDAC_BASE	0x3C00
 
diff -u --recursive --new-file v2.4.5/linux/drivers/video/matrox/matroxfb_g450.c linux/drivers/video/matrox/matroxfb_g450.c
--- v2.4.5/linux/drivers/video/matrox/matroxfb_g450.c	Fri Dec 29 14:07:23 2000
+++ linux/drivers/video/matrox/matroxfb_g450.c	Wed Jun 27 17:10:55 2001
@@ -6,17 +6,20 @@
 
 static int matroxfb_g450_get_reg(WPMINFO int reg) {
 	int val;
+	unsigned long flags;
 
-	matroxfb_DAC_lock();
+	matroxfb_DAC_lock_irqsave(flags);
 	val = matroxfb_DAC_in(PMINFO reg);
-	matroxfb_DAC_unlock();
+	matroxfb_DAC_unlock_irqrestore(flags);
 	return val;
 }
 
 static int matroxfb_g450_set_reg(WPMINFO int reg, int val) {
-	matroxfb_DAC_lock();
+	unsigned long flags;
+
+	matroxfb_DAC_lock_irqsave(flags);
 	matroxfb_DAC_out(PMINFO reg, val);
-	matroxfb_DAC_unlock();
+	matroxfb_DAC_unlock_irqrestore(flags);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/drivers/video/mdacon.c linux/drivers/video/mdacon.c
--- v2.4.5/linux/drivers/video/mdacon.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/video/mdacon.c	Wed Jun 27 17:10:55 2001
@@ -21,6 +21,9 @@
  *  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.
+ *
+ *  Changelog:
+ *  Paul G. (03/2001) Fix mdacon= boot prompt to use __setup().
  */
 
 #include <linux/types.h>
@@ -129,6 +132,7 @@
 	spin_unlock_irqrestore(&mda_lock, flags);
 }
 
+#ifdef TEST_MDA_B
 static int test_mda_b(unsigned char val, unsigned char reg)
 {
 	unsigned long flags;
@@ -143,6 +147,7 @@
 	spin_unlock_irqrestore(&mda_lock, flags);
 	return val;
 }
+#endif
 
 static inline void mda_set_origin(unsigned int location)
 {
@@ -182,20 +187,27 @@
 
 
 #ifndef MODULE
-void __init mdacon_setup(char *str, int *ints)
+static int __init mdacon_setup(char *str)
 {
 	/* command line format: mdacon=<first>,<last> */
 
+	int ints[3];
+
+	str = get_options(str, ARRAY_SIZE(ints), ints);
+
 	if (ints[0] < 2)
-		return;
+		return 0;
 
 	if (ints[1] < 1 || ints[1] > MAX_NR_CONSOLES || 
 	    ints[2] < 1 || ints[2] > MAX_NR_CONSOLES)
-		return;
+		return 0;
 
-	mda_first_vc = ints[1]-1;
-	mda_last_vc  = ints[2]-1;
+	mda_first_vc = ints[1];
+	mda_last_vc  = ints[2];
+	return 1;
 }
+
+__setup("mdacon=", mdacon_setup);
 #endif
 
 static int __init mda_detect(void)
@@ -237,17 +249,19 @@
 	 * memory location, so now we do an I/O port test.
 	 */
 
+#ifdef TEST_MDA_B
 	/* Edward: These two mess `tests' mess up my cursor on bootup */
 
 	/* cursor low register */
-	/* if (! test_mda_b(0x66, 0x0f)) {
+	if (! test_mda_b(0x66, 0x0f)) {
 		return 0;
-	} */
+	}
 
 	/* cursor low register */
-	/* if (! test_mda_b(0x99, 0x0f)) {
+	if (! test_mda_b(0x99, 0x0f)) {
 		return 0;
-	} */
+	}
+#endif
 
 	/* See if the card is a Hercules, by checking whether the vsync
 	 * bit of the status register is changing.  This test lasts for
diff -u --recursive --new-file v2.4.5/linux/fs/Config.in linux/fs/Config.in
--- v2.4.5/linux/fs/Config.in	Sun May 20 12:11:38 2001
+++ linux/fs/Config.in	Wed Jun 20 11:10:27 2001
@@ -104,9 +104,9 @@
 
    dep_tristate 'SMB file system support (to mount Windows shares etc.)' CONFIG_SMB_FS $CONFIG_INET
    if [ "$CONFIG_SMB_FS" != "n" ]; then
-      bool '   Use a default NLS' CONFIG_SMB_NLS_DEFAULT
+      bool '  Use a default NLS' CONFIG_SMB_NLS_DEFAULT
       if [ "$CONFIG_SMB_NLS_DEFAULT" = "y" ]; then
-         string '  Default Remote NLS Option' CONFIG_SMB_NLS_REMOTE "cp437"
+         string '    Default Remote NLS Option' CONFIG_SMB_NLS_REMOTE "cp437"
       fi
    fi
    if [ "$CONFIG_IPX" != "n" -o "$CONFIG_INET" != "n" ]; then
diff -u --recursive --new-file v2.4.5/linux/fs/autofs/autofs_i.h linux/fs/autofs/autofs_i.h
--- v2.4.5/linux/fs/autofs/autofs_i.h	Fri Feb  9 11:29:44 2001
+++ linux/fs/autofs/autofs_i.h	Thu Jun 14 14:16:58 2001
@@ -89,7 +89,8 @@
 #define AUTOFS_FIRST_SYMLINK 2
 #define AUTOFS_FIRST_DIR_INO (AUTOFS_FIRST_SYMLINK+AUTOFS_MAX_SYMLINKS)
 
-#define AUTOFS_SYMLINK_BITMAP_LEN ((AUTOFS_MAX_SYMLINKS+31)/32)
+#define AUTOFS_SYMLINK_BITMAP_LEN \
+	((AUTOFS_MAX_SYMLINKS+((sizeof(long)*1)-1))/(sizeof(long)*8))
 
 #define AUTOFS_SBI_MAGIC 0x6d4a556d
 
@@ -103,7 +104,7 @@
 	struct autofs_wait_queue *queues; /* Wait queue pointer */
 	struct autofs_dirhash dirhash; /* Root directory hash */
 	struct autofs_symlink symlink[AUTOFS_MAX_SYMLINKS];
-	u32 symlink_bitmap[AUTOFS_SYMLINK_BITMAP_LEN];
+	unsigned long symlink_bitmap[AUTOFS_SYMLINK_BITMAP_LEN];
 };
 
 extern inline struct autofs_sb_info *autofs_sbi(struct super_block *sb)
diff -u --recursive --new-file v2.4.5/linux/fs/autofs/inode.c linux/fs/autofs/inode.c
--- v2.4.5/linux/fs/autofs/inode.c	Fri Feb  9 11:29:44 2001
+++ linux/fs/autofs/inode.c	Thu Jun 14 14:16:58 2001
@@ -132,7 +132,7 @@
 	sbi->oz_pgrp = current->pgrp;
 	autofs_initialize_hash(&sbi->dirhash);
 	sbi->queues = NULL;
-	memset(sbi->symlink_bitmap, 0, sizeof(u32)*AUTOFS_SYMLINK_BITMAP_LEN);
+	memset(sbi->symlink_bitmap, 0, sizeof(long)*AUTOFS_SYMLINK_BITMAP_LEN);
 	sbi->next_dir_ino = AUTOFS_FIRST_DIR_INO;
 	s->s_blocksize = 1024;
 	s->s_blocksize_bits = 10;
diff -u --recursive --new-file v2.4.5/linux/fs/autofs4/expire.c linux/fs/autofs4/expire.c
--- v2.4.5/linux/fs/autofs4/expire.c	Fri Apr 20 22:57:51 2001
+++ linux/fs/autofs4/expire.c	Mon Jun 11 19:15:27 2001
@@ -66,19 +66,11 @@
    non-busy mounts */
 static int check_vfsmnt(struct vfsmount *mnt, struct dentry *dentry)
 {
-	int ret = 0;
-	struct list_head *tmp;
-
-	list_for_each(tmp, &dentry->d_vfsmnt) {
-		struct vfsmount *vfs = list_entry(tmp, struct vfsmount, 
-						  mnt_clash);
-		DPRINTK(("check_vfsmnt: mnt=%p, dentry=%p, tmp=%p, vfs=%p\n",
-			 mnt, dentry, tmp, vfs));
-		if (vfs->mnt_parent != mnt || /* don't care about busy-ness of other namespaces */
-		    !is_vfsmnt_tree_busy(vfs))
-			ret++;
-	}
+	int ret = dentry->d_mounted;
+	struct vfsmount *vfs = lookup_mnt(mnt, dentry);
 
+	if (vfs && is_vfsmnt_tree_busy(vfs))
+		ret--;
 	DPRINTK(("check_vfsmnt: ret=%d\n", ret));
 	return ret;
 }
diff -u --recursive --new-file v2.4.5/linux/fs/block_dev.c linux/fs/block_dev.c
--- v2.4.5/linux/fs/block_dev.c	Tue May 22 09:35:42 2001
+++ linux/fs/block_dev.c	Mon Jun 11 19:15:27 2001
@@ -595,14 +595,15 @@
 
 int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg)
 {
-	kdev_t rdev = to_kdev_t(bdev->bd_dev);
 	struct inode inode_fake;
 	int res;
 	mm_segment_t old_fs = get_fs();
 
 	if (!bdev->bd_op->ioctl)
 		return -EINVAL;
-	inode_fake.i_rdev=rdev;
+	memset(&inode_fake, 0, sizeof(inode_fake));
+	inode_fake.i_rdev = to_kdev_t(bdev->bd_dev);
+	inode_fake.i_bdev = bdev;
 	init_waitqueue_head(&inode_fake.i_wait);
 	set_fs(KERNEL_DS);
 	res = bdev->bd_op->ioctl(&inode_fake, NULL, cmd, arg);
diff -u --recursive --new-file v2.4.5/linux/fs/buffer.c linux/fs/buffer.c
--- v2.4.5/linux/fs/buffer.c	Fri May 25 17:57:46 2001
+++ linux/fs/buffer.c	Tue Jun 12 10:21:14 2001
@@ -61,7 +61,7 @@
 
 #define BUFSIZE_INDEX(X) ((int) buffersize_index[(X)>>9])
 #define MAX_BUF_PER_PAGE (PAGE_CACHE_SIZE / 512)
-#define NR_RESERVED (2*MAX_BUF_PER_PAGE)
+#define NR_RESERVED (10*MAX_BUF_PER_PAGE)
 #define MAX_UNUSED_BUFFERS NR_RESERVED+20 /* don't ever have more than this 
 					     number of unused buffer heads */
 
@@ -646,8 +646,8 @@
 			/* Another device? */
 			if (bh->b_dev != dev)
 				continue;
-			/* Part of a mapping? */
-			if (bh->b_page->mapping)
+			/* Not hashed? */
+			if (!bh->b_pprev)
 				continue;
 			if (buffer_locked(bh)) {
 				atomic_inc(&bh->b_count);
@@ -711,6 +711,9 @@
 			bh_next = bh->b_next_free;
 			if (bh->b_dev != dev || bh->b_size == size)
 				continue;
+			/* Unhashed? */
+			if (!bh->b_pprev)
+				continue;
 			if (buffer_locked(bh)) {
 				atomic_inc(&bh->b_count);
 				spin_unlock(&lru_list_lock);
@@ -1348,11 +1351,9 @@
 	 */
 	run_task_queue(&tq_disk);
 
-	/* 
-	 * Set our state for sleeping, then check again for buffer heads.
-	 * This ensures we won't miss a wake_up from an interrupt.
-	 */
-	wait_event(buffer_wait, nr_unused_buffer_heads >= MAX_BUF_PER_PAGE);
+	current->policy |= SCHED_YIELD;
+	__set_current_state(TASK_RUNNING);
+	schedule();
 	goto try_again;
 }
 
diff -u --recursive --new-file v2.4.5/linux/fs/dcache.c linux/fs/dcache.c
--- v2.4.5/linux/fs/dcache.c	Tue May 22 09:35:42 2001
+++ linux/fs/dcache.c	Mon Jun 11 19:15:27 2001
@@ -616,7 +616,7 @@
 	dentry->d_name.hash = name->hash;
 	dentry->d_op = NULL;
 	dentry->d_fsdata = NULL;
-	INIT_LIST_HEAD(&dentry->d_vfsmnt);
+	dentry->d_mounted = 0;
 	INIT_LIST_HEAD(&dentry->d_hash);
 	INIT_LIST_HEAD(&dentry->d_lru);
 	INIT_LIST_HEAD(&dentry->d_subdirs);
@@ -1283,6 +1283,7 @@
 
 	dcache_init(mempages);
 	inode_init(mempages);
+	mnt_init(mempages);
 	bdev_cache_init();
 	cdev_cache_init();
 }
diff -u --recursive --new-file v2.4.5/linux/fs/devfs/base.c linux/fs/devfs/base.c
--- v2.4.5/linux/fs/devfs/base.c	Tue May 22 09:35:42 2001
+++ linux/fs/devfs/base.c	Wed Jun 20 10:54:31 2001
@@ -1,6 +1,6 @@
 /*  devfs (Device FileSystem) driver.
 
-    Copyright (C) 1998-2000  Richard Gooch
+    Copyright (C) 1998-2001  Richard Gooch
 
     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Library General Public
@@ -481,6 +481,32 @@
 	       Simplified interface to <devfs_find_handle>.
 	       Work sponsored by SGI.
   v0.102
+    20010519   Richard Gooch <rgooch@atnf.csiro.au>
+	       Ensure <devfs_generate_path> terminates string for root entry.
+	       Exported <devfs_get_name> to modules.
+    20010520   Richard Gooch <rgooch@atnf.csiro.au>
+	       Make <devfs_mk_symlink> send events to devfsd.
+	       Cleaned up option processing in <devfs_setup>.
+    20010521   Richard Gooch <rgooch@atnf.csiro.au>
+	       Fixed bugs in handling symlinks: could leak or cause Oops.
+    20010522   Richard Gooch <rgooch@atnf.csiro.au>
+	       Cleaned up directory handling by separating fops.
+  v0.103
+    20010601   Richard Gooch <rgooch@atnf.csiro.au>
+	       Fixed handling of inverted options in <devfs_setup>.
+  v0.104
+    20010604   Richard Gooch <rgooch@atnf.csiro.au>
+	       Adjusted <try_modload> to account for <devfs_generate_path> fix.
+  v0.105
+    20010617   Richard Gooch <rgooch@atnf.csiro.au>
+	       Answered question posed by Al Viro and removed his comments.
+	       Moved setting of registered flag after other fields are changed.
+	       Fixed race between <devfsd_close> and <devfsd_notify_one>.
+	       Global VFS changes added bogus BKL to <devfsd_close>: removed.
+	       Widened locking in <devfs_readlink> and <devfs_follow_link>.
+	       Replaced <devfsd_read> stack usage with <devfsd_ioctl> kmalloc.
+	       Simplified locking in <devfsd_ioctl> and fixed memory leak.
+  v0.106
 */
 #include <linux/types.h>
 #include <linux/errno.h>
@@ -515,7 +541,7 @@
 #include <asm/bitops.h>
 #include <asm/atomic.h>
 
-#define DEVFS_VERSION            "0.102 (20000622)"
+#define DEVFS_VERSION            "0.106 (20010617)"
 
 #define DEVFS_NAME "devfs"
 
@@ -560,7 +586,7 @@
 
 #define OPTION_NONE             0x00
 #define OPTION_SHOW             0x01
-#define OPTION_NOMOUNT          0x02
+#define OPTION_MOUNT            0x02
 #define OPTION_ONLY             0x04
 
 #define OOPS(format, args...) {printk (format, ## args); \
@@ -665,26 +691,27 @@
     gid_t gid;
 };
 
-struct fs_info      /*  This structure is for each mounted devfs  */
+struct fs_info      /*  This structure is for the mounted devfs  */
 {
     unsigned int num_inodes;    /*  Number of inodes created         */
     unsigned int table_size;    /*  Size of the inode pointer table  */
     struct devfs_entry **table;
     struct super_block *sb;
     volatile struct devfsd_buf_entry *devfsd_buffer;
+    spinlock_t devfsd_buffer_lock;
     volatile unsigned int devfsd_buf_in;
     volatile unsigned int devfsd_buf_out;
     volatile int devfsd_sleeping;
-    volatile int devfsd_buffer_in_use;
     volatile struct task_struct *devfsd_task;
     volatile struct file *devfsd_file;
+    struct devfsd_notify_struct *devfsd_info;
     volatile unsigned long devfsd_event_mask;
     atomic_t devfsd_overrun_count;
     wait_queue_head_t devfsd_wait_queue;
     wait_queue_head_t revalidate_wait_queue;
 };
 
-static struct fs_info fs_info;
+static struct fs_info fs_info = {devfsd_buffer_lock: SPIN_LOCK_UNLOCKED};
 static unsigned int next_devnum_char = MIN_DEVNUM;
 static unsigned int next_devnum_block = MIN_DEVNUM;
 static const int devfsd_buf_size = PAGE_SIZE / sizeof(struct devfsd_buf_entry);
@@ -694,9 +721,9 @@
 #endif
 
 #ifdef CONFIG_DEVFS_MOUNT
-static unsigned int boot_options = OPTION_NONE;
+static unsigned int boot_options = OPTION_MOUNT;
 #else
-static unsigned int boot_options = OPTION_NOMOUNT;
+static unsigned int boot_options = OPTION_NONE;
 #endif
 
 /*  Forward function declarations  */
@@ -851,14 +878,13 @@
     /*  Always ensure the root is created  */
     if (root_entry != NULL) return root_entry;
     if ( ( root_entry = create_entry (NULL, NULL, 0) ) == NULL ) return NULL;
-    root_entry->registered = TRUE;
     root_entry->mode = S_IFDIR;
     /*  Force an inode update, because lookup() is never done for the root  */
     update_devfs_inode_from_entry (root_entry);
+    root_entry->registered = TRUE;
     /*  And create the entry for ".devfsd"  */
     if ( ( new = create_entry (root_entry, ".devfsd", 0) ) == NULL )
 	return NULL;
-    new->registered = TRUE;
     new->u.fcb.u.device.major = next_devnum_char >> 8;
     new->u.fcb.u.device.minor = next_devnum_char & 0xff;
     ++next_devnum_char;
@@ -866,6 +892,7 @@
     new->u.fcb.default_uid = 0;
     new->u.fcb.default_gid = 0;
     new->u.fcb.ops = &devfsd_fops;
+    new->registered = TRUE;
     return root_entry;
 }   /*  End Function get_root_entry  */
 
@@ -943,8 +970,8 @@
 	    return NULL;
 	}
 	/*  Ensure an unregistered entry is re-registered and visible  */
-	entry->registered = TRUE;
 	entry->hide = FALSE;
+	entry->registered = TRUE;
 	subname = ptr + 1;
 	dir = entry;
     }
@@ -1053,8 +1080,10 @@
     return find_by_dev (root_entry, major, minor, type);
 }   /*  End Function find_entry  */
 
-static struct devfs_entry *get_devfs_entry_from_vfs_inode (struct inode *inode)
+static struct devfs_entry *get_devfs_entry_from_vfs_inode (struct inode *inode,
+							   int do_check)
 {
+    struct devfs_entry *de;
     struct fs_info *fs_info;
 
     if (inode == NULL) return NULL;
@@ -1062,7 +1091,9 @@
     fs_info = inode->i_sb->u.generic_sbp;
     if (fs_info == NULL) return NULL;
     if (inode->i_ino - FIRST_INODE >= fs_info->num_inodes) return NULL;
-    return fs_info->table[inode->i_ino - FIRST_INODE];
+    de = fs_info->table[inode->i_ino - FIRST_INODE];
+    if (do_check && de && !de->registered) de = NULL;
+    return de;
 }   /*  End Function get_devfs_entry_from_vfs_inode  */
 
 
@@ -1075,19 +1106,19 @@
 {
     struct dentry *dentry;
 
-    spin_lock(&dcache_lock);
+    spin_lock (&dcache_lock);
     dentry = de->inode.dentry;
     if (dentry != NULL)
     {
 	dget_locked (dentry);
 	de->inode.dentry = NULL;
-	spin_unlock(&dcache_lock);
+	spin_unlock (&dcache_lock);
 	/*  Forcefully remove the inode  */
 	if (dentry->d_inode != NULL) dentry->d_inode->i_nlink = 0;
 	d_drop (dentry);
 	dput (dentry);
-    } else
-	spin_unlock(&dcache_lock);
+    }
+    else spin_unlock (&dcache_lock);
 }   /*  End Function free_dentries  */
 
 
@@ -1140,7 +1171,7 @@
     add_wait_queue (&fs_info->revalidate_wait_queue, &wait);
     current->state = TASK_UNINTERRUPTIBLE;
     if (!devfsd_queue_empty (fs_info) || !fs_info->devfsd_sleeping)
-	if (fs_info->devfsd_task) schedule();
+	if (fs_info->devfsd_task) schedule ();
     remove_wait_queue (&fs_info->revalidate_wait_queue, &wait);
     current->state = TASK_RUNNING;
     return (TRUE);
@@ -1165,7 +1196,6 @@
     unsigned int next_pos;
     unsigned long flags;
     struct devfsd_buf_entry *entry;
-    static spinlock_t lock = SPIN_LOCK_UNLOCKED;
 
     if ( !( fs_info->devfsd_event_mask & (1 << type) ) ) return (FALSE);
     next_pos = fs_info->devfsd_buf_in + 1;
@@ -1176,8 +1206,7 @@
 	atomic_inc (&fs_info->devfsd_overrun_count);
 	return (FALSE);
     }
-    spin_lock_irqsave (&lock, flags);
-    fs_info->devfsd_buffer_in_use = TRUE;
+    spin_lock_irqsave (&fs_info->devfsd_buffer_lock, flags);
     next_pos = fs_info->devfsd_buf_in + 1;
     if (next_pos >= devfsd_buf_size) next_pos = 0;
     entry = (struct devfsd_buf_entry *) fs_info->devfsd_buffer +
@@ -1188,8 +1217,7 @@
     entry->uid = uid;
     entry->gid = gid;
     fs_info->devfsd_buf_in = next_pos;
-    fs_info->devfsd_buffer_in_use = FALSE;
-    spin_unlock_irqrestore (&lock, flags);
+    spin_unlock_irqrestore (&fs_info->devfsd_buffer_lock, flags);
     wake_up_interruptible (&fs_info->devfsd_wait_queue);
     return (TRUE);
 }   /*  End Function devfsd_notify_one  */
@@ -1322,7 +1350,6 @@
 	    return NULL;
 	}
     }
-    de->registered = TRUE;
     if ( S_ISCHR (mode) || S_ISBLK (mode) )
     {
 	de->u.fcb.u.device.major = major;
@@ -1347,7 +1374,6 @@
 	de->u.fcb.default_uid = 0;
 	de->u.fcb.default_gid = 0;
     }
-    de->registered = TRUE;
     de->u.fcb.ops = ops;
     de->u.fcb.auto_owner = (flags & DEVFS_FL_AUTO_OWNER) ? TRUE : FALSE;
     de->u.fcb.aopen_notify = (flags & DEVFS_FL_AOPEN_NOTIFY) ? TRUE : FALSE;
@@ -1361,6 +1387,7 @@
 			|| (flags & DEVFS_FL_SHOW_UNREG) ) ? TRUE : FALSE;
     de->hide = (flags & DEVFS_FL_HIDE) ? TRUE : FALSE;
     de->no_persistence = (flags & DEVFS_FL_NO_PERSISTENCE) ? TRUE : FALSE;
+    de->registered = TRUE;
     devfsd_notify (de, DEVFSD_NOTIFY_REGISTERED, flags & DEVFS_FL_WAIT);
     return de;
 }   /*  End Function devfs_register  */
@@ -1392,11 +1419,10 @@
 	de->u.fcb.ops = NULL;
 	return;
     }
-    if ( S_ISLNK (de->mode) )
+    if (S_ISLNK (de->mode) && de->registered)
     {
 	de->registered = FALSE;
-	if (de->u.symlink.linkname != NULL) kfree (de->u.symlink.linkname);
-	de->u.symlink.linkname = NULL;
+	kfree (de->u.symlink.linkname);
 	return;
     }
     if ( S_ISFIFO (de->mode) )
@@ -1441,22 +1467,9 @@
     unregister (de);
 }   /*  End Function devfs_unregister  */
 
-
-/**
- *	devfs_mk_symlink Create a symbolic link in the devfs namespace.
- *	@dir: The handle to the parent devfs directory entry. If this is %NULL the
- *		new name is relative to the root of the devfs.
- *	@name: The name of the entry.
- *	@flags: A set of bitwise-ORed flags (DEVFS_FL_*).
- *	@link: The destination name.
- *	@handle: The handle to the symlink entry is written here. This may be %NULL.
- *	@info: An arbitrary pointer which will be associated with the entry.
- *
- *	Returns 0 on success, else a negative error code is returned.
- */
-
-int devfs_mk_symlink (devfs_handle_t dir, const char *name, unsigned int flags,
-		      const char *link, devfs_handle_t *handle, void *info)
+static int devfs_do_symlink (devfs_handle_t dir, const char *name,
+			     unsigned int flags, const char *link,
+			     devfs_handle_t *handle, void *info)
 {
     int is_new;
     unsigned int linklength;
@@ -1466,16 +1479,16 @@
     if (handle != NULL) *handle = NULL;
     if (name == NULL)
     {
-	printk ("%s: devfs_mk_symlink(): NULL name pointer\n", DEVFS_NAME);
+	printk ("%s: devfs_do_symlink(): NULL name pointer\n", DEVFS_NAME);
 	return -EINVAL;
     }
 #ifdef CONFIG_DEVFS_DEBUG
     if (devfs_debug & DEBUG_REGISTER)
-	printk ("%s: devfs_mk_symlink(%s)\n", DEVFS_NAME, name);
+	printk ("%s: devfs_do_symlink(%s)\n", DEVFS_NAME, name);
 #endif
     if (link == NULL)
     {
-	printk ("%s: devfs_mk_symlink(): NULL link pointer\n", DEVFS_NAME);
+	printk ("%s: devfs_do_symlink(): NULL link pointer\n", DEVFS_NAME);
 	return -EINVAL;
     }
     linklength = strlen (link);
@@ -1484,7 +1497,7 @@
     if (de == NULL) return -ENOMEM;
     if (!S_ISLNK (de->mode) && de->registered)
     {
-	printk ("%s: devfs_mk_symlink(): non-link entry already exists\n",
+	printk ("%s: devfs_do_symlink(): non-link entry already exists\n",
 		DEVFS_NAME);
 	return -EEXIST;
     }
@@ -1504,7 +1517,6 @@
     }
     /*  Have to create/update  */
     if (de->registered) return -EEXIST;
-    de->registered = TRUE;
     if ( ( newname = kmalloc (linklength + 1, GFP_KERNEL) ) == NULL )
     {
 	struct devfs_entry *parent = de->parent;
@@ -1518,11 +1530,39 @@
 	kfree (de);
 	return -ENOMEM;
     }
-    if (de->u.symlink.linkname != NULL) kfree (de->u.symlink.linkname);
     de->u.symlink.linkname = newname;
     memcpy (de->u.symlink.linkname, link, linklength);
     de->u.symlink.linkname[linklength] = '\0';
     de->u.symlink.length = linklength;
+    de->registered = TRUE;
+    return 0;
+}   /*  End Function devfs_do_symlink  */
+
+
+/**
+ *	devfs_mk_symlink Create a symbolic link in the devfs namespace.
+ *	@dir: The handle to the parent devfs directory entry. If this is %NULL the
+ *		new name is relative to the root of the devfs.
+ *	@name: The name of the entry.
+ *	@flags: A set of bitwise-ORed flags (DEVFS_FL_*).
+ *	@link: The destination name.
+ *	@handle: The handle to the symlink entry is written here. This may be %NULL.
+ *	@info: An arbitrary pointer which will be associated with the entry.
+ *
+ *	Returns 0 on success, else a negative error code is returned.
+ */
+
+int devfs_mk_symlink (devfs_handle_t dir, const char *name, unsigned int flags,
+		      const char *link, devfs_handle_t *handle, void *info)
+{
+    int err;
+    devfs_handle_t de;
+
+    if (handle != NULL) *handle = NULL;
+    err = devfs_do_symlink (dir, name, flags, link, &de, info);
+    if (err) return err;
+    if (handle != NULL) *handle = de;
+    devfsd_notify (de, DEVFSD_NOTIFY_REGISTERED, flags & DEVFS_FL_WAIT);
     return 0;
 }   /*  End Function devfs_mk_symlink  */
 
@@ -1579,9 +1619,9 @@
     de->mode = S_IFDIR | S_IRUGO | S_IXUGO;
     de->info = info;
     if (!de->registered) de->u.dir.num_removable = 0;
-    de->registered = TRUE;
     de->show_unreg = (boot_options & OPTION_SHOW) ? TRUE : FALSE;
     de->hide = FALSE;
+    de->registered = TRUE;
     return de;
 }   /*  End Function devfs_mk_dir  */
 
@@ -1716,7 +1756,7 @@
 {
     if (!inode || !inode->i_sb) return NULL;
     if (inode->i_sb->s_magic != DEVFS_SUPER_MAGIC) return NULL;
-    return get_devfs_entry_from_vfs_inode (inode);
+    return get_devfs_entry_from_vfs_inode (inode, TRUE);
 }   /*  End Function devfs_get_handle_from_inode  */
 
 
@@ -1737,10 +1777,10 @@
 
     if (de == NULL) return -EINVAL;
     if (de->namelen >= buflen) return -ENAMETOOLONG; /*  Must be first       */
-    if (de->parent == NULL) return buflen;           /*  Don't prepend root  */
+    path[buflen - 1] = '\0';
+    if (de->parent == NULL) return buflen - 1;       /*  Don't prepend root  */
     pos = buflen - de->namelen - 1;
     memcpy (path + pos, de->name, de->namelen);
-    path[buflen - 1] = '\0';
     for (de = de->parent; de->parent != NULL; de = de->parent)
     {
 	if (pos - de->namelen - 1 < 0) return -ENAMETOOLONG;
@@ -1999,84 +2039,56 @@
 
 static int __init devfs_setup (char *str)
 {
-    while ( (*str != '\0') && !isspace (*str) )
+    static struct
     {
-#ifdef CONFIG_DEVFS_DEBUG
-	if (strncmp (str, "dall", 4) == 0)
-	{
-	    devfs_debug_init |= DEBUG_ALL;
-	    str += 4;
-	}
-	else if (strncmp (str, "dmod", 4) == 0)
-	{
-	    devfs_debug_init |= DEBUG_MODULE_LOAD;
-	    str += 4;
-	}
-	else if (strncmp (str, "dreg", 4) == 0)
-	{
-	    devfs_debug_init |= DEBUG_REGISTER;
-	    str += 4;
-	}
-	else if (strncmp (str, "dunreg", 6) == 0)
-	{
-	    devfs_debug_init |= DEBUG_UNREGISTER;
-	    str += 6;
-	}
-	else if (strncmp (str, "diread", 6) == 0)
-	{
-	    devfs_debug_init |= DEBUG_I_READ;
-	    str += 6;
-	}
-	else if (strncmp (str, "dchange", 7) == 0)
-	{
-	    devfs_debug_init |= DEBUG_SET_FLAGS;
-	    str += 7;
-	}
-	else if (strncmp (str, "diwrite", 7) == 0)
-	{
-	    devfs_debug_init |= DEBUG_I_WRITE;
-	    str += 7;
-	}
-	else if (strncmp (str, "dimknod", 7) == 0)
-	{
-	    devfs_debug_init |= DEBUG_I_MKNOD;
-	    str += 7;
-	}
-	else if (strncmp (str, "dilookup", 8) == 0)
-	{
-	    devfs_debug_init |= DEBUG_I_LOOKUP;
-	    str += 8;
-	}
-	else if (strncmp (str, "diunlink", 8) == 0)
-	{
-	    devfs_debug_init |= DEBUG_I_UNLINK;
-	    str += 8;
-	}
-	else
+	char *name;
+	unsigned int mask;
+	unsigned int *opt;
+    } devfs_options_tab[] __initdata =
+    {
+#ifdef CONFIG_DEVFS_DEBUG
+	{"dall",      DEBUG_ALL,          &devfs_debug_init},
+	{"dmod",      DEBUG_MODULE_LOAD,  &devfs_debug_init},
+	{"dreg",      DEBUG_REGISTER,     &devfs_debug_init},
+	{"dunreg",    DEBUG_UNREGISTER,   &devfs_debug_init},
+	{"diread",    DEBUG_I_READ,       &devfs_debug_init},
+	{"dchange",   DEBUG_SET_FLAGS,    &devfs_debug_init},
+	{"diwrite",   DEBUG_I_WRITE,      &devfs_debug_init},
+	{"dimknod",   DEBUG_I_MKNOD,      &devfs_debug_init},
+	{"dilookup",  DEBUG_I_LOOKUP,     &devfs_debug_init},
+	{"diunlink",  DEBUG_I_UNLINK,     &devfs_debug_init},
 #endif  /*  CONFIG_DEVFS_DEBUG  */
-	if (strncmp (str, "show", 4) == 0)
-	{
-	    boot_options |= OPTION_SHOW;
-	    str += 4;
-	}
-	else if (strncmp (str, "only", 4) == 0)
-	{
-	    boot_options |= OPTION_ONLY;
-	    str += 4;
-	}
-	else if (strncmp (str, "mount", 5) == 0)
+	{"show",      OPTION_SHOW,        &boot_options},
+	{"only",      OPTION_ONLY,        &boot_options},
+	{"mount",     OPTION_MOUNT,       &boot_options},
+    };
+
+    while ( (*str != '\0') && !isspace (*str) )
+    {
+	int i, found = 0, invert = 0;
+
+	if (strncmp (str, "no", 2) == 0)
 	{
-	    boot_options &= ~OPTION_NOMOUNT;
-	    str += 5;
+	    invert = 1;
+	    str += 2;
 	}
-	else if (strncmp (str, "nomount", 7) == 0)
+	for (i = 0; i < sizeof (devfs_options_tab); i++)
 	{
-	    boot_options |= OPTION_NOMOUNT;
-	    str += 7;
+	    int len = strlen (devfs_options_tab[i].name);
+
+	    if (strncmp (str, devfs_options_tab[i].name, len) == 0)
+	    {
+		if (invert)
+		    *devfs_options_tab[i].opt &= ~devfs_options_tab[i].mask;
+		else
+		    *devfs_options_tab[i].opt |= devfs_options_tab[i].mask;
+		str += len;
+		found = 1;
+		break;
+	    }
 	}
-	else
-	return 0;
-	if (*str != ',') return 0;
+	if (!found) return 0;       /*  No match         */
+	if (*str != ',') return 0;  /*  No more options  */
 	++str;
     }
     return 1;
@@ -2103,6 +2115,7 @@
 EXPORT_SYMBOL(devfs_get_next_sibling);
 EXPORT_SYMBOL(devfs_auto_unregister);
 EXPORT_SYMBOL(devfs_get_unregister_slave);
+EXPORT_SYMBOL(devfs_get_name);
 EXPORT_SYMBOL(devfs_register_chrdev);
 EXPORT_SYMBOL(devfs_register_blkdev);
 EXPORT_SYMBOL(devfs_unregister_chrdev);
@@ -2125,15 +2138,15 @@
 			const char *name, unsigned namelen,
 			char buf[STRING_LENGTH])
 {
-    int pos;
+    int pos = STRING_LENGTH - namelen - 1;
 
     if ( !( fs_info->devfsd_event_mask & (1 << DEVFSD_NOTIFY_LOOKUP) ) )
 	return -ENOENT;
     if ( is_devfsd_or_child (fs_info) ) return -ENOENT;
     if (namelen >= STRING_LENGTH) return -ENAMETOOLONG;
-    memcpy (buf + STRING_LENGTH - namelen - 1, name, namelen);
+    memcpy (buf + pos, name, namelen);
     buf[STRING_LENGTH - 1] = '\0';
-    pos = devfs_generate_path (parent, buf, STRING_LENGTH - namelen - 1);
+    if (parent->parent != NULL) pos = devfs_generate_path (parent, buf, pos);
     if (pos < 0) return pos;
     buf[STRING_LENGTH - namelen - 2] = '/';
     if ( !devfsd_notify_one (buf + pos, DEVFSD_NOTIFY_LOOKUP, 0,
@@ -2229,13 +2242,14 @@
 static struct inode_operations devfs_iops;
 static struct inode_operations devfs_dir_iops;
 static struct file_operations devfs_fops;
+static struct file_operations devfs_dir_fops;
 static struct inode_operations devfs_symlink_iops;
 
 static void devfs_read_inode (struct inode *inode)
 {
     struct devfs_entry *de;
 
-    de = get_devfs_entry_from_vfs_inode (inode);
+    de = get_devfs_entry_from_vfs_inode (inode, TRUE);
     if (de == NULL)
     {
 	printk ("%s: read_inode(%d): VFS inode: %p  NO devfs_entry\n",
@@ -2273,7 +2287,11 @@
     }
     else if ( S_ISFIFO (de->inode.mode) ) inode->i_fop = &def_fifo_fops;
     else if ( S_ISREG (de->inode.mode) ) inode->i_size = de->u.fcb.u.file.size;
-    else if ( S_ISDIR (de->inode.mode) ) inode->i_op = &devfs_dir_iops;
+    else if ( S_ISDIR (de->inode.mode) )
+    {
+	inode->i_op = &devfs_dir_iops;
+    	inode->i_fop = &devfs_dir_fops;
+    }
     else if ( S_ISLNK (de->inode.mode) )
     {
 	inode->i_op = &devfs_symlink_iops;
@@ -2302,12 +2320,12 @@
 
     if (inode->i_ino < FIRST_INODE) return;
     index = inode->i_ino - FIRST_INODE;
-    lock_kernel();
+    lock_kernel ();
     if (index >= fs_info->num_inodes)
     {
 	printk ("%s: writing inode: %lu for which there is no entry!\n",
 		DEVFS_NAME, inode->i_ino);
-        unlock_kernel();
+        unlock_kernel ();
 	return;
     }
     de = fs_info->table[index];
@@ -2327,7 +2345,7 @@
     de->inode.atime = inode->i_atime;
     de->inode.mtime = inode->i_mtime;
     de->inode.ctime = inode->i_ctime;
-    unlock_kernel();
+    unlock_kernel ();
 }   /*  End Function devfs_write_inode  */
 
 static int devfs_notify_change (struct dentry *dentry, struct iattr *iattr)
@@ -2337,7 +2355,7 @@
     struct inode *inode = dentry->d_inode;
     struct fs_info *fs_info = inode->i_sb->u.generic_sbp;
 
-    de = get_devfs_entry_from_vfs_inode (inode);
+    de = get_devfs_entry_from_vfs_inode (inode, TRUE);
     if (de == NULL) return -ENODEV;
     retval = inode_change_ok (inode, iattr);
     if (retval != 0) return retval;
@@ -2399,12 +2417,6 @@
 
 /*  File operations for device entries follow  */
 
-static ssize_t devfs_read (struct file *file, char *buf, size_t len, loff_t *ppos)
-{
-    if ( S_ISDIR (file->f_dentry->d_inode->i_mode) ) return -EISDIR;
-    return -EINVAL;
-}   /*  End Function devfs_read  */
-
 static int devfs_readdir (struct file *file, void *dirent, filldir_t filldir)
 {
     int err, count;
@@ -2413,13 +2425,8 @@
     struct devfs_entry *parent, *de;
     struct inode *inode = file->f_dentry->d_inode;
 
-    if ( !S_ISDIR (inode->i_mode) )
-    {
-	printk ("%s: readdir(): inode is not a directory\n", DEVFS_NAME);
-	return -ENOTDIR;
-    }
     fs_info = inode->i_sb->u.generic_sbp;
-    parent = get_devfs_entry_from_vfs_inode (file->f_dentry->d_inode);
+    parent = get_devfs_entry_from_vfs_inode (file->f_dentry->d_inode, TRUE);
     if ( (long) file->f_pos < 0 ) return -EINVAL;
 #ifdef CONFIG_DEVFS_DEBUG
     if (devfs_debug & DEBUG_F_READDIR)
@@ -2473,8 +2480,8 @@
     struct devfs_entry *de;
     struct fs_info *fs_info = inode->i_sb->u.generic_sbp;
 
-    lock_kernel();
-    de = get_devfs_entry_from_vfs_inode (inode);
+    lock_kernel ();
+    de = get_devfs_entry_from_vfs_inode (inode, TRUE);
     err = -ENODEV;
     if (de == NULL)
 	goto out;
@@ -2482,34 +2489,18 @@
     if ( S_ISDIR (de->mode) )
 	goto out;
     df = &de->u.fcb;
-    err = -ENODEV;
-    if (!de->registered)
-	goto out;
     file->private_data = de->info;
     if ( S_ISBLK (inode->i_mode) )
     {
 	file->f_op = &def_blk_fops;
 	if (df->ops) inode->i_bdev->bd_op = df->ops;
     }
-    else file->f_op = fops_get((struct file_operations*)df->ops);
+    else file->f_op = fops_get ( (struct file_operations*) df->ops );
     if (file->f_op)
 	err = file->f_op->open ? (*file->f_op->open) (inode, file) : 0;
     else
     {
 	/*  Fallback to legacy scheme  */
-	/*
-	 * Do we need it? Richard, could you verify it?
-	 * It can legitimately happen if
-	 *	it is a character device and 
-	 *	df->ops == NULL and
-	 *	de->registered is true,
-	 * but AFAICS it can't happen - in devfs_register() we never set
-	 * ->ops to NULL, in unregister() we set ->registered to false,
-	 * in devfs_mknod() we set it to NULL only if ->register is false.
-	 *
-	 * Looks like this fallback is not needed at all.
-	 *							AV
-	 */
 	if ( S_ISCHR (inode->i_mode) ) err = chrdev_open (inode, file);
 	else err = -ENODEV;
     }
@@ -2532,13 +2523,18 @@
 	devfsd_notify_one (de, DEVFSD_NOTIFY_ASYNC_OPEN, inode->i_mode,
 			   current->euid, current->egid, fs_info);
 out:
-    unlock_kernel();
+    unlock_kernel ();
     return err;
 }   /*  End Function devfs_open  */
 
 static struct file_operations devfs_fops =
 {
-    read: devfs_read,
+    open: devfs_open,
+};
+
+static struct file_operations devfs_dir_fops =
+{
+    read: generic_read_dir,
     readdir: devfs_readdir,
     open: devfs_open,
 };
@@ -2574,7 +2570,7 @@
     struct devfs_entry *de;
 
     lock_kernel ();
-    de = get_devfs_entry_from_vfs_inode (inode);
+    de = get_devfs_entry_from_vfs_inode (inode, FALSE);
 #ifdef CONFIG_DEVFS_DEBUG
     if (devfs_debug & DEBUG_D_IPUT)
 	printk ("%s: d_iput(): dentry: %p inode: %p de: %p  de->dentry: %p\n",
@@ -2627,7 +2623,7 @@
 	return 1;
     }
     fs_info = inode->i_sb->u.generic_sbp;
-    de = get_devfs_entry_from_vfs_inode (inode);
+    de = get_devfs_entry_from_vfs_inode (inode, TRUE);
 #ifdef CONFIG_DEVFS_DEBUG
     if (devfs_debug & DEBUG_D_DELETE)
 	printk ("%s: d_delete(): dentry: %p  inode: %p  devfs_entry: %p\n",
@@ -2682,7 +2678,7 @@
 	    {
 		devfs_handle_t parent;
 
-		parent = get_devfs_entry_from_vfs_inode (dir);
+		parent = get_devfs_entry_from_vfs_inode (dir, TRUE);
 		de = search_for_entry_in_dir (parent, dentry->d_name.name,
 					      dentry->d_name.len, FALSE);
 	    }
@@ -2723,12 +2719,6 @@
     /*  Set up the dentry operations before anything else, to ensure cleaning
 	up on any error  */
     dentry->d_op = &devfs_dops;
-    if (dir == NULL)
-    {
-	printk ("%s: lookup(): NULL directory inode\n", DEVFS_NAME);
-	return ERR_PTR (-ENOTDIR);
-    }
-    if ( !S_ISDIR (dir->i_mode) ) return ERR_PTR (-ENOTDIR);
     memset (txt, 0, STRING_LENGTH);
     memcpy (txt, dentry->d_name.name,
 	    (dentry->d_name.len >= STRING_LENGTH) ?
@@ -2740,9 +2730,8 @@
 #endif
     fs_info = dir->i_sb->u.generic_sbp;
     /*  First try to get the devfs entry for this directory  */
-    parent = get_devfs_entry_from_vfs_inode (dir);
-    if (parent == NULL) return ERR_PTR (-EINVAL);
-    if (!parent->registered) return ERR_PTR (-ENOENT);
+    parent = get_devfs_entry_from_vfs_inode (dir, TRUE);
+    if (parent == NULL) return ERR_PTR (-ENOENT);
     /*  Try to reclaim an existing devfs entry  */
     de = search_for_entry_in_dir (parent,
 				  dentry->d_name.name, dentry->d_name.len,
@@ -2845,13 +2834,11 @@
     }
 #endif
 
-    if ( !dir || !S_ISDIR (dir->i_mode) ) return -ENOTDIR;
-    if (!dentry || !dentry->d_inode) return -ENOENT;
-    de = get_devfs_entry_from_vfs_inode (dentry->d_inode);
+    de = get_devfs_entry_from_vfs_inode (dentry->d_inode, TRUE);
     if (de == NULL) return -ENOENT;
-    if (!de->registered) return -ENOENT;
     de->registered = FALSE;
     de->hide = TRUE;
+    if ( S_ISLNK (de->mode) ) kfree (de->u.symlink.linkname);
     free_dentries (de);
     return 0;
 }   /*  End Function devfs_unlink  */
@@ -2864,17 +2851,15 @@
     struct devfs_entry *parent, *de;
     struct inode *inode;
 
-    if ( !dir || !S_ISDIR (dir->i_mode) ) return -ENOTDIR;
     fs_info = dir->i_sb->u.generic_sbp;
     /*  First try to get the devfs entry for this directory  */
-    parent = get_devfs_entry_from_vfs_inode (dir);
-    if (parent == NULL) return -EINVAL;
-    if (!parent->registered) return -ENOENT;
-    err = devfs_mk_symlink (parent, dentry->d_name.name, DEVFS_FL_NONE,
+    parent = get_devfs_entry_from_vfs_inode (dir, TRUE);
+    if (parent == NULL) return -ENOENT;
+    err = devfs_do_symlink (parent, dentry->d_name.name, DEVFS_FL_NONE,
 			    symname, &de, NULL);
 #ifdef CONFIG_DEVFS_DEBUG
     if (devfs_debug & DEBUG_DISABLED)
-	printk ("%s: symlink(): errcode from <devfs_mk_symlink>: %d\n",
+	printk ("%s: symlink(): errcode from <devfs_do_symlink>: %d\n",
 		DEVFS_NAME, err);
 #endif
     if (err < 0) return err;
@@ -2904,13 +2889,10 @@
     struct inode *inode;
 
     mode = (mode & ~S_IFMT) | S_IFDIR;
-    if ( !dir || !S_ISDIR (dir->i_mode) ) return -ENOTDIR;
     fs_info = dir->i_sb->u.generic_sbp;
-    /*  We are allowed to create the directory  */
     /*  First try to get the devfs entry for this directory  */
-    parent = get_devfs_entry_from_vfs_inode (dir);
-    if (parent == NULL) return -EINVAL;
-    if (!parent->registered) return -ENOENT;
+    parent = get_devfs_entry_from_vfs_inode (dir, TRUE);
+    if (parent == NULL) return -ENOENT;
     /*  Try to reclaim an existing devfs entry, create if there isn't one  */
     de = search_for_entry (parent, dentry->d_name.name, dentry->d_name.len,
 			   FALSE, TRUE, &is_new, FALSE);
@@ -2920,7 +2902,6 @@
 	printk ("%s: mkdir(): existing entry\n", DEVFS_NAME);
 	return -EEXIST;
     }
-    de->registered = TRUE;
     de->hide = FALSE;
     if (!S_ISDIR (de->mode) && !is_new)
     {
@@ -2936,6 +2917,7 @@
     de->inode.atime = CURRENT_TIME;
     de->inode.mtime = CURRENT_TIME;
     de->inode.ctime = CURRENT_TIME;
+    de->registered = TRUE;
     if ( ( inode = get_vfs_inode (dir->i_sb, de, dentry) ) == NULL )
 	return -ENOMEM;
 #ifdef CONFIG_DEVFS_DEBUG
@@ -2956,13 +2938,10 @@
     struct devfs_entry *de, *child;
     struct inode *inode = dentry->d_inode;
 
-    if ( !dir || !S_ISDIR (dir->i_mode) ) return -ENOTDIR;
     if (dir->i_sb->u.generic_sbp != inode->i_sb->u.generic_sbp) return -EINVAL;
-    if (inode == dir) return -EPERM;
     fs_info = dir->i_sb->u.generic_sbp;
-    de = get_devfs_entry_from_vfs_inode (inode);
+    de = get_devfs_entry_from_vfs_inode (inode, TRUE);
     if (de == NULL) return -ENOENT;
-    if (!de->registered) return -ENOENT;
     if ( !S_ISDIR (de->mode) ) return -ENOTDIR;
     for (child = de->u.dir.first; child != NULL; child = child->next)
     {
@@ -2973,8 +2952,8 @@
 	}
     }
     if (has_children) return -ENOTEMPTY;
-    de->registered = FALSE;
     de->hide = TRUE;
+    de->registered = FALSE;
     free_dentries (de);
     return 0;
 }   /*  End Function devfs_rmdir  */
@@ -3000,15 +2979,10 @@
     }
 #endif
 
-    if ( !dir || !S_ISDIR (dir->i_mode) ) return -ENOTDIR;
     fs_info = dir->i_sb->u.generic_sbp;
-    if ( !S_ISBLK (mode) && !S_ISCHR (mode) && !S_ISFIFO (mode) &&
-	 !S_ISSOCK (mode) ) return -EPERM;
-    /*  We are allowed to create the node  */
     /*  First try to get the devfs entry for this directory  */
-    parent = get_devfs_entry_from_vfs_inode (dir);
-    if (parent == NULL) return -EINVAL;
-    if (!parent->registered) return -ENOENT;
+    parent = get_devfs_entry_from_vfs_inode (dir, TRUE);
+    if (parent == NULL) return -ENOENT;
     /*  Try to reclaim an existing devfs entry, create if there isn't one  */
     de = search_for_entry (parent, dentry->d_name.name, dentry->d_name.len,
 			   FALSE, TRUE, &is_new, FALSE);
@@ -3035,7 +3009,6 @@
 	    de->u.fifo.gid = current->egid;
 	}
     }
-    de->registered = TRUE;
     de->show_unreg = FALSE;
     de->hide = FALSE;
     de->inode.mode = mode;
@@ -3044,6 +3017,7 @@
     de->inode.atime = CURRENT_TIME;
     de->inode.mtime = CURRENT_TIME;
     de->inode.ctime = CURRENT_TIME;
+    de->registered = TRUE;
     if ( ( inode = get_vfs_inode (dir->i_sb, de, dentry) ) == NULL )
 	return -ENOMEM;
 #ifdef CONFIG_DEVFS_DEBUG
@@ -3059,32 +3033,31 @@
 
 static int devfs_readlink (struct dentry *dentry, char *buffer, int buflen)
 {
+    int err;
     struct devfs_entry *de;
 
     lock_kernel ();
-    de = get_devfs_entry_from_vfs_inode (dentry->d_inode);
+    de = get_devfs_entry_from_vfs_inode (dentry->d_inode, TRUE);
+    err = de ? vfs_readlink (dentry, buffer, buflen,
+			     de->u.symlink.linkname) : -ENODEV;
     unlock_kernel ();
-    return vfs_readlink (dentry, buffer, buflen, de->u.symlink.linkname);
+    return err;
 }   /*  End Function devfs_readlink  */
 
 static int devfs_follow_link (struct dentry *dentry, struct nameidata *nd)
 {
+    int err;
     struct devfs_entry *de;
 
     lock_kernel ();
-    de = get_devfs_entry_from_vfs_inode (dentry->d_inode);
+    de = get_devfs_entry_from_vfs_inode (dentry->d_inode, TRUE);
+    err = de ? vfs_follow_link (nd, de->u.symlink.linkname) : -ENODEV;
     unlock_kernel ();
-    return vfs_follow_link (nd, de->u.symlink.linkname);
+    return err;
 }   /*  End Function devfs_follow_link  */
 
 static struct inode_operations devfs_iops =
 {
-    link:           devfs_link,
-    unlink:         devfs_unlink,
-    symlink:        devfs_symlink,
-    mkdir:          devfs_mkdir,
-    rmdir:          devfs_rmdir,
-    mknod:          devfs_mknod,
     setattr:        devfs_notify_change,
 };
 
@@ -3151,17 +3124,17 @@
     int done = FALSE;
     int ival;
     loff_t pos, devname_offset, tlen, rpos;
-    struct devfsd_notify_struct info;
     struct devfsd_buf_entry *entry;
     struct fs_info *fs_info = file->f_dentry->d_inode->i_sb->u.generic_sbp;
+    struct devfsd_notify_struct *info = fs_info->devfsd_info;
     DECLARE_WAITQUEUE (wait, current);
 
     /*  Can't seek (pread) on this device  */
     if (ppos != &file->f_pos) return -ESPIPE;
     /*  Verify the task has grabbed the queue  */
     if (fs_info->devfsd_task != current) return -EPERM;
-    info.major = 0;
-    info.minor = 0;
+    info->major = 0;
+    info->minor = 0;
     /*  Block for a new entry  */
     add_wait_queue (&fs_info->devfsd_wait_queue, &wait);
     current->state = TASK_INTERRUPTIBLE;
@@ -3184,18 +3157,18 @@
     /*  Now play with the data  */
     ival = atomic_read (&fs_info->devfsd_overrun_count);
     if (ival > 0) atomic_sub (ival, &fs_info->devfsd_overrun_count);
-    info.overrun_count = ival;
+    info->overrun_count = ival;
     entry = (struct devfsd_buf_entry *) fs_info->devfsd_buffer +
 	fs_info->devfsd_buf_out;
-    info.type = entry->type;
-    info.mode = entry->mode;
-    info.uid = entry->uid;
-    info.gid = entry->gid;
+    info->type = entry->type;
+    info->mode = entry->mode;
+    info->uid = entry->uid;
+    info->gid = entry->gid;
     if (entry->type == DEVFSD_NOTIFY_LOOKUP)
     {
-	info.namelen = strlen (entry->data);
+	info->namelen = strlen (entry->data);
 	pos = 0;
-	memcpy (info.devname, entry->data, info.namelen + 1);
+	memcpy (info->devname, entry->data, info->namelen + 1);
     }
     else
     {
@@ -3203,22 +3176,22 @@
 
 	if ( S_ISCHR (de->mode) || S_ISBLK (de->mode) || S_ISREG (de->mode) )
 	{
-	    info.major = de->u.fcb.u.device.major;
-	    info.minor = de->u.fcb.u.device.minor;
+	    info->major = de->u.fcb.u.device.major;
+	    info->minor = de->u.fcb.u.device.minor;
 	}
-	pos = devfs_generate_path (de, info.devname, DEVFS_PATHLEN);
+	pos = devfs_generate_path (de, info->devname, DEVFS_PATHLEN);
 	if (pos < 0) return pos;
-	info.namelen = DEVFS_PATHLEN - pos - 1;
-	if (info.mode == 0) info.mode = de->mode;
+	info->namelen = DEVFS_PATHLEN - pos - 1;
+	if (info->mode == 0) info->mode = de->mode;
     }
-    devname_offset = info.devname - (char *) &info;
+    devname_offset = info->devname - (char *) info;
     rpos = *ppos;
     if (rpos < devname_offset)
     {
 	/*  Copy parts of the header  */
 	tlen = devname_offset - rpos;
 	if (tlen > len) tlen = len;
-	if ( copy_to_user (buf, (char *) &info + rpos, tlen) )
+	if ( copy_to_user (buf, (char *) info + rpos, tlen) )
 	{
 	    return -EFAULT;
 	}
@@ -3229,10 +3202,10 @@
     if ( (rpos >= devname_offset) && (len > 0) )
     {
 	/*  Copy the name  */
-	tlen = info.namelen + 1;
+	tlen = info->namelen + 1;
 	if (tlen > len) tlen = len;
 	else done = TRUE;
-	if ( copy_to_user (buf, info.devname + pos + rpos - devname_offset,
+	if ( copy_to_user (buf, info->devname + pos + rpos - devname_offset,
 			   tlen) )
 	{
 	    return -EFAULT;
@@ -3257,6 +3230,7 @@
 {
     int ival;
     struct fs_info *fs_info = inode->i_sb->u.generic_sbp;
+    static spinlock_t lock = SPIN_LOCK_UNLOCKED;
 
     switch (cmd)
     {
@@ -3270,30 +3244,21 @@
 	    doesn't matter who gets in first, as long as only one gets it  */
 	if (fs_info->devfsd_task == NULL)
 	{
-#ifdef CONFIG_SMP
-	    /*  Looks like no-one has it: check again and grab, with interrupts
-		disabled  */
-	    __cli ();
-	    if (fs_info->devfsd_task == NULL)
-#endif
+	    if ( !spin_trylock (&lock) ) return -EBUSY;
+	    fs_info->devfsd_task = current;
+	    spin_unlock (&lock);
+	    fs_info->devfsd_file = file;
+	    fs_info->devfsd_buffer = (void *) __get_free_page (GFP_KERNEL);
+	    fs_info->devfsd_info = kmalloc (sizeof *fs_info->devfsd_info,
+					    GFP_KERNEL);
+	    if (!fs_info->devfsd_buffer || !fs_info->devfsd_info)
 	    {
-		fs_info->devfsd_event_mask = 0;  /*  Temporary disable  */
-		fs_info->devfsd_task = current;
+		devfsd_close (inode, file);
+		return -ENOMEM;
 	    }
-#ifdef CONFIG_SMP
-	    __sti ();
-#endif
-	}
-	/*  Verify the task has grabbed the queue  */
-	if (fs_info->devfsd_task != current) return -EBUSY;
-	fs_info->devfsd_file = file;
-	fs_info->devfsd_buffer = (void *) __get_free_page (GFP_KERNEL);
-	if (fs_info->devfsd_buffer == NULL)
-	{
-	    devfsd_close (inode, file);
-	    return -ENOMEM;
+	    fs_info->devfsd_buf_out = fs_info->devfsd_buf_in;
 	}
-	fs_info->devfsd_buf_out = fs_info->devfsd_buf_in;
+	else if (fs_info->devfsd_task != current) return -EBUSY;
 	fs_info->devfsd_event_mask = arg;  /*  Let the masses come forth  */
 	break;
       case DEVFSDIOC_RELEASE_EVENT_QUEUE:
@@ -3314,25 +3279,26 @@
 
 static int devfsd_close (struct inode *inode, struct file *file)
 {
+    unsigned long flags;
     struct fs_info *fs_info = inode->i_sb->u.generic_sbp;
 
-    lock_kernel();
-    if (fs_info->devfsd_file != file)
-    {
-	unlock_kernel();
-	return 0;
-    }
+    if (fs_info->devfsd_file != file) return 0;
     fs_info->devfsd_event_mask = 0;
     fs_info->devfsd_file = NULL;
+    spin_lock_irqsave (&fs_info->devfsd_buffer_lock, flags);
     if (fs_info->devfsd_buffer)
     {
-	while (fs_info->devfsd_buffer_in_use) schedule ();
 	free_page ( (unsigned long) fs_info->devfsd_buffer );
+	fs_info->devfsd_buffer = NULL;
+    }
+    if (fs_info->devfsd_info)
+    {
+	kfree (fs_info->devfsd_info);
+	fs_info->devfsd_info = NULL;
     }
-    fs_info->devfsd_buffer = NULL;
+    spin_unlock_irqrestore (&fs_info->devfsd_buffer_lock, flags);
     fs_info->devfsd_task = NULL;
     wake_up (&fs_info->revalidate_wait_queue);
-    unlock_kernel();
     return 0;
 }   /*  End Function devfsd_close  */
 
@@ -3362,7 +3328,7 @@
 {
     int err;
 
-    if ( (boot_options & OPTION_NOMOUNT) ) return;
+    if ( !(boot_options & OPTION_MOUNT) ) return;
     err = do_mount ("none", "/dev", "devfs", 0, "");
     if (err == 0) printk ("Mounted devfs on /dev\n");
     else printk ("Warning: unable to mount devfs, err: %d\n", err);
diff -u --recursive --new-file v2.4.5/linux/fs/devfs/util.c linux/fs/devfs/util.c
--- v2.4.5/linux/fs/devfs/util.c	Mon Oct 16 12:58:51 2000
+++ linux/fs/devfs/util.c	Tue Jun 12 10:57:46 2001
@@ -1,6 +1,6 @@
 /*  devfs (Device FileSystem) utilities.
 
-    Copyright (C) 1999-2000  Richard Gooch
+    Copyright (C) 1999-2001  Richard Gooch
 
     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Library General Public
@@ -33,6 +33,8 @@
     20000622   Richard Gooch <rgooch@atnf.csiro.au>
                Took account of interface change to <devfs_mk_symlink>.
                Took account of interface change to <devfs_mk_dir>.
+    20010519   Richard Gooch <rgooch@atnf.csiro.au>
+               Documentation cleanup.
 */
 #include <linux/module.h>
 #include <linux/init.h>
@@ -132,9 +134,10 @@
 
 /**
  *	devfs_register_series - Register a sequence of device entries.
- *	@dir: The handle to the parent devfs directory entry. If this is %NULL the
- *		new names are relative to the root of the devfs.
+ *	@dir: The handle to the parent devfs directory entry. If this is %NULL
+ *		the new names are relative to the root of the devfs.
  *	@format: The printf-style format string. A single "\%u" is allowed.
+ *	@num_entries: The number of entries to register.
  *	@flags: A set of bitwise-ORed flags (DEVFS_FL_*).
  *	@major: The major number. Not needed for regular files.
  *	@minor_start: The starting minor number. Not needed for regular files.
@@ -142,9 +145,9 @@
  *	@ops: The &file_operations or &block_device_operations structure.
  *		This must not be externally deallocated.
  *	@info: An arbitrary pointer which will be written to the private_data
- *		field of the &file structure passed to the device driver. You can set
- *		this to whatever you like, and change it once the file is opened (the next
- *		file opened will not see this change).
+ *		field of the &file structure passed to the device driver. You
+ *		can set this to whatever you like, and change it once the file
+ *		is opened (the next file opened will not see this change).
  */
 
 void devfs_register_series (devfs_handle_t dir, const char *format,
diff -u --recursive --new-file v2.4.5/linux/fs/dquot.c linux/fs/dquot.c
--- v2.4.5/linux/fs/dquot.c	Sun May 20 11:32:11 2001
+++ linux/fs/dquot.c	Tue Jun 12 16:03:27 2001
@@ -325,7 +325,7 @@
         memset(&dquot->dq_dqb, 0, sizeof(struct dqblk));
 }
 
-void invalidate_dquots(kdev_t dev, short type)
+static void invalidate_dquots(kdev_t dev, short type)
 {
 	struct dquot *dquot, *next;
 	int need_restart;
@@ -651,8 +651,6 @@
 {
 	int cnt;
 
-        if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)))
-                return 0;
 	if (is_quotafile(inode))
 		return 0;
 	if (type != -1)
@@ -1022,9 +1020,6 @@
 	unsigned int id = 0;
 	short cnt;
 
-	if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode) &&
-            !S_ISLNK(inode->i_mode))
-		return;
 	lock_kernel();
 	/* We don't want to have quotas on quota files - nasty deadlocks possible */
 	if (is_quotafile(inode)) {
@@ -1388,7 +1383,7 @@
 }
 
 /* Function in inode.c - remove pointers to dquots in icache */
-extern void remove_dquot_ref(kdev_t, short);
+extern void remove_dquot_ref(struct super_block *, short);
 
 /*
  * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
@@ -1413,7 +1408,7 @@
 		reset_enable_flags(dqopt, cnt);
 
 		/* Note: these are blocking operations */
-		remove_dquot_ref(sb->s_dev, cnt);
+		remove_dquot_ref(sb, cnt);
 		invalidate_dquots(sb->s_dev, cnt);
 
 		/* Wait for any pending IO - remove me as soon as invalidate is more polite */
diff -u --recursive --new-file v2.4.5/linux/fs/ext2/dir.c linux/fs/ext2/dir.c
--- v2.4.5/linux/fs/ext2/dir.c	Fri Dec  8 17:35:54 2000
+++ linux/fs/ext2/dir.c	Wed Jun 20 11:40:14 2001
@@ -16,167 +16,567 @@
  *
  *  Big-endian to little-endian byte-swapping/bitmaps by
  *        David S. Miller (davem@caip.rutgers.edu), 1995
+ *
+ * All code that works with directory layout had been switched to pagecache
+ * and moved here. AV
  */
 
 #include <linux/fs.h>
 #include <linux/ext2_fs.h>
+#include <linux/pagemap.h>
 
-static unsigned char ext2_filetype_table[] = {
-	DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
-};
+typedef struct ext2_dir_entry_2 ext2_dirent;
 
-static int ext2_readdir(struct file *, void *, filldir_t);
+/*
+ * ext2 uses block-sized chunks. Arguably, sector-sized ones would be
+ * more robust, but we have what we have
+ */
+static inline unsigned ext2_chunk_size(struct inode *inode)
+{
+	return inode->i_sb->s_blocksize;
+}
 
-struct file_operations ext2_dir_operations = {
-	read:		generic_read_dir,
-	readdir:	ext2_readdir,
-	ioctl:		ext2_ioctl,
-	fsync:		ext2_sync_file,
+static inline void ext2_put_page(struct page *page)
+{
+	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 ext2_commit_chunk(struct page *page, unsigned from, unsigned to)
+{
+	struct inode *dir = page->mapping->host;
+	int err = 0;
+	dir->i_version = ++event;
+	page->mapping->a_ops->commit_write(NULL, page, from, to);
+	if (IS_SYNC(dir))
+		err = waitfor_one_page(page);
+	return err;
+}
+
+static void ext2_check_page(struct page *page)
+{
+	struct inode *dir = page->mapping->host;
+	struct super_block *sb = dir->i_sb;
+	unsigned chunk_size = ext2_chunk_size(dir);
+	char *kaddr = page_address(page);
+	u32 max_inumber = le32_to_cpu(sb->u.ext2_sb.s_es->s_inodes_count);
+	unsigned offs, rec_len;
+	unsigned limit = PAGE_CACHE_SIZE;
+	ext2_dirent *p;
+	char *error;
+
+	if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) {
+		limit = dir->i_size & ~PAGE_CACHE_MASK;
+		if (limit & (chunk_size - 1))
+			goto Ebadsize;
+		for (offs = limit; offs<PAGE_CACHE_SIZE; offs += chunk_size) {
+			ext2_dirent *p = (ext2_dirent*)(kaddr + offs);
+			p->rec_len = cpu_to_le16(chunk_size);
+		}
+		if (!limit)
+			goto out;
+	}
+	for (offs = 0; offs <= limit - EXT2_DIR_REC_LEN(1); offs += rec_len) {
+		p = (ext2_dirent *)(kaddr + offs);
+		rec_len = le16_to_cpu(p->rec_len);
+
+		if (rec_len < EXT2_DIR_REC_LEN(1))
+			goto Eshort;
+		if (rec_len & 3)
+			goto Ealign;
+		if (rec_len < EXT2_DIR_REC_LEN(p->name_len))
+			goto Enamelen;
+		if (((offs + rec_len - 1) ^ offs) & ~(chunk_size-1))
+			goto Espan;
+		if (le32_to_cpu(p->inode) > max_inumber)
+			goto Einumber;
+	}
+	if (offs != limit)
+		goto Eend;
+out:
+	SetPageChecked(page);
+	return;
+
+	/* Too bad, we had an error */
+
+Ebadsize:
+	ext2_error(sb, "ext2_check_page",
+		"size of directory #%lu is not a multiple of chunk size",
+		dir->i_ino
+	);
+	goto fail;
+Eshort:
+	error = "rec_len is smaller than minimal";
+	goto bad_entry;
+Ealign:
+	error = "unaligned directory entry";
+	goto bad_entry;
+Enamelen:
+	error = "rec_len is too small for name_len";
+	goto bad_entry;
+Espan:
+	error = "directory entry across blocks";
+	goto bad_entry;
+Einumber:
+	error = "inode out of bounds";
+bad_entry:
+	ext2_error (sb, "ext2_check_page", "bad entry in directory #%lu: %s - "
+		"offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
+		dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
+		(unsigned long) le32_to_cpu(p->inode),
+		rec_len, p->name_len);
+	goto fail;
+Eend:
+	p = (ext2_dirent *)(kaddr + offs);
+	ext2_error (sb, "ext2_check_page",
+		"entry in directory #%lu spans the page boundary"
+		"offset=%lu, inode=%lu",
+		dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
+		(unsigned long) le32_to_cpu(p->inode));
+fail:
+	SetPageChecked(page);
+	SetPageError(page);
+}
+
+static struct page * ext2_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;
+		if (!PageChecked(page))
+			ext2_check_page(page);
+		if (PageError(page))
+			goto fail;
+	}
+	return page;
+
+fail:
+	ext2_put_page(page);
+	return ERR_PTR(-EIO);
+}
+
+/*
+ * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure.
+ *
+ * len <= EXT2_NAME_LEN and de != NULL are guaranteed by caller.
+ */
+static inline int ext2_match (int len, const char * const name,
+					struct ext2_dir_entry_2 * de)
+{
+	if (len != de->name_len)
+		return 0;
+	if (!de->inode)
+		return 0;
+	return !memcmp(name, de->name, len);
+}
+
+/*
+ * p is at least 6 bytes before the end of page
+ */
+static inline ext2_dirent *ext2_next_entry(ext2_dirent *p)
+{
+	return (ext2_dirent *)((char*)p + le16_to_cpu(p->rec_len));
+}
+
+static inline unsigned 
+ext2_validate_entry(char *base, unsigned offset, unsigned mask)
+{
+	ext2_dirent *de = (ext2_dirent*)(base + offset);
+	ext2_dirent *p = (ext2_dirent*)(base + (offset&mask));
+	while ((char*)p < (char*)de)
+		p = ext2_next_entry(p);
+	return (char *)p - base;
+}
+
+static unsigned char ext2_filetype_table[EXT2_FT_MAX] = {
+	[EXT2_FT_UNKNOWN]	DT_UNKNOWN,
+	[EXT2_FT_REG_FILE]	DT_REG,
+	[EXT2_FT_DIR]		DT_DIR,
+	[EXT2_FT_CHRDEV]	DT_CHR,
+	[EXT2_FT_BLKDEV]	DT_BLK,
+	[EXT2_FT_FIFO]		DT_FIFO,
+	[EXT2_FT_SOCK]		DT_SOCK,
+	[EXT2_FT_SYMLINK]	DT_LNK,
 };
 
-int ext2_check_dir_entry (const char * function, struct inode * dir,
-			  struct ext2_dir_entry_2 * de,
-			  struct buffer_head * bh,
-			  unsigned long offset)
-{
-	const char * error_msg = NULL;
-
-	if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(1))
-		error_msg = "rec_len is smaller than minimal";
-	else if (le16_to_cpu(de->rec_len) % 4 != 0)
-		error_msg = "rec_len % 4 != 0";
-	else if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(de->name_len))
-		error_msg = "rec_len is too small for name_len";
-	else if (dir && ((char *) de - bh->b_data) + le16_to_cpu(de->rec_len) >
-		 dir->i_sb->s_blocksize)
-		error_msg = "directory entry across blocks";
-	else if (dir && le32_to_cpu(de->inode) > le32_to_cpu(dir->i_sb->u.ext2_sb.s_es->s_inodes_count))
-		error_msg = "inode out of bounds";
-
-	if (error_msg != NULL)
-		ext2_error (dir->i_sb, function, "bad entry in directory #%lu: %s - "
-			    "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
-			    dir->i_ino, error_msg, offset,
-			    (unsigned long) le32_to_cpu(de->inode),
-			    le16_to_cpu(de->rec_len), de->name_len);
-	return error_msg == NULL ? 1 : 0;
-}
-
-static int ext2_readdir(struct file * filp,
-			 void * dirent, filldir_t filldir)
-{
-	int error = 0;
-	unsigned long offset, blk;
-	int i, num, stored;
-	struct buffer_head * bh, * tmp, * bha[16];
-	struct ext2_dir_entry_2 * de;
-	struct super_block * sb;
-	int err;
-	struct inode *inode = filp->f_dentry->d_inode;
+#define S_SHIFT 12
+static unsigned char ext2_type_by_mode[S_IFMT >> S_SHIFT] = {
+	[S_IFREG >> S_SHIFT]	EXT2_FT_REG_FILE,
+	[S_IFDIR >> S_SHIFT]	EXT2_FT_DIR,
+	[S_IFCHR >> S_SHIFT]	EXT2_FT_CHRDEV,
+	[S_IFBLK >> S_SHIFT]	EXT2_FT_BLKDEV,
+	[S_IFIFO >> S_SHIFT]	EXT2_FT_FIFO,
+	[S_IFSOCK >> S_SHIFT]	EXT2_FT_SOCK,
+	[S_IFLNK >> S_SHIFT]	EXT2_FT_SYMLINK,
+};
+
+static inline void ext2_set_de_type(ext2_dirent *de, struct inode *inode)
+{
+	mode_t mode = inode->i_mode;
+	if (EXT2_HAS_INCOMPAT_FEATURE(inode->i_sb, EXT2_FEATURE_INCOMPAT_FILETYPE))
+		de->file_type = ext2_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
+	else
+		de->file_type = 0;
+}
 
-	sb = inode->i_sb;
+static int
+ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
+{
+	loff_t 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);
+	unsigned chunk_mask = ~(ext2_chunk_size(inode)-1);
+	unsigned char *types = NULL;
+	int need_revalidate = (filp->f_version != inode->i_version);
+
+	if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
+		goto done;
+
+	if (EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE))
+		types = ext2_filetype_table;
+
+	for ( ; n < npages; n++, offset = 0) {
+		char *kaddr, *limit;
+		ext2_dirent *de;
+		struct page *page = ext2_get_page(inode, n);
 
-	stored = 0;
-	bh = NULL;
-	offset = filp->f_pos & (sb->s_blocksize - 1);
-
-	while (!error && !stored && filp->f_pos < inode->i_size) {
-		blk = (filp->f_pos) >> EXT2_BLOCK_SIZE_BITS(sb);
-		bh = ext2_bread (inode, blk, 0, &err);
-		if (!bh) {
-			ext2_error (sb, "ext2_readdir",
-				    "directory #%lu contains a hole at offset %lu",
-				    inode->i_ino, (unsigned long)filp->f_pos);
-			filp->f_pos += sb->s_blocksize - offset;
+		if (IS_ERR(page))
 			continue;
+		kaddr = page_address(page);
+		if (need_revalidate) {
+			offset = ext2_validate_entry(kaddr, offset, chunk_mask);
+			need_revalidate = 0;
 		}
+		de = (ext2_dirent *)(kaddr+offset);
+		limit = kaddr + PAGE_CACHE_SIZE - EXT2_DIR_REC_LEN(1);
+		for ( ;(char*)de <= limit; de = ext2_next_entry(de))
+			if (de->inode) {
+				int over;
+				unsigned char d_type = DT_UNKNOWN;
 
-		/*
-		 * Do the readahead
-		 */
-		if (!offset) {
-			for (i = 16 >> (EXT2_BLOCK_SIZE_BITS(sb) - 9), num = 0;
-			     i > 0; i--) {
-				tmp = ext2_getblk (inode, ++blk, 0, &err);
-				if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp))
-					bha[num++] = tmp;
-				else
-					brelse (tmp);
-			}
-			if (num) {
-				ll_rw_block (READA, num, bha);
-				for (i = 0; i < num; i++)
-					brelse (bha[i]);
-			}
-		}
-		
-revalidate:
-		/* If the dir block has changed since the last call to
-		 * readdir(2), then we might be pointing to an invalid
-		 * dirent right now.  Scan from the start of the block
-		 * to make sure. */
-		if (filp->f_version != inode->i_version) {
-			for (i = 0; i < sb->s_blocksize && i < offset; ) {
-				de = (struct ext2_dir_entry_2 *) 
-					(bh->b_data + i);
-				/* It's too expensive to do a full
-				 * dirent test each time round this
-				 * loop, but we do have to test at
-				 * least that it is non-zero.  A
-				 * failure will be detected in the
-				 * dirent test below. */
-				if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(1))
-					break;
-				i += le16_to_cpu(de->rec_len);
+				if (types && de->file_type < EXT2_FT_MAX)
+					d_type = types[de->file_type];
+
+				offset = (char *)de - kaddr;
+				over = filldir(dirent, de->name, de->name_len,
+						(n<<PAGE_CACHE_SHIFT) | offset,
+						le32_to_cpu(de->inode), d_type);
+				if (over) {
+					ext2_put_page(page);
+					goto done;
+				}
 			}
-			offset = i;
-			filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1))
-				| offset;
-			filp->f_version = inode->i_version;
+		ext2_put_page(page);
+	}
+
+done:
+	filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
+	filp->f_version = inode->i_version;
+	UPDATE_ATIME(inode);
+	return 0;
+}
+
+/*
+ *	ext2_find_entry()
+ *
+ * finds an entry in the specified directory with the wanted name. It
+ * returns the page in which the entry was found, and the entry itself
+ * (as a parameter - res_dir). Page is returned mapped and unlocked.
+ * Entry is guaranteed to be valid.
+ */
+struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
+			struct dentry *dentry, struct page ** res_page)
+{
+	const char *name = dentry->d_name.name;
+	int namelen = dentry->d_name.len;
+	unsigned reclen = EXT2_DIR_REC_LEN(namelen);
+	unsigned long n;
+	unsigned long npages = dir_pages(dir);
+	struct page *page = NULL;
+	ext2_dirent * de;
+
+	/* OFFSET_CACHE */
+	*res_page = NULL;
+
+	for (n = 0; n < npages; n++) {
+		char *kaddr;
+		page = ext2_get_page(dir, n);
+		if (IS_ERR(page))
+			continue;
+
+		kaddr = page_address(page);
+		de = (ext2_dirent *) kaddr;
+		kaddr += PAGE_CACHE_SIZE - reclen;
+		for ( ; (char *) de <= kaddr ; de = ext2_next_entry(de))
+			if (ext2_match (namelen, name, de))
+				goto found;
+		ext2_put_page(page);
+	}
+	return NULL;
+
+found:
+	*res_page = page;
+	return de;
+}
+
+struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p)
+{
+	struct page *page = ext2_get_page(dir, 0);
+	ext2_dirent *de = NULL;
+
+	if (!IS_ERR(page)) {
+		de = ext2_next_entry((ext2_dirent *) page_address(page));
+		*p = page;
+	}
+	return de;
+}
+
+ino_t ext2_inode_by_name(struct inode * dir, struct dentry *dentry)
+{
+	ino_t res = 0;
+	struct ext2_dir_entry_2 * de;
+	struct page *page;
+	
+	de = ext2_find_entry (dir, dentry, &page);
+	if (de) {
+		res = le32_to_cpu(de->inode);
+		kunmap(page);
+		page_cache_release(page);
+	}
+	return res;
+}
+
+/* Releases the page */
+void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
+			struct page *page, struct inode *inode)
+{
+	unsigned from = (char *)de-(char*)page_address(page);
+	unsigned to = from + le16_to_cpu(de->rec_len);
+	int err;
+
+	lock_page(page);
+	err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
+	if (err)
+		BUG();
+	de->inode = cpu_to_le32(inode->i_ino);
+	ext2_set_de_type (de, inode);
+	err = ext2_commit_chunk(page, from, to);
+	UnlockPage(page);
+	ext2_put_page(page);
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	mark_inode_dirty(dir);
+}
+
+/*
+ *	Parent is locked.
+ */
+int ext2_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;
+	unsigned reclen = EXT2_DIR_REC_LEN(namelen);
+	unsigned short rec_len, name_len;
+	struct page *page = NULL;
+	ext2_dirent * 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 = ext2_get_page(dir, n);
+		err = PTR_ERR(page);
+		if (IS_ERR(page))
+			goto out;
+		kaddr = page_address(page);
+		de = (ext2_dirent *)kaddr;
+		kaddr += PAGE_CACHE_SIZE - reclen;
+		while ((char *)de <= kaddr) {
+			err = -EEXIST;
+			if (ext2_match (namelen, name, de))
+				goto out_page;
+			name_len = EXT2_DIR_REC_LEN(de->name_len);
+			rec_len = le16_to_cpu(de->rec_len);
+			if (!de->inode && rec_len >= reclen)
+				goto got_it;
+			if (rec_len >= name_len + reclen)
+				goto got_it;
+			de = (ext2_dirent *) ((char *) de + rec_len);
 		}
-		
-		while (!error && filp->f_pos < inode->i_size 
-		       && offset < sb->s_blocksize) {
-			de = (struct ext2_dir_entry_2 *) (bh->b_data + offset);
-			if (!ext2_check_dir_entry ("ext2_readdir", inode, de,
-						   bh, offset)) {
-				/* On error, skip the f_pos to the
-                                   next block. */
-				filp->f_pos = (filp->f_pos | (sb->s_blocksize - 1))
-					      + 1;
-				brelse (bh);
-				return stored;
-			}
-			offset += le16_to_cpu(de->rec_len);
-			if (le32_to_cpu(de->inode)) {
-				/* We might block in the next section
-				 * if the data destination is
-				 * currently swapped out.  So, use a
-				 * version stamp to detect whether or
-				 * not the directory has been modified
-				 * during the copy operation.
-				 */
-				unsigned long version = filp->f_version;
-				unsigned char d_type = DT_UNKNOWN;
+		ext2_put_page(page);
+	}
+	BUG();
+	return -EINVAL;
 
-				if (EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE)
-				    && de->file_type < EXT2_FT_MAX)
-					d_type = ext2_filetype_table[de->file_type];
-				error = filldir(dirent, de->name,
-						de->name_len,
-						filp->f_pos, le32_to_cpu(de->inode),
-						d_type);
-				if (error)
-					break;
-				if (version != filp->f_version)
-					goto revalidate;
-				stored ++;
+got_it:
+	from = (char*)de - (char*)page_address(page);
+	to = from + rec_len;
+	lock_page(page);
+	err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
+	if (err)
+		goto out_unlock;
+	if (de->inode) {
+		ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len);
+		de1->rec_len = cpu_to_le16(rec_len - name_len);
+		de->rec_len = cpu_to_le16(name_len);
+		de = de1;
+	}
+	de->name_len = namelen;
+	memcpy (de->name, name, namelen);
+	de->inode = cpu_to_le32(inode->i_ino);
+	ext2_set_de_type (de, inode);
+	err = ext2_commit_chunk(page, from, to);
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	mark_inode_dirty(dir);
+	/* OFFSET_CACHE */
+out_unlock:
+	UnlockPage(page);
+out_page:
+	ext2_put_page(page);
+out:
+	return err;
+}
+
+/*
+ * ext2_delete_entry deletes a directory entry by merging it with the
+ * previous entry. Page is up-to-date. Releases the page.
+ */
+int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
+{
+	struct address_space *mapping = page->mapping;
+	struct inode *inode = mapping->host;
+	char *kaddr = page_address(page);
+	unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
+	unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len);
+	ext2_dirent * pde = NULL;
+	ext2_dirent * de = (ext2_dirent *) (kaddr + from);
+	int err;
+
+	while ((char*)de < (char*)dir) {
+		pde = de;
+		de = ext2_next_entry(de);
+	}
+	if (pde)
+		from = (char*)pde - (char*)page_address(page);
+	lock_page(page);
+	err = mapping->a_ops->prepare_write(NULL, page, from, to);
+	if (err)
+		BUG();
+	if (pde)
+		pde->rec_len = cpu_to_le16(to-from);
+	dir->inode = 0;
+	err = ext2_commit_chunk(page, from, to);
+	UnlockPage(page);
+	ext2_put_page(page);
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	mark_inode_dirty(inode);
+	return err;
+}
+
+/*
+ * Set the first fragment of directory.
+ */
+int ext2_make_empty(struct inode *inode, struct inode *parent)
+{
+	struct address_space *mapping = inode->i_mapping;
+	struct page *page = grab_cache_page(mapping, 0);
+	unsigned chunk_size = ext2_chunk_size(inode);
+	struct ext2_dir_entry_2 * de;
+	char *base;
+	int err;
+
+	if (!page)
+		return -ENOMEM;
+	err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size);
+	if (err)
+		goto fail;
+
+	base = page_address(page);
+
+	de = (struct ext2_dir_entry_2 *) base;
+	de->name_len = 1;
+	de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1));
+	memcpy (de->name, ".\0\0", 4);
+	de->inode = cpu_to_le32(inode->i_ino);
+	ext2_set_de_type (de, inode);
+
+	de = (struct ext2_dir_entry_2 *) (base + EXT2_DIR_REC_LEN(1));
+	de->name_len = 2;
+	de->rec_len = cpu_to_le16(chunk_size - EXT2_DIR_REC_LEN(1));
+	de->inode = cpu_to_le32(parent->i_ino);
+	memcpy (de->name, "..\0", 4);
+	ext2_set_de_type (de, inode);
+
+	err = ext2_commit_chunk(page, 0, chunk_size);
+fail:
+	UnlockPage(page);
+	page_cache_release(page);
+	return err;
+}
+
+/*
+ * routine to check that the specified directory is empty (for rmdir)
+ */
+int ext2_empty_dir (struct inode * inode)
+{
+	struct page *page = NULL;
+	unsigned long i, npages = dir_pages(inode);
+	
+	for (i = 0; i < npages; i++) {
+		char *kaddr;
+		ext2_dirent * de;
+		page = ext2_get_page(inode, i);
+
+		if (IS_ERR(page))
+			continue;
+
+		kaddr = page_address(page);
+		de = (ext2_dirent *)kaddr;
+		kaddr += PAGE_CACHE_SIZE-EXT2_DIR_REC_LEN(1);
+
+		while ((char *)de <= kaddr) {
+			if (de->inode != 0) {
+				/* check for . and .. */
+				if (de->name[0] != '.')
+					goto not_empty;
+				if (de->name_len > 2)
+					goto not_empty;
+				if (de->name_len < 2) {
+					if (de->inode !=
+					    cpu_to_le32(inode->i_ino))
+						goto not_empty;
+				} else if (de->name[1] != '.')
+					goto not_empty;
 			}
-			filp->f_pos += le16_to_cpu(de->rec_len);
+			de = ext2_next_entry(de);
 		}
-		offset = 0;
-		brelse (bh);
+		ext2_put_page(page);
 	}
-	UPDATE_ATIME(inode);
+	return 1;
+
+not_empty:
+	ext2_put_page(page);
 	return 0;
 }
+
+struct file_operations ext2_dir_operations = {
+	read:		generic_read_dir,
+	readdir:	ext2_readdir,
+	fsync:		ext2_sync_file,
+};
diff -u --recursive --new-file v2.4.5/linux/fs/ext2/ialloc.c linux/fs/ext2/ialloc.c
--- v2.4.5/linux/fs/ext2/ialloc.c	Fri Mar 23 12:15:07 2001
+++ linux/fs/ext2/ialloc.c	Mon Jun 11 19:15:27 2001
@@ -199,10 +199,15 @@
 
 	lock_super (sb);
 	es = sb->u.ext2_sb.s_es;
-	if (ino < EXT2_FIRST_INO(sb) || 
+	is_directory = S_ISDIR(inode->i_mode);
+
+	/* Do this BEFORE marking the inode not in use or returning an error */
+	clear_inode (inode);
+
+	if (ino < EXT2_FIRST_INO(sb) ||
 	    ino > le32_to_cpu(es->s_inodes_count)) {
-		ext2_error (sb, "free_inode",
-			    "reserved inode or nonexistent inode");
+		ext2_error (sb, "ext2_free_inode",
+			    "reserved or nonexistent inode %lu", ino);
 		goto error_return;
 	}
 	block_group = (ino - 1) / EXT2_INODES_PER_GROUP(sb);
@@ -210,13 +215,8 @@
 	bitmap_nr = load_inode_bitmap (sb, block_group);
 	if (bitmap_nr < 0)
 		goto error_return;
-	
-	bh = sb->u.ext2_sb.s_inode_bitmap[bitmap_nr];
 
-	is_directory = S_ISDIR(inode->i_mode);
-
-	/* Do this BEFORE marking the inode not in use */
-	clear_inode (inode);
+	bh = sb->u.ext2_sb.s_inode_bitmap[bitmap_nr];
 
 	/* Ok, now we can actually update the inode bitmaps.. */
 	if (!ext2_clear_bit (bit, bh->b_data))
diff -u --recursive --new-file v2.4.5/linux/fs/ext2/inode.c linux/fs/ext2/inode.c
--- v2.4.5/linux/fs/ext2/inode.c	Thu Apr 26 10:44:10 2001
+++ linux/fs/ext2/inode.c	Mon Jun 11 19:15:27 2001
@@ -230,11 +230,11 @@
  *	or when it reads all @depth-1 indirect blocks successfully and finds
  *	the whole chain, all way to the data (returns %NULL, *err == 0).
  */
-static inline Indirect *ext2_get_branch(struct inode *inode,
-					int depth,
-					int *offsets,
-					Indirect chain[4],
-					int *err)
+static Indirect *ext2_get_branch(struct inode *inode,
+				 int depth,
+				 int *offsets,
+				 Indirect chain[4],
+				 int *err)
 {
 	kdev_t dev = inode->i_dev;
 	int size = inode->i_sb->s_blocksize;
@@ -574,82 +574,6 @@
 	goto reread;
 }
 
-struct buffer_head * ext2_getblk(struct inode * inode, long block, int create, int * err)
-{
-	struct buffer_head dummy;
-	int error;
-
-	dummy.b_state = 0;
-	dummy.b_blocknr = -1000;
-	error = ext2_get_block(inode, block, &dummy, create);
-	*err = error;
-	if (!error && buffer_mapped(&dummy)) {
-		struct buffer_head *bh;
-		bh = getblk(dummy.b_dev, dummy.b_blocknr, inode->i_sb->s_blocksize);
-		if (buffer_new(&dummy)) {
-			lock_buffer(bh);
-			memset(bh->b_data, 0, inode->i_sb->s_blocksize);
-			mark_buffer_uptodate(bh, 1);
-			unlock_buffer(bh);
-			mark_buffer_dirty_inode(bh, inode);
-		}
-		return bh;
-	}
-	return NULL;
-}
-
-struct buffer_head * ext2_bread (struct inode * inode, int block, 
-				 int create, int *err)
-{
-	struct buffer_head * bh;
-	int prev_blocks;
-	
-	prev_blocks = inode->i_blocks;
-	
-	bh = ext2_getblk (inode, block, create, err);
-	if (!bh)
-		return bh;
-	
-	/*
-	 * If the inode has grown, and this is a directory, then perform
-	 * preallocation of a few more blocks to try to keep directory
-	 * fragmentation down.
-	 */
-	if (create && 
-	    S_ISDIR(inode->i_mode) && 
-	    inode->i_blocks > prev_blocks &&
-	    EXT2_HAS_COMPAT_FEATURE(inode->i_sb,
-				    EXT2_FEATURE_COMPAT_DIR_PREALLOC)) {
-		int i;
-		struct buffer_head *tmp_bh;
-		
-		for (i = 1;
-		     i < EXT2_SB(inode->i_sb)->s_es->s_prealloc_dir_blocks;
-		     i++) {
-			/* 
-			 * ext2_getblk will zero out the contents of the
-			 * directory for us
-			 */
-			tmp_bh = ext2_getblk(inode, block+i, create, err);
-			if (!tmp_bh) {
-				brelse (bh);
-				return 0;
-			}
-			brelse (tmp_bh);
-		}
-	}
-	
-	if (buffer_uptodate(bh))
-		return bh;
-	ll_rw_block (READ, 1, &bh);
-	wait_on_buffer (bh);
-	if (buffer_uptodate(bh))
-		return bh;
-	brelse (bh);
-	*err = -EIO;
-	return NULL;
-}
-
 static int ext2_writepage(struct page *page)
 {
 	return block_write_full_page(page,ext2_get_block);
@@ -1067,6 +991,7 @@
 	} else if (S_ISDIR(inode->i_mode)) {
 		inode->i_op = &ext2_dir_inode_operations;
 		inode->i_fop = &ext2_dir_operations;
+		inode->i_mapping->a_ops = &ext2_aops;
 	} else if (S_ISLNK(inode->i_mode)) {
 		if (!inode->i_blocks)
 			inode->i_op = &ext2_fast_symlink_inode_operations;
diff -u --recursive --new-file v2.4.5/linux/fs/ext2/namei.c linux/fs/ext2/namei.c
--- v2.4.5/linux/fs/ext2/namei.c	Thu Feb 15 12:32:21 2001
+++ linux/fs/ext2/namei.c	Mon Jun 11 19:15:27 2001
@@ -1,5 +1,18 @@
 /*
- *  linux/fs/ext2/namei.c
+ * linux/fs/ext2/namei.c
+ *
+ * Rewrite to pagecache. Almost all code had been changed, so blame me
+ * if the things go wrong. Please, send bug reports to viro@math.psu.edu
+ *
+ * Stuff here is basically a glue between the VFS and generic UNIXish
+ * filesystem that keeps everything in pagecache. All knowledge of the
+ * directory layout is in fs/ext2/dir.c - it turned out to be easily separatable
+ * and it's easier to debug that way. In principle we might want to
+ * generalize that a bit and turn it into a library. Or not.
+ *
+ * The only non-static object here is ext2_dir_inode_operations.
+ *
+ * TODO: get rid of kmap() use, add readahead.
  *
  * Copyright (C) 1992, 1993, 1994, 1995
  * Remy Card (card@masi.ibp.fr)
@@ -14,344 +27,63 @@
  *
  *  Big-endian to little-endian byte-swapping/bitmaps by
  *        David S. Miller (davem@caip.rutgers.edu), 1995
- *  Directory entry file type support and forward compatibility hooks
- *  	for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
  */
 
 #include <linux/fs.h>
 #include <linux/ext2_fs.h>
-#include <linux/locks.h>
-#include <linux/quotaops.h>
-
-
+#include <linux/pagemap.h>
 
 /*
- * define how far ahead to read directories while searching them.
+ * Couple of helper functions - make the code slightly cleaner.
  */
-#define NAMEI_RA_CHUNKS  2
-#define NAMEI_RA_BLOCKS  4
-#define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
-#define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
 
-/*
- * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure.
- *
- * `len <= EXT2_NAME_LEN' is guaranteed by caller.
- * `de != NULL' is guaranteed by caller.
- */
-static inline int ext2_match (int len, const char * const name,
-		       struct ext2_dir_entry_2 * de)
+static inline void ext2_inc_count(struct inode *inode)
 {
-	if (len != de->name_len)
-		return 0;
-	if (!de->inode)
-		return 0;
-	return !memcmp(name, de->name, len);
+	inode->i_nlink++;
+	mark_inode_dirty(inode);
 }
 
-/*
- *	ext2_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 * ext2_find_entry (struct inode * dir,
-					     const char * const name, int namelen,
-					     struct ext2_dir_entry_2 ** res_dir)
-{
-	struct super_block * sb;
-	struct buffer_head * bh_use[NAMEI_RA_SIZE];
-	struct buffer_head * bh_read[NAMEI_RA_SIZE];
-	unsigned long offset;
-	int block, toread, i, err;
-
-	*res_dir = NULL;
-	sb = dir->i_sb;
-
-	if (namelen > EXT2_NAME_LEN)
-		return NULL;
-
-	memset (bh_use, 0, sizeof (bh_use));
-	toread = 0;
-	for (block = 0; block < NAMEI_RA_SIZE; ++block) {
-		struct buffer_head * bh;
-
-		if ((block << EXT2_BLOCK_SIZE_BITS (sb)) >= dir->i_size)
-			break;
-		bh = ext2_getblk (dir, block, 0, &err);
-		bh_use[block] = bh;
-		if (bh && !buffer_uptodate(bh))
-			bh_read[toread++] = bh;
-	}
-
-	for (block = 0, offset = 0; offset < dir->i_size; block++) {
-		struct buffer_head * bh;
-		struct ext2_dir_entry_2 * de;
-		char * dlimit;
-
-		if ((block % NAMEI_RA_BLOCKS) == 0 && toread) {
-			ll_rw_block (READ, toread, bh_read);
-			toread = 0;
-		}
-		bh = bh_use[block % NAMEI_RA_SIZE];
-		if (!bh) {
-#if 0
-			ext2_error (sb, "ext2_find_entry",
-				    "directory #%lu contains a hole at offset %lu",
-				    dir->i_ino, offset);
-#endif
-			offset += sb->s_blocksize;
-			continue;
-		}
-		wait_on_buffer (bh);
-		if (!buffer_uptodate(bh)) {
-			/*
-			 * read error: all bets are off
-			 */
-			break;
-		}
-
-		de = (struct ext2_dir_entry_2 *) bh->b_data;
-		dlimit = bh->b_data + sb->s_blocksize;
-		while ((char *) de < dlimit) {
-			/* this code is executed quadratically often */
-			/* do minimal checking `by hand' */
-			int de_len;
-
-			if ((char *) de + namelen <= dlimit &&
-			    ext2_match (namelen, name, de)) {
-				/* found a match -
-				   just to be sure, do a full check */
-				if (!ext2_check_dir_entry("ext2_find_entry",
-							  dir, de, bh, offset))
-					goto failure;
-				for (i = 0; i < NAMEI_RA_SIZE; ++i) {
-					if (bh_use[i] != bh)
-						brelse (bh_use[i]);
-				}
-				*res_dir = de;
-				return bh;
-			}
-			/* prevent looping on a bad block */
-			de_len = le16_to_cpu(de->rec_len);
-			if (de_len <= 0)
-				goto failure;
-			offset += de_len;
-			de = (struct ext2_dir_entry_2 *)
-				((char *) de + de_len);
-		}
+static inline void ext2_dec_count(struct inode *inode)
+{
+	inode->i_nlink--;
+	mark_inode_dirty(inode);
+}
 
-		brelse (bh);
-		if (((block + NAMEI_RA_SIZE) << EXT2_BLOCK_SIZE_BITS (sb)) >=
-		    dir->i_size)
-			bh = NULL;
-		else
-			bh = ext2_getblk (dir, block + NAMEI_RA_SIZE, 0, &err);
-		bh_use[block % NAMEI_RA_SIZE] = bh;
-		if (bh && !buffer_uptodate(bh))
-			bh_read[toread++] = bh;
+static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode)
+{
+	int err = ext2_add_link(dentry, inode);
+	if (!err) {
+		d_instantiate(dentry, inode);
+		return 0;
 	}
-
-failure:
-	for (i = 0; i < NAMEI_RA_SIZE; ++i)
-		brelse (bh_use[i]);
-	return NULL;
+	ext2_dec_count(inode);
+	iput(inode);
+	return err;
 }
 
+/*
+ * Methods themselves.
+ */
+
 static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry)
 {
 	struct inode * inode;
-	struct ext2_dir_entry_2 * de;
-	struct buffer_head * bh;
-
+	ino_t ino;
+	
 	if (dentry->d_name.len > EXT2_NAME_LEN)
 		return ERR_PTR(-ENAMETOOLONG);
 
-	bh = ext2_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de);
+	ino = ext2_inode_by_name(dir, dentry);
 	inode = NULL;
-	if (bh) {
-		unsigned long ino = le32_to_cpu(de->inode);
-		brelse (bh);
+	if (ino) {
 		inode = iget(dir->i_sb, ino);
-
-		if (!inode)
+		if (!inode) 
 			return ERR_PTR(-EACCES);
 	}
 	d_add(dentry, inode);
 	return NULL;
 }
 
-#define S_SHIFT 12
-static unsigned char ext2_type_by_mode[S_IFMT >> S_SHIFT] = {
-	[S_IFREG >> S_SHIFT]	EXT2_FT_REG_FILE,
-	[S_IFDIR >> S_SHIFT]	EXT2_FT_DIR,
-	[S_IFCHR >> S_SHIFT]	EXT2_FT_CHRDEV,
-	[S_IFBLK >> S_SHIFT]	EXT2_FT_BLKDEV,
-	[S_IFIFO >> S_SHIFT]	EXT2_FT_FIFO,
-	[S_IFSOCK >> S_SHIFT]	EXT2_FT_SOCK,
-	[S_IFLNK >> S_SHIFT]	EXT2_FT_SYMLINK,
-};
-
-static inline void ext2_set_de_type(struct super_block *sb,
-				struct ext2_dir_entry_2 *de,
-				umode_t mode) {
-	if (EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE))
-		de->file_type = ext2_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
-}
-
-/*
- *	ext2_add_entry()
- *
- * adds a file entry to the specified directory.
- */
-int ext2_add_entry (struct inode * dir, const char * name, int namelen,
-		    struct inode *inode)
-{
-	unsigned long offset;
-	unsigned short rec_len;
-	struct buffer_head * bh;
-	struct ext2_dir_entry_2 * de, * de1;
-	struct super_block * sb;
-	int	retval;
-
-	sb = dir->i_sb;
-
-	if (!namelen)
-		return -EINVAL;
-	bh = ext2_bread (dir, 0, 0, &retval);
-	if (!bh)
-		return retval;
-	rec_len = EXT2_DIR_REC_LEN(namelen);
-	offset = 0;
-	de = (struct ext2_dir_entry_2 *) bh->b_data;
-	while (1) {
-		if ((char *)de >= sb->s_blocksize + bh->b_data) {
-			brelse (bh);
-			bh = NULL;
-			bh = ext2_bread (dir, offset >> EXT2_BLOCK_SIZE_BITS(sb), 1, &retval);
-			if (!bh)
-				return retval;
-			if (dir->i_size <= offset) {
-				if (dir->i_size == 0) {
-					brelse(bh);
-					return -ENOENT;
-				}
-
-				ext2_debug ("creating next block\n");
-
-				de = (struct ext2_dir_entry_2 *) bh->b_data;
-				de->inode = 0;
-				de->rec_len = le16_to_cpu(sb->s_blocksize);
-				dir->i_size = offset + sb->s_blocksize;
-				dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
-				mark_inode_dirty(dir);
-			} else {
-
-				ext2_debug ("skipping to next block\n");
-
-				de = (struct ext2_dir_entry_2 *) bh->b_data;
-			}
-		}
-		if (!ext2_check_dir_entry ("ext2_add_entry", dir, de, bh,
-					   offset)) {
-			brelse (bh);
-			return -ENOENT;
-		}
-		if (ext2_match (namelen, name, de)) {
-				brelse (bh);
-				return -EEXIST;
-		}
-		if ((le32_to_cpu(de->inode) == 0 && le16_to_cpu(de->rec_len) >= rec_len) ||
-		    (le16_to_cpu(de->rec_len) >= EXT2_DIR_REC_LEN(de->name_len) + rec_len)) {
-			offset += le16_to_cpu(de->rec_len);
-			if (le32_to_cpu(de->inode)) {
-				de1 = (struct ext2_dir_entry_2 *) ((char *) de +
-					EXT2_DIR_REC_LEN(de->name_len));
-				de1->rec_len = cpu_to_le16(le16_to_cpu(de->rec_len) -
-					EXT2_DIR_REC_LEN(de->name_len));
-				de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(de->name_len));
-				de = de1;
-			}
-			de->file_type = EXT2_FT_UNKNOWN;
-			if (inode) {
-				de->inode = cpu_to_le32(inode->i_ino);
-				ext2_set_de_type(dir->i_sb, de, inode->i_mode);
-			} else
-				de->inode = 0;
-			de->name_len = namelen;
-			memcpy (de->name, name, namelen);
-			/*
-			 * XXX shouldn't update any times until successful
-			 * completion of syscall, but too many callers depend
-			 * on this.
-			 *
-			 * XXX similarly, too many callers depend on
-			 * ext2_new_inode() setting the times, but error
-			 * recovery deletes the inode, so the worst that can
-			 * happen is that the times are slightly out of date
-			 * and/or different from the directory change time.
-			 */
-			dir->i_mtime = dir->i_ctime = CURRENT_TIME;
-			dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
-			mark_inode_dirty(dir);
-			dir->i_version = ++event;
-			mark_buffer_dirty_inode(bh, dir);
-			if (IS_SYNC(dir)) {
-				ll_rw_block (WRITE, 1, &bh);
-				wait_on_buffer (bh);
-			}
-			brelse(bh);
-			return 0;
-		}
-		offset += le16_to_cpu(de->rec_len);
-		de = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
-	}
-	brelse (bh);
-	return -ENOSPC;
-}
-
-/*
- * ext2_delete_entry deletes a directory entry by merging it with the
- * previous entry
- */
-static int ext2_delete_entry (struct inode * dir,
-			      struct ext2_dir_entry_2 * de_del,
-			      struct buffer_head * bh)
-{
-	struct ext2_dir_entry_2 * de, * pde;
-	int i;
-
-	i = 0;
-	pde = NULL;
-	de = (struct ext2_dir_entry_2 *) bh->b_data;
-	while (i < bh->b_size) {
-		if (!ext2_check_dir_entry ("ext2_delete_entry", NULL, 
-					   de, bh, i))
-			return -EIO;
-		if (de == de_del)  {
-			if (pde)
-				pde->rec_len =
-					cpu_to_le16(le16_to_cpu(pde->rec_len) +
-						    le16_to_cpu(de->rec_len));
-			else
-				de->inode = 0;
-			dir->i_version = ++event;
-			mark_buffer_dirty_inode(bh, dir);
-			if (IS_SYNC(dir)) {
-				ll_rw_block (WRITE, 1, &bh);
-				wait_on_buffer (bh);
-			}
-			return 0;
-		}
-		i += le16_to_cpu(de->rec_len);
-		pde = de;
-		de = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
-	}
-	return -ENOENT;
-}
-
 /*
  * By the time this is called, we already have created
  * the directory cache entry for the new file, but it
@@ -364,454 +96,245 @@
 {
 	struct inode * inode = ext2_new_inode (dir, mode);
 	int err = PTR_ERR(inode);
-	if (IS_ERR(inode))
-		return err;
-
-	inode->i_op = &ext2_file_inode_operations;
-	inode->i_fop = &ext2_file_operations;
-	inode->i_mapping->a_ops = &ext2_aops;
-	inode->i_mode = mode;
-	mark_inode_dirty(inode);
-	err = ext2_add_entry (dir, dentry->d_name.name, dentry->d_name.len, 
-			     inode);
-	if (err) {
-		inode->i_nlink--;
+	if (!IS_ERR(inode)) {
+		inode->i_op = &ext2_file_inode_operations;
+		inode->i_fop = &ext2_file_operations;
+		inode->i_mapping->a_ops = &ext2_aops;
 		mark_inode_dirty(inode);
-		iput (inode);
-		return err;
+		err = ext2_add_nondir(dentry, inode);
 	}
-	d_instantiate(dentry, inode);
-	return 0;
+	return err;
 }
 
 static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
 {
 	struct inode * inode = ext2_new_inode (dir, mode);
 	int err = PTR_ERR(inode);
-
-	if (IS_ERR(inode))
-		return err;
-
-	inode->i_uid = current->fsuid;
-	init_special_inode(inode, mode, rdev);
-	err = ext2_add_entry (dir, dentry->d_name.name, dentry->d_name.len, 
-			     inode);
-	if (err)
-		goto out_no_entry;
-	mark_inode_dirty(inode);
-	d_instantiate(dentry, inode);
-	return 0;
-
-out_no_entry:
-	inode->i_nlink--;
-	mark_inode_dirty(inode);
-	iput(inode);
+	if (!IS_ERR(inode)) {
+		init_special_inode(inode, mode, rdev);
+		mark_inode_dirty(inode);
+		err = ext2_add_nondir(dentry, inode);
+	}
 	return err;
 }
 
-static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
+static int ext2_symlink (struct inode * dir, struct dentry * dentry,
+	const char * symname)
 {
+	struct super_block * sb = dir->i_sb;
+	int err = -ENAMETOOLONG;
+	unsigned l = strlen(symname)+1;
 	struct inode * inode;
-	struct buffer_head * dir_block;
-	struct ext2_dir_entry_2 * de;
-	int err;
 
-	if (dir->i_nlink >= EXT2_LINK_MAX)
-		return -EMLINK;
+	if (l > sb->s_blocksize)
+		goto out;
 
-	inode = ext2_new_inode (dir, S_IFDIR);
+	inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO);
 	err = PTR_ERR(inode);
 	if (IS_ERR(inode))
-		return err;
+		goto out;
 
-	inode->i_op = &ext2_dir_inode_operations;
-	inode->i_fop = &ext2_dir_operations;
-	inode->i_size = inode->i_sb->s_blocksize;
-	inode->i_blocks = 0;	
-	dir_block = ext2_bread (inode, 0, 1, &err);
-	if (!dir_block) {
-		inode->i_nlink--; /* is this nlink == 0? */
-		mark_inode_dirty(inode);
-		iput (inode);
-		return err;
+	if (l > sizeof (inode->u.ext2_i.i_data)) {
+		/* slow symlink */
+		inode->i_op = &page_symlink_inode_operations;
+		inode->i_mapping->a_ops = &ext2_aops;
+		err = block_symlink(inode, symname, l);
+		if (err)
+			goto out_fail;
+	} else {
+		/* fast symlink */
+		inode->i_op = &ext2_fast_symlink_inode_operations;
+		memcpy((char*)&inode->u.ext2_i.i_data,symname,l);
+		inode->i_size = l-1;
 	}
-	de = (struct ext2_dir_entry_2 *) dir_block->b_data;
-	de->inode = cpu_to_le32(inode->i_ino);
-	de->name_len = 1;
-	de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(de->name_len));
-	strcpy (de->name, ".");
-	ext2_set_de_type(dir->i_sb, de, S_IFDIR);
-	de = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
-	de->inode = cpu_to_le32(dir->i_ino);
-	de->rec_len = cpu_to_le16(inode->i_sb->s_blocksize - EXT2_DIR_REC_LEN(1));
-	de->name_len = 2;
-	strcpy (de->name, "..");
-	ext2_set_de_type(dir->i_sb, de, S_IFDIR);
-	inode->i_nlink = 2;
-	mark_buffer_dirty_inode(dir_block, dir);
-	brelse (dir_block);
-	inode->i_mode = S_IFDIR | mode;
-	if (dir->i_mode & S_ISGID)
-		inode->i_mode |= S_ISGID;
 	mark_inode_dirty(inode);
-	err = ext2_add_entry (dir, dentry->d_name.name, dentry->d_name.len, 
-			     inode);
-	if (err)
-		goto out_no_entry;
-	dir->i_nlink++;
-	dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
-	mark_inode_dirty(dir);
-	d_instantiate(dentry, inode);
-	return 0;
 
-out_no_entry:
-	inode->i_nlink = 0;
-	mark_inode_dirty(inode);
-	iput (inode);
+	err = ext2_add_nondir(dentry, inode);
+out:
 	return err;
-}
 
-/*
- * routine to check that the specified directory is empty (for rmdir)
- */
-static int empty_dir (struct inode * inode)
-{
-	unsigned long offset;
-	struct buffer_head * bh;
-	struct ext2_dir_entry_2 * de, * de1;
-	struct super_block * sb;
-	int err;
-
-	sb = inode->i_sb;
-	if (inode->i_size < EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2) ||
-	    !(bh = ext2_bread (inode, 0, 0, &err))) {
-	    	ext2_warning (inode->i_sb, "empty_dir",
-			      "bad directory (dir #%lu) - no data block",
-			      inode->i_ino);
-		return 1;
-	}
-	de = (struct ext2_dir_entry_2 *) bh->b_data;
-	de1 = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
-	if (le32_to_cpu(de->inode) != inode->i_ino || !le32_to_cpu(de1->inode) || 
-	    strcmp (".", de->name) || strcmp ("..", de1->name)) {
-	    	ext2_warning (inode->i_sb, "empty_dir",
-			      "bad directory (dir #%lu) - no `.' or `..'",
-			      inode->i_ino);
-		brelse (bh);
-		return 1;
-	}
-	offset = le16_to_cpu(de->rec_len) + le16_to_cpu(de1->rec_len);
-	de = (struct ext2_dir_entry_2 *) ((char *) de1 + le16_to_cpu(de1->rec_len));
-	while (offset < inode->i_size ) {
-		if (!bh || (void *) de >= (void *) (bh->b_data + sb->s_blocksize)) {
-			brelse (bh);
-			bh = ext2_bread (inode, offset >> EXT2_BLOCK_SIZE_BITS(sb), 0, &err);
-			if (!bh) {
-#if 0
-				ext2_error (sb, "empty_dir",
-					    "directory #%lu contains a hole at offset %lu",
-					    inode->i_ino, offset);
-#endif
-				offset += sb->s_blocksize;
-				continue;
-			}
-			de = (struct ext2_dir_entry_2 *) bh->b_data;
-		}
-		if (!ext2_check_dir_entry ("empty_dir", inode, de, bh,
-					   offset)) {
-			brelse (bh);
-			return 1;
-		}
-		if (le32_to_cpu(de->inode)) {
-			brelse (bh);
-			return 0;
-		}
-		offset += le16_to_cpu(de->rec_len);
-		de = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
-	}
-	brelse (bh);
-	return 1;
+out_fail:
+	ext2_dec_count(inode);
+	iput (inode);
+	goto out;
 }
 
-static int ext2_rmdir (struct inode * dir, struct dentry *dentry)
+static int ext2_link (struct dentry * old_dentry, struct inode * dir,
+	struct dentry *dentry)
 {
-	int retval;
-	struct inode * inode;
-	struct buffer_head * bh;
-	struct ext2_dir_entry_2 * de;
+	struct inode *inode = old_dentry->d_inode;
 
-	retval = -ENOENT;
-	bh = ext2_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de);
-	if (!bh)
-		goto end_rmdir;
-
-	inode = dentry->d_inode;
-	DQUOT_INIT(inode);
-
-	retval = -EIO;
-	if (le32_to_cpu(de->inode) != inode->i_ino)
-		goto end_rmdir;
-
-	retval = -ENOTEMPTY;
-	if (!empty_dir (inode))
-		goto end_rmdir;
-
-	retval = ext2_delete_entry(dir, de, bh);
-	if (retval)
-		goto end_rmdir;
-	if (inode->i_nlink != 2)
-		ext2_warning (inode->i_sb, "ext2_rmdir",
-			      "empty directory has nlink!=2 (%d)",
-			      inode->i_nlink);
-	inode->i_version = ++event;
-	inode->i_nlink = 0;
-	inode->i_size = 0;
-	mark_inode_dirty(inode);
-	dir->i_nlink--;
-	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-	dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
-	mark_inode_dirty(dir);
-
-end_rmdir:
-	brelse (bh);
-	return retval;
-}
+	if (S_ISDIR(inode->i_mode))
+		return -EPERM;
 
-static int ext2_unlink(struct inode * dir, struct dentry *dentry)
-{
-	int retval;
-	struct inode * inode;
-	struct buffer_head * bh;
-	struct ext2_dir_entry_2 * de;
+	if (inode->i_nlink >= EXT2_LINK_MAX)
+		return -EMLINK;
 
-	retval = -ENOENT;
-	bh = ext2_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de);
-	if (!bh)
-		goto end_unlink;
-
-	inode = dentry->d_inode;
-	DQUOT_INIT(inode);
-
-	retval = -EIO;
-	if (le32_to_cpu(de->inode) != inode->i_ino)
-		goto end_unlink;
-	
-	if (!inode->i_nlink) {
-		ext2_warning (inode->i_sb, "ext2_unlink",
-			      "Deleting nonexistent file (%lu), %d",
-			      inode->i_ino, inode->i_nlink);
-		inode->i_nlink = 1;
-	}
-	retval = ext2_delete_entry(dir, de, bh);
-	if (retval)
-		goto end_unlink;
-	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-	dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
-	mark_inode_dirty(dir);
-	inode->i_nlink--;
-	mark_inode_dirty(inode);
-	inode->i_ctime = dir->i_ctime;
-	retval = 0;
+	inode->i_ctime = CURRENT_TIME;
+	ext2_inc_count(inode);
+	atomic_inc(&inode->i_count);
 
-end_unlink:
-	brelse (bh);
-	return retval;
+	return ext2_add_nondir(dentry, inode);
 }
 
-static int ext2_symlink (struct inode * dir, struct dentry *dentry, const char * symname)
+static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
 {
 	struct inode * inode;
-	int l, err;
+	int err = -EMLINK;
 
-	l = strlen(symname)+1;
-	if (l > dir->i_sb->s_blocksize)
-		return -ENAMETOOLONG;
+	if (dir->i_nlink >= EXT2_LINK_MAX)
+		goto out;
+
+	ext2_inc_count(dir);
 
-	inode = ext2_new_inode (dir, S_IFLNK);
+	inode = ext2_new_inode (dir, S_IFDIR | mode);
 	err = PTR_ERR(inode);
 	if (IS_ERR(inode))
-		return err;
+		goto out_dir;
 
-	inode->i_mode = S_IFLNK | S_IRWXUGO;
+	inode->i_op = &ext2_dir_inode_operations;
+	inode->i_fop = &ext2_dir_operations;
+	inode->i_mapping->a_ops = &ext2_aops;
 
-	if (l > sizeof (inode->u.ext2_i.i_data)) {
-		inode->i_op = &page_symlink_inode_operations;
-		inode->i_mapping->a_ops = &ext2_aops;
-		err = block_symlink(inode, symname, l);
-		if (err)
-			goto out_no_entry;
-	} else {
-		inode->i_op = &ext2_fast_symlink_inode_operations;
-		memcpy((char*)&inode->u.ext2_i.i_data,symname,l);
-		inode->i_size = l-1;
-	}
-	mark_inode_dirty(inode);
+	ext2_inc_count(inode);
 
-	err = ext2_add_entry (dir, dentry->d_name.name, dentry->d_name.len, 
-			     inode);
+	err = ext2_make_empty(inode, dir);
 	if (err)
-		goto out_no_entry;
-	d_instantiate(dentry, inode);
-	return 0;
+		goto out_fail;
 
-out_no_entry:
-	inode->i_nlink--;
-	mark_inode_dirty(inode);
-	iput (inode);
+	err = ext2_add_link(dentry, inode);
+	if (err)
+		goto out_fail;
+
+	d_instantiate(dentry, inode);
+out:
 	return err;
+
+out_fail:
+	ext2_dec_count(inode);
+	ext2_dec_count(inode);
+	iput(inode);
+out_dir:
+	ext2_dec_count(dir);
+	goto out;
 }
 
-static int ext2_link (struct dentry * old_dentry,
-		struct inode * dir, struct dentry *dentry)
+static int ext2_unlink(struct inode * dir, struct dentry *dentry)
 {
-	struct inode *inode = old_dentry->d_inode;
-	int err;
+	struct inode * inode = dentry->d_inode;
+	struct ext2_dir_entry_2 * de;
+	struct page * page;
+	int err = -ENOENT;
 
-	if (S_ISDIR(inode->i_mode))
-		return -EPERM;
+	de = ext2_find_entry (dir, dentry, &page);
+	if (!de)
+		goto out;
 
-	if (inode->i_nlink >= EXT2_LINK_MAX)
-		return -EMLINK;
-	
-	err = ext2_add_entry (dir, dentry->d_name.name, dentry->d_name.len, 
-			     inode);
+	err = ext2_delete_entry (de, page);
 	if (err)
-		return err;
+		goto out;
 
-	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;
+	ext2_dec_count(inode);
+	err = 0;
+out:
+	return err;
 }
 
-#define PARENT_INO(buffer) \
-	((struct ext2_dir_entry_2 *) ((char *) buffer + \
-	le16_to_cpu(((struct ext2_dir_entry_2 *) buffer)->rec_len)))->inode
-
-/*
- * Anybody can rename anything with this: the permission checks are left to the
- * higher-level routines.
- */
-static int ext2_rename (struct inode * old_dir, struct dentry *old_dentry,
-			   struct inode * new_dir,struct dentry *new_dentry)
+static int ext2_rmdir (struct inode * dir, struct dentry *dentry)
 {
-	struct inode * old_inode, * new_inode;
-	struct buffer_head * old_bh, * new_bh, * dir_bh;
-	struct ext2_dir_entry_2 * old_de, * new_de;
-	int retval;
-
-	old_bh = new_bh = dir_bh = NULL;
-
-	old_bh = ext2_find_entry (old_dir, old_dentry->d_name.name, old_dentry->d_name.len, &old_de);
-	/*
-	 *  Check for inode number is _not_ due to possible IO errors.
-	 *  We might rmdir the source, keep it as pwd of some process
-	 *  and merrily kill the link to whatever was created under the
-	 *  same name. Goodbye sticky bit ;-<
-	 */
-	old_inode = old_dentry->d_inode;
-	retval = -ENOENT;
-	if (!old_bh || le32_to_cpu(old_de->inode) != old_inode->i_ino)
-		goto end_rename;
-
-	new_inode = new_dentry->d_inode;
-	new_bh = ext2_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;
-		} else {
-			DQUOT_INIT(new_inode);
+	struct inode * inode = dentry->d_inode;
+	int err = -ENOTEMPTY;
+
+	if (ext2_empty_dir(inode)) {
+		err = ext2_unlink(dir, dentry);
+		if (!err) {
+			inode->i_size = 0;
+			ext2_dec_count(inode);
+			ext2_dec_count(dir);
 		}
 	}
+	return err;
+}
+
+static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
+	struct inode * new_dir,	struct dentry * new_dentry )
+{
+	struct inode * old_inode = old_dentry->d_inode;
+	struct inode * new_inode = new_dentry->d_inode;
+	struct page * dir_page = NULL;
+	struct ext2_dir_entry_2 * dir_de = NULL;
+	struct page * old_page;
+	struct ext2_dir_entry_2 * old_de;
+	int err = -ENOENT;
+
+	old_de = ext2_find_entry (old_dir, 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 = ext2_bread (old_inode, 0, 0, &retval);
-		if (!dir_bh)
-			goto end_rename;
-		if (le32_to_cpu(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 >= EXT2_LINK_MAX)
-			goto end_rename;
+		err = -EIO;
+		dir_de = ext2_dotdot(old_inode, &dir_page);
+		if (!dir_de)
+			goto out_old;
 	}
-	if (!new_bh) {
-		retval = ext2_add_entry (new_dir, new_dentry->d_name.name,
-					 new_dentry->d_name.len,
-					 old_inode);
-		if (retval)
-			goto end_rename;
-	} else {
-		new_de->inode = le32_to_cpu(old_inode->i_ino);
-		if (EXT2_HAS_INCOMPAT_FEATURE(new_dir->i_sb,
-					      EXT2_FEATURE_INCOMPAT_FILETYPE))
-			new_de->file_type = old_de->file_type;
-		new_dir->i_version = ++event;
-		mark_buffer_dirty_inode(new_bh, new_dir);
-		if (IS_SYNC(new_dir)) {
-			ll_rw_block (WRITE, 1, &new_bh);
-			wait_on_buffer (new_bh);
-		}
-		brelse(new_bh);
-		new_bh = NULL;
-	}
-	
-	/*
-	 * Like most other Unix systems, set the ctime for inodes on a
-	 * rename.
-	 */
-	old_inode->i_ctime = CURRENT_TIME;
-	mark_inode_dirty(old_inode);
-
-	/*
-	 * ok, that's it
-	 */
-	ext2_delete_entry(old_dir, old_de, old_bh);
 
 	if (new_inode) {
-		new_inode->i_nlink--;
+		struct page *new_page;
+		struct ext2_dir_entry_2 *new_de;
+
+		err = -ENOTEMPTY;
+		if (dir_de && !ext2_empty_dir (new_inode))
+			goto out_dir;
+
+		err = -ENOENT;
+		new_de = ext2_find_entry (new_dir, new_dentry, &new_page);
+		if (!new_de)
+			goto out_dir;
+		ext2_inc_count(old_inode);
+		ext2_set_link(new_dir, new_de, new_page, old_inode);
 		new_inode->i_ctime = CURRENT_TIME;
-		mark_inode_dirty(new_inode);
-	}
-	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
-	old_dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
-	mark_inode_dirty(old_dir);
-	if (dir_bh) {
-		PARENT_INO(dir_bh->b_data) = le32_to_cpu(new_dir->i_ino);
-		mark_buffer_dirty_inode(dir_bh, old_inode);
-		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++;
-			new_dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
-			mark_inode_dirty(new_dir);
-		}
+		ext2_dec_count(new_inode);
+	} else {
+		if (dir_de) {
+			err = -EMLINK;
+			if (new_dir->i_nlink >= EXT2_LINK_MAX)
+				goto out_dir;
+		}
+		ext2_inc_count(old_inode);
+		err = ext2_add_link(new_dentry, old_inode);
+		if (err) {
+			ext2_dec_count(old_inode);
+			goto out_dir;
+		}
+		if (dir_de)
+			ext2_inc_count(new_dir);
+	}
+
+	ext2_delete_entry (old_de, old_page);
+	ext2_dec_count(old_inode);
+
+	if (dir_de) {
+		ext2_set_link(old_inode, dir_de, dir_page, new_dir);
+		ext2_dec_count(old_dir);
 	}
+	return 0;
 
-	retval = 0;
 
-end_rename:
-	brelse (dir_bh);
-	brelse (old_bh);
-	brelse (new_bh);
-	return retval;
+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;
 }
 
-/*
- * directories can handle most operations...
- */
 struct inode_operations ext2_dir_inode_operations = {
 	create:		ext2_create,
 	lookup:		ext2_lookup,
diff -u --recursive --new-file v2.4.5/linux/fs/fat/inode.c linux/fs/fat/inode.c
--- v2.4.5/linux/fs/fat/inode.c	Thu May 24 15:36:34 2001
+++ linux/fs/fat/inode.c	Mon Jun 11 19:15:27 2001
@@ -28,6 +28,7 @@
 #include <linux/locks.h>
 #include <linux/fat_cvf.h>
 #include <linux/slab.h>
+#include <linux/bitops.h>
 #include <linux/smp_lock.h>
 
 #include "msbuffer.h"
diff -u --recursive --new-file v2.4.5/linux/fs/freevxfs/vxfs_bmap.c linux/fs/freevxfs/vxfs_bmap.c
--- v2.4.5/linux/fs/freevxfs/vxfs_bmap.c	Thu May 24 15:00:59 2001
+++ linux/fs/freevxfs/vxfs_bmap.c	Wed Jun 27 17:10:55 2001
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  */
 
-#ident "$Id: vxfs_bmap.c,v 1.20 2001/04/25 18:11:23 hch Exp hch $"
+#ident "$Id: vxfs_bmap.c,v 1.22 2001/05/26 22:41:23 hch Exp hch $"
 
 /*
  * Veritas filesystem driver - filesystem to disk block mapping.
@@ -70,7 +70,7 @@
 	struct super_block		*sbp = ip->i_sb;
 	kdev_t				dev = ip->i_dev;
 	u_long				bsize = sbp->s_blocksize;
-	u_long				size = 0;
+	long				size = 0;
 	int				i;
 
 	for (i = 0; i < VXFS_NDADDR; i++) {
@@ -135,7 +135,7 @@
 
 	for (i = 0; i < size * VXFS_TYPED_PER_BLOCK(ip->i_sb); i++) {
 		struct vxfs_typed	*typ;
-		u_int64_t		off;
+		int64_t			off;
 
 		bp = bread(ip->i_dev,
 				indir + (i / VXFS_TYPED_PER_BLOCK(ip->i_sb)),
@@ -166,10 +166,12 @@
 			goto out;
 		case VXFS_TYPED_INDIRECT_DEV4:
 		case VXFS_TYPED_DATA_DEV4: {
-			struct vxfs_typed_dev4	*typ4 = (struct vxfs_typed_dev4 *)typ;
+			struct vxfs_typed_dev4	*typ4 =
+				(struct vxfs_typed_dev4 *)typ;
+
 			printk(KERN_INFO "\n\nTYPED_DEV4 detected!\n");
-			printk(KERN_INFO "block: %Ld\tsize: %Ld\tdev: %d\n",
-			       (long long)typ4->vd4_block, (long long)typ4->vd4_size, typ4->vd4_dev);
+			printk(KERN_INFO "block: %Lu\tsize: %Ld\tdev: %d\n",
+				typ4->vd4_block, typ4->vd4_size, typ4->vd4_dev);
 			goto fail;
 		}
 		default:
@@ -205,7 +207,7 @@
 
 	for (i = 0; i < VXFS_NTYPED; i++) {
 		struct vxfs_typed	*typ = vip->vii_org.typed + i;
-		u_int64_t		off = (typ->vt_hdr & VXFS_TYPED_OFFSETMASK);
+		int64_t			off = (typ->vt_hdr & VXFS_TYPED_OFFSETMASK);
 
 #ifdef DIAGNOSTIC
 		vxfs_typdump(typ);
@@ -225,10 +227,12 @@
 			break;
 		case VXFS_TYPED_INDIRECT_DEV4:
 		case VXFS_TYPED_DATA_DEV4: {
-			struct vxfs_typed_dev4	*typ4 = (struct vxfs_typed_dev4 *)typ;
+			struct vxfs_typed_dev4	*typ4 =
+				(struct vxfs_typed_dev4 *)typ;
+
 			printk(KERN_INFO "\n\nTYPED_DEV4 detected!\n");
-			printk(KERN_INFO "block: %Ld\tsize: %Ld\tdev: %d\n",
-			       (long long)typ4->vd4_block, (long long)typ4->vd4_size, typ4->vd4_dev);
+			printk(KERN_INFO "block: %Lu\tsize: %Ld\tdev: %d\n",
+				typ4->vd4_block, typ4->vd4_size, typ4->vd4_dev);
 			return 0;
 		}
 		default:
diff -u --recursive --new-file v2.4.5/linux/fs/freevxfs/vxfs_fshead.h linux/fs/freevxfs/vxfs_fshead.h
--- v2.4.5/linux/fs/freevxfs/vxfs_fshead.h	Mon May 21 12:31:06 2001
+++ linux/fs/freevxfs/vxfs_fshead.h	Wed Jun 27 17:10:55 2001
@@ -30,7 +30,7 @@
 #ifndef _VXFS_FSHEAD_H_
 #define _VXFS_FSHEAD_H_
 
-#ident "$Id: vxfs_fshead.h,v 1.6 2001/04/25 18:11:23 hch Exp hch $"
+#ident "$Id: vxfs_fshead.h,v 1.7 2001/05/23 17:27:39 hch Exp hch $"
 
 /*
  * Veritas filesystem driver - fileset header structures.
@@ -61,8 +61,8 @@
 
 	/*
 	 * Slightly more fields follow, but they
-	 *  a) are not of any interested for us, and
-	 *  b) differ much in different vxfs versions/ports
+	 *  a) are not of any interest for us, and
+	 *  b) differ a lot in different vxfs versions/ports
 	 */
 };
 
diff -u --recursive --new-file v2.4.5/linux/fs/freevxfs/vxfs_inode.c linux/fs/freevxfs/vxfs_inode.c
--- v2.4.5/linux/fs/freevxfs/vxfs_inode.c	Mon May 21 12:31:06 2001
+++ linux/fs/freevxfs/vxfs_inode.c	Wed Jun 27 17:10:55 2001
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  */
 
-#ident "$Id: vxfs_inode.c,v 1.34 2001/05/21 15:33:08 hch Exp hch $"
+#ident "$Id: vxfs_inode.c,v 1.36 2001/05/26 22:28:02 hch Exp hch $"
 
 /*
  * Veritas filesystem driver - inode routines.
@@ -47,6 +47,7 @@
 extern struct inode_operations vxfs_immed_symlink_iops;
 
 static struct file_operations vxfs_file_operations = {
+	.llseek =		generic_file_llseek,
 	.read =			generic_file_read,
 	.mmap =			generic_file_mmap,
 };
@@ -91,7 +92,7 @@
  *  Returns the matching VxFS inode on success, else a NULL pointer.
  *
  * NOTE:
- *  While __vxfs_iget uses that pagecache this function uses the
+ *  While __vxfs_iget uses the pagecache vxfs_blkiget uses the
  *  buffercache.  This function should not be used outside the
  *  read_super() method, othwerwise the data may be incoherent.
  */
@@ -138,7 +139,7 @@
  *  Returns the matching VxFS inode on success, else a NULL pointer.
  */
 static struct vxfs_inode_info *
-__vxfs_iget(struct super_block *sbp, ino_t ino, struct inode *ilistp)
+__vxfs_iget(ino_t ino, struct inode *ilistp)
 {
 	struct page			*pp;
 	u_long				offset;
@@ -184,7 +185,7 @@
 struct vxfs_inode_info *
 vxfs_stiget(struct super_block *sbp, ino_t ino)
 {
-        return __vxfs_iget(sbp, ino, VXFS_SBI(sbp)->vsi_stilist);
+        return __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_stilist);
 }
 
 /**
@@ -288,7 +289,7 @@
 	struct address_space_operations	*aops;
 	ino_t				ino = ip->i_ino;
 
-	if (!(vip = __vxfs_iget(sbp, ino, VXFS_SBI(sbp)->vsi_ilist)))
+	if (!(vip = __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_ilist)))
 		return;
 
 	vxfs_iinit(ip, vip);
diff -u --recursive --new-file v2.4.5/linux/fs/freevxfs/vxfs_inode.h linux/fs/freevxfs/vxfs_inode.h
--- v2.4.5/linux/fs/freevxfs/vxfs_inode.h	Mon May 21 12:31:06 2001
+++ linux/fs/freevxfs/vxfs_inode.h	Wed Jun 27 17:10:55 2001
@@ -30,7 +30,7 @@
 #ifndef _VXFS_INODE_H_
 #define _VXFS_INODE_H_
 
-#ident "$Id: vxfs_inode.h,v 1.14 2001/04/25 18:11:23 hch Exp hch $"
+#ident "$Id: vxfs_inode.h,v 1.15 2001/05/26 22:41:23 hch Exp hch $"
 
 /*
  * Veritas filesystem driver - inode structure.
@@ -77,7 +77,7 @@
 	vx_daddr_t		ve4_indir[VXFS_NIADDR];	/* Indirect extents */
 	struct direct {					/* Direct extents */
 		vx_daddr_t	extent;			/* Extent number */
-		u_int32_t	size;			/* Size of extent */
+		int32_t		size;			/* Size of extent */
 	} ve4_direct[VXFS_NDADDR];
 };
 
diff -u --recursive --new-file v2.4.5/linux/fs/freevxfs/vxfs_lookup.c linux/fs/freevxfs/vxfs_lookup.c
--- v2.4.5/linux/fs/freevxfs/vxfs_lookup.c	Mon May 21 12:31:06 2001
+++ linux/fs/freevxfs/vxfs_lookup.c	Wed Jun 27 17:10:55 2001
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  */
 
-#ident "$Id: vxfs_lookup.c,v 1.17 2001/05/21 15:23:53 hch Exp hch $"
+#ident "$Id: vxfs_lookup.c,v 1.19 2001/05/30 19:50:20 hch Exp hch $"
 
 /*
  * Veritas filesystem driver - lookup and other directory related code.
@@ -240,9 +240,8 @@
 	struct inode		*ip = fp->f_dentry->d_inode;
 	struct super_block	*sbp = ip->i_sb;
 	u_long			bsize = sbp->s_blocksize;
-	u_long			page, npages, block, nblocks, offset;
+	u_long			page, npages, block, pblocks, nblocks, offset;
 	loff_t			pos;
-	int			pblocks;
 
 	switch ((long)fp->f_pos) {
 	case 0:
@@ -262,14 +261,14 @@
 	if (pos > VXFS_DIRROUND(ip->i_size))
 		return 0;
 
-	page = pos >> PAGE_CACHE_SHIFT;
-	offset = pos & ~PAGE_CACHE_MASK;
-	block = pos >> sbp->s_blocksize_bits;
-
 	npages = dir_pages(ip);
 	nblocks = dir_blocks(ip);
 	pblocks = VXFS_BLOCK_PER_PAGE(sbp);
 
+	page = pos >> PAGE_CACHE_SHIFT;
+	offset = pos & ~PAGE_CACHE_MASK;
+	block = (u_long)(pos >> sbp->s_blocksize_bits) % pblocks;
+
 	for (; page < npages; page++, block = 0) {
 		caddr_t			kaddr;
 		struct page		*pp;
@@ -310,6 +309,7 @@
 					goto done;
 				}
 			}
+			offset = 0;
 		}
 		vxfs_put_page(pp);
 		offset = 0;
diff -u --recursive --new-file v2.4.5/linux/fs/freevxfs/vxfs_super.c linux/fs/freevxfs/vxfs_super.c
--- v2.4.5/linux/fs/freevxfs/vxfs_super.c	Mon May 21 12:31:06 2001
+++ linux/fs/freevxfs/vxfs_super.c	Wed Jun 27 17:10:55 2001
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  */
 
-#ident "$Id: vxfs_super.c,v 1.24 2001/05/20 15:21:14 hch Exp hch $"
+#ident "$Id: vxfs_super.c,v 1.25 2001/05/25 18:25:55 hch Exp hch $"
 
 /*
  * Veritas filesystem driver - superblock related routines.
@@ -168,18 +168,18 @@
 	bp = bread(dev, 1, bsize);
 	if (!bp) {
 		printk(KERN_WARNING "vxfs: unable to read disk superblock\n");
-		return NULL;
+		goto out;
 	}
 
 	rsbp = (struct vxfs_sb *)bp->b_data;
 	if (rsbp->vs_magic != VXFS_SUPER_MAGIC) {
 		printk(KERN_NOTICE "vxfs: WRONG superblock magic\n");
-		return NULL;
+		goto out;
 	}
 
 	if (rsbp->vs_version < 2 || rsbp->vs_version > 4) {
 		printk(KERN_NOTICE "vxfs: unsupported VxFS version (%d)\n", rsbp->vs_version);
-		return NULL;
+		goto out;
 	}
 
 #ifdef DIAGNOSTIC
@@ -210,12 +210,12 @@
 	default:
 		printk(KERN_WARNING "vxfs: unsupported blocksise: %d\n",
 				rsbp->vs_bsize);
-		return NULL;
+		goto out;
 	}
 
 	if (vxfs_read_olt(sbp, bsize)) {
 		printk(KERN_WARNING "vxfs: unable to read olt\n");
-		return NULL;
+		goto out;
 	}
 
 	if (vxfs_read_fshead(sbp)) {
@@ -228,6 +228,8 @@
 		return (sbp);
 	
 	printk(KERN_WARNING "vxfs: unable to get root dentry.\n");
+out:
+	kfree(infp);
 	return NULL;
 }
 
diff -u --recursive --new-file v2.4.5/linux/fs/hpfs/anode.c linux/fs/hpfs/anode.c
--- v2.4.5/linux/fs/hpfs/anode.c	Tue Sep  5 14:07:29 2000
+++ linux/fs/hpfs/anode.c	Mon Jun 11 19:15:27 2001
@@ -161,6 +161,7 @@
 	if ((a == node && fnod) || na == -1) return se;
 	c2 = 0;
 	while (up != -1) {
+		struct anode *new_anode;
 		if (s->s_hpfs_chk)
 			if (hpfs_stop_cycles(s, up, &c1, &c2, "hpfs_add_sector_to_btree #2")) return -1;
 		if (up != node || !fnod) {
@@ -194,7 +195,8 @@
 		mark_buffer_dirty(bh);
 		brelse(bh);
 		a = na;
-		if ((anode = hpfs_alloc_anode(s, a, &na, &bh))) {
+		if ((new_anode = hpfs_alloc_anode(s, a, &na, &bh))) {
+			anode = new_anode;
 			/*anode->up = up != -1 ? up : ra;*/
 			anode->btree.internal = 1;
 			anode->btree.n_used_nodes = 1;
@@ -282,7 +284,7 @@
 		if (s->s_hpfs_chk)
 			if (hpfs_stop_cycles(s, ano, &d1, &d2, "hpfs_remove_btree #1"))
 				return;
-		anode = hpfs_map_anode(s, ano, &bh);
+		if (!(anode = hpfs_map_anode(s, ano, &bh))) return;
 		btree1 = &anode->btree;
 		level++;
 		pos = 0;
@@ -291,14 +293,14 @@
 		hpfs_free_sectors(s, btree1->u.external[i].disk_secno, btree1->u.external[i].length);
 	go_up:
 	if (!level) return;
+	brelse(bh);
 	if (s->s_hpfs_chk)
 		if (hpfs_stop_cycles(s, ano, &c1, &c2, "hpfs_remove_btree #2")) return;
-	brelse(bh);
 	hpfs_free_sectors(s, ano, 1);
 	oano = ano;
 	ano = anode->up;
 	if (--level) {
-		anode = hpfs_map_anode(s, ano, &bh);
+		if (!(anode = hpfs_map_anode(s, ano, &bh))) return;
 		btree1 = &anode->btree;
 	} else btree1 = btree;
 	for (i = 0; i < btree1->n_used_nodes; i++) {
diff -u --recursive --new-file v2.4.5/linux/fs/hpfs/dir.c linux/fs/hpfs/dir.c
--- v2.4.5/linux/fs/hpfs/dir.c	Fri Aug 11 14:29:01 2000
+++ linux/fs/hpfs/dir.c	Mon Jun 11 19:15:27 2001
@@ -212,7 +212,7 @@
 	hpfs_lock_iget(dir->i_sb, de->directory || (de->ea_size && dir->i_sb->s_hpfs_eas) ? 1 : 2);
 	if (!(result = iget(dir->i_sb, ino))) {
 		hpfs_unlock_iget(dir->i_sb);
-		hpfs_error(result->i_sb, "hpfs_lookup: can't get inode");
+		hpfs_error(dir->i_sb, "hpfs_lookup: can't get inode");
 		goto bail1;
 	}
 	if (!de->directory) result->i_hpfs_parent_dir = dir->i_ino;
diff -u --recursive --new-file v2.4.5/linux/fs/hpfs/super.c linux/fs/hpfs/super.c
--- v2.4.5/linux/fs/hpfs/super.c	Tue Apr 17 23:16:39 2001
+++ linux/fs/hpfs/super.c	Mon Jun 11 19:15:27 2001
@@ -212,6 +212,8 @@
 				return 0;
 		}
 		else if (!strcmp(p, "case")) {
+			if (!rhs || !*rhs)
+				return 0;
 			if (!strcmp(rhs, "lower"))
 				*lowercase = 1;
 			else if (!strcmp(rhs, "asis"))
@@ -220,6 +222,8 @@
 				return 0;
 		}
 		else if (!strcmp(p, "conv")) {
+			if (!rhs || !*rhs)
+				return 0;
 			if (!strcmp(rhs, "binary"))
 				*conv = CONV_BINARY;
 			else if (!strcmp(rhs, "text"))
@@ -230,6 +234,8 @@
 				return 0;
 		}
 		else if (!strcmp(p, "check")) {
+			if (!rhs || !*rhs)
+				return 0;
 			if (!strcmp(rhs, "none"))
 				*chk = 0;
 			else if (!strcmp(rhs, "normal"))
@@ -240,6 +246,8 @@
 				return 0;
 		}
 		else if (!strcmp(p, "errors")) {
+			if (!rhs || !*rhs)
+				return 0;
 			if (!strcmp(rhs, "continue"))
 				*errs = 0;
 			else if (!strcmp(rhs, "remount-ro"))
@@ -250,6 +258,8 @@
 				return 0;
 		}
 		else if (!strcmp(p, "eas")) {
+			if (!rhs || !*rhs)
+				return 0;
 			if (!strcmp(rhs, "no"))
 				*eas = 0;
 			else if (!strcmp(rhs, "ro"))
@@ -260,6 +270,8 @@
 				return 0;
 		}
 		else if (!strcmp(p, "chkdsk")) {
+			if (!rhs || !*rhs)
+				return 0;
 			if (!strcmp(rhs, "no"))
 				*chkdsk = 0;
 			else if (!strcmp(rhs, "errors"))
diff -u --recursive --new-file v2.4.5/linux/fs/inode.c linux/fs/inode.c
--- v2.4.5/linux/fs/inode.c	Tue May 22 09:35:42 2001
+++ linux/fs/inode.c	Tue Jun 12 11:02:44 2001
@@ -1044,6 +1044,8 @@
 				inode->i_state|=I_FREEING;
 				inodes_stat.nr_inodes--;
 				spin_unlock(&inode_lock);
+				if (inode->i_data.nrpages)
+					truncate_inode_pages(&inode->i_data, 0);
 				clear_inode(inode);
 			}
 		}
@@ -1162,14 +1164,13 @@
 void put_dquot_list(struct list_head *);
 int remove_inode_dquot_ref(struct inode *, short, struct list_head *);
 
-void remove_dquot_ref(kdev_t dev, short type)
+void remove_dquot_ref(struct super_block *sb, short type)
 {
-	struct super_block *sb = get_super(dev);
 	struct inode *inode;
 	struct list_head *act_head;
 	LIST_HEAD(tofree_head);
 
-	if (!sb || !sb->dq_op)
+	if (!sb->dq_op)
 		return;	/* nothing to do */
 
 	/* We have to be protected against other CPUs */
diff -u --recursive --new-file v2.4.5/linux/fs/jffs/inode-v23.c linux/fs/jffs/inode-v23.c
--- v2.4.5/linux/fs/jffs/inode-v23.c	Sun May 20 11:35:00 2001
+++ linux/fs/jffs/inode-v23.c	Wed Jun 27 13:51:50 2001
@@ -16,6 +16,7 @@
  * Ported to Linux 2.3.x and MTD:
  * Copyright (C) 2000  Alexander Larsson (alex@cendio.se), Cendio Systems AB
  *
+ * Copyright 2000, 2001  Red Hat, Inc.
  */
 
 /* inode.c -- Contains the code that is called from the VFS.  */
@@ -1719,9 +1720,6 @@
 static int __init
 init_jffs_fs(void)
 {
-	printk("JFFS version "
-	       JFFS_VERSION_STRING
-	       ", (C) 1999, 2000  Axis Communications AB\n");
 	return register_filesystem(&jffs_fs_type);
 }
 
diff -u --recursive --new-file v2.4.5/linux/fs/lockd/mon.c linux/fs/lockd/mon.c
--- v2.4.5/linux/fs/lockd/mon.c	Mon Oct 16 12:58:51 2000
+++ linux/fs/lockd/mon.c	Mon Jun 11 19:15:27 2001
@@ -146,7 +146,7 @@
 	u32	addr = ntohl(argp->addr);
 
 	dprintk("nsm: xdr_encode_mon(%08x, %d, %d, %d)\n",
-			htonl(argp->addr), htonl(argp->proc),
+			htonl(argp->addr), htonl(argp->prog),
 			htonl(argp->vers), htonl(argp->proc));
 
 	/*
diff -u --recursive --new-file v2.4.5/linux/fs/locks.c linux/fs/locks.c
--- v2.4.5/linux/fs/locks.c	Fri Feb  9 11:29:44 2001
+++ linux/fs/locks.c	Sat Jun 16 10:42:53 2001
@@ -857,7 +857,7 @@
 	new_fl2 = locks_alloc_lock(0);
 	error = -ENOLCK; /* "no luck" */
 	if (!(new_fl && new_fl2))
-		goto out;
+		goto out_nolock;
 
 	lock_kernel();
 	if (caller->fl_type != F_UNLCK) {
@@ -1005,6 +1005,7 @@
 	}
 out:
 	unlock_kernel();
+out_nolock:
 	/*
 	 * Free any unused locks.
 	 */
diff -u --recursive --new-file v2.4.5/linux/fs/minix/itree_common.c linux/fs/minix/itree_common.c
--- v2.4.5/linux/fs/minix/itree_common.c	Sun Apr  8 12:30:59 2001
+++ linux/fs/minix/itree_common.c	Wed Jun 20 11:10:27 2001
@@ -80,13 +80,13 @@
 			break;
 		branch[n].key = cpu_to_block(nr);
 		bh = getblk(inode->i_dev, parent, BLOCK_SIZE);
-		if (!buffer_uptodate(bh))
-			wait_on_buffer(bh);
+		lock_buffer(bh);
 		memset(bh->b_data, 0, BLOCK_SIZE);
 		branch[n].bh = bh;
 		branch[n].p = (block_t*) bh->b_data + offsets[n];
 		*branch[n].p = branch[n].key;
 		mark_buffer_uptodate(bh, 1);
+		unlock_buffer(bh);
 		mark_buffer_dirty(bh);
 		parent = nr;
 	}
diff -u --recursive --new-file v2.4.5/linux/fs/namei.c linux/fs/namei.c
--- v2.4.5/linux/fs/namei.c	Sat May 19 18:02:45 2001
+++ linux/fs/namei.c	Tue Jun 12 11:09:28 2001
@@ -15,21 +15,15 @@
  */
 
 #include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
 #include <linux/quotaops.h>
 #include <linux/pagemap.h>
-#include <linux/dcache.h>
 #include <linux/dnotify.h>
-
-#include <asm/uaccess.h>
-#include <asm/unaligned.h>
-#include <asm/semaphore.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
+#include <linux/smp_lock.h>
 
 #include <asm/namei.h>
+#include <asm/uaccess.h>
 
 #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
 
@@ -351,22 +345,17 @@
 
 static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry)
 {
-	struct list_head *p;
+	struct vfsmount *mounted;
+
 	spin_lock(&dcache_lock);
-	p = (*dentry)->d_vfsmnt.next;
-	while (p != &(*dentry)->d_vfsmnt) {
-		struct vfsmount *tmp;
-		tmp = list_entry(p, struct vfsmount, mnt_clash);
-		if (tmp->mnt_parent == *mnt) {
-			*mnt = mntget(tmp);
-			spin_unlock(&dcache_lock);
-			mntput(tmp->mnt_parent);
-			/* tmp holds the mountpoint, so... */
-			dput(*dentry);
-			*dentry = dget(tmp->mnt_root);
-			return 1;
-		}
-		p = p->next;
+	mounted = lookup_mnt(*mnt, *dentry);
+	if (mounted) {
+		*mnt = mntget(mounted);
+		spin_unlock(&dcache_lock);
+		dput(*dentry);
+		mntput(mounted->mnt_parent);
+		*dentry = dget(mounted->mnt_root);
+		return 1;
 	}
 	spin_unlock(&dcache_lock);
 	return 0;
diff -u --recursive --new-file v2.4.5/linux/fs/nfs/dir.c linux/fs/nfs/dir.c
--- v2.4.5/linux/fs/nfs/dir.c	Sat May 19 18:02:45 2001
+++ linux/fs/nfs/dir.c	Tue Jun 12 11:15:08 2001
@@ -73,7 +73,7 @@
 	struct file	*file;
 	struct page	*page;
 	unsigned long	page_index;
-	unsigned	page_offset;
+	u32		*ptr;
 	u64		target;
 	struct nfs_entry *entry;
 	decode_dirent_t	decode;
@@ -100,18 +100,17 @@
 	struct inode	*inode = file->f_dentry->d_inode;
 	struct rpc_cred	*cred = nfs_file_cred(file);
 	void		*buffer = kmap(page);
-	int		plus = NFS_USE_READDIRPLUS(inode);
 	int		error;
 
 	dfprintk(VFS, "NFS: nfs_readdir_filler() reading cookie %Lu into page %lu.\n", (long long)desc->entry->cookie, page->index);
 
  again:
 	error = NFS_PROTO(inode)->readdir(inode, cred, desc->entry->cookie, buffer,
-					  NFS_SERVER(inode)->dtsize, plus);
+					  NFS_SERVER(inode)->dtsize, desc->plus);
 	/* We requested READDIRPLUS, but the server doesn't grok it */
 	if (desc->plus && error == -ENOTSUPP) {
 		NFS_FLAGS(inode) &= ~NFS_INO_ADVISE_RDPLUS;
-		plus = 0;
+		desc->plus = 0;
 		goto again;
 	}
 	if (error < 0)
@@ -135,6 +134,26 @@
 	return -EIO;
 }
 
+static inline
+int dir_decode(nfs_readdir_descriptor_t *desc)
+{
+	u32	*p = desc->ptr;
+	p = desc->decode(p, desc->entry, desc->plus);
+	if (IS_ERR(p))
+		return PTR_ERR(p);
+	desc->ptr = p;
+	return 0;
+}
+
+static inline
+void dir_page_release(nfs_readdir_descriptor_t *desc)
+{
+	kunmap(desc->page);
+	page_cache_release(desc->page);
+	desc->page = NULL;
+	desc->ptr = NULL;
+}
+
 /*
  * Given a pointer to a buffer that has already been filled by a call
  * to readdir, find the next entry.
@@ -147,18 +166,10 @@
 int find_dirent(nfs_readdir_descriptor_t *desc, struct page *page)
 {
 	struct nfs_entry *entry = desc->entry;
-	char		*start = kmap(page),
-			*p = start;
 	int		loop_count = 0,
-			status = 0;
+			status;
 
-	for(;;) {
-		p = (char *)desc->decode((u32*)p, entry, desc->plus);
-		if (IS_ERR(p)) {
-			status = PTR_ERR(p);
-			break;
-		}
-		desc->page_offset = p - start;
+	while((status = dir_decode(desc)) == 0) {
 		dfprintk(VFS, "NFS: found cookie %Lu\n", (long long)entry->cookie);
 		if (entry->prev_cookie == desc->target)
 			break;
@@ -167,7 +178,6 @@
 			schedule();
 		}
 	}
-	kunmap(page);
 	dfprintk(VFS, "NFS: find_dirent() returns %d\n", status);
 	return status;
 }
@@ -181,17 +191,12 @@
 {
 	struct inode	*inode = desc->file->f_dentry->d_inode;
 	struct page	*page;
-	unsigned long	index = desc->page_index;
 	int		status;
 
 	dfprintk(VFS, "NFS: find_dirent_page() searching directory page %ld\n", desc->page_index);
 
-	if (desc->page) {
-		page_cache_release(desc->page);
-		desc->page = NULL;
-	}
-
-	page = read_cache_page(&inode->i_data, index,
+	desc->plus = NFS_USE_READDIRPLUS(inode);
+	page = read_cache_page(&inode->i_data, desc->page_index,
 			       (filler_t *)nfs_readdir_filler, desc);
 	if (IS_ERR(page)) {
 		status = PTR_ERR(page);
@@ -201,12 +206,11 @@
 		goto read_error;
 
 	/* NOTE: Someone else may have changed the READDIRPLUS flag */
-	desc->plus = NFS_USE_READDIRPLUS(inode);
+	desc->page = page;
+	desc->ptr = kmap(page);
 	status = find_dirent(desc, page);
-	if (status >= 0)
-		desc->page = page;
-	else
-		page_cache_release(page);
+	if (status < 0)
+		dir_page_release(desc);
  out:
 	dfprintk(VFS, "NFS: find_dirent_page() returns %d\n", status);
 	return status;
@@ -224,8 +228,8 @@
 static inline
 int readdir_search_pagecache(nfs_readdir_descriptor_t *desc)
 {
-	int		res = 0;
 	int		loop_count = 0;
+	int		res;
 
 	dfprintk(VFS, "NFS: readdir_search_pagecache() searching for cookie %Lu\n", (long long)desc->target);
 	for (;;) {
@@ -233,7 +237,6 @@
 		if (res != -EAGAIN)
 			break;
 		/* Align to beginning of next page */
-		desc->page_offset = 0;
 		desc->page_index ++;
 		if (loop_count++ > 200) {
 			loop_count = 0;
@@ -253,11 +256,9 @@
 {
 	struct file	*file = desc->file;
 	struct nfs_entry *entry = desc->entry;
-	char		*start = kmap(desc->page),
-			*p = start + desc->page_offset;
 	unsigned long	fileid;
 	int		loop_count = 0,
-			res = 0;
+			res;
 
 	dfprintk(VFS, "NFS: nfs_do_filldir() filling starting @ cookie %Lu\n", (long long)desc->target);
 
@@ -270,23 +271,16 @@
 		if (res < 0)
 			break;
 		file->f_pos = desc->target = entry->cookie;
-		p = (char *)desc->decode((u32 *)p, entry, desc->plus);
-		if (IS_ERR(p)) {
-			if (PTR_ERR(p) == -EAGAIN) {
-				desc->page_offset = 0;
-				desc->page_index ++;
-			}
+		if (dir_decode(desc) != 0) {
+			desc->page_index ++;
 			break;
 		}
-		desc->page_offset = p - start;
 		if (loop_count++ > 200) {
 			loop_count = 0;
 			schedule();
 		}
 	}
-	kunmap(desc->page);
-	page_cache_release(desc->page);
-	desc->page = NULL;
+	dir_page_release(desc);
 
 	dfprintk(VFS, "NFS: nfs_do_filldir() filling ended @ cookie %Lu; returning = %d\n", (long long)desc->target, res);
 	return res;
@@ -312,49 +306,40 @@
 	struct inode	*inode = file->f_dentry->d_inode;
 	struct rpc_cred	*cred = nfs_file_cred(file);
 	struct page	*page = NULL;
-	u32		*p;
-	int		status = -EIO;
+	int		status;
 
 	dfprintk(VFS, "NFS: uncached_readdir() searching for cookie %Lu\n", (long long)desc->target);
-	if (desc->page) {
-		page_cache_release(desc->page);
-		desc->page = NULL;
-	}
 
 	page = alloc_page(GFP_HIGHUSER);
 	if (!page) {
 		status = -ENOMEM;
 		goto out;
 	}
-	p = kmap(page);
-	status = NFS_PROTO(inode)->readdir(inode, cred, desc->target, p,
-					   NFS_SERVER(inode)->dtsize, 0);
-	if (status >= 0) {
-		p = desc->decode(p, desc->entry, 0);
-		if (IS_ERR(p))
-			status = PTR_ERR(p);
-		else
+	desc->page = page;
+	desc->ptr = kmap(page);
+	desc->error = NFS_PROTO(inode)->readdir(inode, cred, desc->target,
+						desc->ptr,
+						NFS_SERVER(inode)->dtsize,
+						desc->plus);
+	if (desc->error >= 0) {
+		if ((status = dir_decode(desc)) == 0)
 			desc->entry->prev_cookie = desc->target;
-	}
-	kunmap(page);
+	} else
+		status = -EIO;
 	if (status < 0)
 		goto out_release;
 
-	desc->page_index = 0;
-	desc->page_offset = 0;
-	desc->page = page;
 	status = nfs_do_filldir(desc, dirent, filldir);
 
 	/* Reset read descriptor so it searches the page cache from
 	 * the start upon the next call to readdir_search_pagecache() */
 	desc->page_index = 0;
-	desc->page_offset = 0;
 	memset(desc->entry, 0, sizeof(*desc->entry));
  out:
 	dfprintk(VFS, "NFS: uncached_readdir() returns %d\n", status);
 	return status;
  out_release:
-	page_cache_release(page);
+	dir_page_release(desc);
 	goto out;
 }
 
@@ -392,16 +377,15 @@
 		res = readdir_search_pagecache(desc);
 		if (res == -EBADCOOKIE) {
 			/* This means either end of directory */
-			if (desc->entry->cookie == desc->target) {
-				res = 0;
-				break;
+			if (desc->entry->cookie != desc->target) {
+				/* Or that the server has 'lost' a cookie */
+				res = uncached_readdir(desc, dirent, filldir);
+				if (res >= 0)
+					continue;
 			}
-			/* Or that the server has 'lost' a cookie */
-			res = uncached_readdir(desc, dirent, filldir);
-			if (res >= 0)
-				continue;
-		}
-		if (res < 0)
+			res = 0;
+			break;
+		} else if (res < 0)
 			break;
 
 		res = nfs_do_filldir(desc, dirent, filldir);
@@ -410,8 +394,6 @@
 			break;
 		}
 	}
-	if (desc->page)
-		page_cache_release(desc->page);
 	if (desc->error < 0)
 		return desc->error;
 	if (res < 0)
@@ -753,6 +735,8 @@
 
 	nfs_zap_caches(dir);
 	error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name);
+	if (!error)
+		dentry->d_inode->i_nlink = 0;
 
 	return error;
 }
@@ -870,6 +854,8 @@
 	error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
 	if (error < 0)
 		goto out;
+	if (inode)
+		inode->i_nlink--;
 
  out_delete:
 	/*
diff -u --recursive --new-file v2.4.5/linux/fs/nfs/inode.c linux/fs/nfs/inode.c
--- v2.4.5/linux/fs/nfs/inode.c	Sat May 19 18:14:38 2001
+++ linux/fs/nfs/inode.c	Wed Jun 27 14:02:29 2001
@@ -100,6 +100,8 @@
 	inode->i_blksize = inode->i_sb->s_blocksize;
 	inode->i_mode = 0;
 	inode->i_rdev = 0;
+	/* We can't support UPDATE_ATIME(), since the server will reset it */
+	inode->i_flags |= S_NOATIME;
 	NFS_FILEID(inode) = 0;
 	NFS_FSID(inode) = 0;
 	NFS_FLAGS(inode) = 0;
@@ -973,12 +975,9 @@
 
 	NFS_CACHE_CTIME(inode) = fattr->ctime;
 	inode->i_ctime = nfs_time_to_secs(fattr->ctime);
-	/* If we've been messing around with atime, don't
-	 * update it. Save the server value in NFS_CACHE_ATIME.
-	 */
+
 	NFS_CACHE_ATIME(inode) = fattr->atime;
-	if (time_before(inode->i_atime, nfs_time_to_secs(fattr->atime)))
-		inode->i_atime = nfs_time_to_secs(fattr->atime);
+	inode->i_atime = nfs_time_to_secs(fattr->atime);
 
 	NFS_CACHE_MTIME(inode) = new_mtime;
 	inode->i_mtime = nfs_time_to_secs(new_mtime);
diff -u --recursive --new-file v2.4.5/linux/fs/nfsd/export.c linux/fs/nfsd/export.c
--- v2.4.5/linux/fs/nfsd/export.c	Fri Feb  9 11:29:44 2001
+++ linux/fs/nfsd/export.c	Tue Jun 12 11:12:47 2001
@@ -213,7 +213,8 @@
 
 	err = -EINVAL;
 	if (!(inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV) ||
-	    inode->i_sb->s_op->read_inode == NULL) {
+	    (inode->i_sb->s_op->read_inode == NULL
+	     && inode->i_sb->s_op->fh_to_dentry == NULL)) {
 		dprintk("exp_export: export of invalid fs type.\n");
 		goto finish;
 	}
diff -u --recursive --new-file v2.4.5/linux/fs/nfsd/nfsfh.c linux/fs/nfsd/nfsfh.c
--- v2.4.5/linux/fs/nfsd/nfsfh.c	Sat May 19 17:47:55 2001
+++ linux/fs/nfsd/nfsfh.c	Tue Jun 12 11:12:47 2001
@@ -134,7 +134,11 @@
 	struct inode *inode;
 	struct list_head *lp;
 	struct dentry *result;
+	if (ino == 0)
+		return ERR_PTR(-ESTALE);
 	inode = iget(sb, ino);
+	if (inode == NULL)
+		return ERR_PTR(-ENOMEM);
 	if (is_bad_inode(inode)
 	    || (generation && inode->i_generation != generation)
 		) {
@@ -169,10 +173,34 @@
 		return ERR_PTR(-ENOMEM);
 	}
 	result->d_flags |= DCACHE_NFSD_DISCONNECTED;
-	d_rehash(result); /* so a dput won't loose it */
 	return result;
 }
 
+static struct dentry *nfsd_get_dentry(struct super_block *sb, __u32 *fh,
+					     int len, int fhtype, int parent)
+{
+	if (sb->s_op->fh_to_dentry)
+		return sb->s_op->fh_to_dentry(sb, fh, len, fhtype, parent);
+	switch (fhtype) {
+	case 1:
+		if (len < 2)
+			break;
+		if (parent)
+			break;
+		return nfsd_iget(sb, fh[0], fh[1]);
+
+	case 2:
+		if (len < 3)
+			break;
+		if (parent)
+			return nfsd_iget(sb,fh[2],0);
+		return nfsd_iget(sb,fh[0],fh[1]);
+	default: break;
+	}
+	return ERR_PTR(-EINVAL);
+}
+
+
 /* this routine links an IS_ROOT dentry into the dcache tree.  It gains "parent"
  * as a parent and "name" as a name
  * It should possibly go in dcache.c
@@ -196,7 +224,7 @@
 	 * make it an IS_ROOT instead
 	 */
 	spin_lock(&dcache_lock);
-	list_del(&tdentry->d_child);
+	list_del_init(&tdentry->d_child);
 	tdentry->d_parent = tdentry;
 	spin_unlock(&dcache_lock);
 	d_rehash(target);
@@ -270,10 +298,10 @@
 		}
 		spin_unlock(&dcache_lock);
 		if (pdentry == NULL) {
-			pdentry = d_alloc_root(igrab(tdentry->d_inode));
+			pdentry = d_alloc_root(tdentry->d_inode);
 			if (pdentry) {
+				igrab(tdentry->d_inode);
 				pdentry->d_flags |= DCACHE_NFSD_DISCONNECTED;
-				d_rehash(pdentry);
 			}
 		}
 		if (pdentry == NULL)
@@ -347,11 +375,10 @@
  * connection if made.
  */
 static struct dentry *
-find_fh_dentry(struct super_block *sb, ino_t ino, int generation, ino_t dirino, int needpath)
+find_fh_dentry(struct super_block *sb, __u32 *datap, int len, int fhtype, int needpath)
 {
 	struct dentry *dentry, *result = NULL;
 	struct dentry *tmp;
-	int  found =0;
 	int err = -ESTALE;
 	/* the sb->s_nfsd_free_path_sem semaphore is needed to make sure that only one unconnected (free)
 	 * dcache path ever exists, as otherwise two partial paths might get
@@ -367,7 +394,7 @@
 	 */
  retry:
 	down(&sb->s_nfsd_free_path_sem);
-	result = nfsd_iget(sb, ino, generation);
+	result = nfsd_get_dentry(sb, datap, len, fhtype, 0);
 	if (IS_ERR(result)
 	    || !(result->d_flags & DCACHE_NFSD_DISCONNECTED)
 	    || (!S_ISDIR(result->d_inode->i_mode) && ! needpath)) {
@@ -384,16 +411,12 @@
 	/* It's a directory, or we are required to confirm the file's
 	 * location in the tree.
 	 */
-	dprintk("nfs_fh: need to look harder for %d/%ld\n",sb->s_dev,ino);
+	dprintk("nfs_fh: need to look harder for %d/%d\n",sb->s_dev,datap[0]);
 
-	found = 0;
 	if (!S_ISDIR(result->d_inode->i_mode)) {
 		nfsdstats.fh_nocache_nondir++;
-		if (dirino == 0)
-			goto err_result; /* don't know how to find parent */
-		else {
 			/* need to iget dirino and make sure this inode is in that directory */
-			dentry = nfsd_iget(sb, dirino, 0);
+			dentry = nfsd_get_dentry(sb, datap, len, fhtype, 1);
 			err = PTR_ERR(dentry);
 			if (IS_ERR(dentry))
 				goto err_result;
@@ -402,8 +425,6 @@
 			    || !S_ISDIR(dentry->d_inode->i_mode)) {
 				goto err_dentry;
 			}
-			if (!(dentry->d_flags & DCACHE_NFSD_DISCONNECTED))
-				found = 1;
 			tmp = splice(result, dentry);
 			err = PTR_ERR(tmp);
 			if (IS_ERR(tmp))
@@ -413,15 +434,13 @@
 				d_drop(result);
 				dput(result);
 				result = tmp;
-				/* If !found, then this is really weird, but it shouldn't hurt */
 			}
-		}
 	} else {
 		nfsdstats.fh_nocache_dir++;
 		dentry = dget(result);
 	}
 
-	while(!found) {
+	while(dentry->d_flags & DCACHE_NFSD_DISCONNECTED) {
 		/* LOOP INVARIANT */
 		/* haven't found a place in the tree yet, but we do have a free path
 		 * from dentry down to result, and dentry is a directory.
@@ -440,12 +459,9 @@
 			goto err_dentry;
 		}
 
-		if (!(dentry->d_flags & DCACHE_NFSD_DISCONNECTED))
-			found = 1;
-
 		tmp = splice(dentry, pdentry);
 		if (tmp != dentry) {
-			/* Something wrong.  We need to drop thw whole dentry->result path
+			/* Something wrong.  We need to drop the whole dentry->result path
 			 * whatever it was
 			 */
 			struct dentry *d;
@@ -580,31 +596,23 @@
 			case 0:
 				dentry = dget(exp->ex_dentry);
 				break;
-			case 1:
-				if ((data_left-=2)<0) goto out;
-				dentry = find_fh_dentry(exp->ex_dentry->d_inode->i_sb,
-							datap[0], datap[1],
-							0,
-							!(exp->ex_flags & NFSEXP_NOSUBTREECHECK));
-				break;
-			case 2:
-				if ((data_left-=3)<0) goto out;
+			default:
 				dentry = find_fh_dentry(exp->ex_dentry->d_inode->i_sb,
-							datap[0], datap[1],
-							datap[2],
+							datap, data_left, fh->fh_fileid_type,
 							!(exp->ex_flags & NFSEXP_NOSUBTREECHECK));
-				break;
-			default: goto out;
 			}
 		} else {
-
+			__u32 tfh[3];
+			tfh[0] = fh->ofh_ino;
+			tfh[1] = fh->ofh_generation;
+			tfh[2] = fh->ofh_dirino;
 			dentry = find_fh_dentry(exp->ex_dentry->d_inode->i_sb,
-						fh->ofh_ino, fh->ofh_generation,
-						fh->ofh_dirino,
+						tfh, 3, fh->ofh_dirino?2:1,
 						!(exp->ex_flags & NFSEXP_NOSUBTREECHECK));
 		}
 		if (IS_ERR(dentry)) {
-			error = nfserrno(PTR_ERR(dentry));
+			if (PTR_ERR(dentry) != EINVAL)
+				error = nfserrno(PTR_ERR(dentry));
 			goto out;
 		}
 #ifdef NFSD_PARANOIA
@@ -709,9 +717,20 @@
 		      __u32 **datapp, int maxsize)
 {
 	__u32 *datap= *datapp;
+	struct super_block *sb = dentry->d_inode->i_sb;
+	
 	if (dentry == exp->ex_dentry)
 		return 0;
-	/* if super_operations provides dentry_to_fh lookup, should use that */
+
+	if (sb->s_op->dentry_to_fh) {
+		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;
+		return type;
+	}
 	
 	*datap++ = ino_t_to_u32(dentry->d_inode->i_ino);
 	*datap++ = dentry->d_inode->i_generation;
diff -u --recursive --new-file v2.4.5/linux/fs/nls/Config.in linux/fs/nls/Config.in
--- v2.4.5/linux/fs/nls/Config.in	Sat May 19 17:47:55 2001
+++ linux/fs/nls/Config.in	Wed Jun 27 17:10:55 2001
@@ -29,7 +29,7 @@
   tristate 'Codepage 852 (Central/Eastern Europe)' CONFIG_NLS_CODEPAGE_852
   tristate 'Codepage 855 (Cyrillic)'               CONFIG_NLS_CODEPAGE_855
   tristate 'Codepage 857 (Turkish)'                CONFIG_NLS_CODEPAGE_857
-  tristate 'Codepage 860 (Portugese)'              CONFIG_NLS_CODEPAGE_860
+  tristate 'Codepage 860 (Portuguese)'             CONFIG_NLS_CODEPAGE_860
   tristate 'Codepage 861 (Icelandic)'              CONFIG_NLS_CODEPAGE_861
   tristate 'Codepage 862 (Hebrew)'                 CONFIG_NLS_CODEPAGE_862
   tristate 'Codepage 863 (Canadian French)'        CONFIG_NLS_CODEPAGE_863
@@ -43,7 +43,7 @@
   tristate 'Korean charset (CP949, EUC-KR)'        CONFIG_NLS_CODEPAGE_949
   tristate 'Thai charset (CP874, TIS-620)'         CONFIG_NLS_CODEPAGE_874
   tristate 'Hebrew charsets (ISO-8859-8, CP1255)'  CONFIG_NLS_ISO8859_8
-  tristate 'Windows CP1251 (Bulgarian, Belarussian)' CONFIG_NLS_CODEPAGE_1251
+  tristate 'Windows CP1251 (Bulgarian, Belarusian)' CONFIG_NLS_CODEPAGE_1251
   tristate 'NLS ISO 8859-1  (Latin 1; Western European Languages)' CONFIG_NLS_ISO8859_1
   tristate 'NLS ISO 8859-2  (Latin 2; Slavic/Central European Languages)' CONFIG_NLS_ISO8859_2
   tristate 'NLS ISO 8859-3  (Latin 3; Esperanto, Galician, Maltese, Turkish)' CONFIG_NLS_ISO8859_3
@@ -56,7 +56,7 @@
   tristate 'NLS ISO 8859-14 (Latin 8; Celtic)'      CONFIG_NLS_ISO8859_14
   tristate 'NLS ISO 8859-15 (Latin 9; Western European Languages with Euro)' CONFIG_NLS_ISO8859_15
   tristate 'NLS KOI8-R (Russian)'                   CONFIG_NLS_KOI8_R
-  tristate 'NLS KOI8-U/RU (Ukrainian, Belarussian)' CONFIG_NLS_KOI8_U
+  tristate 'NLS KOI8-U/RU (Ukrainian, Belarusian)' CONFIG_NLS_KOI8_U
   tristate 'NLS UTF8'                               CONFIG_NLS_UTF8
   endmenu
 fi
diff -u --recursive --new-file v2.4.5/linux/fs/partitions/check.c linux/fs/partitions/check.c
--- v2.4.5/linux/fs/partitions/check.c	Wed May 16 14:01:32 2001
+++ linux/fs/partitions/check.c	Tue Jun 12 11:17:17 2001
@@ -418,11 +418,10 @@
 		blk_size[dev->major] = NULL;
 
 	dev->part[first_minor].nr_sects = size;
-	/* No Such Agen^Wdevice or no minors to use for partitions */
+	/* No such device or no minors to use for partitions */
 	if (!size || minors == 1)
 		return;
 
-	blk_size[dev->major] = NULL;
 	check_partition(dev, MKDEV(dev->major, first_minor), 1 + first_minor);
 
  	/*
diff -u --recursive --new-file v2.4.5/linux/fs/proc/array.c linux/fs/proc/array.c
--- v2.4.5/linux/fs/proc/array.c	Fri May  4 14:44:06 2001
+++ linux/fs/proc/array.c	Tue Jun 12 17:27:29 2001
@@ -421,13 +421,12 @@
 		++*total;
 		if (!pte_present(page))
 			continue;
+		ptpage = pte_page(page);
+		if ((!VALID_PAGE(ptpage)) || PageReserved(ptpage))
+			continue;
 		++*pages;
 		if (pte_dirty(page))
 			++*dirty;
-		ptpage = pte_page(page);
-		if ((!VALID_PAGE(ptpage)) || 
-					PageReserved(ptpage))
-			continue;
 		if (page_count(pte_page(page)) > 1)
 			++*shared;
 	} while (address < end);
diff -u --recursive --new-file v2.4.5/linux/fs/proc/base.c linux/fs/proc/base.c
--- v2.4.5/linux/fs/proc/base.c	Fri May  4 14:44:06 2001
+++ linux/fs/proc/base.c	Wed Jun 27 17:10:55 2001
@@ -312,6 +312,13 @@
 #define MAY_PTRACE(p) \
 (p==current||(p->p_pptr==current&&(p->ptrace & PT_PTRACED)&&p->state==TASK_STOPPED))
 
+
+static int mem_open(struct inode* inode, struct file* file)
+{
+	file->private_data = (void*)(current->self_exec_id);
+	return 0;
+}
+
 static ssize_t mem_read(struct file * file, char * buf,
 			size_t count, loff_t *ppos)
 {
@@ -319,6 +326,8 @@
 	char *page;
 	unsigned long src = *ppos;
 	int copied = 0;
+	struct mm_struct *mm;
+
 
 	if (!MAY_PTRACE(task))
 		return -ESRCH;
@@ -327,6 +336,18 @@
 	if (!page)
 		return -ENOMEM;
 
+	task_lock(task);
+	mm = task->mm;
+	if (mm)
+		atomic_inc(&mm->mm_users);
+	task_unlock(task);
+
+	if (file->private_data != (void*)(current->self_exec_id) ) {
+		mmput(mm);
+		return -EIO;
+	}
+		
+
 	while (count > 0) {
 		int this_len, retval;
 
@@ -347,6 +368,7 @@
 		count -= retval;
 	}
 	*ppos = src;
+	mmput(mm);
 	free_page((unsigned long) page);
 	return copied;
 }
@@ -398,6 +420,7 @@
 static struct file_operations proc_mem_operations = {
 	read:		mem_read,
 	write:		mem_write,
+	open:		mem_open,
 };
 
 static struct inode_operations proc_mem_inode_operations = {
@@ -635,15 +658,14 @@
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 	inode->i_ino = fake_ino(task->pid, ino);
 
-	inode->u.proc_i.file = NULL;
+	if (!task->pid)
+		goto out_unlock;
+
 	/*
 	 * grab the reference to task.
 	 */
-	inode->u.proc_i.task = task;
 	get_task_struct(task);
-	if (!task->pid)
-		goto out_unlock;
-
+	inode->u.proc_i.task = task;
 	inode->i_uid = 0;
 	inode->i_gid = 0;
 	if (ino == PROC_PID_INO || task->dumpable) {
diff -u --recursive --new-file v2.4.5/linux/fs/proc/generic.c linux/fs/proc/generic.c
--- v2.4.5/linux/fs/proc/generic.c	Fri May 25 17:56:44 2001
+++ linux/fs/proc/generic.c	Wed Jun 27 17:10:55 2001
@@ -192,13 +192,22 @@
 
 static unsigned char proc_alloc_map[PROC_NDYNAMIC / 8];
 
+spinlock_t proc_alloc_map_lock = SPIN_LOCK_UNLOCKED;
+
 static int make_inode_number(void)
 {
-	int i = find_first_zero_bit((void *) proc_alloc_map, PROC_NDYNAMIC);
-	if (i<0 || i>=PROC_NDYNAMIC) 
-		return -1;
+	int i;
+	spin_lock(&proc_alloc_map_lock);
+	i = find_first_zero_bit((void *) proc_alloc_map, PROC_NDYNAMIC);
+	if (i<0 || i>=PROC_NDYNAMIC) {
+		i = -1;
+		goto out;
+	}
 	set_bit(i, (void *) proc_alloc_map);
-	return PROC_DYNAMIC_FIRST + i;
+	i += PROC_DYNAMIC_FIRST;
+out:
+	spin_unlock(&proc_alloc_map_lock);
+	return i;
 }
 
 static int proc_readlink(struct dentry *dentry, char *buffer, int buflen)
diff -u --recursive --new-file v2.4.5/linux/fs/reiserfs/fix_node.c linux/fs/reiserfs/fix_node.c
--- v2.4.5/linux/fs/reiserfs/fix_node.c	Fri Apr 13 20:26:07 2001
+++ linux/fs/reiserfs/fix_node.c	Tue Jun 12 10:44:57 2001
@@ -936,6 +936,7 @@
     if (p_s_tb->FEB[p_s_tb->cur_blknum])
       BUG();
 
+    mark_buffer_journal_new(p_s_new_bh) ;
     p_s_tb->FEB[p_s_tb->cur_blknum++] = p_s_new_bh;
   }
 
@@ -2719,12 +2720,6 @@
 {
     int	i;
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ( ! tb->vn_buf )
-	reiserfs_panic (tb->tb_sb,
-			"PAP-16050: unfix_nodes: pointer to the virtual node is NULL");
-#endif
-
     /* Release path buffers. */
     pathrelse_and_restore (tb->tb_sb, tb->tb_path);
 
@@ -2781,7 +2776,8 @@
 	    }
 	}
 #endif /* 0 */
-    reiserfs_kfree (tb->vn_buf, tb->vn_buf_size, tb->tb_sb);
+    if (tb->vn_buf) 
+	reiserfs_kfree (tb->vn_buf, tb->vn_buf_size, tb->tb_sb);
 
 } 
 
diff -u --recursive --new-file v2.4.5/linux/fs/reiserfs/inode.c linux/fs/reiserfs/inode.c
--- v2.4.5/linux/fs/reiserfs/inode.c	Fri Apr 27 14:18:08 2001
+++ linux/fs/reiserfs/inode.c	Thu Jun 14 14:16:58 2001
@@ -21,6 +21,7 @@
 #define GET_BLOCK_CREATE 1    /* add anything you need to find block */
 #define GET_BLOCK_NO_HOLE 2   /* return -ENOENT for file holes */
 #define GET_BLOCK_READ_DIRECT 4  /* read the tail if indirect item not found */
+#define GET_BLOCK_NO_ISEM     8 /* i_sem is not held, don't preallocate */
 
 //
 // initially this function was derived from minix or ext2's analog and
@@ -539,6 +540,19 @@
     return retval ;
 }
 
+static inline int _allocate_block(struct reiserfs_transaction_handle *th,
+                           struct inode *inode, 
+			   b_blocknr_t *allocated_block_nr, 
+			   unsigned long tag,
+			   int flags) {
+  
+#ifdef REISERFS_PREALLOCATE
+    if (!(flags & GET_BLOCK_NO_ISEM)) {
+        return reiserfs_new_unf_blocknrs2(th, inode, allocated_block_nr, tag);
+    }
+#endif
+    return reiserfs_new_unf_blocknrs (th, allocated_block_nr, tag);
+}
 //
 // initially this function was derived from ext2's analog and evolved
 // as the prototype did.  You'll need to look at the ext2 version to
@@ -632,11 +646,7 @@
 	    goto research ;
 	}
 
-#ifdef REISERFS_PREALLOCATE
-	repeat = reiserfs_new_unf_blocknrs2 (&th, inode, &allocated_block_nr, tag);
-#else
-	repeat = reiserfs_new_unf_blocknrs (&th, &allocated_block_nr, tag);
-#endif
+	repeat = _allocate_block(&th, inode, &allocated_block_nr, tag, create);
 
 	if (repeat == NO_DISK_SPACE) {
 	    /* restart the transaction to give the journal a chance to free
@@ -644,11 +654,7 @@
 	    ** research if we succeed on the second try
 	    */
 	    restart_transaction(&th, inode, &path) ; 
-#ifdef REISERFS_PREALLOCATE
-	    repeat = reiserfs_new_unf_blocknrs2 (&th, inode, &allocated_block_nr, tag);
-#else
-	    repeat = reiserfs_new_unf_blocknrs (&th, &allocated_block_nr, tag);
-#endif
+	    repeat = _allocate_block(&th, inode,&allocated_block_nr,tag,create);
 
 	    if (repeat != NO_DISK_SPACE) {
 		goto research ;
@@ -736,10 +742,6 @@
 	    retval = reiserfs_insert_item (&th, &path, &tmp_key, &tmp_ih, (char *)&unp);
 	    if (retval) {
 		reiserfs_free_block (&th, allocated_block_nr);
-
-#ifdef REISERFS_PREALLOCATE
-		reiserfs_discard_prealloc (&th, inode); 
-#endif
 		goto failure; // retval == -ENOSPC or -EIO or -EEXIST
 	    }
 	    if (unp)
@@ -787,10 +789,6 @@
 	    mark_buffer_uptodate (unbh, 1);
 	    if (retval) {
 		reiserfs_free_block (&th, allocated_block_nr);
-
-#ifdef REISERFS_PREALLOCATE
-		reiserfs_discard_prealloc (&th, inode); 
-#endif
 		goto failure;
 	    }
 	    /* we've converted the tail, so we must 
@@ -832,10 +830,6 @@
 	    retval = reiserfs_paste_into_item (&th, &path, &tmp_key, (char *)&un, UNFM_P_SIZE);
 	    if (retval) {
 		reiserfs_free_block (&th, allocated_block_nr);
-
-#ifdef REISERFS_PREALLOCATE
-		reiserfs_discard_prealloc (&th, inode); 
-#endif
 		goto failure;
 	    }
 	    if (un.unfm_nodenum)
@@ -872,6 +866,8 @@
 	    reiserfs_warning ("vs-: reiserfs_get_block: "
 			      "%k should not be found", &key);
 	    retval = -EEXIST;
+	    if (allocated_block_nr)
+	        reiserfs_free_block (&th, allocated_block_nr);
 	    pathrelse(&path) ;
 	    goto failure;
 	}
@@ -921,6 +917,8 @@
     inode->i_generation = INODE_PKEY (inode)->k_dir_id;
     inode->i_blksize = PAGE_SIZE;
 
+    INIT_LIST_HEAD(&inode->u.reiserfs_i.i_prealloc_list) ;
+
     if (stat_data_v1 (ih)) {
 	struct stat_data_v1 * sd = (struct stat_data_v1 *)B_I_PITEM (bh, ih);
 	unsigned long blocks;
@@ -1163,7 +1161,7 @@
 	return;
     }
     if (retval != ITEM_FOUND) {
-	reiserfs_warning ("vs-13042: reiserfs_read_inode2: %K not found\n", &key);
+	/* a stale NFS handle can trigger this without it being an error */
 	pathrelse (&path_to_sd);
 	make_bad_inode(inode) ;
 	return;
@@ -1185,23 +1183,86 @@
     if (!inode) 
       return inode ;
 
-    if (is_bad_inode (inode)) {
-	reiserfs_warning ("vs-13048: reiserfs_iget: "
-			  "bad_inode. Stat data of (%lu %lu) not found\n",
-			  key->on_disk_key.k_dir_id, key->on_disk_key.k_objectid);
-	iput (inode);
-	inode = 0;
-    } else if (comp_short_keys (INODE_PKEY (inode), key)) {
-	reiserfs_warning ("vs-13049: reiserfs_iget: "
-			  "Looking for (%lu %lu), found inode of (%lu %lu)\n",
-			  key->on_disk_key.k_dir_id, key->on_disk_key.k_objectid,
-			  INODE_PKEY (inode)->k_dir_id, INODE_PKEY (inode)->k_objectid);
+    if (comp_short_keys (INODE_PKEY (inode), key) || is_bad_inode (inode)) {
+	/* either due to i/o error or a stale NFS handle */
 	iput (inode);
 	inode = 0;
     }
     return inode;
 }
 
+struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, __u32 *data,
+                                     int len, int fhtype, int parent) {
+    struct cpu_key key ;
+    struct inode *inode = NULL ;
+    struct list_head *lp;
+    struct dentry *result;
+
+    if (fhtype < 2 || (parent && fhtype < 4)) 
+	goto out ;
+
+    if (! parent) {
+	    /* this works for handles from old kernels because the default
+	    ** reiserfs generation number is the packing locality.
+	    */
+	    key.on_disk_key.k_objectid = data[0] ;
+	    key.on_disk_key.k_dir_id = data[1] ;
+	    inode = reiserfs_iget(sb, &key) ;
+    } else {
+	    key.on_disk_key.k_objectid = data[2] ;
+	    key.on_disk_key.k_dir_id = data[3] ;
+	    inode = reiserfs_iget(sb, &key) ;
+    }
+out:
+    if (!inode)
+        return ERR_PTR(-ESTALE) ;
+
+    /* now to find a dentry.
+     * If possible, get a well-connected one
+     */
+    spin_lock(&dcache_lock);
+    for (lp = inode->i_dentry.next; lp != &inode->i_dentry ; lp=lp->next) {
+	    result = list_entry(lp,struct dentry, d_alias);
+	    if (! (result->d_flags & DCACHE_NFSD_DISCONNECTED)) {
+		    dget_locked(result);
+		    result->d_vfs_flags |= DCACHE_REFERENCED;
+		    spin_unlock(&dcache_lock);
+		    iput(inode);
+		    return result;
+	    }
+    }
+    spin_unlock(&dcache_lock);
+    result = d_alloc_root(inode);
+    if (result == NULL) {
+	    iput(inode);
+	    return ERR_PTR(-ENOMEM);
+    }
+    result->d_flags |= DCACHE_NFSD_DISCONNECTED;
+    return result;
+
+}
+
+int reiserfs_dentry_to_fh(struct dentry *dentry, __u32 *data, int *lenp, int need_parent) {
+    struct inode *inode = dentry->d_inode ;
+    int maxlen = *lenp;
+    
+    if (maxlen < 2)
+        return 255 ;
+
+    data[0] = inode->i_ino ;
+    data[1] = le32_to_cpu(INODE_PKEY (inode)->k_dir_id) ;
+    *lenp = 2;
+    /* no room for directory info? return what we've stored so far */
+    if (maxlen < 4 || ! need_parent)
+        return 2 ;
+
+    inode = dentry->d_parent->d_inode ;
+    data[2] = inode->i_ino ;
+    data[3] = le32_to_cpu(INODE_PKEY (inode)->k_dir_id) ;
+    *lenp = 4;
+    return 4; 
+}
+
 
 //
 // initially this function was derived from minix or ext2's analog and
@@ -1421,6 +1482,8 @@
     inode->u.reiserfs_i.i_first_direct_byte = S_ISLNK(mode) ? 1 : 
       U32_MAX/*NO_BYTES_IN_DIRECT_ITEM*/;
 
+    INIT_LIST_HEAD(&inode->u.reiserfs_i.i_prealloc_list) ;
+
     if (old_format_only (sb))
 	inode2sd_v1 (&sd, inode);
     else
@@ -1723,7 +1786,8 @@
     /* this is where we fill in holes in the file. */
     if (use_get_block) {
         kmap(bh_result->b_page) ;
-	retval = reiserfs_get_block(inode, block, bh_result, 1) ;
+	retval = reiserfs_get_block(inode, block, bh_result, 
+	                            GET_BLOCK_CREATE | GET_BLOCK_NO_ISEM) ;
         kunmap(bh_result->b_page) ;
 	if (!retval) {
 	    if (!buffer_mapped(bh_result) || bh_result->b_blocknr == 0) {
diff -u --recursive --new-file v2.4.5/linux/fs/reiserfs/journal.c linux/fs/reiserfs/journal.c
--- v2.4.5/linux/fs/reiserfs/journal.c	Fri Apr 27 14:18:08 2001
+++ linux/fs/reiserfs/journal.c	Tue Jun 12 10:44:57 2001
@@ -2553,6 +2553,7 @@
   bh = get_hash_table(p_s_sb->s_dev, blocknr, p_s_sb->s_blocksize) ;
   /* if it is journal new, we just remove it from this transaction */
   if (bh && buffer_journal_new(bh)) {
+    mark_buffer_notjournal_new(bh) ;
     clear_prepared_bits(bh) ;
     cleaned = remove_from_transaction(p_s_sb, blocknr, cleaned) ;
   } else {
diff -u --recursive --new-file v2.4.5/linux/fs/reiserfs/stree.c linux/fs/reiserfs/stree.c
--- v2.4.5/linux/fs/reiserfs/stree.c	Fri Apr 13 20:26:07 2001
+++ linux/fs/reiserfs/stree.c	Tue Jun 12 10:44:58 2001
@@ -1724,7 +1724,7 @@
 	    continue;
 
 	reiserfs_warning ("PAP-5610: reiserfs_cut_from_item: item %K not found\n", p_s_item_key);
-	pathrelse (p_s_path);
+	unfix_nodes (&s_cut_balance);
 	return (n_ret_value == IO_ERROR) ? -EIO : -ENOENT;
     } /* while */
   
@@ -1994,12 +1994,14 @@
     while ( (retval = fix_nodes(M_PASTE, &s_paste_balance, NULL, p_c_body)) == REPEAT_SEARCH ) {
 	/* file system changed while we were in the fix_nodes */
 	retval = search_for_position_by_key (th->t_super, p_s_key, p_s_search_path);
-	if (retval == IO_ERROR)
-	    return -EIO;
+	if (retval == IO_ERROR) {
+	    retval = -EIO ;
+	    goto error_out ;
+	}
 	if (retval == POSITION_FOUND) {
 	    reiserfs_warning ("PAP-5710: reiserfs_paste_into_item: entry or pasted byte (%K) exists", p_s_key);
-	    pathrelse (p_s_search_path);
-	    return -EEXIST;
+	    retval = -EEXIST ;
+	    goto error_out ;
 	}
 	
 #ifdef CONFIG_REISERFS_CHECK
@@ -2013,9 +2015,11 @@
 	do_balance(&s_paste_balance, NULL/*ih*/, p_c_body, M_PASTE);
 	return 0;
     }
-
+    retval = (retval == NO_DISK_SPACE) ? -ENOSPC : -EIO;
+error_out:
+    /* this also releases the path */
     unfix_nodes(&s_paste_balance);
-    return (retval == NO_DISK_SPACE) ? -ENOSPC : -EIO;
+    return retval ;
 }
 
 
@@ -2040,14 +2044,15 @@
     while ( (retval = fix_nodes(M_INSERT, &s_ins_balance, p_s_ih, p_c_body)) == REPEAT_SEARCH) {
 	/* file system changed while we were in the fix_nodes */
 	retval = search_item (th->t_super, key, p_s_path);
-	if (retval == IO_ERROR)
-	    return -EIO;
-
+	if (retval == IO_ERROR) {
+	    retval = -EIO;
+	    goto error_out ;
+	}
 	if (retval == ITEM_FOUND) {
 	    reiserfs_warning ("PAP-5760: reiserfs_insert_item: "
 			      "key %K already exists in the tree\n", key);
-	    pathrelse (p_s_path);
-	    return -EEXIST;
+	    retval = -EEXIST ;
+	    goto error_out; 
 	}
     }
 
@@ -2057,8 +2062,11 @@
 	return 0;
     }
 
+    retval = (retval == NO_DISK_SPACE) ? -ENOSPC : -EIO;
+error_out:
+    /* also releases the path */
     unfix_nodes(&s_ins_balance);
-    return (retval == NO_DISK_SPACE) ? -ENOSPC : -EIO;
+    return retval; 
 }
 
 
diff -u --recursive --new-file v2.4.5/linux/fs/reiserfs/super.c linux/fs/reiserfs/super.c
--- v2.4.5/linux/fs/reiserfs/super.c	Fri Apr 27 14:18:08 2001
+++ linux/fs/reiserfs/super.c	Tue Jun 12 11:12:47 2001
@@ -149,6 +149,9 @@
   statfs: reiserfs_statfs,
   remount_fs: reiserfs_remount,
 
+  fh_to_dentry: reiserfs_fh_to_dentry,
+  dentry_to_fh: reiserfs_dentry_to_fh,
+
 };
 
 /* this was (ext2)parse_options */
diff -u --recursive --new-file v2.4.5/linux/fs/select.c linux/fs/select.c
--- v2.4.5/linux/fs/select.c	Wed May 16 10:31:27 2001
+++ linux/fs/select.c	Wed Jun 27 17:10:55 2001
@@ -260,7 +260,7 @@
 	fd_set_bits fds;
 	char *bits;
 	long timeout;
-	int ret, size;
+	int ret, size, max_fdset;
 
 	timeout = MAX_SCHEDULE_TIMEOUT;
 	if (tvp) {
@@ -285,8 +285,10 @@
 	if (n < 0)
 		goto out_nofds;
 
-	if (n > current->files->max_fdset)
-		n = current->files->max_fdset;
+	/* max_fdset can increase, so grab it once to avoid race */
+	max_fdset = current->files->max_fdset;
+	if (n > max_fdset)
+		n = max_fdset;
 
 	/*
 	 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
diff -u --recursive --new-file v2.4.5/linux/fs/smbfs/ChangeLog linux/fs/smbfs/ChangeLog
--- v2.4.5/linux/fs/smbfs/ChangeLog	Tue May 15 13:40:55 2001
+++ linux/fs/smbfs/ChangeLog	Wed Jun 20 16:07:57 2001
@@ -1,5 +1,10 @@
 ChangeLog for smbfs.
 
+2001-06-12 Urban Widmark <urban@teststation.com>
+
+	* proc.c: replace the win95-flush fix with smb_seek, when needed.
+	* proc.c: readdir 'lastname' bug (NetApp dir listing fix)
+
 2001-05-08 Urban Widmark <urban@teststation.com>
 
 	* inode.c: Fix for changes on the server side not being detected
diff -u --recursive --new-file v2.4.5/linux/fs/smbfs/file.c linux/fs/smbfs/file.c
--- v2.4.5/linux/fs/smbfs/file.c	Tue May 15 13:40:55 2001
+++ linux/fs/smbfs/file.c	Wed Jun 20 16:07:57 2001
@@ -151,6 +151,7 @@
 		 * Update the inode now rather than waiting for a refresh.
 		 */
 		inode->i_mtime = inode->i_atime = CURRENT_TIME;
+		inode->u.smbfs_i.flags |= SMB_F_LOCALWRITE;
 		if (offset > inode->i_size)
 			inode->i_size = offset;
 	} while (count);
diff -u --recursive --new-file v2.4.5/linux/fs/smbfs/inode.c linux/fs/smbfs/inode.c
--- v2.4.5/linux/fs/smbfs/inode.c	Tue May 15 13:40:55 2001
+++ linux/fs/smbfs/inode.c	Wed Jun 20 16:07:57 2001
@@ -141,8 +141,8 @@
 	inode->u.smbfs_i.oldmtime = jiffies;
 
 	if (inode->i_mtime != last_time || inode->i_size != last_sz) {
-		VERBOSE("%s/%s changed, old=%ld, new=%ld, oz=%ld, nz=%ld\n",
-			DENTRY_PATH(dentry),
+		VERBOSE("%ld changed, old=%ld, new=%ld, oz=%ld, nz=%ld\n",
+			inode->i_ino,
 			(long) last_time, (long) inode->i_mtime,
 			(long) last_sz, (long) inode->i_size);
 
diff -u --recursive --new-file v2.4.5/linux/fs/smbfs/proc.c linux/fs/smbfs/proc.c
--- v2.4.5/linux/fs/smbfs/proc.c	Tue May 15 13:40:55 2001
+++ linux/fs/smbfs/proc.c	Wed Jun 20 16:07:57 2001
@@ -919,6 +919,31 @@
 }
 
 /*
+ * Called with the server locked
+ */
+static int
+smb_proc_seek(struct smb_sb_info *server, __u16 fileid,
+	      __u16 mode, off_t offset)
+{
+	int result;
+
+	smb_setup_header(server, SMBlseek, 4, 0);
+	WSET(server->packet, smb_vwv0, fileid);
+	WSET(server->packet, smb_vwv1, mode);
+	DSET(server->packet, smb_vwv2, offset);
+
+	result = smb_request_ok(server, SMBlseek, 2, 0);
+	if (result < 0) {
+		result = 0;
+		goto out;
+	}
+
+	result = DVAL(server->packet, smb_vwv0);
+out:
+	return result;
+}
+
+/*
  * We're called with the server locked, and we leave it that way.
  */
 static int
@@ -1210,11 +1235,6 @@
 	if (result >= 0)
 		result = WVAL(server->packet, smb_vwv0);
 
-	/* flush to disk, to trigger win9x to update its filesize */
-	/* FIXME: this will be rather costly, won't it? */
-	if (server->mnt->flags & SMB_MOUNT_WIN95)
-		smb_proc_flush(server, fileid);
-
 	smb_unlock_server(server);
 	return result;
 }
@@ -1858,6 +1878,7 @@
 		result = mask_len;
 		goto unlock_return;
 	}
+	mask_len--;	/* mask_len is strlen, not #bytes */
 	first = 1;
 	VERBOSE("starting mask_len=%d, mask=%s\n", mask_len, mask);
 
@@ -1946,18 +1967,28 @@
 		 * Note that some servers (win95?) point to the filename and
 		 * others (NT4, Samba using NT1) to the dir entry. We assume
 		 * here that those who do not point to a filename do not need
-		 * this info to continue the listing. OS/2 needs this, but it
-		 * talks "infolevel 1"
+		 * this info to continue the listing.
+		 *
+		 * OS/2 needs this and talks infolevel 1
+		 * NetApps want lastname with infolevel 260
+		 *
+		 * Both are happy if we return the data they point to. So we do.
 		 */
 		mask_len = 0;
-		if (info_level == 1 && ff_lastname > 0 &&
-		    ff_lastname < resp_data_len) {
+		if (ff_lastname > 0 && ff_lastname < resp_data_len) {
 			lastname = resp_data + ff_lastname;
 
-			/* lastname points to a length byte */
-			mask_len = *lastname++;
-			if (ff_lastname + 1 + mask_len > resp_data_len)
-				mask_len = resp_data_len-ff_lastname-1;
+			switch (info_level) {
+			case 260:
+				mask_len = resp_data_len - ff_lastname;
+				break;
+			case 1:
+				/* lastname points to a length byte */
+				mask_len = *lastname++;
+				if (ff_lastname + 1 + mask_len > resp_data_len)
+					mask_len = resp_data_len - ff_lastname - 1;
+				break;
+			}
 
 			/*
 			 * Update the mask string for the next message.
@@ -2062,7 +2093,7 @@
 	DSET(param, 8, 0);
 
 	result = smb_trans2_request(server, TRANSACT2_FINDFIRST,
-				    0, NULL, 12 + mask_len + 1, param,
+				    0, NULL, 12 + mask_len, param,
 				    &resp_data_len, &resp_data,
 				    &resp_param_len, &resp_param);
 	if (result < 0)
@@ -2246,6 +2277,7 @@
 		    struct smb_fattr *fattr)
 {
 	int result;
+	struct inode *inode = dir->d_inode;
 
 	smb_init_dirent(server, fattr);
 
@@ -2261,6 +2293,21 @@
 			result = smb_proc_getattr_ff(server, dir, fattr);
 		else
 			result = smb_proc_getattr_trans2(server, dir, fattr);
+	}
+
+	/*
+	 * None of the getattr versions here can make win9x return the right
+	 * filesize if there are changes made to an open file.
+	 * A seek-to-end does return the right size, but we only need to do
+	 * that on files we have written.
+	 */
+	if (server->mnt->flags & SMB_MOUNT_WIN95 &&
+	    inode &&
+	    inode->u.smbfs_i.flags & SMB_F_LOCALWRITE &&
+	    smb_is_open(inode))
+	{
+		__u16 fileid = inode->u.smbfs_i.fileid;
+		fattr->f_size = smb_proc_seek(server, fileid, 2, 0);
 	}
 
 	smb_finish_dirent(server, fattr);
diff -u --recursive --new-file v2.4.5/linux/fs/super.c linux/fs/super.c
--- v2.4.5/linux/fs/super.c	Fri May 25 12:38:52 2001
+++ linux/fs/super.c	Thu Jun 14 14:16:58 2001
@@ -55,7 +55,6 @@
 extern int root_mountflags;
 
 static int do_remount_sb(struct super_block *sb, int flags, char * data);
-static int do_remount(const char *dir, int flags, char * data);
 
 /* this is initialized in init/main.c */
 kdev_t ROOT_DEV;
@@ -282,13 +281,25 @@
 
 static LIST_HEAD(vfsmntlist);
 
+static struct list_head *mount_hashtable;
+static int hash_mask, hash_bits;
+static kmem_cache_t *mnt_cache; 
+
+static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
+{
+	unsigned long tmp = ((unsigned long) mnt / L1_CACHE_BYTES);
+	tmp += ((unsigned long) dentry / L1_CACHE_BYTES);
+	tmp = tmp + (tmp >> hash_mask);
+	return tmp & hash_bits;
+}
+
 struct vfsmount *alloc_vfsmnt(void)
 {
-	struct vfsmount *mnt = kmalloc(sizeof(struct vfsmount), GFP_KERNEL); 
+	struct vfsmount *mnt = kmem_cache_alloc(mnt_cache, GFP_KERNEL); 
 	if (mnt) {
 		memset(mnt, 0, sizeof(struct vfsmount));
 		atomic_set(&mnt->mnt_count,1);
-		INIT_LIST_HEAD(&mnt->mnt_clash);
+		INIT_LIST_HEAD(&mnt->mnt_hash);
 		INIT_LIST_HEAD(&mnt->mnt_child);
 		INIT_LIST_HEAD(&mnt->mnt_mounts);
 		INIT_LIST_HEAD(&mnt->mnt_list);
@@ -297,6 +308,24 @@
 	return mnt;
 }
 
+struct vfsmount *lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)
+{
+	struct list_head * head = mount_hashtable + hash(mnt, dentry);
+	struct list_head * tmp = head;
+	struct vfsmount *p;
+
+	for (;;) {
+		tmp = tmp->next;
+		p = NULL;
+		if (tmp == head)
+			break;
+		p = list_entry(tmp, struct vfsmount, mnt_hash);
+		if (p->mnt_parent == mnt && p->mnt_mountpoint == dentry)
+			break;
+	}
+	return p;
+}
+
 static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
 {
 	old_nd->dentry = mnt->mnt_mountpoint;
@@ -304,15 +333,17 @@
 	mnt->mnt_parent = mnt;
 	mnt->mnt_mountpoint = mnt->mnt_root;
 	list_del_init(&mnt->mnt_child);
-	list_del_init(&mnt->mnt_clash);
+	list_del_init(&mnt->mnt_hash);
+	old_nd->dentry->d_mounted--;
 }
 
 static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd)
 {
 	mnt->mnt_parent = mntget(nd->mnt);
 	mnt->mnt_mountpoint = dget(nd->dentry);
-	list_add(&mnt->mnt_clash, &nd->dentry->d_vfsmnt);
+	list_add(&mnt->mnt_hash, mount_hashtable+hash(nd->mnt, nd->dentry));
 	list_add(&mnt->mnt_child, &nd->mnt->mnt_mounts);
+	nd->dentry->d_mounted++;
 }
 
 /**
@@ -331,9 +362,7 @@
  *	dentry (if any).
  */
 
-static struct vfsmount *add_vfsmnt(struct nameidata *nd,
-				struct dentry *root,
-				const char *dev_name)
+static struct vfsmount *add_vfsmnt(struct dentry *root, const char *dev_name)
 {
 	struct vfsmount *mnt;
 	struct super_block *sb = root->d_inode->i_sb;
@@ -352,18 +381,11 @@
 		}
 	}
 	mnt->mnt_sb = sb;
-
-	spin_lock(&dcache_lock);
-	if (nd && !IS_ROOT(nd->dentry) && d_unhashed(nd->dentry))
-		goto fail;
 	mnt->mnt_root = dget(root);
+	mnt->mnt_mountpoint = mnt->mnt_root;
+	mnt->mnt_parent = mnt;
 
-	if (nd) {
-		attach_mnt(mnt, nd);
-	} else {
-		mnt->mnt_mountpoint = mnt->mnt_root;
-		mnt->mnt_parent = mnt;
-	}
+	spin_lock(&dcache_lock);
 	list_add(&mnt->mnt_instances, &sb->s_mounts);
 	list_add(&mnt->mnt_list, vfsmntlist.prev);
 	spin_unlock(&dcache_lock);
@@ -371,14 +393,63 @@
 		get_filesystem(sb->s_type);
 out:
 	return mnt;
+}
+
+static struct vfsmount *clone_mnt(struct vfsmount *old_mnt, struct dentry *root)
+{
+	char *name = old_mnt->mnt_devname;
+	struct vfsmount *mnt = alloc_vfsmnt();
+
+	if (!mnt)
+		goto out;
+
+	if (name) {
+		mnt->mnt_devname = kmalloc(strlen(name)+1, GFP_KERNEL);
+		if (mnt->mnt_devname)
+			strcpy(mnt->mnt_devname, name);
+	}
+	mnt->mnt_sb = old_mnt->mnt_sb;
+	mnt->mnt_root = dget(root);
+	mnt->mnt_mountpoint = mnt->mnt_root;
+	mnt->mnt_parent = mnt;
+
+	spin_lock(&dcache_lock);
+	list_add(&mnt->mnt_instances, &old_mnt->mnt_instances);
+	spin_unlock(&dcache_lock);
+out:
+	return mnt;
+}
+
+static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
+{
+	if (S_ISDIR(nd->dentry->d_inode->i_mode) !=
+	      S_ISDIR(mnt->mnt_root->d_inode->i_mode))
+		return -ENOTDIR;
+
+	down(&nd->dentry->d_inode->i_zombie);
+	if (IS_DEADDIR(nd->dentry->d_inode))
+		goto fail1;
+
+	spin_lock(&dcache_lock);
+	if (!IS_ROOT(nd->dentry) && d_unhashed(nd->dentry))
+		goto fail;
+
+	attach_mnt(mnt, nd);
+	list_add(&mnt->mnt_list, vfsmntlist.prev);
+	spin_unlock(&dcache_lock);
+	up(&nd->dentry->d_inode->i_zombie);
+	if (mnt->mnt_sb->s_type->fs_flags & FS_SINGLE)
+		get_filesystem(mnt->mnt_sb->s_type);
+	mntget(mnt);
+	return 0;
 fail:
 	spin_unlock(&dcache_lock);
-	if (mnt->mnt_devname)
-		kfree(mnt->mnt_devname);
-	kfree(mnt);
-	return NULL;
+fail1:
+	up(&nd->dentry->d_inode->i_zombie);
+	return -ENOENT;
 }
 
+#ifdef CONFIG_BLK_DEV_INITRD
 static void move_vfsmnt(struct vfsmount *mnt,
 			struct nameidata *nd, 
 			const char *dev_name)
@@ -407,6 +478,7 @@
 	if (parent_nd.mnt != mnt)
 		path_release(&parent_nd);
 }
+#endif
 
 static void kill_super(struct super_block *);
 
@@ -420,7 +492,7 @@
 	spin_unlock(&dcache_lock);
 	if (mnt->mnt_devname)
 		kfree(mnt->mnt_devname);
-	kfree(mnt);
+	kmem_cache_free(mnt_cache, mnt);
 	kill_super(sb);
 }
 
@@ -734,7 +806,7 @@
  * filesystems which don't use real block-devices.  -- jrs
  */
 
-static unsigned int unnamed_dev_in_use[256/(8*sizeof(unsigned int))];
+static unsigned long unnamed_dev_in_use[256/(8*sizeof(unsigned long))];
 
 kdev_t get_unnamed_dev(void)
 {
@@ -873,6 +945,7 @@
 	}
 	spin_unlock(&dcache_lock);
 	down_write(&sb->s_umount);
+	lock_kernel();
 	sb->s_root = NULL;
 	/* Need to clean after the sucker */
 	if (fs->fs_flags & FS_LITTER)
@@ -901,6 +974,7 @@
 	put_filesystem(fs);
 	sb->s_type = NULL;
 	unlock_super(sb);
+	unlock_kernel();
 	up_write(&sb->s_umount);
 	if (bdev) {
 		blkdev_put(bdev, BDEV_FS);
@@ -921,6 +995,10 @@
 	if (!(flags & MS_RDONLY) && sb->s_dev && is_read_only(sb->s_dev))
 		return -EACCES;
 		/*flags |= MS_RDONLY;*/
+	if (flags & MS_RDONLY)
+		acct_auto_close(sb->s_dev);
+	shrink_dcache_sb(sb);
+	fsync_dev(sb->s_dev);
 	/* If we are remounting RDONLY, make sure there are no rw files open */
 	if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY))
 		if (!fs_may_remount_ro(sb))
@@ -954,13 +1032,13 @@
 
 	dev = get_unnamed_dev();
 	if (!dev) {
-		kfree(mnt);
+		kmem_cache_free(mnt_cache, mnt);
 		return ERR_PTR(-EMFILE);
 	}
 	sb = read_super(dev, NULL, type, 0, NULL, 0);
 	if (!sb) {
 		put_unnamed_dev(dev);
-		kfree(mnt);
+		kmem_cache_free(mnt_cache, mnt);
 		return ERR_PTR(-EINVAL);
 	}
 	mnt->mnt_sb = sb;
@@ -1002,11 +1080,14 @@
 	 * call reboot(9). Then init(8) could umount root and exec /reboot.
 	 */
 	if (mnt == current->fs->rootmnt) {
+		int retval = 0;
 		/*
 		 * Special case for "unmounting" root ...
 		 * we just try to remount it readonly.
 		 */
-		return do_remount("/", MS_RDONLY, NULL);
+		if (!(sb->s_flags & MS_RDONLY))
+			retval = do_remount_sb(sb, MS_RDONLY, 0);
+		return retval;
 	}
 
 	spin_lock(&dcache_lock);
@@ -1143,44 +1224,33 @@
 /*
  * do loopback mount.
  */
-static int do_loopback(char *old_name, char *new_name)
+static int do_loopback(struct nameidata *nd, char *old_name)
 {
-	struct nameidata old_nd, new_nd;
-	int err = 0;
+	struct nameidata old_nd;
+	struct vfsmount *mnt;
+	int err;
+
+	err = mount_is_safe(nd);
+	if (err)
+		return err;
+
 	if (!old_name || !*old_name)
 		return -EINVAL;
-	if (path_init(old_name, LOOKUP_POSITIVE, &old_nd))
+
+	if (path_init(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd))
 		err = path_walk(old_name, &old_nd);
 	if (err)
-		goto out;
-	if (path_init(new_name, LOOKUP_POSITIVE, &new_nd))
-		err = path_walk(new_name, &new_nd);
-	if (err)
-		goto out1;
-	err = mount_is_safe(&new_nd);
-	if (err)
-		goto out2;
-	err = -EINVAL;
-	if (S_ISDIR(new_nd.dentry->d_inode->i_mode) !=
-	      S_ISDIR(old_nd.dentry->d_inode->i_mode))
-		goto out2;
+		return err;
 
-	err = -ENOMEM;
-		
 	down(&mount_sem);
-	/* there we go */
-	down(&new_nd.dentry->d_inode->i_zombie);
-	if (IS_DEADDIR(new_nd.dentry->d_inode))
-		err = -ENOENT;
-	else if (add_vfsmnt(&new_nd, old_nd.dentry, old_nd.mnt->mnt_devname))
-		err = 0;
-	up(&new_nd.dentry->d_inode->i_zombie);
+	err = -ENOMEM;
+	mnt = clone_mnt(old_nd.mnt, old_nd.dentry);
+	if (mnt) {
+		err = graft_tree(mnt, nd);
+		mntput(mnt);
+	}
 	up(&mount_sem);
-out2:
-	path_release(&new_nd);
-out1:
 	path_release(&old_nd);
-out:
 	return err;
 }
 
@@ -1190,34 +1260,87 @@
  * on it - tough luck.
  */
 
-static int do_remount(const char *dir,int flags,char *data)
+static int do_remount(struct nameidata *nd, int flags, char *data)
 {
-	struct nameidata nd;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (nd->dentry != nd->mnt->mnt_root)
+		return -EINVAL;
+
+	return do_remount_sb(nd->mnt->mnt_sb, flags, data);
+}
+
+static int do_add_mount(struct nameidata *nd, 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;
+
+	/* we need capabilities... */
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
-	if (path_init(dir, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd))
-		retval = path_walk(dir, &nd);
-	if (!retval) {
-		struct super_block * sb = nd.dentry->d_inode->i_sb;
-		retval = -ENODEV;
-		if (sb) {
-			retval = -EINVAL;
-			if (nd.dentry == sb->s_root) {
-				/*
-				 * Shrink the dcache and sync the device.
-				 */
-				shrink_dcache_sb(sb);
-				fsync_dev(sb->s_dev);
-				if (flags & MS_RDONLY)
-					acct_auto_close(sb->s_dev);
-				retval = do_remount_sb(sb, flags, data);
-			}
-		}
-		path_release(&nd);
+	/* ... filesystem driver... */
+	fstype = get_fs_type(type);
+	if (!fstype)		
+		return -ENODEV;
+
+	/* ... allocated vfsmount... */
+	retval = -ENOMEM;
+	mnt = alloc_vfsmnt();
+	if (!mnt)
+		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)
+		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);
+		goto fs_out;
 	}
+
+	mnt->mnt_sb = sb;
+	mnt->mnt_root = dget(sb->s_root);
+	mnt->mnt_mountpoint = mnt->mnt_root;
+	mnt->mnt_parent = mnt;
+	spin_lock(&dcache_lock);
+	list_add(&mnt->mnt_instances, &sb->s_mounts);
+	spin_unlock(&dcache_lock);
+
+	/* 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)
+		retval = -EBUSY;
+	else
+		retval = graft_tree(mnt, nd);
+	mntput(mnt);
+	up(&mount_sem);
+fs_out:
+	put_filesystem(fstype);
 	return retval;
 }
 
@@ -1271,10 +1394,7 @@
 long do_mount(char * dev_name, char * dir_name, char *type_page,
 		  unsigned long flags, void *data_page)
 {
-	struct file_system_type * fstype;
 	struct nameidata nd;
-	struct vfsmount *mnt = NULL;
-	struct super_block *sb;
 	int retval = 0;
 
 	/* Discard magic */
@@ -1288,86 +1408,22 @@
 	if (dev_name && !memchr(dev_name, 0, PAGE_SIZE))
 		return -EINVAL;
 
-	/* OK, looks good, now let's see what do they want */
-
-	/* just change the flags? - capabilities are checked in do_remount() */
-	if (flags & MS_REMOUNT)
-		return do_remount(dir_name, flags & ~MS_REMOUNT,
-				  (char *) data_page);
-
-	/* "mount --bind"? Equivalent to older "mount -t bind" */
-	/* No capabilities? What if users do thousands of these? */
-	if (flags & MS_BIND)
-		return do_loopback(dev_name, dir_name);
-
-	/* For the rest we need the type */
-
-	if (!type_page || !memchr(type_page, 0, PAGE_SIZE))
-		return -EINVAL;
-
-	/* for the rest we _really_ need capabilities... */
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
-	/* ... filesystem driver... */
-	fstype = get_fs_type(type_page);
-	if (!fstype)		
-		return -ENODEV;
-
-	/* ... and mountpoint. Do the lookup first to force automounting. */
-	if (path_init(dir_name,
-		      LOOKUP_FOLLOW|LOOKUP_POSITIVE|LOOKUP_DIRECTORY, &nd))
+	/* ... and get the mountpoint */
+	if (path_init(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd))
 		retval = path_walk(dir_name, &nd);
 	if (retval)
-		goto fs_out;
+		return retval;
 
-	/* 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)
-		sb = get_sb_bdev(fstype, dev_name, flags, data_page);
-	else if (fstype->fs_flags & FS_SINGLE)
-		sb = get_sb_single(fstype, flags, data_page);
+	if (flags & MS_REMOUNT)
+		retval = do_remount(&nd, flags&~MS_REMOUNT,
+				  (char *)data_page);
+	else if (flags & MS_BIND)
+		retval = do_loopback(&nd, dev_name);
 	else
-		sb = get_sb_nodev(fstype, flags, data_page);
-
-	retval = PTR_ERR(sb);
-	if (IS_ERR(sb))
-		goto dput_out;
-
-	/* 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 */
-	retval = -EBUSY;
-	if (nd.mnt && nd.mnt->mnt_sb == sb
-	    	   && nd.mnt->mnt_root == nd.dentry)
-		goto fail;
-
-	retval = -ENOENT;
-	if (!nd.dentry->d_inode)
-		goto fail;
-	down(&nd.dentry->d_inode->i_zombie);
-	if (!IS_DEADDIR(nd.dentry->d_inode)) {
-		retval = -ENOMEM;
-		mnt = add_vfsmnt(&nd, sb->s_root, dev_name);
-	}
-	up(&nd.dentry->d_inode->i_zombie);
-	if (!mnt)
-		goto fail;
-	retval = 0;
-unlock_out:
-	up(&mount_sem);
-dput_out:
+		retval = do_add_mount(&nd, type_page, flags,
+				      dev_name, data_page);
 	path_release(&nd);
-fs_out:
-	put_filesystem(fstype);
 	return retval;
-
-fail:
-	kill_super(sb);
-	goto unlock_out;
 }
 
 asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
@@ -1555,10 +1611,10 @@
 		devfs_mk_symlink (NULL, "root", DEVFS_FL_DEFAULT,
 				  path + 5 + path_start, NULL, NULL);
 		memcpy (path + path_start, "/dev/", 5);
-		vfsmnt = add_vfsmnt(NULL, sb->s_root, path + path_start);
+		vfsmnt = add_vfsmnt(sb->s_root, path + path_start);
 	}
 	else
-		vfsmnt = add_vfsmnt(NULL, sb->s_root, "/dev/root");
+		vfsmnt = add_vfsmnt(sb->s_root, "/dev/root");
 	/* FIXME: if something will try to umount us right now... */
 	if (vfsmnt) {
 		set_fs_root(current->fs, vfsmnt, sb->s_root);
@@ -1776,3 +1832,51 @@
 }
 
 #endif
+
+void __init mnt_init(unsigned long mempages)
+{
+	struct list_head *d;
+	unsigned long order;
+	unsigned int nr_hash;
+	int i;
+
+	mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct vfsmount),
+					0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+	if (!mnt_cache)
+		panic("Cannot create vfsmount cache");
+
+	mempages >>= (16 - PAGE_SHIFT);
+	mempages *= sizeof(struct list_head);
+	for (order = 0; ((1UL << order) << PAGE_SHIFT) < mempages; order++)
+		;
+
+	do {
+		unsigned long tmp;
+
+		nr_hash = (1UL << order) * PAGE_SIZE /
+			sizeof(struct list_head);
+		hash_mask = (nr_hash - 1);
+
+		tmp = nr_hash;
+		hash_bits = 0;
+		while ((tmp >>= 1UL) != 0UL)
+			hash_bits++;
+
+		mount_hashtable = (struct list_head *)
+			__get_free_pages(GFP_ATOMIC, order);
+	} while (mount_hashtable == NULL && --order >= 0);
+
+	printk("Mount-cache hash table entries: %d (order: %ld, %ld bytes)\n",
+			nr_hash, order, (PAGE_SIZE << order));
+
+	if (!mount_hashtable)
+		panic("Failed to allocate mount hash table\n");
+
+	d = mount_hashtable;
+	i = nr_hash;
+	do {
+		INIT_LIST_HEAD(d);
+		d++;
+		i--;
+	} while (i);
+}
diff -u --recursive --new-file v2.4.5/linux/fs/sysv/inode.c linux/fs/sysv/inode.c
--- v2.4.5/linux/fs/sysv/inode.c	Tue Apr 17 23:16:39 2001
+++ linux/fs/sysv/inode.c	Tue Jun 12 11:06:54 2001
@@ -442,7 +442,7 @@
 			brelse(bh);
 			printk("SysV FS: cannot read superblock in %d byte mode\n", sb->sv_block_size);
 			goto failed;
-		superblock_ok:
+		superblock_ok:;
 		}
 	} else {
 		/* Switch to 512 block size. Unfortunately, we have to
diff -u --recursive --new-file v2.4.5/linux/fs/udf/Makefile linux/fs/udf/Makefile
--- v2.4.5/linux/fs/udf/Makefile	Fri Dec 29 14:07:23 2000
+++ linux/fs/udf/Makefile	Mon Jun 11 19:15:27 2001
@@ -9,9 +9,9 @@
 
 O_TARGET := udf.o
 
-obj-y   := balloc.o dir.o file.o ialloc.o inode.o lowlevel.o namei.o \
+obj-y    := balloc.o dir.o file.o ialloc.o inode.o lowlevel.o namei.o \
 		partition.o super.o truncate.o symlink.o fsync.o \
 		crc.o directory.o misc.o udftime.o unicode.o
-obj-m   := $(O_TARGET)
+obj-m    := $(O_TARGET)
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.5/linux/fs/udf/balloc.c linux/fs/udf/balloc.c
--- v2.4.5/linux/fs/udf/balloc.c	Tue Sep  5 14:07:30 2000
+++ linux/fs/udf/balloc.c	Mon Jun 11 19:15:27 2001
@@ -7,7 +7,7 @@
  * CONTACTS
  *	E-mail regarding any portion of the Linux UDF file system should be
  *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hootie.lvld.hp.com
+ *		linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
@@ -85,14 +85,14 @@
 #define find_first_one_bit(addr, size)\
 	find_next_one_bit((addr), (size), 0)
 
-static int read_block_bitmap(struct super_block * sb, Uint32 bitmap,
-	unsigned int block, unsigned long bitmap_nr)
+static int read_block_bitmap(struct super_block * sb,
+	struct udf_bitmap *bitmap, unsigned int block, unsigned long bitmap_nr)
 {
 	struct buffer_head *bh = NULL;
 	int retval = 0;
 	lb_addr loc;
 
-	loc.logicalBlockNum = bitmap;
+	loc.logicalBlockNum = bitmap->s_extPosition;
 	loc.partitionReferenceNum = UDF_SB_PARTITION(sb);
 
 	bh = udf_tread(sb, udf_get_lb_pblock(sb, loc, block), sb->s_blocksize);
@@ -100,110 +100,50 @@
 	{
 		retval = -EIO;
 	}
-	UDF_SB_BLOCK_BITMAP_NUMBER(sb, bitmap_nr) = block;
-	UDF_SB_BLOCK_BITMAP(sb, bitmap_nr) = bh;
+	bitmap->s_block_bitmap[bitmap_nr] = bh;
 	return retval;
 }
 
-static int __load_block_bitmap(struct super_block * sb, Uint32 bitmap,
-	unsigned int block_group)
+static int __load_block_bitmap(struct super_block * sb,
+	struct udf_bitmap *bitmap, unsigned int block_group)
 {
-	int i, j, retval = 0;
-	unsigned long block_bitmap_number;
-	struct buffer_head * block_bitmap = NULL;
-	int nr_groups = (UDF_SB_PARTLEN(sb, UDF_SB_PARTITION(sb)) +
-		(sizeof(struct SpaceBitmapDesc) << 3) + (sb->s_blocksize * 8) - 1) / (sb->s_blocksize * 8);
+	int retval = 0;
+	int nr_groups = bitmap->s_nr_groups;
 
 	if (block_group >= nr_groups)
 	{
 		udf_debug("block_group (%d) > nr_groups (%d)\n", block_group, nr_groups);
 	}
 
-	if (nr_groups <= UDF_MAX_BLOCK_LOADED)
+	if (bitmap->s_block_bitmap[block_group])
+		return block_group;
+	else
 	{
-		if (UDF_SB_BLOCK_BITMAP(sb, block_group))
-		{
-			if (UDF_SB_BLOCK_BITMAP_NUMBER(sb, block_group) == block_group)
-				return block_group;
-		}
 		retval = read_block_bitmap(sb, bitmap, block_group, block_group);
 		if (retval < 0)
 			return retval;
 		return block_group;
 	}
-
-	for (i=0; i<UDF_SB_LOADED_BLOCK_BITMAPS(sb) &&
-		UDF_SB_BLOCK_BITMAP_NUMBER(sb, i) != block_group; i++)
-	{
-		;
-	}
-	if (i < UDF_SB_LOADED_BLOCK_BITMAPS(sb) &&
-		UDF_SB_BLOCK_BITMAP_NUMBER(sb, i) == block_group)
-	{
-		block_bitmap_number = UDF_SB_BLOCK_BITMAP_NUMBER(sb, i);
-		block_bitmap = UDF_SB_BLOCK_BITMAP(sb, i);
-		for (j=i; j>0; j--)
-		{
-			UDF_SB_BLOCK_BITMAP_NUMBER(sb, j) = UDF_SB_BLOCK_BITMAP_NUMBER(sb, j-1);
-			UDF_SB_BLOCK_BITMAP(sb, j) = UDF_SB_BLOCK_BITMAP(sb, j-1);
-		}
-		UDF_SB_BLOCK_BITMAP_NUMBER(sb, 0) = block_bitmap_number;
-		UDF_SB_BLOCK_BITMAP(sb, 0) = block_bitmap;
-
-		if (!block_bitmap)
-			retval = read_block_bitmap(sb, bitmap, block_group, 0);
-	}
-	else
-	{
-		if (UDF_SB_LOADED_BLOCK_BITMAPS(sb) < UDF_MAX_BLOCK_LOADED)
-			UDF_SB_LOADED_BLOCK_BITMAPS(sb) ++;
-		else
-			brelse(UDF_SB_BLOCK_BITMAP(sb, UDF_MAX_BLOCK_LOADED-1));
-		for (j=UDF_SB_LOADED_BLOCK_BITMAPS(sb)-1; j>0; j--)
-		{
-			UDF_SB_BLOCK_BITMAP_NUMBER(sb, j) = UDF_SB_BLOCK_BITMAP_NUMBER(sb, j-1);
-			UDF_SB_BLOCK_BITMAP(sb, j) = UDF_SB_BLOCK_BITMAP(sb, j-1);
-		}
-		retval = read_block_bitmap(sb, bitmap, block_group, 0);
-	}
-	return retval;
 }
 
-static inline int load_block_bitmap(struct super_block *sb, Uint32 bitmap,
-	unsigned int block_group)
+static inline int load_block_bitmap(struct super_block *sb,
+	struct udf_bitmap *bitmap, unsigned int block_group)
 {
 	int slot;
-	int nr_groups = (UDF_SB_PARTLEN(sb, UDF_SB_PARTITION(sb)) +
-		(sizeof(struct SpaceBitmapDesc) << 3) + (sb->s_blocksize * 8) - 1) / (sb->s_blocksize * 8);
 
-	if (UDF_SB_LOADED_BLOCK_BITMAPS(sb) > 0 &&
-		UDF_SB_BLOCK_BITMAP_NUMBER(sb, 0) == block_group &&
-		UDF_SB_BLOCK_BITMAP(sb, block_group))
-	{
-		return 0;
-	}
-	else if (nr_groups <= UDF_MAX_BLOCK_LOADED &&
-		UDF_SB_BLOCK_BITMAP_NUMBER(sb, block_group) == block_group &&
-		UDF_SB_BLOCK_BITMAP(sb, block_group))
-	{
-		slot = block_group;
-	}
-	else
-	{
-		slot = __load_block_bitmap(sb, bitmap, block_group);
-	}
+	slot = __load_block_bitmap(sb, bitmap, block_group);
 
 	if (slot < 0)
 		return slot;
 
-	if (!UDF_SB_BLOCK_BITMAP(sb, slot))
+	if (!bitmap->s_block_bitmap[slot])
 		return -EIO;
 
 	return slot;
 }
 
-static void udf_bitmap_free_blocks(const struct inode * inode, Uint32 bitmap,
-	lb_addr bloc, Uint32 offset, Uint32 count)
+static void udf_bitmap_free_blocks(const struct inode * inode,
+	struct udf_bitmap *bitmap, lb_addr bloc, Uint32 offset, Uint32 count)
 {
 	struct buffer_head * bh = NULL;
 	unsigned long block;
@@ -250,7 +190,7 @@
 	if (bitmap_nr < 0)
 		goto error_return;
 
-	bh = UDF_SB_BLOCK_BITMAP(sb, bitmap_nr);
+	bh = bitmap->s_block_bitmap[bitmap_nr];
 	for (i=0; i < count; i++)
 	{
 		if (udf_set_bit(bit + i, bh->b_data))
@@ -283,8 +223,9 @@
 	return;
 }
 
-static int udf_bitmap_prealloc_blocks(const struct inode * inode, Uint32 bitmap,
-	Uint16 partition, Uint32 first_block, Uint32 block_count)
+static int udf_bitmap_prealloc_blocks(const struct inode * inode,
+	struct udf_bitmap *bitmap, Uint16 partition, Uint32 first_block,
+	Uint32 block_count)
 {
 	int alloc_count = 0;
 	int bit, block, block_group, group_start;
@@ -303,6 +244,9 @@
 	if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
 		goto out;
 
+	if (first_block + block_count > UDF_SB_PARTLEN(sb, partition))
+		block_count = UDF_SB_PARTLEN(sb, partition) - first_block;
+
 repeat:
 	nr_groups = (UDF_SB_PARTLEN(sb, partition) +
 		(sizeof(struct SpaceBitmapDesc) << 3) + (sb->s_blocksize * 8) - 1) / (sb->s_blocksize * 8);
@@ -313,7 +257,7 @@
 	bitmap_nr = load_block_bitmap(sb, bitmap, block_group);
 	if (bitmap_nr < 0)
 		goto out;
-	bh = UDF_SB_BLOCK_BITMAP(sb, bitmap_nr);
+	bh = bitmap->s_block_bitmap[bitmap_nr];
 
 	bit = block % (sb->s_blocksize << 3);
 
@@ -349,10 +293,10 @@
 	return alloc_count;
 }
 
-static int udf_bitmap_new_block(const struct inode * inode, Uint32 bitmap,
-	Uint16 partition, Uint32 goal, int *err)
+static int udf_bitmap_new_block(const struct inode * inode,
+	struct udf_bitmap *bitmap, Uint16 partition, Uint32 goal, int *err)
 {
-	int tmp, newbit, bit=0, block, block_group, group_start;
+	int newbit, bit=0, block, block_group, group_start;
 	int end_goal, nr_groups, bitmap_nr, i;
 	struct buffer_head *bh = NULL;
 	struct super_block *sb;
@@ -372,8 +316,7 @@
 	if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
 		goal = 0;
 
-	nr_groups = (UDF_SB_PARTLEN(sb, partition) +
-		(sizeof(struct SpaceBitmapDesc) << 3) + (sb->s_blocksize * 8) - 1) / (sb->s_blocksize * 8);
+	nr_groups = bitmap->s_nr_groups;
 	block = goal + (sizeof(struct SpaceBitmapDesc) << 3);
 	block_group = block >> (sb->s_blocksize_bits + 3);
 	group_start = block_group ? 0 : sizeof(struct SpaceBitmapDesc);
@@ -381,7 +324,7 @@
 	bitmap_nr = load_block_bitmap(sb, bitmap, block_group);
 	if (bitmap_nr < 0)
 		goto error_return;
-	bh = UDF_SB_BLOCK_BITMAP(sb, bitmap_nr);
+	bh = bitmap->s_block_bitmap[bitmap_nr];
 	ptr = memscan((char *)bh->b_data + group_start, 0xFF, sb->s_blocksize - group_start);
 
 	if ((ptr - ((char *)bh->b_data)) < sb->s_blocksize)
@@ -421,7 +364,7 @@
 		bitmap_nr = load_block_bitmap(sb, bitmap, block_group);
 		if (bitmap_nr < 0)
 			goto error_return;
-		bh = UDF_SB_BLOCK_BITMAP(sb, bitmap_nr);
+		bh = bitmap->s_block_bitmap[bitmap_nr];
 		if (i < nr_groups)
 		{
 			ptr = memscan((char *)bh->b_data + group_start, 0xFF, sb->s_blocksize - group_start);
@@ -471,7 +414,6 @@
 	newblock = bit + (block_group << (sb->s_blocksize_bits + 3)) -
 		(sizeof(struct SpaceBitmapDesc) << 3);
 
-	tmp = udf_get_pblock(sb, newblock, partition, 0);
 	if (!udf_clear_bit(bit, bh->b_data))
 	{
 		udf_debug("bit already cleared for block %d\n", bit);
@@ -497,19 +439,479 @@
 	return 0;
 }
 
+static void udf_table_free_blocks(const struct inode * inode,
+	struct inode * table, lb_addr bloc, Uint32 offset, Uint32 count)
+{
+	struct super_block * sb;
+	Uint32 start, end;
+	Uint32 nextoffset, oextoffset, elen;
+	lb_addr nbloc, obloc, eloc;
+	struct buffer_head *obh, *nbh;
+	char etype;
+	int i;
+
+	udf_debug("ino=%ld, bloc=%d, offset=%d, count=%d\n",
+		inode->i_ino, bloc.logicalBlockNum, offset, count);
+
+	sb = inode->i_sb;
+	if (!sb)
+	{
+		udf_debug("nonexistent device");
+		return;
+	}
+
+	if (table == NULL)
+		return;
+
+	lock_super(sb);
+	if (bloc.logicalBlockNum < 0 ||
+		(bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
+	{
+		udf_debug("%d < %d || %d + %d > %d\n",
+			bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
+			UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum));
+		goto error_return;
+	}
+
+	/* We do this up front - There are some error conditions that could occure,
+	   but.. oh well */
+	DQUOT_FREE_BLOCK(sb, inode, count);
+	if (UDF_SB_LVIDBH(sb))
+	{
+		UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)] =
+			cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)])+count);
+		mark_buffer_dirty(UDF_SB_LVIDBH(sb));
+	}
+
+	start = bloc.logicalBlockNum + offset;
+	end = bloc.logicalBlockNum + offset + count - 1;
+
+	oextoffset = nextoffset = sizeof(struct UnallocatedSpaceEntry);
+	elen = 0;
+	obloc = nbloc = UDF_I_LOCATION(table);
+
+	obh = nbh = udf_tread(sb, udf_get_lb_pblock(sb, nbloc, 0), sb->s_blocksize);
+	atomic_inc(&nbh->b_count);
+
+	while (count && (etype =
+		udf_next_aext(table, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)
+	{
+		if (((eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) ==
+			start))
+		{
+			if ((0x3FFFFFFF - elen) < (count << sb->s_blocksize_bits))
+			{
+				count -= ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits);
+				start += ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits);
+				elen = (etype << 30) | (0x40000000 - sb->s_blocksize);
+			}
+			else
+			{
+				elen = (etype << 30) |
+					(elen + (count << sb->s_blocksize_bits));
+				start += count;
+				count = 0;
+			}
+			udf_write_aext(table, obloc, &oextoffset, eloc, elen, obh, 1);
+		}
+		else if (eloc.logicalBlockNum == (end + 1))
+		{
+			if ((0x3FFFFFFF - elen) < (count << sb->s_blocksize_bits))
+			{
+				count -= ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits);
+				end -= ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits);
+				eloc.logicalBlockNum -=
+					((0x3FFFFFFF - elen) >> sb->s_blocksize_bits);
+				elen = (etype << 30) | (0x40000000 - sb->s_blocksize);
+			}
+			else
+			{
+				eloc.logicalBlockNum = start;
+				elen = (etype << 30) |
+					(elen + (count << sb->s_blocksize_bits));
+				end -= count;
+				count = 0;
+			}
+			udf_write_aext(table, obloc, &oextoffset, eloc, elen, obh, 1);
+		}
+
+		if (memcmp(&nbloc, &obloc, sizeof(lb_addr)))
+		{
+			i = -1;
+			obloc = nbloc;
+			udf_release_data(obh);
+			atomic_inc(&nbh->b_count);
+			obh = nbh;
+			oextoffset = 0;
+		}
+		else
+			oextoffset = nextoffset;
+	}
+
+	if (count)
+	{
+		/* NOTE: we CANNOT use udf_add_aext here, as it can try to allocate
+				 a new block, and since we hold the super block lock already
+				 very bad things would happen :)
+
+				 We copy the behavior of udf_add_aext, but instead of
+				 trying to allocate a new block close to the existing one,
+				 we just steal a block from the extent we are trying to add.
+
+				 It would be nice if the blocks were close together, but it
+				 isn't required.
+		*/
+
+		int adsize;
+		short_ad *sad = NULL;
+		long_ad *lad = NULL;
+		struct AllocExtDesc *aed;
+
+		eloc.logicalBlockNum = start;
+		elen = (EXTENT_RECORDED_ALLOCATED << 30) |
+			(count << sb->s_blocksize_bits);
+
+		if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_SHORT)
+			adsize = sizeof(short_ad);
+		else if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_LONG)
+			adsize = sizeof(long_ad);
+		else
+		{
+			udf_release_data(obh);
+			udf_release_data(nbh);
+			goto error_return;
+		}
+
+		if (nextoffset + (2 * adsize) > sb->s_blocksize)
+		{
+			char *sptr, *dptr;
+			int loffset;
+	
+			udf_release_data(obh);
+			obh = nbh;
+			obloc = nbloc;
+			oextoffset = nextoffset;
+
+			/* Steal a block from the extent being free'd */
+			nbloc.logicalBlockNum = eloc.logicalBlockNum;
+			eloc.logicalBlockNum ++;
+			elen -= sb->s_blocksize;
+
+			if (!(nbh = udf_tread(sb,
+				udf_get_lb_pblock(sb, nbloc, 0),
+				sb->s_blocksize)))
+			{
+				udf_release_data(obh);
+				goto error_return;
+			}
+			aed = (struct AllocExtDesc *)(nbh->b_data);
+			aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum);
+			if (nextoffset + adsize > sb->s_blocksize)
+			{
+				loffset = nextoffset;
+				aed->lengthAllocDescs = cpu_to_le32(adsize);
+				sptr = (obh)->b_data + nextoffset - adsize;
+				dptr = nbh->b_data + sizeof(struct AllocExtDesc);
+				memcpy(dptr, sptr, adsize);
+				nextoffset = sizeof(struct AllocExtDesc) + adsize;
+			}
+			else
+			{
+				loffset = nextoffset + adsize;
+				aed->lengthAllocDescs = cpu_to_le32(0);
+				sptr = (obh)->b_data + nextoffset;
+				nextoffset = sizeof(struct AllocExtDesc);
+	
+				if (memcmp(&UDF_I_LOCATION(table), &obloc, sizeof(lb_addr)))
+				{
+					aed = (struct AllocExtDesc *)(obh)->b_data;
+					aed->lengthAllocDescs =
+						cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
+				}
+				else
+				{
+					UDF_I_LENALLOC(table) += adsize;
+					mark_inode_dirty(table);
+				}
+			}
+			udf_new_tag(nbh->b_data, TID_ALLOC_EXTENT_DESC, 2, 1,
+				nbloc.logicalBlockNum, sizeof(tag));
+			switch (UDF_I_ALLOCTYPE(table))
+			{
+				case ICB_FLAG_AD_SHORT:
+				{
+					sad = (short_ad *)sptr;
+					sad->extLength = cpu_to_le32(
+						EXTENT_NEXT_EXTENT_ALLOCDECS << 30 |
+						sb->s_blocksize);
+					sad->extPosition = cpu_to_le32(nbloc.logicalBlockNum);
+					break;
+				}
+				case ICB_FLAG_AD_LONG:
+				{
+					lad = (long_ad *)sptr;
+					lad->extLength = cpu_to_le32(
+						EXTENT_NEXT_EXTENT_ALLOCDECS << 30 |
+						sb->s_blocksize);
+					lad->extLocation = cpu_to_lelb(nbloc);
+					break;
+				}
+			}
+			udf_update_tag(obh->b_data, loffset);
+			mark_buffer_dirty(obh);
+		}
+
+		if (elen) /* It's possible that stealing the block emptied the extent */
+		{
+			udf_write_aext(table, nbloc, &nextoffset, eloc, elen, nbh, 1);
+
+			if (!memcmp(&UDF_I_LOCATION(table), &nbloc, sizeof(lb_addr)))
+			{
+				UDF_I_LENALLOC(table) += adsize;
+				mark_inode_dirty(table);
+			}
+			else
+			{
+				aed = (struct AllocExtDesc *)nbh->b_data;
+				aed->lengthAllocDescs =
+					cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
+				udf_update_tag(nbh->b_data, nextoffset);
+				mark_buffer_dirty(nbh);
+			}
+		}
+	}
+
+	udf_release_data(nbh);
+	udf_release_data(obh);
+
+error_return:
+	sb->s_dirt = 1;
+	unlock_super(sb);
+	return;
+}
+
+static int udf_table_prealloc_blocks(const struct inode * inode,
+	struct inode *table, Uint16 partition, Uint32 first_block,
+	Uint32 block_count)
+{
+	struct super_block *sb;
+	int alloc_count = 0;
+	Uint32 extoffset, elen, adsize;
+	lb_addr bloc, eloc;
+	struct buffer_head *bh;
+	char etype = -1;
+
+	udf_debug("ino=%ld, partition=%d, first_block=%d, block_count=%d\n",
+		inode->i_ino, partition, first_block, block_count);
+
+	sb = inode->i_sb;
+	if (!sb)
+	{
+		udf_debug("nonexistent device\n");
+		return 0;
+	}
+
+	if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
+		return 0;
+
+	if (table == NULL)
+		return 0;
+
+	if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_SHORT)
+		adsize = sizeof(short_ad);
+	else if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_LONG)
+		adsize = sizeof(long_ad);
+	else
+		return 0;
+
+	lock_super(sb);
+
+	extoffset = sizeof(struct UnallocatedSpaceEntry);
+	bloc = UDF_I_LOCATION(table);
+
+	bh = udf_tread(sb, udf_get_lb_pblock(sb, bloc, 0), sb->s_blocksize);
+	eloc.logicalBlockNum = 0xFFFFFFFF;
+
+	while (first_block != eloc.logicalBlockNum && (etype =
+		udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
+	{
+		udf_debug("eloc=%d, elen=%d, first_block=%d\n",
+			eloc.logicalBlockNum, elen, first_block);
+		; /* empty loop body */
+	}
+
+	if (first_block == eloc.logicalBlockNum)
+	{
+		extoffset -= adsize;
+
+		alloc_count = (elen >> sb->s_blocksize_bits);
+		if (alloc_count > block_count)
+		{
+			alloc_count = block_count;
+			eloc.logicalBlockNum += alloc_count;
+			elen -= (alloc_count << sb->s_blocksize_bits);
+			udf_write_aext(table, bloc, &extoffset, eloc, (etype << 30) | elen, bh, 1);
+		}
+		else
+			udf_delete_aext(table, bloc, extoffset, eloc, (etype << 30) | elen, bh);
+	}
+	else
+		alloc_count = 0;
+
+	udf_release_data(bh);
+
+	if (alloc_count && UDF_SB_LVIDBH(sb))
+	{
+		UDF_SB_LVID(sb)->freeSpaceTable[partition] =
+			cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition])-alloc_count);
+		mark_buffer_dirty(UDF_SB_LVIDBH(sb));
+	}
+	sb->s_dirt = 1;
+	unlock_super(sb);
+	udf_debug("alloc_count=%d\n", alloc_count);
+	return alloc_count;
+}
+
+static int udf_table_new_block(const struct inode * inode,
+	struct inode *table, Uint16 partition, Uint32 goal, int *err)
+{
+	struct super_block *sb;
+	Uint32 spread = 0xFFFFFFFF, nspread;
+	Uint32 newblock = 0, adsize;
+	Uint32 extoffset, goal_extoffset, elen, goal_elen = 0;
+	lb_addr bloc, goal_bloc, eloc, goal_eloc;
+	struct buffer_head *bh, *goal_bh;
+	char etype;
+
+	udf_debug("ino=%ld, partition=%d, goal=%d\n",
+		inode->i_ino, partition, goal);
+
+	*err = -ENOSPC;
+	sb = inode->i_sb;
+	if (!sb)
+	{
+		udf_debug("nonexistent device\n");
+		return newblock;
+	}
+
+	if (table == NULL)
+		return newblock;
+
+	if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_SHORT)
+		adsize = sizeof(short_ad);
+	else if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_LONG)
+		adsize = sizeof(long_ad);
+	else
+		return newblock;
+
+	lock_super(sb);
+
+	if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
+		goal = 0;
+
+	/* We search for the closest matching block to goal. If we find a exact hit,	   we stop. Otherwise we keep going till we run out of extents.
+	   We store the buffer_head, bloc, and extoffset of the current closest
+	   match and use that when we are done.
+	*/
+
+	extoffset = sizeof(struct UnallocatedSpaceEntry);
+	bloc = UDF_I_LOCATION(table);
+
+	goal_bh = bh = udf_tread(sb, udf_get_lb_pblock(sb, bloc, 0), sb->s_blocksize);
+	atomic_inc(&goal_bh->b_count);
+
+	while (spread && (etype =
+		udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
+	{
+		if (goal >= eloc.logicalBlockNum)
+		{
+			if (goal < eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits))
+				nspread = 0;
+			else
+				nspread = goal - eloc.logicalBlockNum -
+					(elen >> sb->s_blocksize_bits);
+		}
+		else
+			nspread = eloc.logicalBlockNum - goal;
+
+		if (nspread < spread)
+		{
+			spread = nspread;
+			if (goal_bh != bh)
+			{
+				udf_release_data(goal_bh);
+				goal_bh = bh;
+				atomic_inc(&goal_bh->b_count);
+			}
+			goal_bloc = bloc;
+			goal_extoffset = extoffset - adsize;
+			goal_eloc = eloc;
+			goal_elen = (etype << 30) | elen;
+		}
+	}
+
+	udf_release_data(bh);
+
+	if (spread == 0xFFFFFFFF)
+	{
+		udf_release_data(goal_bh);
+		unlock_super(sb);
+		return 0;
+	}
+
+	/* Only allocate blocks from the beginning of the extent.
+	   That way, we only delete (empty) extents, never have to insert an
+	   extent because of splitting */
+	/* This works, but very poorly.... */
+
+	newblock = goal_eloc.logicalBlockNum;
+	goal_eloc.logicalBlockNum ++;
+	goal_elen -= sb->s_blocksize;
+
+	if (goal_elen)
+		udf_write_aext(table, goal_bloc, &goal_extoffset, goal_eloc, goal_elen, goal_bh, 1);
+	else
+		udf_delete_aext(table, goal_bloc, goal_extoffset, goal_eloc, goal_elen, goal_bh);
+	udf_release_data(goal_bh);
+
+	if (UDF_SB_LVIDBH(sb))
+	{
+		UDF_SB_LVID(sb)->freeSpaceTable[partition] =
+			cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition])-1);
+		mark_buffer_dirty(UDF_SB_LVIDBH(sb));
+	}
+
+	sb->s_dirt = 1;
+	unlock_super(sb);
+	*err = 0;
+	return newblock;
+}
+
 inline void udf_free_blocks(const struct inode * inode, lb_addr bloc,
-    Uint32 offset, Uint32 count)
+	Uint32 offset, Uint32 count)
 {
 	if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_UNALLOC_BITMAP)
 	{
 		return udf_bitmap_free_blocks(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_uspace.bitmap,
+			UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_uspace.s_bitmap,
+			bloc, offset, count);
+	}
+	else if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_UNALLOC_TABLE)
+	{
+		return udf_table_free_blocks(inode,
+			UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_uspace.s_table,
 			bloc, offset, count);
 	}
 	else if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_FREED_BITMAP)
 	{
 		return udf_bitmap_free_blocks(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_fspace.bitmap,
+			UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_fspace.s_bitmap,
+			bloc, offset, count);
+	}
+	else if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_FREED_TABLE)
+	{
+		return udf_table_free_blocks(inode,
+			UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_fspace.s_table,
 			bloc, offset, count);
 	}
 	else
@@ -522,13 +924,25 @@
 	if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
 	{
 		return udf_bitmap_prealloc_blocks(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.bitmap,
+			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_bitmap,
+			partition, first_block, block_count);
+	}
+	else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
+	{
+		return udf_table_prealloc_blocks(inode,
+			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_table,
 			partition, first_block, block_count);
 	}
 	else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
 	{
 		return udf_bitmap_prealloc_blocks(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.bitmap,
+			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_bitmap,
+			partition, first_block, block_count);
+	}
+	else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_TABLE)
+	{
+		return udf_table_prealloc_blocks(inode,
+			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_table,
 			partition, first_block, block_count);
 	}
 	else
@@ -541,13 +955,25 @@
 	if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
 	{
 		return udf_bitmap_new_block(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.bitmap,
+			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_bitmap,
+			partition, goal, err);
+	}
+	else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
+	{
+		return udf_table_new_block(inode,
+			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_table,
 			partition, goal, err);
 	}
 	else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
 	{
 		return udf_bitmap_new_block(inode,
-			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.bitmap,
+			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_bitmap,
+			partition, goal, err);
+	}
+	else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_TABLE)
+	{
+		return udf_table_new_block(inode,
+			UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_table,
 			partition, goal, err);
 	}
 	else
@@ -556,4 +982,3 @@
 		return 0;
 	}
 }
-
diff -u --recursive --new-file v2.4.5/linux/fs/udf/crc.c linux/fs/udf/crc.c
--- v2.4.5/linux/fs/udf/crc.c	Sat Sep  4 12:42:30 1999
+++ linux/fs/udf/crc.c	Mon Jun 11 19:15:27 2001
@@ -17,7 +17,7 @@
  * CONTACTS
  *	E-mail regarding any portion of the Linux UDF file system should be
  *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hootie.lvld.hp.com
+ *		linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
diff -u --recursive --new-file v2.4.5/linux/fs/udf/dir.c linux/fs/udf/dir.c
--- v2.4.5/linux/fs/udf/dir.c	Fri Feb  9 11:29:44 2001
+++ linux/fs/udf/dir.c	Mon Jun 11 19:15:27 2001
@@ -7,7 +7,7 @@
  * CONTACTS
  *	E-mail regarding any portion of the Linux UDF file system should be
  *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hootie.lvld.hp.com
+ *		linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
@@ -49,10 +49,10 @@
 /* readdir and lookup functions */
 
 struct file_operations udf_dir_operations = {
-	read:				generic_read_dir,
-	readdir:			udf_readdir,
-	ioctl:				udf_ioctl,
-	fsync:				udf_sync_file,
+	read:			generic_read_dir,
+	readdir:		udf_readdir,
+	ioctl:			udf_ioctl,
+	fsync:			udf_fsync_file,
 };
 
 /*
@@ -88,8 +88,9 @@
 
 	if ( filp->f_pos == 0 ) 
 	{
-		if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR))
+		if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) < 0)
 			return 0;
+		filp->f_pos ++;
 	}
  
 	result = do_udf_readdir(dir, filp, filldir, dirent);
@@ -104,19 +105,21 @@
 	struct FileIdentDesc *fi=NULL;
 	struct FileIdentDesc cfi;
 	int block, iblock;
-	loff_t nf_pos = filp->f_pos;
+	loff_t nf_pos = filp->f_pos - 1;
 	int flen;
 	char fname[255];
 	char *nameptr;
 	Uint16 liu;
 	Uint8 lfi;
 	loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
-	struct buffer_head * bh = NULL;
+	struct buffer_head * bh = NULL, * tmp, * bha[16];
 	lb_addr bloc, eloc;
 	Uint32 extoffset, elen, offset;
+	int i, num;
+	unsigned int dt_type;
 
 	if (nf_pos >= size)
-		return 1;
+		return 0;
 
 	if (nf_pos == 0)
 		nf_pos = (udf_ext0_offset(dir) >> 2);
@@ -125,6 +128,7 @@
 	if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2),
 		&bloc, &extoffset, &eloc, &elen, &offset, &bh) == EXTENT_RECORDED_ALLOCATED)
 	{
+		offset >>= dir->i_sb->s_blocksize_bits;
 		block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
 		if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
 		{
@@ -139,18 +143,40 @@
 	else
 	{
 		udf_release_data(bh);
-		return 0;
+		return -ENOENT;
 	}
 
 	if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize)))
 	{
 		udf_release_data(bh);
-		return 0;
+		return -EIO;
+	}
+
+	if (!(offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9))-1)))
+	{
+		i = 16 >> (dir->i_sb->s_blocksize_bits - 9);
+		if (i+offset > (elen >> dir->i_sb->s_blocksize_bits))
+			i = (elen >> dir->i_sb->s_blocksize_bits)-offset;
+		for (num=0; i>0; i--)
+		{
+			block = udf_get_lb_pblock(dir->i_sb, eloc, offset+i);
+			tmp = udf_tgetblk(dir->i_sb, block, dir->i_sb->s_blocksize);
+			if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp))
+				bha[num++] = tmp;
+			else
+				brelse(tmp);
+		}
+		if (num)
+		{
+			ll_rw_block(READA, num, bha);
+			for (i=0; i<num; i++)
+				brelse(bha[i]);
+		}
 	}
 
 	while ( nf_pos < size )
 	{
-		filp->f_pos = nf_pos;
+		filp->f_pos = nf_pos + 1;
 
 		fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
 
@@ -160,7 +186,7 @@
 				udf_release_data(fibh.ebh);
 			udf_release_data(fibh.sbh);
 			udf_release_data(bh);
-			return 1;
+			return -ENOENT;
 		}
 
 		liu = le16_to_cpu(cfi.lengthOfImpUse);
@@ -196,44 +222,39 @@
 				continue;
 		}
 
-		iblock = udf_get_lb_pblock(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation), 0);
- 
- 		if (!lfi) /* parent directory */
- 		{
-			if (filldir(dirent, "..", 2, filp->f_pos, filp->f_dentry->d_parent->d_inode->i_ino, DT_DIR))
+		if ( cfi.fileCharacteristics & FILE_PARENT )
+		{
+			iblock = udf_get_lb_pblock(dir->i_sb, UDF_I_LOCATION(filp->f_dentry->d_parent->d_inode), 0);
+			flen = 2;
+			memcpy(fname, "..", flen);
+			dt_type = DT_DIR;
+		}
+		else
+		{
+			iblock = udf_get_lb_pblock(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation), 0);
+			flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi);
+			dt_type = DT_UNKNOWN;
+		}
+
+		if (flen)
+		{
+			if (filldir(dirent, fname, flen, filp->f_pos, iblock, dt_type) < 0)
 			{
 				if (fibh.sbh != fibh.ebh)
 					udf_release_data(fibh.ebh);
 				udf_release_data(fibh.sbh);
 				udf_release_data(bh);
- 				return 1;
-			}
-		}
-		else
-		{
-			if ((flen = udf_get_filename(nameptr, fname, lfi)))
-			{
-				if (filldir(dirent, fname, flen, filp->f_pos, iblock, DT_UNKNOWN))
-				{
-					if (fibh.sbh != fibh.ebh)
-						udf_release_data(fibh.ebh);
-					udf_release_data(fibh.sbh);
-					udf_release_data(bh);
-		 			return 1; /* halt enum */
-				}
+	 			return 0;
 			}
 		}
 	} /* end while */
 
-	filp->f_pos = nf_pos;
+	filp->f_pos = nf_pos + 1;
 
 	if (fibh.sbh != fibh.ebh)
 		udf_release_data(fibh.ebh);
 	udf_release_data(fibh.sbh);
 	udf_release_data(bh);
 
-	if ( filp->f_pos >= size)
-		return 1;
-	else
-		return 0;
+	return 0;
 }
diff -u --recursive --new-file v2.4.5/linux/fs/udf/directory.c linux/fs/udf/directory.c
--- v2.4.5/linux/fs/udf/directory.c	Thu Mar  2 11:17:32 2000
+++ linux/fs/udf/directory.c	Mon Jun 11 19:15:27 2001
@@ -7,7 +7,7 @@
  * CONTACTS
  *	E-mail regarding any portion of the Linux UDF file system should be
  *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hootie.lvld.hp.com
+ *		linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
@@ -92,7 +92,8 @@
 	Uint32 *offset, struct buffer_head **bh)
 {
 	struct FileIdentDesc *fi;
-	int block;
+	int i, num, block;
+	struct buffer_head * tmp, * bha[16];
 
 	fibh->soffset = fibh->eoffset;
 
@@ -119,6 +120,28 @@
 		if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize)))
 			return NULL;
 		fibh->soffset = fibh->eoffset = 0;
+
+		if (!(*offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9))-1)))
+		{
+			i = 16 >> (dir->i_sb->s_blocksize_bits - 9);
+			if (i+*offset > (*elen >> dir->i_sb->s_blocksize_bits))
+				i = (*elen >> dir->i_sb->s_blocksize_bits)-*offset;
+			for (num=0; i>0; i--)
+			{
+				block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset+i);
+				tmp = udf_tgetblk(dir->i_sb, block, dir->i_sb->s_blocksize);
+				if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp))
+					bha[num++] = tmp;
+				else
+					brelse(tmp);
+			}
+			if (num)
+			{
+				ll_rw_block(READA, num, bha);
+				for (i=0; i<num; i++)
+					brelse(bha[i]);
+			}
+		}
 	}
 	else if (fibh->sbh != fibh->ebh)
 	{
diff -u --recursive --new-file v2.4.5/linux/fs/udf/file.c linux/fs/udf/file.c
--- v2.4.5/linux/fs/udf/file.c	Sun Jan 28 13:28:09 2001
+++ linux/fs/udf/file.c	Mon Jun 11 19:15:27 2001
@@ -7,7 +7,7 @@
  * CONTACTS
  *  E-mail regarding any portion of the Linux UDF file system should be
  *  directed to the development team mailing list (run by majordomo):
- *    linux_udf@hootie.lvld.hp.com
+ *    linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *  This file is distributed under the terms of the GNU General Public
@@ -119,8 +119,8 @@
 }
 
 struct address_space_operations udf_adinicb_aops = {
-	readpage:			udf_adinicb_readpage,
-	writepage:			udf_adinicb_writepage,
+	readpage:		udf_adinicb_readpage,
+	writepage:		udf_adinicb_writepage,
 	sync_page:		block_sync_page,
 	prepare_write:		udf_adinicb_prepare_write,
 	commit_write:		udf_adinicb_commit_write,
@@ -208,7 +208,6 @@
 {
 	int result = -1;
 	struct buffer_head *bh = NULL;
-	Uint16 ident;
 	long_ad eaicb;
 	Uint8 *ea = NULL;
 
@@ -232,17 +231,28 @@
 			if ( (result == verify_area(VERIFY_WRITE, (char *)arg, 32)) == 0)
 				result = copy_to_user((char *)arg, UDF_SB_VOLIDENT(inode->i_sb), 32);
 			return result;
+		case UDF_RELOCATE_BLOCKS:
+		{
+			long old, new;
+
+			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+			get_user(old, (long *)arg);
+			if ((result = udf_relocate_blocks(inode->i_sb, old, &new)) == 0)
+				result = put_user(new, (long *)arg);
 
+			return result;
+		}
 	}
 
 	/* ok, we need to read the inode */
-	bh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 0, &ident);
+	bh = udf_tread(inode->i_sb,
+		udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0),
+		inode->i_sb->s_blocksize);
 
-	if (!bh || (ident != TID_FILE_ENTRY && ident != TID_EXTENDED_FILE_ENTRY))
+	if (!bh)
 	{
-		udf_debug("bread failed (ino=%ld) or ident (%d) != TID_(EXTENDED_)FILE_ENTRY",
-			inode->i_ino, ident);
-		return -EFAULT;
+		udf_debug("bread failed (inode=%ld)\n", inode->i_ino);
+		return -EIO;
 	}
 
 	if (UDF_I_EXTENDED_FE(inode) == 0)
@@ -277,7 +287,6 @@
 			break;
 
 		default:
-			udf_debug("ino=%ld, cmd=%d\n", inode->i_ino, cmd);
 			break;
 	}
 
@@ -299,7 +308,8 @@
  */
 static int udf_release_file(struct inode * inode, struct file * filp)
 {
-	if (filp->f_mode & FMODE_WRITE) {
+	if (filp->f_mode & FMODE_WRITE)
+	{
 		lock_kernel();
 		udf_discard_prealloc(inode);
 		unlock_kernel();
@@ -322,21 +332,21 @@
  */
 static int udf_open_file(struct inode * inode, struct file * filp)
 {
-	if ((inode->i_size & 0xFFFFFFFF00000000ULL) && !(filp->f_flags & O_LARGEFILE))
+	if ((inode->i_size & 0xFFFFFFFF80000000ULL) && !(filp->f_flags & O_LARGEFILE))
 		return -EFBIG;
 	return 0;
 }
 
 struct file_operations udf_file_operations = {
-	read:				generic_file_read,
-	ioctl:				udf_ioctl,
-	open:				udf_open_file,
-	mmap:				generic_file_mmap,
-	write:				udf_file_write,
-	release:			udf_release_file,
-	fsync:				udf_sync_file,
+	read:			generic_file_read,
+	ioctl:			udf_ioctl,
+	open:			udf_open_file,
+	mmap:			generic_file_mmap,
+	write:			udf_file_write,
+	release:		udf_release_file,
+	fsync:			udf_fsync_file,
 };
 
 struct inode_operations udf_file_inode_operations = {
-	truncate:			udf_truncate,
+	truncate:		udf_truncate,
 };
diff -u --recursive --new-file v2.4.5/linux/fs/udf/fsync.c linux/fs/udf/fsync.c
--- v2.4.5/linux/fs/udf/fsync.c	Thu Jun 29 16:23:11 2000
+++ linux/fs/udf/fsync.c	Mon Jun 11 19:15:27 2001
@@ -7,7 +7,7 @@
  * CONTACTS
  *  E-mail regarding any portion of the Linux UDF file system should be
  *  directed to the development team mailing list (run by majordomo):
- *      linux_udf@hootie.lvld.hp.com
+ *      linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *  This file is distributed under the terms of the GNU General Public
@@ -28,96 +28,28 @@
 #include <linux/fs.h>
 #include <linux/locks.h>
 #include <linux/smp_lock.h>
-#include <linux/udf_fs.h>
-#include "udf_i.h"
-
-static int sync_extent_block (struct inode * inode, Uint32 block, int wait)
-{
-	struct buffer_head * bh;
-	
-	if (!block)
-		return 0;
-	bh = get_hash_table (inode->i_dev, block, inode->i_sb->s_blocksize);
-	if (!bh)
-		return 0;
-	if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
-		/* There can be a parallell read(2) that started read-I/O
-		   on the buffer so we can't assume that there's been
-		   an I/O error without first waiting I/O completation. */
-		wait_on_buffer(bh);
-		if (!buffer_uptodate(bh))
-		{
-			brelse (bh);
-			return -1;
-		}
-	}
-	if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) {
-		if (wait)
-			/* when we return from fsync all the blocks
-			   must be _just_ stored on disk */
-			wait_on_buffer(bh);
-		brelse (bh);
-		return 0;
-	}
-	ll_rw_block (WRITE, 1, &bh);
-	atomic_dec(&bh->b_count);
-	return 0;
-}
-
-static int sync_all_extents(struct inode * inode, int wait)
-{
-	lb_addr bloc, eloc;
-	Uint32 extoffset, lextoffset, elen, offset, block;
-	int err = 0, etype;
-	struct buffer_head *bh = NULL;
-	
-	if ((etype = inode_bmap(inode, 0, &bloc, &extoffset, &eloc, &elen, &offset, &bh)) != -1)
-	{
-		block = udf_get_lb_pblock(inode->i_sb, bloc, 0);
-		err |= sync_extent_block(inode, block, wait);
-		lextoffset = extoffset;
-
-		while ((etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
-		{
-			if (lextoffset > extoffset)
-			{
-				block = udf_get_lb_pblock(inode->i_sb, bloc, 0);
-				err |= sync_extent_block(inode, block, wait);
-			}
-			lextoffset = extoffset;
-		}
-	}
-	udf_release_data(bh);
-	return err;
-}
 
 /*
  *	File may be NULL when we are called. Perhaps we shouldn't
  *	even pass file to fsync ?
  */
 
-int udf_sync_file(struct file * file, struct dentry *dentry, int datasync)
+int udf_fsync_file(struct file * file, struct dentry *dentry, int datasync)
 {
-	int wait, err = 0;
 	struct inode *inode = dentry->d_inode;
+	return udf_fsync_inode(inode, datasync);
+}
+
+int udf_fsync_inode(struct inode *inode, int datasync)
+{
+	int err;
+
+	err = fsync_inode_buffers(inode);
+	if (!(inode->i_state & I_DIRTY))
+		return err;
+	if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
+		return err;
 
-	lock_kernel();
-	if (S_ISLNK(inode->i_mode) && !(inode->i_blocks)) 
-	{
-		/*
-		 * Don't sync fast links! or ICB_FLAG_AD_IN_ICB
-		 */
-		goto skip;
-	}
-
-	err = generic_buffer_fdatasync(inode, 0, ~0UL);
-
-	for (wait=0; wait<=1; wait++)
-	{
-		err |= sync_all_extents (inode, wait);
-	}
-skip:
 	err |= udf_sync_inode (inode);
-	unlock_kernel();
 	return err ? -EIO : 0;
 }
diff -u --recursive --new-file v2.4.5/linux/fs/udf/ialloc.c linux/fs/udf/ialloc.c
--- v2.4.5/linux/fs/udf/ialloc.c	Fri Nov 17 11:35:27 2000
+++ linux/fs/udf/ialloc.c	Mon Jun 11 19:15:27 2001
@@ -7,7 +7,7 @@
  * CONTACTS
  *	E-mail regarding any portion of the Linux UDF file system should be
  *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hootie.lvld.hp.com
+ *		linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
@@ -79,6 +79,7 @@
 
 	sb = dir->i_sb;
 	inode = new_inode(sb);
+
 	if (!inode)
 	{
 		*err = -ENOMEM;
@@ -114,7 +115,8 @@
 	}
 	inode->i_mode = mode;
 	inode->i_uid = current->fsuid;
-	if (dir->i_mode & S_ISGID) {
+	if (dir->i_mode & S_ISGID)
+	{
 		inode->i_gid = dir->i_gid;
 		if (S_ISDIR(mode))
 			mode |= S_ISGID;
diff -u --recursive --new-file v2.4.5/linux/fs/udf/inode.c linux/fs/udf/inode.c
--- v2.4.5/linux/fs/udf/inode.c	Sun Jan 28 13:28:09 2001
+++ linux/fs/udf/inode.c	Mon Jun 11 19:15:27 2001
@@ -7,7 +7,7 @@
  * CONTACTS
  *  E-mail regarding any portion of the Linux UDF file system should be
  *  directed to the development team mailing list (run by majordomo):
- *    linux_udf@hootie.lvld.hp.com
+ *    linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *  This file is distributed under the terms of the GNU General Public
@@ -106,23 +106,27 @@
 	lock_kernel();
 
 	if (is_bad_inode(inode))
-	{
-		clear_inode(inode);
-		goto out;
-	}
+		goto no_delete;
 
 	inode->i_size = 0;
 	udf_truncate(inode);
 	udf_update_inode(inode, IS_SYNC(inode));
 	udf_free_inode(inode);
-out:
+
 	unlock_kernel();
+	return;
+no_delete:
+	unlock_kernel();
+	clear_inode(inode);
 }
 
 void udf_discard_prealloc(struct inode * inode)
 {
-	if (inode->i_size && UDF_I_ALLOCTYPE(inode) != ICB_FLAG_AD_IN_ICB)
-		udf_trunc(inode);
+	if (inode->i_size && inode->i_size != UDF_I_LENEXTENTS(inode) &&
+		UDF_I_ALLOCTYPE(inode) != ICB_FLAG_AD_IN_ICB)
+	{
+		udf_truncate_extents(inode);
+	}
 }
 
 static int udf_writepage(struct page *page)
@@ -146,18 +150,19 @@
 }
 
 struct address_space_operations udf_aops = {
-	readpage:			udf_readpage,
-	writepage:			udf_writepage,
+	readpage:		udf_readpage,
+	writepage:		udf_writepage,
 	sync_page:		block_sync_page,
 	prepare_write:		udf_prepare_write,
 	commit_write:		generic_commit_write,
-	bmap:				udf_bmap,
+	bmap:			udf_bmap,
 };
 
 void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err)
 {
 	struct buffer_head *bh = NULL;
 	struct page *page;
+	char *kaddr;
 	int block;
 
 	/* from now on we have normal address_space methods */
@@ -182,7 +187,7 @@
 		PAGE_BUG(page);
 	if (!Page_Uptodate(page))
 	{
-		char *kaddr = kmap(page);
+		kaddr = kmap(page);
 		memset(kaddr + UDF_I_LENALLOC(inode), 0x00,
 			PAGE_CACHE_SIZE - UDF_I_LENALLOC(inode));
 		memcpy(kaddr, bh->b_data + udf_file_entry_alloc_offset(inode),
@@ -199,7 +204,7 @@
 	else
 		UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG;
 	inode->i_blocks = inode->i_sb->s_blocksize / 512;
-	mark_buffer_dirty(bh);
+	mark_buffer_dirty_inode(bh, inode);
 	udf_release_data(bh);
 
 	inode->i_data.a_ops->writepage(page);
@@ -245,9 +250,14 @@
 	sbh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize);
 	if (!sbh)
 		return NULL;
-	dbh = udf_tread(inode->i_sb, newblock, inode->i_sb->s_blocksize);
+	dbh = udf_tgetblk(inode->i_sb, newblock, inode->i_sb->s_blocksize);
 	if (!dbh)
 		return NULL;
+	lock_buffer(dbh);
+	memset(dbh->b_data, 0x00, inode->i_sb->s_blocksize);
+	mark_buffer_uptodate(dbh, 1);
+	unlock_buffer(dbh);
+	mark_buffer_dirty_inode(dbh, inode);
 
 	sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2;
 	sfibh.sbh = sfibh.ebh = sbh;
@@ -266,7 +276,7 @@
 		dfibh.soffset = dfibh.eoffset;
 		dfibh.eoffset += (sfibh.eoffset - sfibh.soffset);
 		dfi = (struct FileIdentDesc *)(dbh->b_data + dfibh.soffset);
-		if (udf_write_fi(sfi, dfi, &dfibh, sfi->impUse,
+		if (udf_write_fi(inode, sfi, dfi, &dfibh, sfi->impUse,
 			sfi->fileIdent + sfi->lengthOfImpUse))
 		{
 			udf_release_data(sbh);
@@ -274,7 +284,7 @@
 			return NULL;
 		}
 	}
-	mark_buffer_dirty(dbh);
+	mark_buffer_dirty_inode(dbh, inode);
 
 	memset(sbh->b_data + udf_file_entry_alloc_offset(inode),
 		0, UDF_I_LENALLOC(inode));
@@ -288,6 +298,7 @@
 	eloc.logicalBlockNum = *block;
 	eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
 	elen = inode->i_size;
+	UDF_I_LENEXTENTS(inode) = elen;
 	extoffset = udf_file_entry_alloc_offset(inode);
 	udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &sbh, 0);
 	/* UniqueID stuff */
@@ -361,23 +372,21 @@
 	int create, int * err)
 {
 	struct buffer_head dummy;
-	int error;
 
 	dummy.b_state = 0;
 	dummy.b_blocknr = -1000;
-	error = udf_get_block(inode, block, &dummy, create);
-	*err = error;
-	if (!error & buffer_mapped(&dummy))
+	*err = udf_get_block(inode, block, &dummy, create);
+	if (!*err && buffer_mapped(&dummy))
 	{
 		struct buffer_head *bh;
 		bh = getblk(dummy.b_dev, dummy.b_blocknr, inode->i_sb->s_blocksize);
 		if (buffer_new(&dummy))
 		{
-			if (!buffer_uptodate(bh))
-				wait_on_buffer(bh);
+			lock_buffer(bh);
 			memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);
 			mark_buffer_uptodate(bh, 1);
-			mark_buffer_dirty(bh);
+			unlock_buffer(bh);
+			mark_buffer_dirty_inode(bh, inode);
 		}
 		return bh;
 	}
@@ -387,22 +396,22 @@
 static struct buffer_head * inode_getblk(struct inode * inode, long block,
 	int *err, long *phys, int *new)
 {
-	struct buffer_head *pbh = NULL, *cbh = NULL, *result = NULL;
+	struct buffer_head *pbh = NULL, *cbh = NULL, *nbh = NULL, *result = NULL;
 	long_ad laarr[EXTENT_MERGE_SIZE];
 	Uint32 pextoffset = 0, cextoffset = 0, nextoffset = 0;
 	int count = 0, startnum = 0, endnum = 0;
 	Uint32 elen = 0;
-	lb_addr eloc, pbloc = UDF_I_LOCATION(inode), cbloc = UDF_I_LOCATION(inode);
+	lb_addr eloc, pbloc, cbloc, nbloc;
 	int c = 1;
 	int lbcount = 0, b_off = 0, offset = 0;
 	Uint32 newblocknum, newblock;
-	int etype;
+	char etype;
 	int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum;
 	char lastblock = 0;
 
 	pextoffset = cextoffset = nextoffset = udf_file_entry_alloc_offset(inode);
 	b_off = block << inode->i_sb->s_blocksize_bits;
-	pbloc = cbloc = UDF_I_LOCATION(inode);
+	pbloc = cbloc = nbloc = UDF_I_LOCATION(inode);
 
 	/* find the extent which contains the block we are looking for.
        alternate between laarr[0] and laarr[1] for locations of the
@@ -412,17 +421,25 @@
 		if (pbh != cbh)
 		{
 			udf_release_data(pbh);
-			pbh = cbh;
 			atomic_inc(&cbh->b_count);
-			pbloc = cbloc;
+			pbh = cbh;
+		}
+		if (cbh != nbh)
+		{
+			udf_release_data(cbh);
+			atomic_inc(&nbh->b_count);
+			cbh = nbh;
 		}
 
 		lbcount += elen;
 
+		pbloc = cbloc;
+		cbloc = nbloc;
+
 		pextoffset = cextoffset;
 		cextoffset = nextoffset;
 
-		if ((etype = udf_next_aext(inode, &cbloc, &nextoffset, &eloc, &elen, &cbh, 1)) == -1)
+		if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) == -1)
 			break;
 
 		c = !c;
@@ -433,7 +450,7 @@
 		if (etype != EXTENT_NOT_RECORDED_NOT_ALLOCATED)
 			pgoal = eloc.logicalBlockNum +
 				((elen + inode->i_sb->s_blocksize - 1) >>
-				inode->i_sb->s_blocksize);
+				inode->i_sb->s_blocksize_bits);
 
 		count ++;
 	} while (lbcount + elen <= b_off);
@@ -451,10 +468,11 @@
 			elen = (EXTENT_RECORDED_ALLOCATED << 30) |
 				((elen + inode->i_sb->s_blocksize - 1) &
 				~(inode->i_sb->s_blocksize - 1));
-			etype = udf_write_aext(inode, cbloc, &cextoffset, eloc, elen, &cbh, 1);
+			etype = udf_write_aext(inode, nbloc, &cextoffset, eloc, elen, nbh, 1);
 		}
 		udf_release_data(pbh);
 		udf_release_data(cbh);
+		udf_release_data(nbh);
 		newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset);
 		*phys = newblock;
 		return NULL;
@@ -470,6 +488,9 @@
 				(((laarr[c].extLength & UDF_EXTENT_LENGTH_MASK) +
 					inode->i_sb->s_blocksize - 1) &
 				~(inode->i_sb->s_blocksize - 1));
+			UDF_I_LENEXTENTS(inode) =
+				(UDF_I_LENEXTENTS(inode) + inode->i_sb->s_blocksize - 1) &
+					~(inode->i_sb->s_blocksize - 1);
 		}
 		c = !c;
 		laarr[c].extLength = (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30) |
@@ -494,7 +515,7 @@
 	/* if the current block is located in a extent, read the next extent */
 	if (etype != -1)
 	{
-		if ((etype = udf_next_aext(inode, &cbloc, &nextoffset, &eloc, &elen, &cbh, 0)) != -1)
+		if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 0)) != -1)
 		{
 			laarr[c+1].extLength = (etype << 30) | elen;
 			laarr[c+1].extLocation = eloc;
@@ -505,7 +526,11 @@
 		else
 			lastblock = 1;
 	}
-	udf_release_data(cbh);
+	udf_release_data(nbh);
+	if (!pbh)
+		pbh = cbh;
+	else
+		udf_release_data(cbh);
 
 	/* if the current extent is not recorded but allocated, get the
 		block in the extent corresponding to the requested block */
@@ -529,6 +554,7 @@
 			*err = -ENOSPC;
 			return NULL;
 		}
+		UDF_I_LENEXTENTS(inode) += inode->i_sb->s_blocksize;
 	}
 
 	/* if the extent the requsted block is located in contains multiple blocks,
@@ -629,17 +655,24 @@
 {
 	int start, length = 0, currlength = 0, i;
 
-	if (*endnum >= (c+1) && !lastblock)
-		return;
-
-	if ((laarr[c+1].extLength >> 30) == EXTENT_NOT_RECORDED_ALLOCATED)
+	if (*endnum >= (c+1))
 	{
-		start = c+1;
-		length = currlength = (((laarr[c+1].extLength & UDF_EXTENT_LENGTH_MASK) +
-			inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
+		if (!lastblock)
+			return;
+		else
+			start = c;
 	}
 	else
-		start = c;
+	{
+		if ((laarr[c+1].extLength >> 30) == EXTENT_NOT_RECORDED_ALLOCATED)
+		{
+			start = c+1;
+			length = currlength = (((laarr[c+1].extLength & UDF_EXTENT_LENGTH_MASK) +
+				inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
+		}
+		else
+			start = c;
+	}
 
 	for (i=start+1; i<=*endnum; i++)
 	{
@@ -667,6 +700,7 @@
 
 		if (numalloc)
 		{
+			UDF_I_LENEXTENTS(inode) += numalloc << inode->i_sb->s_blocksize_bits;
 			if (start == (c+1))
 				laarr[start].extLength +=
 					(numalloc << inode->i_sb->s_blocksize_bits);
@@ -784,7 +818,7 @@
 	{
 		udf_next_aext(inode, &pbloc, &pextoffset, &tmploc, &tmplen, pbh, 0);
 		udf_write_aext(inode, pbloc, &pextoffset, laarr[i].extLocation,
-			laarr[i].extLength, pbh, 1);
+			laarr[i].extLength, *pbh, 1);
 	}
 }
 
@@ -800,29 +834,6 @@
 	if (!bh)
 		return NULL;
 
-#if 0
-	if (create &&
-		S_ISDIR(inode->i_mode) &&
-		inode->i_blocks > prev_blocks)
-	{
-		int i;
-		struct buffer_head *tmp_bh = NULL;
-
-		for (i=1;
-			i < UDF_DEFAULT_PREALLOC_DIR_BLOCKS;
-			i++)
-		{
-			tmp_bh = udf_getblk(inode, block+i, create, err);
-			if (!tmp_bh)
-			{
-				udf_release_data(bh);
-				return 0;
-			}
-			udf_release_data(tmp_bh);
-		}
-	}
-#endif
-
 	if (buffer_uptodate(bh))
 		return bh;
 	ll_rw_block(READ, 1, &bh);
@@ -834,6 +845,62 @@
 	return NULL;
 }
 
+void udf_truncate(struct inode * inode)
+{
+	int offset;
+	struct buffer_head *bh;
+	int err;
+
+	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+			S_ISLNK(inode->i_mode)))
+		return;
+	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+		return;
+
+	if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
+	{
+		if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) +
+			inode->i_size))
+		{
+			udf_expand_file_adinicb(inode, inode->i_size, &err);
+			if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
+			{
+				inode->i_size = UDF_I_LENALLOC(inode);
+				return;
+			}
+			else
+				udf_truncate_extents(inode);
+		}
+		else
+		{
+			offset = (inode->i_size & (inode->i_sb->s_blocksize - 1)) +
+				udf_file_entry_alloc_offset(inode);
+
+			if ((bh = udf_tread(inode->i_sb,
+				udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0),
+				inode->i_sb->s_blocksize)))
+			{
+				memset(bh->b_data + offset, 0x00, inode->i_sb->s_blocksize - offset);
+				mark_buffer_dirty(bh);
+				udf_release_data(bh);
+			}
+			UDF_I_LENALLOC(inode) = inode->i_size;
+		}
+	}
+	else
+	{
+		block_truncate_page(inode->i_mapping, inode->i_size, udf_get_block);
+		udf_truncate_extents(inode);
+	}	
+
+	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	UDF_I_UMTIME(inode) = UDF_I_UCTIME(inode) = CURRENT_UTIME;
+	if (IS_SYNC(inode))
+		udf_sync_inode (inode);
+	else
+		mark_inode_dirty(inode);
+}
+
 /*
  * udf_read_inode
  *
@@ -891,7 +958,8 @@
 		return;
 	}
 
-	if (ident != TID_FILE_ENTRY && ident != TID_EXTENDED_FILE_ENTRY)
+	if (ident != TID_FILE_ENTRY && ident != TID_EXTENDED_FILE_ENTRY &&
+		ident != TID_UNALLOCATED_SPACE_ENTRY)
 	{
 		printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed ident=%d\n",
 			inode->i_ino, ident);
@@ -969,16 +1037,24 @@
 	fe = (struct FileEntry *)bh->b_data;
 	efe = (struct ExtendedFileEntry *)bh->b_data;
 
-	if (fe->descTag.tagIdent == TID_EXTENDED_FILE_ENTRY)
-		UDF_I_EXTENDED_FE(inode) = 1;
-	else /* fe->descTag.tagIdent == TID_FILE_ENTRY */
-		UDF_I_EXTENDED_FE(inode) = 0;
-
 	if (le16_to_cpu(fe->icbTag.strategyType) == 4)
 		UDF_I_STRAT4096(inode) = 0;
 	else /* if (le16_to_cpu(fe->icbTag.strategyType) == 4096) */
 		UDF_I_STRAT4096(inode) = 1;
 
+	UDF_I_ALLOCTYPE(inode) = le16_to_cpu(fe->icbTag.flags) & ICB_FLAG_ALLOC_MASK;
+	if (fe->descTag.tagIdent == TID_EXTENDED_FILE_ENTRY)
+		UDF_I_EXTENDED_FE(inode) = 1;
+	else if (fe->descTag.tagIdent == TID_FILE_ENTRY)
+		UDF_I_EXTENDED_FE(inode) = 0;
+	else if (fe->descTag.tagIdent == TID_UNALLOCATED_SPACE_ENTRY)
+	{
+		UDF_I_LENALLOC(inode) =
+			le32_to_cpu(
+				((struct UnallocatedSpaceEntry *)bh->b_data)->lengthAllocDescs);
+		return;
+	}
+
 	inode->i_uid = le32_to_cpu(fe->uid);
 	if ( inode->i_uid == -1 ) inode->i_uid = UDF_SB(inode->i_sb)->s_uid;
 
@@ -990,6 +1066,7 @@
 		inode->i_nlink = 1;
 	
 	inode->i_size = le64_to_cpu(fe->informationLength);
+	UDF_I_LENEXTENTS(inode) = inode->i_size;
 
 	inode->i_mode = udf_convert_permissions(fe);
 	inode->i_mode &= ~UDF_SB(inode->i_sb)->s_umask;
@@ -997,8 +1074,6 @@
 	UDF_I_NEXT_ALLOC_BLOCK(inode) = 0;
 	UDF_I_NEXT_ALLOC_GOAL(inode) = 0;
 
-	UDF_I_ALLOCTYPE(inode) = le16_to_cpu(fe->icbTag.flags) & ICB_FLAG_ALLOC_MASK;
-
 	if (UDF_I_EXTENDED_FE(inode) == 0)
 	{
 		inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
@@ -1171,11 +1246,11 @@
 	flags = le16_to_cpu(fe->icbTag.flags);
 
 	mode =	(( permissions      ) & S_IRWXO) |
-			(( permissions >> 2 ) & S_IRWXG) |
-			(( permissions >> 4 ) & S_IRWXU) |
-			(( flags & ICB_FLAG_SETUID) ? S_ISUID : 0) |
-			(( flags & ICB_FLAG_SETGID) ? S_ISGID : 0) |
-			(( flags & ICB_FLAG_STICKY) ? S_ISVTX : 0);
+		(( permissions >> 2 ) & S_IRWXG) |
+		(( permissions >> 4 ) & S_IRWXU) |
+		(( flags & ICB_FLAG_SETUID) ? S_ISUID : 0) |
+		(( flags & ICB_FLAG_SETGID) ? S_ISGID : 0) |
+		(( flags & ICB_FLAG_STICKY) ? S_ISVTX : 0);
 
 	return mode;
 }
@@ -1221,8 +1296,9 @@
 	int err = 0;
 
 	bh = udf_tread(inode->i_sb,
-			udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0),
-			inode->i_sb->s_blocksize);
+		udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0),
+		inode->i_sb->s_blocksize);
+
 	if (!bh)
 	{
 		udf_debug("bread failure\n");
@@ -1233,7 +1309,7 @@
 	if (UDF_I_NEW_INODE(inode) == 1)
 	{
 		if (UDF_I_EXTENDED_FE(inode) == 0)
-			memset(bh->b_data, 0x0, sizeof(struct FileEntry));
+			memset(bh->b_data, 0x00, sizeof(struct FileEntry));
 		else
 			memset(bh->b_data, 0x00, sizeof(struct ExtendedFileEntry));
 		memset(bh->b_data + udf_file_entry_alloc_offset(inode) +
@@ -1242,20 +1318,41 @@
 		UDF_I_NEW_INODE(inode) = 0;
 	}
 
+	if (fe->descTag.tagIdent == TID_UNALLOCATED_SPACE_ENTRY)
+	{
+		struct UnallocatedSpaceEntry *use =
+			(struct UnallocatedSpaceEntry *)bh->b_data;
+
+		use->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
+		crclen = sizeof(struct UnallocatedSpaceEntry) + UDF_I_LENALLOC(inode) -
+			sizeof(tag);
+		use->descTag.descCRCLength = cpu_to_le16(crclen);
+		use->descTag.descCRC = cpu_to_le16(udf_crc((char *)use + sizeof(tag), crclen, 0));
+
+		use->descTag.tagChecksum = 0;
+		for (i=0; i<16; i++)
+			if (i != 4)
+				use->descTag.tagChecksum += ((Uint8 *)&(use->descTag))[i];
+
+		mark_buffer_dirty(bh);
+		udf_release_data(bh);
+		return err;
+	}
+
 	if (inode->i_uid != UDF_SB(inode->i_sb)->s_uid)
 		fe->uid = cpu_to_le32(inode->i_uid);
 
 	if (inode->i_gid != UDF_SB(inode->i_sb)->s_gid)
 		fe->gid = cpu_to_le32(inode->i_gid);
 
-	udfperms =  ((inode->i_mode & S_IRWXO)     ) |
-				((inode->i_mode & S_IRWXG) << 2) |
-				((inode->i_mode & S_IRWXU) << 4);
-
-	udfperms |= (le32_to_cpu(fe->permissions) &
-		(PERM_O_DELETE | PERM_O_CHATTR |
-		 PERM_G_DELETE | PERM_G_CHATTR |
-		 PERM_U_DELETE | PERM_U_CHATTR));
+	udfperms =	((inode->i_mode & S_IRWXO)     ) |
+			((inode->i_mode & S_IRWXG) << 2) |
+			((inode->i_mode & S_IRWXU) << 4);
+
+	udfperms |=	(le32_to_cpu(fe->permissions) &
+			(PERM_O_DELETE | PERM_O_CHATTR |
+			 PERM_G_DELETE | PERM_G_CHATTR |
+			 PERM_U_DELETE | PERM_U_CHATTR));
 	fe->permissions = cpu_to_le32(udfperms);
 
 	if (S_ISDIR(inode->i_mode))
@@ -1292,7 +1389,7 @@
 		eid->identSuffix[1] = UDF_OS_ID_LINUX;
 		dsea->majorDeviceIdent = kdev_t_to_nr(inode->i_rdev) >> 8;
 		dsea->minorDeviceIdent = kdev_t_to_nr(inode->i_rdev) & 0xFF;
-		mark_buffer_dirty(tbh);
+		mark_buffer_dirty_inode(tbh, inode);
 		udf_release_data(tbh);
 	}
 
@@ -1305,7 +1402,10 @@
 		if (udf_time_to_stamp(&cpu_time, inode->i_atime, UDF_I_UATIME(inode)))
 			fe->accessTime = cpu_to_lets(cpu_time);
 		if (udf_time_to_stamp(&cpu_time, inode->i_mtime, UDF_I_UMTIME(inode)))
+		{
 			fe->modificationTime = cpu_to_lets(cpu_time);
+			fe->attrTime = cpu_to_lets(cpu_time);
+		}
 		memset(&(fe->impIdent), 0, sizeof(EntityID));
 		strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER);
 		fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
@@ -1327,7 +1427,10 @@
 		if (udf_time_to_stamp(&cpu_time, inode->i_mtime, UDF_I_UMTIME(inode)))
 			efe->modificationTime = cpu_to_lets(cpu_time);
 		if (udf_time_to_stamp(&cpu_time, inode->i_ctime, UDF_I_UCTIME(inode)))
+		{
 			efe->createTime = cpu_to_lets(cpu_time);
+			efe->attrTime = cpu_to_lets(cpu_time);
+		}
 		memset(&(efe->impIdent), 0, sizeof(EntityID));
 		strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER);
 		efe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
@@ -1363,7 +1466,7 @@
 	else if (S_ISFIFO(inode->i_mode))
 		fe->icbTag.fileType = FILE_TYPE_FIFO;
 
-	icbflags = UDF_I_ALLOCTYPE(inode) |
+	icbflags =	UDF_I_ALLOCTYPE(inode) |
 			((inode->i_mode & S_ISUID) ? ICB_FLAG_SETUID : 0) |
 			((inode->i_mode & S_ISGID) ? ICB_FLAG_SETGID : 0) |
 			((inode->i_mode & S_ISVTX) ? ICB_FLAG_STICKY : 0) |
@@ -1444,12 +1547,19 @@
 	{
 		memcpy(&UDF_I_LOCATION(inode), &ino, sizeof(lb_addr));
 		__udf_read_inode(inode);
+		if (is_bad_inode(inode))
+		{
+			iput(inode);
+			return NULL;
+		}
 	}
 
 	if ( ino.logicalBlockNum >= UDF_SB_PARTLEN(sb, ino.partitionReferenceNum) )
 	{
 		udf_debug("block=%d, partition=%d out of range\n",
 			ino.logicalBlockNum, ino.partitionReferenceNum);
+		make_bad_inode(inode);
+		iput(inode);
 		return NULL;
  	}
 
@@ -1496,13 +1606,20 @@
 		{
 			return -1;
 		}
-		if (!(nbh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb,
+		if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb,
 			*bloc, 0), inode->i_sb->s_blocksize)))
 		{
 			return -1;
 		}
+		lock_buffer(nbh);
+		memset(nbh->b_data, 0x00, inode->i_sb->s_blocksize);
+		mark_buffer_uptodate(nbh, 1);
+		unlock_buffer(nbh);
+		mark_buffer_dirty_inode(nbh, inode);
+
 		aed = (struct AllocExtDesc *)(nbh->b_data);
-		aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum);
+		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
+			aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum);
 		if (*extoffset + adsize > inode->i_sb->s_blocksize)
 		{
 			loffset = *extoffset;
@@ -1551,16 +1668,20 @@
 					EXTENT_NEXT_EXTENT_ALLOCDECS << 30 |
 					inode->i_sb->s_blocksize);
 				lad->extLocation = cpu_to_lelb(*bloc);
+				memset(lad->impUse, 0x00, sizeof(lad->impUse));
 				break;
 			}
 		}
-		udf_update_tag((*bh)->b_data, loffset);
-		mark_buffer_dirty(*bh);
+		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
+			udf_update_tag((*bh)->b_data, loffset);
+		else
+			udf_update_tag((*bh)->b_data, sizeof(struct AllocExtDesc));
+		mark_buffer_dirty_inode(*bh, inode);
 		udf_release_data(*bh);
 		*bh = nbh;
 	}
 
-	ret = udf_write_aext(inode, *bloc, extoffset, eloc, elen, bh, inc);
+	ret = udf_write_aext(inode, *bloc, extoffset, eloc, elen, *bh, inc);
 
 	if (!memcmp(&UDF_I_LOCATION(inode), bloc, sizeof(lb_addr)))
 	{
@@ -1572,23 +1693,26 @@
 		aed = (struct AllocExtDesc *)(*bh)->b_data;
 		aed->lengthAllocDescs =
 			cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
-		udf_update_tag((*bh)->b_data, *extoffset + (inc ? 0 : adsize));
-		mark_buffer_dirty(*bh);
+		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
+			udf_update_tag((*bh)->b_data, *extoffset + (inc ? 0 : adsize));
+		else
+			udf_update_tag((*bh)->b_data, sizeof(struct AllocExtDesc));
+		mark_buffer_dirty_inode(*bh, inode);
 	}
 
 	return ret;
 }
 
 int udf_write_aext(struct inode *inode, lb_addr bloc, int *extoffset,
-    lb_addr eloc, Uint32 elen, struct buffer_head **bh, int inc)
+    lb_addr eloc, Uint32 elen, struct buffer_head *bh, int inc)
 {
 	int adsize;
 	short_ad *sad = NULL;
 	long_ad *lad = NULL;
 
-	if (!(*bh))
+	if (!(bh))
 	{
-		if (!(*bh = udf_tread(inode->i_sb,
+		if (!(bh = udf_tread(inode->i_sb,
 			udf_get_lb_pblock(inode->i_sb, bloc, 0),
 			inode->i_sb->s_blocksize)))
 		{
@@ -1597,6 +1721,8 @@
 			return -1;
 		}
 	}
+	else
+		atomic_inc(&bh->b_count);
 
 	if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)
 		adsize = sizeof(short_ad);
@@ -1609,39 +1735,47 @@
 	{
 		case ICB_FLAG_AD_SHORT:
 		{
-			sad = (short_ad *)((*bh)->b_data + *extoffset);
+			sad = (short_ad *)((bh)->b_data + *extoffset);
 			sad->extLength = cpu_to_le32(elen);
 			sad->extPosition = cpu_to_le32(eloc.logicalBlockNum);
 			break;
 		}
 		case ICB_FLAG_AD_LONG:
 		{
-			lad = (long_ad *)((*bh)->b_data + *extoffset);
+			lad = (long_ad *)((bh)->b_data + *extoffset);
 			lad->extLength = cpu_to_le32(elen);
 			lad->extLocation = cpu_to_lelb(eloc);
+			memset(lad->impUse, 0x00, sizeof(lad->impUse));
 			break;
 		}
 	}
 
 	if (memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr)))
 	{
-		struct AllocExtDesc *aed = (struct AllocExtDesc *)(*bh)->b_data;
-		udf_update_tag((*bh)->b_data,
-			le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct AllocExtDesc));
+		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
+		{
+			struct AllocExtDesc *aed = (struct AllocExtDesc *)(bh)->b_data;
+			udf_update_tag((bh)->b_data,
+				le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct AllocExtDesc));
+		}
+		mark_buffer_dirty_inode(bh, inode);
 	}
 	else
+	{
 		mark_inode_dirty(inode);
-
-	mark_buffer_dirty(*bh);
+		mark_buffer_dirty(bh);
+	}
 
 	if (inc)
 		*extoffset += adsize;
+	udf_release_data(bh);
 	return (elen >> 30);
 }
 
 int udf_next_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
 	lb_addr *eloc, Uint32 *elen, struct buffer_head **bh, int inc)
 {
+	Uint16 tagIdent;
 	int pos, alen;
 	Uint8 etype;
 
@@ -1657,18 +1791,33 @@
 		}
 	}
 
+	tagIdent = ((tag *)(*bh)->b_data)->tagIdent;
+
 	if (!memcmp(&UDF_I_LOCATION(inode), bloc, sizeof(lb_addr)))
 	{
-		pos = udf_file_entry_alloc_offset(inode);
-		alen = UDF_I_LENALLOC(inode) + pos;
+		if (tagIdent == TID_FILE_ENTRY || tagIdent == TID_EXTENDED_FILE_ENTRY ||
+			UDF_I_NEW_INODE(inode))
+		{
+			pos = udf_file_entry_alloc_offset(inode);
+			alen = UDF_I_LENALLOC(inode) + pos;
+		}
+		else if (tagIdent == TID_UNALLOCATED_SPACE_ENTRY)
+		{
+			pos = sizeof(struct UnallocatedSpaceEntry);
+			alen = UDF_I_LENALLOC(inode) + pos;
+		}
+		else
+			return -1;
 	}
-	else
+	else if (tagIdent == TID_ALLOC_EXTENT_DESC)
 	{
 		struct AllocExtDesc *aed = (struct AllocExtDesc *)(*bh)->b_data;
 
 		pos = sizeof(struct AllocExtDesc);
 		alen = le32_to_cpu(aed->lengthAllocDescs) + pos;
 	}
+	else
+		return -1;
 
 	if (!(*extoffset))
 		*extoffset = pos;
@@ -1829,7 +1978,7 @@
 }
 
 int udf_insert_aext(struct inode *inode, lb_addr bloc, int extoffset,
-    lb_addr neloc, Uint32 nelen, struct buffer_head *bh)
+	lb_addr neloc, Uint32 nelen, struct buffer_head *bh)
 {
 	lb_addr oeloc;
 	Uint32 oelen;
@@ -1851,7 +2000,7 @@
 
 	while ((type = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1)
 	{
-		udf_write_aext(inode, bloc, &extoffset, neloc, nelen, &bh, 1);
+		udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
 
 		neloc = oeloc;
 		nelen = (type << 30) | oelen;
@@ -1867,7 +2016,7 @@
 	struct buffer_head *obh;
 	lb_addr obloc;
 	int oextoffset, adsize;
-	int type;
+	char type;
 	struct AllocExtDesc *aed;
 
 	if (!(nbh))
@@ -1901,7 +2050,7 @@
 
 	while ((type = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)
 	{
-		udf_write_aext(inode, obloc, &oextoffset, eloc, (type << 30) | elen, &obh, 1);
+		udf_write_aext(inode, obloc, &oextoffset, eloc, (type << 30) | elen, obh, 1);
 		if (memcmp(&nbloc, &obloc, sizeof(lb_addr)))
 		{
 			obloc = nbloc;
@@ -1917,8 +2066,8 @@
 	if (memcmp(&nbloc, &obloc, sizeof(lb_addr)))
 	{
 		udf_free_blocks(inode, nbloc, 0, 1);
-		udf_write_aext(inode, obloc, &oextoffset, eloc, elen, &obh, 1);
-		udf_write_aext(inode, obloc, &oextoffset, eloc, elen, &obh, 1);
+		udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
+		udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
 		if (!memcmp(&UDF_I_LOCATION(inode), &obloc, sizeof(lb_addr)))
 		{
 			UDF_I_LENALLOC(inode) -= (adsize * 2);
@@ -1929,13 +2078,16 @@
 			aed = (struct AllocExtDesc *)(obh)->b_data;
 			aed->lengthAllocDescs =
 				cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize));
-			udf_update_tag((obh)->b_data, oextoffset - (2*adsize));
-			mark_buffer_dirty(obh);
+			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
+				udf_update_tag((obh)->b_data, oextoffset - (2*adsize));
+			else
+				udf_update_tag((obh)->b_data, sizeof(struct AllocExtDesc));
+			mark_buffer_dirty_inode(obh, inode);
 		}
 	}
 	else
 	{
-		udf_write_aext(inode, obloc, &oextoffset, eloc, elen, &obh, 1);
+		udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
 		if (!memcmp(&UDF_I_LOCATION(inode), &obloc, sizeof(lb_addr)))
 		{
 			UDF_I_LENALLOC(inode) -= adsize;
@@ -1946,8 +2098,11 @@
 			aed = (struct AllocExtDesc *)(obh)->b_data;
 			aed->lengthAllocDescs =
 				cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize);
-			udf_update_tag((obh)->b_data, oextoffset - adsize);
-			mark_buffer_dirty(obh);
+			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
+				udf_update_tag((obh)->b_data, oextoffset - adsize);
+			else
+				udf_update_tag((obh)->b_data, sizeof(struct AllocExtDesc));
+			mark_buffer_dirty_inode(obh, inode);
 		}
 	}
 	
@@ -1959,7 +2114,8 @@
 int inode_bmap(struct inode *inode, int block, lb_addr *bloc, Uint32 *extoffset,
 	lb_addr *eloc, Uint32 *elen, Uint32 *offset, struct buffer_head **bh)
 {
-	int etype, lbcount = 0;
+	Uint64 lbcount = 0, bcount = block << inode->i_sb->s_blocksize_bits;
+	char etype;
 
 	if (block < 0)
 	{
@@ -1980,31 +2136,34 @@
 	{
 		if ((etype = udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, 1)) == -1)
 		{
-			*offset = block - lbcount;
+			*offset = bcount - lbcount;
+			UDF_I_LENEXTENTS(inode) = lbcount;
 			return -1;
 		}
-		lbcount += ((*elen + inode->i_sb->s_blocksize - 1) >>
-			inode->i_sb->s_blocksize_bits);
-	} while (lbcount <= block);
+		lbcount += *elen;
+	} while (lbcount <= bcount);
 
-	*offset = block + ((*elen + inode->i_sb->s_blocksize - 1) >>
-		inode->i_sb->s_blocksize_bits) - lbcount;
+	*offset = bcount + *elen - lbcount;
 
 	return etype;
 }
 
-long udf_locked_block_map(struct inode *inode, long block)
+long udf_block_map(struct inode *inode, long block)
 {
 	lb_addr eloc, bloc;
 	Uint32 offset, extoffset, elen;
 	struct buffer_head *bh = NULL;
 	int ret;
 
+	lock_kernel();
+
 	if (inode_bmap(inode, block, &bloc, &extoffset, &eloc, &elen, &offset, &bh) == EXTENT_RECORDED_ALLOCATED)
-		ret = udf_get_lb_pblock(inode->i_sb, eloc, offset);
+		ret = udf_get_lb_pblock(inode->i_sb, eloc, offset >> inode->i_sb->s_blocksize_bits);
 	else
 		ret = 0;
 
+	unlock_kernel();
+
 	if (bh)
 		udf_release_data(bh);
 
@@ -2012,14 +2171,4 @@
 		return udf_fixed_to_variable(ret);
 	else
 		return ret;
-}
-
-long udf_block_map(struct inode *inode, long block)
-{
-	int ret;
-
-	lock_kernel();
-	ret = udf_locked_block_map(inode, block);
-	unlock_kernel();
-	return ret;
 }
diff -u --recursive --new-file v2.4.5/linux/fs/udf/lowlevel.c linux/fs/udf/lowlevel.c
--- v2.4.5/linux/fs/udf/lowlevel.c	Mon Mar 20 08:17:43 2000
+++ linux/fs/udf/lowlevel.c	Mon Jun 11 19:15:27 2001
@@ -7,7 +7,7 @@
  * CONTACTS
  *	E-mail regarding any portion of the Linux UDF file system should be
  *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hootie.lvld.hp.com
+ *		linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
diff -u --recursive --new-file v2.4.5/linux/fs/udf/misc.c linux/fs/udf/misc.c
--- v2.4.5/linux/fs/udf/misc.c	Mon Mar 20 08:17:43 2000
+++ linux/fs/udf/misc.c	Mon Jun 11 19:15:27 2001
@@ -7,7 +7,7 @@
  * CONTACTS
  *	E-mail regarding any portion of the Linux UDF file system should be
  *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hootie.lvld.hp.com
+ *		linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
@@ -67,6 +67,15 @@
 #if defined(__linux__) && defined(__KERNEL__)
 
 extern struct buffer_head *
+udf_tgetblk(struct super_block *sb, int block, int size)
+{
+	if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV))
+		return getblk(sb->s_dev, udf_fixed_to_variable(block), size);
+	else
+		return getblk(sb->s_dev, block, size);
+}
+
+extern struct buffer_head *
 udf_tread(struct super_block *sb, int block, int size)
 {
 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV))
@@ -309,7 +318,7 @@
 
 	if ( location != le32_to_cpu(tag_p->tagLocation) )
 	{
-		udf_debug("location mismatch block %d, tag %d != %d\n",
+		udf_debug("location mismatch block %u, tag %u != %u\n",
 			block, le32_to_cpu(tag_p->tagLocation), location);
 		goto error_out;
 	}
@@ -424,32 +433,35 @@
 
 	if ( size < udf_blocksize )
 	{
-		udf_errno=3;
+		udf_errno = 3;
 		return -1;
 	}
-	udf_errno=0;
+	udf_errno = 0;
 	
-	offs=(long)block * udf_blocksize;
-	if ( lseek(fd, offs, SEEK_SET) != offs ) {
-		udf_errno=4;
+	offs = (long)block * udf_blocksize;
+	if ( lseek(fd, offs, SEEK_SET) != offs )
+	{
+		udf_errno = 4;
 		return -1;
 	}
 
-	i=read(fd, buffer, udf_blocksize);
-	if ( i < udf_blocksize ) {
-		udf_errno=5;
+	i = read(fd, buffer, udf_blocksize);
+	if ( i < udf_blocksize )
+	{
+		udf_errno = 5;
 		return -1;
 	}
 
 	tag_p = (tag *)(buffer);
 
 	/* Verify the tag location */
-	if ((block-offset) != tag_p->tagLocation) {
+	if ((block-offset) != tag_p->tagLocation)
+	{
 #ifdef __KERNEL__
 		printk(KERN_ERR "udf: location mismatch block %d, tag %d\n",
 			block, tag_p->tagLocation);
 #else
-		udf_errno=6;
+		udf_errno = 6;
 #endif
 		goto error_out;
 	}
@@ -460,35 +472,38 @@
 		checksum += (Uint8)(buffer[i]);
 	for (i = 5; i < 16; i++)
 		checksum += (Uint8)(buffer[i]);
-	if (checksum != tag_p->tagChecksum) {
+	if (checksum != tag_p->tagChecksum)
+	{
 #ifdef __KERNEL__
 		printk(KERN_ERR "udf: tag checksum failed\n");
 #else
-		udf_errno=7;
+		udf_errno = 7;
 #endif
 		goto error_out;
 	}
 
 	/* Verify the tag version */
-	if (tag_p->descVersion != 0x0002U) {
+	if (tag_p->descVersion != 0x0002U)
+	{
 #ifdef __KERNEL__
 		printk(KERN_ERR "udf: tag version 0x%04x != 0x0002U\n",
 			tag_p->descVersion);
 #else
-		udf_errno=8;
+		udf_errno = 8;
 #endif
 		goto error_out;
 	}
 
 	/* Verify the descriptor CRC */
-	if (tag_p->descCRC == udf_crc(buffer + 16, tag_p->descCRCLength, 0)) {
-		udf_errno=0;
+	if (tag_p->descCRC == udf_crc(buffer + 16, tag_p->descCRCLength, 0))
+	{
+		udf_errno = 0;
 		return 0;
 	}
 #ifdef __KERNEL__
 	printk(KERN_ERR "udf: crc failure in udf_read_tagged\n");
 #else
-	udf_errno=9;
+	udf_errno = 9;
 #endif
 
 error_out:
diff -u --recursive --new-file v2.4.5/linux/fs/udf/namei.c linux/fs/udf/namei.c
--- v2.4.5/linux/fs/udf/namei.c	Fri Feb  9 11:29:44 2001
+++ linux/fs/udf/namei.c	Mon Jun 11 19:15:27 2001
@@ -7,7 +7,7 @@
  * CONTACTS
  *      E-mail regarding any portion of the Linux UDF file system should be
  *      directed to the development team mailing list (run by majordomo):
- *              linux_udf@hootie.lvld.hp.com
+ *              linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *      This file is distributed under the terms of the GNU General Public
@@ -33,6 +33,8 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/quotaops.h>
+#include <linux/locks.h>
+#include <linux/smp_lock.h>
 #include <linux/udf_fs.h>
 
 static inline int udf_match(int len, const char * const name, struct qstr *qs)
@@ -42,8 +44,8 @@
 	return !memcmp(name, qs->name, len);
 }
 
-int udf_write_fi(struct FileIdentDesc *cfi, struct FileIdentDesc *sfi,
-	struct udf_fileident_bh *fibh,
+int udf_write_fi(struct inode *inode, struct FileIdentDesc *cfi,
+	struct FileIdentDesc *sfi, struct udf_fileident_bh *fibh,
 	Uint8 *impuse, Uint8 *fileident)
 {
 	Uint16 crclen = fibh->eoffset - fibh->soffset - sizeof(tag);
@@ -56,7 +58,6 @@
 	int padlen = fibh->eoffset - fibh->soffset - liu - lfi -
 		sizeof(struct FileIdentDesc);
 
-
 	offset = fibh->soffset + sizeof(struct FileIdentDesc);
 
 	if (impuse)
@@ -133,8 +134,8 @@
 	}
 
 	if (fibh->sbh != fibh->ebh)
-		mark_buffer_dirty(fibh->ebh);
-	mark_buffer_dirty(fibh->sbh);
+		mark_buffer_dirty_inode(fibh->ebh, inode);
+	mark_buffer_dirty_inode(fibh->sbh, inode);
 	return 0;
 }
 
@@ -164,6 +165,7 @@
 	if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
 		&bloc, &extoffset, &eloc, &elen, &offset, &bh) == EXTENT_RECORDED_ALLOCATED)
 	{
+		offset >>= dir->i_sb->s_blocksize_bits;
 		block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
 		if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
 		{
@@ -238,7 +240,7 @@
 		if (!lfi)
 			continue;
 
-		if ((flen = udf_get_filename(nameptr, fname, lfi)))
+		if ((flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi)))
 		{
 			if (udf_match(flen, fname, &(dentry->d_name)))
 			{
@@ -348,28 +350,41 @@
 
 	if (dentry)
 	{
-		if ( !(udf_char_to_ustr(&unifilename, dentry->d_name.name, dentry->d_name.len)) )
+		if (!dentry->d_name.len)
 		{
-			*err = -ENAMETOOLONG;
+			*err = -EINVAL;
 			return NULL;
 		}
 
-		if ( !(namelen = udf_UTF8toCS0(name, &unifilename, UDF_NAME_LEN)) )
+		if ( !(udf_char_to_ustr(&unifilename, dentry->d_name.name, dentry->d_name.len)) )
 		{
 			*err = -ENAMETOOLONG;
 			return NULL;
 		}
+
+		if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8))
+		{
+			if ( !(namelen = udf_UTF8toCS0(name, &unifilename, UDF_NAME_LEN)) )
+			{
+				*err = -ENAMETOOLONG;
+				return NULL;
+			}
+		}
+		else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
+		{
+			if ( !(namelen = udf_NLStoCS0(UDF_SB(sb)->s_nls_map, name, &unifilename, UDF_NAME_LEN)) )
+			{
+				*err = -ENAMETOOLONG;
+				return NULL;
+			}
+		}
+		else
+			return NULL;
 	}
-	else if (dir->i_size != 0)
-	{
-		/* WTF??? */
-		*err = -ENOENT;
-		return NULL;
-	}
-	else /* .. */
+	else
 		namelen = 0;
 
-	nfidlen = (sizeof(struct FileIdentDesc) + 0 + namelen + 3) & ~3;
+	nfidlen = (sizeof(struct FileIdentDesc) + namelen + 3) & ~3;
 
 	f_pos = (udf_ext0_offset(dir) >> 2);
 
@@ -377,6 +392,7 @@
 	if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
 		&bloc, &extoffset, &eloc, &elen, &offset, &bh) == EXTENT_RECORDED_ALLOCATED)
 	{
+		offset >>= dir->i_sb->s_blocksize_bits;
 		block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
 		if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
 		{
@@ -391,6 +407,7 @@
 		if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize)))
 		{
 			udf_release_data(bh);
+			*err = -EIO;
 			return NULL;
 		}
 	
@@ -406,6 +423,7 @@
 					udf_release_data(fibh->ebh);
 				udf_release_data(fibh->sbh);
 				udf_release_data(bh);
+				*err = -EIO;
 				return NULL;
 			}
 	
@@ -440,18 +458,22 @@
 					cfi->fileCharacteristics = 0;
 					cfi->lengthFileIdent = namelen;
 					cfi->lengthOfImpUse = cpu_to_le16(0);
-					if (!udf_write_fi(cfi, fi, fibh, NULL, name))
+					if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name))
 						return fi;
 					else
+					{
+						*err = -EIO;
 						return NULL;
+					}
 				}
 			}
-	
+
 			if (!lfi || !dentry)
 				continue;
-	
-			if ((flen = udf_get_filename(nameptr, fname, lfi)) &&
-			    udf_match(flen, fname, &(dentry->d_name))) {
+
+			if ((flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi)) &&
+				udf_match(flen, fname, &(dentry->d_name)))
+			{
 				if (fibh->sbh != fibh->ebh)
 					udf_release_data(fibh->ebh);
 				udf_release_data(fibh->sbh);
@@ -533,7 +555,6 @@
 		block = eloc.logicalBlockNum + ((elen - 1) >>
 			dir->i_sb->s_blocksize_bits);
 
-		*err = -ENOSPC;
 		if (!(fibh->ebh = udf_bread(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), 1, err)))
 		{
 			udf_release_data(bh);
@@ -568,7 +589,7 @@
 	cfi->fileVersionNum = cpu_to_le16(1);
 	cfi->lengthFileIdent = namelen;
 	cfi->lengthOfImpUse = cpu_to_le16(0);
-	if (!udf_write_fi(cfi, fi, fibh, NULL, name))
+	if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name))
 	{
 		udf_release_data(bh);
 		dir->i_size += nfidlen;
@@ -584,16 +605,18 @@
 		if (fibh->sbh != fibh->ebh)
 			udf_release_data(fibh->ebh);
 		udf_release_data(fibh->sbh);
+		*err = -EIO;
 		return NULL;
 	}
 }
 
-static int udf_delete_entry(struct FileIdentDesc *fi,
-	struct udf_fileident_bh *fibh,
-	struct FileIdentDesc *cfi)
+static int udf_delete_entry(struct inode *inode, struct FileIdentDesc *fi,
+	struct udf_fileident_bh *fibh, struct FileIdentDesc *cfi)
 {
 	cfi->fileCharacteristics |= FILE_DELETED;
-	return udf_write_fi(cfi, fi, fibh, NULL, NULL);
+	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
+		memset(&(cfi->icb), 0x00, sizeof(long_ad));
+	return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL);
 }
 
 static int udf_create(struct inode *dir, struct dentry *dentry, int mode)
@@ -627,7 +650,7 @@
 	cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
 	*(Uint32 *)((struct ADImpUse *)cfi.icb.impUse)->impUse =
 		cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
-	udf_write_fi(&cfi, fi, &fibh, NULL, NULL);
+	udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
 	if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB)
 	{
 		mark_inode_dirty(dir);
@@ -665,7 +688,7 @@
 	cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
 	*(Uint32 *)((struct ADImpUse *)cfi.icb.impUse)->impUse =
 		cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
-	udf_write_fi(&cfi, fi, &fibh, NULL, NULL);
+	udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
 	if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB)
 	{
 		mark_inode_dirty(dir);
@@ -700,7 +723,6 @@
 
 	inode->i_op = &udf_dir_inode_operations;
 	inode->i_fop = &udf_dir_operations;
-	inode->i_size = 0;
 	if (!(fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err)))
 	{
 		inode->i_nlink--;
@@ -714,7 +736,7 @@
 	*(Uint32 *)((struct ADImpUse *)cfi.icb.impUse)->impUse =
 		cpu_to_le32(UDF_I_UNIQUE(dir) & 0x00000000FFFFFFFFUL);
 	cfi.fileCharacteristics = FILE_DIRECTORY | FILE_PARENT;
-	udf_write_fi(&cfi, fi, &fibh, NULL, NULL);
+	udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL);
 	udf_release_data(fibh.sbh);
 	inode->i_mode = S_IFDIR | mode;
 	if (dir->i_mode & S_ISGID)
@@ -733,7 +755,7 @@
 	*(Uint32 *)((struct ADImpUse *)cfi.icb.impUse)->impUse =
 		cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
 	cfi.fileCharacteristics |= FILE_DIRECTORY;
-	udf_write_fi(&cfi, fi, &fibh, NULL, NULL);
+	udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
 	dir->i_version = ++event;
 	dir->i_nlink++;
 	mark_inode_dirty(dir);
@@ -763,6 +785,7 @@
 	if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
 		&bloc, &extoffset, &eloc, &elen, &offset, &bh) == EXTENT_RECORDED_ALLOCATED)
 	{
+		offset >>= dir->i_sb->s_blocksize_bits;
 		block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
 		if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
 		{
@@ -830,7 +853,7 @@
 	retval = -ENOTEMPTY;
 	if (!empty_dir(inode))
 		goto end_rmdir;
-	retval = udf_delete_entry(fi, &fibh, &cfi);
+	retval = udf_delete_entry(dir, fi, &fibh, &cfi);
 	dir->i_version = ++event;
 	if (retval)
 		goto end_rmdir;
@@ -885,7 +908,7 @@
 			inode->i_ino, inode->i_nlink);
 		inode->i_nlink = 1;
 	}
-	retval = udf_delete_entry(fi, &fibh, &cfi);
+	retval = udf_delete_entry(dir, fi, &fibh, &cfi);
 	if (retval)
 		goto end_unlink;
 	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
@@ -940,6 +963,7 @@
 		eloc.logicalBlockNum = block;
 		eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
 		elen = inode->i_sb->s_blocksize;
+		UDF_I_LENEXTENTS(inode) = elen;
 		extoffset = udf_file_entry_alloc_offset(inode);
 		udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 0);
 		udf_release_data(bh);
@@ -947,11 +971,18 @@
 		inode->i_blocks = inode->i_sb->s_blocksize / 512;
 		block = udf_get_pblock(inode->i_sb, block,
 			UDF_I_LOCATION(inode).partitionReferenceNum, 0);
+		bh = udf_tread(inode->i_sb, block, inode->i_sb->s_blocksize);
+		lock_buffer(bh);
+		memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);
+		mark_buffer_uptodate(bh, 1);
+		unlock_buffer(bh);
+		mark_buffer_dirty_inode(bh, inode);
 	}
 	else
+	{
 		block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0);
-
-	bh = udf_tread(inode->i_sb, block, inode->i_sb->s_blocksize);
+		bh = udf_tread(inode->i_sb, block, inode->i_sb->s_blocksize);
+	}
 	ea = bh->b_data + udf_ext0_offset(inode);
 
 	eoffset = inode->i_sb->s_blocksize - udf_ext0_offset(inode);
@@ -1042,7 +1073,7 @@
 		lvhd->uniqueID = cpu_to_le64(uniqueID);
 		mark_buffer_dirty(UDF_SB_LVIDBH(inode->i_sb));
 	}
-	udf_write_fi(&cfi, fi, &fibh, NULL, NULL);
+	udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
 	if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB)
 	{
 		mark_inode_dirty(dir);
@@ -1095,7 +1126,7 @@
 		lvhd->uniqueID = cpu_to_le64(uniqueID);
 		mark_buffer_dirty(UDF_SB_LVIDBH(inode->i_sb));
 	}
-	udf_write_fi(&cfi, fi, &fibh, NULL, NULL);
+	udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
 	if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB)
 	{
 		mark_inode_dirty(dir);
@@ -1126,7 +1157,12 @@
 	int retval = -ENOENT;
 
 	old_inode = old_dentry->d_inode;
-	ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi);
+	if ((ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi)))
+	{
+		if (ofibh.sbh != ofibh.ebh)
+			udf_release_data(ofibh.ebh);
+		udf_release_data(ofibh.sbh);
+	}
 	if (!ofi || udf_get_lb_pblock(old_dir->i_sb, lelb_to_cpu(ocfi.icb.extLocation), 0) !=
 		old_inode->i_ino)
 	{
@@ -1197,9 +1233,11 @@
 	ncfi.fileVersionNum = ocfi.fileVersionNum;
 	ncfi.fileCharacteristics = ocfi.fileCharacteristics;
 	memcpy(&(ncfi.icb), &(ocfi.icb), sizeof(long_ad));
-	udf_write_fi(&ncfi, nfi, &nfibh, NULL, NULL);
+	udf_write_fi(new_dir, &ncfi, nfi, &nfibh, NULL, NULL);
 
-	udf_delete_entry(ofi, &ofibh, &ocfi);
+	/* The old fid may have moved - find it again */
+	ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi);
+	udf_delete_entry(old_dir, ofi, &ofibh, &ocfi);
 
 	old_dir->i_version = ++event;
 	if (new_inode)
@@ -1216,15 +1254,15 @@
 	if (dir_bh)
 	{
 		dir_fi->icb.extLocation = lelb_to_cpu(UDF_I_LOCATION(new_dir));
-		udf_update_tag((char *)dir_fi, sizeof(struct FileIdentDesc) +
-			cpu_to_le16(dir_fi->lengthOfImpUse));
+		udf_update_tag((char *)dir_fi, (sizeof(struct FileIdentDesc) +
+			cpu_to_le16(dir_fi->lengthOfImpUse) + 3) & ~3);
 		if (UDF_I_ALLOCTYPE(old_inode) == ICB_FLAG_AD_IN_ICB)
 		{
 			mark_inode_dirty(old_inode);
 			old_inode->i_version = ++event;
 		}
 		else
-			mark_buffer_dirty(dir_bh);
+			mark_buffer_dirty_inode(dir_bh, old_inode);
 		old_dir->i_nlink --;
 		mark_inode_dirty(old_dir);
 		if (new_inode)
@@ -1239,16 +1277,17 @@
 		}
 	}
 
-	retval = 0;
-
-end_rename:
-	udf_release_data(dir_bh);
 	if (ofi)
 	{
 		if (ofibh.sbh != ofibh.ebh)
 			udf_release_data(ofibh.ebh);
 		udf_release_data(ofibh.sbh);
 	}
+
+	retval = 0;
+
+end_rename:
+	udf_release_data(dir_bh);
 	if (nfi)
 	{
 		if (nfibh.sbh != nfibh.ebh)
diff -u --recursive --new-file v2.4.5/linux/fs/udf/partition.c linux/fs/udf/partition.c
--- v2.4.5/linux/fs/udf/partition.c	Fri Apr 13 20:26:07 2001
+++ linux/fs/udf/partition.c	Mon Jun 11 19:15:27 2001
@@ -7,7 +7,7 @@
  * CONTACTS
  *      E-mail regarding any portion of the Linux UDF file system should be
  *      directed to the development team mailing list (run by majordomo):
- *              linux_udf@hootie.lvld.hp.com
+ *              linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *      This file is distributed under the terms of the GNU General Public
@@ -74,7 +74,7 @@
 		index = UDF_SB_TYPEVIRT(sb,partition).s_start_offset / sizeof(Uint32) + block;
 	}
 
-	loc = udf_locked_block_map(UDF_SB_VAT(sb), newblock);
+	loc = udf_block_map(UDF_SB_VAT(sb), newblock);
 
 	if (!(bh = bread(sb->s_dev, loc, sb->s_blocksize)))
 	{
@@ -103,135 +103,123 @@
 
 Uint32 udf_get_pblock_spar15(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset)
 {
-	Uint32 packet = (block + offset) >> UDF_SB_TYPESPAR(sb,partition).s_spar_pshift;
-	Uint32 index = 0;
-
-	if (UDF_SB_TYPESPAR(sb,partition).s_spar_indexsize == 8)
-		index = UDF_SB_TYPESPAR(sb,partition).s_spar_remap.s_spar_remap8[packet];
-	else if (UDF_SB_TYPESPAR(sb,partition).s_spar_indexsize == 16)
-		index = UDF_SB_TYPESPAR(sb,partition).s_spar_remap.s_spar_remap16[packet];
-	else if (UDF_SB_TYPESPAR(sb,partition).s_spar_indexsize == 32)
-		index = UDF_SB_TYPESPAR(sb,partition).s_spar_remap.s_spar_remap32[packet];
-
-	if (index == ((1 << UDF_SB_TYPESPAR(sb,partition).s_spar_indexsize)-1))
-		return UDF_SB_PARTROOT(sb,partition) + block + offset;
-
-	packet = UDF_SB_TYPESPAR(sb,partition).s_spar_map[index];
-	return packet + ((block + offset) & ((1 << UDF_SB_TYPESPAR(sb,partition).s_spar_pshift)-1));
-}
-
-void udf_fill_spartable(struct super_block *sb, struct udf_sparing_data *sdata, int partlen)
-{
-	Uint16 ident;
-	Uint32 spartable;
 	int i;
-	struct buffer_head *bh;
-	struct SparingTable *st;
+	struct SparingTable *st = NULL;
+	Uint32 packet = (block + offset) & ~(UDF_SB_TYPESPAR(sb,partition).s_packet_len - 1);
 
 	for (i=0; i<4; i++)
 	{
-		if (!(spartable = sdata->s_spar_loc[i]))
-			continue;
-
-		bh = udf_read_tagged(sb, spartable, spartable, &ident);
-
-		if (!bh)
+		if (UDF_SB_TYPESPAR(sb,partition).s_spar_map[i] != NULL)
 		{
-			sdata->s_spar_loc[i] = 0;
-			continue;
+			st = (struct SparingTable *)UDF_SB_TYPESPAR(sb,partition).s_spar_map[i]->b_data;
+			break;
 		}
+	}
 
-		if (ident == 0)
+	if (st)
+	{
+		for (i=0; i<st->reallocationTableLen; i++)
 		{
-			st = (struct SparingTable *)bh->b_data;
-			if (!strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING)))
+			if (le32_to_cpu(st->mapEntry[i].origLocation) >= 0xFFFFFFF0)
+				break;
+			else if (le32_to_cpu(st->mapEntry[i].origLocation) == packet)
 			{
-				SparingEntry *se;
-				Uint16 rtl = le16_to_cpu(st->reallocationTableLen);
-				int index;
+				return le32_to_cpu(st->mapEntry[i].mappedLocation) +
+					((block + offset) & (UDF_SB_TYPESPAR(sb,partition).s_packet_len - 1));
+			}
+			else if (le32_to_cpu(st->mapEntry[i].origLocation) > packet)
+				break;
+		}
+	}
+	return UDF_SB_PARTROOT(sb,partition) + block + offset;
+}
 
-				if (!sdata->s_spar_map)
+int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
+{
+	struct udf_sparing_data *sdata;
+	struct SparingTable *st = NULL;
+	SparingEntry mapEntry;
+	Uint32 packet;
+	int i, j, k, l;
+
+	for (i=0; i<UDF_SB_NUMPARTS(sb); i++)
+	{
+		if (old_block > UDF_SB_PARTROOT(sb,i) &&
+		    old_block < UDF_SB_PARTROOT(sb,i) + UDF_SB_PARTLEN(sb,i))
+		{
+			sdata = &UDF_SB_TYPESPAR(sb,i);
+			packet = (old_block - UDF_SB_PARTROOT(sb,i)) & ~(sdata->s_packet_len - 1);
+
+			for (j=0; j<4; j++)
+			{
+				if (UDF_SB_TYPESPAR(sb,i).s_spar_map[j] != NULL)
 				{
-					int num = 1, mapsize;
-					sdata->s_spar_indexsize = 8;
-					while (rtl*sizeof(Uint32) >= (1 << sdata->s_spar_indexsize))
-					{
-						num ++;
-						sdata->s_spar_indexsize <<= 1;
-					}
-					mapsize = (rtl * sizeof(Uint32)) +
-						((partlen/(1 << sdata->s_spar_pshift)) * sizeof(Uint8) * num);
-					sdata->s_spar_map = kmalloc(mapsize, GFP_KERNEL);
-					if (!sdata->s_spar_map) {
-						printk("couldnt allocate UDF s_spar_map!\n");
-						return;
-					}
-					sdata->s_spar_remap.s_spar_remap32 = &sdata->s_spar_map[rtl];
-					memset(sdata->s_spar_map, 0xFF, mapsize);
+					st = (struct SparingTable *)sdata->s_spar_map[j]->b_data;
+					break;
 				}
+			}
+
+			if (!st)
+				return 1;
 
-				index = sizeof(struct SparingTable);
-				for (i=0; i<rtl; i++)
+			for (k=0; k<st->reallocationTableLen; k++)
+			{
+				if (le32_to_cpu(st->mapEntry[k].origLocation) == 0xFFFFFFFF)
 				{
-					if (index > sb->s_blocksize)
+					for (; j<4; j++)
 					{
-						udf_release_data(bh);
-						bh = udf_tread(sb, ++spartable, sb->s_blocksize);
-						if (!bh)
+						if (sdata->s_spar_map[j])
 						{
-							sdata->s_spar_loc[i] = 0;
-							continue;
+							st = (struct SparingTable *)sdata->s_spar_map[j]->b_data;
+							st->mapEntry[k].origLocation = cpu_to_le32(packet);
+							udf_update_tag((char *)st, sizeof(struct SparingTable) + st->reallocationTableLen * sizeof(SparingEntry));
+							mark_buffer_dirty(sdata->s_spar_map[j]);
 						}
-						index = 0;
 					}
-					se = (SparingEntry *)&(bh->b_data[index]);
-					index += sizeof(SparingEntry);
-
-					if (sdata->s_spar_map[i] == 0xFFFFFFFF)
-						sdata->s_spar_map[i] = le32_to_cpu(se->mappedLocation);
-					else if (sdata->s_spar_map[i] != le32_to_cpu(se->mappedLocation))
-					{
-						udf_debug("Found conflicting Sparing Data (%d vs %d for entry %d)\n",
-							sdata->s_spar_map[i], le32_to_cpu(se->mappedLocation), i);
-					}
-
-					if (le32_to_cpu(se->origLocation) < 0xFFFFFFF0)
+					*new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
+						((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1));
+					return 0;
+				}
+				else if (le32_to_cpu(st->mapEntry[k].origLocation) == packet)
+				{
+					*new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
+						((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1));
+					return 0;
+				}
+				else if (le32_to_cpu(st->mapEntry[k].origLocation) > packet)
+					break;
+			}
+			for (l=k; l<st->reallocationTableLen; l++)
+			{
+				if (le32_to_cpu(st->mapEntry[l].origLocation) == 0xFFFFFFFF)
+				{
+					for (; j<4; j++)
 					{
-						int packet = le32_to_cpu(se->origLocation) >> sdata->s_spar_pshift;
-						if (sdata->s_spar_indexsize == 8)
-						{
-							if (sdata->s_spar_remap.s_spar_remap8[packet] == 0xFF)
-								sdata->s_spar_remap.s_spar_remap8[packet] = i;
-							else if (sdata->s_spar_remap.s_spar_remap8[packet] != i)
-							{
-								udf_debug("Found conflicting Sparing Data (%d vs %d)\n",
-									sdata->s_spar_remap.s_spar_remap8[packet], i);
-							}
-						}
-						else if (sdata->s_spar_indexsize == 16)
+						if (sdata->s_spar_map[j])
 						{
-							if (sdata->s_spar_remap.s_spar_remap16[packet] == 0xFFFF)
-								sdata->s_spar_remap.s_spar_remap16[packet] = i;
-							else if (sdata->s_spar_remap.s_spar_remap16[packet] != i)
-							{
-								udf_debug("Found conflicting Sparing Data (%d vs %d)\n",
-									sdata->s_spar_remap.s_spar_remap16[packet], i);
-							}
-						}
-						else if (sdata->s_spar_indexsize == 32)
-						{
-							if (sdata->s_spar_remap.s_spar_remap32[packet] == 0xFFFFFFFF)
-								sdata->s_spar_remap.s_spar_remap32[packet] = i;
-							else if (sdata->s_spar_remap.s_spar_remap32[packet] != i)
-							{
-								udf_debug("Found conflicting Sparing Data (%d vs %d)\n",
-									sdata->s_spar_remap.s_spar_remap32[packet], i);
-							}
+							st = (struct SparingTable *)sdata->s_spar_map[j]->b_data;
+							mapEntry = st->mapEntry[l];
+							mapEntry.origLocation = cpu_to_le32(packet);
+							memmove(&st->mapEntry[k+1], &st->mapEntry[k], (l-k)*sizeof(SparingEntry));
+							st->mapEntry[k] = mapEntry;
+							udf_update_tag((char *)st, sizeof(struct SparingTable) + st->reallocationTableLen * sizeof(SparingEntry));
+							mark_buffer_dirty(sdata->s_spar_map[j]);
 						}
 					}
+					*new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
+						((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1));
+					return 0;
 				}
 			}
+			return 1;
 		}
-		udf_release_data(bh);
 	}
+	if (i == UDF_SB_NUMPARTS(sb))
+	{
+		/* outside of partitions */
+		/* for now, fail =) */
+		return 1;
+	}
+
+	return 0;
 }
diff -u --recursive --new-file v2.4.5/linux/fs/udf/super.c linux/fs/udf/super.c
--- v2.4.5/linux/fs/udf/super.c	Mon Apr 23 10:00:21 2001
+++ linux/fs/udf/super.c	Mon Jun 11 19:15:27 2001
@@ -17,7 +17,7 @@
  * CONTACTS
  *  E-mail regarding any portion of the Linux UDF file system should be
  *  directed to the development team mailing list (run by majordomo):
- *	  linux_udf@hootie.lvld.hp.com
+ *	  linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *  This file is distributed under the terms of the GNU General Public
@@ -71,7 +71,7 @@
 #define VDS_POS_IMP_USE_VOL_DESC	4
 #define VDS_POS_VOL_DESC_PTR		5
 #define VDS_POS_TERMINATING_DESC	6
-#define VDS_POS_LENGTH				7
+#define VDS_POS_LENGTH			7
 
 static char error_buf[1024];
 
@@ -125,6 +125,7 @@
 	mode_t umask;
 	gid_t gid;
 	uid_t uid;
+	struct nls_table *nls_map;
 };
 
 static int __init init_udf_fs(void)
@@ -139,6 +140,8 @@
 	unregister_filesystem(&udf_fstype);
 }
 
+EXPORT_NO_SYMBOLS;
+
 module_init(init_udf_fs)
 module_exit(exit_udf_fs)
 
@@ -161,7 +164,8 @@
  *	noadinicb	Don't embed data in the inode
  *	shortad		Use short ad's
  *	longad		Use long ad's (default)
- *	strict		Set strict conformance (unused)
+ *	strict		Set strict conformance
+ *	iocharset=	Set the NLS character set
  *
  *	The remaining are for debugging and disaster recovery:
  *
@@ -209,6 +213,7 @@
 	uopt->volume = 0xFFFFFFFF;
 	uopt->rootdir = 0xFFFFFFFF;
 	uopt->fileset = 0xFFFFFFFF;
+	uopt->nls_map = NULL;
 
 	if (!options)
 		return 1;
@@ -257,6 +262,15 @@
 			uopt->fileset = simple_strtoul(val, NULL, 0);
 		else if (!strcmp(opt, "rootdir") && val)
 			uopt->rootdir = simple_strtoul(val, NULL, 0);
+#ifdef CONFIG_NLS
+		else if (!strcmp(opt, "iocharset") && val)
+		{
+			uopt->nls_map = load_nls(val);
+			uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
+		}
+#endif
+		else if (!strcmp(opt, "utf8") && !val)
+			uopt->flags |= (1 << UDF_FLAG_UTF8);
 		else if (val)
 		{
 			printk(KERN_ERR "udf: bad mount option \"%s=%s\"\n",
@@ -280,7 +294,7 @@
 		udf_open_lvid(sb);
 	sb->s_dirt = 0;
 }
-		
+
 static int
 udf_remount_fs(struct super_block *sb, int *flags, char *options)
 {
@@ -299,7 +313,7 @@
 	UDF_SB(sb)->s_gid   = uopt.gid;
 	UDF_SB(sb)->s_umask = uopt.umask;
 
-#if CONFIG_UDF_RW != 1
+#if UDFFS_RW != 1
 	*flags |= MS_RDONLY;
 #endif
 
@@ -344,12 +358,14 @@
 udf_set_blocksize(struct super_block *sb, int bsize)
 {
 	/* Use specified block size if specified */
-	sb->s_blocksize = get_hardsect_size(sb->s_dev);
-	if (bsize > sb->s_blocksize)
+	if (bsize)
 		sb->s_blocksize = bsize;
+	if (get_hardsect_size(sb->s_dev) > sb->s_blocksize)
+		sb->s_blocksize = get_hardsect_size(sb->s_dev); 
 
 	/* Block size must be an even multiple of 512 */
-	switch (sb->s_blocksize) {
+	switch (sb->s_blocksize)
+	{
 		case 512: sb->s_blocksize_bits = 9;	break;
 		case 1024: sb->s_blocksize_bits = 10; break;
 		case 2048: sb->s_blocksize_bits = 11; break;
@@ -373,6 +389,7 @@
 {
 	struct VolStructDesc *vsd = NULL;
 	int sector = 32768;
+	int sectorsize;
 	struct buffer_head *bh = NULL;
 	int iso9660=0;
 	int nsr02=0;
@@ -380,14 +397,19 @@
 
 	/* Block size must be a multiple of 512 */
 	if (sb->s_blocksize & 511)
-		return sector;
+		return 0;
+
+	if (sb->s_blocksize < sizeof(struct VolStructDesc))
+		sectorsize = sizeof(struct VolStructDesc);
+	else
+		sectorsize = sb->s_blocksize;
 
 	sector += (UDF_SB_SESSION(sb) << sb->s_blocksize_bits);
 
 	udf_debug("Starting at sector %u (%ld byte sectors)\n",
 		(sector >> sb->s_blocksize_bits), sb->s_blocksize);
 	/* Process the sequence (if applicable) */
-	for (;!nsr02 && !nsr03; sector += 2048)
+	for (;!nsr02 && !nsr03; sector += sectorsize)
 	{
 		/* Read a block */
 		bh = udf_tread(sb, sector >> sb->s_blocksize_bits, sb->s_blocksize);
@@ -479,9 +501,9 @@
 {
 	int varlastblock = udf_variable_to_fixed(lastblock);
 	int last[] =  { lastblock, lastblock - 2,
-					lastblock - 150, lastblock - 152,
-					varlastblock, varlastblock - 2,
-					varlastblock - 150, varlastblock - 152 };
+			lastblock - 150, lastblock - 152,
+			varlastblock, varlastblock - 2,
+			varlastblock - 150, varlastblock - 152 };
 	struct buffer_head *bh = NULL;
 	Uint16 ident;
 	Uint32 location;
@@ -504,7 +526,7 @@
 
 	for (i=0; (!lastblock && i<sizeof(last)/sizeof(int)); i++)
 	{
-		if (!(bh = bread(sb->s_dev, last[i], sb->s_blocksize)))
+		if (last[i] < 0 || !(bh = bread(sb->s_dev, last[i], sb->s_blocksize)))
 		{
 			ident = location = 0;
 		}
@@ -777,7 +799,7 @@
 	struct PartitionDesc *p;
 	int i;
 
-	p=(struct PartitionDesc *)bh->b_data;
+	p = (struct PartitionDesc *)bh->b_data;
 
 	for (i=0; i<UDF_SB_NUMPARTS(sb); i++)
 	{
@@ -788,9 +810,6 @@
 			UDF_SB_PARTLEN(sb,i) = le32_to_cpu(p->partitionLength); /* blocks */
 			UDF_SB_PARTROOT(sb,i) = le32_to_cpu(p->partitionStartingLocation) + UDF_SB_SESSION(sb);
 
-			if (UDF_SB_PARTTYPE(sb,i) == UDF_SPARABLE_MAP15)
-				udf_fill_spartable(sb, &UDF_SB_TYPESPAR(sb,i), UDF_SB_PARTLEN(sb,i));
-
 			if (!strcmp(p->partitionContents.ident, PARTITION_CONTENTS_NSR02) ||
 				!strcmp(p->partitionContents.ident, PARTITION_CONTENTS_NSR03))
 			{
@@ -798,26 +817,54 @@
 
 				phd = (struct PartitionHeaderDesc *)(p->partitionContentsUse);
 				if (phd->unallocatedSpaceTable.extLength)
-					udf_debug("unallocatedSpaceTable (part %d)\n", i);
+				{
+					lb_addr loc = { le32_to_cpu(phd->unallocatedSpaceTable.extPosition), i };
+
+					UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table =
+						udf_iget(sb, loc);
+					UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_TABLE;
+					udf_debug("unallocatedSpaceTable (part %d) @ %ld\n",
+						i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table->i_ino);
+				}
 				if (phd->unallocatedSpaceBitmap.extLength)
 				{
-					UDF_SB_PARTMAPS(sb)[i].s_uspace.bitmap =
-						le32_to_cpu(phd->unallocatedSpaceBitmap.extPosition);
-					UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_BITMAP;
-					udf_debug("unallocatedSpaceBitmap (part %d) @ %d\n",
-						i, UDF_SB_PARTMAPS(sb)[i].s_uspace.bitmap);
+					UDF_SB_ALLOC_BITMAP(sb, i, s_uspace);
+					if (UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap != NULL)
+					{
+						UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extLength =
+							le32_to_cpu(phd->unallocatedSpaceBitmap.extLength);
+						UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extPosition =
+							le32_to_cpu(phd->unallocatedSpaceBitmap.extPosition);
+						UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_BITMAP;
+						udf_debug("unallocatedSpaceBitmap (part %d) @ %d\n",
+							i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extPosition);
+					}
 				}
 				if (phd->partitionIntegrityTable.extLength)
 					udf_debug("partitionIntegrityTable (part %d)\n", i);
 				if (phd->freedSpaceTable.extLength)
-					udf_debug("freedSpaceTable (part %d)\n", i);
+				{
+					lb_addr loc = { le32_to_cpu(phd->freedSpaceTable.extPosition), i };
+
+					UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table =
+						udf_iget(sb, loc);
+					UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_TABLE;
+					udf_debug("freedSpaceTable (part %d) @ %ld\n",
+						i, UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table->i_ino);
+				}
 				if (phd->freedSpaceBitmap.extLength)
 				{
-					UDF_SB_PARTMAPS(sb)[i].s_fspace.bitmap =
-						le32_to_cpu(phd->freedSpaceBitmap.extPosition);
-					UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_BITMAP;
-					udf_debug("freedSpaceBitmap (part %d) @ %d\n",
-						i, UDF_SB_PARTMAPS(sb)[i].s_fspace.bitmap);
+					UDF_SB_ALLOC_BITMAP(sb, i, s_fspace);
+					if (UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap != NULL)
+					{
+						UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extLength =
+							le32_to_cpu(phd->freedSpaceBitmap.extLength);
+						UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extPosition =
+							le32_to_cpu(phd->freedSpaceBitmap.extPosition);
+						UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_BITMAP;
+						udf_debug("freedSpaceBitmap (part %d) @ %d\n",
+							i, UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extPosition);
+					}
 				}
 			}
 			break;
@@ -844,15 +891,13 @@
 
 	lvd = (struct LogicalVolDesc *)bh->b_data;
 
-	UDF_SB_NUMPARTS(sb) = le32_to_cpu(lvd->numPartitionMaps);
-	UDF_SB_ALLOC_PARTMAPS(sb, UDF_SB_NUMPARTS(sb));
+	UDF_SB_ALLOC_PARTMAPS(sb, le32_to_cpu(lvd->numPartitionMaps));
 
 	for (i=0,offset=0;
 		 i<UDF_SB_NUMPARTS(sb) && offset<le32_to_cpu(lvd->mapTableLength);
 		 i++,offset+=((struct GenericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapLength)
 	{
 		type = ((struct GenericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapType;
-		udf_debug("Partition (%d) type %d\n", i, type);
 		if (type == 1)
 		{
 			struct GenericPartitionMap1 *gpm1 = (struct GenericPartitionMap1 *)&(lvd->partitionMaps[offset]);
@@ -879,16 +924,29 @@
 			}
 			else if (!strncmp(upm2->partIdent.ident, UDF_ID_SPARABLE, strlen(UDF_ID_SPARABLE)))
 			{
-				int plen;
-
+				Uint32 loc;
+				Uint16 ident;
+				struct SparingTable *st;
 				struct SparablePartitionMap *spm = (struct SparablePartitionMap *)&(lvd->partitionMaps[offset]);
+
 				UDF_SB_PARTTYPE(sb,i) = UDF_SPARABLE_MAP15;
-				plen = le16_to_cpu(spm->packetLength);
-				UDF_SB_TYPESPAR(sb,i).s_spar_pshift = 0;
-				while (plen >>= 1)
-					UDF_SB_TYPESPAR(sb,i).s_spar_pshift ++;
+				UDF_SB_TYPESPAR(sb,i).s_packet_len = le16_to_cpu(spm->packetLength);
 				for (j=0; j<spm->numSparingTables; j++)
-					UDF_SB_TYPESPAR(sb,i).s_spar_loc[j] = le32_to_cpu(spm->locSparingTable[j]);
+				{
+					loc = le32_to_cpu(spm->locSparingTable[j]);
+					UDF_SB_TYPESPAR(sb,i).s_spar_map[j] =
+						udf_read_tagged(sb, loc, loc, &ident);
+					if (UDF_SB_TYPESPAR(sb,i).s_spar_map[j] != NULL)
+					{
+						st = (struct SparingTable *)UDF_SB_TYPESPAR(sb,i).s_spar_map[j]->b_data;
+						if (ident != 0 ||
+							strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING)))
+						{
+							udf_release_data(UDF_SB_TYPESPAR(sb,i).s_spar_map[j]);
+							UDF_SB_TYPESPAR(sb,i).s_spar_map[j] = NULL;
+						}
+					}
+				}
 				UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_spar15;
 			}
 			else
@@ -899,6 +957,8 @@
 			UDF_SB_PARTVSN(sb,i) = le16_to_cpu(upm2->volSeqNum);
 			UDF_SB_PARTNUM(sb,i) = le16_to_cpu(upm2->partitionNum);
 		}
+		udf_debug("Partition (%d:%d) type %d on volume %d\n",
+			i, UDF_SB_PARTNUM(sb,i), type, UDF_SB_PARTVSN(sb,i));
 	}
 
 	if (fileset)
@@ -963,10 +1023,12 @@
 	struct buffer_head *bh = NULL;
 	struct udf_vds_record vds[VDS_POS_LENGTH];
 	struct GenericDesc *gd;
+	struct VolDescPtr *vdp;
 	int done=0;
 	int i,j;
 	Uint32 vdsn;
 	Uint16 ident;
+	long next_s = 0, next_e = 0;
 
 	memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH);
 
@@ -995,6 +1057,12 @@
 				{
 					vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum = vdsn;
 					vds[VDS_POS_VOL_DESC_PTR].block = block;
+
+					vdp = (struct VolDescPtr *)bh->b_data;
+					next_s = le32_to_cpu(vdp->nextVolDescSeqExt.extLocation);
+					next_e = le32_to_cpu(vdp->nextVolDescSeqExt.extLength);
+					next_e = next_e >> sb->s_blocksize_bits;
+					next_e += next_s;
 				}
 				break;
 			case TID_IMP_USE_VOL_DESC: /* ISO 13346 3/10.4 */
@@ -1024,7 +1092,14 @@
 				break;
 			case TID_TERMINATING_DESC: /* ISO 13346 3/10.9 */
 				vds[VDS_POS_TERMINATING_DESC].block = block;
-				done = 1;
+				if (next_e)
+				{
+					block = next_s;
+					lastblock = next_e;
+					next_s = next_e = 0;
+				}
+				else
+					done = 1;
 				break;
 		}
 		udf_release_data(bh);
@@ -1098,7 +1173,7 @@
 	for (i=0; i<sizeof(UDF_SB_ANCHOR(sb))/sizeof(int); i++)
 	{
 		if (UDF_SB_ANCHOR(sb)[i] && (bh = udf_read_tagged(sb,
-			UDF_SB_ANCHOR(sb)[i], UDF_SB_ANCHOR(sb)[i] - UDF_SB_SESSION(sb), &ident)))
+			UDF_SB_ANCHOR(sb)[i], UDF_SB_ANCHOR(sb)[i], &ident)))
 		{
 			anchor = (struct AnchorVolDescPtr *)bh->b_data;
 
@@ -1155,10 +1230,10 @@
 						UDF_SB_PARTVSN(sb,i) == UDF_SB_PARTVSN(sb,j) &&
 						UDF_SB_PARTNUM(sb,i) == UDF_SB_PARTNUM(sb,j))
 					{
-							ino.partitionReferenceNum = j;
-							ino.logicalBlockNum = UDF_SB_LASTBLOCK(sb) -
-								UDF_SB_PARTROOT(sb,j);
-							break;
+						ino.partitionReferenceNum = j;
+						ino.logicalBlockNum = UDF_SB_LASTBLOCK(sb) -
+							UDF_SB_PARTROOT(sb,j);
+						break;
 					}
 				}
 
@@ -1219,7 +1294,6 @@
 					((Uint8 *)&(UDF_SB_LVID(sb)->descTag))[i];
 
 		mark_buffer_dirty(UDF_SB_LVIDBH(sb));
-		sb->s_dirt = 0;
 	}
 }
 
@@ -1276,10 +1350,10 @@
 static struct super_block *
 udf_read_super(struct super_block *sb, void *options, int silent)
 {
+	int i;
 	struct inode *inode=NULL;
 	struct udf_options uopt;
 	lb_addr rootdir, fileset;
-	int i;
 
 	uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB);
 	uopt.uid = -1;
@@ -1288,13 +1362,33 @@
 
 	memset(UDF_SB(sb), 0x00, sizeof(struct udf_sb_info));
 
-#if CONFIG_UDF_RW != 1
+#if UDFFS_RW != 1
 	sb->s_flags |= MS_RDONLY;
 #endif
 
 	if (!udf_parse_options((char *)options, &uopt))
 		goto error_out;
 
+	if (uopt.flags & (1 << UDF_FLAG_UTF8) &&
+	    uopt.flags & (1 << UDF_FLAG_NLS_MAP))
+	{
+		udf_error(sb, "udf_read_super",
+			"utf8 cannot be combined with iocharset\n");
+		goto error_out;
+	}
+#ifdef CONFIG_NLS
+	if ((uopt.flags & (1 << UDF_FLAG_NLS_MAP)) && !uopt.nls_map)
+	{
+		uopt.nls_map = load_nls_default();
+		if (!uopt.nls_map)
+			uopt.flags &= ~(1 << UDF_FLAG_NLS_MAP);
+		else
+			udf_debug("Using default NLS map\n");
+	}
+#endif
+	if (!(uopt.flags & (1 << UDF_FLAG_NLS_MAP)))
+		uopt.flags |= (1 << UDF_FLAG_UTF8);
+
 	fileset.logicalBlockNum = 0xFFFFFFFF;
 	fileset.partitionReferenceNum = 0xFFFF;
 
@@ -1302,6 +1396,7 @@
 	UDF_SB(sb)->s_uid = uopt.uid;
 	UDF_SB(sb)->s_gid = uopt.gid;
 	UDF_SB(sb)->s_umask = uopt.umask;
+	UDF_SB(sb)->s_nls_map = uopt.nls_map;
 
 	/* Set the block size for all transfers */
 	if (!udf_set_blocksize(sb, uopt.blocksize))
@@ -1335,13 +1430,6 @@
 	sb->s_dirt = 0;
 	sb->s_magic = UDF_SUPER_MAGIC;
 
-	for (i=0; i<UDF_MAX_BLOCK_LOADED; i++)
-	{
-		UDF_SB_BLOCK_BITMAP_NUMBER(sb,i) = 0;
-		UDF_SB_BLOCK_BITMAP(sb,i) = NULL;
-	}
-	UDF_SB_LOADED_BLOCK_BITMAPS(sb) = 0;
-
 	if (udf_load_partition(sb, &fileset))
 	{
 		printk("UDF-fs: No partition found (1)\n");
@@ -1365,6 +1453,8 @@
 			sb->s_flags |= MS_RDONLY;
 		}
 
+		UDF_SB_UDFREV(sb) = minUDFWriteRev;
+
 		if (minUDFReadRev >= UDF_VERS_USE_EXTENDED_FE)
 			UDF_SET_FLAG(sb, UDF_FLAG_USE_EXTENDED_FE);
 		if (minUDFReadRev >= UDF_VERS_USE_STREAMS)
@@ -1387,8 +1477,8 @@
 	{
 		timestamp ts;
 		udf_time_to_stamp(&ts, UDF_SB_RECORDTIME(sb), 0);
-		udf_info("UDF %s (%s) Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x)\n",
-			UDFFS_VERSION, UDFFS_DATE,
+		udf_info("UDF %s-%s (%s) Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x)\n",
+			UDFFS_VERSION, UDFFS_RW ? "rw" : "ro", UDFFS_DATE,
 			UDF_SB_VOLIDENT(sb), ts.year, ts.month, ts.day, ts.hour, ts.minute,
 			ts.typeAndTimezone);
 	}
@@ -1420,6 +1510,40 @@
 error_out:
 	if (UDF_SB_VAT(sb))
 		iput(UDF_SB_VAT(sb));
+	if (UDF_SB_NUMPARTS(sb))
+	{
+		if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE)
+			iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table);
+		if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE)
+			iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
+		if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
+		{
+			for (i=0; i<UDF_SB_BITMAP_NR_GROUPS(sb,UDF_SB_PARTITION(sb),s_uspace); i++)
+			{
+				if (UDF_SB_BITMAP(sb,UDF_SB_PARTITION(sb),s_uspace,i))
+					udf_release_data(UDF_SB_BITMAP(sb,UDF_SB_PARTITION(sb),s_uspace,i));
+			}
+			kfree(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_bitmap);
+		}
+		if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP)
+		{
+			for (i=0; i<UDF_SB_BITMAP_NR_GROUPS(sb,UDF_SB_PARTITION(sb),s_fspace); i++)
+			{
+				if (UDF_SB_BITMAP(sb,UDF_SB_PARTITION(sb),s_fspace,i))
+					udf_release_data(UDF_SB_BITMAP(sb,UDF_SB_PARTITION(sb),s_fspace,i));
+			}
+			kfree(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_bitmap);
+		}
+		if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15)
+		{
+			for (i=0; i<4; i++)
+				udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
+		}
+	}
+#ifdef CONFIG_NLS
+	if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
+		unload_nls(UDF_SB(sb)->s_nls_map);
+#endif
 	if (!(sb->s_flags & MS_RDONLY))
 		udf_close_lvid(sb);
 	udf_release_data(UDF_SB_LVIDBH(sb));
@@ -1476,11 +1600,43 @@
 
 	if (UDF_SB_VAT(sb))
 		iput(UDF_SB_VAT(sb));
+	if (UDF_SB_NUMPARTS(sb))
+	{
+		if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE)
+			iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table);
+		if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE)
+			iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
+		if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
+		{
+			for (i=0; i<UDF_SB_BITMAP_NR_GROUPS(sb,UDF_SB_PARTITION(sb),s_uspace); i++)
+			{
+				if (UDF_SB_BITMAP(sb,UDF_SB_PARTITION(sb),s_uspace,i))
+					udf_release_data(UDF_SB_BITMAP(sb,UDF_SB_PARTITION(sb),s_uspace,i));
+			}
+			kfree(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_bitmap);
+		}
+		if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP)
+		{
+			for (i=0; i<UDF_SB_BITMAP_NR_GROUPS(sb,UDF_SB_PARTITION(sb),s_fspace); i++)
+			{
+				if (UDF_SB_BITMAP(sb,UDF_SB_PARTITION(sb),s_fspace,i))
+					udf_release_data(UDF_SB_BITMAP(sb,UDF_SB_PARTITION(sb),s_fspace,i));
+			}
+			kfree(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_bitmap);
+		}
+		if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15)
+		{
+			for (i=0; i<4; i++)
+				udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
+		}
+	}
+#ifdef CONFIG_NLS
+	if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
+		unload_nls(UDF_SB(sb)->s_nls_map);
+#endif
 	if (!(sb->s_flags & MS_RDONLY))
 		udf_close_lvid(sb);
 	udf_release_data(UDF_SB_LVIDBH(sb));
-	for (i=0; i<UDF_MAX_BLOCK_LOADED; i++)
-		udf_release_data(UDF_SB_BLOCK_BITMAP(sb, i));
 	UDF_SB_FREE(sb);
 }
 
@@ -1518,89 +1674,130 @@
 static unsigned char udf_bitmap_lookup[16] = {
 	0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
 };
-	
+
 static unsigned int
-udf_count_free(struct super_block *sb)
+udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
 {
 	struct buffer_head *bh = NULL;
 	unsigned int accum = 0;
+	int index;
+	int block = 0, newblock;
 	lb_addr loc;
-	Uint32 bitmap;
+	Uint32 bytes;
+	Uint8 value;
+	Uint8 *ptr;
+	Uint16 ident;
+	struct SpaceBitmapDesc *bm;
 
-	if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
-		bitmap = UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.bitmap;
-	else if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP)
-		bitmap = UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.bitmap;
-	else
-		bitmap = 0xFFFFFFFF;
+	loc.logicalBlockNum = bitmap->s_extPosition;
+	loc.partitionReferenceNum = UDF_SB_PARTITION(sb);
+	bh = udf_read_ptagged(sb, loc, 0, &ident);
 
-	if (bitmap != 0xFFFFFFFF)
+	if (!bh)
+	{
+		printk(KERN_ERR "udf: udf_count_free failed\n");
+		return 0;
+	}
+	else if (ident != TID_SPACE_BITMAP_DESC)
 	{
-		struct SpaceBitmapDesc *bm;
-		int block = 0, newblock, index;
-		Uint16 ident;
-		Uint32 bytes;
-		Uint8 value;
-		Uint8 * ptr;
-
-		loc.logicalBlockNum = bitmap;
-		loc.partitionReferenceNum = UDF_SB_PARTITION(sb);
-		bh = udf_read_ptagged(sb, loc, 0, &ident);
+		udf_release_data(bh);
+		printk(KERN_ERR "udf: udf_count_free failed\n");
+		return 0;
+	}
 
-		if (!bh)
-		{
-			printk(KERN_ERR "udf: udf_count_free failed\n");
-			return 0;
+	bm = (struct SpaceBitmapDesc *)bh->b_data;
+	bytes = bm->numOfBytes;
+	index = sizeof(struct SpaceBitmapDesc); /* offset in first block only */
+	ptr = (Uint8 *)bh->b_data;
+
+	while ( bytes > 0 )
+	{
+		while ((bytes > 0) && (index < sb->s_blocksize))
+		{
+			value = ptr[index];
+			accum += udf_bitmap_lookup[ value & 0x0f ];
+			accum += udf_bitmap_lookup[ value >> 4 ];
+			index++;
+			bytes--;
 		}
-		else if (ident != TID_SPACE_BITMAP_DESC)
+		if ( bytes )
 		{
 			udf_release_data(bh);
-			printk(KERN_ERR "udf: udf_count_free failed\n");
-			return 0;
-		}
-
-		bm = (struct SpaceBitmapDesc *)bh->b_data;
-		bytes = bm->numOfBytes;
-		index = sizeof(struct SpaceBitmapDesc); /* offset in first block only */
-		ptr = (Uint8 *)bh->b_data;
-
-		while ( bytes > 0 )
-		{
-			while ((bytes > 0) && (index < sb->s_blocksize))
-			{
-				value = ptr[index];
-				accum += udf_bitmap_lookup[ value & 0x0f ];
-				accum += udf_bitmap_lookup[ value >> 4 ];
-				index++;
-				bytes--;
-			}
-			if ( bytes )
+			newblock = udf_get_lb_pblock(sb, loc, ++block);
+			bh = udf_tread(sb, newblock, sb->s_blocksize);
+			if (!bh)
 			{
-				udf_release_data(bh);
-				newblock = udf_get_lb_pblock(sb, loc, ++block);
-				bh = udf_tread(sb, newblock, sb->s_blocksize);
-				if (!bh)
-				{
-					udf_debug("read failed\n");
-					return accum;
-				}
-				index = 0;
-				ptr = (Uint8 *)bh->b_data;
+				udf_debug("read failed\n");
+				return accum;
 			}
+			index = 0;
+			ptr = (Uint8 *)bh->b_data;
 		}
-		udf_release_data(bh);
 	}
-	else
+	udf_release_data(bh);
+	return accum;
+}
+
+static unsigned int
+udf_count_free_table(struct super_block *sb, struct inode * table)
+{
+	unsigned int accum = 0;
+	Uint32 extoffset, elen;
+	lb_addr bloc, eloc;
+	char etype;
+	struct buffer_head *bh = NULL;
+
+	bloc = UDF_I_LOCATION(table);
+	extoffset = sizeof(struct UnallocatedSpaceEntry);
+
+	while ((etype = udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
 	{
-		if (UDF_SB_LVIDBH(sb))
+		accum += (elen >> table->i_sb->s_blocksize_bits);
+	}
+	udf_release_data(bh);
+	return accum;
+}
+	
+static unsigned int
+udf_count_free(struct super_block *sb)
+{
+	unsigned int accum = 0;
+
+	if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
+	{
+		accum += udf_count_free_bitmap(sb,
+			UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_bitmap);
+	}
+	if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP)
+	{
+		accum += udf_count_free_bitmap(sb,
+			UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_bitmap);
+	}
+	if (accum)
+		return accum;
+
+	if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE)
+	{
+		accum += udf_count_free_table(sb,
+			UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table);
+	}
+	if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE)
+	{
+		accum += udf_count_free_table(sb,
+			UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
+	}
+	if (accum)
+		return accum;
+
+	if (UDF_SB_LVIDBH(sb))
+	{
+		if (le32_to_cpu(UDF_SB_LVID(sb)->numOfPartitions) > UDF_SB_PARTITION(sb))
 		{
-			if (le32_to_cpu(UDF_SB_LVID(sb)->numOfPartitions) > UDF_SB_PARTITION(sb))
-				accum = le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)]);
+			accum = le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)]);
 
 			if (accum == 0xFFFFFFFF)
 				accum = 0;
 		}
 	}
-
 	return accum;
 }
diff -u --recursive --new-file v2.4.5/linux/fs/udf/symlink.c linux/fs/udf/symlink.c
--- v2.4.5/linux/fs/udf/symlink.c	Fri Feb  9 11:29:44 2001
+++ linux/fs/udf/symlink.c	Mon Jun 11 19:15:27 2001
@@ -7,7 +7,7 @@
  * CONTACTS
  *	E-mail regarding any portion of the Linux UDF file system should be
  *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hootie.lvld.hp.com
+ *		linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
@@ -126,5 +126,5 @@
  * symlinks can't do much...
  */
 struct address_space_operations udf_symlink_aops = {
-	readpage:			udf_symlink_filler,
+	readpage:		udf_symlink_filler,
 };
diff -u --recursive --new-file v2.4.5/linux/fs/udf/truncate.c linux/fs/udf/truncate.c
--- v2.4.5/linux/fs/udf/truncate.c	Tue Sep  5 14:07:30 2000
+++ linux/fs/udf/truncate.c	Mon Jun 11 19:15:27 2001
@@ -7,7 +7,7 @@
  * CONTACTS
  *	E-mail regarding any portion of the Linux UDF file system should be
  *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hootie.lvld.hp.com
+ *		linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
@@ -33,7 +33,7 @@
 #include "udf_sb.h"
 
 static void extent_trunc(struct inode * inode, lb_addr bloc, int extoffset,
-	lb_addr eloc, Uint8 etype, Uint32 elen, struct buffer_head **bh, Uint32 nelen)
+	lb_addr eloc, Uint8 etype, Uint32 elen, struct buffer_head *bh, Uint32 nelen)
 {
 	lb_addr neloc = { 0, 0 };
 	int blocks = inode->i_sb->s_blocksize / 512;
@@ -62,7 +62,7 @@
 	}
 }
 
-void udf_trunc(struct inode * inode)
+void udf_truncate_extents(struct inode * inode)
 {
 	lb_addr bloc, eloc, neloc = { 0, 0 };
 	Uint32 extoffset, elen, offset, nelen = 0, lelen = 0, lenalloc;
@@ -79,12 +79,11 @@
 		adsize = 0;
 
 	etype = inode_bmap(inode, first_block, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
-	offset = (offset << inode->i_sb->s_blocksize_bits) |
-		(inode->i_size & (inode->i_sb->s_blocksize - 1));
+	offset += (inode->i_size & (inode->i_sb->s_blocksize - 1));
 	if (etype != -1)
 	{
 		extoffset -= adsize;
-		extent_trunc(inode, bloc, extoffset, eloc, etype, elen, &bh, offset);
+		extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, offset);
 		extoffset += adsize;
 
 		if (offset)
@@ -101,7 +100,7 @@
 		{
 			if (etype == EXTENT_NEXT_EXTENT_ALLOCDECS)
 			{
-				udf_write_aext(inode, bloc, &extoffset, neloc, nelen, &bh, 0);
+				udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 0);
 				extoffset = 0;
 				if (lelen)
 				{
@@ -122,9 +121,12 @@
 					{
 						struct AllocExtDesc *aed = (struct AllocExtDesc *)(bh->b_data);
 						aed->lengthAllocDescs = cpu_to_le32(lenalloc);
-						udf_update_tag(bh->b_data, lenalloc +
-							sizeof(struct AllocExtDesc));
-						mark_buffer_dirty(bh);
+						if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
+							udf_update_tag(bh->b_data, lenalloc +
+								sizeof(struct AllocExtDesc));
+						else
+							udf_update_tag(bh->b_data, sizeof(struct AllocExtDesc));
+						mark_buffer_dirty_inode(bh, inode);
 					}
 				}
 
@@ -140,7 +142,7 @@
 			}
 			else
 			{
-				extent_trunc(inode, bloc, extoffset, eloc, etype, elen, &bh, 0);
+				extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, 0);
 				extoffset += adsize;
 			}
 		}
@@ -164,9 +166,12 @@
 			{
 				struct AllocExtDesc *aed = (struct AllocExtDesc *)(bh->b_data);
 				aed->lengthAllocDescs = cpu_to_le32(lenalloc);
-				udf_update_tag(bh->b_data, lenalloc +
-					sizeof(struct AllocExtDesc));
-				mark_buffer_dirty(bh);
+				if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
+					udf_update_tag(bh->b_data, lenalloc +
+						sizeof(struct AllocExtDesc));
+				else
+					udf_update_tag(bh->b_data, sizeof(struct AllocExtDesc));
+				mark_buffer_dirty_inode(bh, inode);
 			}
 		}
 	}
@@ -180,7 +185,7 @@
 			{
 				extoffset -= adsize;
 				elen = (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30) | (elen + offset);
-				udf_write_aext(inode, bloc, &extoffset, eloc, elen, &bh, 0);
+				udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0);
 			}
 			else if (etype == EXTENT_NOT_RECORDED_ALLOCATED)
 			{
@@ -189,7 +194,7 @@
 				nelen = (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30) |
 					((elen + offset + inode->i_sb->s_blocksize - 1) &
 					~(inode->i_sb->s_blocksize - 1));
-				udf_write_aext(inode, bloc, &extoffset, neloc, nelen, &bh, 1);
+				udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
 				udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1);
 			}
 			else
@@ -200,7 +205,7 @@
 					elen = (EXTENT_RECORDED_ALLOCATED << 30) |
 						((elen + inode->i_sb->s_blocksize - 1) &
 						~(inode->i_sb->s_blocksize - 1));
-					udf_write_aext(inode, bloc, &extoffset, eloc, elen, &bh, 1);
+					udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1);
 				}
 				memset(&eloc, 0x00, sizeof(lb_addr));
 				elen = (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30) | offset;
@@ -208,40 +213,7 @@
 			}
 		}
 	}
+	UDF_I_LENEXTENTS(inode) = inode->i_size;
 
 	udf_release_data(bh);
-}
-
-void udf_truncate(struct inode * inode)
-{
-	int err;
-
-	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
-			S_ISLNK(inode->i_mode)))
-		return;
-	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
-		return;
-
-	if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
-	{
-		if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) +
-			inode->i_size))
-		{
-			udf_expand_file_adinicb(inode, inode->i_size, &err);
-			if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
-			{
-				inode->i_size = UDF_I_LENALLOC(inode);
-				return;
-			}
-			else
-				udf_trunc(inode);
-		}
-		else
-			UDF_I_LENALLOC(inode) = inode->i_size;
-	}
-	else
-		udf_trunc(inode);
-
-	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-	mark_inode_dirty(inode);
 }
diff -u --recursive --new-file v2.4.5/linux/fs/udf/udf_i.h linux/fs/udf/udf_i.h
--- v2.4.5/linux/fs/udf/udf_i.h	Thu Mar  2 11:17:32 2000
+++ linux/fs/udf/udf_i.h	Mon Jun 11 19:15:27 2001
@@ -6,6 +6,7 @@
 #define UDF_I_LOCATION(X)	( UDF_I(X)->i_location )
 #define UDF_I_LENEATTR(X)	( UDF_I(X)->i_lenEAttr )
 #define UDF_I_LENALLOC(X)	( UDF_I(X)->i_lenAlloc )
+#define UDF_I_LENEXTENTS(X)	( UDF_I(X)->i_lenExtents )
 #define UDF_I_UNIQUE(X)		( UDF_I(X)->i_unique )
 #define UDF_I_ALLOCTYPE(X)	( UDF_I(X)->i_alloc_type )
 #define UDF_I_EXTENDED_FE(X)( UDF_I(X)->i_extended_fe )
diff -u --recursive --new-file v2.4.5/linux/fs/udf/udf_sb.h linux/fs/udf/udf_sb.h
--- v2.4.5/linux/fs/udf/udf_sb.h	Mon Mar 20 08:17:43 2000
+++ linux/fs/udf/udf_sb.h	Mon Jun 11 19:15:27 2001
@@ -1,11 +1,11 @@
 #ifndef __LINUX_UDF_SB_H
 #define __LINUX_UDF_SB_H
 
-/* Since UDF 1.50 is ISO 13346 based... */
-#define UDF_SUPER_MAGIC				0x15013346
+/* Since UDF 2.01 is ISO 13346 based... */
+#define UDF_SUPER_MAGIC			0x15013346
 
-#define UDF_MAX_READ_VERSION		0x0200
-#define UDF_MAX_WRITE_VERSION		0x0200
+#define UDF_MAX_READ_VERSION		0x0201
+#define UDF_MAX_WRITE_VERSION		0x0201
 
 #define UDF_FLAG_USE_EXTENDED_FE	0
 #define UDF_VERS_USE_EXTENDED_FE	0x0200
@@ -14,16 +14,18 @@
 #define UDF_FLAG_USE_SHORT_AD		2
 #define UDF_FLAG_USE_AD_IN_ICB		3
 #define UDF_FLAG_USE_FILE_CTIME_EA	4
-#define UDF_FLAG_STRICT				5
-#define UDF_FLAG_UNDELETE			6
-#define UDF_FLAG_UNHIDE				7
-#define UDF_FLAG_VARCONV			8
-
-#define UDF_PART_FLAG_UNALLOC_BITMAP		0x0001
-#define UDF_PART_FLAG_UNALLOC_TABLE			0x0002
-#define UDF_PART_FLAG_FREED_BITMAP			0x0004
-#define UDF_PART_FLAG_FREED_TABLE			0x0008
-	
+#define UDF_FLAG_STRICT			5
+#define UDF_FLAG_UNDELETE		6
+#define UDF_FLAG_UNHIDE			7
+#define UDF_FLAG_VARCONV		8
+#define UDF_FLAG_NLS_MAP		9
+#define UDF_FLAG_UTF8			10
+
+#define UDF_PART_FLAG_UNALLOC_BITMAP	0x0001
+#define UDF_PART_FLAG_UNALLOC_TABLE	0x0002
+#define UDF_PART_FLAG_FREED_BITMAP	0x0004
+#define UDF_PART_FLAG_FREED_TABLE	0x0008
+
 #define UDF_SB_FREE(X)\
 {\
 	if (UDF_SB(X))\
@@ -37,11 +39,41 @@
 
 #define UDF_SB_ALLOC_PARTMAPS(X,Y)\
 {\
-	UDF_SB_NUMPARTS(X) = Y;\
 	UDF_SB_PARTMAPS(X) = kmalloc(sizeof(struct udf_part_map) * Y, GFP_KERNEL);\
-	memset(UDF_SB_PARTMAPS(X), 0x00, sizeof(struct udf_part_map) * Y);\
+	if (UDF_SB_PARTMAPS(X) != NULL)\
+	{\
+		UDF_SB_NUMPARTS(X) = Y;\
+		memset(UDF_SB_PARTMAPS(X), 0x00, sizeof(struct udf_part_map) * Y);\
+	}\
+	else\
+	{\
+		UDF_SB_NUMPARTS(X) = 0;\
+		udf_error(X, __FUNCTION__, "Unable to allocate space for %d partition maps", Y);\
+	}\
 }
 
+#define UDF_SB_ALLOC_BITMAP(X,Y,Z)\
+{\
+	int nr_groups = ((UDF_SB_PARTLEN((X),(Y)) + (sizeof(struct SpaceBitmapDesc) << 3) +\
+		((X)->s_blocksize * 8) - 1) / ((X)->s_blocksize * 8));\
+	UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap = kmalloc(sizeof(struct udf_bitmap) +\
+		sizeof(struct buffer_head *) * nr_groups,\
+		GFP_KERNEL);\
+	if (UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap != NULL)\
+	{\
+		memset(UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap, 0x00,\
+			sizeof(struct udf_bitmap) + sizeof(struct buffer_head *) * nr_groups);\
+		UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap->s_block_bitmap =\
+			(struct buffer_head **)(UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap + 1);\
+		UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap->s_nr_groups = nr_groups;\
+	}\
+	else\
+	{\
+		udf_error(X, __FUNCTION__, "Unable to allocate space for bitmap and %d buffer_head pointers", nr_groups);\
+	}\
+}
+
+
 #define UDF_QUERY_FLAG(X,Y)				( UDF_SB(X)->s_flags & ( 1 << (Y) ) )
 #define UDF_SET_FLAG(X,Y)				( UDF_SB(X)->s_flags |= ( 1 << (Y) ) )
 #define UDF_CLEAR_FLAG(X,Y)				( UDF_SB(X)->s_flags &= ~( 1 << (Y) ) )
@@ -58,6 +90,8 @@
 #define UDF_SB_TYPEVIRT(X,Y)			( UDF_SB_PARTMAPS(X)[(Y)].s_type_specific.s_virtual )
 #define UDF_SB_PARTFUNC(X,Y)			( UDF_SB_PARTMAPS(X)[(Y)].s_partition_func )
 #define UDF_SB_PARTFLAGS(X,Y)			( UDF_SB_PARTMAPS(X)[(Y)].s_partition_flags )
+#define UDF_SB_BITMAP(X,Y,Z,I)			( UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap->s_block_bitmap[I] )
+#define UDF_SB_BITMAP_NR_GROUPS(X,Y,Z)	( UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap->s_nr_groups )
 
 #define UDF_SB_VOLIDENT(X)				( UDF_SB(X)->s_volident )
 #define UDF_SB_NUMPARTS(X)				( UDF_SB(X)->s_partitions )
@@ -69,9 +103,6 @@
 #define UDF_SB_LVID(X)					( (struct LogicalVolIntegrityDesc *)UDF_SB_LVIDBH(X)->b_data )
 #define UDF_SB_LVIDIU(X)				( (struct LogicalVolIntegrityDescImpUse *)&(UDF_SB_LVID(X)->impUse[UDF_SB_LVID(X)->numOfPartitions * 2 * sizeof(Uint32)/sizeof(Uint8)]) )
 
-#define UDF_SB_LOADED_BLOCK_BITMAPS(X)	( UDF_SB(X)->s_loaded_block_bitmaps )
-#define UDF_SB_BLOCK_BITMAP_NUMBER(X,Y) ( UDF_SB(X)->s_block_bitmap_number[(Y)] )
-#define UDF_SB_BLOCK_BITMAP(X,Y)		( UDF_SB(X)->s_block_bitmap[(Y)] )
 #define UDF_SB_UMASK(X)					( UDF_SB(X)->s_umask )
 #define UDF_SB_GID(X)					( UDF_SB(X)->s_gid )
 #define UDF_SB_UID(X)					( UDF_SB(X)->s_uid )
diff -u --recursive --new-file v2.4.5/linux/fs/udf/udfdecl.h linux/fs/udf/udfdecl.h
--- v2.4.5/linux/fs/udf/udfdecl.h	Mon Dec 11 13:27:05 2000
+++ linux/fs/udf/udfdecl.h	Mon Jun 11 19:15:27 2001
@@ -12,14 +12,6 @@
 #include <linux/config.h>
 #include <linux/types.h>
 
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,7)
-#error "The UDF Module Current Requires Kernel Version 2.3.7 or greater"
-#endif
-
 #include <linux/fs.h>
 
 #if !defined(CONFIG_UDF_FS) && !defined(CONFIG_UDF_FS_MODULE)
@@ -119,7 +111,7 @@
 extern void udf_warning(struct super_block *, const char *, const char *, ...);
 
 /* namei.c */
-extern int udf_write_fi(struct FileIdentDesc *, struct FileIdentDesc *, struct udf_fileident_bh *, Uint8 *, Uint8 *);
+extern int udf_write_fi(struct inode *inode, struct FileIdentDesc *, struct FileIdentDesc *, struct udf_fileident_bh *, Uint8 *, Uint8 *);
 
 /* file.c */
 extern int udf_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
@@ -131,15 +123,15 @@
 extern struct buffer_head * udf_expand_dir_adinicb(struct inode *, int *, int *);
 extern struct buffer_head * udf_getblk(struct inode *, long, int, int *);
 extern struct buffer_head * udf_bread(struct inode *, int, int, int *);
+extern void udf_truncate(struct inode *);
 extern void udf_read_inode(struct inode *);
 extern void udf_put_inode(struct inode *);
 extern void udf_delete_inode(struct inode *);
 extern void udf_write_inode(struct inode *, int);
-extern long udf_locked_block_map(struct inode *, long);
 extern long udf_block_map(struct inode *, long);
 extern int inode_bmap(struct inode *, int, lb_addr *, Uint32 *, lb_addr *, Uint32 *, Uint32 *, struct buffer_head **);
 extern int udf_add_aext(struct inode *, lb_addr *, int *, lb_addr, Uint32, struct buffer_head **, int);
-extern int udf_write_aext(struct inode *, lb_addr, int *, lb_addr, Uint32, struct buffer_head **, int);
+extern int udf_write_aext(struct inode *, lb_addr, int *, lb_addr, Uint32, struct buffer_head *, int);
 extern int udf_insert_aext(struct inode *, lb_addr, int, lb_addr, Uint32, struct buffer_head *);
 extern int udf_delete_aext(struct inode *, lb_addr, int, lb_addr, Uint32, struct buffer_head *);
 extern int udf_next_aext(struct inode *, lb_addr *, int *, lb_addr *, Uint32 *, struct buffer_head **, int);
@@ -148,6 +140,7 @@
 
 /* misc.c */
 extern int udf_read_tagged_data(char *, int size, int fd, int block, int partref);
+extern struct buffer_head *udf_tgetblk(struct super_block *, int, int);
 extern struct buffer_head *udf_tread(struct super_block *, int, int);
 extern struct GenericAttrFormat *udf_add_extendedattr(struct inode *, Uint32, Uint32, Uint8, struct buffer_head **);
 extern struct GenericAttrFormat *udf_get_extendedattr(struct inode *, Uint32, Uint8, struct buffer_head **);
@@ -165,18 +158,17 @@
 extern Uint32 udf_get_pblock_virt15(struct super_block *, Uint32, Uint16, Uint32);
 extern Uint32 udf_get_pblock_virt20(struct super_block *, Uint32, Uint16, Uint32);
 extern Uint32 udf_get_pblock_spar15(struct super_block *, Uint32, Uint16, Uint32);
-extern void udf_fill_spartable(struct super_block *, struct udf_sparing_data *, int);
+extern int udf_relocate_blocks(struct super_block *, long, long *);
 
 /* unicode.c */
-extern int udf_get_filename(Uint8 *, Uint8 *, int);
+extern int udf_get_filename(struct super_block *, Uint8 *, Uint8 *, int);
 
 /* ialloc.c */
 extern void udf_free_inode(struct inode *);
 extern struct inode * udf_new_inode (const struct inode *, int, int *);
 
 /* truncate.c */
-extern void udf_trunc(struct inode *);
-extern void udf_truncate(struct inode *);
+extern void udf_truncate_extents(struct inode *);
 
 /* balloc.c */
 extern void udf_free_blocks(const struct inode *, lb_addr, Uint32, Uint32);
@@ -184,7 +176,8 @@
 extern int udf_new_block(const struct inode *, Uint16, Uint32, int *);
 
 /* fsync.c */
-extern int udf_sync_file(struct file *, struct dentry *, int);
+extern int udf_fsync_file(struct file *, struct dentry *, int);
+extern int udf_fsync_inode(struct inode *, int);
 
 /* directory.c */
 extern Uint8 * udf_filead_read(struct inode *, Uint8 *, Uint8, lb_addr, int *, int *, struct buffer_head **, int *);
@@ -206,6 +199,10 @@
 extern int udf_build_ustr_exact(struct ustr *, dstring *, int);
 extern int udf_CS0toUTF8(struct ustr *, struct ustr *);
 extern int udf_UTF8toCS0(dstring *, struct ustr *, int);
+#ifdef __KERNEL__
+extern int udf_CS0toNLS(struct nls_table *, struct ustr *, struct ustr *);
+extern int udf_NLStoCS0(struct nls_table *, dstring *, struct ustr *, int);
+#endif
 
 /* crc.c */
 extern Uint16 udf_crc(Uint8 *, Uint32, Uint16);
diff -u --recursive --new-file v2.4.5/linux/fs/udf/udfend.h linux/fs/udf/udfend.h
--- v2.4.5/linux/fs/udf/udfend.h	Mon Dec 11 13:27:05 2000
+++ linux/fs/udf/udfend.h	Mon Jun 11 19:15:27 2001
@@ -80,6 +80,22 @@
 	return out;
 }
 
+static inline short_ad lesa_to_cpu(short_ad in)
+{
+	short_ad out;
+	out.extLength = le32_to_cpu(in.extLength);
+	out.extPosition = le32_to_cpu(in.extPosition);
+	return out;
+}
+
+static inline short_ad cpu_to_lesa(short_ad in)
+{
+	short_ad out;
+	out.extLength = cpu_to_le32(in.extLength);
+	out.extPosition = cpu_to_le32(in.extPosition);
+	return out;
+}
+
 static inline long_ad lela_to_cpu(long_ad in)
 {
 	long_ad out;
diff -u --recursive --new-file v2.4.5/linux/fs/udf/udftime.c linux/fs/udf/udftime.c
--- v2.4.5/linux/fs/udf/udftime.c	Thu Mar  2 11:17:32 2000
+++ linux/fs/udf/udftime.c	Mon Jun 11 19:15:27 2001
@@ -105,6 +105,8 @@
 		offset = src.typeAndTimezone << 4;
 		/* sign extent offset */
 		offset = (offset >> 4);
+		if (offset == -2047) /* unspecified offset */
+			offset = 0;
 	}
 	else
 		offset = 0;
diff -u --recursive --new-file v2.4.5/linux/fs/udf/unicode.c linux/fs/udf/unicode.c
--- v2.4.5/linux/fs/udf/unicode.c	Mon Mar 20 08:17:43 2000
+++ linux/fs/udf/unicode.c	Mon Jun 11 19:15:27 2001
@@ -14,7 +14,7 @@
  * CONTACTS
  *	E-mail regarding any portion of the Linux UDF file system should be
  *	directed to the development team's mailing list (run by majordomo):
- *		linux_udf@hootie.lvld.hp.com
+ *		linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
@@ -27,7 +27,9 @@
 #ifdef __KERNEL__
 #include <linux/kernel.h>
 #include <linux/string.h>	/* for memset */
+#include <linux/nls.h>
 #include <linux/udf_fs.h>
+#include "udf_sb.h"
 #else
 #include <string.h>
 #endif
@@ -127,7 +129,7 @@
 }
 
 /*
- * udf_ocu_to_udf8
+ * udf_ocu_to_utf8
  *
  * PURPOSE
  *	Convert OSTA Compressed Unicode to the UTF-8 equivalent.
@@ -327,7 +329,88 @@
 }
 
 #ifdef __KERNEL__
-int udf_get_filename(Uint8 *sname, Uint8 *dname, int flen)
+int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, struct ustr *ocu_i)
+{
+	Uint8 *ocu;
+	Uint32 c;
+	Uint8 cmp_id, ocu_len;
+	int i;
+
+	ocu = ocu_i->u_name;
+
+	ocu_len = ocu_i->u_len;
+	cmp_id = ocu_i->u_cmpID;
+	utf_o->u_len = 0;
+
+	if (ocu_len == 0)
+	{
+		memset(utf_o, 0, sizeof(struct ustr));
+		utf_o->u_cmpID = 0;
+		utf_o->u_len = 0;
+		return 0;
+	}
+
+	if ((cmp_id != 8) && (cmp_id != 16))
+	{
+		printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n", cmp_id, ocu_i->u_name);
+		return 0;
+	}
+
+	for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN-3)) ;)
+	{
+		/* Expand OSTA compressed Unicode to Unicode */
+		c = ocu[i++];
+		if (cmp_id == 16)
+			c = (c << 8) | ocu[i++];
+
+		utf_o->u_len += nls->uni2char(c, &utf_o->u_name[utf_o->u_len], 
+			UDF_NAME_LEN - utf_o->u_len);
+	}
+	utf_o->u_cmpID=8;
+	utf_o->u_hash=0L;
+	utf_o->padding=0;
+
+	return utf_o->u_len;
+}
+
+int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni, int length)
+{
+	unsigned len, i, max_val;
+	Uint16 uni_char;
+	int uni_cnt;
+	int u_len = 0;
+
+	memset(ocu, 0, sizeof(dstring) * length);
+	ocu[0] = 8;
+	max_val = 0xffU;
+
+try_again:
+	uni_char = 0U;
+	uni_cnt = 0U;
+	for (i = 0U; i < uni->u_len; i++)
+	{
+		len = nls->char2uni(&uni->u_name[i], uni->u_len-i, &uni_char);
+
+		if (len == 2 && max_val == 0xff)
+		{
+			max_val = 0xffffU;
+			ocu[0] = (Uint8)0x10U;
+			goto try_again;
+		}
+		
+		if (max_val == 0xffffU)
+		{
+			ocu[++u_len] = (Uint8)(uni_char >> 8);
+			i++;
+		}
+		ocu[++u_len] = (Uint8)(uni_char & 0xffU);
+	}
+
+	ocu[length - 1] = (Uint8)u_len + 1;
+	return u_len + 1;
+}
+
+int udf_get_filename(struct super_block *sb, Uint8 *sname, Uint8 *dname, int flen)
 {
 	struct ustr filename, unifilename;
 	int len;
@@ -337,11 +420,24 @@
 		return 0;
 	}
 
-	if (!udf_CS0toUTF8(&filename, &unifilename) )
+	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8))
 	{
-		udf_debug("Failed in udf_get_filename: sname = %s\n", sname);
-		return 0;
+		if (!udf_CS0toUTF8(&filename, &unifilename) )
+		{
+			udf_debug("Failed in udf_get_filename: sname = %s\n", sname);
+			return 0;
+		}
+	}
+	else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
+	{
+		if (!udf_CS0toNLS(UDF_SB(sb)->s_nls_map, &filename, &unifilename) )
+		{
+			udf_debug("Failed in udf_get_filename: sname = %s\n", sname);
+			return 0;
+		}
 	}
+	else
+		return 0;
 
 	if ((len = udf_translate_to_linux(dname, filename.u_name, filename.u_len,
 		unifilename.u_name, unifilename.u_len)))
diff -u --recursive --new-file v2.4.5/linux/include/asm-alpha/delay.h linux/include/asm-alpha/delay.h
--- v2.4.5/linux/include/asm-alpha/delay.h	Tue Jan  2 16:45:37 2001
+++ linux/include/asm-alpha/delay.h	Wed Jun 20 11:10:27 2001
@@ -1,48 +1,8 @@
 #ifndef __ALPHA_DELAY_H
 #define __ALPHA_DELAY_H
 
-#include <linux/config.h>
-#include <asm/param.h>
-#include <asm/smp.h>
-
-/*
- * Copyright (C) 1993, 2000 Linus Torvalds
- *
- * Delay routines, using a pre-computed "loops_per_jiffy" value.
- */
-
-/*
- * Use only for very small delays (< 1 msec). 
- *
- * The active part of our cycle counter is only 32-bits wide, and
- * we're treating the difference between two marks as signed.  On
- * a 1GHz box, that's about 2 seconds.
- */
-
-extern __inline__ void
-__delay(int loops)
-{
-	int tmp;
-	__asm__ __volatile__(
-		"	rpcc %0\n"
-		"	addl %1,%0,%1\n"
-		"1:	rpcc %0\n"
-		"	subl %1,%0,%0\n"
-		"	bgt %0,1b"
-		: "=&r" (tmp), "=r" (loops) : "1"(loops));
-}
-
-extern __inline__ void
-__udelay(unsigned long usecs, unsigned long lpj)
-{
-	usecs *= (((unsigned long)HZ << 32) / 1000000) * lpj;
-	__delay((long)usecs >> 32);
-}
-
-#ifdef CONFIG_SMP
-#define udelay(u)  __udelay((u), cpu_data[smp_processor_id()].loops_per_jiffy)
-#else
-#define udelay(u)  __udelay((u), loops_per_jiffy)
-#endif
+extern void __delay(int loops);
+extern void __udelay(unsigned long usecs, unsigned long lpj);
+extern void udelay(unsigned long usecs);
 
 #endif /* defined(__ALPHA_DELAY_H) */
diff -u --recursive --new-file v2.4.5/linux/include/asm-alpha/hardirq.h linux/include/asm-alpha/hardirq.h
--- v2.4.5/linux/include/asm-alpha/hardirq.h	Fri Aug  4 16:15:37 2000
+++ linux/include/asm-alpha/hardirq.h	Mon Jun 11 19:15:27 2001
@@ -6,8 +6,7 @@
 
 /* entry.S is sensitive to the offsets of these fields */
 typedef struct {
-	unsigned int __softirq_active;
-	unsigned int __softirq_mask;
+	unsigned long __softirq_pending;
 	unsigned int __local_irq_count;
 	unsigned int __local_bh_count;
 	unsigned int __syscall_count;
diff -u --recursive --new-file v2.4.5/linux/include/asm-alpha/linux_logo.h linux/include/asm-alpha/linux_logo.h
--- v2.4.5/linux/include/asm-alpha/linux_logo.h	Thu Oct  1 10:02:22 1998
+++ linux/include/asm-alpha/linux_logo.h	Mon Jun 11 19:15:27 2001
@@ -23,26 +23,5 @@
 
 #define linux_logo_banner "Linux/AXP version " UTS_RELEASE
 
-#define LINUX_LOGO_COLORS 214
-
-#ifdef INCLUDE_LINUX_LOGO_DATA
-
-#define INCLUDE_LINUX_LOGOBW
-#define INCLUDE_LINUX_LOGO16
-
 #include <linux/linux_logo.h>
 
-#else
-
-/* prototypes only */
-extern unsigned char linux_logo_red[];
-extern unsigned char linux_logo_green[];
-extern unsigned char linux_logo_blue[];
-extern unsigned char linux_logo[];
-extern unsigned char linux_logo_bw[];
-extern unsigned char linux_logo16_red[];
-extern unsigned char linux_logo16_green[];
-extern unsigned char linux_logo16_blue[];
-extern unsigned char linux_logo16[];
-
-#endif
diff -u --recursive --new-file v2.4.5/linux/include/asm-alpha/socket.h linux/include/asm-alpha/socket.h
--- v2.4.5/linux/include/asm-alpha/socket.h	Sat Feb  3 11:26:44 2001
+++ linux/include/asm-alpha/socket.h	Wed Jun 20 21:00:55 2001
@@ -66,6 +66,7 @@
 					/* level.  For writing rarp and	*/
 					/* other similar things on the	*/
 					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
 #endif
 
 #endif /* _ASM_SOCKET_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-alpha/softirq.h linux/include/asm-alpha/softirq.h
--- v2.4.5/linux/include/asm-alpha/softirq.h	Sun Aug  6 12:42:21 2000
+++ linux/include/asm-alpha/softirq.h	Mon Jun 11 19:15:27 2001
@@ -18,8 +18,11 @@
 }
 
 #define local_bh_enable()	cpu_bh_enable(smp_processor_id())
+#define __local_bh_enable	local_bh_enable
 #define local_bh_disable()	cpu_bh_disable(smp_processor_id())
 
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
+
+#define __cpu_raise_softirq(cpu,nr) set_bit((nr), &softirq_pending(cpu))
 
 #endif /* _ALPHA_SOFTIRQ_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-alpha/termios.h linux/include/asm-alpha/termios.h
--- v2.4.5/linux/include/asm-alpha/termios.h	Sat Feb  3 20:00:45 2001
+++ linux/include/asm-alpha/termios.h	Mon Jun 11 19:15:27 2001
@@ -82,6 +82,7 @@
 #define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
 #define N_HDLC		13	/* synchronous HDLC */
 #define N_SYNC_PPP	14
+#define N_HCI		15  /* Bluetooth HCI UART */
 
 #ifdef __KERNEL__
 /*	eof=^D		eol=\0		eol2=\0		erase=del
diff -u --recursive --new-file v2.4.5/linux/include/asm-arm/bitops.h linux/include/asm-arm/bitops.h
--- v2.4.5/linux/include/asm-arm/bitops.h	Mon Nov 27 17:07:59 2000
+++ linux/include/asm-arm/bitops.h	Wed Jun 27 14:12:04 2001
@@ -24,12 +24,62 @@
  * Function prototypes to keep gcc -Wall happy.
  */
 extern void set_bit(int nr, volatile void * addr);
+
+static inline void __set_bit(int nr, volatile void *addr)
+{
+	((unsigned char *) addr)[nr >> 3] |= (1U << (nr & 7));
+}
+
 extern void clear_bit(int nr, volatile void * addr);
+
+static inline void __clear_bit(int nr, volatile void *addr)
+{
+	((unsigned char *) addr)[nr >> 3] &= ~(1U << (nr & 7));
+}
+
 extern void change_bit(int nr, volatile void * addr);
 
+static inline void __change_bit(int nr, volatile void *addr)
+{
+	((unsigned char *) addr)[nr >> 3] ^= (1U << (nr & 7));
+}
+
 extern int test_and_set_bit(int nr, volatile void * addr);
+
+static inline int __test_and_set_bit(int nr, volatile void *addr)
+{
+	unsigned int mask = 1 << (nr & 7);
+	unsigned int oldval;
+
+	oldval = ((unsigned char *) addr)[nr >> 3];
+	((unsigned char *) addr)[nr >> 3] = oldval | mask;
+	return oldval & mask;
+}
+
 extern int test_and_clear_bit(int nr, volatile void * addr);
+
+static inline int __test_and_clear_bit(int nr, volatile void *addr)
+{
+	unsigned int mask = 1 << (nr & 7);
+	unsigned int oldval;
+
+	oldval = ((unsigned char *) addr)[nr >> 3];
+	((unsigned char *) addr)[nr >> 3] = oldval & ~mask;
+	return oldval & mask;
+}
+
 extern int test_and_change_bit(int nr, volatile void * addr);
+
+static inline int __test_and_change_bit(int nr, volatile void *addr)
+{
+	unsigned int mask = 1 << (nr & 7);
+	unsigned int oldval;
+
+	oldval = ((unsigned char *) addr)[nr >> 3];
+	((unsigned char *) addr)[nr >> 3] = oldval ^ mask;
+	return oldval & mask;
+}
+
 extern int find_first_zero_bit(void * addr, unsigned size);
 extern int find_next_zero_bit(void * addr, int size, int offset);
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-arm/io.h linux/include/asm-arm/io.h
--- v2.4.5/linux/include/asm-arm/io.h	Thu Apr 12 12:20:31 2001
+++ linux/include/asm-arm/io.h	Wed Jun 27 14:12:04 2001
@@ -119,7 +119,7 @@
  * is in pci.h
  */
 extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle);
-extern void consistent_free(void *vaddr);
+extern void consistent_free(void *vaddr, size_t size, dma_addr_t handle);
 extern void consistent_sync(void *vaddr, size_t size, int rw);
 
 #define __raw_writeb(v,a)		__arch_putb(v,a)
diff -u --recursive --new-file v2.4.5/linux/include/asm-arm/linux_logo.h linux/include/asm-arm/linux_logo.h
--- v2.4.5/linux/include/asm-arm/linux_logo.h	Thu Feb  8 16:32:44 2001
+++ linux/include/asm-arm/linux_logo.h	Mon Jun 11 19:15:27 2001
@@ -15,26 +15,5 @@
 
 #define linux_logo_banner "ARM Linux version " UTS_RELEASE
 
-#define LINUX_LOGO_COLORS	214
-
-#ifdef INCLUDE_LINUX_LOGO_DATA
-
-#define INCLUDE_LINUX_LOGOBW
-#define INCLUDE_LINUX_LOGO16
-
 #include <linux/linux_logo.h>
 
-#else
-
-/* prototypes only */
-extern unsigned char linux_logo_red[];
-extern unsigned char linux_logo_green[];
-extern unsigned char linux_logo_blue[];
-extern unsigned char linux_logo[];
-extern unsigned char linux_logo_bw[];
-extern unsigned char linux_logo16[];
-extern unsigned char *linux_serial_image;
-
-extern int (*console_show_logo)(void);
-
-#endif
diff -u --recursive --new-file v2.4.5/linux/include/asm-arm/pci.h linux/include/asm-arm/pci.h
--- v2.4.5/linux/include/asm-arm/pci.h	Wed May 16 10:31:27 2001
+++ linux/include/asm-arm/pci.h	Wed Jun 27 14:12:04 2001
@@ -41,7 +41,7 @@
 pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr,
 		    dma_addr_t dma_handle)
 {
-	consistent_free(vaddr);
+	consistent_free(vaddr, size, dma_handle);
 }
 
 /* Map a single buffer of the indicated size for DMA in streaming mode.
diff -u --recursive --new-file v2.4.5/linux/include/asm-arm/proc-armo/system.h linux/include/asm-arm/proc-armo/system.h
--- v2.4.5/linux/include/asm-arm/proc-armo/system.h	Mon Sep 18 15:15:24 2000
+++ linux/include/asm-arm/proc-armo/system.h	Wed Jun 27 14:12:04 2001
@@ -12,6 +12,8 @@
 
 #include <asm/proc-fns.h>
 
+#define vectors_base()	(0)
+
 extern __inline__ unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
 {
 	extern void __bad_xchg(volatile void *, int);
diff -u --recursive --new-file v2.4.5/linux/include/asm-arm/proc-armv/system.h linux/include/asm-arm/proc-armv/system.h
--- v2.4.5/linux/include/asm-arm/proc-armv/system.h	Mon Nov 27 17:07:59 2000
+++ linux/include/asm-arm/proc-armv/system.h	Wed Jun 27 14:12:04 2001
@@ -17,8 +17,30 @@
 	"mcr	p15, 0, %0, c1, c0	@ set CR"	\
 	: : "r" (x))
 
+#define CR_M	(1 << 0)	/* MMU enable				*/
+#define CR_A	(1 << 1)	/* Alignment abort enable		*/
+#define CR_C	(1 << 2)	/* Dcache enable			*/
+#define CR_W	(1 << 3)	/* Write buffer enable			*/
+#define CR_P	(1 << 4)	/* 32-bit exception handler		*/
+#define CR_D	(1 << 5)	/* 32-bit data address range		*/
+#define CR_L	(1 << 6)	/* Implementation defined		*/
+#define CD_B	(1 << 7)	/* Big endian				*/
+#define CR_S	(1 << 8)	/* System MMU protection		*/
+#define CD_R	(1 << 9)	/* ROM MMU protection			*/
+#define CR_F	(1 << 10)	/* Implementation defined		*/
+#define CR_Z	(1 << 11)	/* Implementation defined		*/
+#define CR_I	(1 << 12)	/* Icache enable			*/
+#define CR_V	(1 << 13)	/* Vectors relocated to 0xffff0000	*/
+#define CR_RR	(1 << 14)	/* Round Robin cache replacement	*/
+
 extern unsigned long cr_no_alignment;	/* defined in entry-armv.S */
 extern unsigned long cr_alignment;	/* defined in entry-armv.S */
+
+#ifdef __ARM_ARCH_4__
+#define vectors_base()	((cr_alignment & CR_V) ? 0xffff0000 : 0)
+#else
+#define vectors_base()	(0)
+#endif
 
 /*
  * A couple of speedups for the ARM
diff -u --recursive --new-file v2.4.5/linux/include/asm-arm/socket.h linux/include/asm-arm/socket.h
--- v2.4.5/linux/include/asm-arm/socket.h	Sat Feb  3 11:26:44 2001
+++ linux/include/asm-arm/socket.h	Wed Jun 20 21:00:55 2001
@@ -58,6 +58,7 @@
 					/* level.  For writing rarp and	*/
 					/* other similar things on the	*/
 					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
 #endif
 
 #endif /* _ASM_SOCKET_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-arm/termios.h linux/include/asm-arm/termios.h
--- v2.4.5/linux/include/asm-arm/termios.h	Sat Feb  3 20:00:45 2001
+++ linux/include/asm-arm/termios.h	Mon Jun 11 19:15:27 2001
@@ -65,6 +65,7 @@
 #define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
 #define N_HDLC		13	/* synchronous HDLC */
 #define N_SYNC_PPP	14
+#define N_HCI		15  /* Bluetooth HCI UART */
 
 #ifdef __KERNEL__
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-arm/xor.h linux/include/asm-arm/xor.h
--- v2.4.5/linux/include/asm-arm/xor.h	Thu Apr 12 12:20:31 2001
+++ linux/include/asm-arm/xor.h	Wed Jun 27 14:12:04 2001
@@ -7,290 +7,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
-/*
- *  linux/include/asm-arm/xor.h
- *
- *  Copyright (C) 2001 Russell King
- *
- * 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.
- */
-
-/*
- *  linux/include/asm-arm/xor.h
- *
- *  Copyright (C) 2001 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
 #include <asm-generic/xor.h>
-
-#define __XOR(a1, a2) a1 ^= a2
-
-#define GET_BLOCK_2(dst) \
-	__asm__("ldmia	%0, {%1, %2}" \
-		: "=r" (dst), "=r" (a1), "=r" (a2) \
-		: "0" (dst))
-
-#define GET_BLOCK_4(dst) \
-	__asm__("ldmia	%0, {%1, %2, %3, %4}" \
-		: "=r" (dst), "=r" (a1), "=r" (a2), "=r" (a3), "=r" (a4) \
-		: "0" (dst))
-
-#define XOR_BLOCK_2(src) \
-	__asm__("ldmia	%0!, {%1, %2}" \
-		: "=r" (src), "=r" (b1), "=r" (b2) \
-		: "0" (src)); \
-	__XOR(a1, b1); __XOR(a2, b2);
-
-#define XOR_BLOCK_4(src) \
-	__asm__("ldmia	%0!, {%1, %2, %3, %4}" \
-		: "=r" (src), "=r" (b1), "=r" (b2), "=r" (b3), "=r" (b4) \
-		: "0" (src)); \
-	__XOR(a1, b1); __XOR(a2, b2); __XOR(a3, b3); __XOR(a4, b4)
-
-#define PUT_BLOCK_2(dst) \
-	__asm__ __volatile__("stmia	%0!, {%2, %3}" \
-		: "=r" (dst) \
-		: "0" (dst), "r" (a1), "r" (a2))
-
-#define PUT_BLOCK_4(dst) \
-	__asm__ __volatile__("stmia	%0!, {%2, %3, %4, %5}" \
-		: "=r" (dst) \
-		: "0" (dst), "r" (a1), "r" (a2), "r" (a3), "r" (a4))
-
-static void
-xor_arm4regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
-{
-	unsigned int lines = bytes / sizeof(unsigned long) / 4;
-	register unsigned int a1 __asm__("r4");
-	register unsigned int a2 __asm__("r5");
-	register unsigned int a3 __asm__("r6");
-	register unsigned int a4 __asm__("r7");
-	register unsigned int b1 __asm__("r8");
-	register unsigned int b2 __asm__("r9");
-	register unsigned int b3 __asm__("ip");
-	register unsigned int b4 __asm__("lr");
-
-	do {
-		GET_BLOCK_4(p1);
-		XOR_BLOCK_4(p2);
-		PUT_BLOCK_4(p1);
-	} while (--lines);
-}
-
-static void
-xor_arm4regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-		unsigned long *p3)
-{
-	unsigned int lines = bytes / sizeof(unsigned long) / 4;
-	register unsigned int a1 __asm__("r4");
-	register unsigned int a2 __asm__("r5");
-	register unsigned int a3 __asm__("r6");
-	register unsigned int a4 __asm__("r7");
-	register unsigned int b1 __asm__("r8");
-	register unsigned int b2 __asm__("r9");
-	register unsigned int b3 __asm__("ip");
-	register unsigned int b4 __asm__("lr");
-
-	do {
-		GET_BLOCK_4(p1);
-		XOR_BLOCK_4(p2);
-		XOR_BLOCK_4(p3);
-		PUT_BLOCK_4(p1);
-	} while (--lines);
-}
-
-static void
-xor_arm4regs_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-		unsigned long *p3, unsigned long *p4)
-{
-	unsigned int lines = bytes / sizeof(unsigned long) / 2;
-	register unsigned int a1 __asm__("r8");
-	register unsigned int a2 __asm__("r9");
-	register unsigned int b1 __asm__("ip");
-	register unsigned int b2 __asm__("lr");
-
-	do {
-		GET_BLOCK_2(p1);
-		XOR_BLOCK_2(p2);
-		XOR_BLOCK_2(p3);
-		XOR_BLOCK_2(p4);
-		PUT_BLOCK_2(p1);
-	} while (--lines);
-}
-
-static void
-xor_arm4regs_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-		unsigned long *p3, unsigned long *p4, unsigned long *p5)
-{
-	unsigned int lines = bytes / sizeof(unsigned long) / 2;
-	register unsigned int a1 __asm__("r8");
-	register unsigned int a2 __asm__("r9");
-	register unsigned int b1 __asm__("ip");
-	register unsigned int b2 __asm__("lr");
-
-	do {
-		GET_BLOCK_2(p1);
-		XOR_BLOCK_2(p2);
-		XOR_BLOCK_2(p3);
-		XOR_BLOCK_2(p4);
-		XOR_BLOCK_2(p5);
-		PUT_BLOCK_2(p1);
-	} while (--lines);
-}
-
-static struct xor_block_template xor_block_arm4regs = {
-	name:	"arm4regs",
-	do_2:	xor_arm4regs_2,
-	do_3:	xor_arm4regs_3,
-	do_4:	xor_arm4regs_4,
-	do_5:	xor_arm4regs_5,
-};
-
-#undef XOR_TRY_TEMPLATES
-#define XOR_TRY_TEMPLATES			\
-	do {					\
-		xor_speed(&xor_block_arm4regs);	\
-		xor_speed(&xor_block_8regs);	\
-		xor_speed(&xor_block_32regs);	\
-	} while (0)
-
-#define __XOR(a1, a2) a1 ^= a2
-
-#define GET_BLOCK_2(dst) \
-	__asm__("ldmia	%0, {%1, %2}" \
-		: "=r" (dst), "=r" (a1), "=r" (a2) \
-		: "0" (dst))
-
-#define GET_BLOCK_4(dst) \
-	__asm__("ldmia	%0, {%1, %2, %3, %4}" \
-		: "=r" (dst), "=r" (a1), "=r" (a2), "=r" (a3), "=r" (a4) \
-		: "0" (dst))
-
-#define XOR_BLOCK_2(src) \
-	__asm__("ldmia	%0!, {%1, %2}" \
-		: "=r" (src), "=r" (b1), "=r" (b2) \
-		: "0" (src)); \
-	__XOR(a1, b1); __XOR(a2, b2);
-
-#define XOR_BLOCK_4(src) \
-	__asm__("ldmia	%0!, {%1, %2, %3, %4}" \
-		: "=r" (src), "=r" (b1), "=r" (b2), "=r" (b3), "=r" (b4) \
-		: "0" (src)); \
-	__XOR(a1, b1); __XOR(a2, b2); __XOR(a3, b3); __XOR(a4, b4)
-
-#define PUT_BLOCK_2(dst) \
-	__asm__ __volatile__("stmia	%0!, {%2, %3}" \
-		: "=r" (dst) \
-		: "0" (dst), "r" (a1), "r" (a2))
-
-#define PUT_BLOCK_4(dst) \
-	__asm__ __volatile__("stmia	%0!, {%2, %3, %4, %5}" \
-		: "=r" (dst) \
-		: "0" (dst), "r" (a1), "r" (a2), "r" (a3), "r" (a4))
-
-static void
-xor_arm4regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
-{
-	unsigned int lines = bytes / sizeof(unsigned long) / 4;
-	register unsigned int a1 __asm__("r4");
-	register unsigned int a2 __asm__("r5");
-	register unsigned int a3 __asm__("r6");
-	register unsigned int a4 __asm__("r7");
-	register unsigned int b1 __asm__("r8");
-	register unsigned int b2 __asm__("r9");
-	register unsigned int b3 __asm__("ip");
-	register unsigned int b4 __asm__("lr");
-
-	do {
-		GET_BLOCK_4(p1);
-		XOR_BLOCK_4(p2);
-		PUT_BLOCK_4(p1);
-	} while (--lines);
-}
-
-static void
-xor_arm4regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-		unsigned long *p3)
-{
-	unsigned int lines = bytes / sizeof(unsigned long) / 4;
-	register unsigned int a1 __asm__("r4");
-	register unsigned int a2 __asm__("r5");
-	register unsigned int a3 __asm__("r6");
-	register unsigned int a4 __asm__("r7");
-	register unsigned int b1 __asm__("r8");
-	register unsigned int b2 __asm__("r9");
-	register unsigned int b3 __asm__("ip");
-	register unsigned int b4 __asm__("lr");
-
-	do {
-		GET_BLOCK_4(p1);
-		XOR_BLOCK_4(p2);
-		XOR_BLOCK_4(p3);
-		PUT_BLOCK_4(p1);
-	} while (--lines);
-}
-
-static void
-xor_arm4regs_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-		unsigned long *p3, unsigned long *p4)
-{
-	unsigned int lines = bytes / sizeof(unsigned long) / 2;
-	register unsigned int a1 __asm__("r8");
-	register unsigned int a2 __asm__("r9");
-	register unsigned int b1 __asm__("ip");
-	register unsigned int b2 __asm__("lr");
-
-	do {
-		GET_BLOCK_2(p1);
-		XOR_BLOCK_2(p2);
-		XOR_BLOCK_2(p3);
-		XOR_BLOCK_2(p4);
-		PUT_BLOCK_2(p1);
-	} while (--lines);
-}
-
-static void
-xor_arm4regs_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-		unsigned long *p3, unsigned long *p4, unsigned long *p5)
-{
-	unsigned int lines = bytes / sizeof(unsigned long) / 2;
-	register unsigned int a1 __asm__("r8");
-	register unsigned int a2 __asm__("r9");
-	register unsigned int b1 __asm__("ip");
-	register unsigned int b2 __asm__("lr");
-
-	do {
-		GET_BLOCK_2(p1);
-		XOR_BLOCK_2(p2);
-		XOR_BLOCK_2(p3);
-		XOR_BLOCK_2(p4);
-		XOR_BLOCK_2(p5);
-		PUT_BLOCK_2(p1);
-	} while (--lines);
-}
-
-static struct xor_block_template xor_block_arm4regs = {
-	name:	"arm4regs",
-	do_2:	xor_arm4regs_2,
-	do_3:	xor_arm4regs_3,
-	do_4:	xor_arm4regs_4,
-	do_5:	xor_arm4regs_5,
-};
-
-#undef XOR_TRY_TEMPLATES
-#define XOR_TRY_TEMPLATES			\
-	do {					\
-		xor_speed(&xor_block_arm4regs);	\
-		xor_speed(&xor_block_8regs);	\
-		xor_speed(&xor_block_32regs);	\
-	} while (0)
 
 #define __XOR(a1, a2) a1 ^= a2
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-cris/socket.h linux/include/asm-cris/socket.h
--- v2.4.5/linux/include/asm-cris/socket.h	Fri Apr  6 10:51:19 2001
+++ linux/include/asm-cris/socket.h	Wed Jun 20 21:00:55 2001
@@ -59,6 +59,7 @@
                                         /* level.  For writing rarp and */
                                         /* other similar things on the  */
                                         /* user level.                  */
+#define	SOCK_MAX	(SOCK_PACKET+1)
 #endif
 
 #endif /* _ASM_SOCKET_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-i386/hardirq.h linux/include/asm-i386/hardirq.h
--- v2.4.5/linux/include/asm-i386/hardirq.h	Fri May 25 18:01:27 2001
+++ linux/include/asm-i386/hardirq.h	Wed Jun 27 16:01:22 2001
@@ -5,10 +5,9 @@
 #include <linux/threads.h>
 #include <linux/irq.h>
 
-/* entry.S is sensitive to the offsets of these fields */
+/* assembly code in softirq.h is sensitive to the offsets of these fields */
 typedef struct {
-	unsigned int __softirq_active;
-	unsigned int __softirq_mask;
+	unsigned int __softirq_pending;
 	unsigned int __local_irq_count;
 	unsigned int __local_bh_count;
 	unsigned int __syscall_count;
diff -u --recursive --new-file v2.4.5/linux/include/asm-i386/hw_irq.h linux/include/asm-i386/hw_irq.h
--- v2.4.5/linux/include/asm-i386/hw_irq.h	Fri May 25 18:01:26 2001
+++ linux/include/asm-i386/hw_irq.h	Wed Jun 27 16:01:21 2001
@@ -13,6 +13,7 @@
  */
 
 #include <linux/config.h>
+#include <asm/atomic.h>
 #include <asm/irq.h>
 
 /*
@@ -83,7 +84,9 @@
 extern void send_IPI(int dest, int vector);
 
 extern unsigned long io_apic_irqs;
-extern volatile unsigned long irq_err_count;
+
+extern atomic_t irq_err_count;
+extern atomic_t irq_mis_count;
 
 extern char _stext, _etext;
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-i386/io_apic.h linux/include/asm-i386/io_apic.h
--- v2.4.5/linux/include/asm-i386/io_apic.h	Fri May 25 18:01:26 2001
+++ linux/include/asm-i386/io_apic.h	Wed Jun 27 16:01:21 2001
@@ -12,6 +12,8 @@
 
 #ifdef CONFIG_X86_IO_APIC
 
+#define APIC_MISMATCH_DEBUG
+
 #define IO_APIC_BASE(idx) \
 		((volatile int *)__fix_to_virt(FIX_IO_APIC_BASE_0 + idx))
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-i386/linux_logo.h linux/include/asm-i386/linux_logo.h
--- v2.4.5/linux/include/asm-i386/linux_logo.h	Fri May 25 18:02:51 2001
+++ linux/include/asm-i386/linux_logo.h	Mon Jun 11 19:15:27 2001
@@ -23,26 +23,5 @@
 
 #define linux_logo_banner "Linux/ia32 version " UTS_RELEASE
 
-#define LINUX_LOGO_COLORS 214
-
-#ifdef INCLUDE_LINUX_LOGO_DATA
-
-#define INCLUDE_LINUX_LOGOBW
-#define INCLUDE_LINUX_LOGO16
-
 #include <linux/linux_logo.h>
 
-#else
-
-/* prototypes only */
-extern unsigned char linux_logo_red[];
-extern unsigned char linux_logo_green[];
-extern unsigned char linux_logo_blue[];
-extern unsigned char linux_logo[];
-extern unsigned char linux_logo_bw[];
-extern unsigned char linux_logo16_red[];
-extern unsigned char linux_logo16_green[];
-extern unsigned char linux_logo16_blue[];
-extern unsigned char linux_logo16[];
-
-#endif
diff -u --recursive --new-file v2.4.5/linux/include/asm-i386/mca_dma.h linux/include/asm-i386/mca_dma.h
--- v2.4.5/linux/include/asm-i386/mca_dma.h	Wed Apr 12 09:47:29 2000
+++ linux/include/asm-i386/mca_dma.h	Tue Jun 12 11:06:54 2001
@@ -199,4 +199,4 @@
 	outb(mode, MCA_DMA_REG_EXE);
 }
 
-#endif MCA_DMA_H
+#endif /* MCA_DMA_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-i386/pci.h linux/include/asm-i386/pci.h
--- v2.4.5/linux/include/asm-i386/pci.h	Fri May 25 18:02:07 2001
+++ linux/include/asm-i386/pci.h	Wed Jun 27 16:01:49 2001
@@ -1,13 +1,19 @@
 #ifndef __i386_PCI_H
 #define __i386_PCI_H
 
+#include <linux/config.h>
+
 #ifdef __KERNEL__
 
 /* Can be used to override the logic in pci_scan_bus for skipping
    already-configured bus numbers - to be used for buggy BIOSes
    or architectures with incomplete PCI setup by the loader */
 
+#ifdef CONFIG_PCI
+extern unsigned int pcibios_assign_all_busses(void);
+#else
 #define pcibios_assign_all_busses()	0
+#endif
 
 extern unsigned long pci_mem_start;
 #define PCIBIOS_MIN_IO		0x1000
diff -u --recursive --new-file v2.4.5/linux/include/asm-i386/socket.h linux/include/asm-i386/socket.h
--- v2.4.5/linux/include/asm-i386/socket.h	Sat Feb  3 11:26:44 2001
+++ linux/include/asm-i386/socket.h	Wed Jun 20 21:00:55 2001
@@ -58,6 +58,7 @@
 					/* level.  For writing rarp and	*/
 					/* other similar things on the	*/
 					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
 #endif
 
 #endif /* _ASM_SOCKET_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-i386/softirq.h linux/include/asm-i386/softirq.h
--- v2.4.5/linux/include/asm-i386/softirq.h	Fri May 25 18:01:27 2001
+++ linux/include/asm-i386/softirq.h	Wed Jun 27 16:01:22 2001
@@ -4,12 +4,46 @@
 #include <asm/atomic.h>
 #include <asm/hardirq.h>
 
-#define cpu_bh_disable(cpu)	do { local_bh_count(cpu)++; barrier(); } while (0)
-#define cpu_bh_enable(cpu)	do { barrier(); local_bh_count(cpu)--; } while (0)
+#define __cpu_bh_enable(cpu) \
+		do { barrier(); local_bh_count(cpu)--; } while (0)
+#define cpu_bh_disable(cpu) \
+		do { local_bh_count(cpu)++; barrier(); } while (0)
 
 #define local_bh_disable()	cpu_bh_disable(smp_processor_id())
-#define local_bh_enable()	cpu_bh_enable(smp_processor_id())
+#define __local_bh_enable()	__cpu_bh_enable(smp_processor_id())
+#define __cpu_raise_softirq(cpu,nr) set_bit((nr), &softirq_pending(cpu));
+#define raise_softirq(nr) __cpu_raise_softirq(smp_processor_id(), (nr))
 
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
+
+/*
+ * NOTE: this assembly code assumes:
+ *
+ *    (char *)&local_bh_count - 8 == (char *)&softirq_pending
+ *
+ * If you change the offsets in irq_stat then you have to
+ * update this code as well.
+ */
+#define local_bh_enable()						\
+do {									\
+	unsigned int *ptr = &local_bh_count(smp_processor_id());	\
+									\
+	if (!--*ptr)							\
+		__asm__ __volatile__ (					\
+			"cmpl $0, -8(%0);"				\
+			"jnz 2f;"					\
+			"1:;"						\
+									\
+			".section .text.lock,\"ax\";"			\
+			"2: pushl %%eax; pushl %%ecx; pushl %%edx;"	\
+			"call %c1;"					\
+			"popl %%edx; popl %%ecx; popl %%eax;"		\
+			"jmp 1b;"					\
+			".previous;"					\
+									\
+		: /* no output */					\
+		: "r" (ptr), "i" (do_softirq)				\
+		/* no registers clobbered */ );				\
+} while (0)
 
 #endif	/* __ASM_SOFTIRQ_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-i386/termios.h linux/include/asm-i386/termios.h
--- v2.4.5/linux/include/asm-i386/termios.h	Sat Feb  3 20:00:45 2001
+++ linux/include/asm-i386/termios.h	Mon Jun 11 19:15:27 2001
@@ -55,6 +55,7 @@
 #define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
 #define N_HDLC		13	/* synchronous HDLC */
 #define N_SYNC_PPP	14	/* synchronous PPP */
+#define N_HCI		15  /* Bluetooth HCI UART */
 
 #ifdef __KERNEL__
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-ia64/linux_logo.h linux/include/asm-ia64/linux_logo.h
--- v2.4.5/linux/include/asm-ia64/linux_logo.h	Sun Feb  6 18:42:40 2000
+++ linux/include/asm-ia64/linux_logo.h	Mon Jun 11 19:15:27 2001
@@ -24,26 +24,5 @@
 
 #define linux_logo_banner "Linux/ia64 version " UTS_RELEASE
 
-#define LINUX_LOGO_COLORS 214
-
-#ifdef INCLUDE_LINUX_LOGO_DATA
-
-#define INCLUDE_LINUX_LOGOBW
-#define INCLUDE_LINUX_LOGO16
-
 #include <linux/linux_logo.h>
 
-#else
-
-/* prototypes only */
-extern unsigned char linux_logo_red[];
-extern unsigned char linux_logo_green[];
-extern unsigned char linux_logo_blue[];
-extern unsigned char linux_logo[];
-extern unsigned char linux_logo_bw[];
-extern unsigned char linux_logo16_red[];
-extern unsigned char linux_logo16_green[];
-extern unsigned char linux_logo16_blue[];
-extern unsigned char linux_logo16[];
-
-#endif
diff -u --recursive --new-file v2.4.5/linux/include/asm-ia64/socket.h linux/include/asm-ia64/socket.h
--- v2.4.5/linux/include/asm-ia64/socket.h	Sat Feb  3 11:26:44 2001
+++ linux/include/asm-ia64/socket.h	Wed Jun 20 21:00:55 2001
@@ -65,6 +65,7 @@
 					/* level.  For writing rarp and	*/
 					/* other similar things on the	*/
 					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
 #endif
 
 #endif /* _ASM_IA64_SOCKET_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-ia64/termios.h linux/include/asm-ia64/termios.h
--- v2.4.5/linux/include/asm-ia64/termios.h	Sat Feb  3 20:00:45 2001
+++ linux/include/asm-ia64/termios.h	Mon Jun 11 19:15:27 2001
@@ -62,6 +62,7 @@
 #define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS msgs */
 #define N_HDLC		13	/* synchronous HDLC */
 #define N_SYNC_PPP	14	/* synchronous PPP */
+#define N_HCI		15  /* Bluetooth HCI UART */
 
 # ifdef __KERNEL__
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/amigahw.h linux/include/asm-m68k/amigahw.h
--- v2.4.5/linux/include/asm-m68k/amigahw.h	Mon Nov 27 17:57:34 2000
+++ linux/include/asm-m68k/amigahw.h	Mon Jun 11 19:15:27 2001
@@ -106,6 +106,7 @@
     AMIGAHW_DECLARE(ALICE_NTSC);	/* NTSC Alice (8374) */
     AMIGAHW_DECLARE(MAGIC_REKICK);	/* A3000 Magic Hard Rekick */
     AMIGAHW_DECLARE(PCMCIA);		/* PCMCIA Slot */
+    AMIGAHW_DECLARE(GG2_ISA);		/* GG2 Zorro2ISA Bridge */
     AMIGAHW_DECLARE(ZORRO);		/* Zorro AutoConfig */
     AMIGAHW_DECLARE(ZORRO3);		/* Zorro III */
 };
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/amigayle.h linux/include/asm-m68k/amigayle.h
--- v2.4.5/linux/include/asm-m68k/amigayle.h	Thu Jul 30 11:08:20 1998
+++ linux/include/asm-m68k/amigayle.h	Mon Jun 11 19:15:27 2001
@@ -17,8 +17,8 @@
 #ifndef _M68K_AMIGAYLE_H_
 #define _M68K_AMIGAYLE_H_
 
+#include <linux/types.h>
 #include <asm/amigahw.h>
-#include <asm/io.h>
 
 /* memory layout */
 
@@ -59,11 +59,13 @@
 
 #define gayle_attribute ((volatile u_char *)(GAYLE_ATTRIBUTE))
 
+#if 0
 #define gayle_inb(a) readb( GAYLE_IO+(a)+(((a)&1)*GAYLE_ODD) )
 #define gayle_outb(v,a) writeb( v, GAYLE_IO+(a)+(((a)&1)*GAYLE_ODD) )
 
 #define gayle_inw(a) readw( GAYLE_IO+(a) )
 #define gayle_outw(v,a) writew( v, GAYLE_IO+(a) )
+#endif
 
 /* GAYLE_CARDSTATUS bit def */
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/bitops.h linux/include/asm-m68k/bitops.h
--- v2.4.5/linux/include/asm-m68k/bitops.h	Sat Feb  3 11:26:44 2001
+++ linux/include/asm-m68k/bitops.h	Mon Jun 11 19:15:27 2001
@@ -19,23 +19,23 @@
    __constant_test_and_set_bit(nr, vaddr) : \
    __generic_test_and_set_bit(nr, vaddr))
 
-extern __inline__ int __constant_test_and_set_bit(int nr,void * vaddr)
+extern __inline__ int __constant_test_and_set_bit(int nr,volatile void * vaddr)
 {
 	char retval;
 
-	__asm__ __volatile__ ("bset %1,%2; sne %0"
-	     : "=d" (retval)
-	     : "di" (nr & 7), "m" (((char *)vaddr)[(nr^31) >> 3]));
+	__asm__ __volatile__ ("bset %2,%1; sne %0"
+	     : "=d" (retval), "+m" (((volatile char *)vaddr)[(nr^31) >> 3])
+	     : "di" (nr & 7));
 
 	return retval;
 }
 
-extern __inline__ int __generic_test_and_set_bit(int nr,void * vaddr)
+extern __inline__ int __generic_test_and_set_bit(int nr,volatile void * vaddr)
 {
 	char retval;
 
 	__asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
-	     : "=d" (retval) : "d" (nr^31), "a" (vaddr));
+	     : "=d" (retval) : "d" (nr^31), "a" (vaddr) : "memory");
 
 	return retval;
 }
@@ -45,16 +45,16 @@
    __constant_set_bit(nr, vaddr) : \
    __generic_set_bit(nr, vaddr))
 
-extern __inline__ void __constant_set_bit(int nr, void * vaddr)
+extern __inline__ void __constant_set_bit(int nr, volatile void * vaddr)
 {
-	__asm__ __volatile__ ("bset %0,%1"
-	     : : "di" (nr & 7), "m" (((char *)vaddr)[(nr^31) >> 3]));
+	__asm__ __volatile__ ("bset %1,%0"
+	     : "+m" (((volatile char *)vaddr)[(nr^31) >> 3]) : "di" (nr & 7));
 }
 
-extern __inline__ void __generic_set_bit(int nr, void * vaddr)
+extern __inline__ void __generic_set_bit(int nr, volatile void * vaddr)
 {
 	__asm__ __volatile__ ("bfset %1@{%0:#1}"
-	     : : "d" (nr^31), "a" (vaddr));
+	     : : "d" (nr^31), "a" (vaddr) : "memory");
 }
 
 #define test_and_clear_bit(nr,vaddr) \
@@ -62,23 +62,23 @@
    __constant_test_and_clear_bit(nr, vaddr) : \
    __generic_test_and_clear_bit(nr, vaddr))
 
-extern __inline__ int __constant_test_and_clear_bit(int nr, void * vaddr)
+extern __inline__ int __constant_test_and_clear_bit(int nr, volatile void * vaddr)
 {
 	char retval;
 
-	__asm__ __volatile__ ("bclr %1,%2; sne %0"
-	     : "=d" (retval)
-	     : "di" (nr & 7), "m" (((char *)vaddr)[(nr^31) >> 3]));
+	__asm__ __volatile__ ("bclr %2,%1; sne %0"
+	     : "=d" (retval), "+m" (((volatile char *)vaddr)[(nr^31) >> 3])
+	     : "di" (nr & 7));
 
 	return retval;
 }
 
-extern __inline__ int __generic_test_and_clear_bit(int nr, void * vaddr)
+extern __inline__ int __generic_test_and_clear_bit(int nr, volatile void * vaddr)
 {
 	char retval;
 
 	__asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0"
-	     : "=d" (retval) : "d" (nr^31), "a" (vaddr));
+	     : "=d" (retval) : "d" (nr^31), "a" (vaddr) : "memory");
 
 	return retval;
 }
@@ -94,16 +94,16 @@
    __constant_clear_bit(nr, vaddr) : \
    __generic_clear_bit(nr, vaddr))
 
-extern __inline__ void __constant_clear_bit(int nr, void * vaddr)
+extern __inline__ void __constant_clear_bit(int nr, volatile void * vaddr)
 {
-	__asm__ __volatile__ ("bclr %0,%1"
-	     : : "di" (nr & 7), "m" (((char *)vaddr)[(nr^31) >> 3]));
+	__asm__ __volatile__ ("bclr %1,%0"
+	     : "+m" (((volatile char *)vaddr)[(nr^31) >> 3]) : "di" (nr & 7));
 }
 
-extern __inline__ void __generic_clear_bit(int nr, void * vaddr)
+extern __inline__ void __generic_clear_bit(int nr, volatile void * vaddr)
 {
 	__asm__ __volatile__ ("bfclr %1@{%0:#1}"
-	     : : "d" (nr^31), "a" (vaddr));
+	     : : "d" (nr^31), "a" (vaddr) : "memory");
 }
 
 #define test_and_change_bit(nr,vaddr) \
@@ -111,23 +111,26 @@
    __constant_test_and_change_bit(nr, vaddr) : \
    __generic_test_and_change_bit(nr, vaddr))
 
-extern __inline__ int __constant_test_and_change_bit(int nr, void * vaddr)
+#define __test_and_change_bit(nr,vaddr) test_and_change_bit(nr,vaddr)
+#define __change_bit(nr,vaddr) change_bit(nr,vaddr)
+
+extern __inline__ int __constant_test_and_change_bit(int nr, volatile void * vaddr)
 {
 	char retval;
 
-	__asm__ __volatile__ ("bchg %1,%2; sne %0"
-	     : "=d" (retval)
-	     : "di" (nr & 7), "m" (((char *)vaddr)[(nr^31) >> 3]));
+	__asm__ __volatile__ ("bchg %2,%1; sne %0"
+	     : "=d" (retval), "+m" (((volatile char *)vaddr)[(nr^31) >> 3])
+	     : "di" (nr & 7));
 
 	return retval;
 }
 
-extern __inline__ int __generic_test_and_change_bit(int nr, void * vaddr)
+extern __inline__ int __generic_test_and_change_bit(int nr, volatile void * vaddr)
 {
 	char retval;
 
 	__asm__ __volatile__ ("bfchg %2@{%1:#1}; sne %0"
-	     : "=d" (retval) : "d" (nr^31), "a" (vaddr));
+	     : "=d" (retval) : "d" (nr^31), "a" (vaddr) : "memory");
 
 	return retval;
 }
@@ -137,21 +140,21 @@
    __constant_change_bit(nr, vaddr) : \
    __generic_change_bit(nr, vaddr))
 
-extern __inline__ void __constant_change_bit(int nr, void * vaddr)
+extern __inline__ void __constant_change_bit(int nr, volatile void * vaddr)
 {
-	__asm__ __volatile__ ("bchg %0,%1"
-	     : : "di" (nr & 7), "m" (((char *)vaddr)[(nr^31) >> 3]));
+	__asm__ __volatile__ ("bchg %1,%0"
+	     : "+m" (((volatile char *)vaddr)[(nr^31) >> 3]) : "di" (nr & 7));
 }
 
-extern __inline__ void __generic_change_bit(int nr, void * vaddr)
+extern __inline__ void __generic_change_bit(int nr, volatile void * vaddr)
 {
 	__asm__ __volatile__ ("bfchg %1@{%0:#1}"
-	     : : "d" (nr^31), "a" (vaddr));
+	     : : "d" (nr^31), "a" (vaddr) : "memory");
 }
 
-extern __inline__ int test_bit(int nr, const void * vaddr)
+extern __inline__ int test_bit(int nr, const volatile void * vaddr)
 {
-	return ((1UL << (nr & 31)) & (((const unsigned int *) vaddr)[nr >> 5])) != 0;
+	return ((1UL << (nr & 31)) & (((const volatile unsigned int *) vaddr)[nr >> 5])) != 0;
 }
 
 extern __inline__ int find_first_zero_bit(void * vaddr, unsigned size)
@@ -228,7 +231,7 @@
 {
 	int cnt;
 
-	asm ("bfffo %1{#0:#0},%0" : "=d" (cnt) : "dm" (x & -x));
+	__asm__ __volatile__("bfffo %1{#0:#0},%0" : "=d" (cnt) : "dm" (x & -x));
 
 	return 32 - cnt;
 }
@@ -268,12 +271,12 @@
 }
 
 extern __inline__ int
-minix_test_and_set_bit (int nr, void *vaddr)
+minix_test_and_set_bit (int nr, volatile void *vaddr)
 {
 	char retval;
 
 	__asm__ __volatile__ ("bfset %2{%1:#1}; sne %0"
-	     : "=d" (retval) : "d" (nr^15), "m" (*(char *)vaddr));
+	     : "=d" (retval) : "d" (nr^15), "m" (*(volatile char *)vaddr) : "memory");
 
 	return retval;
 }
@@ -281,50 +284,50 @@
 #define minix_set_bit(nr,addr)	((void)minix_test_and_set_bit(nr,addr))
 
 extern __inline__ int
-minix_test_and_clear_bit (int nr, void *vaddr)
+minix_test_and_clear_bit (int nr, volatile void *vaddr)
 {
 	char retval;
 
 	__asm__ __volatile__ ("bfclr %2{%1:#1}; sne %0"
-	     : "=d" (retval) : "d" (nr^15), "m" (*(char *) vaddr));
+	     : "=d" (retval) : "d" (nr^15), "m" (*(volatile char *) vaddr) : "memory");
 
 	return retval;
 }
 
 extern __inline__ int
-minix_test_bit (int nr, const void *vaddr)
+minix_test_bit (int nr, const volatile void *vaddr)
 {
-	return ((1U << (nr & 15)) & (((const unsigned short *) vaddr)[nr >> 4])) != 0;
+	return ((1U << (nr & 15)) & (((const volatile unsigned short *) vaddr)[nr >> 4])) != 0;
 }
 
 /* Bitmap functions for the ext2 filesystem. */
 
 extern __inline__ int
-ext2_set_bit (int nr, void *vaddr)
+ext2_set_bit (int nr, volatile void *vaddr)
 {
 	char retval;
 
 	__asm__ __volatile__ ("bfset %2{%1,#1}; sne %0"
-	     : "=d" (retval) : "d" (nr^7), "m" (*(char *) vaddr));
+	     : "=d" (retval) : "d" (nr^7), "m" (*(volatile char *) vaddr) : "memory");
 
 	return retval;
 }
 
 extern __inline__ int
-ext2_clear_bit (int nr, void *vaddr)
+ext2_clear_bit (int nr, volatile void *vaddr)
 {
 	char retval;
 
 	__asm__ __volatile__ ("bfclr %2{%1,#1}; sne %0"
-	     : "=d" (retval) : "d" (nr^7), "m" (*(char *) vaddr));
+	     : "=d" (retval) : "d" (nr^7), "m" (*(volatile char *) vaddr) : "memory");
 
 	return retval;
 }
 
 extern __inline__ int
-ext2_test_bit (int nr, const void *vaddr)
+ext2_test_bit (int nr, const volatile void *vaddr)
 {
-	return ((1U << (nr & 7)) & (((const unsigned char *) vaddr)[nr >> 3])) != 0;
+	return ((1U << (nr & 7)) & (((const volatile unsigned char *) vaddr)[nr >> 3])) != 0;
 }
 
 extern __inline__ int
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/dvma.h linux/include/asm-m68k/dvma.h
--- v2.4.5/linux/include/asm-m68k/dvma.h	Fri Dec 29 14:07:23 2000
+++ linux/include/asm-m68k/dvma.h	Mon Jun 11 19:15:27 2001
@@ -11,17 +11,37 @@
 
 #include <linux/config.h>
 
+#define DVMA_PAGE_SHIFT	13
+#define DVMA_PAGE_SIZE	(1UL << DVMA_PAGE_SHIFT)
+#define DVMA_PAGE_MASK	(~(DVMA_PAGE_SIZE-1))
+#define DVMA_PAGE_ALIGN(addr)	(((addr)+DVMA_PAGE_SIZE-1)&DVMA_PAGE_MASK)
+
+extern void dvma_init(void);	
+extern int dvma_map_iommu(unsigned long kaddr, unsigned long baddr, 
+			  int len);
+
+#define dvma_malloc(x) dvma_malloc_align(x, 0)
+#define dvma_map(x, y) dvma_map_align(x, y, 0)
+
+extern unsigned long dvma_map_align(unsigned long kaddr, int len, 
+			    int align);
+extern void *dvma_malloc_align(unsigned long len, unsigned long align);
+
+extern void dvma_unmap(void *baddr);
+extern void dvma_free(void *vaddr);
+
+
 #ifdef CONFIG_SUN3
 /* sun3 dvma page support */
 
-#define DVMA_RESERVED_PMEGS 2 /* 256k of dvma */
-
 /* memory and pmegs potentially reserved for dvma */
 #define DVMA_PMEG_START 10
 #define DVMA_PMEG_END 16
-#define DVMA_START 0xff00000
-#define DVMA_END 0xffe0000
+#define DVMA_START 0xf00000
+#define DVMA_END 0xfe0000
 #define DVMA_SIZE (DVMA_END-DVMA_START)
+#define IOMMU_TOTAL_ENTRIES 128
+#define IOMMU_ENTRIES 120
 
 /* empirical kludge -- dvma regions only seem to work right on 0x10000 
    byte boundries */
@@ -29,15 +49,40 @@
 #define DVMA_ALIGN(addr) (((addr)+DVMA_REGION_SIZE-1) & \
                          ~(DVMA_REGION_SIZE-1))
 
-
 /* virt <-> phys conversions */
-#define sun3_dvma_vtop(x) ((unsigned long)(x) & 0xffffff)
-#define sun3_dvma_ptov(x) ((unsigned long)(x) | 0xf000000)
+#define dvma_vtop(x) ((unsigned long)(x) & 0xffffff)
+#define dvma_ptov(x) ((unsigned long)(x) | 0xf000000)
+#define dvma_vtob(x) dvma_vtop(x)
+#define dvma_btov(x) dvma_ptov(x)
+
+extern inline int dvma_map_cpu(unsigned long kaddr, unsigned long vaddr, int len)
+{
+	return 0;
+}
+
+extern unsigned long dvma_page(unsigned long kaddr, unsigned long vaddr);
 
-extern void sun3_dvma_init(void);	
-extern void *sun3_dvma_malloc(int len);
 #else /* Sun3x */
 
+/* sun3x dvma page support */
+
+#define DVMA_START 0x0
+#define DVMA_END 0xf00000
+#define DVMA_SIZE (DVMA_END-DVMA_START)
+#define IOMMU_TOTAL_ENTRIES	   2048
+/* the prom takes the top meg */
+#define IOMMU_ENTRIES              (IOMMU_TOTAL_ENTRIES - 0x80)
+
+#define dvma_vtob(x) ((unsigned long)(x) & 0x00ffffff)
+#define dvma_btov(x) ((unsigned long)(x) | 0xff000000)
+
+extern int dvma_map_cpu(unsigned long kaddr, unsigned long vaddr, int len);
+
+
+
+/* everything below this line is specific to dma used for the onboard 
+   ESP scsi on sun3x */
+
 /* Structure to describe the current status of DMA registers on the Sparc */
 struct sparc_dma_registers {
   __volatile__ unsigned long cond_reg;	/* DMA condition register */
@@ -188,7 +233,7 @@
 	dma->running = 0;                                                  \
 } while(0)
 
-extern unsigned long dvma_alloc (unsigned long, unsigned long);
-extern void dvma_free (unsigned long, unsigned long);
+
 #endif /* !CONFIG_SUN3 */
+
 #endif /* !(__M68K_DVMA_H) */
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/floppy.h linux/include/asm-m68k/floppy.h
--- v2.4.5/linux/include/asm-m68k/floppy.h	Thu Jan  4 13:00:55 2001
+++ linux/include/asm-m68k/floppy.h	Mon Jun 11 19:15:27 2001
@@ -1,23 +1,58 @@
 /*
- * Q40 Architecture specific parts of the Floppy driver
+ * Implementation independent bits of the Floppy driver.
+ *
+ * much of this file is derived from what was originally the Q40 floppy driver.
  *
  * 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.
  *
- * Copyright (C) 1999
+ * Copyright (C) 1999, 2000, 2001
+ *
+ * Sun3x support added 2/4/2000 Sam Creasey (sammy@oh.verio.com)
+ *
  */
 
 #include <asm/io.h>
 
 #include <linux/vmalloc.h>
 
-
 asmlinkage void floppy_hardint(int irq, void *dev_id, struct pt_regs * regs);
 
+/* constants... */
+
 #undef MAX_DMA_ADDRESS
 #define MAX_DMA_ADDRESS   0x00  /* nothing like that */
 
+
+/*
+ * Again, the CMOS information doesn't work on m68k..
+ */
+#define FLOPPY0_TYPE (MACH_IS_Q40 ? 6 : 4)
+#define FLOPPY1_TYPE 0
+
+#define FLOPPY_MOTOR_MASK 0xf0
+
+
+/* basically PC init + set use_virtual_dma */
+#define  FDC1 m68k_floppy_init()
+static int FDC2 = -1;
+
+
+#define N_FDC 1
+#define N_DRIVE 8
+
+
+/* vdma globals adapted from asm-i386/floppy.h */
+
+static int virtual_dma_count=0;
+static int virtual_dma_residue=0;
+static char *virtual_dma_addr=0;
+static int virtual_dma_mode=0;
+static int doing_pdma=0;
+
+#include <asm/sun3xflop.h>
+
 extern spinlock_t  dma_spin_lock;
 
 static __inline__ unsigned long claim_dma_lock(void)
@@ -33,23 +68,46 @@
 }
 
 
+static __inline__ unsigned char fd_inb(int port)
+{
+	if(MACH_IS_Q40)
+		return inb_p(port);
+	else if(MACH_IS_SUN3X)
+		return sun3x_82072_fd_inb(port);
+}
 
-#define fd_inb(port)			inb_p(port)
-#define fd_outb(port,value)		outb_p(port,value)
+static __inline__ void fd_outb(unsigned char value, int port)
+{
+	if(MACH_IS_Q40)
+		outb_p(value, port);
+	else if(MACH_IS_SUN3X)
+		sun3x_82072_fd_outb(value, port);
+}
 
 
-#define fd_request_dma()        vdma_request_dma(FLOPPY_DMA,"floppy")
-/*#define fd_free_dma()           */
+static int fd_request_irq(void)
+{
+	if(MACH_IS_Q40)
+		return request_irq(FLOPPY_IRQ, floppy_hardint,SA_INTERRUPT,
+						   "floppy", NULL);
+	else if(MACH_IS_SUN3X) 
+		return sun3xflop_request_irq();
+	
+}
 
+static void fd_free_irq(void)
+{
+	if(MACH_IS_Q40)
+		free_irq(FLOPPY_IRQ, NULL);
+}
 
+#define fd_request_dma()        vdma_request_dma(FLOPPY_DMA,"floppy")
 #define fd_get_dma_residue()    vdma_get_dma_residue(FLOPPY_DMA)
 #define fd_dma_mem_alloc(size)	vdma_mem_alloc(size)
 #define fd_dma_setup(addr, size, mode, io) vdma_dma_setup(addr, size, mode, io)
 
-
 #define fd_enable_irq()           /* nothing... */
 #define fd_disable_irq()          /* nothing... */
-#define fd_free_irq()		free_irq(FLOPPY_IRQ, NULL)
 
 #define fd_free_dma()             /* nothing */
 
@@ -60,62 +118,71 @@
 #define DMA_MODE_WRITE 0x48
 
 
-static int q40_floppy_init(void)
+static int m68k_floppy_init(void)
 {
   use_virtual_dma =1;
-  /* FLOPPY_IRQ=6; */
-
+  can_use_virtual_dma = 1;
+ 
+  
   if (MACH_IS_Q40)  
-    return 0x3f0;
+	  return 0x3f0;
+  else if(MACH_IS_SUN3X)
+	  return sun3xflop_init();
   else
     return -1;
 }
 
 
+static int vdma_request_dma(unsigned int dmanr, const char * device_id)
+{
+	return 0;
+}
 
 
-/*
- * Again, the CMOS information doesn't work on the Q40..
- */
-#define FLOPPY0_TYPE 6
-#define FLOPPY1_TYPE 0
-
-
-
-
-#define FLOPPY_MOTOR_MASK 0xf0
-
-
-
+static int vdma_get_dma_residue(unsigned int dummy)
+{
+	return virtual_dma_count + virtual_dma_residue;
+}
 
-/* basically PC init + set use_virtual_dma */
-#define  FDC1 q40_floppy_init()
-static int FDC2 = -1;
 
+static unsigned long vdma_mem_alloc(unsigned long size)
+{
+	return (unsigned long) vmalloc(size);
 
-#define N_FDC 1
-#define N_DRIVE 8
+}
 
+static void _fd_dma_mem_free(unsigned long addr, unsigned long size)
+{
+        vfree((void *)addr);
+}
+#define fd_dma_mem_free(addr,size) _fd_dma_mem_free(addr, size)
 
 
-/* vdma stuff adapted from asm-i386/floppy.h */
+/* choose_dma_mode ???*/
 
-static int virtual_dma_count=0;
-static int virtual_dma_residue=0;
-static char *virtual_dma_addr=0;
-static int virtual_dma_mode=0;
-static int doing_pdma=0;
+static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
+{
+	doing_pdma = 1;
+	virtual_dma_port = (MACH_IS_Q40 ? io : 0);
+	virtual_dma_mode = (mode  == DMA_MODE_WRITE);
+	virtual_dma_addr = addr;
+	virtual_dma_count = size;
+	virtual_dma_residue = 0;
+	return 0;
+}
 
 
 
-static int fd_request_irq(void)
+static void fd_disable_dma(void)
 {
-  return request_irq(FLOPPY_IRQ, floppy_hardint,SA_INTERRUPT,
-						   "floppy", NULL);
+	doing_pdma = 0;
+	virtual_dma_residue += virtual_dma_count;
+	virtual_dma_count=0;
 }
 
-/*#define SLOW_DOWN do{outb(0,0x80);}while(0)*/
-#define SLOW_DOWN do{int count=1;do{if(!jiffies)break;}while(count-->0);}while(0)
+
+
+/* this is the only truly Q40 specific function */
 
 asmlinkage void floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
 {
@@ -185,55 +252,6 @@
 	if(!virtual_dma_count)
 		dma_wait++;
 #endif
-}
-
-
-
-static int vdma_request_dma(unsigned int dmanr, const char * device_id)
-{
-	return 0;
-}
-
-
-static int vdma_get_dma_residue(unsigned int dummy)
-{
-	return virtual_dma_count + virtual_dma_residue;
-}
-
-
-static unsigned long vdma_mem_alloc(unsigned long size)
-{
-	return (unsigned long) vmalloc(size);
-
-}
-
-static void _fd_dma_mem_free(unsigned long addr, unsigned long size)
-{
-        vfree((void *)addr);
-}
-#define fd_dma_mem_free(addr,size) _fd_dma_mem_free(addr, size)
-
-
-/* choose_dma_mode ???*/
-
-static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
-{
-	doing_pdma = 1;
-	virtual_dma_port = io;
-	virtual_dma_mode = (mode  == DMA_MODE_WRITE);
-	virtual_dma_addr = addr;
-	virtual_dma_count = size;
-	virtual_dma_residue = 0;
-	return 0;
-}
-
-
-
-static void fd_disable_dma(void)
-{
-	doing_pdma = 0;
-	virtual_dma_residue += virtual_dma_count;
-	virtual_dma_count=0;
 }
 
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/ide.h linux/include/asm-m68k/ide.h
--- v2.4.5/linux/include/asm-m68k/ide.h	Fri Dec 29 14:07:23 2000
+++ linux/include/asm-m68k/ide.h	Mon Jun 11 19:15:27 2001
@@ -61,10 +61,6 @@
           return 0;
 }
 
-/*
- *  Can we do this in a generic manner??
- */
-
 
 /*
  * Set up a hw structure for a specified data port, control port and IRQ.
@@ -160,219 +156,64 @@
 #define SUPPORT_VLB_SYNC 0
 
 /* this definition is used only on startup .. */
-#ifndef CONFIG_Q40
 #undef HD_DATA
 #define HD_DATA NULL
+
+
+/* get rid of defs from io.h - ide has its private and conflicting versions */
+#undef inb
+#undef inw
+#undef outb
+#undef outw
+#undef inb_p
+#undef outb_p
+#undef insw
+#undef outsw
+#undef insw_swapw
+#undef outsw_swapw
+
+/* 
+ * define IO method and translation,
+ * so far only Q40 has ide-if on ISA 
+*/
+#ifndef CONFIG_Q40
+
+#define ADDR_TRANS_B(_addr_) (_addr_)
+#define ADDR_TRANS_W(_addr_) (_addr_)
+
 #else
-#ifdef MACH_Q40_ONLY
-#undef HD_DATA
-#define HD_DATA ((ide_ioreg_t)0x1f0)
-#else
-#undef HD_DATA
-#define HD_DATA   (MACH_IS_Q40 ? (ide_ioreg_t)0x1f0 : 0)
-#endif
+
+#define ADDR_TRANS_B(_addr_) (MACH_IS_Q40 ? ((unsigned char *)Q40_ISA_IO_B(_addr_)) : (_addr_))
+#define ADDR_TRANS_W(_addr_) (MACH_IS_Q40 ? ((unsigned char *)Q40_ISA_IO_W(_addr_)) : (_addr_))
 #endif
 
+#define inb(p)     in_8(ADDR_TRANS_B(p))
+#define inb_p(p)     in_8(ADDR_TRANS_B(p))
+#define inw(p)     in_be16(ADDR_TRANS_W(p))
+#define outb(v,p)  out_8(ADDR_TRANS_B(p),v)
+#define outb_p(v,p)  out_8(ADDR_TRANS_B(p),v)
+#define outw(v,p)  out_be16(ADDR_TRANS_W(p),v)
+
+#define insw(port, buf, nr) raw_insw(ADDR_TRANS_W(port), buf, nr)
+#define outsw(port, buf, nr) raw_outsw(ADDR_TRANS_W(port), buf, nr)
 
 #define insl(data_reg, buffer, wcount) insw(data_reg, buffer, (wcount)<<1)
 #define outsl(data_reg, buffer, wcount) outsw(data_reg, buffer, (wcount)<<1)
 
-#ifdef CONFIG_Q40
-#ifdef MACH_Q40_ONLY
-#define ADDR_TRANS(_addr_) (Q40_ISA_IO_W(_addr_))
-#else
-#define ADDR_TRANS(_addr_) (MACH_IS_Q40 ? ((unsigned char *)Q40_ISA_IO_W(_addr_)) : (_addr_))
-#endif
-#else
-#define ADDR_TRANS(_addr_) (_addr_)
-#endif
 
-#define insw(port, buf, nr) ({				\
-	unsigned char *_port = (unsigned char *) ADDR_TRANS(port);	\
-	unsigned char *_buf = (buf);			\
-	int _nr = (nr);					\
-	unsigned long _tmp;				\
-							\
-	if (_nr & 15) {					\
-		_tmp = (_nr & 15) - 1;			\
-		asm volatile (				\
-			"1: movew %2@,%0@+; dbra %1,1b"	\
-			: "=a" (_buf), "=d" (_tmp)	\
-			: "a" (_port), "0" (_buf),	\
-			  "1" (_tmp));			\
-	}						\
-	if (_nr >> 4) {					\
-		_tmp = (_nr >> 4) - 1;			\
-		asm volatile (				\
-			"1: "				\
-			"movew %2@,%0@+; "		\
-			"movew %2@,%0@+; "		\
-			"movew %2@,%0@+; "		\
-			"movew %2@,%0@+; "		\
-			"movew %2@,%0@+; "		\
-			"movew %2@,%0@+; "		\
-			"movew %2@,%0@+; "		\
-			"movew %2@,%0@+; "		\
-			"movew %2@,%0@+; "		\
-			"movew %2@,%0@+; "		\
-			"movew %2@,%0@+; "		\
-			"movew %2@,%0@+; "		\
-			"movew %2@,%0@+; "		\
-			"movew %2@,%0@+; "		\
-			"movew %2@,%0@+; "		\
-			"movew %2@,%0@+; "		\
-			"dbra %1,1b"			\
-			: "=a" (_buf), "=d" (_tmp)	\
-			: "a" (_port), "0" (_buf),	\
-			  "1" (_tmp));			\
-	}						\
-})
-
-#define outsw(port, buf, nr) ({				\
-	unsigned char *_port = (unsigned char *) ADDR_TRANS(port);	\
-	unsigned char *_buf = (buf);			\
-	int _nr = (nr);					\
-	unsigned long _tmp;				\
-							\
-	if (_nr & 15) {					\
-		_tmp = (_nr & 15) - 1;			\
-		asm volatile (				\
-			"1: movew %0@+,%2@; dbra %1,1b"	\
-			: "=a" (_buf), "=d" (_tmp)	\
-			: "a" (_port), "0" (_buf),	\
-			  "1" (_tmp));			\
-	}						\
-	if (_nr >> 4) {					\
-		_tmp = (_nr >> 4) - 1;			\
-		asm volatile (				\
-			"1: "				\
-			"movew %0@+,%2@; "		\
-			"movew %0@+,%2@; "		\
-			"movew %0@+,%2@; "		\
-			"movew %0@+,%2@; "		\
-			"movew %0@+,%2@; "		\
-			"movew %0@+,%2@; "		\
-			"movew %0@+,%2@; "		\
-			"movew %0@+,%2@; "		\
-			"movew %0@+,%2@; "		\
-			"movew %0@+,%2@; "		\
-			"movew %0@+,%2@; "		\
-			"movew %0@+,%2@; "		\
-			"movew %0@+,%2@; "		\
-			"movew %0@+,%2@; "		\
-			"movew %0@+,%2@; "		\
-			"movew %0@+,%2@; "		\
-			"dbra %1,1b"	   		\
-			: "=a" (_buf), "=d" (_tmp)	\
-			: "a" (_port), "0" (_buf),	\
-			  "1" (_tmp));			\
-	}						\
-})
 
 #if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
+
 #define insl_swapw(data_reg, buffer, wcount) \
     insw_swapw(data_reg, buffer, (wcount)<<1)
 #define outsl_swapw(data_reg, buffer, wcount) \
     outsw_swapw(data_reg, buffer, (wcount)<<1)
 
-#define insw_swapw(port, buf, nr) \
-    if ((nr) % 8) \
-	__asm__ __volatile__ \
-	       ("movel %0,%/a0; \
-		 movel %1,%/a1; \
-		 movel %2,%/d6; \
-		 subql #1,%/d6; \
-	       1:movew %/a0@,%/d0; \
-		 rolw  #8,%/d0; \
-		 movew %/d0,%/a1@+; \
-		 dbra %/d6,1b" : \
-		: "g" (ADDR_TRANS(port)), "g" (buf), "g" (nr) \
-		: "d0", "a0", "a1", "d6"); \
-    else \
-	__asm__ __volatile__ \
-	       ("movel %0,%/a0; \
-		 movel %1,%/a1; \
-		 movel %2,%/d6; \
-		 lsrl  #3,%/d6; \
-		 subql #1,%/d6; \
-	       1:movew %/a0@,%/d0; \
-		 rolw  #8,%/d0; \
-		 movew %/d0,%/a1@+; \
-		 movew %/a0@,%/d0; \
-		 rolw  #8,%/d0; \
-		 movew %/d0,%/a1@+; \
-		 movew %/a0@,%/d0; \
-		 rolw  #8,%/d0; \
-		 movew %/d0,%/a1@+; \
-		 movew %/a0@,%/d0; \
-		 rolw  #8,%/d0; \
-		 movew %/d0,%/a1@+; \
-		 movew %/a0@,%/d0; \
-		 rolw  #8,%/d0; \
-		 movew %/d0,%/a1@+; \
-		 movew %/a0@,%/d0; \
-		 rolw  #8,%/d0; \
-		 movew %/d0,%/a1@+; \
-		 movew %/a0@,%/d0; \
-		 rolw  #8,%/d0; \
-		 movew %/d0,%/a1@+; \
-		 movew %/a0@,%/d0; \
-		 rolw  #8,%/d0; \
-		 movew %/d0,%/a1@+; \
-		 dbra %/d6,1b" : \
-		: "g" (ADDR_TRANS(port)), "g" (buf), "g" (nr) \
-		: "d0", "a0", "a1", "d6") 
-
-
-#define outsw_swapw(port, buf, nr) \
-    if ((nr) % 8) \
-	__asm__ __volatile__ \
-	       ("movel %0,%/a0; \
-		 movel %1,%/a1; \
-		 movel %2,%/d6; \
-		 subql #1,%/d6; \
-	       1:movew %/a1@+,%/d0; \
-		 rolw  #8,%/d0; \
-		 movew %/d0,%/a0@; \
-		 dbra %/d6,1b" : \
-		: "g" (ADDR_TRANS(port)), "g" (buf), "g" (nr) \
-		: "d0", "a0", "a1", "d6"); \
-    else \
-	__asm__ __volatile__ \
-	       ("movel %0,%/a0; \
-		 movel %1,%/a1; \
-		 movel %2,%/d6; \
-		 lsrl  #3,%/d6; \
-		 subql #1,%/d6; \
-	       1:movew %/a1@+,%/d0; \
-		 rolw  #8,%/d0; \
-		 movew %/d0,%/a0@; \
-		 movew %/a1@+,%/d0; \
-		 rolw  #8,%/d0; \
-		 movew %/d0,%/a0@; \
-		 movew %/a1@+,%/d0; \
-		 rolw  #8,%/d0; \
-		 movew %/d0,%/a0@; \
-		 movew %/a1@+,%/d0; \
-		 rolw  #8,%/d0; \
-		 movew %/d0,%/a0@; \
-		 movew %/a1@+,%/d0; \
-		 rolw  #8,%/d0; \
-		 movew %/d0,%/a0@; \
-		 movew %/a1@+,%/d0; \
-		 rolw  #8,%/d0; \
-		 movew %/d0,%/a0@; \
-		 movew %/a1@+,%/d0; \
-		 rolw  #8,%/d0; \
-		 movew %/d0,%/a0@; \
-		 movew %/a1@+,%/d0; \
-		 rolw  #8,%/d0; \
-		 movew %/d0,%/a0@; \
-		 dbra %/d6,1b" : \
-		: "g" (ADDR_TRANS(port)), "g" (buf), "g" (nr) \
-		: "d0", "a0", "a1", "d6")
+#define insw_swapw(port, buf, nr) raw_insw_swapw(ADDR_TRANS_W(port), buf, nr)
+#define outsw_swapw(port, buf, nr) raw_outsw_swapw(ADDR_TRANS_W(port),buf,nr)
+
+#endif /* CONFIG_ATARI || CONFIG_Q40 */
 
-#endif /* CONFIG_ATARI */
 
 #define T_CHAR          (0x0000)        /* char:  don't touch  */
 #define T_SHORT         (0x4000)        /* short: 12 -> 21     */
@@ -387,7 +228,15 @@
 #define D_INT(cnt)      (T_INT   | (cnt))
 #define D_TEXT(cnt)     (T_TEXT  | (cnt))
 
-#if defined(CONFIG_AMIGA) || defined (CONFIG_MAC)
+/* Q40 and Atari have byteswapped IDE bus and since many interesting
+ * values in the identification string are text, chars and words they
+ * happened to be almost correct without swapping.. However *_capacity 
+ * is needed for drives over 8 GB. RZ */
+#if defined(CONFIG_Q40) || defined(CONFIG_ATARI)
+#define M68K_IDE_SWAPW  (MACH_IS_Q40 || MACH_IS_ATARI)
+#endif
+
+#if defined(CONFIG_AMIGA) || defined (CONFIG_MAC) || defined(M68K_IDE_SWAPW)
 static u_short driveid_types[] = {
 	D_SHORT(10),	/* config - vendor2 */
 	D_TEXT(20),	/* serial_no */
@@ -402,7 +251,7 @@
 	D_INT(1),	/* cur_capacity */
 	D_CHAR(2),	/* multsect - multsect_valid */
 	D_INT(1),	/* lba_capacity */
-	D_SHORT(194)	/* dma_1word - reservedyy */
+	D_SHORT(194)	/* dma_1word - reserved */
 };
 
 #define num_driveid_types       (sizeof(driveid_types)/sizeof(*driveid_types))
@@ -410,13 +259,19 @@
 
 static __inline__ void ide_fix_driveid(struct hd_driveid *id)
 {
-#if defined(CONFIG_AMIGA) || defined (CONFIG_MAC)
+#if defined(CONFIG_AMIGA) || defined (CONFIG_MAC) || defined(M68K_IDE_SWAPW)
    u_char *p = (u_char *)id;
    int i, j, cnt;
    u_char t;
 
-   if (!MACH_IS_AMIGA && !MACH_IS_MAC)
+   if (!MACH_IS_AMIGA && !MACH_IS_MAC && !MACH_IS_Q40 && !MACH_IS_ATARI)
    	return;
+#ifdef M68K_IDE_SWAPW
+   if (M68K_IDE_SWAPW)    /* fix bus byteorder first */
+      for (i=0; i < 512; i+=2) {
+	 t = p[i]; p[i] = p[i+1]; p[i+1] = t; 
+      }
+#endif
    for (i = 0; i < num_driveid_types; i++) {
       cnt = driveid_types[i] & T_MASK_COUNT;
       switch (driveid_types[i] & T_MASK_TYPE) {
@@ -425,28 +280,28 @@
             break;
          case T_SHORT:
             for (j = 0; j < cnt; j++) {
-               t = p[0];
-               p[0] = p[1];
-               p[1] = t;
+	       t = p[0];
+	       p[0] = p[1];
+	       p[1] = t;
                p += 2;
             }
             break;
          case T_INT:
             for (j = 0; j < cnt; j++) {
-               t = p[0];
-               p[0] = p[3];
-               p[3] = t;
-               t = p[1];
-               p[1] = p[2];
-               p[2] = t;
+	       t = p[0];
+	       p[0] = p[3];
+	       p[3] = t;
+	       t = p[1];
+	       p[1] = p[2];
+	       p[2] = t;
                p += 4;
             }
             break;
          case T_TEXT:
             for (j = 0; j < cnt; j += 2) {
-               t = p[0];
-               p[0] = p[1];
-               p[1] = t;
+	       t = p[0];
+	       p[0] = p[1];
+	       p[1] = t;
                p += 2;
             }
             break;
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/intersil.h linux/include/asm-m68k/intersil.h
--- v2.4.5/linux/include/asm-m68k/intersil.h	Fri Dec 29 14:07:23 2000
+++ linux/include/asm-m68k/intersil.h	Mon Jun 11 19:15:27 2001
@@ -25,21 +25,21 @@
 #define INTERSIL_HZ_100_MASK	 0x02
 
 struct intersil_dt {
-	u_char	csec;
-	u_char	hour;
-	u_char	minute;
-	u_char	second;
-	u_char	month;
-	u_char	day;
-	u_char	year;
-	u_char	weekday;
+	unsigned char	csec;
+	unsigned char	hour;
+	unsigned char	minute;
+	unsigned char	second;
+	unsigned char	month;
+	unsigned char	day;
+	unsigned char	year;
+	unsigned char	weekday;
 };
 
 struct intersil_7170 {
 	struct intersil_dt counter;
 	struct intersil_dt alarm;
-	u_char	int_reg;
-	u_char	cmd_reg;
+	unsigned char	int_reg;
+	unsigned char	cmd_reg;
 };
 
 extern volatile char* clock_va;
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/io.h linux/include/asm-m68k/io.h
--- v2.4.5/linux/include/asm-m68k/io.h	Thu Jan  4 13:00:55 2001
+++ linux/include/asm-m68k/io.h	Mon Jun 11 19:15:27 2001
@@ -1,57 +1,260 @@
-#ifndef _M68K_IO_H
-#define _M68K_IO_H
+/*
+ * linux/include/asm-m68k/io.h 
+ *
+ * 4/1/00 RZ: - rewritten to avoid clashes between ISA/PCI and other
+ *              IO access
+ *            - added Q40 support
+ *            - added skeleton for GG-II and Amiga PCMCIA
+ * 2/3/01 RZ: - moved a few more defs into raw_io.h
+ *
+ * inX/outX/readX/writeX should not be used by any driver unless it does
+ * ISA or PCI access. Other drivers should use function defined in raw_io.h
+ * or define its own macros on top of these.
+ *
+ *    inX(),outX()              are for PCI and ISA I/O
+ *    readX(),writeX()          are for PCI memory
+ *    isa_readX(),isa_writeX()  are for ISA memory
+ *
+ * moved mem{cpy,set}_*io inside CONFIG_PCI
+ */
+
+#ifndef _IO_H
+#define _IO_H
 
 #ifdef __KERNEL__
 
 #include <linux/config.h>
+#include <asm/raw_io.h>
+#include <asm/virtconvert.h>
+
 
 #ifdef CONFIG_ATARI
 #include <asm/atarihw.h>
-
-#define SLOW_DOWN_IO	do { if (MACH_IS_ATARI) MFPDELAY(); } while (0)
 #endif
 
-#include <asm/virtconvert.h>
 
 /*
- * These are for PCI shared memory _only_ and should never be used
- * on any other type of memory, including Zorro memory. They are meant to
- * access the bus in the bus byte order which is little-endian!.
- *
- * readX/writeX() are used to access memory mapped devices. On some
- * architectures the memory mapped IO stuff needs to be accessed
- * differently. On the m68k architecture, we just read/write the
- * memory location directly.
+ * IO/MEM definitions for various ISA bridges
  */
-/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
- * two accesses to memory, which may be undesireable for some devices.
+
+
+#ifdef CONFIG_Q40
+
+#define q40_isa_io_base  0xff400000
+#define q40_isa_mem_base 0xff800000
+
+#define Q40_ISA_IO_B(ioaddr) (q40_isa_io_base+1+4*((unsigned long)(ioaddr)))
+#define Q40_ISA_IO_W(ioaddr) (q40_isa_io_base+  4*((unsigned long)(ioaddr)))
+#define Q40_ISA_MEM_B(madr)  (q40_isa_mem_base+1+4*((unsigned long)(madr)))
+#define Q40_ISA_MEM_W(madr)  (q40_isa_mem_base+  4*((unsigned long)(madr)))
+
+#define MACH_HAS_ISA 1
+#endif /* Q40 */
+
+/* GG-II Zorro to ISA bridge */
+#ifdef CONFIG_GG2
+
+extern unsigned long gg2_isa_base;
+#define GG2_ISA_IO_B(ioaddr) (gg2_isa_base+1+((unsigned long)(ioaddr)*4))
+#define GG2_ISA_IO_W(ioaddr) (gg2_isa_base+  ((unsigned long)(ioaddr)*4))
+#define GG2_ISA_MEM_B(madr)  (gg2_isa_base+1+(((unsigned long)(madr)*4) & 0xfffff))
+#define GG2_ISA_MEM_W(madr)  (gg2_isa_base+  (((unsigned long)(madr)*4) & 0xfffff))
+
+#ifndef MACH_HAS_ISA
+#define MACH_HAS_ISA 1
+#else 
+#undef MACH_HAS_ISA
+#define MACH_HAS_ISA m
+#endif
+#endif /* GG2 */
+
+#ifdef CONFIG_AMIGA_PCMCIA
+#include <asm/amigayle.h>
+
+#define AG_ISA_IO_B(ioaddr) ( GAYLE_IO+(ioaddr)+(((ioaddr)&1)*GAYLE_ODD) )
+#define AG_ISA_IO_W(ioaddr) ( GAYLE_IO+(ioaddr) )
+
+#ifndef MACH_HAS_ISA
+#define MACH_HAS_ISA 1
+#else 
+#undef MACH_HAS_ISA
+#define MACH_HAS_ISA m
+#endif
+#endif /* AMIGA_PCMCIA */
+
+
+
+#ifdef MACH_HAS_ISA
+
+#define Q40_ISA (1)
+#define GG2_ISA (2)
+#define AG_ISA  (3)
+
+#if defined(CONFIG_Q40) && MACH_HAS_ISA==1
+#define ISA_TYPE Q40_ISA
+#define ISA_SEX  0
+#endif
+#if defined(CONFIG_AMIGA_PCMCIA) && MACH_HAS_ISA==1
+#define ISA_TYPE AG_ISA
+#define ISA_SEX  1
+#endif 
+#if defined(CONFIG_GG2) && MACH_HAS_ISA==1
+#define ISA_TYPE GG2_ISA
+#define ISA_SEX  0
+#endif
+
+#ifdef CONFIG_ISA
+extern int isa_type;
+extern int isa_sex;
+
+#define ISA_TYPE isa_type
+#define ISA_SEX  isa_sex
+#endif
+
+/*
+ * define inline addr translation functions. Normally only one variant will
+ * be compiled in so the case statement will be optimised away
  */
-#define readb(addr) \
-    ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
-#define readw(addr) \
-    ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
-#define readl(addr) \
-    ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
-
-#define writeb(b,addr) (void)((*(volatile unsigned char *) (addr)) = (b))
-#define writew(b,addr) (void)((*(volatile unsigned short *) (addr)) = (b))
-#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
-
-#define memset_io(a,b,c)	memset((void *)(a),(b),(c))
-#define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
-#define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
 
-#define inb_p(addr) readb(addr)
-#define inb(addr) readb(addr)
+static inline unsigned long isa_itb(long addr)
+{
+  switch(ISA_TYPE)
+    {
+#ifdef CONFIG_Q40
+    case Q40_ISA: return Q40_ISA_IO_B(addr);
+#endif
+#ifdef CONFIG_GG2
+    case GG2_ISA: return GG2_ISA_IO_B(addr);
+#endif
+#ifdef CONFIG_AMIGA_PCMCIA
+    case AG_ISA: return AG_ISA_IO_B(addr);
+#endif
+    default: return 0; /* avoid warnings, just in case */
+    }
+}
+static inline unsigned long isa_itw(long addr)
+{
+  switch(ISA_TYPE)
+    {
+#ifdef CONFIG_Q40
+    case Q40_ISA: return Q40_ISA_IO_W(addr);
+#endif
+#ifdef CONFIG_GG2
+    case GG2_ISA: return GG2_ISA_IO_W(addr);
+#endif
+#ifdef CONFIG_AMIGA_PCMCIA
+    case AG_ISA: return AG_ISA_IO_W(addr);
+#endif
+    default: return 0; /* avoid warnings, just in case */
+    }
+}
+static inline unsigned long isa_mtb(long addr)
+{
+  switch(ISA_TYPE)
+    {
+#ifdef CONFIG_Q40
+    case Q40_ISA: return Q40_ISA_MEM_B(addr);
+#endif
+#ifdef CONFIG_GG2
+    case GG2_ISA: return GG2_ISA_MEM_B(addr);
+#endif
+      /* FIXME: any ISA mem mapping for PCMCIA? */
+    default: return 0; /* avoid warnings, just in case */
+    }
+}
+static inline unsigned long isa_mtw(long addr)
+{
+  switch(ISA_TYPE)
+    {
+#ifdef CONFIG_Q40
+    case Q40_ISA: return Q40_ISA_MEM_W(addr);
+#endif
+#ifdef CONFIG_GG2
+    case GG2_ISA: return GG2_ISA_MEM_W(addr);
+#endif
+    default: return 0; /* avoid warnings, just in case */
+    }
+}
 
-#define outb(x,addr) ((void) writeb(x,addr))
-#define outb_p(x,addr) outb(x,addr)
 
-#ifndef CONFIG_SUN3
-#define IO_SPACE_LIMIT 0xffff
+#define isa_inb(port)      in_8(isa_itb(port))
+#define isa_inw(port)      (ISA_SEX ? in_be16(isa_itw(port)) : in_le16(isa_itw(port)))
+#define isa_outb(val,port) out_8(isa_itb(port),(val))
+#define isa_outw(val,port) (ISA_SEX ? out_be16(isa_itw(port),(val)) : out_le16(isa_itw(port),(val)))
+
+#define isa_readb(p)       in_8(isa_mtb(p))
+#define isa_readw(p)       in_le16(isa_mtw(p))
+#define isa_writeb(val,p)  out_8(isa_mtb(p),(val))
+#define isa_writew(val,p)  out_le16(isa_mtw(p),(val))
+
+#define isa_inb_p(p)      ({unsigned char v=isa_inb(p);isa_outb(0,0x80);v;})
+#define isa_outb_p(v,p)   ({isa_outb((v),(p));isa_outb(0,0x80);})
+
+#define isa_insb(port, buf, nr) raw_insb(isa_itb(port), (buf), (nr))
+#define isa_outsb(port, buf, nr) raw_outsb(isa_itb(port), (buf), (nr))
+
+#define isa_insw(port, buf, nr)     \
+       (ISA_SEX ? raw_insw(isa_itw(port), (buf), (nr)) :    \
+                  raw_insw_swapw(isa_itw(port), (buf), (nr)))
+
+#define isa_outsw(port, buf, nr)    \
+       (ISA_SEX ? raw_outsw(isa_itw(port), (buf), (nr)) :  \
+                  raw_outsw_swapw(isa_itw(port), (buf), (nr)))
+#endif  /* MACH_HAS_ISA */
+
+
+#if defined(CONFIG_ISA) && !defined(CONFIG_PCI) 
+#define inb     isa_inb
+#define inb_p   isa_inb_p
+#define outb    isa_outb
+#define outb_p  isa_outb_p
+#define inw     isa_inw
+#define outw    isa_outw
+#define inl     isa_inw
+#define outl    isa_outw
+#define insb    isa_insb
+#define insw    isa_insw
+#define outsb   isa_outsb
+#define outsw   isa_outsw
+#endif /* MACH_HAS_ISA */
+
+
+#if defined(CONFIG_PCI)
+
+#define inl(port)       in_le32(port)
+#define outl(val,port)  out_le32((port),(val))
+
+#define readb(addr)  in_8(addr)
+#define readw(addr)  in_le16(addr)
+#define readl(addr)  in_le32(addr)
+
+#define writeb(val,addr)  out_8((addr),(val))
+#define writew(val,addr)  out_le16((addr),(val))
+#define writel(val,addr)  out_le32((addr),(val))
+
+
+#ifndef CONFIG_ISA
+#define inb(port)      in_8(port)
+#define outb(val,port) out_8((port),(val))
+#define inw(port)      in_le16(port)
+#define outw(val,port) out_le16((port),(val))
+
 #else
-#define IO_SPACE_LIMIT 0x0fffffff
+/*
+ * kernel with both ISA and PCI compiled in, those have 
+ * conflicting defs for in/out. Simply consider port < 1024 
+ * ISA and everything else PCI
+ */
+#define inb(port) ((port)<1024 ? isa_inb(port) : in_8(port))
+#define inb_p(port) ((port)<1024 ? isa_inb_p(port) : in_8(port))
+#define inw(port) ((port)<1024 ? isa_inw(port) : in_le16(port))
+
+#define outb(val,port) ((port)<1024 ? isa_outb((val),(port)) : out_8((port),(val)))
+#define outb_p(val,port) ((port)<1024 ? isa_outb_p((val),(port)) : out_8((port),(val)))
+#define outw(val,port) ((port)<1024 ? isa_outw((val),(port)) : out_le16((port),(val)))
 #endif
+#endif /* CONFIG_PCI */
+
 
 /* Values for nocacheflag and cmode */
 #define IOMAP_FULL_CACHING		0
@@ -59,7 +262,10 @@
 #define IOMAP_NOCACHE_NONSER		2
 #define IOMAP_WRITETHROUGH		3
 
-extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
+extern void iounmap(void *addr);
+
+extern void *__ioremap(unsigned long physaddr, unsigned long size,
+		       int cacheflag);
 extern void __iounmap(void *addr, unsigned long size);
 
 extern inline void *ioremap(unsigned long physaddr, unsigned long size)
@@ -70,11 +276,13 @@
 {
 	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
 }
-extern inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size)
+extern inline void *ioremap_writethrough(unsigned long physaddr,
+					 unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
 }
-extern inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+extern inline void *ioremap_fullcache(unsigned long physaddr,
+				      unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
 }
@@ -87,6 +295,11 @@
 #define dma_cache_wback(_start,_size)		do { } while (0)
 #define dma_cache_wback_inv(_start,_size)	do { } while (0)
 
-#endif /* __KERNEL__ */
+#ifndef CONFIG_SUN3
+#define IO_SPACE_LIMIT 0xffff
+#else
+#define IO_SPACE_LIMIT 0x0fffffff
+#endif
 
-#endif /* _M68K_IO_H */
+#endif /* __KERNEL__ */
+#endif /* _IO_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/linux_logo.h linux/include/asm-m68k/linux_logo.h
--- v2.4.5/linux/include/asm-m68k/linux_logo.h	Mon Oct  5 13:54:39 1998
+++ linux/include/asm-m68k/linux_logo.h	Tue Jun 12 10:39:50 2001
@@ -26,883 +26,899 @@
 
 #ifdef CONFIG_MAC
 
-#define LINUX_LOGO_COLORS 95
+#define __HAVE_ARCH_LINUX_LOGO
+
+#define LINUX_LOGO_COLORS	185
 
 #ifdef INCLUDE_LINUX_LOGO_DATA
 
 unsigned char linux_logo_red[] __initdata = {
-  0x02, 0x82, 0xEA, 0x42, 0xC2, 0x82, 0xE2, 0xA2,
-  0xDA, 0xC2, 0x22, 0x62, 0xB2, 0x92, 0xD2, 0x8A,
-  0xB2, 0xFA, 0xDA, 0x32, 0x72, 0x12, 0xF2, 0x52,
-  0xF2, 0xEA, 0xFA, 0xAA, 0xCA, 0x9A, 0xE2, 0xAA,
-  0x8A, 0xEA, 0xD2, 0x92, 0xEA, 0xDA, 0x2A, 0x6A,
-  0xDA, 0xBA, 0xD2, 0x52, 0x7A, 0x2A, 0x5A, 0x0A,
-  0x6A, 0xEA, 0xE2, 0xC6, 0x96, 0xF2, 0x3A, 0x1A,
-  0xB2, 0xBA, 0xF2, 0xDA, 0x0A, 0x86, 0x4A, 0xCA,
-  0x8A, 0xE2, 0xA6, 0xDA, 0x66, 0xBA, 0x92, 0xDA,
-  0xA2, 0xB6, 0x76, 0x12, 0xF2, 0xFA, 0xEA, 0xAE,
-  0xCE, 0x9E, 0xB2, 0x8E, 0xF2, 0xD2, 0xA2, 0x6E,
-  0xBE, 0xD6, 0x7E, 0x5E, 0xC2, 0xFA, 0x3A
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0xfa,
+    0xf2, 0xf6, 0xe7, 0x74, 0x65, 0x7b, 0xea, 0xdd,
+    0xd6, 0x5e, 0xbe, 0x5a, 0xe2, 0xda, 0xee, 0xb6,
+    0xce, 0x65, 0x6e, 0x6a, 0xd2, 0xc6, 0x90, 0xca,
+    0x9e, 0xbb, 0xb2, 0x8a, 0xa2, 0x9a, 0x86, 0xc3,
+    0xfd, 0xae, 0x3e, 0xaa, 0x95, 0x80, 0x76, 0x79,
+    0x62, 0x36, 0x9a, 0xe2, 0xec, 0xe1, 0xb8, 0xd7,
+    0xaf, 0x25, 0xbc, 0xc0, 0xef, 0xea, 0xe8, 0xe8,
+    0xf5, 0xf1, 0xda, 0xd3, 0x79, 0xdb, 0xf4, 0xf6,
+    0xf6, 0xf6, 0xe2, 0x3d, 0xb4, 0xce, 0xe6, 0xee,
+    0xf6, 0xa6, 0x68, 0xd8, 0xec, 0xf5, 0xc6, 0xc8,
+    0x9c, 0x89, 0xd2, 0xee, 0xcb, 0xb9, 0xd2, 0x66,
+    0x5e, 0x8b, 0xbe, 0xa8, 0xd5, 0xca, 0xb6, 0xae,
+    0x9c, 0xc5, 0x8d, 0xbe, 0xbe, 0xb2, 0x9a, 0xa8,
+    0x16, 0x12, 0x4a, 0x8e, 0xf2, 0xf6, 0xe4, 0xf1,
+    0x26, 0x9a, 0xea, 0xf6, 0xe0, 0xd2, 0x9a, 0x2e,
+    0x70, 0xd6, 0x46, 0x7c, 0xb4, 0x62, 0xd6, 0xa3,
+    0x74, 0xa7, 0xa2, 0xca, 0xe0, 0xae, 0xbe, 0xce,
+    0xa3, 0x8e, 0x6d, 0x8e, 0x32, 0xaf, 0x50, 0x9e,
+    0x5b, 0x8a, 0x98, 0x82, 0x7a, 0x82, 0x56, 0x7c,
+    0x8a, 0x56, 0x5e, 0x86, 0x6a, 0x52, 0x59, 0x64,
+    0x5e,
 };
 
 unsigned char linux_logo_green[] __initdata = {
-  0x02, 0x82, 0xC2, 0x42, 0x8A, 0x56, 0xE2, 0xA2,
-  0xAA, 0xC2, 0x22, 0x62, 0x86, 0x92, 0x9E, 0x6E,
-  0xB2, 0xB2, 0xD2, 0x32, 0x72, 0x12, 0xD2, 0x52,
-  0xF2, 0xB2, 0xC2, 0xAA, 0xCA, 0x9A, 0xA2, 0x7E,
-  0x8A, 0xCA, 0x92, 0x66, 0xEA, 0xB2, 0x2A, 0x6A,
-  0xA2, 0xBA, 0xD2, 0x36, 0x7A, 0x1A, 0x5A, 0x0A,
-  0x4A, 0xE6, 0xAE, 0xC6, 0x96, 0xBA, 0x3A, 0x1A,
-  0xAA, 0x7A, 0xCA, 0xDA, 0x02, 0x86, 0x4A, 0x8A,
-  0x5E, 0xE2, 0xA6, 0xAE, 0x66, 0x82, 0x92, 0x9A,
-  0x72, 0xB6, 0x76, 0x12, 0xD2, 0xFA, 0xB2, 0xAE,
-  0xCE, 0x9E, 0x7A, 0x8E, 0xCA, 0x92, 0x6A, 0x6E,
-  0xBE, 0xD6, 0x7E, 0x5E, 0xC6, 0xBA, 0x3E
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0xfa,
+    0xf2, 0xf6, 0xe7, 0x74, 0x65, 0x7b, 0xea, 0xdd,
+    0xd6, 0x5e, 0xbe, 0x5a, 0xe2, 0xda, 0xee, 0xb6,
+    0xce, 0x62, 0x6e, 0x6a, 0xd2, 0xc6, 0x90, 0xca,
+    0x9e, 0xbb, 0xb2, 0x8a, 0xa2, 0x9a, 0x86, 0xc3,
+    0xfd, 0xae, 0x3e, 0xaa, 0x95, 0x80, 0x62, 0x5c,
+    0x4e, 0x26, 0x72, 0xaa, 0xba, 0xaf, 0x90, 0xae,
+    0x92, 0x1a, 0xa4, 0x85, 0xb6, 0xbe, 0xc3, 0xc8,
+    0xcf, 0xd0, 0xc2, 0xce, 0x57, 0xa2, 0xd6, 0xda,
+    0xda, 0xd7, 0xb8, 0x2a, 0x7b, 0x91, 0xae, 0xca,
+    0xda, 0xa6, 0x45, 0x9e, 0xb2, 0xd7, 0x9b, 0x90,
+    0x76, 0x5c, 0xa2, 0xbe, 0xa6, 0x85, 0x96, 0x4e,
+    0x46, 0x66, 0x92, 0x7a, 0x9a, 0x96, 0x9d, 0x9a,
+    0x6b, 0x8a, 0x8d, 0x8e, 0xb2, 0xa6, 0x79, 0x7c,
+    0x12, 0x0e, 0x36, 0x86, 0xba, 0xbe, 0xb8, 0xc4,
+    0x1e, 0x8e, 0xae, 0xba, 0xb2, 0xa6, 0x7a, 0x20,
+    0x64, 0xaa, 0x2f, 0x70, 0x85, 0x46, 0xa6, 0x6e,
+    0x51, 0x72, 0x92, 0xa2, 0xa6, 0x87, 0x96, 0xa2,
+    0x85, 0x7a, 0x6a, 0x6e, 0x22, 0x76, 0x36, 0x76,
+    0x3c, 0x6e, 0x63, 0x53, 0x66, 0x62, 0x42, 0x50,
+    0x56, 0x42, 0x56, 0x56, 0x56, 0x3e, 0x51, 0x52,
+    0x56,
 };
 
 unsigned char linux_logo_blue[] __initdata = {
-  0x04, 0x84, 0x04, 0x44, 0x04, 0x04, 0xDC, 0xA4,
-  0x0C, 0xC4, 0x1C, 0x64, 0x04, 0x8C, 0x04, 0x34,
-  0xB4, 0x0C, 0xAC, 0x34, 0x74, 0x04, 0x0C, 0x4C,
-  0xF4, 0x0C, 0x0C, 0xAC, 0xCC, 0x9C, 0x0C, 0x04,
-  0x8C, 0x0C, 0x04, 0x04, 0xEC, 0x2C, 0x2C, 0x6C,
-  0x04, 0xBC, 0xD4, 0x04, 0x7C, 0x04, 0x5C, 0x0C,
-  0x04, 0xEC, 0x04, 0xC4, 0x94, 0x14, 0x3C, 0x1C,
-  0xA4, 0x04, 0x24, 0xDC, 0x04, 0x84, 0x4C, 0x0C,
-  0x04, 0xE4, 0xA4, 0x04, 0x64, 0x04, 0x94, 0x14,
-  0x0C, 0xB4, 0x74, 0x14, 0x24, 0xFC, 0x14, 0xAC,
-  0xCC, 0x9C, 0x0C, 0x8C, 0x14, 0x14, 0x04, 0x6C,
-  0xBC, 0xD4, 0x7C, 0x5C, 0xD4, 0x14, 0x3C
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x01, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x06, 0xfa,
+    0xf2, 0xf6, 0xe7, 0x74, 0x65, 0x7b, 0xea, 0xdd,
+    0xd6, 0x5e, 0xbe, 0x5a, 0xe2, 0xda, 0xee, 0xb6,
+    0xce, 0x59, 0x6e, 0x6a, 0xd2, 0xc6, 0x90, 0xca,
+    0x9e, 0xbb, 0xb2, 0x8a, 0xa2, 0x9a, 0x86, 0xc3,
+    0xfd, 0xae, 0x3e, 0xaa, 0x95, 0x80, 0x2e, 0x08,
+    0x0a, 0x06, 0x0a, 0x0b, 0x0b, 0x0f, 0x0c, 0x0f,
+    0x3d, 0x09, 0x73, 0x09, 0x0d, 0x0a, 0x10, 0x1e,
+    0x2d, 0x13, 0x86, 0xba, 0x19, 0x0a, 0x36, 0x3c,
+    0x26, 0x14, 0x0d, 0x06, 0x07, 0x0a, 0x0b, 0x0f,
+    0x4a, 0xa6, 0x06, 0x0a, 0x0c, 0x2b, 0x0a, 0x0b,
+    0x0a, 0x06, 0x0a, 0x0a, 0x11, 0x0b, 0x0a, 0x0a,
+    0x1e, 0x0f, 0x0d, 0x0a, 0x0b, 0x22, 0x6a, 0x72,
+    0x0b, 0x0b, 0x8d, 0x22, 0x90, 0x92, 0x3c, 0x2c,
+    0x06, 0x06, 0x0e, 0x6a, 0x0e, 0x0e, 0x3e, 0x0e,
+    0x0a, 0x5a, 0x0d, 0x0e, 0x3e, 0x0a, 0x2e, 0x06,
+    0x4e, 0x36, 0x06, 0x58, 0x24, 0x06, 0x3a, 0x08,
+    0x08, 0x07, 0x5e, 0x45, 0x0a, 0x32, 0x2e, 0x2a,
+    0x43, 0x48, 0x5f, 0x2e, 0x06, 0x06, 0x07, 0x24,
+    0x06, 0x32, 0x06, 0x06, 0x46, 0x2e, 0x22, 0x06,
+    0x06, 0x1e, 0x4c, 0x06, 0x3a, 0x22, 0x42, 0x34,
+    0x42,
 };
 
 unsigned char linux_logo[] __initdata = {
-  0x53, 0x3D, 0x40, 0x73, 0x71, 0x3B, 0x3B, 0x71,
-  0x3D, 0x54, 0x73, 0x40, 0x73, 0x3D, 0x27, 0x71,
-  0x40, 0x6A, 0x7A, 0x3D, 0x3B, 0x30, 0x30, 0x62,
-  0x40, 0x6A, 0x21, 0x62, 0x78, 0x29, 0x49, 0x30,
-  0x6F, 0x27, 0x54, 0x3D, 0x62, 0x27, 0x54, 0x66,
-  0x71, 0x6F, 0x6F, 0x6F, 0x78, 0x53, 0x29, 0x29,
-  0x53, 0x70, 0x53, 0x3D, 0x40, 0x73, 0x71, 0x3B,
-  0x3B, 0x71, 0x3D, 0x54, 0x73, 0x40, 0x73, 0x3D,
-  0x27, 0x71, 0x40, 0x6A, 0x7A, 0x3D, 0x3B, 0x30,
-  0x30, 0x62, 0x40, 0x6A, 0x21, 0x62, 0x78, 0x29,
-  0x71, 0x4C, 0x6A, 0x40, 0x71, 0x62, 0x27, 0x71,
-  0x54, 0x66, 0x73, 0x40, 0x73, 0x3D, 0x3D, 0x40,
-  0x6A, 0x77, 0x7A, 0x71, 0x30, 0x69, 0x6F, 0x71,
-  0x54, 0x73, 0x3D, 0x30, 0x49, 0x30, 0x3B, 0x62,
-  0x27, 0x3D, 0x54, 0x3D, 0x71, 0x71, 0x27, 0x62,
-  0x62, 0x3B, 0x62, 0x27, 0x3B, 0x69, 0x69, 0x69,
-  0x69, 0x30, 0x71, 0x4C, 0x6A, 0x40, 0x71, 0x62,
-  0x27, 0x71, 0x54, 0x66, 0x73, 0x40, 0x73, 0x3D,
-  0x3D, 0x40, 0x6A, 0x77, 0x7A, 0x71, 0x30, 0x69,
-  0x6F, 0x71, 0x54, 0x73, 0x3D, 0x30, 0x49, 0x30,
-  0x40, 0x34, 0x34, 0x40, 0x27, 0x6F, 0x62, 0x3D,
-  0x54, 0x66, 0x40, 0x73, 0x66, 0x66, 0x2D, 0x5D,
-  0x7A, 0x5D, 0x3D, 0x6F, 0x69, 0x69, 0x30, 0x27,
-  0x27, 0x27, 0x62, 0x6F, 0x30, 0x3B, 0x62, 0x27,
-  0x3D, 0x54, 0x2D, 0x54, 0x27, 0x71, 0x3D, 0x27,
-  0x62, 0x62, 0x62, 0x62, 0x3B, 0x30, 0x6F, 0x6F,
-  0x6F, 0x71, 0x40, 0x34, 0x34, 0x40, 0x27, 0x6F,
-  0x62, 0x3D, 0x54, 0x66, 0x40, 0x73, 0x66, 0x66,
-  0x2D, 0x5D, 0x7A, 0x5D, 0x3D, 0x6F, 0x69, 0x69,
-  0x30, 0x27, 0x27, 0x27, 0x62, 0x6F, 0x30, 0x6F,
-  0x4C, 0x77, 0x6A, 0x2D, 0x3B, 0x6F, 0x3B, 0x71,
-  0x54, 0x66, 0x2D, 0x73, 0x66, 0x54, 0x73, 0x73,
-  0x73, 0x3D, 0x62, 0x6F, 0x69, 0x30, 0x6F, 0x27,
-  0x3D, 0x3D, 0x27, 0x62, 0x62, 0x62, 0x27, 0x71,
-  0x54, 0x73, 0x73, 0x54, 0x3D, 0x3D, 0x20, 0x20,
-  0x20, 0x20, 0x3B, 0x62, 0x3B, 0x62, 0x71, 0x71,
-  0x3D, 0x2D, 0x4C, 0x77, 0x6A, 0x66, 0x3B, 0x6F,
-  0x3B, 0x71, 0x54, 0x66, 0x2D, 0x73, 0x66, 0x54,
-  0x73, 0x73, 0x73, 0x3D, 0x62, 0x6F, 0x69, 0x30,
-  0x6F, 0x27, 0x3D, 0x3D, 0x27, 0x62, 0x62, 0x27,
-  0x4C, 0x4C, 0x5D, 0x71, 0x30, 0x30, 0x3B, 0x27,
-  0x54, 0x66, 0x73, 0x66, 0x66, 0x54, 0x54, 0x3D,
-  0x27, 0x62, 0x6F, 0x30, 0x30, 0x6F, 0x27, 0x3D,
-  0x54, 0x54, 0x3D, 0x71, 0x3D, 0x71, 0x3D, 0x3D,
-  0x66, 0x73, 0x66, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x71, 0x3D,
-  0x66, 0x40, 0x4C, 0x4C, 0x5D, 0x71, 0x30, 0x30,
-  0x3B, 0x27, 0x54, 0x66, 0x73, 0x66, 0x66, 0x54,
-  0x54, 0x3D, 0x27, 0x62, 0x6F, 0x30, 0x30, 0x6F,
-  0x27, 0x3D, 0x54, 0x54, 0x3D, 0x71, 0x71, 0x71,
-  0x5D, 0x5D, 0x54, 0x62, 0x69, 0x69, 0x3B, 0x3D,
-  0x66, 0x40, 0x73, 0x66, 0x54, 0x54, 0x71, 0x62,
-  0x3B, 0x6F, 0x6F, 0x6F, 0x3B, 0x27, 0x3D, 0x2D,
-  0x66, 0x54, 0x71, 0x71, 0x27, 0x71, 0x71, 0x3D,
-  0x3D, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54,
-  0x73, 0x40, 0x5D, 0x5D, 0x54, 0x62, 0x69, 0x69,
-  0x3B, 0x3D, 0x66, 0x40, 0x73, 0x66, 0x54, 0x54,
-  0x71, 0x62, 0x3B, 0x6F, 0x6F, 0x6F, 0x3B, 0x27,
-  0x3D, 0x66, 0x66, 0x54, 0x71, 0x71, 0x27, 0x71,
-  0x66, 0x73, 0x3D, 0x27, 0x6F, 0x6F, 0x62, 0x54,
-  0x40, 0x21, 0x5D, 0x73, 0x3D, 0x27, 0x62, 0x6F,
-  0x6F, 0x3B, 0x3B, 0x62, 0x27, 0x71, 0x3D, 0x3D,
-  0x3D, 0x71, 0x62, 0x62, 0x62, 0x27, 0x27, 0x71,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x4F, 0x46, 0x2A, 0x20, 0x20,
-  0x20, 0x73, 0x66, 0x73, 0x3D, 0x27, 0x6F, 0x6F,
-  0x62, 0x54, 0x40, 0x21, 0x5D, 0x73, 0x3D, 0x27,
-  0x62, 0x6F, 0x6F, 0x3B, 0x3B, 0x62, 0x27, 0x71,
-  0x3D, 0x3D, 0x3D, 0x71, 0x62, 0x27, 0x62, 0x27,
-  0x3D, 0x40, 0x66, 0x27, 0x3B, 0x3B, 0x71, 0x66,
-  0x7A, 0x21, 0x40, 0x54, 0x27, 0x3B, 0x6F, 0x3B,
-  0x62, 0x62, 0x27, 0x6D, 0x6D, 0x6D, 0x6D, 0x38,
-  0x6D, 0x6D, 0x38, 0x6D, 0x38, 0x6D, 0x38, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x6D, 0x6D, 0x38, 0x6D, 0x6D, 0x38,
-  0x38, 0x6D, 0x38, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D,
-  0x6F, 0x3B, 0x62, 0x62, 0x27, 0x27, 0x27, 0x27,
-  0x71, 0x3D, 0x71, 0x71, 0x71, 0x71, 0x3D, 0x3D,
-  0x27, 0x40, 0x54, 0x62, 0x30, 0x30, 0x27, 0x40,
-  0x7A, 0x5D, 0x54, 0x3D, 0x62, 0x30, 0x30, 0x3B,
-  0x71, 0x3D, 0x71, 0x38, 0x6D, 0x6D, 0x6D, 0x6D,
-  0x38, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x38, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x6D, 0x6D, 0x38, 0x6D, 0x6D,
-  0x6D, 0x6D, 0x38, 0x6D, 0x38, 0x6D, 0x6D, 0x6D,
-  0x30, 0x3B, 0x71, 0x3D, 0x71, 0x27, 0x71, 0x71,
-  0x3D, 0x66, 0x73, 0x40, 0x73, 0x66, 0x2D, 0x66,
-  0x30, 0x66, 0x71, 0x6F, 0x69, 0x6F, 0x54, 0x21,
-  0x7A, 0x66, 0x3D, 0x3B, 0x6F, 0x6F, 0x3B, 0x71,
-  0x54, 0x66, 0x3D, 0x4C, 0x44, 0x51, 0x44, 0x44,
-  0x44, 0x38, 0x44, 0x38, 0x44, 0x38, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x6D, 0x38, 0x6D, 0x6D, 0x6D,
-  0x38, 0x6D, 0x6D, 0x38, 0x6D, 0x38, 0x38, 0x51,
-  0x3B, 0x71, 0x54, 0x66, 0x3D, 0x3D, 0x3D, 0x2D,
-  0x40, 0x40, 0x5D, 0x40, 0x73, 0x66, 0x66, 0x3D,
-  0x69, 0x27, 0x3B, 0x30, 0x69, 0x3B, 0x73, 0x7A,
-  0x21, 0x3D, 0x62, 0x3B, 0x6F, 0x3B, 0x27, 0x66,
-  0x73, 0x73, 0x54, 0x4E, 0x44, 0x26, 0x26, 0x5B,
-  0x26, 0x44, 0x44, 0x44, 0x44, 0x44, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x38, 0x38, 0x38, 0x38, 0x38,
-  0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x6D, 0x26,
-  0x27, 0x66, 0x73, 0x73, 0x66, 0x2D, 0x66, 0x2D,
-  0x66, 0x54, 0x54, 0x71, 0x27, 0x27, 0x27, 0x62,
-  0x69, 0x3B, 0x6F, 0x6F, 0x62, 0x54, 0x40, 0x21,
-  0x73, 0x27, 0x3B, 0x3B, 0x71, 0x54, 0x66, 0x66,
-  0x73, 0x73, 0x2D, 0x37, 0x44, 0x51, 0x38, 0x38,
-  0x44, 0x6D, 0x38, 0x6D, 0x38, 0x38, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x38, 0x6D, 0x38, 0x6D,
-  0x38, 0x6D, 0x6D, 0x6D, 0x38, 0x38, 0x6D, 0x70,
-  0x2D, 0x66, 0x73, 0x66, 0x66, 0x54, 0x54, 0x54,
-  0x27, 0x62, 0x6F, 0x6F, 0x6F, 0x6F, 0x3B, 0x62,
-  0x3B, 0x27, 0x27, 0x27, 0x3D, 0x40, 0x21, 0x40,
-  0x54, 0x62, 0x3B, 0x71, 0x73, 0x5D, 0x40, 0x73,
-  0x66, 0x66, 0x2D, 0x33, 0x6D, 0x26, 0x44, 0x4F,
-  0x5E, 0x5E, 0x37, 0x5E, 0x37, 0x46, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x44, 0x26, 0x26, 0x44,
-  0x70, 0x38, 0x26, 0x38, 0x38, 0x44, 0x6D, 0x53,
-  0x40, 0x73, 0x66, 0x2D, 0x66, 0x73, 0x66, 0x54,
-  0x27, 0x6F, 0x30, 0x69, 0x30, 0x6F, 0x62, 0x62,
-  0x62, 0x71, 0x3D, 0x54, 0x73, 0x5D, 0x5D, 0x66,
-  0x27, 0x62, 0x71, 0x54, 0x5D, 0x5D, 0x66, 0x3D,
-  0x3D, 0x73, 0x40, 0x37, 0x44, 0x44, 0x51, 0x20,
-  0x6F, 0x6F, 0x62, 0x27, 0x27, 0x20, 0x20, 0x20,
-  0x4F, 0x20, 0x2A, 0x2A, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x71, 0x3D, 0x73, 0x5D,
-  0x40, 0x54, 0x27, 0x3B, 0x2D, 0x6D, 0x38, 0x3C,
-  0x66, 0x3D, 0x54, 0x66, 0x40, 0x40, 0x73, 0x54,
-  0x62, 0x6F, 0x30, 0x6F, 0x62, 0x71, 0x71, 0x71,
-  0x62, 0x3D, 0x66, 0x73, 0x40, 0x5D, 0x73, 0x71,
-  0x62, 0x27, 0x54, 0x73, 0x5D, 0x73, 0x27, 0x62,
-  0x71, 0x40, 0x21, 0x37, 0x26, 0x51, 0x44, 0x4E,
-  0x3B, 0x71, 0x2D, 0x73, 0x2D, 0x20, 0x20, 0x20,
-  0x35, 0x73, 0x77, 0x4F, 0x6B, 0x20, 0x20, 0x4F,
-  0x20, 0x73, 0x73, 0x73, 0x58, 0x20, 0x77, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x2D, 0x40, 0x40, 0x5D,
-  0x73, 0x71, 0x62, 0x27, 0x71, 0x38, 0x44, 0x49,
-  0x27, 0x62, 0x3D, 0x40, 0x21, 0x40, 0x54, 0x27,
-  0x3B, 0x6F, 0x3B, 0x71, 0x54, 0x66, 0x66, 0x3D,
-  0x62, 0x54, 0x40, 0x21, 0x7A, 0x40, 0x3D, 0x62,
-  0x62, 0x71, 0x66, 0x40, 0x66, 0x71, 0x62, 0x3B,
-  0x54, 0x5D, 0x73, 0x23, 0x51, 0x26, 0x26, 0x30,
-  0x3B, 0x3D, 0x66, 0x73, 0x66, 0x20, 0x20, 0x4F,
-  0x58, 0x7C, 0x62, 0x34, 0x57, 0x20, 0x20, 0x20,
-  0x73, 0x58, 0x49, 0x7C, 0x79, 0x73, 0x20, 0x4F,
-  0x20, 0x20, 0x20, 0x20, 0x40, 0x21, 0x7A, 0x40,
-  0x3D, 0x27, 0x62, 0x71, 0x49, 0x44, 0x6D, 0x78,
-  0x62, 0x3B, 0x3D, 0x5D, 0x40, 0x3D, 0x3B, 0x69,
-  0x49, 0x49, 0x3B, 0x71, 0x66, 0x73, 0x66, 0x54,
-  0x27, 0x66, 0x5D, 0x7A, 0x21, 0x73, 0x71, 0x62,
-  0x27, 0x54, 0x73, 0x66, 0x3D, 0x27, 0x62, 0x62,
-  0x54, 0x73, 0x71, 0x37, 0x26, 0x5B, 0x44, 0x5B,
-  0x27, 0x54, 0x40, 0x2D, 0x54, 0x20, 0x20, 0x77,
-  0x78, 0x6D, 0x6D, 0x6D, 0x20, 0x20, 0x20, 0x20,
-  0x79, 0x38, 0x38, 0x6D, 0x6D, 0x69, 0x2D, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x7A, 0x7A, 0x40,
-  0x71, 0x62, 0x27, 0x54, 0x79, 0x26, 0x38, 0x49,
-  0x3B, 0x27, 0x54, 0x2D, 0x71, 0x6F, 0x49, 0x53,
-  0x78, 0x30, 0x27, 0x54, 0x40, 0x73, 0x54, 0x3D,
-  0x71, 0x66, 0x5D, 0x7A, 0x21, 0x66, 0x27, 0x3B,
-  0x27, 0x66, 0x73, 0x54, 0x27, 0x27, 0x27, 0x3D,
-  0x3D, 0x71, 0x6F, 0x5E, 0x26, 0x79, 0x26, 0x78,
-  0x5D, 0x4C, 0x4C, 0x21, 0x73, 0x20, 0x20, 0x2D,
-  0x35, 0x5C, 0x46, 0x38, 0x77, 0x20, 0x4F, 0x20,
-  0x51, 0x6D, 0x20, 0x2D, 0x20, 0x6D, 0x6D, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x7A, 0x21, 0x54,
-  0x62, 0x3B, 0x27, 0x2D, 0x29, 0x26, 0x44, 0x70,
-  0x27, 0x3D, 0x3D, 0x71, 0x6F, 0x78, 0x53, 0x29,
-  0x69, 0x3D, 0x21, 0x4C, 0x4C, 0x5D, 0x66, 0x54,
-  0x54, 0x73, 0x21, 0x6A, 0x21, 0x3D, 0x3B, 0x3B,
-  0x71, 0x66, 0x66, 0x3D, 0x27, 0x27, 0x71, 0x3D,
-  0x27, 0x6F, 0x49, 0x7E, 0x61, 0x5B, 0x44, 0x26,
-  0x34, 0x34, 0x6A, 0x21, 0x73, 0x66, 0x20, 0x32,
-  0x20, 0x20, 0x2D, 0x6D, 0x77, 0x2A, 0x37, 0x20,
-  0x6D, 0x20, 0x20, 0x20, 0x7E, 0x38, 0x38, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x4C, 0x21, 0x3D,
-  0x3B, 0x3B, 0x71, 0x73, 0x69, 0x44, 0x38, 0x71,
-  0x27, 0x3D, 0x71, 0x3B, 0x49, 0x29, 0x29, 0x6F,
-  0x54, 0x7A, 0x34, 0x77, 0x6A, 0x21, 0x66, 0x66,
-  0x4C, 0x7A, 0x21, 0x4C, 0x21, 0x71, 0x3B, 0x3B,
-  0x54, 0x73, 0x3D, 0x62, 0x3B, 0x62, 0x62, 0x62,
-  0x62, 0x69, 0x29, 0x2B, 0x79, 0x79, 0x26, 0x38,
-  0x47, 0x6A, 0x5D, 0x54, 0x27, 0x3D, 0x20, 0x29,
-  0x57, 0x20, 0x2D, 0x61, 0x37, 0x5C, 0x20, 0x20,
-  0x29, 0x20, 0x20, 0x20, 0x20, 0x29, 0x6D, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x6A, 0x21, 0x3D,
-  0x3B, 0x3B, 0x54, 0x66, 0x78, 0x26, 0x26, 0x30,
-  0x62, 0x62, 0x3B, 0x69, 0x78, 0x78, 0x6F, 0x66,
-  0x6A, 0x64, 0x47, 0x4C, 0x5D, 0x54, 0x71, 0x71,
-  0x4C, 0x5D, 0x5D, 0x21, 0x5D, 0x71, 0x3B, 0x62,
-  0x54, 0x66, 0x27, 0x3B, 0x6F, 0x6F, 0x3B, 0x3B,
-  0x6F, 0x49, 0x78, 0x23, 0x4A, 0x79, 0x4A, 0x6D,
-  0x34, 0x21, 0x66, 0x3D, 0x62, 0x27, 0x20, 0x20,
-  0x38, 0x20, 0x20, 0x52, 0x3A, 0x52, 0x63, 0x36,
-  0x48, 0x4D, 0x20, 0x20, 0x20, 0x6D, 0x38, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x5D, 0x3D,
-  0x3B, 0x62, 0x2D, 0x66, 0x79, 0x26, 0x51, 0x54,
-  0x3B, 0x62, 0x6F, 0x49, 0x78, 0x30, 0x66, 0x34,
-  0x2B, 0x2B, 0x34, 0x21, 0x66, 0x71, 0x62, 0x62,
-  0x3D, 0x3D, 0x54, 0x5D, 0x40, 0x71, 0x3B, 0x3B,
-  0x54, 0x54, 0x3B, 0x69, 0x30, 0x6F, 0x3B, 0x27,
-  0x6F, 0x78, 0x78, 0x46, 0x26, 0x5B, 0x4A, 0x51,
-  0x5D, 0x54, 0x71, 0x62, 0x3B, 0x3B, 0x20, 0x20,
-  0x6D, 0x20, 0x72, 0x55, 0x3A, 0x74, 0x41, 0x39,
-  0x45, 0x5A, 0x24, 0x2F, 0x6D, 0x38, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x5D, 0x40, 0x27,
-  0x3B, 0x62, 0x3D, 0x54, 0x30, 0x5B, 0x26, 0x27,
-  0x3B, 0x62, 0x6F, 0x78, 0x78, 0x3B, 0x21, 0x64,
-  0x7B, 0x77, 0x5D, 0x54, 0x71, 0x62, 0x62, 0x3B,
-  0x53, 0x62, 0x71, 0x73, 0x73, 0x27, 0x6F, 0x3B,
-  0x3D, 0x3D, 0x3B, 0x49, 0x30, 0x62, 0x27, 0x27,
-  0x6F, 0x78, 0x49, 0x46, 0x79, 0x53, 0x4A, 0x38,
-  0x2D, 0x71, 0x62, 0x6F, 0x6F, 0x6F, 0x20, 0x20,
-  0x20, 0x24, 0x52, 0x3A, 0x22, 0x41, 0x5A, 0x45,
-  0x45, 0x63, 0x41, 0x22, 0x36, 0x28, 0x4D, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x73, 0x27,
-  0x6F, 0x3B, 0x3D, 0x3D, 0x49, 0x51, 0x61, 0x69,
-  0x27, 0x27, 0x30, 0x78, 0x69, 0x71, 0x4C, 0x64,
-  0x34, 0x5D, 0x66, 0x71, 0x62, 0x6F, 0x6F, 0x6F,
-  0x79, 0x27, 0x66, 0x73, 0x66, 0x62, 0x6F, 0x6F,
-  0x3D, 0x3D, 0x3B, 0x30, 0x30, 0x62, 0x3D, 0x71,
-  0x6F, 0x69, 0x6F, 0x23, 0x5B, 0x4A, 0x4A, 0x38,
-  0x66, 0x3D, 0x3B, 0x6F, 0x6F, 0x3B, 0x20, 0x4D,
-  0x43, 0x48, 0x39, 0x55, 0x22, 0x22, 0x41, 0x45,
-  0x45, 0x45, 0x45, 0x41, 0x22, 0x45, 0x5A, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x2D, 0x62,
-  0x30, 0x3B, 0x3D, 0x3D, 0x27, 0x26, 0x61, 0x27,
-  0x3D, 0x27, 0x6F, 0x69, 0x6F, 0x54, 0x4C, 0x34,
-  0x7A, 0x40, 0x66, 0x54, 0x62, 0x30, 0x6F, 0x3B,
-  0x53, 0x7A, 0x7A, 0x73, 0x54, 0x62, 0x30, 0x3B,
-  0x3D, 0x3D, 0x62, 0x30, 0x30, 0x3B, 0x71, 0x62,
-  0x30, 0x30, 0x27, 0x7E, 0x70, 0x70, 0x3C, 0x6D,
-  0x21, 0x66, 0x3B, 0x69, 0x3B, 0x71, 0x20, 0x72,
-  0x24, 0x67, 0x22, 0x22, 0x36, 0x36, 0x45, 0x45,
-  0x45, 0x22, 0x41, 0x41, 0x3F, 0x42, 0x52, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x54, 0x62,
-  0x30, 0x3B, 0x3D, 0x54, 0x62, 0x26, 0x79, 0x3B,
-  0x71, 0x27, 0x30, 0x30, 0x27, 0x5D, 0x4C, 0x6A,
-  0x7A, 0x7A, 0x5D, 0x54, 0x3B, 0x30, 0x6F, 0x71,
-  0x27, 0x64, 0x77, 0x40, 0x71, 0x62, 0x3B, 0x62,
-  0x3D, 0x54, 0x27, 0x3B, 0x6F, 0x3B, 0x27, 0x27,
-  0x62, 0x3B, 0x3D, 0x23, 0x26, 0x5B, 0x3C, 0x38,
-  0x5D, 0x71, 0x69, 0x69, 0x62, 0x54, 0x20, 0x50,
-  0x5F, 0x48, 0x3A, 0x55, 0x41, 0x63, 0x70, 0x22,
-  0x22, 0x45, 0x3F, 0x42, 0x48, 0x48, 0x45, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x71, 0x62,
-  0x3B, 0x62, 0x3D, 0x54, 0x30, 0x26, 0x61, 0x71,
-  0x27, 0x27, 0x62, 0x62, 0x54, 0x5D, 0x7A, 0x4C,
-  0x4C, 0x4C, 0x5D, 0x71, 0x30, 0x69, 0x62, 0x54,
-  0x7A, 0x64, 0x34, 0x73, 0x71, 0x27, 0x62, 0x62,
-  0x71, 0x54, 0x71, 0x3B, 0x6F, 0x3B, 0x71, 0x3D,
-  0x3D, 0x71, 0x2D, 0x7E, 0x79, 0x53, 0x3C, 0x38,
-  0x3D, 0x6F, 0x78, 0x49, 0x71, 0x73, 0x20, 0x20,
-  0x25, 0x3F, 0x3A, 0x41, 0x5A, 0x45, 0x41, 0x45,
-  0x3F, 0x50, 0x24, 0x28, 0x28, 0x3F, 0x4D, 0x20,
-  0x20, 0x77, 0x77, 0x20, 0x20, 0x20, 0x71, 0x27,
-  0x62, 0x62, 0x71, 0x54, 0x78, 0x79, 0x38, 0x71,
-  0x71, 0x3D, 0x71, 0x71, 0x66, 0x5D, 0x5D, 0x21,
-  0x21, 0x21, 0x54, 0x30, 0x78, 0x69, 0x27, 0x66,
-  0x7A, 0x4C, 0x40, 0x3D, 0x27, 0x62, 0x62, 0x3B,
-  0x62, 0x71, 0x62, 0x30, 0x69, 0x6F, 0x71, 0x54,
-  0x3D, 0x3D, 0x54, 0x23, 0x4A, 0x3C, 0x3C, 0x38,
-  0x6F, 0x29, 0x53, 0x30, 0x54, 0x66, 0x20, 0x57,
-  0x7C, 0x25, 0x4B, 0x3F, 0x43, 0x4B, 0x4B, 0x2C,
-  0x2E, 0x2E, 0x2E, 0x24, 0x58, 0x58, 0x78, 0x20,
-  0x20, 0x20, 0x34, 0x77, 0x20, 0x20, 0x20, 0x62,
-  0x62, 0x3B, 0x62, 0x71, 0x29, 0x79, 0x61, 0x27,
-  0x27, 0x54, 0x54, 0x71, 0x54, 0x54, 0x66, 0x54,
-  0x66, 0x71, 0x6F, 0x78, 0x53, 0x69, 0x54, 0x73,
-  0x73, 0x73, 0x3D, 0x27, 0x27, 0x27, 0x62, 0x3B,
-  0x62, 0x71, 0x71, 0x3B, 0x6F, 0x3B, 0x27, 0x54,
-  0x66, 0x3D, 0x3D, 0x37, 0x53, 0x78, 0x49, 0x38,
-  0x78, 0x29, 0x78, 0x3B, 0x66, 0x73, 0x20, 0x20,
-  0x7C, 0x69, 0x68, 0x68, 0x52, 0x2E, 0x42, 0x67,
-  0x5F, 0x45, 0x2C, 0x69, 0x78, 0x32, 0x78, 0x78,
-  0x20, 0x20, 0x34, 0x77, 0x35, 0x20, 0x20, 0x27,
-  0x62, 0x3B, 0x62, 0x71, 0x30, 0x26, 0x61, 0x73,
-  0x27, 0x3D, 0x66, 0x3D, 0x3D, 0x27, 0x27, 0x62,
-  0x62, 0x6F, 0x78, 0x53, 0x78, 0x62, 0x54, 0x66,
-  0x27, 0x71, 0x3D, 0x71, 0x62, 0x62, 0x27, 0x3B,
-  0x62, 0x71, 0x71, 0x27, 0x27, 0x27, 0x27, 0x3D,
-  0x54, 0x3D, 0x27, 0x7E, 0x29, 0x29, 0x29, 0x6D,
-  0x49, 0x49, 0x6F, 0x54, 0x73, 0x54, 0x20, 0x20,
-  0x29, 0x7C, 0x69, 0x43, 0x76, 0x72, 0x2C, 0x76,
-  0x68, 0x62, 0x78, 0x29, 0x6D, 0x38, 0x6D, 0x32,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62,
-  0x27, 0x3B, 0x62, 0x71, 0x78, 0x61, 0x6D, 0x3C,
-  0x27, 0x3D, 0x54, 0x3D, 0x27, 0x62, 0x3B, 0x6F,
-  0x6F, 0x69, 0x49, 0x49, 0x6F, 0x3D, 0x73, 0x66,
-  0x3D, 0x3D, 0x3D, 0x3D, 0x71, 0x27, 0x71, 0x62,
-  0x62, 0x71, 0x3D, 0x71, 0x71, 0x71, 0x27, 0x71,
-  0x54, 0x3D, 0x27, 0x46, 0x49, 0x78, 0x49, 0x6D,
-  0x6F, 0x27, 0x54, 0x73, 0x40, 0x20, 0x20, 0x20,
-  0x44, 0x32, 0x29, 0x49, 0x77, 0x2F, 0x73, 0x62,
-  0x29, 0x32, 0x29, 0x51, 0x6D, 0x38, 0x6D, 0x38,
-  0x56, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x71, 0x62, 0x62, 0x71, 0x6F, 0x70, 0x38, 0x71,
-  0x27, 0x71, 0x54, 0x3D, 0x62, 0x3B, 0x3B, 0x6F,
-  0x6F, 0x6F, 0x3B, 0x27, 0x54, 0x40, 0x73, 0x66,
-  0x40, 0x40, 0x66, 0x3D, 0x71, 0x3D, 0x71, 0x71,
-  0x27, 0x27, 0x3D, 0x54, 0x3D, 0x3D, 0x71, 0x54,
-  0x73, 0x73, 0x3D, 0x46, 0x78, 0x49, 0x78, 0x44,
-  0x66, 0x73, 0x5D, 0x5D, 0x35, 0x20, 0x20, 0x78,
-  0x6D, 0x51, 0x78, 0x49, 0x58, 0x29, 0x29, 0x49,
-  0x29, 0x79, 0x38, 0x38, 0x6D, 0x6D, 0x38, 0x6D,
-  0x6D, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x6B, 0x71, 0x27, 0x27, 0x29, 0x3C, 0x44, 0x40,
-  0x3D, 0x54, 0x73, 0x73, 0x54, 0x71, 0x71, 0x3D,
-  0x3D, 0x3D, 0x66, 0x40, 0x5D, 0x5D, 0x5D, 0x40,
-  0x21, 0x5D, 0x73, 0x66, 0x3D, 0x3D, 0x71, 0x71,
-  0x27, 0x27, 0x3D, 0x54, 0x54, 0x66, 0x54, 0x73,
-  0x5D, 0x21, 0x40, 0x33, 0x69, 0x49, 0x30, 0x38,
-  0x7A, 0x7A, 0x7A, 0x21, 0x6B, 0x20, 0x20, 0x6D,
-  0x38, 0x6D, 0x38, 0x7C, 0x49, 0x29, 0x69, 0x78,
-  0x38, 0x38, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x38,
-  0x6D, 0x37, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x71, 0x27, 0x71, 0x78, 0x3C, 0x26, 0x30,
-  0x66, 0x66, 0x5D, 0x21, 0x5D, 0x73, 0x73, 0x40,
-  0x5D, 0x21, 0x7A, 0x4C, 0x21, 0x5D, 0x21, 0x21,
-  0x5D, 0x54, 0x54, 0x54, 0x3D, 0x71, 0x3D, 0x71,
-  0x27, 0x27, 0x71, 0x54, 0x66, 0x54, 0x66, 0x66,
-  0x5D, 0x21, 0x5D, 0x7E, 0x29, 0x69, 0x49, 0x6D,
-  0x4C, 0x7A, 0x5D, 0x20, 0x20, 0x20, 0x51, 0x38,
-  0x6D, 0x6D, 0x6D, 0x44, 0x69, 0x78, 0x5B, 0x6D,
-  0x6D, 0x6D, 0x6D, 0x6D, 0x38, 0x6D, 0x6D, 0x6D,
-  0x38, 0x38, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x62, 0x27, 0x3C, 0x69, 0x38, 0x71,
-  0x54, 0x73, 0x5D, 0x21, 0x40, 0x73, 0x66, 0x73,
-  0x21, 0x4C, 0x4C, 0x7A, 0x5D, 0x5D, 0x5D, 0x4C,
-  0x66, 0x62, 0x62, 0x27, 0x71, 0x71, 0x71, 0x27,
-  0x27, 0x27, 0x71, 0x3D, 0x54, 0x54, 0x54, 0x54,
-  0x73, 0x73, 0x3D, 0x57, 0x29, 0x69, 0x30, 0x38,
-  0x73, 0x73, 0x20, 0x20, 0x20, 0x2D, 0x6D, 0x6D,
-  0x38, 0x6D, 0x6D, 0x6D, 0x38, 0x38, 0x6D, 0x6D,
-  0x6D, 0x38, 0x6D, 0x6D, 0x38, 0x6D, 0x6D, 0x6D,
-  0x6D, 0x38, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x27, 0x5B, 0x53, 0x6D, 0x73,
-  0x54, 0x54, 0x73, 0x73, 0x3D, 0x27, 0x27, 0x71,
-  0x66, 0x40, 0x73, 0x40, 0x66, 0x73, 0x40, 0x21,
-  0x62, 0x30, 0x6F, 0x62, 0x27, 0x71, 0x3D, 0x71,
-  0x27, 0x71, 0x71, 0x71, 0x3D, 0x3D, 0x3D, 0x3D,
-  0x3D, 0x27, 0x58, 0x46, 0x69, 0x30, 0x6F, 0x6D,
-  0x3D, 0x71, 0x20, 0x20, 0x20, 0x44, 0x6D, 0x6D,
-  0x6D, 0x6D, 0x6D, 0x38, 0x6D, 0x6D, 0x38, 0x6D,
-  0x38, 0x6D, 0x38, 0x6D, 0x6D, 0x6D, 0x38, 0x6D,
-  0x6D, 0x6D, 0x2F, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x70, 0x53, 0x38, 0x27,
-  0x3D, 0x3D, 0x3D, 0x71, 0x3B, 0x30, 0x62, 0x3D,
-  0x66, 0x54, 0x3D, 0x71, 0x3D, 0x3D, 0x66, 0x66,
-  0x3B, 0x69, 0x69, 0x6F, 0x62, 0x27, 0x3D, 0x71,
-  0x27, 0x27, 0x27, 0x27, 0x71, 0x3D, 0x3D, 0x3D,
-  0x3D, 0x27, 0x3B, 0x46, 0x62, 0x3B, 0x49, 0x38,
-  0x3D, 0x20, 0x20, 0x20, 0x34, 0x44, 0x6D, 0x6D,
-  0x38, 0x6D, 0x6D, 0x38, 0x6D, 0x6D, 0x38, 0x6D,
-  0x6D, 0x6D, 0x6D, 0x38, 0x6D, 0x6D, 0x38, 0x6D,
-  0x38, 0x6D, 0x26, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x21, 0x49, 0x79, 0x51, 0x5D,
-  0x3D, 0x3D, 0x71, 0x27, 0x62, 0x62, 0x3D, 0x73,
-  0x40, 0x66, 0x3D, 0x3D, 0x54, 0x3D, 0x3D, 0x71,
-  0x78, 0x49, 0x69, 0x30, 0x3B, 0x62, 0x27, 0x27,
-  0x27, 0x27, 0x27, 0x71, 0x71, 0x71, 0x3D, 0x3D,
-  0x3D, 0x27, 0x3D, 0x33, 0x49, 0x69, 0x62, 0x44,
-  0x20, 0x20, 0x20, 0x20, 0x2D, 0x32, 0x6D, 0x38,
-  0x6D, 0x6D, 0x6D, 0x6D, 0x38, 0x38, 0x6D, 0x6D,
-  0x6D, 0x6D, 0x38, 0x6D, 0x38, 0x6D, 0x38, 0x51,
-  0x26, 0x61, 0x44, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x6A, 0x70, 0x6F, 0x6D, 0x21,
-  0x71, 0x3D, 0x3D, 0x71, 0x3D, 0x66, 0x40, 0x5D,
-  0x40, 0x73, 0x66, 0x73, 0x66, 0x54, 0x3D, 0x71,
-  0x70, 0x78, 0x49, 0x30, 0x6F, 0x6F, 0x62, 0x62,
-  0x62, 0x27, 0x71, 0x3D, 0x54, 0x54, 0x54, 0x3D,
-  0x3D, 0x71, 0x3D, 0x2A, 0x30, 0x2D, 0x3B, 0x26,
-  0x38, 0x20, 0x20, 0x20, 0x2D, 0x62, 0x32, 0x26,
-  0x38, 0x6D, 0x6D, 0x38, 0x5B, 0x38, 0x6D, 0x38,
-  0x6D, 0x6D, 0x6D, 0x26, 0x32, 0x29, 0x29, 0x29,
-  0x53, 0x29, 0x61, 0x6D, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x44, 0x3D, 0x3C, 0x62, 0x79, 0x7A,
-  0x54, 0x54, 0x71, 0x27, 0x3D, 0x66, 0x73, 0x40,
-  0x73, 0x66, 0x66, 0x73, 0x2D, 0x54, 0x71, 0x71,
-  0x4A, 0x3B, 0x62, 0x3B, 0x3B, 0x3B, 0x3B, 0x27,
-  0x27, 0x27, 0x71, 0x3D, 0x2D, 0x73, 0x73, 0x54,
-  0x3D, 0x71, 0x71, 0x33, 0x30, 0x71, 0x5D, 0x38,
-  0x6D, 0x6D, 0x38, 0x38, 0x38, 0x6D, 0x6D, 0x6D,
-  0x6D, 0x6D, 0x44, 0x38, 0x6F, 0x7A, 0x64, 0x64,
-  0x23, 0x23, 0x56, 0x23, 0x23, 0x7B, 0x47, 0x64,
-  0x54, 0x29, 0x44, 0x38, 0x38, 0x6D, 0x38, 0x38,
-  0x6D, 0x38, 0x38, 0x6D, 0x53, 0x49, 0x6D, 0x34,
-  0x73, 0x54, 0x3D, 0x71, 0x71, 0x3D, 0x54, 0x3D,
-  0x3D, 0x54, 0x66, 0x66, 0x66, 0x54, 0x54, 0x3D,
-  0x49, 0x3D, 0x54, 0x54, 0x3D, 0x71, 0x27, 0x27,
-  0x71, 0x71, 0x71, 0x3D, 0x54, 0x54, 0x54, 0x3D,
-  0x3D, 0x71, 0x71, 0x33, 0x29, 0x3D, 0x3D, 0x6D,
-  0x38, 0x6D, 0x6D, 0x38, 0x6D, 0x38, 0x38, 0x6D,
-  0x38, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x38, 0x6D,
-  0x38, 0x6D, 0x38, 0x6D, 0x6D, 0x38, 0x6D, 0x6D,
-  0x38, 0x6D, 0x6D, 0x6D, 0x38, 0x38, 0x6D, 0x44,
-  0x6D, 0x38, 0x38, 0x6D, 0x69, 0x78, 0x61, 0x73,
-  0x54, 0x3D, 0x3D, 0x71, 0x71, 0x3D, 0x3D, 0x3D,
-  0x71, 0x3D, 0x3D, 0x3D, 0x3D, 0x54, 0x3D, 0x71,
-  0x3B, 0x66, 0x73, 0x73, 0x2D, 0x2D, 0x54, 0x3D,
-  0x71, 0x71, 0x3D, 0x71, 0x71, 0x71, 0x27, 0x27,
-  0x27, 0x71, 0x71, 0x33, 0x3B, 0x62, 0x27, 0x3D,
-  0x27, 0x3B, 0x3B, 0x27, 0x62, 0x3B, 0x3D, 0x3D,
-  0x30, 0x27, 0x62, 0x62, 0x62, 0x71, 0x30, 0x27,
-  0x3B, 0x6F, 0x30, 0x30, 0x3B, 0x30, 0x3B, 0x62,
-  0x3B, 0x69, 0x49, 0x30, 0x29, 0x29, 0x29, 0x29,
-  0x49, 0x29, 0x30, 0x29, 0x29, 0x29, 0x51, 0x21,
-  0x27, 0x27, 0x71, 0x71, 0x71, 0x3D, 0x3D, 0x71,
-  0x71, 0x71, 0x71, 0x3D, 0x71, 0x71, 0x71, 0x62,
-  0x3B, 0x54, 0x66, 0x66, 0x66, 0x54, 0x3D, 0x54,
-  0x66, 0x54, 0x3D, 0x27, 0x62, 0x62, 0x3B, 0x3B,
-  0x3B, 0x62, 0x27, 0x33, 0x30, 0x6F, 0x71, 0x3B,
-  0x62, 0x3B, 0x62, 0x27, 0x27, 0x30, 0x62, 0x27,
-  0x62, 0x27, 0x3B, 0x49, 0x3B, 0x30, 0x29, 0x3B,
-  0x3B, 0x30, 0x30, 0x69, 0x30, 0x6F, 0x30, 0x49,
-  0x3B, 0x6F, 0x49, 0x29, 0x49, 0x49, 0x3C, 0x29,
-  0x49, 0x49, 0x69, 0x70, 0x70, 0x29, 0x51, 0x27,
-  0x3B, 0x3B, 0x3B, 0x62, 0x27, 0x27, 0x27, 0x27,
-  0x27, 0x3D, 0x3D, 0x3D, 0x71, 0x27, 0x27, 0x27,
-  0x69, 0x71, 0x3D, 0x54, 0x71, 0x62, 0x27, 0x71,
-  0x54, 0x2D, 0x3D, 0x27, 0x62, 0x3B, 0x3B, 0x3B,
-  0x3B, 0x62, 0x62, 0x33, 0x27, 0x27, 0x3B, 0x71,
-  0x27, 0x71, 0x27, 0x62, 0x71, 0x6F, 0x27, 0x71,
-  0x3B, 0x62, 0x62, 0x6F, 0x62, 0x6F, 0x6F, 0x6F,
-  0x6F, 0x69, 0x62, 0x49, 0x69, 0x49, 0x6F, 0x62,
-  0x62, 0x49, 0x69, 0x71, 0x6F, 0x6F, 0x6F, 0x69,
-  0x69, 0x69, 0x30, 0x29, 0x30, 0x69, 0x44, 0x7B,
-  0x3B, 0x3B, 0x3B, 0x62, 0x62, 0x62, 0x62, 0x62,
-  0x27, 0x3D, 0x3D, 0x54, 0x71, 0x3D, 0x3D, 0x54,
-  0x69, 0x71, 0x3D, 0x71, 0x62, 0x3B, 0x3B, 0x27,
-  0x54, 0x54, 0x3D, 0x71, 0x71, 0x71, 0x27, 0x62,
-  0x62, 0x62, 0x27, 0x2A, 0x3D, 0x71, 0x3D, 0x71,
-  0x3D, 0x62, 0x27, 0x30, 0x30, 0x62, 0x3B, 0x71,
-  0x3B, 0x30, 0x30, 0x49, 0x29, 0x30, 0x30, 0x30,
-  0x27, 0x49, 0x62, 0x30, 0x6F, 0x30, 0x3B, 0x3B,
-  0x6F, 0x3B, 0x49, 0x30, 0x30, 0x3C, 0x3B, 0x49,
-  0x30, 0x69, 0x6F, 0x78, 0x30, 0x62, 0x44, 0x7B,
-  0x27, 0x62, 0x62, 0x62, 0x71, 0x71, 0x3D, 0x54,
-  0x3D, 0x73, 0x66, 0x73, 0x66, 0x73, 0x73, 0x66,
-  0x62, 0x66, 0x66, 0x3D, 0x27, 0x3B, 0x3B, 0x71,
-  0x3D, 0x3D, 0x3D, 0x54, 0x54, 0x71, 0x3D, 0x3D,
-  0x54, 0x73, 0x5D, 0x33, 0x62, 0x27, 0x54, 0x27,
-  0x71, 0x3B, 0x71, 0x71, 0x62, 0x3B, 0x54, 0x3B,
-  0x71, 0x6F, 0x62, 0x62, 0x62, 0x62, 0x69, 0x71,
-  0x71, 0x6F, 0x3B, 0x71, 0x30, 0x62, 0x71, 0x6F,
-  0x3B, 0x62, 0x6F, 0x62, 0x6F, 0x69, 0x6F, 0x69,
-  0x6F, 0x30, 0x49, 0x3C, 0x69, 0x3B, 0x79, 0x21,
-  0x20, 0x3D, 0x54, 0x73, 0x5D, 0x5D, 0x5D, 0x40,
-  0x40, 0x73, 0x73, 0x73, 0x2D, 0x66, 0x66, 0x3D,
-  0x3D, 0x54, 0x54, 0x3D, 0x71, 0x27, 0x62, 0x27,
-  0x71, 0x71, 0x3D, 0x54, 0x54, 0x3D, 0x3D, 0x54,
-  0x5D, 0x6A, 0x77, 0x46, 0x71, 0x2D, 0x54, 0x27,
-  0x54, 0x3B, 0x3B, 0x3B, 0x6F, 0x3B, 0x71, 0x27,
-  0x3B, 0x27, 0x3B, 0x3B, 0x27, 0x27, 0x3B, 0x3B,
-  0x3B, 0x62, 0x3D, 0x62, 0x3D, 0x27, 0x3B, 0x54,
-  0x3B, 0x2D, 0x49, 0x3B, 0x3B, 0x29, 0x49, 0x3C,
-  0x53, 0x69, 0x53, 0x3C, 0x78, 0x3D, 0x78, 0x5D,
-  0x20, 0x66, 0x5D, 0x6A, 0x47, 0x77, 0x4C, 0x5D,
-  0x66, 0x3D, 0x3D, 0x66, 0x73, 0x66, 0x3D, 0x62,
-  0x62, 0x62, 0x71, 0x3D, 0x71, 0x27, 0x27, 0x27,
-  0x71, 0x71, 0x71, 0x3D, 0x3D, 0x71, 0x71, 0x73,
-  0x7A, 0x77, 0x47, 0x46, 0x27, 0x73, 0x27, 0x54,
-  0x3D, 0x71, 0x62, 0x6F, 0x27, 0x71, 0x27, 0x71,
-  0x71, 0x71, 0x62, 0x62, 0x71, 0x71, 0x71, 0x62,
-  0x62, 0x3B, 0x69, 0x49, 0x62, 0x6F, 0x62, 0x3D,
-  0x6F, 0x6F, 0x62, 0x78, 0x2A, 0x20, 0x6B, 0x20,
-  0x2A, 0x20, 0x20, 0x2A, 0x3B, 0x6F, 0x3C, 0x4C,
-  0x20, 0x20, 0x7A, 0x77, 0x47, 0x6A, 0x5D, 0x54,
-  0x27, 0x6F, 0x3B, 0x54, 0x40, 0x2D, 0x71, 0x6F,
-  0x49, 0x6F, 0x27, 0x3D, 0x71, 0x62, 0x62, 0x3B,
-  0x62, 0x27, 0x71, 0x3D, 0x3D, 0x71, 0x71, 0x66,
-  0x7A, 0x34, 0x6A, 0x46, 0x27, 0x5D, 0x3D, 0x54,
-  0x3D, 0x3D, 0x3D, 0x62, 0x27, 0x71, 0x27, 0x3D,
-  0x3B, 0x3D, 0x30, 0x27, 0x27, 0x3B, 0x27, 0x3D,
-  0x20, 0x20, 0x2A, 0x46, 0x46, 0x2A, 0x35, 0x2A,
-  0x46, 0x46, 0x23, 0x2A, 0x7A, 0x4F, 0x4F, 0x6B,
-  0x6B, 0x4F, 0x4F, 0x62, 0x3B, 0x62, 0x78, 0x20,
-  0x20, 0x20, 0x7A, 0x34, 0x34, 0x40, 0x54, 0x71,
-  0x3B, 0x69, 0x6F, 0x40, 0x7A, 0x66, 0x62, 0x69,
-  0x3C, 0x3B, 0x71, 0x3D, 0x27, 0x3B, 0x6F, 0x27,
-  0x71, 0x3D, 0x3D, 0x66, 0x2D, 0x3D, 0x62, 0x27,
-  0x2D, 0x4C, 0x7A, 0x33, 0x27, 0x3D, 0x54, 0x2D,
-  0x54, 0x62, 0x54, 0x27, 0x54, 0x27, 0x54, 0x71,
-  0x62, 0x71, 0x71, 0x62, 0x62, 0x54, 0x71, 0x62,
-  0x7A, 0x6B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x35, 0x57,
-  0x6B, 0x20, 0x20, 0x30, 0x6F, 0x27, 0x29, 0x20,
-  0x20, 0x20, 0x66, 0x4C, 0x7A, 0x54, 0x62, 0x3B,
-  0x6F, 0x30, 0x71, 0x7A, 0x4C, 0x3D, 0x69, 0x78,
-  0x53, 0x3D, 0x73, 0x2D, 0x71, 0x62, 0x3B, 0x71,
-  0x3D, 0x2D, 0x2D, 0x40, 0x73, 0x3D, 0x27, 0x71,
-  0x40, 0x6A, 0x20, 0x20, 0x71, 0x2D, 0x62, 0x2D,
-  0x3D, 0x3B, 0x71, 0x27, 0x54, 0x27, 0x3D, 0x3D,
-  0x27, 0x2D, 0x27, 0x3D, 0x3B, 0x2D, 0x3D, 0x3B,
-  0x34, 0x2D, 0x77, 0x6A, 0x77, 0x2D, 0x6A, 0x7A,
-  0x5D, 0x6A, 0x5D, 0x54, 0x71, 0x44, 0x6D, 0x6D,
-  0x6D, 0x38, 0x26, 0x30, 0x54, 0x62, 0x20, 0x20,
-  0x20, 0x20, 0x40, 0x6A, 0x4C, 0x54, 0x6F, 0x69,
-  0x30, 0x62, 0x40, 0x6A, 0x21, 0x62, 0x49, 0x29,
-  0x71, 0x4C, 0x34, 0x5D, 0x71, 0x3B, 0x27, 0x71,
-  0x54, 0x54, 0x40, 0x40, 0x73, 0x3D, 0x3D, 0x40,
-  0x6A, 0x20, 0x20, 0x33, 0x2D, 0x73, 0x40, 0x4E,
-  0x77, 0x7A, 0x3D, 0x54, 0x2D, 0x54, 0x71, 0x54,
-  0x62, 0x71, 0x71, 0x62, 0x71, 0x71, 0x71, 0x71,
-  0x2D, 0x3B, 0x27, 0x3B, 0x49, 0x6F, 0x3B, 0x3B,
-  0x27, 0x3B, 0x3B, 0x30, 0x49, 0x53, 0x6F, 0x6F,
-  0x69, 0x3B, 0x6F, 0x53, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x6A, 0x77, 0x21, 0x27, 0x30, 0x30,
-  0x6F, 0x71, 0x66, 0x73, 0x3D, 0x30, 0x49, 0x30,
-  0x5D, 0x34, 0x34, 0x40, 0x27, 0x6F, 0x62, 0x3D,
-  0x54, 0x66, 0x40, 0x73, 0x2D, 0x66, 0x2D, 0x5D,
-  0x7A, 0x20, 0x20, 0x56, 0x20, 0x54, 0x5D, 0x5E,
-  0x33, 0x71, 0x3D, 0x62, 0x27, 0x3B, 0x27, 0x30,
-  0x3B, 0x3D, 0x27, 0x3D, 0x3D, 0x3D, 0x3B, 0x73,
-  0x54, 0x62, 0x62, 0x62, 0x30, 0x6F, 0x71, 0x6F,
-  0x6F, 0x6F, 0x6F, 0x71, 0x62, 0x3B, 0x3B, 0x49,
-  0x3B, 0x3B, 0x3B, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x7A, 0x21, 0x54, 0x3B, 0x69, 0x69,
-  0x30, 0x62, 0x27, 0x71, 0x62, 0x30, 0x30, 0x6F,
-  0x4C, 0x77, 0x6A, 0x66, 0x62, 0x6F, 0x62, 0x71,
-  0x54, 0x66, 0x2D, 0x73, 0x66, 0x54, 0x73, 0x73,
-  0x73, 0x20, 0x20, 0x7E, 0x20, 0x3D, 0x27, 0x6B,
-  0x35, 0x21, 0x54, 0x3D, 0x71, 0x71, 0x54, 0x62,
-  0x62, 0x71, 0x71, 0x69, 0x71, 0x54, 0x54, 0x30,
-  0x27, 0x3B, 0x3B, 0x3B, 0x6F, 0x30, 0x3B, 0x30,
-  0x3B, 0x30, 0x30, 0x27, 0x30, 0x6F, 0x62, 0x69,
-  0x6F, 0x6F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x73, 0x3D, 0x62, 0x6F, 0x69, 0x69,
-  0x6F, 0x71, 0x3D, 0x71, 0x27, 0x62, 0x62, 0x27,
-  0x4C, 0x4C, 0x5D, 0x71, 0x30, 0x69, 0x3B, 0x71,
-  0x54, 0x66, 0x73, 0x66, 0x66, 0x66, 0x54, 0x3D,
-  0x71, 0x20, 0x20, 0x7E, 0x20, 0x20, 0x21, 0x62,
-  0x69, 0x27, 0x5D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3B,
-  0x3D, 0x3D, 0x27, 0x3B, 0x27, 0x3D, 0x71, 0x6F,
-  0x54, 0x62, 0x6F, 0x30, 0x6F, 0x6F, 0x62, 0x6F,
-  0x62, 0x62, 0x62, 0x62, 0x3B, 0x3B, 0x27, 0x3B,
-  0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x27, 0x3B, 0x6F, 0x30, 0x6F, 0x6F,
-  0x62, 0x3D, 0x66, 0x54, 0x54, 0x71, 0x71, 0x71,
-  0x5D, 0x5D, 0x54, 0x3B, 0x69, 0x69, 0x3B, 0x71,
-  0x54, 0x40, 0x73, 0x66, 0x54, 0x3D, 0x71, 0x62,
-  0x6F, 0x20, 0x20, 0x39, 0x20, 0x20, 0x20, 0x2D,
-  0x2D, 0x73, 0x40, 0x54, 0x54, 0x54, 0x71, 0x73,
-  0x54, 0x73, 0x71, 0x54, 0x54, 0x54, 0x27, 0x3B,
-  0x3D, 0x3B, 0x27, 0x62, 0x3B, 0x3B, 0x3B, 0x27,
-  0x27, 0x3B, 0x3B, 0x27, 0x62, 0x62, 0x71, 0x62,
-  0x71, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x3B, 0x6F, 0x30, 0x6F, 0x3B, 0x27,
-  0x3D, 0x66, 0x66, 0x54, 0x71, 0x71, 0x27, 0x71,
-  0x66, 0x73, 0x54, 0x27, 0x6F, 0x6F, 0x27, 0x54,
-  0x40, 0x21, 0x5D, 0x73, 0x3D, 0x27, 0x62, 0x3B,
-  0x3B, 0x42, 0x74, 0x52, 0x52, 0x6E, 0x20, 0x20,
-  0x40, 0x54, 0x3D, 0x3D, 0x3D, 0x40, 0x27, 0x3B,
-  0x30, 0x40, 0x27, 0x27, 0x27, 0x71, 0x54, 0x6F,
-  0x5D, 0x6F, 0x3B, 0x71, 0x71, 0x6F, 0x73, 0x6F,
-  0x54, 0x6F, 0x54, 0x27, 0x39, 0x6E, 0x6E, 0x3B,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x3B, 0x3B, 0x3B, 0x62, 0x27, 0x71,
-  0x3D, 0x3D, 0x3D, 0x27, 0x62, 0x27, 0x62, 0x27,
-  0x3D, 0x40, 0x54, 0x27, 0x3B, 0x3B, 0x27, 0x73,
-  0x7A, 0x21, 0x40, 0x54, 0x71, 0x62, 0x6F, 0x6F,
-  0x3B, 0x67, 0x3A, 0x3A, 0x5A, 0x48, 0x3A, 0x20,
-  0x20, 0x53, 0x6D, 0x38, 0x38, 0x6D, 0x38, 0x38,
-  0x6D, 0x38, 0x79, 0x6D, 0x38, 0x6D, 0x6D, 0x6D,
-  0x6D, 0x6D, 0x38, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D,
-  0x6D, 0x6D, 0x6D, 0x67, 0x52, 0x41, 0x22, 0x2F,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4F, 0x6B,
-  0x43, 0x3A, 0x3B, 0x27, 0x27, 0x62, 0x27, 0x71,
-  0x71, 0x71, 0x71, 0x3D, 0x71, 0x71, 0x3D, 0x3D,
-  0x27, 0x40, 0x54, 0x27, 0x30, 0x30, 0x27, 0x40,
-  0x7A, 0x5D, 0x54, 0x71, 0x3B, 0x30, 0x30, 0x3B,
-  0x42, 0x67, 0x67, 0x3E, 0x3A, 0x48, 0x22, 0x5A,
-  0x4F, 0x20, 0x2D, 0x6D, 0x6D, 0x6D, 0x6D, 0x38,
-  0x6D, 0x6D, 0x26, 0x6D, 0x38, 0x6D, 0x38, 0x6D,
-  0x6D, 0x6D, 0x38, 0x6D, 0x38, 0x38, 0x6D, 0x38,
-  0x6D, 0x38, 0x38, 0x3E, 0x55, 0x6C, 0x22, 0x73,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4D,
-  0x5A, 0x45, 0x36, 0x3D, 0x71, 0x27, 0x27, 0x71,
-  0x54, 0x66, 0x73, 0x40, 0x73, 0x66, 0x2D, 0x66,
-  0x30, 0x66, 0x71, 0x30, 0x69, 0x6F, 0x3D, 0x21,
-  0x7A, 0x66, 0x3D, 0x62, 0x3B, 0x6F, 0x3B, 0x28,
-  0x67, 0x52, 0x5A, 0x74, 0x41, 0x3A, 0x74, 0x3A,
-  0x52, 0x20, 0x20, 0x7E, 0x38, 0x6D, 0x6D, 0x6D,
-  0x6D, 0x38, 0x38, 0x6D, 0x6D, 0x6D, 0x6D, 0x38,
-  0x38, 0x6D, 0x6D, 0x38, 0x6D, 0x6D, 0x38, 0x6D,
-  0x6D, 0x6D, 0x6D, 0x2F, 0x52, 0x22, 0x28, 0x50,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E,
-  0x41, 0x5A, 0x5A, 0x66, 0x54, 0x3D, 0x54, 0x66,
-  0x73, 0x40, 0x40, 0x40, 0x73, 0x66, 0x66, 0x3D,
-  0x69, 0x27, 0x3B, 0x30, 0x30, 0x62, 0x73, 0x7A,
-  0x21, 0x3D, 0x3B, 0x6F, 0x6F, 0x62, 0x2F, 0x75,
-  0x28, 0x55, 0x22, 0x3A, 0x31, 0x3A, 0x41, 0x3A,
-  0x5A, 0x2E, 0x20, 0x4F, 0x20, 0x6D, 0x6D, 0x6D,
-  0x6D, 0x6D, 0x38, 0x6D, 0x38, 0x6D, 0x6D, 0x6D,
-  0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x38,
-  0x6D, 0x6D, 0x78, 0x2F, 0x31, 0x55, 0x2E, 0x3F,
-  0x50, 0x20, 0x20, 0x20, 0x20, 0x4D, 0x24, 0x52,
-  0x22, 0x22, 0x31, 0x2D, 0x66, 0x54, 0x66, 0x66,
-  0x66, 0x66, 0x54, 0x71, 0x27, 0x27, 0x27, 0x62,
-  0x30, 0x3B, 0x3B, 0x6F, 0x3B, 0x3D, 0x40, 0x21,
-  0x73, 0x71, 0x5F, 0x6E, 0x2E, 0x2E, 0x67, 0x52,
-  0x52, 0x31, 0x7D, 0x48, 0x3A, 0x3A, 0x74, 0x74,
-  0x55, 0x39, 0x20, 0x20, 0x20, 0x20, 0x38, 0x6D,
-  0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D,
-  0x38, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D,
-  0x6D, 0x29, 0x29, 0x2F, 0x55, 0x52, 0x2E, 0x24,
-  0x72, 0x68, 0x25, 0x76, 0x68, 0x3F, 0x2E, 0x39,
-  0x52, 0x74, 0x3A, 0x73, 0x66, 0x66, 0x54, 0x54,
-  0x27, 0x3B, 0x6F, 0x6F, 0x6F, 0x6F, 0x3B, 0x62,
-  0x3B, 0x62, 0x27, 0x71, 0x54, 0x40, 0x21, 0x40,
-  0x3D, 0x2E, 0x48, 0x6E, 0x55, 0x55, 0x6E, 0x55,
-  0x3A, 0x74, 0x3E, 0x55, 0x74, 0x5A, 0x22, 0x3A,
-  0x3A, 0x36, 0x2E, 0x20, 0x20, 0x20, 0x20, 0x38,
-  0x6D, 0x6D, 0x38, 0x6D, 0x38, 0x6D, 0x6D, 0x6D,
-  0x38, 0x6D, 0x38, 0x38, 0x6D, 0x38, 0x6D, 0x38,
-  0x6D, 0x32, 0x78, 0x62, 0x3E, 0x52, 0x28, 0x42,
-  0x65, 0x24, 0x5F, 0x24, 0x5F, 0x2E, 0x55, 0x22,
-  0x3A, 0x41, 0x74, 0x31, 0x54, 0x73, 0x66, 0x54,
-  0x27, 0x6F, 0x30, 0x69, 0x30, 0x6F, 0x62, 0x62,
-  0x62, 0x71, 0x3D, 0x54, 0x73, 0x5D, 0x5D, 0x66,
-  0x71, 0x2E, 0x22, 0x31, 0x55, 0x3A, 0x31, 0x5A,
-  0x3A, 0x3A, 0x74, 0x5A, 0x74, 0x3E, 0x31, 0x3A,
-  0x55, 0x22, 0x22, 0x35, 0x20, 0x20, 0x20, 0x20,
-  0x34, 0x38, 0x6D, 0x6D, 0x6D, 0x38, 0x38, 0x6D,
-  0x6D, 0x38, 0x6D, 0x6D, 0x38, 0x6D, 0x6D, 0x6D,
-  0x38, 0x79, 0x29, 0x2F, 0x42, 0x52, 0x28, 0x48,
-  0x48, 0x2E, 0x2E, 0x48, 0x3E, 0x52, 0x3A, 0x74,
-  0x7D, 0x3A, 0x3A, 0x3E, 0x40, 0x40, 0x40, 0x54,
-  0x27, 0x6F, 0x30, 0x6F, 0x62, 0x71, 0x71, 0x71,
-  0x62, 0x3D, 0x66, 0x73, 0x40, 0x5D, 0x73, 0x71,
-  0x62, 0x28, 0x55, 0x5A, 0x5A, 0x55, 0x3A, 0x41,
-  0x55, 0x3A, 0x3A, 0x31, 0x55, 0x55, 0x5A, 0x74,
-  0x3A, 0x31, 0x22, 0x48, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x6D, 0x38, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D,
-  0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x38, 0x6D, 0x6D,
-  0x6D, 0x6D, 0x29, 0x2F, 0x24, 0x28, 0x28, 0x52,
-  0x52, 0x48, 0x48, 0x28, 0x39, 0x52, 0x74, 0x48,
-  0x74, 0x55, 0x22, 0x41, 0x5A, 0x40, 0x54, 0x27,
-  0x3B, 0x6F, 0x3B, 0x71, 0x54, 0x66, 0x66, 0x3D,
-  0x62, 0x54, 0x40, 0x21, 0x7A, 0x40, 0x3D, 0x62,
-  0x62, 0x48, 0x52, 0x55, 0x6C, 0x5A, 0x31, 0x31,
-  0x5A, 0x41, 0x31, 0x3A, 0x3A, 0x7D, 0x31, 0x3A,
-  0x41, 0x41, 0x22, 0x36, 0x42, 0x20, 0x20, 0x20,
-  0x20, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x38,
-  0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x38,
-  0x6D, 0x6D, 0x29, 0x25, 0x59, 0x2E, 0x39, 0x39,
-  0x55, 0x39, 0x39, 0x39, 0x31, 0x22, 0x3A, 0x74,
-  0x5A, 0x3E, 0x6C, 0x3E, 0x31, 0x3E, 0x3A, 0x69,
-  0x49, 0x49, 0x3B, 0x71, 0x66, 0x73, 0x66, 0x54,
-  0x27, 0x66, 0x5D, 0x7A, 0x21, 0x73, 0x71, 0x62,
-  0x27, 0x75, 0x39, 0x41, 0x3A, 0x36, 0x7D, 0x74,
-  0x74, 0x41, 0x55, 0x55, 0x3A, 0x3A, 0x3A, 0x3A,
-  0x31, 0x31, 0x5A, 0x22, 0x52, 0x20, 0x20, 0x20,
-  0x26, 0x38, 0x6D, 0x38, 0x6D, 0x38, 0x6D, 0x38,
-  0x6D, 0x38, 0x38, 0x6D, 0x6D, 0x6D, 0x6D, 0x38,
-  0x38, 0x6D, 0x20, 0x60, 0x24, 0x48, 0x39, 0x3A,
-  0x55, 0x55, 0x31, 0x55, 0x41, 0x74, 0x41, 0x22,
-  0x7D, 0x3A, 0x22, 0x3E, 0x41, 0x5A, 0x3A, 0x74,
-  0x78, 0x30, 0x27, 0x54, 0x40, 0x73, 0x54, 0x3D,
-  0x71, 0x54, 0x5D, 0x7A, 0x21, 0x66, 0x62, 0x3B,
-  0x71, 0x5F, 0x52, 0x3E, 0x41, 0x5A, 0x5A, 0x22,
-  0x3E, 0x3A, 0x74, 0x3E, 0x55, 0x55, 0x3A, 0x31,
-  0x41, 0x3A, 0x48, 0x55, 0x41, 0x42, 0x6D, 0x38,
-  0x38, 0x6D, 0x6D, 0x6D, 0x38, 0x6D, 0x6D, 0x6D,
-  0x38, 0x6D, 0x6D, 0x38, 0x6D, 0x38, 0x6D, 0x6D,
-  0x6D, 0x20, 0x20, 0x25, 0x24, 0x28, 0x52, 0x3A,
-  0x5A, 0x5A, 0x5A, 0x5A, 0x74, 0x74, 0x7D, 0x74,
-  0x3A, 0x74, 0x3A, 0x41, 0x7D, 0x41, 0x3A, 0x3A,
-  0x69, 0x3D, 0x21, 0x4C, 0x4C, 0x5D, 0x66, 0x54,
-  0x66, 0x73, 0x21, 0x6A, 0x21, 0x3D, 0x3B, 0x6F,
-  0x71, 0x75, 0x48, 0x31, 0x5A, 0x3A, 0x3E, 0x48,
-  0x74, 0x7D, 0x3A, 0x7D, 0x3A, 0x3A, 0x55, 0x74,
-  0x5A, 0x3A, 0x41, 0x55, 0x22, 0x22, 0x3F, 0x6D,
-  0x6D, 0x38, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D,
-  0x6D, 0x6D, 0x6D, 0x38, 0x6D, 0x6D, 0x6D, 0x38,
-  0x20, 0x20, 0x20, 0x60, 0x42, 0x28, 0x39, 0x3A,
-  0x3A, 0x31, 0x41, 0x3A, 0x22, 0x55, 0x74, 0x55,
-  0x74, 0x74, 0x74, 0x3A, 0x3A, 0x74, 0x3A, 0x67,
-  0x54, 0x7A, 0x34, 0x77, 0x6A, 0x21, 0x66, 0x66,
-  0x7A, 0x21, 0x21, 0x4C, 0x21, 0x3D, 0x3B, 0x62,
-  0x66, 0x67, 0x28, 0x55, 0x41, 0x31, 0x55, 0x3A,
-  0x74, 0x41, 0x31, 0x3A, 0x3A, 0x41, 0x3A, 0x36,
-  0x5A, 0x5A, 0x31, 0x31, 0x39, 0x22, 0x24, 0x43,
-  0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x38, 0x6D, 0x6D,
-  0x6D, 0x38, 0x6D, 0x6D, 0x6D, 0x38, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x60, 0x24, 0x63, 0x39, 0x55,
-  0x31, 0x5A, 0x3A, 0x74, 0x3A, 0x31, 0x3A, 0x31,
-  0x5A, 0x48, 0x3A, 0x7D, 0x48, 0x41, 0x31, 0x3E,
-  0x6A, 0x64, 0x47, 0x4C, 0x5D, 0x54, 0x71, 0x71,
-  0x6A, 0x5D, 0x5D, 0x21, 0x5D, 0x3D, 0x3B, 0x62,
-  0x66, 0x42, 0x39, 0x3A, 0x41, 0x3A, 0x31, 0x3A,
-  0x7D, 0x3A, 0x74, 0x41, 0x31, 0x31, 0x3E, 0x41,
-  0x5A, 0x41, 0x3A, 0x31, 0x39, 0x52, 0x48, 0x25,
-  0x62, 0x6D, 0x38, 0x38, 0x6D, 0x38, 0x6D, 0x6D,
-  0x6D, 0x6D, 0x6D, 0x6D, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x4D, 0x43, 0x5F, 0x28, 0x52, 0x3E,
-  0x22, 0x31, 0x3A, 0x3A, 0x55, 0x3A, 0x3E, 0x31,
-  0x74, 0x67, 0x3E, 0x3A, 0x3E, 0x67, 0x54, 0x34,
-  0x2B, 0x2B, 0x34, 0x21, 0x66, 0x71, 0x62, 0x62,
-  0x3D, 0x3D, 0x54, 0x5D, 0x40, 0x27, 0x6F, 0x3B,
-  0x67, 0x48, 0x48, 0x39, 0x52, 0x7D, 0x7D, 0x22,
-  0x74, 0x3A, 0x5A, 0x5A, 0x3A, 0x55, 0x31, 0x3A,
-  0x41, 0x7D, 0x3A, 0x22, 0x55, 0x48, 0x42, 0x76,
-  0x4B, 0x20, 0x37, 0x6D, 0x6D, 0x6D, 0x38, 0x78,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x4D, 0x76, 0x42, 0x48, 0x55, 0x74,
-  0x41, 0x6C, 0x48, 0x31, 0x31, 0x3A, 0x5A, 0x74,
-  0x31, 0x6C, 0x22, 0x3E, 0x67, 0x62, 0x7A, 0x64,
-  0x7B, 0x77, 0x5D, 0x54, 0x71, 0x62, 0x62, 0x3B,
-  0x53, 0x62, 0x71, 0x73, 0x73, 0x27, 0x6F, 0x3B,
-  0x67, 0x2E, 0x5F, 0x48, 0x48, 0x52, 0x52, 0x52,
-  0x52, 0x52, 0x31, 0x41, 0x74, 0x41, 0x74, 0x31,
-  0x74, 0x3A, 0x74, 0x74, 0x48, 0x48, 0x42, 0x72,
-  0x4B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x4B, 0x68, 0x42, 0x28, 0x55, 0x74,
-  0x5A, 0x3A, 0x48, 0x55, 0x5A, 0x31, 0x55, 0x55,
-  0x39, 0x67, 0x2F, 0x49, 0x69, 0x27, 0x4C, 0x64,
-  0x34, 0x5D, 0x66, 0x71, 0x62, 0x6F, 0x6F, 0x6F,
-  0x79, 0x27, 0x66, 0x73, 0x66, 0x27, 0x6F, 0x3B,
-  0x54, 0x24, 0x5F, 0x59, 0x24, 0x24, 0x42, 0x2E,
-  0x48, 0x67, 0x28, 0x39, 0x52, 0x39, 0x31, 0x3E,
-  0x55, 0x3A, 0x3A, 0x31, 0x39, 0x48, 0x24, 0x76,
-  0x50, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x4B, 0x76, 0x24, 0x42, 0x52, 0x55,
-  0x41, 0x31, 0x31, 0x39, 0x52, 0x52, 0x48, 0x67,
-  0x72, 0x71, 0x6F, 0x69, 0x58, 0x2D, 0x4C, 0x34,
-  0x7A, 0x40, 0x66, 0x54, 0x62, 0x30, 0x6F, 0x3B,
-  0x53, 0x7A, 0x7A, 0x73, 0x3D, 0x62, 0x30, 0x6F,
-  0x3D, 0x3D, 0x3B, 0x60, 0x2F, 0x76, 0x59, 0x59,
-  0x59, 0x24, 0x24, 0x5F, 0x42, 0x2E, 0x28, 0x55,
-  0x3A, 0x39, 0x39, 0x48, 0x48, 0x65, 0x68, 0x25,
-  0x4B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x4B, 0x25, 0x72, 0x65, 0x2E, 0x28,
-  0x52, 0x28, 0x48, 0x48, 0x2E, 0x24, 0x3F, 0x4B,
-  0x71, 0x27, 0x30, 0x30, 0x27, 0x5D, 0x4C, 0x6A,
-  0x7A, 0x7A, 0x5D, 0x54, 0x3B, 0x30, 0x6F, 0x71,
-  0x27, 0x64, 0x34, 0x40, 0x3D, 0x62, 0x3B, 0x27,
-  0x3D, 0x54, 0x71, 0x3B, 0x3B, 0x62, 0x71, 0x4B,
-  0x43, 0x43, 0x76, 0x76, 0x72, 0x59, 0x24, 0x24,
-  0x42, 0x2E, 0x42, 0x24, 0x2C, 0x76, 0x60, 0x50,
-  0x4D, 0x20, 0x20, 0x20, 0x20, 0x62, 0x27, 0x3D,
-  0x3D, 0x27, 0x62, 0x62, 0x27, 0x27, 0x62, 0x30,
-  0x20, 0x20, 0x4B, 0x25, 0x76, 0x59, 0x24, 0x24,
-  0x42, 0x42, 0x42, 0x65, 0x3F, 0x60, 0x6F, 0x62,
-  0x27, 0x27, 0x62, 0x3B, 0x3D, 0x5D, 0x7A, 0x4C,
-  0x4C, 0x4C, 0x5D, 0x71, 0x30, 0x69, 0x62, 0x54,
-  0x7A, 0x2B, 0x34, 0x2D, 0x71, 0x27, 0x58, 0x62,
-  0x71, 0x3D, 0x71, 0x6F, 0x30, 0x6F, 0x27, 0x54,
-  0x3D, 0x71, 0x66, 0x4B, 0x25, 0x60, 0x76, 0x76,
-  0x72, 0x72, 0x3F, 0x76, 0x76, 0x60, 0x50, 0x4B,
-  0x20, 0x73, 0x3D, 0x62, 0x3B, 0x27, 0x71, 0x3D,
-  0x3D, 0x71, 0x27, 0x62, 0x62, 0x27, 0x62, 0x3B,
-  0x30, 0x27, 0x4D, 0x4B, 0x25, 0x76, 0x72, 0x2C,
-  0x59, 0x2C, 0x3F, 0x76, 0x25, 0x62, 0x30, 0x3B,
-  0x71, 0x3D, 0x71, 0x71, 0x66, 0x5D, 0x5D, 0x21,
-  0x21, 0x21, 0x54, 0x30, 0x78, 0x69, 0x27, 0x66,
-  0x7A, 0x4C, 0x5D, 0x3D, 0x27, 0x62, 0x62, 0x3B,
-  0x62, 0x3D, 0x27, 0x6F, 0x30, 0x3B, 0x71, 0x54,
-  0x3D, 0x3D, 0x54, 0x66, 0x66, 0x66, 0x4B, 0x25,
-  0x25, 0x25, 0x25, 0x60, 0x25, 0x50, 0x4B, 0x71,
-  0x54, 0x54, 0x71, 0x27, 0x3D, 0x54, 0x54, 0x3D,
-  0x3D, 0x71, 0x3B, 0x3B, 0x62, 0x3B, 0x62, 0x3B,
-  0x27, 0x54, 0x4C, 0x4D, 0x4B, 0x25, 0x76, 0x76,
-  0x68, 0x43, 0x25, 0x50, 0x27, 0x30, 0x30, 0x58,
-  0x27, 0x54, 0x54, 0x3D, 0x54, 0x54, 0x66, 0x54,
-  0x66, 0x71, 0x6F, 0x78, 0x53, 0x69, 0x54, 0x73,
-  0x66, 0x66, 0x54, 0x27, 0x27, 0x27, 0x62, 0x3B,
-  0x3B, 0x27, 0x27, 0x3B, 0x6F, 0x62, 0x27, 0x54,
-  0x66, 0x3D, 0x3D, 0x27, 0x27, 0x27, 0x62, 0x6F,
-  0x78, 0x53, 0x78, 0x62, 0x66, 0x73, 0x3D, 0x3D,
-  0x66, 0x2D, 0x54, 0x54, 0x73, 0x73, 0x54, 0x71,
-  0x71, 0x27, 0x3B, 0x6F, 0x3B, 0x3B, 0x62, 0x3B,
-  0x3B, 0x71, 0x73, 0x73, 0x54, 0x71, 0x62, 0x27,
-  0x27, 0x58, 0x62, 0x71, 0x71, 0x6F, 0x6F, 0x62,
-  0x27, 0x54, 0x66, 0x3D, 0x3D, 0x27, 0x27, 0x62,
-  0x62, 0x6F, 0x78, 0x53, 0x78, 0x62, 0x54, 0x66,
-  0x71, 0x3D, 0x71, 0x71, 0x62, 0x27, 0x27, 0x62,
-  0x62, 0x71, 0x3D, 0x27, 0x27, 0x62, 0x27, 0x3D,
-  0x54, 0x3D, 0x27, 0x62, 0x3B, 0x6F, 0x6F, 0x69,
-  0x78, 0x78, 0x6F, 0x54, 0x73, 0x66, 0x54, 0x54,
-  0x40, 0x5D, 0x40, 0x40, 0x40, 0x66, 0x3D, 0x71,
-  0x27, 0x27, 0x3B, 0x30, 0x6F, 0x3B, 0x3B, 0x62,
-  0x3B, 0x3B, 0x27, 0x71, 0x71, 0x27, 0x62, 0x62,
-  0x62, 0x62, 0x62, 0x71, 0x71, 0x71, 0x62, 0x62,
-  0x27, 0x71, 0x54, 0x3D, 0x27, 0x62, 0x3B, 0x6F,
-  0x6F, 0x69, 0x49, 0x49, 0x6F, 0x3D, 0x73, 0x66
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22,
+    0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+    0x26, 0x26, 0x25, 0x28, 0x23, 0x22, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x25, 0x2a, 0x2b, 0x2c, 0x2d, 0x2d,
+    0x2d, 0x2e, 0x2c, 0x2b, 0x2a, 0x25, 0x28, 0x22,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x24, 0x2a, 0x2c, 0x2f, 0x2c, 0x30, 0x30, 0x24,
+    0x25, 0x27, 0x2b, 0x2c, 0x2f, 0x31, 0x32, 0x25,
+    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
+    0x33, 0x34, 0x35, 0x21, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x21, 0x2b, 0x2f, 0x2c,
+    0x30, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
+    0x2d, 0x27, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x31,
+    0x2d, 0x32, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x37, 0x37, 0x37, 0x37, 0x38,
+    0x37, 0x37, 0x39, 0x37, 0x39, 0x38, 0x39, 0x3a,
+    0x32, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x23, 0x32, 0x27, 0x21, 0x36,
+    0x34, 0x38, 0x38, 0x39, 0x38, 0x37, 0x38, 0x39,
+    0x38, 0x37, 0x38, 0x37, 0x37, 0x37, 0x37, 0x37,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x38, 0x37, 0x37, 0x37, 0x37,
+    0x38, 0x39, 0x37, 0x37, 0x37, 0x37, 0x38, 0x3b,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x25, 0x2f, 0x3c, 0x32, 0x22,
+    0x36, 0x3d, 0x38, 0x37, 0x39, 0x37, 0x38, 0x37,
+    0x39, 0x37, 0x38, 0x37, 0x38, 0x37, 0x37, 0x37,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x3d, 0x3e, 0x3a, 0x3e, 0x3e,
+    0x3e, 0x3f, 0x3e, 0x3a, 0x3e, 0x3e, 0x40, 0x22,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x26, 0x41, 0x41, 0x35, 0x25,
+    0x36, 0x22, 0x42, 0x38, 0x38, 0x37, 0x37, 0x38,
+    0x39, 0x37, 0x37, 0x38, 0x37, 0x38, 0x38, 0x3a,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x43, 0x3e, 0x44, 0x44, 0x45,
+    0x44, 0x40, 0x3a, 0x3f, 0x3a, 0x3f, 0x3b, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x25, 0x2b, 0x30, 0x28, 0x22,
+    0x36, 0x36, 0x35, 0x38, 0x38, 0x38, 0x38, 0x38,
+    0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x37, 0x44,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x34, 0x3e, 0x3a, 0x38, 0x38,
+    0x3e, 0x3e, 0x46, 0x3e, 0x46, 0x46, 0x33, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x22, 0x22, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x47, 0x38, 0x37, 0x37, 0x37,
+    0x38, 0x37, 0x37, 0x37, 0x38, 0x38, 0x37, 0x48,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x33, 0x37, 0x44, 0x3e, 0x22,
+    0x2d, 0x2c, 0x49, 0x43, 0x4a, 0x4b, 0x22, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x49, 0x4c, 0x46, 0x44, 0x46,
+    0x4c, 0x38, 0x44, 0x38, 0x38, 0x3e, 0x37, 0x4d,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x34, 0x3e, 0x3e, 0x3a, 0x36,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x36, 0x36,
+    0x36, 0x21, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x21, 0x23, 0x22, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x28, 0x34, 0x27, 0x22, 0x20,
+    0x21, 0x20, 0x20, 0x20, 0x4e, 0x37, 0x38, 0x4f,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x34, 0x44, 0x3a, 0x3e, 0x43,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
+    0x21, 0x21, 0x24, 0x27, 0x21, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x28, 0x27, 0x22, 0x33, 0x24, 0x36,
+    0x36, 0x36, 0x36, 0x22, 0x2f, 0x2a, 0x23, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x50, 0x38, 0x3e, 0x51,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x2c, 0x3a, 0x44, 0x44, 0x52,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
+    0x30, 0x3b, 0x41, 0x24, 0x24, 0x36, 0x36, 0x36,
+    0x23, 0x2f, 0x53, 0x54, 0x55, 0x30, 0x25, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2f, 0x32, 0x23, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x51, 0x3e, 0x37, 0x42,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x34, 0x44, 0x45, 0x3e, 0x45,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x23,
+    0x56, 0x4d, 0x57, 0x3b, 0x22, 0x36, 0x36, 0x21,
+    0x49, 0x51, 0x4c, 0x45, 0x40, 0x56, 0x23, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2f, 0x33, 0x28, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x40, 0x44, 0x38, 0x51,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x2e, 0x44, 0x40, 0x44, 0x42,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x2b,
+    0x45, 0x57, 0x44, 0x39, 0x35, 0x36, 0x36, 0x26,
+    0x4c, 0x58, 0x59, 0x3d, 0x3f, 0x3e, 0x2e, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x57, 0x44, 0x3e, 0x48,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x5a, 0x44, 0x45, 0x3e, 0x44,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x34, 0x36, 0x4b,
+    0x5b, 0x25, 0x2f, 0x44, 0x3d, 0x22, 0x23, 0x32,
+    0x3a, 0x42, 0x21, 0x31, 0x43, 0x46, 0x50, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x47, 0x3e, 0x38, 0x50,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x49, 0x40, 0x40, 0x44, 0x38,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x21, 0x3b,
+    0x4b, 0x21, 0x31, 0x5c, 0x5d, 0x28, 0x30, 0x2b,
+    0x3f, 0x4b, 0x36, 0x23, 0x32, 0x42, 0x4d, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x2e, 0x5a, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x42, 0x44, 0x44, 0x52,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x2c, 0x4c, 0x40, 0x4c, 0x37,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x41, 0x23, 0x3c,
+    0x5d, 0x36, 0x28, 0x3b, 0x5e, 0x5f, 0x5f, 0x60,
+    0x54, 0x4b, 0x36, 0x36, 0x36, 0x57, 0x57, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2e, 0x5a, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x40, 0x44, 0x3a, 0x5c,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x29, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x2a, 0x44, 0x45, 0x4c, 0x3a,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x43, 0x23, 0x35,
+    0x4c, 0x25, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+    0x67, 0x68, 0x69, 0x36, 0x31, 0x39, 0x53, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x2c, 0x25, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x52, 0x45, 0x44, 0x54,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x2a, 0x40, 0x4d, 0x4c, 0x38,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x22,
+    0x57, 0x6a, 0x6b, 0x65, 0x6c, 0x6d, 0x6e, 0x6f,
+    0x70, 0x71, 0x6e, 0x66, 0x72, 0x73, 0x2a, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x33, 0x2e, 0x26, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x51, 0x3a, 0x44, 0x47,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x2c, 0x45, 0x4c, 0x4c, 0x38,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x2f, 0x23, 0x36,
+    0x74, 0x6b, 0x75, 0x6c, 0x64, 0x6e, 0x71, 0x76,
+    0x77, 0x78, 0x79, 0x71, 0x71, 0x7a, 0x74, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x33, 0x34, 0x27, 0x22,
+    0x20, 0x20, 0x20, 0x20, 0x54, 0x44, 0x44, 0x54,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x5a, 0x48, 0x48, 0x4f, 0x37,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x34, 0x26, 0x7b,
+    0x7c, 0x7d, 0x7e, 0x6c, 0x6d, 0x7f, 0x71, 0x80,
+    0x78, 0x79, 0x79, 0x79, 0x7a, 0x67, 0x66, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x25, 0x41, 0x2a, 0x23,
+    0x20, 0x20, 0x20, 0x20, 0x81, 0x44, 0x40, 0x5b,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x2c, 0x44, 0x45, 0x4f, 0x38,
+    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x33, 0x82,
+    0x6b, 0x83, 0x84, 0x64, 0x6e, 0x71, 0x76, 0x85,
+    0x79, 0x79, 0x71, 0x86, 0x87, 0x83, 0x88, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x21, 0x43, 0x2b, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x52, 0x44, 0x44, 0x50,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x5a, 0x40, 0x4d, 0x4f, 0x38,
+    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x32, 0x24,
+    0x89, 0x8a, 0x6c, 0x8b, 0x7f, 0x71, 0x79, 0x79,
+    0x71, 0x8c, 0x8d, 0x8e, 0x83, 0x8e, 0x8f, 0x36,
+    0x21, 0x2b, 0x23, 0x36, 0x36, 0x5a, 0x2e, 0x26,
+    0x22, 0x20, 0x20, 0x20, 0x42, 0x40, 0x38, 0x50,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x2c, 0x4c, 0x4f, 0x4f, 0x38,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x2d, 0x33, 0x21,
+    0x90, 0x91, 0x92, 0x7a, 0x6f, 0x6e, 0x67, 0x92,
+    0x93, 0x6b, 0x8e, 0x94, 0x95, 0x96, 0x49, 0x36,
+    0x36, 0x2d, 0x3b, 0x35, 0x36, 0x24, 0x43, 0x32,
+    0x28, 0x21, 0x20, 0x20, 0x57, 0x40, 0x44, 0x54,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x34, 0x4d, 0x42, 0x51, 0x38,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x33, 0x21,
+    0x5d, 0x97, 0x98, 0x93, 0x86, 0x66, 0x99, 0x87,
+    0x7d, 0x7d, 0x99, 0x6a, 0x57, 0x4d, 0x59, 0x23,
+    0x36, 0x24, 0x3b, 0x3b, 0x24, 0x36, 0x2e, 0x31,
+    0x26, 0x22, 0x20, 0x20, 0x52, 0x44, 0x44, 0x9a,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x5a, 0x57, 0x57, 0x57, 0x37,
+    0x20, 0x20, 0x21, 0x28, 0x33, 0x3c, 0x25, 0x22,
+    0x53, 0x42, 0x97, 0x98, 0x99, 0x87, 0x99, 0x6b,
+    0x7c, 0x9b, 0x9c, 0x51, 0x4f, 0x3f, 0x40, 0x2c,
+    0x36, 0x36, 0x33, 0x5a, 0x21, 0x36, 0x22, 0x43,
+    0x33, 0x28, 0x21, 0x20, 0x42, 0x44, 0x37, 0x4f,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x2a, 0x51, 0x42, 0x51, 0x37,
+    0x20, 0x20, 0x22, 0x27, 0x2e, 0x2e, 0x36, 0x21,
+    0x4e, 0x4d, 0x42, 0x9d, 0x9e, 0x98, 0x98, 0x9f,
+    0x97, 0x51, 0x42, 0x4c, 0x39, 0x58, 0x58, 0x47,
+    0x21, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x5a,
+    0x2e, 0x27, 0x23, 0x20, 0x59, 0x48, 0x38, 0x50,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x2a, 0x42, 0x51, 0x42, 0x3e,
+    0x20, 0x22, 0x24, 0x2b, 0x41, 0x28, 0x36, 0x32,
+    0x3e, 0x3f, 0x42, 0x42, 0x42, 0x51, 0x51, 0x42,
+    0x42, 0x57, 0x40, 0x38, 0x58, 0x58, 0x58, 0x58,
+    0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x23,
+    0x2f, 0x2b, 0x24, 0x21, 0x57, 0x4f, 0x3e, 0x53,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x33, 0x47, 0x51, 0x52, 0x38,
+    0x21, 0x28, 0x32, 0x43, 0x32, 0x28, 0x21, 0x47,
+    0x58, 0x39, 0x48, 0x42, 0x42, 0x42, 0x42, 0x42,
+    0x48, 0x3a, 0x37, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x4f, 0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x2a, 0x2f, 0x2a, 0x28, 0x42, 0x4f, 0x44, 0x52,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x5a, 0x57, 0x47, 0x51, 0x37,
+    0x23, 0x30, 0x2e, 0x2c, 0x36, 0x21, 0x43, 0x37,
+    0x58, 0x58, 0x46, 0x4d, 0x42, 0x42, 0x57, 0x3f,
+    0x39, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2d, 0x31, 0x27, 0x4f, 0x47, 0x38, 0x50,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x25, 0x57, 0x47, 0x52, 0x38,
+    0x27, 0x2c, 0x2d, 0x21, 0x36, 0x28, 0x45, 0x58,
+    0x58, 0x58, 0x58, 0x39, 0x44, 0x3a, 0x39, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x52, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x28, 0x43, 0x5a, 0x45, 0x4d, 0x37, 0x9a,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x2a, 0x47, 0x52, 0x59, 0x37,
+    0x35, 0x43, 0x28, 0x36, 0x36, 0x4a, 0x58, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x37, 0x58, 0x58, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x3a, 0x28, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x28, 0x41, 0x48, 0x4d, 0x38, 0x54,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x2a, 0x81, 0x5b, 0x51, 0x38,
+    0x43, 0x25, 0x36, 0x36, 0x23, 0x57, 0x37, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x37, 0x38, 0x2b, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x30, 0x51, 0x40, 0x3a, 0x56,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x33, 0x51, 0x47, 0x81, 0x3e,
+    0x27, 0x36, 0x36, 0x36, 0x2a, 0x57, 0x39, 0x58,
+    0x58, 0x58, 0x58, 0x37, 0x38, 0x38, 0x37, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x37, 0x39, 0x46,
+    0x44, 0x3a, 0x3c, 0x21, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x48, 0x59, 0x37, 0x5d,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x27, 0x52, 0x4e, 0x5b, 0x44,
+    0x36, 0x36, 0x36, 0x21, 0x31, 0x5b, 0x48, 0x3e,
+    0x39, 0x37, 0x37, 0x46, 0x44, 0x3a, 0x46, 0x37,
+    0x37, 0x37, 0x39, 0x3a, 0x40, 0x48, 0x4f, 0x4f,
+    0x4d, 0x4f, 0x47, 0x28, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x4f, 0x81, 0x40, 0x5d,
+    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x33, 0x52, 0x50, 0x56, 0x38,
+    0x36, 0x36, 0x36, 0x22, 0x41, 0x47, 0x45, 0x38,
+    0x37, 0x58, 0x58, 0x37, 0x3e, 0x58, 0x58, 0x58,
+    0x58, 0x58, 0x58, 0x39, 0x46, 0x44, 0x4c, 0x4f,
+    0x57, 0x57, 0x4c, 0x50, 0x21, 0x23, 0x33, 0x23,
+    0x36, 0x36, 0x36, 0x36, 0x4d, 0x51, 0x39, 0x3b,
+    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x33, 0x57, 0x55, 0x55, 0x37,
+    0x37, 0x37, 0x38, 0x38, 0x38, 0x37, 0x37, 0x37,
+    0x37, 0x37, 0x38, 0x37, 0x37, 0x37, 0x38, 0x37,
+    0x37, 0x37, 0x37, 0x39, 0x3e, 0x37, 0x38, 0x38,
+    0x38, 0x37, 0x38, 0x38, 0x38, 0x37, 0x38, 0x38,
+    0x37, 0x38, 0x38, 0x37, 0x47, 0x42, 0x48, 0x9a,
+    0x25, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x33, 0x5b, 0x81, 0x5d, 0x37,
+    0x38, 0x37, 0x37, 0x38, 0x37, 0x38, 0x38, 0x37,
+    0x38, 0x37, 0x37, 0x37, 0x37, 0x37, 0x38, 0x37,
+    0x38, 0x37, 0x38, 0x37, 0x37, 0x38, 0x37, 0x37,
+    0x38, 0x37, 0x37, 0x37, 0x38, 0x38, 0x37, 0x3e,
+    0x37, 0x38, 0x38, 0x37, 0x57, 0x57, 0x48, 0x5d,
+    0x2a, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x33, 0x52, 0x59, 0x50, 0x5b,
+    0x54, 0x5b, 0x5b, 0x54, 0x81, 0x5b, 0x55, 0x55,
+    0x52, 0x54, 0x81, 0x81, 0x81, 0x50, 0x52, 0x54,
+    0x5b, 0x59, 0x52, 0x52, 0x5b, 0x52, 0x5b, 0x81,
+    0x5b, 0x47, 0x51, 0x52, 0x57, 0x57, 0x57, 0x57,
+    0x51, 0x57, 0x52, 0x57, 0x48, 0x57, 0x4c, 0x3b,
+    0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x21, 0x33, 0x54, 0x54, 0x5b, 0x50,
+    0x54, 0x50, 0x54, 0x81, 0x50, 0x59, 0x54, 0x50,
+    0x5b, 0x81, 0x81, 0x59, 0x81, 0x59, 0x59, 0x59,
+    0x59, 0x47, 0x81, 0x51, 0x47, 0x51, 0x59, 0x81,
+    0x81, 0x51, 0x47, 0x50, 0x59, 0x59, 0x59, 0x47,
+    0x47, 0x47, 0x52, 0x57, 0x52, 0x47, 0x59, 0x26,
+    0x2d, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x22, 0x27, 0x55, 0x50, 0x55, 0x50,
+    0x55, 0x81, 0x54, 0x52, 0x52, 0x81, 0x5b, 0x50,
+    0x5b, 0x52, 0x52, 0x51, 0x57, 0x52, 0x52, 0x52,
+    0x54, 0x51, 0x81, 0x52, 0x59, 0x52, 0x5b, 0x5b,
+    0x59, 0x5b, 0x51, 0x52, 0x52, 0x4f, 0x5b, 0x51,
+    0x52, 0x47, 0x59, 0x42, 0x47, 0x81, 0x5c, 0x21,
+    0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x33, 0x81, 0x54, 0x5c, 0x54,
+    0x50, 0x5b, 0x50, 0x50, 0x81, 0x5b, 0x5c, 0x5b,
+    0x50, 0x59, 0x81, 0x81, 0x81, 0x81, 0x47, 0x50,
+    0x50, 0x59, 0x5b, 0x50, 0x52, 0x81, 0x50, 0x59,
+    0x5b, 0x81, 0x59, 0x81, 0x59, 0x47, 0x59, 0x47,
+    0x59, 0x52, 0x51, 0x48, 0x51, 0x52, 0x5d, 0x36,
+    0x2e, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x22, 0x25, 0x2a, 0x50, 0x4e, 0x5c, 0x54,
+    0x5c, 0x5b, 0x5b, 0x5b, 0x59, 0x5b, 0x50, 0x54,
+    0x5b, 0x54, 0x5b, 0x5b, 0x54, 0x54, 0x5b, 0x5b,
+    0x5b, 0x81, 0x55, 0x81, 0x55, 0x54, 0x5b, 0x5c,
+    0x5b, 0x4e, 0x51, 0x5b, 0x5b, 0x57, 0x51, 0x4f,
+    0x4d, 0x47, 0x4f, 0x4c, 0x51, 0x52, 0x4b, 0x36,
+    0x2a, 0x2e, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x2a, 0x2a, 0x50, 0x9a, 0x54, 0x5c,
+    0x55, 0x50, 0x81, 0x59, 0x54, 0x50, 0x54, 0x50,
+    0x50, 0x50, 0x81, 0x81, 0x50, 0x50, 0x50, 0x81,
+    0x81, 0x5b, 0x47, 0x51, 0x81, 0x59, 0x81, 0x55,
+    0x59, 0x59, 0x81, 0x42, 0x27, 0x36, 0x28, 0x36,
+    0x27, 0x36, 0x28, 0x2d, 0x47, 0x52, 0x2d, 0x36,
+    0x22, 0x2f, 0x30, 0x22, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x22, 0x25, 0x2c, 0x26, 0x53, 0x4e, 0x55, 0x5c,
+    0x55, 0x55, 0x55, 0x81, 0x54, 0x50, 0x54, 0x55,
+    0x5b, 0x55, 0x52, 0x54, 0x54, 0x5b, 0x54, 0x55,
+    0x36, 0x36, 0x27, 0x2a, 0x2a, 0x27, 0xa0, 0x27,
+    0x2a, 0x2a, 0x2c, 0x27, 0x5d, 0x22, 0x22, 0x28,
+    0x28, 0x22, 0x25, 0x59, 0x51, 0x53, 0x27, 0x36,
+    0x21, 0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x28, 0x32, 0x2f, 0x21, 0x4a, 0x54, 0x5c, 0x4e,
+    0x5c, 0x81, 0x5c, 0x54, 0x5c, 0x54, 0x5c, 0x50,
+    0x81, 0x50, 0x50, 0x81, 0x81, 0x5c, 0x50, 0x81,
+    0x5d, 0x28, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xa0, 0x25,
+    0x28, 0x21, 0x28, 0x81, 0x59, 0x4a, 0x28, 0x36,
+    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x25, 0x2c, 0x5a, 0x36, 0x32, 0x9a, 0x81, 0x4e,
+    0x55, 0x5b, 0x50, 0x54, 0x5c, 0x54, 0x55, 0x55,
+    0x54, 0x4e, 0x54, 0x55, 0x5b, 0x4e, 0x55, 0x5b,
+    0x3b, 0x4e, 0x4a, 0x3b, 0x4a, 0x4e, 0x3b, 0x5d,
+    0x56, 0x3b, 0x56, 0x5c, 0x50, 0x3a, 0x3e, 0x40,
+    0x4f, 0x57, 0x81, 0x4e, 0x4e, 0x27, 0x36, 0x36,
+    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x30, 0x2d, 0x21, 0x36, 0x23, 0x3d, 0x53, 0x43,
+    0x4a, 0x5d, 0x55, 0x5c, 0x4e, 0x5c, 0x50, 0x5c,
+    0x81, 0x50, 0x50, 0x81, 0x50, 0x50, 0x50, 0x50,
+    0x4e, 0x5b, 0x54, 0x5b, 0x51, 0x59, 0x5b, 0x5b,
+    0x54, 0x5b, 0x5b, 0x52, 0x51, 0x42, 0x5b, 0x5c,
+    0x5c, 0x53, 0x5b, 0x3b, 0x28, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x5a, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0x2e, 0x36, 0x36, 0x23, 0x41, 0x56, 0x2e,
+    0x33, 0x50, 0x55, 0x81, 0x54, 0x5b, 0x54, 0x52,
+    0x5b, 0x55, 0x54, 0x55, 0x55, 0x55, 0x5b, 0x9a,
+    0x5c, 0x81, 0x81, 0x81, 0x52, 0x59, 0x50, 0x59,
+    0x59, 0x59, 0x59, 0x50, 0x81, 0x81, 0x5b, 0x5b,
+    0x5b, 0x54, 0x34, 0x22, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x5a, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x2b, 0x5a, 0x36, 0x36, 0x36, 0x27, 0x3d, 0x28,
+    0xa0, 0x5d, 0x5c, 0x55, 0x50, 0x50, 0x5c, 0x81,
+    0x81, 0x50, 0x50, 0x47, 0x50, 0x5c, 0x5c, 0x52,
+    0x54, 0x5b, 0x5b, 0x5b, 0x59, 0x52, 0x5b, 0x52,
+    0x5b, 0x52, 0x52, 0x54, 0x59, 0x5b, 0x81, 0x81,
+    0x9a, 0x33, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x35, 0x5a, 0x36, 0x36, 0x36, 0x36, 0x30, 0x4e,
+    0x52, 0x54, 0x56, 0x55, 0x55, 0x55, 0x55, 0x5b,
+    0x55, 0x55, 0x54, 0x5b, 0x54, 0x55, 0x50, 0x59,
+    0x5c, 0x81, 0x59, 0x52, 0x59, 0x59, 0x81, 0x59,
+    0x81, 0x81, 0x81, 0x81, 0x5b, 0x5b, 0x81, 0x53,
+    0x2a, 0x27, 0xa1, 0x24, 0x25, 0x28, 0x21, 0x36,
+    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x25,
+    0x5a, 0x4b, 0xa2, 0x8d, 0x8a, 0x5f, 0x21, 0x2d,
+    0x55, 0x5c, 0x9a, 0x5c, 0x5c, 0x5c, 0x50, 0x9a,
+    0x5c, 0x9a, 0x50, 0x5c, 0x5c, 0x5c, 0x54, 0x5b,
+    0x55, 0x5b, 0x54, 0x81, 0x5b, 0x5b, 0x5b, 0x54,
+    0x54, 0x5b, 0x5b, 0x5b, 0x5b, 0x54, 0x54, 0x30,
+    0x23, 0x36, 0x36, 0x36, 0x21, 0x28, 0x2c, 0x30,
+    0x21, 0x41, 0x33, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x28, 0x30,
+    0x2d, 0xa3, 0x83, 0xa4, 0xa5, 0xa5, 0x88, 0x22,
+    0x3b, 0x47, 0x53, 0x55, 0x55, 0x53, 0x54, 0x5b,
+    0x52, 0x53, 0x54, 0x54, 0x54, 0x50, 0x5c, 0x59,
+    0x56, 0x59, 0x5b, 0x50, 0x50, 0x59, 0x9a, 0x59,
+    0x5c, 0x81, 0x50, 0x59, 0x9a, 0x52, 0x68, 0x69,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x30, 0x32,
+    0x25, 0x4b, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x24, 0x26, 0x30, 0x33, 0x31,
+    0x4b, 0x9b, 0x63, 0xa4, 0xa5, 0xa5, 0xa5, 0x62,
+    0x21, 0x2e, 0x44, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x58, 0x3a, 0x37, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x58, 0x58, 0xa6, 0xa7, 0x71, 0x6e, 0xa8,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x26, 0x25,
+    0x8c, 0xa9, 0x2c, 0x25, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x28, 0x30, 0x35, 0x2d, 0x2f, 0x3c, 0x3d,
+    0x68, 0x8e, 0xaa, 0xab, 0xa5, 0xa5, 0xa5, 0x8b,
+    0x8f, 0x36, 0x32, 0x4d, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x58, 0x3e, 0x38, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x58, 0x58, 0xac, 0xa4, 0xa7, 0xad, 0xa0,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x5f,
+    0x7f, 0x6e, 0x34, 0x27, 0x22, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x23, 0x30, 0x31, 0xae, 0x9b, 0x87, 0x99, 0x99,
+    0x94, 0x63, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+    0x65, 0xaf, 0x36, 0x24, 0x50, 0x37, 0x58, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x37, 0x38, 0xac, 0x6c, 0x64, 0x94, 0xaf,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x7b, 0x65,
+    0x8b, 0x64, 0xb0, 0x2a, 0x23, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x24, 0x2b, 0xae, 0x94, 0x63, 0x7e, 0x63, 0x63,
+    0x84, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+    0xa7, 0x66, 0x22, 0x36, 0x21, 0x3b, 0x38, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x3a, 0x4d, 0xb1, 0x84, 0x84, 0x8e, 0x89,
+    0xa1, 0x36, 0x36, 0x36, 0x21, 0xb2, 0x87, 0x84,
+    0x6c, 0x6c, 0xb3, 0x35, 0x24, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x31, 0xb4, 0x63, 0x6c, 0xa4, 0xa4, 0xab,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+    0xa5, 0x6e, 0xb5, 0x36, 0x36, 0x36, 0x2c, 0x3f,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x48, 0x4d, 0xb6, 0x7e, 0x7e, 0x83, 0x6b,
+    0xb7, 0xb8, 0x8f, 0xb8, 0xb9, 0x99, 0x63, 0x6c,
+    0xa4, 0xa4, 0xba, 0x2d, 0x27, 0x23, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x26, 0x2d, 0x9b, 0x63, 0x6c, 0xa5, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+    0xa5, 0xa7, 0x8c, 0xa0, 0x36, 0x36, 0x36, 0x30,
+    0x45, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x37, 0x48, 0x4d, 0xbb, 0x63, 0x84, 0xbc, 0x8e,
+    0x87, 0x99, 0x6b, 0x99, 0x8e, 0x63, 0xa4, 0xa5,
+    0xa5, 0xab, 0x65, 0xb3, 0x5a, 0x26, 0x23, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2d, 0xbd, 0xbc, 0x6c, 0xa5, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa7, 0x91, 0x36, 0x36, 0x36, 0x36,
+    0x2d, 0x37, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x37, 0x40, 0x4d, 0xbe, 0x75, 0x84, 0xaa, 0xbc,
+    0x83, 0x94, 0x94, 0x83, 0x63, 0x6c, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa4, 0xbf, 0x3c, 0x35, 0x26, 0x23,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2e, 0xbd, 0x83, 0x84, 0xa5, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa7, 0x7a, 0x7b, 0x36, 0x36, 0x36,
+    0x24, 0x46, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x44, 0x51, 0xb4, 0x83, 0x84, 0x6c, 0x84,
+    0x7e, 0x63, 0x63, 0x7e, 0x84, 0xa4, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xab, 0x6c, 0xbf, 0x4b, 0x2c, 0x27,
+    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x25, 0x31, 0xc0, 0x94, 0x84, 0xa5, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa7, 0x92, 0xa1, 0x36, 0x36,
+    0x32, 0x39, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x3f, 0x2f, 0x98, 0x83, 0x84, 0xa4, 0xab,
+    0xa4, 0x6c, 0x6c, 0xa4, 0xa4, 0xab, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0x65, 0xc1, 0x2c,
+    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x25, 0x31, 0xc0, 0x8e, 0x84, 0xa5, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0x6e, 0x5f, 0x27, 0x4b,
+    0x3f, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x38, 0x34, 0xa1, 0xb7, 0x83, 0x84, 0xa4, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0xc0,
+    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2d, 0xc0, 0x8e, 0x84, 0xab, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa7, 0x67, 0x9c, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x45,
+    0x35, 0x36, 0xa0, 0xb9, 0x83, 0x84, 0xab, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xab, 0xa4, 0xbe,
+    0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+    0x30, 0x2f, 0xb4, 0x94, 0x84, 0xab, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0x6e, 0x92, 0x40,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x58, 0x37, 0x5b, 0x25,
+    0x36, 0x36, 0x69, 0xb7, 0x75, 0x6c, 0xab, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xab, 0x84, 0xbc, 0xc1,
+    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0xc2, 0x6b, 0xbc, 0xa4, 0xa5, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0x7a, 0x8a, 0xc3,
+    0x44, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+    0x58, 0x58, 0x58, 0x58, 0x4d, 0x2c, 0x36, 0x36,
+    0x36, 0x36, 0xc4, 0x98, 0x75, 0x6c, 0xab, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa4, 0xaa, 0x94, 0xae, 0x2c,
+    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x35, 0x9e, 0x7d, 0xaa, 0xa4, 0xab, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xab, 0x84, 0x8a, 0xb7,
+    0x7b, 0x53, 0x45, 0x37, 0x58, 0x58, 0x58, 0x37,
+    0x38, 0x4c, 0x4e, 0x2c, 0x21, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x7b, 0xb7, 0x83, 0x84, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+    0xa5, 0x6c, 0x7e, 0x83, 0x9b, 0xb3, 0x31, 0x30,
+    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x5a, 0x9f, 0x7d, 0xbc, 0x84, 0x6c, 0xa4, 0xa4,
+    0xab, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0x84, 0x83, 0xc5,
+    0xc6, 0x36, 0x21, 0x26, 0x2b, 0x5a, 0x33, 0x30,
+    0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xc6, 0xb9, 0x94, 0x84, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0x6c, 0x6c,
+    0x7e, 0x8e, 0xbd, 0xb3, 0x34, 0x2b, 0x27, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0xc7, 0x6b, 0x87, 0x83, 0x75, 0xbc, 0x63,
+    0x7e, 0x84, 0x6c, 0x6c, 0xa4, 0xab, 0xa5, 0xa5,
+    0xa5, 0xa5, 0xa5, 0xa5, 0xab, 0x7e, 0x8e, 0xb7,
+    0x82, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xc8, 0xb9, 0x7d, 0x7e, 0xa4, 0xa5,
+    0xa5, 0xa5, 0xab, 0xa4, 0x6c, 0x7e, 0xbc, 0x94,
+    0xb4, 0xb3, 0x2f, 0x35, 0x30, 0x24, 0x22, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+    0x27, 0x31, 0xc9, 0xc7, 0xb9, 0x7c, 0x6b, 0x99,
+    0x87, 0x7d, 0x94, 0x75, 0xbc, 0x7e, 0x6c, 0xa4,
+    0xab, 0xab, 0xab, 0xab, 0x6c, 0x83, 0x8d, 0xca,
+    0x82, 0xa1, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xc6, 0xca, 0x6b, 0x75, 0x84, 0x6c,
+    0xab, 0xa4, 0x6c, 0x84, 0xbc, 0x7d, 0x6b, 0x9e,
+    0x41, 0x5a, 0x2a, 0x24, 0x23, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x28, 0x27, 0x35, 0x2d, 0x49, 0xb3, 0xc3, 0x98,
+    0xb7, 0xb9, 0xc5, 0x7c, 0x8d, 0x99, 0x8e, 0x75,
+    0x63, 0x84, 0x84, 0xaa, 0x75, 0x99, 0xb7, 0xcb,
+    0xc8, 0x22, 0x36, 0x36, 0x28, 0x30, 0x30, 0x30,
+    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x25, 0x36,
+    0x36, 0x21, 0xb2, 0x89, 0xc5, 0x87, 0x75, 0x7e,
+    0xaa, 0x7e, 0x75, 0x8e, 0x6b, 0xb7, 0xb3, 0x34,
+    0x33, 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x24, 0x27, 0x2a, 0x35, 0x2e, 0x2f,
+    0x49, 0xcc, 0xcd, 0x74, 0x89, 0xca, 0xb7, 0x7c,
+    0x8d, 0x99, 0x7d, 0x87, 0x7c, 0x98, 0xcb, 0x82,
+    0xc4, 0x2b, 0x4a, 0x49, 0x2f, 0x34, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x2f, 0x41,
+    0x4b, 0x3c, 0xce, 0xcf, 0x98, 0x7c, 0x6b, 0x87,
+    0x7d, 0x87, 0x6b, 0xc5, 0x91, 0xc2, 0x31, 0x2a,
+    0x24, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x21, 0x22, 0x23, 0x24, 0x26, 0x30,
+    0x33, 0x5a, 0x2e, 0x43, 0x49, 0xb0, 0x74, 0xcf,
+    0x89, 0xca, 0xca, 0xca, 0xd0, 0xcf, 0xb5, 0xd1,
+    0x49, 0x34, 0x35, 0x32, 0x30, 0x27, 0x27, 0x27,
+    0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x2a,
+    0x2b, 0x34, 0xd2, 0xc8, 0xd3, 0x98, 0xb9, 0xc5,
+    0xc5, 0xb9, 0xca, 0x74, 0x49, 0x5a, 0x27, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22,
+    0x28, 0x24, 0x26, 0x2a, 0x33, 0x2c, 0x2f, 0x49,
+    0xd4, 0xb5, 0x82, 0x82, 0x82, 0xc8, 0xd5, 0x43,
+    0x5a, 0x30, 0x24, 0x23, 0x22, 0x22, 0x22, 0x22,
+    0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23,
+    0x24, 0x2a, 0x31, 0xd6, 0xc6, 0x82, 0xcf, 0x89,
+    0xd3, 0xb8, 0xd7, 0x2f, 0x35, 0x26, 0x23, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x22, 0x23, 0x28, 0x25, 0x30, 0x2b,
+    0x31, 0x2f, 0xd2, 0xd6, 0xd6, 0x2f, 0x2e, 0x33,
+    0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x28, 0x27, 0x35, 0x34, 0xd6, 0xd6, 0xd6,
+    0xd8, 0xd2, 0x2e, 0x33, 0x25, 0x23, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x23, 0x28,
+    0x26, 0x30, 0x32, 0x2b, 0x33, 0x2a, 0x26, 0x28,
+    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x25, 0x30, 0x33, 0x35, 0x35,
+    0x2b, 0x2a, 0x26, 0x28, 0x22, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x21, 0x22, 0x23, 0x28, 0x28, 0x23, 0x22, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x23, 0x28, 0x24, 0x24,
+    0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 };
 
-#endif
-
-#else
+#endif /* !INCLUDE_LINUX_LOGO_DATA */
 
-#define LINUX_LOGO_COLORS 214
+#endif /* CONFIG_MAC */
 
-#endif
-
-#ifdef INCLUDE_LINUX_LOGO_DATA
-
-#define INCLUDE_LINUX_LOGOBW
-#define INCLUDE_LINUX_LOGO16
 #include <linux/linux_logo.h>
 
-#else
-
-/* prototypes only */
-extern unsigned char linux_logo_red[];
-extern unsigned char linux_logo_green[];
-extern unsigned char linux_logo_blue[];
-extern unsigned char linux_logo[];
-extern unsigned char linux_logo_bw[];
-extern unsigned char linux_logo16_red[];
-extern unsigned char linux_logo16_green[];
-extern unsigned char linux_logo16_blue[];
-extern unsigned char linux_logo16[];
-
-#endif
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/mac_psc.h linux/include/asm-m68k/mac_psc.h
--- v2.4.5/linux/include/asm-m68k/mac_psc.h	Sat Sep  4 13:06:41 1999
+++ linux/include/asm-m68k/mac_psc.h	Mon Jun 11 19:15:27 2001
@@ -51,6 +51,8 @@
  * One-shot DMA control registers
  */
 
+#define PSC_MYSTERY	0x804
+
 #define PSC_CTL_BASE	0xC00
 
 #define PSC_SCSI_CTL	0xC00
@@ -70,6 +72,9 @@
 #define PSC_ADDR_BASE	0x1000
 #define PSC_LEN_BASE	0x1004
 #define PSC_CMD_BASE	0x1008
+
+#define PSC_SET0	0x00
+#define PSC_SET1	0x10
 
 #define PSC_SCSI_ADDR	0x1000 	/* confirmed */
 #define PSC_SCSI_LEN	0x1004 	/* confirmed */
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/mc146818rtc.h linux/include/asm-m68k/mc146818rtc.h
--- v2.4.5/linux/include/asm-m68k/mc146818rtc.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-m68k/mc146818rtc.h	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,48 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef _ASM_MC146818RTC_H
+#define _ASM_MC146818RTC_H
+
+#include <linux/config.h>
+
+#ifdef CONFIG_ATARI
+/* RTC in Atari machines */
+
+#include <asm/atarihw.h>
+#include <asm/atariints.h>
+#include <asm/io.h>
+#define RTC_HAS_IRQ	(ATARIHW_PRESENT(TT_MFP))
+#define RTC_IRQ 	IRQ_TT_MFP_RTC
+#define RTC_IRQ_FLAGS	IRQ_TYPE_FAST
+#define RTC_PORT(x)	(TT_RTC_BAS + 2*(x))
+#define RTC_ALWAYS_BCD	0	/* TOS uses binary mode, Linux should be able
+				 * to deal with both modes */
+
+#define RTC_CHECK_DRIVER_INIT() (MACH_IS_ATARI && ATARIHW_PRESENT(TT_CLK))
+#define RTC_MACH_INIT()							\
+    do {								\
+	epoch = atari_rtc_year_offset + 1900;				\
+	if (RTC_HAS_IRQ)						\
+	    /* select RTC int on H->L edge */				\
+	    tt_mfp.active_edge &= ~0x40;				\
+    } while(0)
+#define RTC_MACH_EXIT()
+
+/* On Atari, the year was stored with base 1970 in old TOS versions (before
+ * 3.06). Later, Atari recognized that this broke leap year recognition, and
+ * changed the base to 1968. Medusa and Hades always use the new version. */
+#define RTC_CENTURY_SWITCH	-1	/* no century switch */
+#define RTC_MINYEAR		epoch
+
+#define CMOS_READ(addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+inb_p(RTC_PORT(1)); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+outb_p((val),RTC_PORT(1)); \
+})
+#endif /* CONFIG_ATARI */
+
+#endif /* _ASM_MC146818RTC_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/motorola_pgalloc.h linux/include/asm-m68k/motorola_pgalloc.h
--- v2.4.5/linux/include/asm-m68k/motorola_pgalloc.h	Mon Apr 23 15:28:07 2001
+++ linux/include/asm-m68k/motorola_pgalloc.h	Mon Jun 11 19:15:27 2001
@@ -21,6 +21,22 @@
 extern pmd_t *get_pointer_table(void);
 extern int free_pointer_table(pmd_t *);
 
+
+extern inline void flush_tlb_kernel_page(unsigned long addr)
+{
+	if (CPU_IS_040_OR_060) {
+		mm_segment_t old_fs = get_fs();
+		set_fs(KERNEL_DS);
+		__asm__ __volatile__(".chip 68040\n\t"
+				     "pflush (%0)\n\t"
+				     ".chip 68k"
+				     : : "a" (addr));
+		set_fs(old_fs);
+	} else
+		__asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr));
+}
+
+
 extern inline pte_t *get_pte_fast(void)
 {
 	unsigned long *ret;
@@ -33,6 +49,29 @@
 	}
 	return (pte_t *)ret;
 }
+#define pte_alloc_one_fast(mm,addr)  get_pte_fast()
+
+static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
+{
+ 	pte_t *pte;
+
+	pte = (pte_t *) __get_free_page(GFP_KERNEL);
+	if (pte) {
+	         clear_page(pte);
+		 __flush_page_to_ram((unsigned long)pte);
+		 flush_tlb_kernel_page((unsigned long)pte);
+		 nocache_page((unsigned long)pte);
+		}
+
+	return pte;
+}
+
+
+extern __inline__ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
+{
+        return get_pointer_table();
+}
+
 
 extern inline void free_pte_fast(pte_t *pte)
 {
@@ -59,6 +98,7 @@
 	}
 	return (pmd_t *)ret;
 }
+#define pmd_alloc_one_fast(mm,addr) get_pmd_fast()
 
 extern inline void free_pmd_fast(pmd_t *pmd)
 {
@@ -94,46 +134,11 @@
 	free_pte_fast(pte);
 }
 
-extern inline pte_t *pte_alloc(pmd_t *pmd, unsigned long address)
-{
-	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
-	if (pmd_none(*pmd)) {
-		pte_t *page = get_pte_fast();
-
-		if (!page)
-			return get_pte_slow(pmd, address);
-		pmd_set(pmd,page);
-		return page + address;
-	}
-	if (pmd_bad(*pmd)) {
-		__bad_pte(pmd);
-		return NULL;
-	}
-	return (pte_t *)__pmd_page(*pmd) + address;
-}
-
 extern inline void pmd_free(pmd_t *pmd)
 {
 	free_pmd_fast(pmd);
 }
 
-extern inline pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address)
-{
-	address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
-	if (pgd_none(*pgd)) {
-		pmd_t *page = get_pmd_fast();
-
-		if (!page)
-			return get_pmd_slow(pgd, address);
-		pgd_set(pgd, page);
-		return page + address;
-	}
-	if (pgd_bad(*pgd)) {
-		__bad_pmd(pgd);
-		return NULL;
-	}
-	return (pmd_t *)__pgd_page(*pgd) + address;
-}
 
 extern inline void pte_free_kernel(pte_t *pte)
 {
@@ -142,7 +147,7 @@
 
 extern inline pte_t *pte_alloc_kernel(pmd_t *pmd, unsigned long address)
 {
-	return pte_alloc(pmd, address);
+	return pte_alloc(&init_mm,pmd, address);
 }
 
 extern inline void pmd_free_kernel(pmd_t *pmd)
@@ -152,7 +157,7 @@
 
 extern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address)
 {
-	return pmd_alloc(pgd, address);
+	return pmd_alloc(&init_mm,pgd, address);
 }
 
 extern inline void pgd_free(pgd_t *pgd)
@@ -168,6 +173,11 @@
 	return pgd;
 }
 
+
+#define pmd_populate(MM, PMD, PTE)	pmd_set(PMD, PTE)
+#define pgd_populate(MM, PGD, PMD)	pgd_set(PGD, PMD)
+
+
 extern int do_check_pgt_cache(int, int);
 
 extern inline void set_pgdir(unsigned long address, pgd_t entry)
@@ -238,19 +248,6 @@
 		__flush_tlb();
 }
 
-extern inline void flush_tlb_kernel_page(unsigned long addr)
-{
-	if (CPU_IS_040_OR_060) {
-		mm_segment_t old_fs = get_fs();
-		set_fs(KERNEL_DS);
-		__asm__ __volatile__(".chip 68040\n\t"
-				     "pflush (%0)\n\t"
-				     ".chip 68k"
-				     : : "a" (addr));
-		set_fs(old_fs);
-	} else
-		__asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr));
-}
 
 extern inline void flush_tlb_pgtables(struct mm_struct *mm,
 				      unsigned long start, unsigned long end)
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/openprom.h linux/include/asm-m68k/openprom.h
--- v2.4.5/linux/include/asm-m68k/openprom.h	Fri Nov 12 04:29:47 1999
+++ linux/include/asm-m68k/openprom.h	Mon Jun 11 19:15:27 2001
@@ -89,7 +89,7 @@
 	int *fd_stdout;
 };
 
-#ifdef CONFIG_SUN3
+#if defined(CONFIG_SUN3) || defined(CONFIG_SUN3X)
 struct linux_romvec {
 	char		*pv_initsp;		
 	int		(*pv_startmon)(void);
@@ -173,12 +173,15 @@
 						
 	void		(*pv_halt)(void);	
 	unsigned char	*pv_memorybitmap;	
+
+#ifdef CONFIG_SUN3
 	void		(*pv_setctxt)(int ctxt, char *va, int pmeg);
 	void		(*pv_vector_cmd)(void);	
 	int		dummy1z;
 	int		dummy2z;
 	int		dummy3z;
 	int		dummy4z;
+#endif
 };
 #else
 /* The top level PROM vector. */
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/parport.h linux/include/asm-m68k/parport.h
--- v2.4.5/linux/include/asm-m68k/parport.h	Mon Nov 27 17:11:26 2000
+++ linux/include/asm-m68k/parport.h	Mon Jun 11 19:15:27 2001
@@ -11,6 +11,9 @@
 #ifndef _ASM_M68K_PARPORT_H
 #define _ASM_M68K_PARPORT_H 1
 
+#define insl(port,buf,len)   isa_insb(port,buf,(len)<<2)
+#define outsl(port,buf,len)  isa_outsb(port,buf,(len)<<2)
+
 /* no dma, or IRQ autoprobing */
 static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma);
 static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/pgalloc.h linux/include/asm-m68k/pgalloc.h
--- v2.4.5/linux/include/asm-m68k/pgalloc.h	Tue Dec  5 12:43:48 2000
+++ linux/include/asm-m68k/pgalloc.h	Mon Jun 11 19:15:27 2001
@@ -105,14 +105,14 @@
 }
 
 /* Push the page at kernel virtual address and clear the icache */
+/* RZ: use cpush %bc instead of cpush %dc, cinv %ic */
 #define flush_page_to_ram(page) __flush_page_to_ram((unsigned long) page_address(page))
 extern inline void __flush_page_to_ram(unsigned long address)
 {
 	if (CPU_IS_040_OR_060) {
 		__asm__ __volatile__("nop\n\t"
 				     ".chip 68040\n\t"
-				     "cpushp %%dc,(%0)\n\t"
-				     "cinvp %%ic,(%0)\n\t"
+				     "cpushp %%bc,(%0)\n\t"
 				     ".chip 68k"
 				     : : "a" (__pa((void *)address)));
 	} else {
@@ -128,6 +128,7 @@
 #define flush_dcache_page(page)			do { } while (0)
 
 /* Push n pages at kernel virtual address and clear the icache */
+/* RZ: use cpush %bc instead of cpush %dc, cinv %ic */
 extern inline void flush_icache_range (unsigned long address,
 				       unsigned long endaddr)
 {
@@ -137,8 +138,7 @@
 		while (--n >= 0) {
 			__asm__ __volatile__("nop\n\t"
 					     ".chip 68040\n\t"
-					     "cpushp %%dc,(%0)\n\t"
-					     "cinvp %%ic,(%0)\n\t"
+					     "cpushp %%bc,(%0)\n\t"
 					     ".chip 68k"
 					     : : "a" (virt_to_phys((void *)address)));
 			address += PAGE_SIZE;
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/q40_keyboard.h linux/include/asm-m68k/q40_keyboard.h
--- v2.4.5/linux/include/asm-m68k/q40_keyboard.h	Mon Nov 27 17:57:34 2000
+++ linux/include/asm-m68k/q40_keyboard.h	Mon Jun 11 19:15:27 2001
@@ -1,11 +1,7 @@
 /*
  *  linux/include/asm-m68k/q40_keyboard.h
  *
- *  Created 
- */
-
-/*
- *  This file contains the Q40 specific keyboard definitions
+ *  Q40 specific keyboard definitions
  */
 
 
@@ -23,23 +19,12 @@
 			   char raw_mode);
 extern char q40kbd_unexpected_up(unsigned char keycode);
 extern void q40kbd_leds(unsigned char leds);
+extern int q40kbd_is_sysrq(unsigned char keycode);
 extern void q40kbd_init_hw(void);
 extern unsigned char q40kbd_sysrq_xlate[128];
 
 
-#if 0
-#define kbd_setkeycode		q40kbd_setkeycode
-#define kbd_getkeycode		q40kbd_getkeycode
-#define kbd_pretranslate	q40kbd_pretranslate
-#define kbd_translate		q40kbd_translate
-#define kbd_unexpected_up	q40kbd_unexpected_up
-#define kbd_leds		q40kbd_leds
-#define kbd_init_hw		q40kbd_init_hw
-#define kbd_sysrq_xlate		q40kbd_sysrq_xlate
-
 
-#define SYSRQ_KEY 0x54
-#endif
 #endif /* __KERNEL__ */
 
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/q40_master.h linux/include/asm-m68k/q40_master.h
--- v2.4.5/linux/include/asm-m68k/q40_master.h	Mon Nov 27 17:11:26 2000
+++ linux/include/asm-m68k/q40_master.h	Mon Jun 11 19:15:27 2001
@@ -6,7 +6,7 @@
 #ifndef _Q40_MASTER_H
 #define _Q40_MASTER_H
 
-#include <asm/io.h>
+#include <asm/raw_io.h>
 
 
 #define q40_master_addr 0xff000000
@@ -17,6 +17,10 @@
 #define KEYCODE_REG         0x1c      /* value of received scancode  */
 #define DISPLAY_CONTROL_REG 0x18
 #define FRAME_CLEAR_REG     0x24
+#define LED_REG             0x30
+
+#define Q40_LED_ON()        master_outb(1,LED_REG)
+#define Q40_LED_OFF()       master_outb(0,LED_REG)
 
 #define INTERRUPT_REG       IIRQ_REG  /* "native" ints */
 #define KEY_IRQ_ENABLE_REG  0x08      /**/
@@ -35,13 +39,10 @@
 #endif
 #define EXT_ENABLE_REG      0x10      /* ... rest of the ISA ints ... */
 
-#if 0
-#define master_inb(_reg_)           (*(((unsigned char *)q40_master_addr)+_reg_))
-#define master_outb(_b_,_reg_)      (*(((unsigned char *)q40_master_addr)+_reg_)=(_b_))
-#else
-#define master_inb(_reg_)      native_inb((unsigned char *)q40_master_addr+_reg_)
-#define master_outb(_b_,_reg_)  native_outb(_b_,(unsigned char *)q40_master_addr+_reg_)
-#endif
+
+#define master_inb(_reg_)      in_8((unsigned char *)q40_master_addr+_reg_)
+#define master_outb(_b_,_reg_)  out_8((unsigned char *)q40_master_addr+_reg_,_b_)
+
 
 /* define some Q40 specific ints */
 #include "q40ints.h"
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/raw_io.h linux/include/asm-m68k/raw_io.h
--- v2.4.5/linux/include/asm-m68k/raw_io.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-m68k/raw_io.h	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,242 @@
+/*
+ * linux/include/asm-m68k/io_native.h 
+ *
+ * 10/20/00 RZ: - created from bits of io.h and ide.h to cleanup namespace
+ *
+ */
+
+#ifndef _RAW_IO_H
+#define _RAW_IO_H
+
+#ifdef __KERNEL__
+
+
+/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
+ * two accesses to memory, which may be undesirable for some devices.
+ */
+#define in_8(addr) \
+    ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
+#define in_be16(addr) \
+    ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
+#define in_be32(addr) \
+    ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
+
+#define out_8(addr,b) (void)((*(volatile unsigned char *) (addr)) = (b))
+#define out_be16(addr,b) (void)((*(volatile unsigned short *) (addr)) = (b))
+#define out_be32(addr,b) (void)((*(volatile unsigned int *) (addr)) = (b))
+
+#define raw_inb in_8
+#define raw_inw in_be16
+#define raw_inl in_be32
+
+#define raw_outb(val,port) out_8((port),(val))
+#define raw_outw(val,port) out_be16((port),(val))
+#define raw_outl(val,port) out_be32((port),(val))
+
+#define raw_insb(port, buf, len) ({	   \
+	volatile unsigned char *_port = (volatile unsigned char *) (port);   \
+        unsigned char *_buf =(unsigned char *)(buf);	   \
+        unsigned int  _i,_len=(unsigned int)(len);	   \
+        for(_i=0; _i< _len; _i++)  \
+           *_buf++=in_8(_port);      \
+  })
+
+#define raw_outsb(port, buf, len) ({	   \
+	volatile unsigned char *_port = (volatile unsigned char *) (port);   \
+        unsigned char *_buf =(unsigned char *)(buf);	   \
+        unsigned int  _i,_len=(unsigned int)(len);	   \
+        for( _i=0; _i< _len; _i++)  \
+           out_8(_port,*_buf++);      \
+  })
+ 
+
+#define raw_insw(port, buf, nr) ({				\
+	volatile unsigned char *_port = (volatile unsigned char *) (port);	\
+	unsigned char *_buf = (unsigned char *)(buf);			\
+	unsigned int _nr = (unsigned int)(nr);					\
+	unsigned long _tmp;				\
+							\
+	if (_nr & 15) {					\
+		_tmp = (_nr & 15) - 1;			\
+		asm volatile (				\
+			"1: movew %2@,%0@+; dbra %1,1b"	\
+			: "=a" (_buf), "=d" (_tmp)	\
+			: "a" (_port), "0" (_buf),	\
+			  "1" (_tmp));			\
+	}						\
+	if (_nr >> 4) {					\
+		_tmp = (_nr >> 4) - 1;			\
+		asm volatile (				\
+			"1: "				\
+			"movew %2@,%0@+; "		\
+			"movew %2@,%0@+; "		\
+			"movew %2@,%0@+; "		\
+			"movew %2@,%0@+; "		\
+			"movew %2@,%0@+; "		\
+			"movew %2@,%0@+; "		\
+			"movew %2@,%0@+; "		\
+			"movew %2@,%0@+; "		\
+			"movew %2@,%0@+; "		\
+			"movew %2@,%0@+; "		\
+			"movew %2@,%0@+; "		\
+			"movew %2@,%0@+; "		\
+			"movew %2@,%0@+; "		\
+			"movew %2@,%0@+; "		\
+			"movew %2@,%0@+; "		\
+			"movew %2@,%0@+; "		\
+			"dbra %1,1b"			\
+			: "=a" (_buf), "=d" (_tmp)	\
+			: "a" (_port), "0" (_buf),	\
+			  "1" (_tmp));			\
+	}						\
+})
+
+#define raw_outsw(port, buf, nr) ({				\
+	volatile unsigned char *_port = (volatile unsigned char *) (port);	\
+	unsigned char *_buf = (unsigned char *)(buf);			\
+	unsigned int _nr = (unsigned int)(nr);					\
+	unsigned long _tmp;				\
+							\
+	if (_nr & 15) {					\
+		_tmp = (_nr & 15) - 1;			\
+		asm volatile (				\
+			"1: movew %0@+,%2@; dbra %1,1b"	\
+			: "=a" (_buf), "=d" (_tmp)	\
+			: "a" (_port), "0" (_buf),	\
+			  "1" (_tmp));			\
+	}						\
+	if (_nr >> 4) {					\
+		_tmp = (_nr >> 4) - 1;			\
+		asm volatile (				\
+			"1: "				\
+			"movew %0@+,%2@; "		\
+			"movew %0@+,%2@; "		\
+			"movew %0@+,%2@; "		\
+			"movew %0@+,%2@; "		\
+			"movew %0@+,%2@; "		\
+			"movew %0@+,%2@; "		\
+			"movew %0@+,%2@; "		\
+			"movew %0@+,%2@; "		\
+			"movew %0@+,%2@; "		\
+			"movew %0@+,%2@; "		\
+			"movew %0@+,%2@; "		\
+			"movew %0@+,%2@; "		\
+			"movew %0@+,%2@; "		\
+			"movew %0@+,%2@; "		\
+			"movew %0@+,%2@; "		\
+			"movew %0@+,%2@; "		\
+			"dbra %1,1b"	   		\
+			: "=a" (_buf), "=d" (_tmp)	\
+			: "a" (_port), "0" (_buf),	\
+			  "1" (_tmp));			\
+	}						\
+})
+
+
+#define raw_insw_swapw(port, buf, nr) \
+({  if ((nr) % 8) \
+	__asm__ __volatile__ \
+	       ("movel %0,%/a0; \
+		 movel %1,%/a1; \
+		 movel %2,%/d6; \
+		 subql #1,%/d6; \
+	       1:movew %/a0@,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a1@+; \
+		 dbra %/d6,1b"  \
+		:               \
+		: "g" (port), "g" (buf), "g" (nr) \
+		: "d0", "a0", "a1", "d6"); \
+    else \
+	__asm__ __volatile__ \
+	       ("movel %0,%/a0; \
+		 movel %1,%/a1; \
+		 movel %2,%/d6; \
+		 lsrl  #3,%/d6; \
+		 subql #1,%/d6; \
+	       1:movew %/a0@,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a1@+; \
+		 movew %/a0@,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a1@+; \
+		 movew %/a0@,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a1@+; \
+		 movew %/a0@,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a1@+; \
+		 movew %/a0@,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a1@+; \
+		 movew %/a0@,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a1@+; \
+		 movew %/a0@,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a1@+; \
+		 movew %/a0@,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a1@+; \
+		 dbra %/d6,1b"  \
+                :               \
+		: "g" (port), "g" (buf), "g" (nr) \
+		: "d0", "a0", "a1", "d6"); \
+})
+
+
+#define raw_outsw_swapw(port, buf, nr) \
+({  if ((nr) % 8) \
+	__asm__ __volatile__ \
+	       ("movel %0,%/a0; \
+		 movel %1,%/a1; \
+		 movel %2,%/d6; \
+		 subql #1,%/d6; \
+	       1:movew %/a1@+,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a0@; \
+		 dbra %/d6,1b"  \
+                :               \
+		: "g" (port), "g" (buf), "g" (nr) \
+		: "d0", "a0", "a1", "d6"); \
+    else \
+	__asm__ __volatile__ \
+	       ("movel %0,%/a0; \
+		 movel %1,%/a1; \
+		 movel %2,%/d6; \
+		 lsrl  #3,%/d6; \
+		 subql #1,%/d6; \
+	       1:movew %/a1@+,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a0@; \
+		 movew %/a1@+,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a0@; \
+		 movew %/a1@+,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a0@; \
+		 movew %/a1@+,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a0@; \
+		 movew %/a1@+,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a0@; \
+		 movew %/a1@+,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a0@; \
+		 movew %/a1@+,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a0@; \
+		 movew %/a1@+,%/d0; \
+		 rolw  #8,%/d0; \
+		 movew %/d0,%/a0@; \
+		 dbra %/d6,1b"  \
+                :               \
+		: "g" (port), "g" (buf), "g" (nr) \
+		: "d0", "a0", "a1", "d6"); \
+})
+
+
+#endif /* __KERNEL__ */
+
+#endif /* _RAW_IO_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/rtc.h linux/include/asm-m68k/rtc.h
--- v2.4.5/linux/include/asm-m68k/rtc.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-m68k/rtc.h	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,49 @@
+/* asm-m68k/rtc.h
+ *
+ * Copyright Richard Zidlicky
+ * implementation details for genrtc/q40rtc driver
+ */
+/* permission is hereby granted to copy, modify and redistribute this code
+ * in terms of the GNU Library General Public License, Version 2 or later,
+ * at your option.
+ */
+
+#ifndef _ASM_RTC_H
+#define _ASM_RTC_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+
+struct hwclk_time {
+	unsigned	sec;	/* 0..59 */
+	unsigned	min;	/* 0..59 */
+	unsigned	hour;	/* 0..23 */
+	unsigned	day;	/* 1..31 */
+	unsigned	mon;	/* 0..11 */
+	unsigned	year;	/* 70... */
+	int		wday;	/* 0..6, 0 is Sunday, -1 means unknown/don't set */
+};
+
+/* a few implementation details for the emulation : */
+
+extern unsigned gen_rtc_irq_flags; /* which sort(s) of interrupts caused int */
+extern unsigned gen_rtc_irq_ctrl;  /*                             are enabled */
+extern short q40rtc_oldsecs;
+
+#define RTC_PIE 0x40		/* periodic interrupt enable */
+#define RTC_AIE 0x20		/* alarm interrupt enable */
+#define RTC_UIE 0x10		/* update-finished interrupt enable */
+
+extern void gen_rtc_interrupt(unsigned long);
+
+/* some dummy definitions */
+#define RTC_SQWE 0x08		/* enable square-wave output */
+#define RTC_DM_BINARY 0x04	/* all time/date values are BCD if clear */
+#define RTC_24H 0x02		/* 24 hour mode - else hours bit 7 means pm */
+#define RTC_DST_EN 0x01	        /* auto switch DST - works f. USA only */
+
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM__RTC_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/sbus.h linux/include/asm-m68k/sbus.h
--- v2.4.5/linux/include/asm-m68k/sbus.h	Sat Sep  4 13:06:41 1999
+++ linux/include/asm-m68k/sbus.h	Mon Jun 11 19:15:27 2001
@@ -17,4 +17,27 @@
 
 #define ARCH_SUN4  0
 
+/* sbus IO functions stolen from include/asm-sparc/io.h for the serial driver */
+/* No SBUS on the Sun3, kludge -- sam */
+
+extern inline void _sbus_writeb(unsigned char val, unsigned long addr)
+{
+	*(volatile unsigned char *)addr = val;
+}
+
+extern inline unsigned char _sbus_readb(unsigned long addr)
+{
+	return *(volatile unsigned char *)addr;
+}
+
+extern inline void _sbus_writel(unsigned long val, unsigned long addr)
+{
+	*(volatile unsigned long *)addr = val;
+
+}
+
+#define sbus_readb(a) _sbus_readb((unsigned long)a)
+#define sbus_writeb(v, a) _sbus_writeb(v, (unsigned long)a)
+#define sbus_writel(v, a) _sbus_writel(v, (unsigned long)a)
+
 #endif
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/serial.h linux/include/asm-m68k/serial.h
--- v2.4.5/linux/include/asm-m68k/serial.h	Wed Apr 18 11:49:13 2001
+++ linux/include/asm-m68k/serial.h	Mon Jun 11 19:15:27 2001
@@ -7,11 +7,6 @@
  */
 
 #include <linux/config.h>
-#if 0
-#define rs_init serial_rs_init
-#define register_serial serial_register_serial
-#define unregister_serial serial_unregister_serial
-#endif
 
 /*
  * This assumes you have a 1.8432 MHz clock for your UART.
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/socket.h linux/include/asm-m68k/socket.h
--- v2.4.5/linux/include/asm-m68k/socket.h	Sat Feb  3 11:26:44 2001
+++ linux/include/asm-m68k/socket.h	Wed Jun 20 21:00:55 2001
@@ -58,6 +58,7 @@
 					/* level.  For writing rarp and	*/
 					/* other similar things on the	*/
 					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
 #endif
 
 #endif /* _ASM_SOCKET_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/string.h linux/include/asm-m68k/string.h
--- v2.4.5/linux/include/asm-m68k/string.h	Thu Apr 27 15:55:09 2000
+++ linux/include/asm-m68k/string.h	Mon Jun 11 19:15:27 2001
@@ -80,8 +80,9 @@
   return( (char *) s);
 }
 
+#if 0
 #define __HAVE_ARCH_STRPBRK
-static inline char * strpbrk(const char * cs,const char * ct)
+extern inline char * strpbrk(const char * cs,const char * ct)
 {
   const char *sc1,*sc2;
   
@@ -91,7 +92,9 @@
 	return((char *) sc1);
   return( NULL );
 }
+#endif
 
+#if 0
 #define __HAVE_ARCH_STRSPN
 static inline size_t strspn(const char *s, const char *accept)
 {
@@ -112,9 +115,11 @@
 
   return count;
 }
+#endif
 
+#if 0
 #define __HAVE_ARCH_STRTOK
-static inline char * strtok(char * s,const char * ct)
+extern inline char * strtok(char * s,const char * ct)
 {
   char *sbegin, *send;
   
@@ -133,6 +138,7 @@
   ___strtok = send;
   return (sbegin);
 }
+#endif
 
 /* strstr !! */
 
@@ -318,7 +324,7 @@
 #ifdef CPU_M68040_OR_M68060_ONLY
 
   if (((unsigned long) s) & 0x0f)
-	  memset(s, c, count);
+	  __memset_g(s, c, count);
   else{
 	  *((unsigned long *)(s))++ = data;
 	  *((unsigned long *)(s))++ = data;
@@ -356,6 +362,8 @@
   return xs;
 }
 
+extern void *memset(void *,int,__kernel_size_t);
+
 #define __memset_const(s,c,count) \
 ((count==PAGE_SIZE) ? \
   __memset_page((s),(c),(count)) : \
@@ -364,7 +372,7 @@
 #define memset(s, c, count) \
 (__builtin_constant_p(count) ? \
  __memset_const((s),(c),(count)) : \
- memset((s),(c),(count)))
+ __memset_g((s),(c),(count)))
 
 #define __HAVE_ARCH_MEMCPY
 /*
@@ -541,5 +549,15 @@
 (__builtin_constant_p(n) ? \
  __builtin_memcmp((cs),(ct),(n)) : \
  memcmp((cs),(ct),(n)))
+
+#define __HAVE_ARCH_MEMCHR
+extern inline void * memchr(const void * cs, int c, size_t count) {
+	/* Someone else can optimize this, I don't care - tonym@mac.linux-m68k.org */
+	unsigned char *ret = (unsigned char *)cs;
+	for(;count>0;count--,ret++)
+		if(*ret == c) return ret;
+
+	return NULL;
+}
 
 #endif /* _M68K_STRING_H_ */
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/sun3_pgalloc.h linux/include/asm-m68k/sun3_pgalloc.h
--- v2.4.5/linux/include/asm-m68k/sun3_pgalloc.h	Mon Apr 23 15:28:07 2001
+++ linux/include/asm-m68k/sun3_pgalloc.h	Mon Jun 11 19:15:27 2001
@@ -74,46 +74,30 @@
         return (pmd_t *) pgd;
 }
 
+#define pmd_alloc_one_fast(mm, address) ({ BUG(); ((pmd_t *)1); })
+#define pmd_alloc_one(mm,address)       ({ BUG(); ((pmd_t *)2); })
+
 extern inline void pte_free(pte_t * pte)
 {
         free_page((unsigned long) pte);
 }
 
-extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
-{
-	address = (address >> (PAGE_SHIFT-2)) & 4*(PTRS_PER_PTE - 1);
-
-repeat:
-	if (pmd_none(*pmd))
-		goto getnew;
-	if (pmd_bad(*pmd))
-		goto fix;
-	return (pte_t *) (__pmd_page(*pmd) + address);
-
-getnew:
+static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
 {
 	unsigned long page = __get_free_page(GFP_KERNEL);
-	if (!pmd_none(*pmd))
-		goto freenew;
+
 	if (!page)
-		goto oom;
+		return NULL;
+		
 	memset((void *)page, 0, PAGE_SIZE);
 //	pmd_val(*pmd) = SUN3_PMD_MAGIC + __pa(page);
-	pmd_val(*pmd) = __pa(page);
-	return (pte_t *) (page + address);
-freenew:
-	free_page(page);
-	goto repeat;
+/*	pmd_val(*pmd) = __pa(page); */
+	return (pte_t *) (page);
 }
 
-fix:
-	printk(bad_pmd_string, pmd_val(*pmd));
-	printk("in normal pgd offset %08x\n", (unsigned int)pmd);
-oom:
-//	pmd_val(*pmd) = SUN3_PMD_MAGIC + __pa(BAD_PAGETABLE);
-	pmd_val(*pmd) = __pa(BAD_PAGETABLE);
-	return NULL;
-}
+#define pte_alloc_one_fast(mm,addr) pte_alloc_one(mm,addr)
+
+#define pmd_populate(mm, pmd, pte) (pmd_val(*pmd) = __pa((unsigned long)pte))
 
 /*
  * allocating and freeing a pmd is trivial: the 1-entry pmd is
@@ -124,11 +108,6 @@
         pmd_val(*pmd) = 0;
 }
 
-extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address)
-{
-        return (pmd_t *) pgd;
-}
-
 extern inline void pgd_free(pgd_t * pgd)
 {
         free_page((unsigned long) pgd);
@@ -143,6 +122,8 @@
      memset(new_pgd, 0, (PAGE_OFFSET >> PGDIR_SHIFT));
      return new_pgd;
 }
+
+#define pgd_populate(mm, pmd, pte) BUG()
 
 /* FIXME: the sun3 doesn't have a page table cache! 
    (but the motorola routine should just return 0) */
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/sun3_pgtable.h linux/include/asm-m68k/sun3_pgtable.h
--- v2.4.5/linux/include/asm-m68k/sun3_pgtable.h	Mon Nov 27 18:00:49 2000
+++ linux/include/asm-m68k/sun3_pgtable.h	Mon Jun 11 19:15:27 2001
@@ -135,12 +135,13 @@
 extern inline int pmd_bad2 (pmd_t *pmd) { return 0; }
 #define pmd_bad(pmd) pmd_bad2(&(pmd))
 extern inline int pmd_present2 (pmd_t *pmd) { return pmd_val (*pmd) & SUN3_PMD_VALID; }
-#define pmd_present(pmd) pmd_present2(&(pmd))
+/* #define pmd_present(pmd) pmd_present2(&(pmd)) */
+#define pmd_present(pmd) (!pmd_none2(&(pmd)))
 extern inline void pmd_clear (pmd_t *pmdp) { pmd_val (*pmdp) = 0; }
 
 extern inline int pgd_none (pgd_t pgd) { return 0; }
 extern inline int pgd_bad (pgd_t pgd) { return 0; }
-extern inline int pgd_present (pgd_t pgd) { return 0; }
+extern inline int pgd_present (pgd_t pgd) { return 1; }
 extern inline void pgd_clear (pgd_t *pgdp) {}
 
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/sun3ints.h linux/include/asm-m68k/sun3ints.h
--- v2.4.5/linux/include/asm-m68k/sun3ints.h	Fri Nov 12 04:29:47 1999
+++ linux/include/asm-m68k/sun3ints.h	Mon Jun 11 19:15:27 2001
@@ -26,5 +26,15 @@
                      void (*handler)(int, void *, struct pt_regs *),
                      unsigned long flags, const char *devname, void *dev_id
 		    );
+extern void sun3_init_IRQ (void);
+extern void (*sun3_default_handler[]) (int, void *, struct pt_regs *);
+extern void (*sun3_inthandler[]) (int, void *, struct pt_regs *);
+extern void sun3_free_irq (unsigned int irq, void *dev_id);
+extern void sun3_enable_interrupts (void);
+extern void sun3_disable_interrupts (void);
+extern int sun3_get_irq_list(char *buf);
+extern void sun3_process_int(int, struct pt_regs *);
+extern volatile unsigned char* sun3_intreg;
+
 
 #endif /* SUN3INTS_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/sun3x.h linux/include/asm-m68k/sun3x.h
--- v2.4.5/linux/include/asm-m68k/sun3x.h	Tue May 11 09:57:14 1999
+++ linux/include/asm-m68k/sun3x.h	Mon Jun 11 19:15:27 2001
@@ -15,6 +15,9 @@
 #define SUN3X_VIDEO_P4ID  0x50300000
 #define SUN3X_ESP_BASE	  0x66000000
 #define SUN3X_ESP_DMA	  0x66001000
+#define SUN3X_FDC         0x6e000000
+#define SUN3X_FDC_FCR     0x6e000400
+#define SUN3X_FDC_FVR     0x6e000800
 
 /* some NVRAM addresses */
 #define SUN3X_EEPROM_CONS 	(SUN3X_EEPROM + 0x1f)
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/sun3xflop.h linux/include/asm-m68k/sun3xflop.h
--- v2.4.5/linux/include/asm-m68k/sun3xflop.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-m68k/sun3xflop.h	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,263 @@
+/* sun3xflop.h: Sun3/80 specific parts of the floppy driver.
+ *
+ * Derived partially from asm-sparc/floppy.h, which is:
+ *     Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ *
+ * Sun3x version 2/4/2000 Sam Creasey (sammy@oh.verio.com)
+ */
+
+#ifndef __ASM_SUN3X_FLOPPY_H
+#define __ASM_SUN3X_FLOPPY_H
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/sun3x.h>
+
+/* default interrupt vector */
+#define SUN3X_FDC_IRQ 0x40
+
+/* some constants */
+#define FCR_TC 0x1
+#define FCR_EJECT 0x2
+#define FCR_MTRON 0x4
+#define FCR_DSEL1 0x8
+#define FCR_DSEL0 0x10
+
+/* We don't need no stinkin' I/O port allocation crap. */
+#undef release_region
+#undef check_region
+#undef request_region
+#define release_region(X, Y)	do { } while(0)
+#define check_region(X, Y)	(0)
+#define request_region(X, Y, Z)	(1)
+
+struct sun3xflop_private {
+	volatile unsigned char *status_r;
+	volatile unsigned char *data_r;
+	volatile unsigned char *fcr_r;
+	volatile unsigned char *fvr_r;
+	unsigned char fcr;
+} sun3x_fdc;
+
+/* Super paranoid... */
+#undef HAVE_DISABLE_HLT
+
+/* Routines unique to each controller type on a Sun. */
+static unsigned char sun3x_82072_fd_inb(int port)
+{
+	static int once = 0;
+//	udelay(5);
+	switch(port & 7) {
+	default:
+		printk("floppy: Asked to read unknown port %d\n", port);
+		panic("floppy: Port bolixed.");
+	case 4: /* FD_STATUS */
+		return (*sun3x_fdc.status_r) & ~STATUS_DMA;
+	case 5: /* FD_DATA */
+		return (*sun3x_fdc.data_r);
+	case 7: /* FD_DIR */
+		/* ugly hack, I can't find a way to actually detect the disk */
+		if(!once) {
+			once = 1;
+			return 0x80;
+		}
+		return 0;
+	};
+	panic("sun_82072_fd_inb: How did I get here?");
+}
+
+static void sun3x_82072_fd_outb(unsigned char value, int port)
+{
+//	udelay(5);
+	switch(port & 7) {
+	default:
+		printk("floppy: Asked to write to unknown port %d\n", port);
+		panic("floppy: Port bolixed.");
+	case 2: /* FD_DOR */
+		/* Oh geese, 82072 on the Sun has no DOR register,
+		 * so we make do with taunting the FCR.
+		 *
+		 * ASSUMPTIONS:  There will only ever be one floppy
+		 *               drive attached to a Sun controller
+		 *               and it will be at drive zero.
+		 */
+
+	{
+		unsigned char fcr = sun3x_fdc.fcr;
+
+		if(value & 0x10) {
+			fcr |= (FCR_DSEL0 | FCR_MTRON);
+		} else 
+			fcr &= ~(FCR_DSEL0 | FCR_MTRON);
+		
+		
+		if(fcr != sun3x_fdc.fcr) { 
+			*(sun3x_fdc.fcr_r) = fcr;
+			sun3x_fdc.fcr = fcr;
+		}
+	}
+		break;
+	case 5: /* FD_DATA */
+		*(sun3x_fdc.data_r) = value;
+		break;
+	case 7: /* FD_DCR */
+		*(sun3x_fdc.status_r) = value;
+		break;
+	case 4: /* FD_STATUS */
+		*(sun3x_fdc.status_r) = value;
+		break;
+	};
+	return;
+}
+
+
+asmlinkage void sun3xflop_hardint(int irq, void *dev_id, struct pt_regs * regs)
+{
+	register unsigned char st;
+
+#undef TRACE_FLPY_INT
+#define NO_FLOPPY_ASSEMBLER
+
+#ifdef TRACE_FLPY_INT 
+	static int calls=0;
+	static int bytes=0;
+	static int dma_wait=0;
+#endif
+	if(!doing_pdma) {
+		floppy_interrupt(irq, dev_id, regs);
+		return;
+	}
+
+//	printk("doing pdma\n");// st %x\n", sun_fdc->status_82072);
+
+#ifdef TRACE_FLPY_INT
+	if(!calls)
+		bytes = virtual_dma_count;
+#endif
+
+	{
+		register int lcount;
+		register char *lptr;
+
+		for(lcount=virtual_dma_count, lptr=virtual_dma_addr; 
+		    lcount; lcount--, lptr++) {
+//			st=fd_inb(virtual_dma_port+4) & 0x80 ;
+			st = *(sun3x_fdc.status_r);
+//			if(st != 0xa0)
+//				break;
+	
+			if((st & 0x80) == 0) {
+				virtual_dma_count = lcount;
+				virtual_dma_addr = lptr;
+				return;
+			}
+
+			if((st & 0x20) == 0)
+				break;
+		
+			if(virtual_dma_mode)
+//				fd_outb(*lptr, virtual_dma_port+5);
+				*(sun3x_fdc.data_r) = *lptr;
+			else
+//				*lptr = fd_inb(virtual_dma_port+5);
+				*lptr = *(sun3x_fdc.data_r);
+		}
+		
+		virtual_dma_count = lcount;
+		virtual_dma_addr = lptr;
+//		st = fd_inb(virtual_dma_port+4);
+		st = *(sun3x_fdc.status_r);
+	}
+
+#ifdef TRACE_FLPY_INT
+	calls++;
+#endif
+//	printk("st=%02x\n", st);
+	if(st == 0x20)
+		return;
+	if(!(st & 0x20)) {
+		virtual_dma_residue += virtual_dma_count;
+		virtual_dma_count=0;
+		doing_pdma = 0;
+
+#ifdef TRACE_FLPY_INT
+		printk("count=%x, residue=%x calls=%d bytes=%x dma_wait=%d\n", 
+		       virtual_dma_count, virtual_dma_residue, calls, bytes,
+		       dma_wait);
+		calls = 0;
+		dma_wait=0;
+#endif
+
+		floppy_interrupt(irq, dev_id, regs);
+		return;
+	}
+
+	
+#ifdef TRACE_FLPY_INT
+	if(!virtual_dma_count)
+		dma_wait++;
+#endif
+}
+
+static int sun3xflop_request_irq(void)
+{
+	static int once = 0;
+	int error;
+
+	if(!once) {
+		once = 1;
+		error = request_irq(FLOPPY_IRQ, sun3xflop_hardint, SA_INTERRUPT, "floppy", 0);
+		return ((error == 0) ? 0 : -1);
+	} else return 0;
+}
+
+static void __init floppy_set_flags(int *ints,int param, int param2);
+
+static int sun3xflop_init(void)
+{
+	if(FLOPPY_IRQ < 0x40)
+		FLOPPY_IRQ = SUN3X_FDC_IRQ;
+
+	sun3x_fdc.status_r = (volatile unsigned char *)SUN3X_FDC;
+	sun3x_fdc.data_r  = (volatile unsigned char *)(SUN3X_FDC+1);
+	sun3x_fdc.fcr_r = (volatile unsigned char *)SUN3X_FDC_FCR;
+	sun3x_fdc.fvr_r = (volatile unsigned char *)SUN3X_FDC_FVR;
+	sun3x_fdc.fcr = 0;
+
+	/* Last minute sanity check... */
+	if(*sun3x_fdc.status_r == 0xff) {
+		return -1;
+	}
+	
+	*sun3x_fdc.fvr_r = FLOPPY_IRQ;
+	
+	*sun3x_fdc.fcr_r = FCR_TC;
+	udelay(10);
+	*sun3x_fdc.fcr_r = 0;
+
+	/* Success... */
+	floppy_set_flags(0, 1, FD_BROKEN_DCL); // I don't know how to detect this.
+	allowed_drive_mask = 0x01;
+	return (int) SUN3X_FDC;
+}
+
+/* I'm not precisely sure this eject routine works */
+static int sun3x_eject(void)
+{
+	if(MACH_IS_SUN3X) {
+	
+		sun3x_fdc.fcr |= (FCR_DSEL0 | FCR_EJECT);
+		*(sun3x_fdc.fcr_r) = sun3x_fdc.fcr;
+		udelay(10);
+		sun3x_fdc.fcr &= ~(FCR_DSEL0 | FCR_EJECT);
+		*(sun3x_fdc.fcr_r) = sun3x_fdc.fcr;
+	}
+
+	return 0;
+}
+
+#define fd_eject(drive) sun3x_eject()
+
+#endif /* !(__ASM_SUN3X_FLOPPY_H) */
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/sun3xprom.h linux/include/asm-m68k/sun3xprom.h
--- v2.4.5/linux/include/asm-m68k/sun3xprom.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-m68k/sun3xprom.h	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,43 @@
+/* Useful PROM locations */
+
+#ifndef SUN3X_PROM_H
+#define SUN3X_PROM_H
+
+extern void (*sun3x_putchar)(int);
+extern int (*sun3x_getchar)(void);
+extern int (*sun3x_mayget)(void);
+extern int (*sun3x_mayput)(int);
+
+void sun3x_reboot(void);
+void sun3x_abort(void);
+void sun3x_prom_init(void);
+unsigned long sun3x_prom_ptov(unsigned long pa, unsigned long size);
+
+/* interesting hardware locations */
+#define SUN3X_IOMMU       0x60000000
+#define SUN3X_ENAREG      0x61000000
+#define SUN3X_INTREG      0x61001400
+#define SUN3X_DIAGREG     0x61001800
+#define SUN3X_ZS1         0x62000000
+#define SUN3X_ZS2         0x62002000
+#define SUN3X_LANCE       0x65002000
+#define SUN3X_EEPROM      0x64000000
+#define SUN3X_IDPROM      0x640007d8
+#define SUN3X_VIDEO_BASE  0x50400000
+#define SUN3X_VIDEO_REGS  0x50300000
+
+/* vector table */
+#define SUN3X_PROM_BASE   0xfefe0000
+#define SUN3X_P_GETCHAR   (SUN3X_PROM_BASE + 20)
+#define SUN3X_P_PUTCHAR   (SUN3X_PROM_BASE + 24)
+#define SUN3X_P_MAYGET    (SUN3X_PROM_BASE + 28)
+#define SUN3X_P_MAYPUT    (SUN3X_PROM_BASE + 32)
+#define SUN3X_P_REBOOT    (SUN3X_PROM_BASE + 96)
+#define SUN3X_P_SETLEDS   (SUN3X_PROM_BASE + 144)
+#define SUN3X_P_ABORT     (SUN3X_PROM_BASE + 152)
+
+/* mapped area */
+#define SUN3X_MAP_START   0xfee00000
+#define SUN3X_MAP_END     0xff000000
+
+#endif
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/system.h linux/include/asm-m68k/system.h
--- v2.4.5/linux/include/asm-m68k/system.h	Mon Nov 27 18:00:49 2000
+++ linux/include/asm-m68k/system.h	Mon Jun 11 19:15:27 2001
@@ -52,9 +52,9 @@
 #define __sti() asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory")
 #else
 #include <asm/hardirq.h>
-#define __sti() ({								\
-	if (!local_irq_count(smp_processor_id()))				\
-		asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory");	\
+#define __sti() ({							      \
+	if (MACH_IS_Q40 || !local_irq_count(smp_processor_id()))              \
+		asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory");  \
 })
 #endif
 #define __cli() asm volatile ("oriw  #0x0700,%%sr": : : "memory")
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/termios.h linux/include/asm-m68k/termios.h
--- v2.4.5/linux/include/asm-m68k/termios.h	Sat Feb  3 20:00:45 2001
+++ linux/include/asm-m68k/termios.h	Mon Jun 11 19:15:27 2001
@@ -65,6 +65,7 @@
 #define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
 #define N_HDLC		13	/* synchronous HDLC */
 #define N_SYNC_PPP	14
+#define N_HCI		15  /* Bluetooth HCI UART */
 
 #ifdef __KERNEL__
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-m68k/zorro.h linux/include/asm-m68k/zorro.h
--- v2.4.5/linux/include/asm-m68k/zorro.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-m68k/zorro.h	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,18 @@
+#ifndef _ASM_ZORRO_H
+#define _ASM_ZORRO_H
+#include <asm/raw_io.h>
+
+#define z_readb raw_inb
+#define z_readw raw_inw
+#define z_readl raw_inl
+
+#define z_writeb raw_outb
+#define z_writew raw_outw
+#define z_writel raw_outl
+
+#define z_memset_io(a,b,c)	memset((void *)(a),(b),(c))
+#define z_memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
+#define z_memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
+
+
+#endif /* _ASM_ZORRO_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-mips/linux_logo.h linux/include/asm-mips/linux_logo.h
--- v2.4.5/linux/include/asm-mips/linux_logo.h	Sat May 13 08:31:25 2000
+++ linux/include/asm-mips/linux_logo.h	Mon Jun 11 19:15:27 2001
@@ -24,918 +24,897 @@
 
 #define linux_logo_banner "Linux/MIPS version " UTS_RELEASE
 
-#define LINUX_LOGO_COLORS 212
+#define __HAVE_ARCH_LINUX_LOGO
+
+#define LINUX_LOGO_COLORS	187
 
 #ifdef INCLUDE_LINUX_LOGO_DATA
 
 unsigned char linux_logo_red[] __initdata = {
-  0x03, 0x82, 0xE9, 0xBF, 0x42, 0xC9, 0x7E, 0xC0,
-  0xE9, 0xE3, 0xC2, 0x24, 0xA4, 0x65, 0xEC, 0xC4,
-  0x82, 0x9F, 0xF3, 0x12, 0x5F, 0xA0, 0xC2, 0xED,
-  0x3E, 0xD5, 0xDB, 0xA0, 0x1C, 0xF4, 0xEB, 0xA4,
-  0xCD, 0x0A, 0x9A, 0x51, 0xCC, 0xBE, 0xC0, 0xBA,
-  0x74, 0xDC, 0xAA, 0xF6, 0xD3, 0xC5, 0xE6, 0x26,
-  0xC2, 0x83, 0x38, 0xEA, 0x49, 0xB0, 0xED, 0xE5,
-  0xF4, 0x96, 0x96, 0x1B, 0xFA, 0xCC, 0xF2, 0x0F,
-  0xCD, 0xE5, 0xF4, 0xD3, 0x50, 0x7A, 0xB5, 0xDE,
-  0xD5, 0xB6, 0x60, 0x0A, 0x6A, 0xEA, 0xD4, 0xEB,
-  0xC1, 0xCA, 0xEA, 0xEC, 0x2A, 0x96, 0x95, 0xDC,
-  0xE4, 0xCE, 0xEC, 0x1E, 0xDC, 0x8A, 0xD1, 0xF6,
-  0x3C, 0x5E, 0xC6, 0xB4, 0xB2, 0xAC, 0xBA, 0x9E,
-  0x0F, 0x59, 0xBA, 0xFA, 0xCC, 0xBF, 0x82, 0xCE,
-  0xE6, 0x4F, 0xAA, 0x4C, 0xCA, 0x8E, 0x8E, 0xDF,
-  0x2C, 0xB6, 0x3B, 0xDE, 0xCE, 0xEE, 0x46, 0x4A,
-  0x6F, 0x7A, 0x82, 0xE4, 0xAA, 0x88, 0xE2, 0xCE,
-  0xAE, 0xB6, 0x70, 0xC2, 0x9A, 0xDA, 0x35, 0x9E,
-  0x95, 0xC0, 0x7E, 0x8C, 0xC2, 0xB6, 0xCE, 0xB9,
-  0xD5, 0xAA, 0xC1, 0xF4, 0xC7, 0xB6, 0xB6, 0xA3,
-  0xF2, 0x68, 0xDB, 0x76, 0xDC, 0x57, 0xD3, 0xA8,
-  0xC0, 0xEF, 0x46, 0xF4, 0x2F, 0xD7, 0x53, 0x36,
-  0xE6, 0xA7, 0xCA, 0xCB, 0x7E, 0xE4, 0x86, 0x9A,
-  0xCE, 0x94, 0xB4, 0x1D, 0xDA, 0xCE, 0x6C, 0xE6,
-  0x9E, 0xC6, 0xDA, 0x16, 0xFA, 0xAA, 0x56, 0xB6,
-  0xFE, 0x6E, 0xEA, 0xCE, 0xE5, 0xCC, 0xDB, 0xD3,
-  0xED, 0xDC, 0xF4, 0x72
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
+    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
+    0xc3, 0x65, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
+    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
+    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x76, 0x79,
+    0x62, 0x36, 0x9a, 0xe2, 0xec, 0xe1, 0xb8, 0xd7,
+    0xaf, 0x25, 0xbc, 0xc0, 0xef, 0xea, 0xe8, 0xe8,
+    0xf5, 0xf1, 0xda, 0xd3, 0x79, 0xdb, 0xf4, 0xf6,
+    0xf6, 0xf6, 0xe2, 0x3d, 0xb4, 0xce, 0xe6, 0xee,
+    0xf6, 0x68, 0xd8, 0xec, 0xf5, 0xc6, 0xc8, 0x9c,
+    0x89, 0xd2, 0xee, 0xcb, 0xb9, 0xd2, 0x66, 0x5e,
+    0x8b, 0xbe, 0xa8, 0xd5, 0xca, 0xb6, 0xae, 0x9c,
+    0xc5, 0xbe, 0xbe, 0xca, 0x90, 0xb2, 0x9a, 0xa8,
+    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x8d,
+    0x12, 0x4a, 0x8e, 0xf2, 0xf6, 0xee, 0xb5, 0xe4,
+    0xf1, 0x26, 0x9a, 0xea, 0xf6, 0xe0, 0xd2, 0x16,
+    0x9a, 0x2e, 0x70, 0xd6, 0x46, 0x7c, 0xb4, 0x62,
+    0xd6, 0xa3, 0x74, 0xa7, 0xa2, 0xca, 0xe0, 0xae,
+    0xbe, 0xce, 0xa3, 0x8e, 0x6d, 0x8e, 0x32, 0xaf,
+    0x50, 0x9e, 0x5b, 0x8a, 0x98, 0x82, 0x7a, 0x82,
+    0x56, 0x7c, 0x8a, 0x56, 0x5e, 0x86, 0x6a, 0x52,
+    0x59, 0x64, 0x5e,
 };
 
 unsigned char linux_logo_green[] __initdata = {
-  0x03, 0x82, 0xC4, 0x83, 0x42, 0xA2, 0x4A, 0xA4,
-  0xE5, 0xA6, 0xC2, 0x24, 0xA4, 0x65, 0xB4, 0x94,
-  0x66, 0x87, 0xB6, 0x12, 0x44, 0x6C, 0x96, 0xD4,
-  0x36, 0x95, 0xB2, 0x92, 0x0E, 0xF4, 0xBC, 0x77,
-  0xA5, 0x0A, 0x92, 0x52, 0xB4, 0x9A, 0x8C, 0xB2,
-  0x74, 0xC2, 0x8E, 0xBD, 0xA2, 0xCA, 0xD2, 0x12,
-  0xB6, 0x61, 0x24, 0xDA, 0x33, 0x79, 0xCB, 0xAC,
-  0xDA, 0x84, 0x7A, 0x1B, 0xFA, 0x8D, 0xBE, 0x06,
-  0x93, 0xBB, 0xBC, 0xAB, 0x44, 0x62, 0x83, 0xDA,
-  0x9B, 0xA2, 0x4C, 0x04, 0x6A, 0xB6, 0xC8, 0xBD,
-  0x8D, 0xB6, 0xAD, 0xEC, 0x2A, 0x68, 0x62, 0x9D,
-  0xC4, 0xC4, 0xB4, 0x13, 0xA3, 0x8A, 0xD2, 0xD6,
-  0x3C, 0x5D, 0x8C, 0x7E, 0x82, 0xAC, 0x96, 0x7E,
-  0x0D, 0x5A, 0xBA, 0xBB, 0xCC, 0xBE, 0x76, 0xB6,
-  0xDE, 0x4E, 0x9A, 0x3C, 0xBE, 0x8E, 0x6E, 0xCB,
-  0x1C, 0xAA, 0x2E, 0xBE, 0xAA, 0xDE, 0x3E, 0x4B,
-  0x4D, 0x7A, 0x54, 0xE4, 0x8E, 0x6E, 0xCA, 0x9B,
-  0x70, 0x9E, 0x5A, 0xAA, 0x9A, 0xBE, 0x34, 0x9E,
-  0x71, 0x9E, 0x7E, 0x5F, 0xAA, 0x8A, 0xBE, 0x91,
-  0xCE, 0x88, 0x92, 0xDB, 0xC6, 0xAB, 0x8A, 0x72,
-  0xE2, 0x44, 0xC3, 0x54, 0xAA, 0x45, 0xBB, 0x92,
-  0xBA, 0xC4, 0x46, 0xCA, 0x2D, 0xD6, 0x3B, 0x1A,
-  0xC2, 0x7E, 0xA6, 0xCB, 0x7A, 0xDC, 0x86, 0x72,
-  0xB6, 0x94, 0xB4, 0x1C, 0xBC, 0xAE, 0x4C, 0xD6,
-  0x62, 0x86, 0xD3, 0x16, 0xF6, 0x7A, 0x55, 0x79,
-  0xFE, 0x6E, 0xC6, 0xC6, 0xAA, 0x93, 0xDC, 0x9D,
-  0xAE, 0xA4, 0xD4, 0x56
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
+    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
+    0xc3, 0x62, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
+    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
+    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x62, 0x5c,
+    0x4e, 0x26, 0x72, 0xaa, 0xba, 0xaf, 0x90, 0xae,
+    0x92, 0x1a, 0xa4, 0x85, 0xb6, 0xbe, 0xc3, 0xc8,
+    0xcf, 0xd0, 0xc2, 0xce, 0x57, 0xa2, 0xd6, 0xda,
+    0xda, 0xd7, 0xb8, 0x2a, 0x7b, 0x91, 0xae, 0xca,
+    0xda, 0x45, 0x9e, 0xb2, 0xd7, 0x9b, 0x90, 0x76,
+    0x5c, 0xa2, 0xbe, 0xa6, 0x85, 0x96, 0x4e, 0x46,
+    0x66, 0x92, 0x7a, 0x9a, 0x96, 0x9d, 0x9a, 0x6b,
+    0x8a, 0x8e, 0xb2, 0xca, 0x90, 0xa6, 0x79, 0x7c,
+    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x8d,
+    0x0e, 0x36, 0x86, 0xba, 0xbe, 0xcc, 0x8e, 0xb8,
+    0xc4, 0x1e, 0x8e, 0xae, 0xba, 0xb2, 0xa6, 0x12,
+    0x7a, 0x20, 0x64, 0xaa, 0x2f, 0x70, 0x85, 0x46,
+    0xa6, 0x6e, 0x51, 0x72, 0x92, 0xa2, 0xa6, 0x87,
+    0x96, 0xa2, 0x85, 0x7a, 0x6a, 0x6e, 0x22, 0x76,
+    0x36, 0x76, 0x3c, 0x6e, 0x63, 0x53, 0x66, 0x62,
+    0x42, 0x50, 0x56, 0x42, 0x56, 0x56, 0x56, 0x3e,
+    0x51, 0x52, 0x56,
 };
 
 unsigned char linux_logo_blue[] __initdata = {
-  0x04, 0x84, 0x10, 0x0C, 0x41, 0x14, 0x04, 0x78,
-  0xC7, 0x0E, 0xC4, 0x24, 0xA4, 0x64, 0x0C, 0x0D,
-  0x17, 0x24, 0x0D, 0x13, 0x11, 0x07, 0x40, 0x22,
-  0x0C, 0x0C, 0x11, 0x78, 0x06, 0xF4, 0x0B, 0x0A,
-  0x47, 0x0B, 0x7C, 0x54, 0x6C, 0x0C, 0x0D, 0x9C,
-  0x73, 0x54, 0x14, 0x0C, 0x0F, 0xC7, 0x94, 0x04,
-  0x94, 0x17, 0x0A, 0x6C, 0x08, 0x0F, 0x14, 0x0B,
-  0x12, 0x68, 0x28, 0x11, 0xFA, 0x0A, 0x34, 0x09,
-  0x0A, 0x2F, 0x15, 0x19, 0x14, 0x3C, 0x06, 0xC4,
-  0x0B, 0x84, 0x24, 0x08, 0x69, 0x38, 0xBC, 0x15,
-  0x1F, 0xA0, 0x0A, 0xEC, 0x2A, 0x0C, 0x0C, 0x0C,
-  0x2C, 0xA0, 0x15, 0x07, 0x0B, 0x8C, 0xD3, 0x10,
-  0x3B, 0x5C, 0x0C, 0x04, 0x3C, 0xAC, 0x54, 0x1C,
-  0x0B, 0x5B, 0xBB, 0x0A, 0xC1, 0xBB, 0x5C, 0x3C,
-  0xBC, 0x4D, 0x74, 0x10, 0x8C, 0x8C, 0x14, 0x91,
-  0x0C, 0x74, 0x17, 0x0C, 0x48, 0x9C, 0x3C, 0x4C,
-  0x09, 0x7C, 0x05, 0xE4, 0x34, 0x38, 0x6C, 0x11,
-  0x08, 0x7C, 0x18, 0x2C, 0x9C, 0x4C, 0x34, 0x9C,
-  0x29, 0x54, 0x7C, 0x0C, 0x78, 0x18, 0x9C, 0x14,
-  0xBA, 0x30, 0x27, 0x31, 0xC2, 0x97, 0x24, 0x09,
-  0xB4, 0x04, 0x87, 0x0C, 0x14, 0x1F, 0x7C, 0x64,
-  0xB0, 0x0F, 0x45, 0x10, 0x2C, 0xD4, 0x0A, 0x04,
-  0x44, 0x1F, 0x2C, 0xCC, 0x7C, 0xD8, 0x84, 0x0C,
-  0x8C, 0x94, 0xB4, 0x1D, 0x20, 0x5C, 0x18, 0xB4,
-  0x04, 0x09, 0xBC, 0x14, 0xF4, 0x08, 0x54, 0x07,
-  0xFC, 0x6C, 0x24, 0xB4, 0x15, 0x18, 0xDB, 0x17,
-  0x17, 0x18, 0x21, 0x24
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x01, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x06, 0x65,
+    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
+    0xc3, 0x59, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
+    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
+    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x2e, 0x08,
+    0x0a, 0x06, 0x0a, 0x0b, 0x0b, 0x0f, 0x0c, 0x0f,
+    0x3d, 0x09, 0x73, 0x09, 0x0d, 0x0a, 0x10, 0x1e,
+    0x2d, 0x13, 0x86, 0xba, 0x19, 0x0a, 0x36, 0x3c,
+    0x26, 0x14, 0x0d, 0x06, 0x07, 0x0a, 0x0b, 0x0f,
+    0x4a, 0x06, 0x0a, 0x0c, 0x2b, 0x0a, 0x0b, 0x0a,
+    0x06, 0x0a, 0x0a, 0x11, 0x0b, 0x0a, 0x0a, 0x1e,
+    0x0f, 0x0d, 0x0a, 0x0b, 0x22, 0x6a, 0x72, 0x0b,
+    0x0b, 0x22, 0x90, 0xca, 0x90, 0x92, 0x3c, 0x2c,
+    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x8d,
+    0x06, 0x0e, 0x6a, 0x0e, 0x0e, 0x5b, 0x2c, 0x3e,
+    0x0e, 0x0a, 0x5a, 0x0d, 0x0e, 0x3e, 0x0a, 0x06,
+    0x2e, 0x06, 0x4e, 0x36, 0x06, 0x58, 0x24, 0x06,
+    0x3a, 0x08, 0x08, 0x07, 0x5e, 0x45, 0x0a, 0x32,
+    0x2e, 0x2a, 0x43, 0x48, 0x5f, 0x2e, 0x06, 0x06,
+    0x07, 0x24, 0x06, 0x32, 0x06, 0x06, 0x46, 0x2e,
+    0x22, 0x06, 0x06, 0x1e, 0x4c, 0x06, 0x3a, 0x22,
+    0x42, 0x34, 0x42,
 };
 
 unsigned char linux_logo[] __initdata = {
-  0xBC, 0xAC, 0x7D, 0x95, 0xAF, 0x85, 0x2C, 0x2C,
-  0xAC, 0xD9, 0x95, 0x7D, 0x95, 0xAC, 0x2C, 0xAF,
-  0x7D, 0x48, 0xB2, 0xAC, 0x85, 0xDA, 0xDA, 0x2C,
-  0x7D, 0x48, 0x21, 0x2C, 0x8D, 0x2A, 0x8A, 0xDA,
-  0x85, 0x2C, 0xD9, 0xAC, 0x2C, 0x2C, 0xD9, 0xD9,
-  0xAF, 0x85, 0x85, 0x85, 0x8D, 0xBC, 0x2A, 0x2A,
-  0xBC, 0x8C, 0xBC, 0xAC, 0x7D, 0x95, 0xAF, 0x85,
-  0x2C, 0x2C, 0xAC, 0xD9, 0x95, 0x7D, 0x95, 0xAC,
-  0x2C, 0xAF, 0x7D, 0x48, 0xB2, 0xAC, 0x85, 0xDA,
-  0xDA, 0x2C, 0x7D, 0x48, 0x21, 0x2C, 0x8D, 0x2A,
-  0xAF, 0xA1, 0x48, 0x7D, 0xAF, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xD9, 0x95, 0x7D, 0x95, 0xAC, 0xD9, 0x7D,
-  0x48, 0xE9, 0x21, 0xAF, 0xDA, 0xDA, 0x85, 0x2C,
-  0xD9, 0xD9, 0xAC, 0xDA, 0x8A, 0xDA, 0x85, 0x2C,
-  0x2C, 0xAC, 0xD9, 0xAC, 0xAF, 0xAF, 0x2C, 0x2C,
-  0x2C, 0x85, 0x2C, 0x2C, 0x85, 0xDA, 0xDA, 0xDA,
-  0xDA, 0xDA, 0xAF, 0xA1, 0x48, 0x7D, 0xAF, 0x2C,
-  0x2C, 0xAC, 0xD9, 0xD9, 0x95, 0x7D, 0x95, 0xAC,
-  0xD9, 0x7D, 0x48, 0xE9, 0x21, 0xAF, 0xDA, 0xDA,
-  0x85, 0x2C, 0xD9, 0xD9, 0xAC, 0xDA, 0x8A, 0xDA,
-  0x7D, 0x48, 0x48, 0x7D, 0x2C, 0x85, 0x2C, 0xAF,
-  0xD9, 0xD9, 0x7D, 0x95, 0xD9, 0xD9, 0xD9, 0x7D,
-  0xB2, 0x21, 0xD9, 0x85, 0xDA, 0xDA, 0x85, 0x2C,
-  0xAF, 0x2C, 0x2C, 0xDA, 0x85, 0x85, 0x2C, 0x2C,
-  0xAC, 0xD9, 0xD9, 0xAF, 0xDA, 0x85, 0x2C, 0x2C,
-  0x85, 0xDA, 0xDA, 0x85, 0x85, 0xDA, 0x85, 0x85,
-  0x85, 0xAF, 0x7D, 0x48, 0x48, 0x7D, 0x2C, 0x85,
-  0x2C, 0xAF, 0xD9, 0xD9, 0x7D, 0x95, 0xD9, 0xD9,
-  0xD9, 0x7D, 0xB2, 0x21, 0xD9, 0x85, 0xDA, 0xDA,
-  0x85, 0x2C, 0xAF, 0x2C, 0x2C, 0xDA, 0xDA, 0x85,
-  0xA1, 0xE9, 0x48, 0x95, 0x85, 0xDA, 0x85, 0xAF,
-  0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9, 0x95, 0x95,
-  0xD9, 0xAC, 0x85, 0x85, 0xDA, 0xDA, 0x85, 0x2C,
-  0xAC, 0xAC, 0x2C, 0x2C, 0x85, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xD9, 0x2C, 0x91, 0x41, 0x20, 0x6B, 0x20,
-  0x6B, 0x20, 0x6B, 0xAE, 0x2C, 0x85, 0x2C, 0x2C,
-  0xAC, 0xD9, 0xA1, 0xE9, 0x48, 0x95, 0x85, 0xDA,
-  0x85, 0xAF, 0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9,
-  0x95, 0x95, 0xD9, 0xAC, 0x85, 0x85, 0xDA, 0xDA,
-  0x85, 0x2C, 0xAC, 0xAC, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xA1, 0xA1, 0xD6, 0xAF, 0xDA, 0xDA, 0x85, 0x2C,
-  0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9, 0xD9, 0xD9,
-  0x2C, 0x2C, 0xDA, 0xDA, 0xDA, 0x85, 0x2C, 0xD9,
-  0xD9, 0xD9, 0xD9, 0xAC, 0xAC, 0xAC, 0xAF, 0xAC,
-  0x2C, 0xB2, 0x88, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x6B, 0x80, 0x85, 0x2C,
-  0xD9, 0xD6, 0xA1, 0xA1, 0xD6, 0xAF, 0xDA, 0xDA,
-  0x85, 0x2C, 0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9,
-  0xD9, 0xD9, 0x2C, 0x2C, 0xDA, 0xDA, 0xDA, 0x85,
-  0x2C, 0xD9, 0xD9, 0xD9, 0xD9, 0xAF, 0xAF, 0xAF,
-  0xD6, 0xD6, 0xD9, 0x2C, 0xDA, 0xDA, 0x2C, 0xAC,
-  0xD9, 0x7D, 0x95, 0xD9, 0xD9, 0xD9, 0xAF, 0x2C,
-  0x85, 0x85, 0x85, 0x85, 0x2C, 0x2C, 0xAC, 0xD9,
-  0xD9, 0xD9, 0xAF, 0xAF, 0x2C, 0x2C, 0xAF, 0xDA,
-  0xAE, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x41, 0xE3, 0x20, 0x6B, 0x48,
-  0xAC, 0x95, 0xD6, 0xD6, 0xD9, 0x2C, 0xDA, 0xDA,
-  0x2C, 0xAC, 0xD9, 0x7D, 0x95, 0xD9, 0xD9, 0xD9,
-  0xAF, 0x2C, 0x85, 0x85, 0x85, 0x85, 0x2C, 0x2C,
-  0xAC, 0xD9, 0xD9, 0xD9, 0xAF, 0xAF, 0xAF, 0xAF,
-  0xD9, 0xD9, 0xD9, 0x2C, 0x85, 0x85, 0x2C, 0xD9,
-  0x7D, 0x21, 0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0x85,
-  0x85, 0x85, 0x85, 0x85, 0x2C, 0xAF, 0xAF, 0xAC,
-  0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x89,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x74, 0x43, 0x80, 0x41, 0x20,
-  0x9F, 0x2C, 0xD9, 0xD9, 0xD9, 0x2C, 0x85, 0x85,
-  0x2C, 0xD9, 0x7D, 0x21, 0xD6, 0xD9, 0xAF, 0x2C,
-  0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x2C, 0xAF,
-  0xAF, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xD9, 0x7D, 0xD9, 0xAF, 0x85, 0x85, 0x2C, 0xD9,
-  0xB2, 0x21, 0x7D, 0xD9, 0xAF, 0x2C, 0x85, 0x85,
-  0x85, 0x2C, 0x2C, 0x2C, 0x2C, 0xAF, 0xAF, 0xAC,
-  0xAF, 0xAC, 0xAF, 0xAF, 0xAC, 0xAC, 0x85, 0x41,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xAE, 0x48, 0x89, 0x74, 0x41,
-  0x6B, 0xD6, 0xD9, 0x7D, 0xD9, 0xAF, 0x85, 0x85,
-  0x2C, 0xD9, 0xB2, 0x21, 0x7D, 0xD9, 0xAF, 0x2C,
-  0x85, 0x85, 0x85, 0x2C, 0x2C, 0x2C, 0x2C, 0xAF,
-  0xAF, 0xAC, 0xAF, 0xAC, 0xAC, 0x2C, 0xAF, 0xAC,
-  0x2C, 0x7D, 0xD9, 0x2C, 0xDA, 0x85, 0x2C, 0x7D,
-  0xB2, 0xD6, 0xD9, 0xAF, 0x85, 0x85, 0x85, 0x85,
-  0xAF, 0xAC, 0xAC, 0xAF, 0xAF, 0xAC, 0xAC, 0xD9,
-  0x95, 0x7D, 0x95, 0x95, 0xD9, 0xD9, 0x48, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x6B, 0xAE, 0xE6, 0x80, 0x2B, 0x88,
-  0x20, 0x33, 0xDA, 0x95, 0xD9, 0x2C, 0xDA, 0x85,
-  0x2C, 0x7D, 0xB2, 0xD6, 0xD9, 0xAF, 0x85, 0x85,
-  0x85, 0x85, 0xAF, 0xAC, 0xAC, 0xAF, 0xAF, 0xAC,
-  0xAC, 0xD9, 0x95, 0x95, 0x7D, 0x95, 0x95, 0xD9,
-  0x85, 0xD9, 0x2C, 0x85, 0xDA, 0xDA, 0xD9, 0x21,
-  0xA1, 0xD9, 0xAF, 0x2C, 0x85, 0xDA, 0x85, 0xAF,
-  0xD9, 0xD9, 0xAC, 0xAC, 0xAC, 0xD9, 0x7D, 0xD6,
-  0xD6, 0x7D, 0x95, 0xD9, 0xD9, 0x85, 0xDB, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xDB, 0xE3, 0x6B, 0x20, 0x20,
-  0x20, 0x20, 0xE9, 0xD9, 0x2C, 0x85, 0xDA, 0xDA,
-  0xD9, 0x21, 0xA1, 0xD9, 0xAF, 0x2C, 0x85, 0xDA,
-  0x85, 0xAF, 0xD9, 0xD9, 0xAC, 0xAC, 0xAC, 0xD9,
-  0x7D, 0xD6, 0xD6, 0x7D, 0x95, 0xD9, 0xD9, 0xD9,
-  0xDA, 0x2C, 0x85, 0xDA, 0xDA, 0x85, 0x95, 0x21,
-  0x21, 0xD9, 0x85, 0x85, 0x85, 0x2C, 0x2C, 0xD9,
-  0x95, 0x95, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xAC, 0xAC, 0x2C, 0xAF, 0x2C, 0x85, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x88, 0xDA, 0x85, 0xDA, 0xDA, 0x85,
-  0x95, 0x21, 0x21, 0xD9, 0x85, 0x85, 0x85, 0x2C,
-  0x2C, 0xD9, 0x95, 0x95, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xD9, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xDA, 0x2C, 0x85, 0x85, 0x2C, 0xD9, 0xD6, 0xB2,
-  0x95, 0x2C, 0x85, 0x85, 0xAF, 0xAC, 0x95, 0x95,
-  0x7D, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0x2C, 0x85,
-  0x85, 0x85, 0x85, 0x85, 0x85, 0xAC, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xAC, 0x85, 0x85, 0x2C, 0xD9,
-  0xD6, 0xB2, 0x95, 0x2C, 0x85, 0x85, 0xAF, 0xAC,
-  0x95, 0x95, 0x7D, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
-  0x2C, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-  0x85, 0x2C, 0x2C, 0x2C, 0xAC, 0x95, 0xD6, 0x7D,
-  0xD9, 0x2C, 0x2C, 0xAF, 0x95, 0x7D, 0x7D, 0x95,
-  0x95, 0xD9, 0xD9, 0x95, 0xD9, 0xD9, 0x2C, 0x85,
-  0xDA, 0xDA, 0xDA, 0x85, 0x85, 0x21, 0x20, 0x20,
-  0x6B, 0x41, 0xDB, 0x6B, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x41, 0xDB, 0xDB, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xE6, 0x2C, 0x2C, 0xAC, 0x95,
-  0xD6, 0x7D, 0xD9, 0x2C, 0x2C, 0xAF, 0x95, 0x7D,
-  0x7D, 0x95, 0x95, 0xD9, 0xD9, 0x95, 0xD9, 0xD9,
-  0x2C, 0x85, 0xDA, 0xDA, 0xDA, 0x85, 0x2C, 0x2C,
-  0x2C, 0xAF, 0xAC, 0xD9, 0x95, 0xD6, 0xD6, 0xD9,
-  0x2C, 0x2C, 0x2C, 0xD9, 0xD6, 0xD6, 0xD9, 0xAF,
-  0xAC, 0x95, 0xD6, 0x7D, 0x7D, 0xD9, 0x2C, 0x85,
-  0xDA, 0xDA, 0x2C, 0xAF, 0xAF, 0x21, 0x20, 0x20,
-  0x88, 0x2B, 0x88, 0x74, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0xAE, 0x2D, 0x2D, 0x74, 0x74, 0x88, 0x20,
-  0x20, 0x20, 0x20, 0x80, 0xAC, 0xD9, 0x95, 0xD6,
-  0xD6, 0xD9, 0x2C, 0x2C, 0x2C, 0xD9, 0xD6, 0xD6,
-  0xD9, 0xAF, 0xAC, 0x95, 0xD6, 0x7D, 0x7D, 0xD9,
-  0x2C, 0xDA, 0xDA, 0x85, 0x2C, 0xAF, 0xAF, 0xAF,
-  0x2C, 0xAF, 0xD9, 0x95, 0xD6, 0xD6, 0x95, 0xAF,
-  0x2C, 0x2C, 0xD9, 0x95, 0xD6, 0x95, 0xAF, 0x2C,
-  0xAC, 0x7D, 0x21, 0x95, 0xD9, 0x2C, 0x85, 0x85,
-  0x85, 0xAF, 0xD9, 0x95, 0xD9, 0x7D, 0x20, 0x33,
-  0x7D, 0x8A, 0x7D, 0x5B, 0x6B, 0x20, 0x20, 0x6B,
-  0xE6, 0xD9, 0x85, 0x2A, 0xDA, 0x2B, 0x41, 0x20,
-  0x20, 0x20, 0x6B, 0x74, 0xD9, 0x95, 0xD6, 0xD6,
-  0x95, 0xAF, 0x2C, 0x2C, 0xD9, 0x95, 0xD6, 0x95,
-  0xAF, 0x2C, 0xAC, 0x7D, 0x21, 0x95, 0xD9, 0x2C,
-  0x85, 0x85, 0x85, 0x2C, 0xD9, 0xD9, 0xD9, 0xD9,
-  0x85, 0xD9, 0x7D, 0x21, 0x21, 0x7D, 0xAC, 0x2C,
-  0x2C, 0xAC, 0xD9, 0x7D, 0xD9, 0xAF, 0x2C, 0x85,
-  0xAC, 0x7D, 0x7D, 0xAC, 0x85, 0xDA, 0x8A, 0xDA,
-  0x85, 0xAF, 0xD9, 0x7D, 0xD9, 0x95, 0x20, 0x91,
-  0xBC, 0x73, 0xEE, 0x7D, 0x20, 0x20, 0x20, 0x80,
-  0x4D, 0x3D, 0x73, 0x73, 0xA3, 0xD6, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x2B, 0x7D, 0x21, 0x21, 0x7D,
-  0xAC, 0x2C, 0x2C, 0xAC, 0xD9, 0x7D, 0xD9, 0xAF,
-  0x2C, 0x85, 0xAC, 0x7D, 0x7D, 0xAC, 0x85, 0xDA,
-  0x8A, 0x8A, 0x85, 0xAC, 0xD9, 0x7D, 0xD9, 0xAC,
-  0x2C, 0xD9, 0xD6, 0xB2, 0xB2, 0x7D, 0xAF, 0x85,
-  0x2C, 0xD9, 0x95, 0x95, 0xAF, 0x2C, 0x2C, 0x2C,
-  0xD9, 0xD9, 0xAC, 0x85, 0x8D, 0x2A, 0x2A, 0xDA,
-  0xAF, 0xD9, 0x95, 0x95, 0xD9, 0xAC, 0x20, 0xAF,
-  0x2C, 0xE6, 0x8D, 0x73, 0xE3, 0x20, 0x20, 0x48,
-  0x5C, 0xDA, 0x5B, 0x43, 0xBC, 0x73, 0x2B, 0x20,
-  0x20, 0x20, 0x20, 0x41, 0xD6, 0xB2, 0xB2, 0x7D,
-  0xAF, 0x85, 0x2C, 0xD9, 0x95, 0x95, 0xAF, 0x2C,
-  0x2C, 0x2C, 0xD9, 0xD9, 0xAC, 0x85, 0x8A, 0x2A,
-  0x8D, 0xDA, 0xAF, 0xD9, 0x95, 0x95, 0xD9, 0xAF,
-  0xAC, 0xD9, 0xD6, 0xB2, 0x21, 0xD9, 0x2C, 0x85,
-  0x2C, 0xD9, 0x95, 0xD9, 0xAF, 0x2C, 0x2C, 0xAC,
-  0xAC, 0xAF, 0x85, 0x8D, 0xBC, 0xBC, 0xDA, 0xD9,
-  0xD6, 0xA1, 0xA1, 0x21, 0xD9, 0xAC, 0x20, 0x2A,
-  0xCC, 0xAE, 0x9F, 0xE4, 0xAE, 0x5B, 0x74, 0xA1,
-  0xE4, 0xAE, 0x20, 0x9F, 0x89, 0xE8, 0xE6, 0x20,
-  0x20, 0x20, 0x20, 0x41, 0xD6, 0xB2, 0x21, 0xD9,
-  0x2C, 0x85, 0x2C, 0xD9, 0x95, 0xD9, 0xAF, 0x2C,
-  0x2C, 0xAC, 0xAC, 0xAF, 0x85, 0x8D, 0xBC, 0x2A,
-  0xDA, 0xD9, 0xD6, 0xA1, 0xA1, 0x21, 0xD9, 0xD9,
-  0xD9, 0x95, 0x21, 0xA1, 0x21, 0xAC, 0x85, 0x85,
-  0xAC, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C, 0xAF, 0xAC,
-  0xAF, 0x85, 0x8A, 0x2A, 0x2A, 0xDA, 0xD9, 0xA1,
-  0x48, 0xE9, 0x48, 0x21, 0x95, 0xAC, 0x20, 0x2A,
-  0xDB, 0x41, 0x74, 0xBC, 0x2B, 0x7B, 0x7B, 0x80,
-  0x73, 0x41, 0x20, 0x6B, 0x2B, 0xE8, 0x2D, 0x20,
-  0x20, 0x20, 0x20, 0x33, 0x21, 0xA1, 0x21, 0xAC,
-  0x85, 0x85, 0xAC, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C,
-  0xAF, 0xAC, 0xAF, 0x85, 0x8A, 0xBC, 0x2A, 0xDA,
-  0xD9, 0xA1, 0x48, 0xE9, 0x48, 0x21, 0xD9, 0xD9,
-  0xA1, 0xB2, 0xB2, 0x48, 0xD6, 0xAC, 0x2C, 0x2C,
-  0xD9, 0x95, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
-  0x85, 0x8A, 0x8D, 0x8D, 0x85, 0x95, 0xA1, 0x6C,
-  0x6C, 0x48, 0xD6, 0xD9, 0x2C, 0x85, 0x20, 0x2C,
-  0x89, 0x20, 0x3C, 0xB9, 0xA7, 0x63, 0xD2, 0xB9,
-  0xC6, 0x9A, 0x20, 0x20, 0x43, 0x5C, 0xE6, 0x20,
-  0x20, 0x20, 0x20, 0x33, 0xB2, 0x48, 0xD6, 0xAC,
-  0x2C, 0x2C, 0xD9, 0x95, 0xAF, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x2C, 0x85, 0x8A, 0x8D, 0x8D, 0x85, 0x95,
-  0xA1, 0x6C, 0x6C, 0x48, 0xD6, 0xD9, 0xAF, 0xAC,
-  0xA1, 0xD6, 0x7D, 0xB2, 0xD6, 0xAF, 0x85, 0x85,
-  0xD9, 0x95, 0x2C, 0x85, 0xDA, 0x85, 0x85, 0x2C,
-  0x85, 0x8A, 0x8D, 0xDA, 0xD9, 0x48, 0x81, 0x2D,
-  0x48, 0xD6, 0xD9, 0xAC, 0x2C, 0x85, 0x20, 0x2D,
-  0xEE, 0x93, 0xD1, 0xA7, 0x3E, 0x3E, 0x3A, 0x25,
-  0x56, 0xAB, 0xAA, 0xC5, 0xEE, 0xEE, 0x33, 0x20,
-  0x20, 0x20, 0x20, 0x41, 0xD9, 0xB2, 0xD6, 0xAF,
-  0x85, 0x85, 0xD9, 0x95, 0x2C, 0x85, 0xDA, 0x85,
-  0x85, 0x2C, 0x85, 0x8A, 0x8D, 0xDA, 0xD9, 0x48,
-  0x81, 0x2D, 0x48, 0xD6, 0xD9, 0xAF, 0x2C, 0x2C,
-  0xAC, 0xAF, 0xD9, 0x7D, 0xD6, 0x2C, 0x85, 0x2C,
-  0xD9, 0xD9, 0x2C, 0xDA, 0xDA, 0xDA, 0x2C, 0x2C,
-  0x85, 0x8D, 0x8D, 0x2C, 0x21, 0x2D, 0x2D, 0xE9,
-  0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0xDA, 0x20, 0xE3,
-  0xB4, 0xBE, 0xF1, 0x3E, 0x9B, 0x22, 0x56, 0xF2,
-  0xBB, 0x7F, 0x56, 0xDC, 0x8F, 0x5A, 0x5F, 0x20,
-  0x20, 0x20, 0x20, 0x6B, 0x2C, 0x7D, 0xD6, 0x2C,
-  0x85, 0x2C, 0xD9, 0xD9, 0x2C, 0xDA, 0xDA, 0xDA,
-  0x2C, 0x2C, 0x85, 0x8D, 0x8A, 0x85, 0x21, 0x2D,
-  0x2D, 0xE9, 0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0x85,
-  0x2A, 0x85, 0xAC, 0x95, 0x95, 0x2C, 0x85, 0x85,
-  0xAC, 0xAF, 0x85, 0xDA, 0xDA, 0x85, 0x2C, 0x2C,
-  0xDA, 0x8A, 0x8A, 0xAF, 0xA1, 0x2D, 0xE9, 0xD6,
-  0xD9, 0xAC, 0x85, 0x85, 0x85, 0xDA, 0x20, 0x52,
-  0x55, 0xED, 0x57, 0x3E, 0x22, 0x56, 0x37, 0xBB,
-  0xBB, 0x58, 0x7F, 0x7F, 0x56, 0x5E, 0xC5, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x2C, 0x95, 0x95, 0x2C,
-  0x85, 0x85, 0xAC, 0xAF, 0x85, 0xDA, 0xDA, 0x85,
-  0x2C, 0x2C, 0xDA, 0x8D, 0xDA, 0xAF, 0xA1, 0x2D,
-  0xE9, 0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0x85, 0x85,
-  0xCD, 0xAF, 0xD9, 0x95, 0xD9, 0x2C, 0xDA, 0x85,
-  0xAF, 0xD9, 0x85, 0xDA, 0x85, 0x2C, 0xAC, 0xAF,
-  0x85, 0x8A, 0x85, 0xD9, 0x48, 0x48, 0xB2, 0x95,
-  0x95, 0xAC, 0x2C, 0x85, 0xDA, 0xDA, 0x6B, 0xB3,
-  0x46, 0x7C, 0x2E, 0x9B, 0x22, 0x56, 0xBB, 0x37,
-  0x58, 0x58, 0xF2, 0x3A, 0x46, 0x63, 0x64, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x2D, 0x95, 0xD9, 0x2C,
-  0xDA, 0x85, 0xAF, 0xD9, 0x85, 0xDA, 0x85, 0x2C,
-  0xAC, 0xAF, 0x85, 0xDA, 0x85, 0xD9, 0x48, 0x48,
-  0xB2, 0x95, 0x95, 0xD9, 0x85, 0xDA, 0x85, 0x85,
-  0xBC, 0xB2, 0xB2, 0x7D, 0xD9, 0x2C, 0xDA, 0x85,
-  0xAF, 0xD9, 0x85, 0xDA, 0x85, 0x85, 0xAF, 0x2C,
-  0x85, 0xDA, 0x2C, 0x7D, 0xA1, 0x48, 0xB2, 0x21,
-  0xD6, 0xD9, 0x85, 0xDA, 0x85, 0xDA, 0x41, 0x51,
-  0xB7, 0xEC, 0x2E, 0x22, 0x56, 0x37, 0xBB, 0xF2,
-  0x37, 0xEA, 0x2F, 0x2F, 0x77, 0xA7, 0x38, 0x20,
-  0x20, 0x6B, 0x20, 0x20, 0x5B, 0x2C, 0xD9, 0x2C,
-  0xDA, 0x85, 0xAF, 0xD9, 0x85, 0xDA, 0x85, 0x85,
-  0xAF, 0x2C, 0xDA, 0xDA, 0x2C, 0x7D, 0xA1, 0x48,
-  0xB2, 0x21, 0xD6, 0xD9, 0x2C, 0xDA, 0x85, 0xAF,
-  0x2C, 0x2D, 0x48, 0x7D, 0xAF, 0x2C, 0x85, 0x2C,
-  0xD9, 0xAC, 0xAF, 0x85, 0x85, 0x2C, 0x2C, 0x2C,
-  0x85, 0x2C, 0xD9, 0xD6, 0xA1, 0xA1, 0x48, 0xA1,
-  0x21, 0x2C, 0xDA, 0xDA, 0x2C, 0x85, 0x41, 0x98,
-  0xA2, 0xA7, 0x6F, 0xC9, 0x37, 0xF2, 0xF2, 0x9B,
-  0xB7, 0x66, 0x60, 0x4C, 0xED, 0x84, 0x3C, 0x20,
-  0x5B, 0x2D, 0x2B, 0x6B, 0x20, 0xAF, 0xAF, 0x2C,
-  0x85, 0x2C, 0xD9, 0xAC, 0xAF, 0x85, 0x85, 0x2C,
-  0x2C, 0x2C, 0x2C, 0x85, 0xD9, 0xD6, 0xA1, 0xA1,
-  0x48, 0xA1, 0xD6, 0xAF, 0xDA, 0x8A, 0x2C, 0xD9,
-  0xB2, 0x2D, 0x48, 0x95, 0x2C, 0x2C, 0x2C, 0x85,
-  0xAC, 0xAC, 0xAF, 0x85, 0xDA, 0x85, 0xAF, 0xAC,
-  0xAF, 0x2C, 0xD9, 0xD6, 0xD6, 0xD6, 0x21, 0xD6,
-  0xD9, 0xDA, 0x8D, 0xDA, 0xAF, 0x2C, 0x20, 0x88,
-  0x42, 0x51, 0x3F, 0x2F, 0x45, 0xB7, 0x66, 0x55,
-  0x46, 0x60, 0x5D, 0x36, 0xD8, 0x71, 0x43, 0x20,
-  0x20, 0x2D, 0xB2, 0x80, 0x20, 0x2D, 0x2C, 0x2C,
-  0x2C, 0x85, 0xAC, 0xAC, 0xAF, 0x85, 0xDA, 0x85,
-  0xAF, 0xAC, 0xAC, 0xAF, 0xD9, 0xD6, 0xD6, 0xD6,
-  0x21, 0xD6, 0xD9, 0xDA, 0x8D, 0x8A, 0x2C, 0xD9,
-  0xB2, 0x48, 0xD6, 0xAC, 0xAF, 0x2C, 0x2C, 0x85,
-  0x2C, 0xAC, 0x2C, 0xDA, 0xDA, 0x85, 0xAF, 0xD9,
-  0xD9, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xAC,
-  0x85, 0x8D, 0xBC, 0xDA, 0xD9, 0xDA, 0x20, 0xE3,
-  0xDA, 0x69, 0x96, 0xB5, 0xF1, 0x68, 0x5D, 0x82,
-  0xE1, 0xBE, 0x27, 0x8D, 0x4D, 0xD3, 0x7D, 0x20,
-  0x20, 0xDB, 0xA1, 0xCA, 0x20, 0x88, 0x85, 0x2C,
-  0x2C, 0x85, 0x2C, 0xAC, 0x2C, 0xDA, 0xDA, 0x85,
-  0xAF, 0xD9, 0xAC, 0xAF, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xD9, 0xAC, 0xDA, 0x8D, 0xBC, 0xDA, 0xD9, 0x95,
-  0xD9, 0x95, 0xAC, 0x2C, 0x2C, 0x2C, 0x2C, 0x85,
-  0x85, 0xAF, 0xAF, 0x85, 0x85, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x85,
-  0x8D, 0x2A, 0x2A, 0x85, 0xD9, 0x95, 0x20, 0xDB,
-  0x8D, 0x8D, 0x99, 0xB0, 0x35, 0xE5, 0x3F, 0x35,
-  0xB9, 0x50, 0x8A, 0x4D, 0x73, 0xE8, 0xA3, 0xCC,
-  0x20, 0x20, 0x33, 0x6B, 0x20, 0x20, 0xCC, 0x85,
-  0x2C, 0x85, 0x85, 0xAF, 0xAF, 0x85, 0x85, 0x85,
-  0x2C, 0xD9, 0xD9, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x85, 0x8A, 0x2A, 0x8D, 0x2C, 0xD9, 0xD9,
-  0xAF, 0xAF, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x85,
-  0x2C, 0xAF, 0xAF, 0xAF, 0x2C, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xAC, 0xAF, 0x2C, 0x85, 0x85, 0xDA, 0xDA,
-  0x8A, 0x8A, 0x85, 0xD9, 0x2C, 0x2B, 0x20, 0xAE,
-  0xA3, 0xBC, 0x8D, 0xC8, 0xA9, 0xC7, 0x92, 0x47,
-  0x8D, 0x8D, 0x7E, 0xE4, 0xE8, 0xE8, 0x5C, 0x2C,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6B, 0xAF,
-  0x2C, 0x85, 0x2C, 0xAF, 0xAF, 0xAF, 0x2C, 0x2C,
-  0x2C, 0xAF, 0xD9, 0xAC, 0x2C, 0x2C, 0x85, 0x85,
-  0x85, 0xDA, 0x8D, 0x8A, 0x85, 0xAC, 0x95, 0xD9,
-  0xAC, 0xAC, 0xAC, 0xAC, 0x2C, 0xAF, 0xAF, 0x2C,
-  0x2C, 0xAF, 0xAF, 0xAC, 0x2C, 0xAF, 0x2C, 0xAF,
-  0xD9, 0xAC, 0x2C, 0x2C, 0x85, 0x85, 0x85, 0x85,
-  0x85, 0x2C, 0xD9, 0xD9, 0x2D, 0x6B, 0x41, 0x2A,
-  0xE8, 0xA3, 0xC8, 0x8D, 0x8A, 0x8A, 0x8A, 0x8D,
-  0x4D, 0xA3, 0x3D, 0xE8, 0xE8, 0xE8, 0xE8, 0x5C,
-  0xAE, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xDB,
-  0xDA, 0x2C, 0x2C, 0xAF, 0xAF, 0xAC, 0xAC, 0xAF,
-  0x2C, 0xAC, 0xD9, 0xAC, 0x2C, 0x2C, 0x85, 0x85,
-  0x85, 0x85, 0x85, 0x2C, 0xD9, 0x95, 0x7D, 0xD9,
-  0x7D, 0x7D, 0xD9, 0xAC, 0xAC, 0xAF, 0xAF, 0xAF,
-  0x2C, 0x2C, 0xAC, 0xAC, 0xD9, 0xAC, 0xAC, 0xD9,
-  0x95, 0xD9, 0xAC, 0xAF, 0xAF, 0xAC, 0xAF, 0xAC,
-  0xD9, 0x7D, 0x7D, 0x7D, 0x33, 0x41, 0x2D, 0xE8,
-  0xE8, 0x5C, 0xD3, 0x8D, 0x8D, 0x8D, 0x8D, 0x7E,
-  0x3D, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xDA, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x81, 0x2C, 0x2C, 0x2C, 0xAC, 0xAC, 0xAC, 0xAC,
-  0xAC, 0xD9, 0x95, 0x95, 0xAC, 0xAF, 0xAF, 0xAF,
-  0xAF, 0xAC, 0xD9, 0x95, 0x7D, 0xD6, 0xD6, 0x7D,
-  0x21, 0xD6, 0x95, 0xD9, 0xD9, 0xAC, 0xAF, 0xAF,
-  0x2C, 0xAF, 0xAC, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9,
-  0x21, 0x21, 0x7D, 0x95, 0x95, 0x7D, 0xD6, 0x21,
-  0xB2, 0xA1, 0x2C, 0x88, 0x20, 0xE3, 0xA3, 0xE8,
-  0xE8, 0xE8, 0xE4, 0xEE, 0xD3, 0x7E, 0x73, 0x5C,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0x5C, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x2C, 0xAF, 0xAF, 0xAC, 0xD9, 0xD9, 0xD9,
-  0xD9, 0xD9, 0xD6, 0x21, 0x7D, 0x95, 0x95, 0x7D,
-  0xD6, 0xB2, 0xA1, 0xA1, 0xB2, 0xD6, 0x21, 0x21,
-  0x21, 0xD9, 0xD9, 0xD9, 0xAC, 0xAF, 0xAC, 0xAF,
-  0x2C, 0x2C, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9, 0x95,
-  0x7D, 0xB2, 0xD6, 0x95, 0xD9, 0x95, 0xD6, 0xA1,
-  0xA1, 0xAF, 0x5B, 0x20, 0x20, 0xD6, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0x5C, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0x48, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0xE3, 0x8A, 0x2C, 0xAC, 0xAC, 0xD9, 0xD9,
-  0xD9, 0x95, 0xD6, 0xB2, 0xD6, 0x95, 0xD9, 0x95,
-  0x21, 0xB2, 0xA1, 0xB2, 0xD6, 0xD6, 0xD6, 0xA1,
-  0xD9, 0x2C, 0x2C, 0x2C, 0xAF, 0xAF, 0xAC, 0xAF,
-  0x2C, 0x2C, 0xAF, 0xAC, 0xD9, 0xAC, 0xD9, 0xD9,
-  0xD9, 0x95, 0xAC, 0x2C, 0x2C, 0xAC, 0x95, 0x7D,
-  0xD9, 0x91, 0x20, 0x20, 0xE3, 0xA3, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0x85, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x2B, 0x8A, 0xAF, 0xAC, 0xD9, 0xAC,
-  0xD9, 0xD9, 0xD9, 0x95, 0xAC, 0x2C, 0x2C, 0xAC,
-  0x95, 0x7D, 0x95, 0x95, 0xD9, 0x95, 0x7D, 0x21,
-  0x2C, 0xDA, 0xDA, 0x85, 0x2C, 0xAF, 0xAF, 0xAF,
-  0xAF, 0xAF, 0x2C, 0xAF, 0xAF, 0xAC, 0xAC, 0xAC,
-  0xD9, 0xAF, 0x85, 0x85, 0x2C, 0xAF, 0xD9, 0xAF,
-  0x48, 0x20, 0x20, 0x20, 0xE6, 0xA3, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0x5C,
-  0xE4, 0x73, 0x41, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x2B, 0xDA, 0xAF, 0xAF, 0xAC,
-  0xAC, 0xAF, 0xD9, 0x2C, 0x85, 0x85, 0x2C, 0xAF,
-  0xD9, 0xD9, 0xAC, 0xAF, 0xAC, 0xD9, 0xD9, 0xD9,
-  0x85, 0xDA, 0xDA, 0x85, 0x2C, 0x2C, 0xAC, 0xAF,
-  0xAF, 0xAF, 0xAF, 0x2C, 0xAF, 0xAF, 0xAC, 0xAC,
-  0xAF, 0x2C, 0x2C, 0x2C, 0xAC, 0x95, 0x95, 0xA1,
-  0x20, 0x20, 0x20, 0x20, 0xE9, 0x8C, 0x5C, 0xE8,
-  0xE8, 0xE8, 0xE8, 0x3D, 0x73, 0x73, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE4, 0x73, 0x73, 0x73, 0xCD,
-  0x7E, 0xA3, 0x74, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x24, 0x85, 0xAF, 0xAF,
-  0xAC, 0xAC, 0xAC, 0xAF, 0x85, 0x2C, 0xAC, 0x95,
-  0x95, 0xD9, 0xAC, 0xAC, 0xAC, 0xD9, 0xAC, 0xAF,
-  0x8A, 0x8A, 0xDA, 0xDA, 0x85, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x2C, 0x2C, 0xAF, 0xAF, 0xAC, 0xAF, 0xAC,
-  0xAC, 0xAF, 0xAF, 0xD9, 0xD6, 0xD6, 0x2C, 0x88,
-  0x20, 0x20, 0x20, 0x88, 0xB2, 0xDA, 0x7E, 0x73,
-  0xE8, 0xE8, 0xE8, 0x3D, 0x73, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xA3, 0xCD, 0xD3, 0x2A, 0x2A,
-  0x2A, 0x8C, 0x8D, 0x88, 0x20, 0xE3, 0x6B, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x41, 0x85, 0xAF, 0xAC,
-  0xAC, 0xAC, 0xAC, 0xAF, 0xAC, 0xD9, 0x7D, 0xD6,
-  0x7D, 0x7D, 0xD9, 0x95, 0xD9, 0xAC, 0xAC, 0xAF,
-  0xD3, 0x8D, 0xDA, 0xDA, 0x85, 0x85, 0x2C, 0x2C,
-  0x2C, 0xAF, 0xAF, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xAF, 0xAF, 0xAC, 0xD9, 0x95, 0x7D, 0xAC, 0x20,
-  0x20, 0x20, 0x20, 0xDB, 0x2C, 0xA3, 0x5C, 0xE8,
-  0xE8, 0xE8, 0xE8, 0x5C, 0x3D, 0x3D, 0xE8, 0xE8,
-  0xE8, 0xE4, 0xE8, 0xE8, 0xE8, 0xE4, 0x73, 0xEE,
-  0xD3, 0x2A, 0xEE, 0xAC, 0x20, 0x33, 0x2B, 0xE3,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x9F, 0xAF, 0xD9,
-  0xD9, 0xAC, 0xAF, 0xAF, 0xAC, 0xD9, 0x95, 0x7D,
-  0xD9, 0x95, 0x95, 0x95, 0x95, 0xD9, 0xAF, 0xAF,
-  0x7E, 0x85, 0x85, 0x2C, 0x85, 0x85, 0x85, 0x2C,
-  0x2C, 0x2C, 0xAF, 0xD9, 0xD9, 0x95, 0xD9, 0xAC,
-  0xAC, 0xAF, 0xAF, 0xAC, 0xAC, 0xAC, 0x91, 0x20,
-  0x33, 0xE3, 0x41, 0x48, 0x73, 0x5C, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xA3, 0xD6, 0x6C, 0x85, 0xE8,
-  0xDA, 0xAE, 0xB2, 0xA3, 0x5C, 0xE8, 0xE8, 0xE8,
-  0x3D, 0xEE, 0x4D, 0xA3, 0x24, 0x20, 0x6B, 0xDB,
-  0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x85, 0x95,
-  0xD9, 0xD9, 0xAC, 0xAF, 0xAF, 0xAC, 0xD9, 0xAC,
-  0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xAC, 0xD9, 0xAC,
-  0x8A, 0xD9, 0xAC, 0xD9, 0xAC, 0xAC, 0x2C, 0x2C,
-  0xAF, 0xAF, 0xAF, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xAF, 0xAF, 0xAF, 0xAC, 0xAC, 0x85, 0x33, 0x20,
-  0xCC, 0x20, 0xE3, 0xA3, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xA3, 0xD9, 0x81, 0xAC, 0xDA, 0x2D, 0x5C,
-  0x48, 0x41, 0x88, 0x74, 0x21, 0xA3, 0xE8, 0xE8,
-  0xE8, 0xE8, 0x73, 0x8C, 0x8A, 0x20, 0x20, 0x20,
-  0xDB, 0x33, 0x20, 0x20, 0x20, 0x20, 0xE6, 0xD9,
-  0xD9, 0xAC, 0xAC, 0xAF, 0xAC, 0xAF, 0xAC, 0xAF,
-  0xAF, 0xAC, 0xD9, 0xAF, 0xD9, 0xAC, 0xAC, 0xAF,
-  0x85, 0xD9, 0x95, 0xD9, 0x95, 0xD9, 0xD9, 0xAC,
-  0xAF, 0xAC, 0xAF, 0xAF, 0x2C, 0xAF, 0x2C, 0x2C,
-  0xAF, 0xAF, 0xAF, 0xAC, 0xAC, 0x2C, 0x20, 0x5B,
-  0x33, 0x20, 0xD6, 0xE8, 0xE8, 0xE8, 0xE8, 0x73,
-  0xAF, 0x2D, 0xD9, 0xDA, 0xB2, 0x81, 0x81, 0xE4,
-  0xA1, 0x91, 0x2B, 0x88, 0x33, 0x80, 0xAF, 0x73,
-  0xE8, 0xE8, 0xE8, 0x5C, 0xA3, 0x80, 0x41, 0xCC,
-  0x2B, 0xCC, 0x20, 0x20, 0x20, 0x20, 0x88, 0xDA,
-  0x2C, 0x2C, 0x2C, 0xAF, 0xAF, 0xAC, 0xAC, 0xAF,
-  0xAF, 0xAF, 0xAF, 0xAC, 0xAF, 0xAF, 0xAF, 0x2C,
-  0x85, 0xD9, 0xD9, 0xD9, 0xD9, 0xAC, 0xAC, 0xD9,
-  0xD9, 0xD9, 0xAC, 0x2C, 0x2C, 0x2C, 0x85, 0x85,
-  0x85, 0x2C, 0x2C, 0xAF, 0x2C, 0x91, 0x20, 0xAE,
-  0x20, 0xDB, 0x3D, 0xE8, 0xE8, 0x5C, 0xB2, 0x80,
-  0xB2, 0xAF, 0x48, 0xB2, 0x48, 0x89, 0x89, 0x3D,
-  0x21, 0x48, 0x6C, 0x2D, 0x2B, 0x41, 0xE3, 0xAE,
-  0xD9, 0x5C, 0xE8, 0xE8, 0xE8, 0x95, 0x33, 0x80,
-  0xAE, 0x33, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x95,
-  0x85, 0x2C, 0x85, 0x2C, 0x2C, 0xAF, 0x2C, 0x2C,
-  0x2C, 0xAF, 0xAC, 0xAF, 0xAF, 0x2C, 0x2C, 0x2C,
-  0xDA, 0xAF, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C, 0x2C,
-  0xAC, 0xD9, 0xAC, 0xAF, 0x2C, 0x85, 0x2C, 0x85,
-  0x85, 0x2C, 0x2C, 0x2C, 0x8A, 0x41, 0xDB, 0x33,
-  0x20, 0x95, 0xE8, 0xE8, 0xE8, 0xA3, 0xDB, 0x88,
-  0xDB, 0x80, 0xD6, 0x7E, 0x85, 0x2D, 0xE6, 0x5C,
-  0x21, 0x48, 0xD9, 0x7E, 0xD6, 0x2B, 0xCC, 0xAC,
-  0x85, 0xBC, 0xE8, 0xE8, 0xE8, 0xCD, 0x88, 0x5B,
-  0x41, 0x20, 0xAE, 0x20, 0x20, 0x20, 0x20, 0x74,
-  0xDA, 0x85, 0x85, 0x85, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xAF, 0xAC, 0xD9, 0xD9, 0xAC, 0xAC, 0xAC, 0xD9,
-  0x8A, 0xAF, 0xAC, 0xAC, 0x2C, 0x85, 0x2C, 0xAF,
-  0xD9, 0xD9, 0xAF, 0xAF, 0xAF, 0x2C, 0xAF, 0x2C,
-  0x2C, 0x2C, 0x2C, 0xAF, 0x95, 0x20, 0x74, 0x20,
-  0x33, 0xA3, 0xE8, 0xE8, 0xE8, 0xE4, 0x7D, 0xCC,
-  0x6B, 0x33, 0xAE, 0x2C, 0x85, 0x2D, 0x9F, 0x73,
-  0xA1, 0x2D, 0x2C, 0xDA, 0x89, 0x48, 0xD3, 0xD9,
-  0x21, 0xA3, 0xE8, 0xE8, 0xE8, 0xE8, 0xE3, 0x20,
-  0x20, 0x20, 0xDB, 0x41, 0x20, 0x20, 0x20, 0x20,
-  0xDA, 0x2C, 0x2C, 0x2C, 0x2C, 0xAF, 0xAC, 0xAC,
-  0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0x95, 0x95, 0xD9,
-  0x2C, 0xD9, 0xD9, 0xAC, 0x2C, 0x2C, 0x85, 0xAF,
-  0xAF, 0xAF, 0xAC, 0xAC, 0xD9, 0xAC, 0xAF, 0xAC,
-  0xAC, 0x95, 0xD6, 0x7D, 0xAE, 0x88, 0x2B, 0x20,
-  0x6C, 0xE8, 0xE8, 0xE8, 0x73, 0xEE, 0x73, 0x2C,
-  0x89, 0x2B, 0x41, 0x33, 0xCC, 0xCC, 0x80, 0x3D,
-  0x2D, 0x74, 0x80, 0x48, 0x8D, 0x95, 0x48, 0x95,
-  0xEE, 0x5C, 0x5C, 0xE8, 0xE8, 0xE8, 0x24, 0x20,
-  0x20, 0x20, 0x5B, 0xDB, 0x20, 0x20, 0x20, 0x20,
-  0xAF, 0xAC, 0xD9, 0x95, 0xD6, 0xD6, 0xD6, 0x7D,
-  0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0xD9, 0xAC,
-  0xAC, 0xD9, 0xD9, 0xAC, 0x2C, 0x2C, 0x2C, 0xAF,
-  0xAC, 0xAC, 0xAC, 0xAC, 0xD9, 0xAC, 0xAC, 0xD9,
-  0xD6, 0x48, 0xE9, 0x95, 0x20, 0x2B, 0x41, 0x6B,
-  0x8D, 0xE8, 0xE8, 0xCD, 0x2B, 0x2B, 0x2C, 0x73,
-  0xCD, 0x48, 0xCA, 0x5B, 0x41, 0x5B, 0x74, 0xDA,
-  0x80, 0xE6, 0xC8, 0x85, 0xA1, 0x7D, 0x8D, 0x3D,
-  0x7E, 0xE9, 0x7D, 0xEE, 0xE8, 0xE8, 0x81, 0x20,
-  0x20, 0x20, 0xE3, 0xE3, 0x20, 0x20, 0x20, 0x20,
-  0x2D, 0xD9, 0xD6, 0x48, 0x6C, 0xE9, 0xA1, 0xD6,
-  0xD9, 0xD9, 0xAC, 0xD9, 0xD9, 0x95, 0xAC, 0x2C,
-  0x2C, 0x2C, 0x2C, 0xD9, 0xAC, 0x2C, 0x2C, 0x2C,
-  0xAF, 0x2C, 0xAF, 0xD9, 0xAC, 0xAF, 0xAF, 0x95,
-  0xB2, 0xE9, 0x21, 0x2B, 0x41, 0x2B, 0x20, 0x5B,
-  0x3D, 0xE8, 0xE8, 0x8D, 0x2B, 0x88, 0x5B, 0xE6,
-  0xBC, 0x73, 0x85, 0x89, 0x80, 0x5B, 0xE3, 0xAE,
-  0x2C, 0x8A, 0xD6, 0xB2, 0x2C, 0xA3, 0xA3, 0xD9,
-  0xA1, 0x2C, 0x85, 0x8D, 0xE8, 0xE8, 0x48, 0x20,
-  0x20, 0x20, 0xE3, 0x88, 0x20, 0x20, 0x20, 0x20,
-  0xAE, 0xD9, 0xB2, 0xE9, 0x6C, 0x48, 0xD6, 0xD9,
-  0x2C, 0x85, 0x2C, 0xD9, 0x7D, 0xD9, 0x2C, 0x85,
-  0x8D, 0x85, 0x2C, 0xAC, 0xAF, 0x2C, 0x2C, 0x85,
-  0x2C, 0x2C, 0xAF, 0xAC, 0xAC, 0xAF, 0xAF, 0xD9,
-  0xB2, 0x48, 0xB2, 0x20, 0x20, 0xCC, 0x20, 0x9F,
-  0xE8, 0xE8, 0xE8, 0xCD, 0x48, 0x89, 0xDB, 0x88,
-  0x2B, 0xE9, 0xCD, 0x2A, 0x48, 0x80, 0xAE, 0xAE,
-  0x7D, 0x48, 0x21, 0xEE, 0x3D, 0x2C, 0x48, 0x85,
-  0x2C, 0x95, 0x7D, 0x8C, 0xE8, 0xE8, 0xB2, 0x20,
-  0x20, 0x20, 0xDB, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0xDB, 0x2C, 0xB2, 0x48, 0x48, 0x7D, 0xD9, 0xAF,
-  0x85, 0x8A, 0x85, 0x7D, 0xB2, 0x95, 0x85, 0xDA,
-  0xD3, 0x85, 0xAF, 0xAC, 0x2C, 0x85, 0x85, 0x2C,
-  0xAC, 0xAC, 0xAC, 0xD9, 0xD9, 0xAC, 0x2C, 0x2C,
-  0xD9, 0xAC, 0x5B, 0x20, 0x20, 0xAE, 0x20, 0x2D,
-  0xE8, 0xE8, 0xE8, 0x7E, 0xD6, 0x48, 0xE9, 0xAE,
-  0x88, 0x5B, 0x80, 0x6C, 0xAE, 0xCA, 0x91, 0xE9,
-  0x43, 0x9F, 0xE6, 0x2C, 0x48, 0x21, 0xBC, 0x95,
-  0x95, 0xD6, 0x21, 0x7E, 0xE8, 0xE8, 0x7D, 0x20,
-  0x20, 0x20, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x6B, 0xDA, 0xD9, 0x48, 0xB2, 0xD9, 0x2C, 0x85,
-  0xDA, 0xDA, 0x2C, 0xA1, 0x48, 0xAC, 0xDA, 0x8D,
-  0x2A, 0xAC, 0x7D, 0x95, 0xAF, 0x85, 0x2C, 0x2C,
-  0xAC, 0xD9, 0x95, 0x7D, 0x95, 0xAC, 0x2C, 0xAF,
-  0x7D, 0xD6, 0x20, 0x20, 0x88, 0x9F, 0x20, 0xA1,
-  0xE8, 0xE8, 0xE8, 0xA3, 0xD6, 0x6C, 0xB2, 0x2C,
-  0x89, 0xE3, 0x88, 0xDB, 0xCC, 0x24, 0x7D, 0xEE,
-  0xB2, 0xCC, 0xAE, 0x2D, 0xDA, 0x2C, 0xD6, 0x2C,
-  0xB2, 0x2D, 0xD6, 0xEE, 0xE8, 0xE8, 0x95, 0x20,
-  0x20, 0x20, 0xDB, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x6B, 0xDA, 0x95, 0xA1, 0xB2, 0xAC, 0x85, 0x85,
-  0xDA, 0x2C, 0x95, 0xA1, 0x21, 0x2C, 0x8A, 0x2A,
-  0xAF, 0xA1, 0x48, 0xD6, 0xAF, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xD9, 0x95, 0x7D, 0x95, 0xAC, 0xD9, 0x7D,
-  0x48, 0xE6, 0x20, 0x20, 0x33, 0x89, 0x6B, 0x95,
-  0xE8, 0xE8, 0xE8, 0xA3, 0x21, 0x48, 0xAF, 0xAF,
-  0x9F, 0xE9, 0x43, 0x33, 0x33, 0x2D, 0xDA, 0xCD,
-  0xD6, 0xAE, 0x85, 0x2C, 0x7D, 0xD6, 0x91, 0xB8,
-  0xD4, 0x48, 0x7D, 0xA3, 0xE8, 0xE8, 0x95, 0x20,
-  0x20, 0x33, 0xE3, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x2C, 0x48, 0x6C, 0xB2, 0xAF, 0xDA, 0xDA,
-  0x85, 0xAF, 0xD9, 0x95, 0xAC, 0xDA, 0x8A, 0xDA,
-  0x7D, 0x48, 0x48, 0x7D, 0x2C, 0x85, 0x2C, 0xAF,
-  0xD9, 0xD9, 0x7D, 0x95, 0xD9, 0xD9, 0x95, 0xD6,
-  0x21, 0x24, 0x20, 0x20, 0x20, 0x5B, 0xDB, 0xAC,
-  0xE8, 0xE8, 0xE8, 0x3D, 0x7D, 0x48, 0xE6, 0x2D,
-  0x85, 0x81, 0x81, 0x48, 0xAE, 0xCA, 0x89, 0xCC,
-  0xAE, 0xDB, 0x2D, 0x95, 0x21, 0xCC, 0xDB, 0xAE,
-  0x91, 0xE9, 0x7D, 0x73, 0xE8, 0xE8, 0x48, 0x20,
-  0x6B, 0x74, 0x41, 0x88, 0x6B, 0x20, 0x20, 0x20,
-  0x6B, 0x95, 0xB2, 0xD6, 0xD9, 0x85, 0xDA, 0xDA,
-  0xDA, 0x2C, 0xAF, 0xAF, 0x2C, 0xDA, 0xDA, 0x85,
-  0xA1, 0xE9, 0x48, 0x95, 0x85, 0xDA, 0x85, 0xAC,
-  0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9, 0xD9, 0x95,
-  0x95, 0x6C, 0x41, 0x93, 0x93, 0x41, 0xDB, 0x95,
-  0xE8, 0xE8, 0xE8, 0x3D, 0x95, 0xD4, 0x6C, 0x21,
-  0x2D, 0x95, 0xCD, 0x2C, 0xD6, 0xD9, 0x6C, 0x91,
-  0x89, 0x7D, 0xAC, 0x2A, 0x8D, 0xE6, 0xCC, 0x88,
-  0x74, 0x48, 0xD9, 0xE4, 0xE8, 0xE8, 0xE6, 0x88,
-  0x2B, 0x88, 0x20, 0x33, 0xDB, 0x2B, 0xDB, 0x20,
-  0x91, 0x7D, 0xD9, 0xD9, 0x85, 0x85, 0xDA, 0xDA,
-  0x85, 0xAF, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xA1, 0xA1, 0xD6, 0xAF, 0x85, 0xDA, 0x85, 0x2C,
-  0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9, 0xD9, 0xAC,
-  0x2C, 0x47, 0x87, 0x3E, 0x3E, 0xA4, 0x7B, 0x80,
-  0xA3, 0xE8, 0xE8, 0x5C, 0x7D, 0x48, 0xE6, 0xD9,
-  0xBC, 0xEE, 0x7D, 0x43, 0xD6, 0x21, 0x43, 0x6C,
-  0x43, 0x7D, 0x7D, 0xB2, 0x8A, 0xEE, 0x2C, 0xCA,
-  0xAE, 0x48, 0x2C, 0xE4, 0xE8, 0x5C, 0xCC, 0x88,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x91, 0xE3,
-  0x21, 0xD9, 0x2C, 0x2C, 0xDA, 0xDA, 0xDA, 0x85,
-  0x2C, 0xAC, 0xD9, 0xD9, 0xAC, 0xAF, 0xAF, 0xAF,
-  0xD6, 0x7D, 0xD9, 0x2C, 0xDA, 0xDA, 0x85, 0xAC,
-  0xD9, 0x7D, 0x7D, 0xD9, 0xD9, 0xD9, 0x2C, 0x2C,
-  0xB8, 0x9C, 0xEC, 0x62, 0x6F, 0x62, 0x70, 0x3C,
-  0xAE, 0xCD, 0xE8, 0xE8, 0x8C, 0x7D, 0xC8, 0x3D,
-  0x8A, 0xE9, 0x2D, 0x9E, 0xA1, 0xD6, 0x48, 0x73,
-  0x81, 0xD6, 0xD6, 0xAE, 0x5B, 0x2D, 0xA3, 0xA3,
-  0x21, 0x21, 0xCD, 0xE8, 0xC0, 0x56, 0x31, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x33, 0xCC, 0xDB,
-  0x42, 0x85, 0x85, 0x85, 0x85, 0x85, 0x2C, 0x2C,
-  0xAC, 0xD9, 0xD9, 0xD9, 0xAC, 0xAF, 0xAF, 0xAF,
-  0xD9, 0x95, 0xAC, 0x2C, 0x85, 0x85, 0x2C, 0xD9,
-  0x7D, 0xD6, 0xD6, 0xD9, 0xAC, 0xAF, 0x8A, 0xBC,
-  0xC2, 0x68, 0x2E, 0x4B, 0xC9, 0x8B, 0x62, 0x87,
-  0x3C, 0x74, 0xBC, 0xE8, 0xE8, 0xE4, 0xEE, 0xA1,
-  0xE9, 0x21, 0xE6, 0x89, 0x48, 0x7D, 0xB2, 0x5C,
-  0x6C, 0x7D, 0x21, 0x80, 0xE3, 0x33, 0xCC, 0x2C,
-  0x3D, 0x3D, 0xE8, 0xE8, 0xEC, 0xCB, 0x5A, 0x6B,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x88, 0x41, 0x51,
-  0x49, 0x28, 0x85, 0x85, 0x85, 0x85, 0x2C, 0xAF,
-  0xAC, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xD9, 0x95, 0xD9, 0x2C, 0x85, 0x85, 0x2C, 0xD9,
-  0xB2, 0xB2, 0x2C, 0x2A, 0x79, 0x79, 0x97, 0x44,
-  0xED, 0x29, 0x32, 0x62, 0x4B, 0x62, 0x6F, 0x22,
-  0xF3, 0x6B, 0x33, 0x85, 0x73, 0xE4, 0x2D, 0x2B,
-  0xCC, 0x9F, 0xDA, 0xBC, 0x48, 0xD6, 0xA1, 0xE4,
-  0xE9, 0xD6, 0xD9, 0x2A, 0xB2, 0x2B, 0x2B, 0xA1,
-  0xB8, 0xE8, 0xE8, 0xE8, 0xEC, 0x3E, 0x30, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x6B, 0x54, 0xDC,
-  0xC9, 0x53, 0xBC, 0x2C, 0x2C, 0x2C, 0xAF, 0xAF,
-  0xAF, 0xAC, 0xAF, 0xAC, 0xAC, 0x2C, 0xAF, 0xAC,
-  0x2C, 0x7D, 0xD9, 0x2C, 0x85, 0xDA, 0xAF, 0x7D,
-  0xB2, 0xAC, 0xC6, 0xBA, 0x4C, 0xEF, 0xA7, 0xEF,
-  0xEC, 0x7A, 0x62, 0x4B, 0x62, 0x4B, 0x8B, 0x4B,
-  0x3A, 0x52, 0x20, 0x6B, 0x21, 0x73, 0xAC, 0x2B,
-  0x41, 0x33, 0x48, 0x67, 0xA1, 0xD6, 0xD6, 0x5C,
-  0xE9, 0xD6, 0x2C, 0xEE, 0xB2, 0x9F, 0x8A, 0x95,
-  0x4D, 0xE8, 0xE8, 0x3D, 0x7A, 0x57, 0xD1, 0x7B,
-  0x20, 0x20, 0x20, 0x20, 0x6B, 0xCF, 0xBA, 0x3E,
-  0x3E, 0xD0, 0xBC, 0xAC, 0xAC, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xD9, 0x95, 0x95, 0x7D, 0x95, 0x95, 0xD9,
-  0x85, 0xD9, 0xAF, 0xDA, 0xDA, 0x85, 0xAC, 0x21,
-  0xB2, 0x2A, 0xBA, 0x57, 0x2E, 0x2E, 0x2E, 0x7A,
-  0x32, 0x62, 0x8B, 0x4B, 0x8B, 0x4B, 0x4B, 0x4B,
-  0xC9, 0x4A, 0x5F, 0x20, 0x20, 0x2D, 0xA3, 0xD9,
-  0xCA, 0x88, 0xDB, 0x24, 0x48, 0x7D, 0xB2, 0xE4,
-  0x2D, 0x7D, 0x7D, 0x81, 0xA1, 0xDA, 0x21, 0xDA,
-  0xE4, 0xE8, 0xEE, 0xF1, 0x2E, 0x57, 0x82, 0x76,
-  0x52, 0x4F, 0x4F, 0x98, 0xDE, 0xB5, 0xEC, 0x2E,
-  0x3E, 0x6D, 0x85, 0x2C, 0xAC, 0xAC, 0xD9, 0xD9,
-  0x95, 0xD6, 0x7D, 0x7D, 0x95, 0xD9, 0xD9, 0xD9,
-  0xDA, 0x2C, 0x85, 0xDA, 0xDA, 0x2C, 0x95, 0xB2,
-  0x21, 0xB8, 0xED, 0x2E, 0x3E, 0x4B, 0xC9, 0x4B,
-  0x8B, 0x62, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x22, 0x6F, 0xCE, 0x20, 0x20, 0x20, 0x80, 0xCD,
-  0xDA, 0x2D, 0x2B, 0xDB, 0xE9, 0xD6, 0x95, 0x5C,
-  0x2D, 0x7D, 0x7D, 0xAF, 0xAF, 0xAC, 0xEE, 0x5C,
-  0xE8, 0xE8, 0xEB, 0x25, 0x7A, 0x57, 0x39, 0xE1,
-  0x83, 0xA8, 0x55, 0x83, 0x82, 0x57, 0x32, 0x8B,
-  0x62, 0x6D, 0xEB, 0x95, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xD9, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xDA, 0x2C, 0x85, 0x85, 0x85, 0xAC, 0xD6, 0x21,
-  0x95, 0x6E, 0xED, 0x57, 0x62, 0x4B, 0x8B, 0x4B,
-  0x4B, 0x62, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x62,
-  0x62, 0x62, 0x25, 0x3C, 0x20, 0x20, 0x20, 0xE3,
-  0x2A, 0xBC, 0x7D, 0xCA, 0x6C, 0xD6, 0x95, 0x3D,
-  0x81, 0x7D, 0xD6, 0xD6, 0xDA, 0x73, 0xE8, 0xE8,
-  0xE8, 0x4D, 0x94, 0xED, 0x72, 0x3A, 0xF1, 0xA7,
-  0x39, 0xED, 0x39, 0xEF, 0x57, 0x32, 0x8B, 0x4B,
-  0x62, 0x62, 0xA6, 0x2A, 0xD9, 0xD9, 0xD9, 0xD9,
-  0x2C, 0x2C, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-  0x85, 0x2C, 0x2C, 0xAF, 0xAC, 0x95, 0x21, 0x7D,
-  0xAC, 0x8C, 0x46, 0xC4, 0x62, 0x8B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x62, 0xC9, 0x30, 0x7B, 0x20, 0x20, 0x20,
-  0x41, 0x4D, 0x3D, 0x85, 0x48, 0x21, 0xDA, 0x3D,
-  0xE9, 0xD6, 0xD9, 0xCD, 0x5C, 0xE8, 0xE8, 0xE8,
-  0xE8, 0x4D, 0x71, 0x46, 0xEC, 0x2E, 0x72, 0xEC,
-  0x29, 0x29, 0x7C, 0x29, 0x2E, 0x4B, 0x4B, 0x62,
-  0x62, 0x4B, 0x3A, 0xAD, 0xE2, 0xAF, 0xD9, 0xD9,
-  0x2C, 0xDA, 0xDA, 0xDA, 0xDA, 0x85, 0x2C, 0x2C,
-  0x2C, 0xAF, 0xAC, 0xD9, 0x95, 0xD6, 0xD6, 0xD9,
-  0x2C, 0x8C, 0xBA, 0x7C, 0x2E, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x62, 0xC9, 0xDC, 0x34, 0x20, 0x20, 0x20,
-  0x20, 0xAC, 0xE8, 0x5C, 0x8C, 0xBC, 0xE4, 0xE8,
-  0xEE, 0x2A, 0xA3, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE4, 0x7E, 0x65, 0x46, 0x29, 0x62, 0x62, 0x2E,
-  0x2E, 0x72, 0x2E, 0x2E, 0x32, 0x4B, 0x4B, 0x62,
-  0x4B, 0x4B, 0x4B, 0x32, 0x61, 0x9D, 0x2C, 0xD9,
-  0x2C, 0x85, 0xDA, 0x85, 0x2C, 0xAF, 0xAF, 0xAF,
-  0x2C, 0xAC, 0xD9, 0x95, 0xD6, 0x7D, 0x95, 0xAC,
-  0x2C, 0xDA, 0x40, 0x7C, 0x2E, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x62, 0x62, 0x22, 0xB7, 0xCE, 0x20, 0x20,
-  0x20, 0x95, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0x5C,
-  0x3D, 0xE9, 0x9A, 0x46, 0x7C, 0x32, 0x8B, 0x62,
-  0x4B, 0x8B, 0x8B, 0x4B, 0x4B, 0x4B, 0x4B, 0x62,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x62, 0x61, 0x4E, 0xDA,
-  0x85, 0x85, 0x85, 0x2C, 0xD9, 0xD9, 0xD9, 0xD9,
-  0x85, 0xD9, 0x7D, 0x21, 0x21, 0xD6, 0xAC, 0x2C,
-  0x2C, 0xDA, 0xDD, 0x77, 0x8B, 0x62, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x3E, 0x8B, 0x32, 0xC9, 0x22, 0x68, 0x88, 0x33,
-  0xA1, 0x73, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0x5C, 0x5C, 0x5C, 0x5C, 0x3D,
-  0x89, 0x20, 0x54, 0x23, 0x29, 0x2E, 0x4B, 0x62,
-  0x4B, 0x3E, 0x4B, 0x62, 0x4B, 0x4B, 0x4B, 0x8B,
-  0x8B, 0xC9, 0x6F, 0x4B, 0x8B, 0x4B, 0x78, 0xE2,
-  0x8A, 0x8A, 0x85, 0xAC, 0xD9, 0x7D, 0xD9, 0xAC,
-  0x2C, 0xD9, 0xD6, 0xB2, 0x21, 0x7D, 0xAF, 0x85,
-  0x2C, 0xDA, 0x40, 0xEF, 0x62, 0x62, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x8B, 0x4B, 0xC9, 0x63, 0xB4, 0x5C,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0x5C, 0x5C, 0xCD, 0xAE,
-  0x20, 0x20, 0xCE, 0xE1, 0x57, 0x32, 0x4B, 0x4B,
-  0x8B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x8B, 0x4B, 0x62, 0x4B, 0x62, 0x2E, 0x61, 0x28,
-  0x8D, 0xDA, 0xAF, 0xD9, 0x95, 0x95, 0xD9, 0xAF,
-  0xAF, 0xD9, 0xD6, 0xB2, 0x21, 0xD9, 0x2C, 0x85,
-  0xAF, 0xEB, 0xE1, 0x57, 0x2E, 0x62, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x3E, 0x9B, 0x31, 0x6E,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0x5C, 0xE8, 0xE8, 0xE8, 0x3D, 0x7D, 0x33, 0x6B,
-  0x20, 0x20, 0x34, 0x23, 0x29, 0x3E, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x3E, 0x62, 0x62, 0x2E, 0xC4, 0x49, 0xD5,
-  0xDA, 0xD9, 0xD6, 0xA1, 0xA1, 0x21, 0xD9, 0xD9,
-  0xD9, 0x95, 0x21, 0x48, 0xD6, 0xAC, 0x85, 0x85,
-  0xAF, 0xB6, 0x5D, 0x2E, 0x32, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x62, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x62, 0x2E, 0x45, 0xDE,
-  0xDA, 0x5C, 0xE8, 0x5C, 0xE8, 0xE8, 0x5C, 0xE8,
-  0x5C, 0x5C, 0xA3, 0xAC, 0x2B, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x34, 0x23, 0x29, 0x62, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x62, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x3E, 0x3E, 0x63, 0x40, 0x97, 0x28, 0xDA,
-  0xD9, 0xA1, 0x48, 0xE9, 0x48, 0x21, 0xD9, 0xD9,
-  0xA1, 0xB2, 0xB2, 0xA1, 0x21, 0xAC, 0x85, 0x2C,
-  0xDA, 0x36, 0x77, 0x72, 0x62, 0x8B, 0x62, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x3E, 0xEC, 0x2F, 0x51,
-  0xE3, 0xAE, 0x48, 0x2C, 0xDA, 0xDA, 0x85, 0xAC,
-  0x48, 0x9E, 0x88, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x41, 0xA0, 0x23, 0x72, 0x2E, 0x4B, 0x4B,
-  0x4B, 0x62, 0x62, 0x4B, 0x4B, 0x4B, 0x2E, 0x8B,
-  0xF0, 0x4C, 0x40, 0xC2, 0x90, 0x8D, 0x85, 0xD9,
-  0xA1, 0x6C, 0x6C, 0x48, 0xD6, 0xD9, 0xAF, 0xAC,
-  0xA1, 0xD6, 0xD6, 0xB2, 0xD6, 0xAC, 0x85, 0x85,
-  0x4D, 0xBE, 0x39, 0x4C, 0x57, 0x2E, 0x2E, 0x2E,
-  0x3E, 0x3E, 0x62, 0x3E, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x8B, 0x8B, 0x57, 0x60, 0x76,
-  0x52, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x3C, 0xA0, 0x23, 0x7C, 0x2E, 0x4B, 0x4B,
-  0x8B, 0x62, 0x4B, 0x4B, 0x3E, 0x7A, 0xF0, 0x29,
-  0x36, 0x97, 0xBC, 0x8A, 0x8D, 0xDA, 0xD9, 0x48,
-  0x81, 0x2D, 0x48, 0xD6, 0xD9, 0xAF, 0x2C, 0x2C,
-  0xAC, 0xAF, 0xD9, 0x7D, 0x7D, 0x2C, 0x85, 0x85,
-  0x85, 0xB4, 0x66, 0x23, 0x46, 0x2F, 0x60, 0x68,
-  0x77, 0x29, 0x29, 0xF0, 0x2E, 0x2E, 0x62, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x32, 0x7C, 0x83, 0xB3,
-  0x54, 0x6B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x6B, 0x7B, 0xC3, 0xE7, 0x39, 0x72, 0x62, 0x62,
-  0x62, 0x62, 0x62, 0x2E, 0x29, 0x77, 0xA7, 0x36,
-  0xB8, 0x85, 0x85, 0x8D, 0x8D, 0x85, 0xB2, 0x2D,
-  0x2D, 0xE9, 0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0x85,
-  0x2A, 0x85, 0xAC, 0x95, 0x95, 0xAF, 0x85, 0x85,
-  0xAF, 0x8C, 0xDF, 0xC6, 0xB1, 0xD1, 0xE5, 0xE7,
-  0x83, 0x23, 0x5D, 0x60, 0x39, 0x77, 0xEC, 0x2E,
-  0x2E, 0x32, 0x32, 0x2E, 0x7C, 0x5D, 0x35, 0xA2,
-  0x54, 0x6B, 0x6B, 0x20, 0x6B, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x6B, 0x88, 0xC1, 0x35, 0xE1, 0x77, 0x57, 0x2E,
-  0x2E, 0x72, 0x29, 0x77, 0x60, 0xB5, 0x44, 0xE2,
-  0x2C, 0x2C, 0xDA, 0x8A, 0xDA, 0xAF, 0xA1, 0x2D,
-  0xE9, 0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0x85, 0x85,
-  0xEE, 0xAF, 0xD9, 0x7D, 0xD9, 0x2C, 0xDA, 0x85,
-  0xAC, 0xAF, 0x85, 0xDA, 0x8A, 0x2A, 0xE2, 0x50,
-  0x86, 0xD7, 0x75, 0x35, 0xA8, 0xE7, 0xE1, 0x5D,
-  0x68, 0x7C, 0xF1, 0x68, 0xE1, 0xBF, 0xA2, 0xC1,
-  0x52, 0x2B, 0x7D, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x85, 0x85, 0x85, 0x2C, 0x2C, 0x2C, 0x95,
-  0xE9, 0x74, 0xCE, 0xE0, 0xE7, 0x60, 0x77, 0x77,
-  0x7C, 0xEF, 0x5D, 0x23, 0x3F, 0xB6, 0x8A, 0x2C,
-  0xAC, 0xAF, 0x85, 0x8A, 0x85, 0xD9, 0x48, 0x48,
-  0xB2, 0x95, 0x95, 0xD9, 0x85, 0xDA, 0x85, 0x85,
-  0xD3, 0xB2, 0x21, 0x7D, 0xAC, 0x2C, 0xDA, 0x85,
-  0xAC, 0xAC, 0x85, 0x85, 0x85, 0x2C, 0xAF, 0x2C,
-  0xDA, 0x8C, 0x79, 0xC7, 0xB0, 0x51, 0xB3, 0x35,
-  0xBF, 0xE5, 0xE7, 0xA8, 0xE0, 0xA2, 0xC1, 0x34,
-  0x7D, 0x85, 0xAC, 0xD9, 0xAC, 0xAF, 0xAC, 0xAC,
-  0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0xAF, 0xAF, 0x85,
-  0xC8, 0xCD, 0x6A, 0x26, 0x35, 0x3F, 0x83, 0x23,
-  0x23, 0xE7, 0xBF, 0x96, 0xEB, 0xDA, 0xDA, 0x2C,
-  0x2C, 0x2C, 0x85, 0xDA, 0x2C, 0x7D, 0xA1, 0x48,
-  0xB2, 0x21, 0xD6, 0xD9, 0x2C, 0xDA, 0x85, 0xAF,
-  0xAF, 0x2D, 0xE9, 0x7D, 0xAC, 0x2C, 0x85, 0x2C,
-  0xD9, 0xD9, 0xAF, 0x85, 0x85, 0x85, 0x2C, 0x2C,
-  0x2C, 0x85, 0xD9, 0x21, 0xAC, 0x2C, 0xBD, 0xA5,
-  0xC3, 0xA2, 0xA2, 0xA2, 0x26, 0xC1, 0xCE, 0x2A,
-  0xAF, 0x95, 0xD9, 0x2C, 0x2C, 0x85, 0x2C, 0xAF,
-  0xAC, 0x2C, 0x85, 0x2C, 0xAF, 0x2C, 0x85, 0xDA,
-  0x8D, 0x2A, 0x85, 0x34, 0xC1, 0xB3, 0x76, 0x35,
-  0xE0, 0x30, 0xA5, 0xB6, 0x2C, 0x85, 0x85, 0x85,
-  0xAF, 0x2C, 0x85, 0x85, 0xD9, 0xD6, 0xA1, 0xA1,
-  0x48, 0xA1, 0xD6, 0xAF, 0xDA, 0x8A, 0x2C, 0xD9,
-  0xB2, 0x2D, 0x48, 0xD9, 0xAF, 0x2C, 0x2C, 0x85,
-  0xAF, 0xAC, 0x2C, 0x85, 0x85, 0x85, 0xAF, 0xAC,
-  0xAC, 0x2C, 0xD9, 0xD6, 0xD6, 0x21, 0xB2, 0x2C,
-  0xC8, 0x3B, 0x65, 0xC5, 0xCE, 0x8E, 0xC8, 0x2C,
-  0xD9, 0x95, 0xAC, 0x2C, 0x2C, 0x2C, 0xAF, 0xAC,
-  0xAC, 0xAF, 0x2C, 0x85, 0x2C, 0x2C, 0x2C, 0x85,
-  0xDA, 0x2C, 0xD6, 0xAF, 0x59, 0x65, 0xDE, 0xF3,
-  0xF3, 0x59, 0xBC, 0xAC, 0xAF, 0x85, 0x85, 0x85,
-  0xAF, 0xD9, 0xAF, 0x2C, 0xD9, 0xD6, 0xD6, 0xD6,
-  0x21, 0xD6, 0xD9, 0xDA, 0x8D, 0x8A, 0x2C, 0xD9,
-  0xB2, 0xA1, 0xD6, 0xAC, 0x2C, 0x2C, 0x2C, 0x85,
-  0x2C, 0xAC, 0x2C, 0xDA, 0xDA, 0x85, 0xAF, 0xD9,
-  0xD9, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xAC,
-  0x85, 0x2A, 0x4D, 0xBC, 0x85, 0xAC, 0xAF, 0xAF,
-  0xAC, 0xD9, 0xAF, 0x2C, 0xAF, 0xD9, 0xD9, 0xAC,
-  0xAC, 0xAF, 0x85, 0x2C, 0x85, 0x2C, 0x2C, 0x2C,
-  0x2C, 0xD9, 0xB2, 0xD4, 0xD6, 0x2C, 0x8A, 0xDA,
-  0xC8, 0x85, 0x2C, 0xAC, 0x2C, 0xDA, 0xDA, 0x85,
-  0xAF, 0xAC, 0xD9, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xD9, 0xAC, 0xDA, 0x8D, 0xBC, 0xDA, 0xD9, 0x95,
-  0x95, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C, 0x2C, 0x85,
-  0x2C, 0xAF, 0xAF, 0x85, 0x85, 0x85, 0x2C, 0xAC,
-  0xD9, 0xAF, 0xAF, 0xAF, 0x2C, 0x2C, 0x2C, 0x85,
-  0x8A, 0x2A, 0x8D, 0x2C, 0xD9, 0x95, 0xAC, 0xAC,
-  0xD9, 0xD9, 0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xAF,
-  0xAF, 0x2C, 0x85, 0x85, 0x85, 0x85, 0x85, 0x2C,
-  0x85, 0x2C, 0xD9, 0xD9, 0xD9, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x85, 0x85, 0xAF, 0xAF, 0x85, 0x85, 0x85,
-  0xAF, 0xD9, 0xD9, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x85, 0x8A, 0x2A, 0x8D, 0x2C, 0xD9, 0xD9,
-  0x2C, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
-  0x85, 0xAF, 0xAC, 0x2C, 0x2C, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xD9, 0xAF, 0x85, 0x85, 0x85, 0xDA, 0xDA,
-  0x8A, 0x8A, 0x85, 0xAC, 0xD9, 0xD9, 0xAC, 0xD9,
-  0xD6, 0xD6, 0x7D, 0x95, 0x7D, 0xD9, 0xAF, 0xAF,
-  0xAF, 0x2C, 0x85, 0x85, 0xDA, 0x85, 0x2C, 0x85,
-  0x85, 0x2C, 0xAF, 0xAC, 0xAF, 0xAF, 0x2C, 0x2C,
-  0x2C, 0x2C, 0x2C, 0xAF, 0xAC, 0x2C, 0x2C, 0x2C,
-  0x2C, 0xAF, 0xD9, 0xAC, 0xAF, 0x2C, 0x85, 0x85,
-  0x85, 0xDA, 0x8D, 0x8A, 0x85, 0xAC, 0x95, 0xD9
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22,
+    0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+    0x26, 0x26, 0x25, 0x28, 0x23, 0x22, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x25, 0x2a, 0x2b, 0x2c, 0x2d, 0x2d,
+    0x2d, 0x2e, 0x2c, 0x2b, 0x2a, 0x25, 0x28, 0x22,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x24, 0x2a, 0x2c, 0x2f, 0x2c, 0x30, 0x30, 0x24,
+    0x25, 0x27, 0x2b, 0x2c, 0x2f, 0x31, 0x32, 0x25,
+    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
+    0x33, 0x34, 0x35, 0x21, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x21, 0x2b, 0x2f, 0x2c,
+    0x30, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
+    0x2d, 0x27, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x31,
+    0x2d, 0x32, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x2a, 0x34,
+    0x25, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x23, 0x32, 0x27, 0x21, 0x36,
+    0x2a, 0x2d, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x22, 0x26, 0x2c, 0x35,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x25, 0x2f, 0x37, 0x32, 0x22,
+    0x36, 0x35, 0x31, 0x27, 0x22, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x22,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x26, 0x38, 0x38, 0x35, 0x25,
+    0x36, 0x21, 0x2d, 0x2b, 0x24, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x24, 0x39, 0x39, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x25, 0x2b, 0x30, 0x28, 0x22,
+    0x36, 0x36, 0x27, 0x34, 0x30, 0x23, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x26, 0x2d, 0x26, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x22, 0x22, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x2d, 0x33, 0x28, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x2b, 0x2c, 0x25, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x36, 0x36,
+    0x36, 0x21, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x21, 0x23, 0x22, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x28, 0x34, 0x27, 0x22, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
+    0x21, 0x21, 0x24, 0x27, 0x21, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x28, 0x27, 0x22, 0x33, 0x24, 0x36,
+    0x36, 0x36, 0x36, 0x22, 0x2f, 0x2a, 0x23, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
+    0x30, 0x3a, 0x38, 0x24, 0x24, 0x36, 0x36, 0x36,
+    0x23, 0x2f, 0x3b, 0x3c, 0x3d, 0x30, 0x25, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2f, 0x32, 0x23, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x23,
+    0x3e, 0x3f, 0x40, 0x3a, 0x22, 0x36, 0x36, 0x21,
+    0x41, 0x42, 0x43, 0x44, 0x45, 0x3e, 0x23, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2f, 0x33, 0x28, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x2b,
+    0x44, 0x40, 0x46, 0x47, 0x35, 0x36, 0x36, 0x26,
+    0x43, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x2e, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x34, 0x36, 0x4d,
+    0x4e, 0x25, 0x2f, 0x46, 0x4a, 0x22, 0x23, 0x32,
+    0x4f, 0x50, 0x21, 0x31, 0x51, 0x52, 0x53, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x21, 0x3a,
+    0x4d, 0x21, 0x31, 0x54, 0x55, 0x28, 0x30, 0x2b,
+    0x4b, 0x4d, 0x36, 0x23, 0x32, 0x50, 0x3f, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x38, 0x23, 0x37,
+    0x55, 0x36, 0x28, 0x3a, 0x56, 0x57, 0x57, 0x58,
+    0x3c, 0x4d, 0x36, 0x36, 0x36, 0x40, 0x40, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x29, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x51, 0x23, 0x35,
+    0x43, 0x25, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
+    0x5f, 0x60, 0x61, 0x36, 0x31, 0x47, 0x3b, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x2c, 0x25, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x22,
+    0x40, 0x62, 0x63, 0x5d, 0x64, 0x65, 0x66, 0x67,
+    0x68, 0x69, 0x66, 0x5e, 0x6a, 0x6b, 0x2a, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x33, 0x2e, 0x26, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x2f, 0x23, 0x36,
+    0x6c, 0x63, 0x6d, 0x64, 0x5c, 0x66, 0x69, 0x6e,
+    0x6f, 0x70, 0x71, 0x69, 0x69, 0x72, 0x6c, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x33, 0x34, 0x27, 0x22,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x34, 0x26, 0x73,
+    0x74, 0x75, 0x76, 0x64, 0x65, 0x77, 0x69, 0x78,
+    0x70, 0x71, 0x71, 0x71, 0x72, 0x5f, 0x5e, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x25, 0x38, 0x2a, 0x23,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x33, 0x79,
+    0x63, 0x7a, 0x7b, 0x5c, 0x66, 0x69, 0x6e, 0x7c,
+    0x71, 0x71, 0x69, 0x7d, 0x7e, 0x7a, 0x7f, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x21, 0x51, 0x2b, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x32, 0x24,
+    0x80, 0x81, 0x64, 0x82, 0x77, 0x69, 0x71, 0x71,
+    0x69, 0x83, 0x84, 0x85, 0x7a, 0x85, 0x86, 0x36,
+    0x21, 0x2b, 0x23, 0x36, 0x36, 0x39, 0x2e, 0x26,
+    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x2d, 0x33, 0x21,
+    0x87, 0x88, 0x89, 0x72, 0x67, 0x66, 0x5f, 0x89,
+    0x8a, 0x63, 0x85, 0x8b, 0x8c, 0x8d, 0x41, 0x36,
+    0x36, 0x2d, 0x3a, 0x35, 0x36, 0x24, 0x51, 0x32,
+    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x33, 0x21,
+    0x55, 0x8e, 0x8f, 0x8a, 0x7d, 0x5e, 0x90, 0x7e,
+    0x75, 0x75, 0x90, 0x62, 0x40, 0x3f, 0x49, 0x23,
+    0x36, 0x24, 0x3a, 0x3a, 0x24, 0x36, 0x2e, 0x31,
+    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x21, 0x28, 0x33, 0x37, 0x25, 0x22,
+    0x3b, 0x50, 0x8e, 0x8f, 0x90, 0x7e, 0x90, 0x63,
+    0x74, 0x91, 0x92, 0x42, 0x93, 0x4b, 0x45, 0x2c,
+    0x36, 0x36, 0x33, 0x39, 0x21, 0x36, 0x22, 0x51,
+    0x33, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x22, 0x27, 0x2e, 0x2e, 0x36, 0x21,
+    0x94, 0x3f, 0x50, 0x95, 0x96, 0x8f, 0x8f, 0x97,
+    0x8e, 0x42, 0x50, 0x43, 0x47, 0x48, 0x48, 0x98,
+    0x21, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39,
+    0x2e, 0x27, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x22, 0x24, 0x2b, 0x38, 0x28, 0x36, 0x32,
+    0x4c, 0x4b, 0x50, 0x50, 0x50, 0x42, 0x42, 0x50,
+    0x50, 0x40, 0x45, 0x99, 0x48, 0x48, 0x48, 0x48,
+    0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x23,
+    0x2f, 0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x28, 0x32, 0x51, 0x32, 0x28, 0x21, 0x98,
+    0x48, 0x47, 0x9a, 0x50, 0x50, 0x50, 0x50, 0x50,
+    0x9a, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x93, 0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x2a, 0x2f, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x23, 0x30, 0x2e, 0x2c, 0x36, 0x21, 0x51, 0x9b,
+    0x48, 0x48, 0x52, 0x3f, 0x50, 0x50, 0x40, 0x4b,
+    0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2d, 0x31, 0x27, 0x23, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+    0x27, 0x2c, 0x2d, 0x21, 0x36, 0x28, 0x44, 0x48,
+    0x48, 0x48, 0x48, 0x47, 0x46, 0x4f, 0x47, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x9c, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x28, 0x51, 0x39, 0x26, 0x22, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
+    0x35, 0x51, 0x28, 0x36, 0x36, 0x9d, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x9b, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x4f, 0x28, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x28, 0x38, 0x2b, 0x25, 0x22, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
+    0x51, 0x25, 0x36, 0x36, 0x23, 0x40, 0x9b, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x9b, 0x99, 0x2b, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x30, 0x2f, 0x33, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x23, 0x30, 0x34,
+    0x27, 0x36, 0x36, 0x36, 0x2a, 0x40, 0x47, 0x48,
+    0x48, 0x48, 0x48, 0x9b, 0x99, 0x99, 0x9b, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x47, 0x52,
+    0x46, 0x4f, 0x37, 0x21, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x30, 0x34, 0x2a, 0x23,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x22, 0x25, 0x39, 0x2c,
+    0x36, 0x36, 0x36, 0x21, 0x31, 0x4e, 0x9a, 0x4c,
+    0x47, 0x9b, 0x9b, 0x52, 0x46, 0x4f, 0x52, 0x9b,
+    0x9b, 0x9b, 0x47, 0x4f, 0x45, 0x9a, 0x93, 0x93,
+    0x3f, 0x93, 0x98, 0x28, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c, 0x26,
+    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x28,
+    0x36, 0x36, 0x36, 0x22, 0x38, 0x98, 0x44, 0x99,
+    0x9b, 0x48, 0x48, 0x9b, 0x4c, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x47, 0x52, 0x46, 0x43, 0x93,
+    0x40, 0x40, 0x43, 0x53, 0x21, 0x23, 0x33, 0x23,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x2f, 0x32,
+    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x24, 0x2b, 0x31, 0x36,
+    0x36, 0x22, 0x36, 0x24, 0x9e, 0x4f, 0x9b, 0x48,
+    0x48, 0x48, 0x48, 0x9b, 0x99, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x47,
+    0x4f, 0x9a, 0x3f, 0x46, 0x38, 0x36, 0x21, 0x30,
+    0x26, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c,
+    0x25, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x26, 0x2e, 0x33, 0x36,
+    0x25, 0x25, 0x36, 0x4d, 0x52, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x4f, 0x3e, 0x4d, 0x49, 0x48,
+    0x98, 0x2b, 0x55, 0x4f, 0x9b, 0x48, 0x48, 0x48,
+    0x48, 0x47, 0x44, 0x93, 0x43, 0x23, 0x36, 0x36,
+    0x26, 0x24, 0x36, 0x36, 0x36, 0x36, 0x28, 0x2f,
+    0x2a, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x51, 0x24, 0x36,
+    0x2a, 0x36, 0x28, 0x44, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x4f, 0x54, 0x38, 0x3d, 0x98, 0x37, 0x9b,
+    0x3a, 0x22, 0x23, 0x2a, 0x55, 0x4f, 0x48, 0x48,
+    0x48, 0x48, 0x9b, 0x4b, 0x44, 0x37, 0x36, 0x23,
+    0x28, 0x30, 0x22, 0x36, 0x36, 0x36, 0x36, 0x2d,
+    0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x21, 0x28, 0x2b, 0x34, 0x36, 0x25,
+    0x24, 0x36, 0x4a, 0x48, 0x48, 0x48, 0x48, 0x52,
+    0x53, 0x37, 0x54, 0x98, 0x55, 0x38, 0x38, 0x47,
+    0x4a, 0x2d, 0x30, 0x23, 0x28, 0x39, 0x53, 0x52,
+    0x48, 0x48, 0x48, 0x9b, 0x52, 0x3f, 0x21, 0x30,
+    0x35, 0x25, 0x30, 0x36, 0x36, 0x36, 0x36, 0x32,
+    0x2d, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x22, 0x26, 0x2e, 0x35, 0x36, 0x2a,
+    0x36, 0x24, 0x4f, 0x48, 0x48, 0x9b, 0x55, 0x39,
+    0x55, 0x53, 0x3a, 0x55, 0x3a, 0x51, 0x51, 0x47,
+    0x55, 0x3a, 0x4d, 0x37, 0x30, 0x22, 0x24, 0x2b,
+    0x54, 0x9b, 0x48, 0x48, 0x48, 0x47, 0x32, 0x30,
+    0x2a, 0x23, 0x30, 0x23, 0x36, 0x36, 0x36, 0x21,
+    0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x2a, 0x51, 0x28, 0x28, 0x25,
+    0x36, 0x3a, 0x48, 0x48, 0x48, 0x4f, 0x26, 0x23,
+    0x26, 0x39, 0x3e, 0x43, 0x49, 0x37, 0x2f, 0x9b,
+    0x55, 0x3a, 0x54, 0x43, 0x3e, 0x30, 0x32, 0x3d,
+    0x49, 0x3f, 0x48, 0x48, 0x48, 0x48, 0x38, 0x21,
+    0x36, 0x36, 0x22, 0x27, 0x36, 0x36, 0x36, 0x36,
+    0x2e, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x22, 0x25, 0x2c, 0x34, 0x36, 0x30, 0x21,
+    0x23, 0x43, 0x48, 0x48, 0x48, 0x47, 0x3b, 0x32,
+    0x21, 0x28, 0x2b, 0x9e, 0x49, 0x37, 0x2e, 0x52,
+    0x4a, 0x37, 0x9e, 0x98, 0x51, 0x3a, 0x93, 0x54,
+    0x55, 0x4f, 0x48, 0x48, 0x48, 0x48, 0x94, 0x36,
+    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
+    0x2a, 0x2e, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x2a, 0x51, 0x25, 0x21, 0x2a, 0x36,
+    0x2e, 0x9b, 0x48, 0x48, 0x52, 0x4b, 0x52, 0x9e,
+    0x51, 0x30, 0x22, 0x28, 0x32, 0x32, 0x39, 0x47,
+    0x37, 0x2a, 0x39, 0x3a, 0x50, 0x9f, 0x3a, 0x9f,
+    0x4b, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x98, 0x36,
+    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
+    0x22, 0x2f, 0x30, 0x22, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x22, 0x25, 0x2c, 0x34, 0x36, 0x24, 0x28, 0x36,
+    0x54, 0x48, 0x48, 0x45, 0x30, 0x30, 0x9e, 0x52,
+    0x45, 0x3a, 0x31, 0x25, 0x22, 0x25, 0x2a, 0x98,
+    0x39, 0x2f, 0x42, 0x49, 0x4a, 0x3b, 0x50, 0x47,
+    0x43, 0x9d, 0x3b, 0x4b, 0x48, 0x48, 0x9a, 0x36,
+    0x36, 0x36, 0x36, 0x30, 0x36, 0x36, 0x36, 0x36,
+    0x21, 0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x28, 0x32, 0x2f, 0x28, 0x36, 0x27, 0x22, 0x21,
+    0x43, 0x48, 0x48, 0x50, 0x30, 0x23, 0x25, 0x2f,
+    0x3f, 0x52, 0x49, 0x51, 0x39, 0x25, 0x24, 0x2b,
+    0x9e, 0x42, 0x3e, 0x55, 0x9e, 0x4f, 0x4f, 0x54,
+    0x4a, 0x9e, 0x49, 0x50, 0x48, 0x48, 0x4b, 0x21,
+    0x36, 0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x25, 0x2c, 0x39, 0x36, 0x36, 0x30, 0x22, 0x25,
+    0x52, 0x48, 0x48, 0x45, 0x3a, 0x51, 0x26, 0x23,
+    0x30, 0x9d, 0x45, 0x40, 0x3a, 0x39, 0x2b, 0x2b,
+    0x3b, 0x3a, 0x55, 0x4b, 0x47, 0x9e, 0x3a, 0x49,
+    0x9e, 0x9f, 0x3b, 0x9a, 0x48, 0x48, 0x4f, 0x21,
+    0x36, 0x36, 0x22, 0x26, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x30, 0x2d, 0x21, 0x36, 0x36, 0x32, 0x23, 0x2a,
+    0x47, 0x48, 0x48, 0x43, 0x3e, 0x3a, 0x9d, 0x2b,
+    0x23, 0x25, 0x39, 0x4d, 0x2b, 0x31, 0x2d, 0x9d,
+    0x34, 0x2e, 0x2f, 0x9e, 0x3a, 0x55, 0x3f, 0x9f,
+    0x9f, 0x3e, 0x55, 0x43, 0x48, 0x48, 0x4c, 0x22,
+    0x36, 0x36, 0x24, 0x23, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0x2e, 0x36, 0x36, 0x23, 0x31, 0x27, 0x39,
+    0x9b, 0x48, 0x48, 0x4f, 0x3e, 0x4d, 0x55, 0x9e,
+    0x51, 0x24, 0x23, 0x26, 0x32, 0x2c, 0x3b, 0x4b,
+    0x55, 0x32, 0x2b, 0x37, 0x98, 0x9e, 0x3e, 0x9e,
+    0x55, 0x37, 0x3e, 0x4b, 0x48, 0x48, 0x4c, 0x23,
+    0x36, 0x36, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x2b, 0x39, 0x36, 0x36, 0x36, 0x26, 0x32, 0x31,
+    0x9b, 0x48, 0x48, 0x4f, 0x55, 0x3a, 0x53, 0x53,
+    0x2e, 0x9d, 0x34, 0x28, 0x28, 0x37, 0x98, 0x45,
+    0x3e, 0x2b, 0x49, 0x9e, 0x3b, 0x3e, 0x2d, 0x6b,
+    0x4a, 0x3a, 0x3b, 0x4f, 0x48, 0x48, 0x46, 0x22,
+    0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x35, 0x39, 0x36, 0x36, 0x36, 0x36, 0x26, 0x2d,
+    0x9b, 0x48, 0x48, 0x47, 0x3b, 0x3a, 0x2f, 0x37,
+    0x49, 0x38, 0x38, 0x3a, 0x2b, 0x31, 0x51, 0x32,
+    0x2b, 0x26, 0x37, 0x9f, 0x55, 0x32, 0x26, 0x2b,
+    0x2d, 0x9d, 0x3b, 0x52, 0x48, 0x48, 0x9a, 0x36,
+    0x24, 0x27, 0xa0, 0x24, 0x25, 0x28, 0x21, 0x36,
+    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x25,
+    0x39, 0x4d, 0xa1, 0x84, 0x81, 0x57, 0x21, 0x39,
+    0x52, 0x48, 0x48, 0x47, 0x9f, 0x4a, 0x4d, 0x55,
+    0x37, 0x9f, 0x45, 0x9e, 0x3e, 0x54, 0x4d, 0x2d,
+    0x51, 0x3b, 0x3d, 0x40, 0x50, 0x2f, 0x32, 0x23,
+    0x2a, 0x3a, 0x54, 0x47, 0x48, 0x48, 0x53, 0x28,
+    0x23, 0x36, 0x36, 0x36, 0x21, 0x28, 0x2c, 0x30,
+    0x21, 0x38, 0x33, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x28, 0x30,
+    0x2d, 0xa2, 0x7a, 0xa3, 0xa4, 0xa4, 0x7f, 0x22,
+    0x51, 0x52, 0x48, 0x9b, 0x3b, 0x3a, 0x2f, 0x54,
+    0x3f, 0x4b, 0x3b, 0x34, 0x3e, 0x55, 0x34, 0x4d,
+    0x34, 0x3b, 0x3b, 0x55, 0x42, 0x4b, 0x9e, 0x31,
+    0x2b, 0x3a, 0x9e, 0x47, 0xa5, 0xa5, 0xa6, 0x61,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x30, 0x32,
+    0x25, 0x4d, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x24, 0x26, 0x30, 0x33, 0x31,
+    0x4d, 0x91, 0x5b, 0xa3, 0xa4, 0xa4, 0xa4, 0x5a,
+    0x21, 0x2e, 0x46, 0x48, 0x9a, 0x3b, 0x42, 0x47,
+    0x42, 0x9d, 0x37, 0x39, 0x4a, 0x3e, 0x3a, 0x52,
+    0x38, 0x3e, 0x3e, 0x2b, 0x25, 0x37, 0x4f, 0x4f,
+    0x55, 0x55, 0x45, 0xa7, 0xa8, 0x69, 0x66, 0xa9,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x26, 0x25,
+    0x83, 0xaa, 0x2c, 0x25, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x28, 0x30, 0x35, 0x2d, 0x2f, 0x37, 0x4a,
+    0x60, 0x85, 0xab, 0xac, 0xa4, 0xa4, 0xa4, 0x82,
+    0x86, 0x36, 0x32, 0x3f, 0x48, 0x47, 0x4b, 0x4a,
+    0x9d, 0x55, 0x2f, 0x51, 0x3a, 0x3b, 0x55, 0x9b,
+    0x4d, 0x3b, 0x55, 0x39, 0x24, 0x28, 0x32, 0x9e,
+    0x47, 0x47, 0x48, 0xad, 0xa3, 0xa8, 0xae, 0xaf,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x57,
+    0x77, 0x66, 0x34, 0x27, 0x22, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x23, 0x30, 0x31, 0xb0, 0x91, 0x7e, 0x90, 0x90,
+    0x8b, 0x5b, 0xa3, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0x5d, 0xb1, 0x36, 0x24, 0x53, 0x47, 0x37, 0x30,
+    0x32, 0x2e, 0x98, 0x3f, 0x3a, 0x3e, 0x4a, 0x47,
+    0x9d, 0x3e, 0x54, 0x40, 0x55, 0x30, 0x30, 0x4a,
+    0x6b, 0x9b, 0x99, 0xad, 0x64, 0x5c, 0x8b, 0xb1,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x73, 0x5d,
+    0x82, 0x5c, 0xb2, 0x2a, 0x23, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x24, 0x2b, 0xb0, 0x8b, 0x5b, 0x76, 0x5b, 0x5b,
+    0x7b, 0xa3, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa8, 0x5e, 0x22, 0x36, 0x21, 0x3a, 0x3d, 0x30,
+    0x22, 0x28, 0x3a, 0x44, 0x4a, 0x3e, 0x3e, 0x9b,
+    0x9d, 0x3e, 0x9e, 0x4b, 0x55, 0x2e, 0x42, 0x9f,
+    0x93, 0x4f, 0x3f, 0xb3, 0x7b, 0x7b, 0x85, 0x80,
+    0xa0, 0x36, 0x36, 0x36, 0x21, 0xb4, 0x7e, 0x7b,
+    0x64, 0x64, 0xb5, 0x35, 0x24, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x31, 0xb6, 0x5b, 0x64, 0xa3, 0xa3, 0xac,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0x66, 0xb7, 0x36, 0x36, 0x36, 0x2c, 0x54,
+    0x31, 0x23, 0x26, 0x2c, 0x3a, 0x3b, 0x55, 0x47,
+    0x37, 0x3b, 0x3b, 0x38, 0x4a, 0x98, 0x55, 0x98,
+    0x47, 0x9a, 0x3f, 0xb8, 0x76, 0x76, 0x7a, 0x63,
+    0xb9, 0xba, 0x86, 0xba, 0xbb, 0x90, 0x5b, 0x64,
+    0xa3, 0xa3, 0xbc, 0x2d, 0x27, 0x23, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x26, 0x2d, 0x91, 0x5b, 0x64, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa8, 0x83, 0xaf, 0x36, 0x36, 0x36, 0x30,
+    0x98, 0x37, 0x30, 0x26, 0x9d, 0x3e, 0x9f, 0x9b,
+    0x37, 0x3b, 0x3b, 0x53, 0x53, 0x3d, 0x4b, 0x48,
+    0x9b, 0x9a, 0x3f, 0xbd, 0x5b, 0x7b, 0xbe, 0x85,
+    0x7e, 0x90, 0x63, 0x90, 0x85, 0x5b, 0xa3, 0xa4,
+    0xa4, 0xac, 0x5d, 0xb5, 0x39, 0x26, 0x23, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2d, 0xbf, 0xbe, 0x64, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa8, 0x88, 0x36, 0x36, 0x36, 0x36,
+    0x2d, 0x3f, 0x3b, 0x31, 0x4d, 0x3e, 0x9f, 0x47,
+    0x38, 0x3b, 0x3e, 0x3e, 0x98, 0x52, 0x48, 0x48,
+    0x9b, 0x45, 0x3f, 0xc0, 0x6d, 0x7b, 0xab, 0xbe,
+    0x7a, 0x8b, 0x8b, 0x7a, 0x5b, 0x64, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa3, 0xc1, 0x37, 0x35, 0x26, 0x23,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2e, 0xbf, 0x7a, 0x7b, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa8, 0x72, 0x73, 0x36, 0x36, 0x36,
+    0x24, 0x52, 0x47, 0x49, 0x3a, 0x55, 0x98, 0x47,
+    0x9d, 0x3e, 0x54, 0x45, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x46, 0x42, 0xb6, 0x7a, 0x7b, 0x64, 0x7b,
+    0x76, 0x5b, 0x5b, 0x76, 0x7b, 0xa3, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xac, 0x64, 0xc1, 0x4d, 0x2c, 0x27,
+    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x25, 0x31, 0xc2, 0x8b, 0x7b, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa8, 0x89, 0xa0, 0x36, 0x36,
+    0x32, 0x47, 0x48, 0x9b, 0x9a, 0x3f, 0x47, 0x48,
+    0x4b, 0x40, 0x4f, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x4b, 0x2f, 0x8f, 0x7a, 0x7b, 0xa3, 0xac,
+    0xa3, 0x64, 0x64, 0xa3, 0xa3, 0xac, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0x5d, 0xc3, 0x2c,
+    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x25, 0x31, 0xc2, 0x85, 0x7b, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0x66, 0x57, 0x27, 0x4d,
+    0x4b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x99, 0x34, 0xa0, 0xb9, 0x7a, 0x7b, 0xa3, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0xc2,
+    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2d, 0xc2, 0x85, 0x7b, 0xac, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa8, 0x5f, 0x92, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x44,
+    0x35, 0x36, 0xaf, 0xbb, 0x7a, 0x7b, 0xac, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xac, 0xa3, 0xc0,
+    0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+    0x30, 0x2f, 0xb6, 0x8b, 0x7b, 0xac, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0x66, 0x89, 0x45,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x4e, 0x25,
+    0x36, 0x36, 0x61, 0xb9, 0x6d, 0x64, 0xac, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xac, 0x7b, 0xbe, 0xc3,
+    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0xc4, 0x63, 0xbe, 0xa3, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0x72, 0x81, 0xc5,
+    0x46, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x3f, 0x2c, 0x36, 0x36,
+    0x36, 0x36, 0xc6, 0x8f, 0x6d, 0x64, 0xac, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa3, 0xab, 0x8b, 0xb0, 0x2c,
+    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x35, 0x96, 0x75, 0xab, 0xa3, 0xac, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xac, 0x7b, 0x81, 0xb9,
+    0x73, 0x3b, 0x44, 0x9b, 0x48, 0x48, 0x48, 0x9b,
+    0x99, 0x43, 0x94, 0x2c, 0x21, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x73, 0xb9, 0x7a, 0x7b, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0x64, 0x76, 0x7a, 0x91, 0xb5, 0x31, 0x30,
+    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x39, 0x97, 0x75, 0xbe, 0x7b, 0x64, 0xa3, 0xa3,
+    0xac, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0x7b, 0x7a, 0xc7,
+    0xc8, 0x36, 0x21, 0x26, 0x2b, 0x39, 0x33, 0x30,
+    0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xc8, 0xbb, 0x8b, 0x7b, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0x64, 0x64,
+    0x76, 0x85, 0xbf, 0xb5, 0x34, 0x2b, 0x27, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0xc9, 0x63, 0x7e, 0x7a, 0x6d, 0xbe, 0x5b,
+    0x76, 0x7b, 0x64, 0x64, 0xa3, 0xac, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xac, 0x76, 0x85, 0xb9,
+    0x79, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xca, 0xbb, 0x75, 0x76, 0xa3, 0xa4,
+    0xa4, 0xa4, 0xac, 0xa3, 0x64, 0x76, 0xbe, 0x8b,
+    0xb6, 0xb5, 0x2f, 0x35, 0x30, 0x24, 0x22, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+    0x27, 0x31, 0xcb, 0xc9, 0xbb, 0x74, 0x63, 0x90,
+    0x7e, 0x75, 0x8b, 0x6d, 0xbe, 0x76, 0x64, 0xa3,
+    0xac, 0xac, 0xac, 0xac, 0x64, 0x7a, 0x84, 0xcc,
+    0x79, 0xa0, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xc8, 0xcc, 0x63, 0x6d, 0x7b, 0x64,
+    0xac, 0xa3, 0x64, 0x7b, 0xbe, 0x75, 0x63, 0x96,
+    0x38, 0x39, 0x2a, 0x24, 0x23, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x28, 0x27, 0x35, 0x2d, 0x41, 0xb5, 0xc5, 0x8f,
+    0xb9, 0xbb, 0xc7, 0x74, 0x84, 0x90, 0x85, 0x6d,
+    0x5b, 0x7b, 0x7b, 0xab, 0x6d, 0x90, 0xb9, 0xcd,
+    0xca, 0x22, 0x36, 0x36, 0x28, 0x30, 0x30, 0x30,
+    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x25, 0x36,
+    0x36, 0x21, 0xb4, 0x80, 0xc7, 0x7e, 0x6d, 0x76,
+    0xab, 0x76, 0x6d, 0x85, 0x63, 0xb9, 0xb5, 0x34,
+    0x33, 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x24, 0x27, 0x2a, 0x35, 0x2e, 0x2f,
+    0x41, 0xce, 0xcf, 0x6c, 0x80, 0xcc, 0xb9, 0x74,
+    0x84, 0x90, 0x75, 0x7e, 0x74, 0x8f, 0xcd, 0x79,
+    0xc6, 0x2b, 0x9d, 0x41, 0x2f, 0x34, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x2f, 0x38,
+    0x4d, 0x37, 0xd0, 0xd1, 0x8f, 0x74, 0x63, 0x7e,
+    0x75, 0x7e, 0x63, 0xc7, 0x88, 0xc4, 0x31, 0x2a,
+    0x24, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x21, 0x22, 0x23, 0x24, 0x26, 0x30,
+    0x33, 0x39, 0x2e, 0x51, 0x41, 0xb2, 0x6c, 0xd1,
+    0x80, 0xcc, 0xcc, 0xcc, 0xd2, 0xd1, 0xb7, 0xd3,
+    0x41, 0x34, 0x35, 0x32, 0x30, 0x27, 0x27, 0x27,
+    0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x2a,
+    0x2b, 0x34, 0xd4, 0xca, 0xd5, 0x8f, 0xbb, 0xc7,
+    0xc7, 0xbb, 0xcc, 0x6c, 0x41, 0x39, 0x27, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22,
+    0x28, 0x24, 0x26, 0x2a, 0x33, 0x2c, 0x2f, 0x41,
+    0xd6, 0xb7, 0x79, 0x79, 0x79, 0xca, 0xd7, 0x51,
+    0x39, 0x30, 0x24, 0x23, 0x22, 0x22, 0x22, 0x22,
+    0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23,
+    0x24, 0x2a, 0x31, 0xd8, 0xc8, 0x79, 0xd1, 0x80,
+    0xd5, 0xba, 0xd9, 0x2f, 0x35, 0x26, 0x23, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x22, 0x23, 0x28, 0x25, 0x30, 0x2b,
+    0x31, 0x2f, 0xd4, 0xd8, 0xd8, 0x2f, 0x2e, 0x33,
+    0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x28, 0x27, 0x35, 0x34, 0xd8, 0xd8, 0xd8,
+    0xda, 0xd4, 0x2e, 0x33, 0x25, 0x23, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x23, 0x28,
+    0x26, 0x30, 0x32, 0x2b, 0x33, 0x2a, 0x26, 0x28,
+    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x25, 0x30, 0x33, 0x35, 0x35,
+    0x2b, 0x2a, 0x26, 0x28, 0x22, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x21, 0x22, 0x23, 0x28, 0x28, 0x23, 0x22, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x23, 0x28, 0x24, 0x24,
+    0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 };
 
-#define INCLUDE_LINUX_LOGOBW
-#define INCLUDE_LINUX_LOGO16
-#include <linux/linux_logo.h>
-
-#else
+#endif /* INCLUDE_LINUX_LOGO_DATA */
 
-/* prototypes only */
-extern unsigned char linux_logo_red[];
-extern unsigned char linux_logo_green[];
-extern unsigned char linux_logo_blue[];
-extern unsigned char linux_logo[];
-extern unsigned char linux_logo_bw[];
-extern unsigned char linux_logo16_red[];
-extern unsigned char linux_logo16_green[];
-extern unsigned char linux_logo16_blue[];
-extern unsigned char linux_logo16[];
+#include <linux/linux_logo.h>
 
-#endif
diff -u --recursive --new-file v2.4.5/linux/include/asm-mips/socket.h linux/include/asm-mips/socket.h
--- v2.4.5/linux/include/asm-mips/socket.h	Sat Feb  3 11:26:44 2001
+++ linux/include/asm-mips/socket.h	Wed Jun 20 21:00:55 2001
@@ -71,6 +71,7 @@
 					/* level.  For writing rarp and	*/
 					/* other similar things on the	*/
 					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
 #endif
 
 #endif /* _ASM_SOCKET_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-mips/termios.h linux/include/asm-mips/termios.h
--- v2.4.5/linux/include/asm-mips/termios.h	Sat Feb  3 20:00:45 2001
+++ linux/include/asm-mips/termios.h	Mon Jun 11 19:15:27 2001
@@ -101,6 +101,7 @@
 #define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
 #define N_HDLC		13	/* synchronous HDLC */
 #define N_SYNC_PPP	14	/* synchronous PPP */
+#define N_HCI		15  /* Bluetooth HCI UART */
 
 #ifdef __KERNEL__
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-mips64/linux_logo.h linux/include/asm-mips64/linux_logo.h
--- v2.4.5/linux/include/asm-mips64/linux_logo.h	Sat May 13 08:31:25 2000
+++ linux/include/asm-mips64/linux_logo.h	Mon Jun 11 19:15:27 2001
@@ -24,918 +24,897 @@
 
 #define linux_logo_banner "Linux/MIPS64 version " UTS_RELEASE
 
-#define LINUX_LOGO_COLORS 212
+#define __HAVE_ARCH_LINUX_LOGO
+
+#define LINUX_LOGO_COLORS	187
 
 #ifdef INCLUDE_LINUX_LOGO_DATA
 
 unsigned char linux_logo_red[] __initdata = {
-  0x03, 0x82, 0xE9, 0xBF, 0x42, 0xC9, 0x7E, 0xC0,
-  0xE9, 0xE3, 0xC2, 0x24, 0xA4, 0x65, 0xEC, 0xC4,
-  0x82, 0x9F, 0xF3, 0x12, 0x5F, 0xA0, 0xC2, 0xED,
-  0x3E, 0xD5, 0xDB, 0xA0, 0x1C, 0xF4, 0xEB, 0xA4,
-  0xCD, 0x0A, 0x9A, 0x51, 0xCC, 0xBE, 0xC0, 0xBA,
-  0x74, 0xDC, 0xAA, 0xF6, 0xD3, 0xC5, 0xE6, 0x26,
-  0xC2, 0x83, 0x38, 0xEA, 0x49, 0xB0, 0xED, 0xE5,
-  0xF4, 0x96, 0x96, 0x1B, 0xFA, 0xCC, 0xF2, 0x0F,
-  0xCD, 0xE5, 0xF4, 0xD3, 0x50, 0x7A, 0xB5, 0xDE,
-  0xD5, 0xB6, 0x60, 0x0A, 0x6A, 0xEA, 0xD4, 0xEB,
-  0xC1, 0xCA, 0xEA, 0xEC, 0x2A, 0x96, 0x95, 0xDC,
-  0xE4, 0xCE, 0xEC, 0x1E, 0xDC, 0x8A, 0xD1, 0xF6,
-  0x3C, 0x5E, 0xC6, 0xB4, 0xB2, 0xAC, 0xBA, 0x9E,
-  0x0F, 0x59, 0xBA, 0xFA, 0xCC, 0xBF, 0x82, 0xCE,
-  0xE6, 0x4F, 0xAA, 0x4C, 0xCA, 0x8E, 0x8E, 0xDF,
-  0x2C, 0xB6, 0x3B, 0xDE, 0xCE, 0xEE, 0x46, 0x4A,
-  0x6F, 0x7A, 0x82, 0xE4, 0xAA, 0x88, 0xE2, 0xCE,
-  0xAE, 0xB6, 0x70, 0xC2, 0x9A, 0xDA, 0x35, 0x9E,
-  0x95, 0xC0, 0x7E, 0x8C, 0xC2, 0xB6, 0xCE, 0xB9,
-  0xD5, 0xAA, 0xC1, 0xF4, 0xC7, 0xB6, 0xB6, 0xA3,
-  0xF2, 0x68, 0xDB, 0x76, 0xDC, 0x57, 0xD3, 0xA8,
-  0xC0, 0xEF, 0x46, 0xF4, 0x2F, 0xD7, 0x53, 0x36,
-  0xE6, 0xA7, 0xCA, 0xCB, 0x7E, 0xE4, 0x86, 0x9A,
-  0xCE, 0x94, 0xB4, 0x1D, 0xDA, 0xCE, 0x6C, 0xE6,
-  0x9E, 0xC6, 0xDA, 0x16, 0xFA, 0xAA, 0x56, 0xB6,
-  0xFE, 0x6E, 0xEA, 0xCE, 0xE5, 0xCC, 0xDB, 0xD3,
-  0xED, 0xDC, 0xF4, 0x72
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
+    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
+    0xc3, 0x65, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
+    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
+    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x76, 0x79,
+    0x62, 0x36, 0x9a, 0xe2, 0xec, 0xe1, 0xb8, 0xd7,
+    0xaf, 0x25, 0xbc, 0xc0, 0xef, 0xea, 0xe8, 0xe8,
+    0xf5, 0xf1, 0xda, 0xd3, 0x79, 0xdb, 0xf4, 0xf6,
+    0xf6, 0xf6, 0xe2, 0x3d, 0xb4, 0xce, 0xe6, 0xee,
+    0xf6, 0x68, 0xd8, 0xec, 0xf5, 0xc6, 0xc8, 0x9c,
+    0x89, 0xd2, 0xee, 0xcb, 0xb9, 0xd2, 0x66, 0x5e,
+    0x8b, 0xbe, 0xa8, 0xd5, 0xca, 0xb6, 0xae, 0x9c,
+    0xc5, 0xbe, 0xbe, 0xca, 0x90, 0xb2, 0x9a, 0xa8,
+    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x8d,
+    0x12, 0x4a, 0x8e, 0xf2, 0xf6, 0xee, 0xb5, 0xe4,
+    0xf1, 0x26, 0x9a, 0xea, 0xf6, 0xe0, 0xd2, 0x16,
+    0x9a, 0x2e, 0x70, 0xd6, 0x46, 0x7c, 0xb4, 0x62,
+    0xd6, 0xa3, 0x74, 0xa7, 0xa2, 0xca, 0xe0, 0xae,
+    0xbe, 0xce, 0xa3, 0x8e, 0x6d, 0x8e, 0x32, 0xaf,
+    0x50, 0x9e, 0x5b, 0x8a, 0x98, 0x82, 0x7a, 0x82,
+    0x56, 0x7c, 0x8a, 0x56, 0x5e, 0x86, 0x6a, 0x52,
+    0x59, 0x64, 0x5e,
 };
 
 unsigned char linux_logo_green[] __initdata = {
-  0x03, 0x82, 0xC4, 0x83, 0x42, 0xA2, 0x4A, 0xA4,
-  0xE5, 0xA6, 0xC2, 0x24, 0xA4, 0x65, 0xB4, 0x94,
-  0x66, 0x87, 0xB6, 0x12, 0x44, 0x6C, 0x96, 0xD4,
-  0x36, 0x95, 0xB2, 0x92, 0x0E, 0xF4, 0xBC, 0x77,
-  0xA5, 0x0A, 0x92, 0x52, 0xB4, 0x9A, 0x8C, 0xB2,
-  0x74, 0xC2, 0x8E, 0xBD, 0xA2, 0xCA, 0xD2, 0x12,
-  0xB6, 0x61, 0x24, 0xDA, 0x33, 0x79, 0xCB, 0xAC,
-  0xDA, 0x84, 0x7A, 0x1B, 0xFA, 0x8D, 0xBE, 0x06,
-  0x93, 0xBB, 0xBC, 0xAB, 0x44, 0x62, 0x83, 0xDA,
-  0x9B, 0xA2, 0x4C, 0x04, 0x6A, 0xB6, 0xC8, 0xBD,
-  0x8D, 0xB6, 0xAD, 0xEC, 0x2A, 0x68, 0x62, 0x9D,
-  0xC4, 0xC4, 0xB4, 0x13, 0xA3, 0x8A, 0xD2, 0xD6,
-  0x3C, 0x5D, 0x8C, 0x7E, 0x82, 0xAC, 0x96, 0x7E,
-  0x0D, 0x5A, 0xBA, 0xBB, 0xCC, 0xBE, 0x76, 0xB6,
-  0xDE, 0x4E, 0x9A, 0x3C, 0xBE, 0x8E, 0x6E, 0xCB,
-  0x1C, 0xAA, 0x2E, 0xBE, 0xAA, 0xDE, 0x3E, 0x4B,
-  0x4D, 0x7A, 0x54, 0xE4, 0x8E, 0x6E, 0xCA, 0x9B,
-  0x70, 0x9E, 0x5A, 0xAA, 0x9A, 0xBE, 0x34, 0x9E,
-  0x71, 0x9E, 0x7E, 0x5F, 0xAA, 0x8A, 0xBE, 0x91,
-  0xCE, 0x88, 0x92, 0xDB, 0xC6, 0xAB, 0x8A, 0x72,
-  0xE2, 0x44, 0xC3, 0x54, 0xAA, 0x45, 0xBB, 0x92,
-  0xBA, 0xC4, 0x46, 0xCA, 0x2D, 0xD6, 0x3B, 0x1A,
-  0xC2, 0x7E, 0xA6, 0xCB, 0x7A, 0xDC, 0x86, 0x72,
-  0xB6, 0x94, 0xB4, 0x1C, 0xBC, 0xAE, 0x4C, 0xD6,
-  0x62, 0x86, 0xD3, 0x16, 0xF6, 0x7A, 0x55, 0x79,
-  0xFE, 0x6E, 0xC6, 0xC6, 0xAA, 0x93, 0xDC, 0x9D,
-  0xAE, 0xA4, 0xD4, 0x56
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
+    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
+    0xc3, 0x62, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
+    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
+    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x62, 0x5c,
+    0x4e, 0x26, 0x72, 0xaa, 0xba, 0xaf, 0x90, 0xae,
+    0x92, 0x1a, 0xa4, 0x85, 0xb6, 0xbe, 0xc3, 0xc8,
+    0xcf, 0xd0, 0xc2, 0xce, 0x57, 0xa2, 0xd6, 0xda,
+    0xda, 0xd7, 0xb8, 0x2a, 0x7b, 0x91, 0xae, 0xca,
+    0xda, 0x45, 0x9e, 0xb2, 0xd7, 0x9b, 0x90, 0x76,
+    0x5c, 0xa2, 0xbe, 0xa6, 0x85, 0x96, 0x4e, 0x46,
+    0x66, 0x92, 0x7a, 0x9a, 0x96, 0x9d, 0x9a, 0x6b,
+    0x8a, 0x8e, 0xb2, 0xca, 0x90, 0xa6, 0x79, 0x7c,
+    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x8d,
+    0x0e, 0x36, 0x86, 0xba, 0xbe, 0xcc, 0x8e, 0xb8,
+    0xc4, 0x1e, 0x8e, 0xae, 0xba, 0xb2, 0xa6, 0x12,
+    0x7a, 0x20, 0x64, 0xaa, 0x2f, 0x70, 0x85, 0x46,
+    0xa6, 0x6e, 0x51, 0x72, 0x92, 0xa2, 0xa6, 0x87,
+    0x96, 0xa2, 0x85, 0x7a, 0x6a, 0x6e, 0x22, 0x76,
+    0x36, 0x76, 0x3c, 0x6e, 0x63, 0x53, 0x66, 0x62,
+    0x42, 0x50, 0x56, 0x42, 0x56, 0x56, 0x56, 0x3e,
+    0x51, 0x52, 0x56,
 };
 
 unsigned char linux_logo_blue[] __initdata = {
-  0x04, 0x84, 0x10, 0x0C, 0x41, 0x14, 0x04, 0x78,
-  0xC7, 0x0E, 0xC4, 0x24, 0xA4, 0x64, 0x0C, 0x0D,
-  0x17, 0x24, 0x0D, 0x13, 0x11, 0x07, 0x40, 0x22,
-  0x0C, 0x0C, 0x11, 0x78, 0x06, 0xF4, 0x0B, 0x0A,
-  0x47, 0x0B, 0x7C, 0x54, 0x6C, 0x0C, 0x0D, 0x9C,
-  0x73, 0x54, 0x14, 0x0C, 0x0F, 0xC7, 0x94, 0x04,
-  0x94, 0x17, 0x0A, 0x6C, 0x08, 0x0F, 0x14, 0x0B,
-  0x12, 0x68, 0x28, 0x11, 0xFA, 0x0A, 0x34, 0x09,
-  0x0A, 0x2F, 0x15, 0x19, 0x14, 0x3C, 0x06, 0xC4,
-  0x0B, 0x84, 0x24, 0x08, 0x69, 0x38, 0xBC, 0x15,
-  0x1F, 0xA0, 0x0A, 0xEC, 0x2A, 0x0C, 0x0C, 0x0C,
-  0x2C, 0xA0, 0x15, 0x07, 0x0B, 0x8C, 0xD3, 0x10,
-  0x3B, 0x5C, 0x0C, 0x04, 0x3C, 0xAC, 0x54, 0x1C,
-  0x0B, 0x5B, 0xBB, 0x0A, 0xC1, 0xBB, 0x5C, 0x3C,
-  0xBC, 0x4D, 0x74, 0x10, 0x8C, 0x8C, 0x14, 0x91,
-  0x0C, 0x74, 0x17, 0x0C, 0x48, 0x9C, 0x3C, 0x4C,
-  0x09, 0x7C, 0x05, 0xE4, 0x34, 0x38, 0x6C, 0x11,
-  0x08, 0x7C, 0x18, 0x2C, 0x9C, 0x4C, 0x34, 0x9C,
-  0x29, 0x54, 0x7C, 0x0C, 0x78, 0x18, 0x9C, 0x14,
-  0xBA, 0x30, 0x27, 0x31, 0xC2, 0x97, 0x24, 0x09,
-  0xB4, 0x04, 0x87, 0x0C, 0x14, 0x1F, 0x7C, 0x64,
-  0xB0, 0x0F, 0x45, 0x10, 0x2C, 0xD4, 0x0A, 0x04,
-  0x44, 0x1F, 0x2C, 0xCC, 0x7C, 0xD8, 0x84, 0x0C,
-  0x8C, 0x94, 0xB4, 0x1D, 0x20, 0x5C, 0x18, 0xB4,
-  0x04, 0x09, 0xBC, 0x14, 0xF4, 0x08, 0x54, 0x07,
-  0xFC, 0x6C, 0x24, 0xB4, 0x15, 0x18, 0xDB, 0x17,
-  0x17, 0x18, 0x21, 0x24
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x01, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x06, 0x65,
+    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
+    0xc3, 0x59, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
+    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
+    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x2e, 0x08,
+    0x0a, 0x06, 0x0a, 0x0b, 0x0b, 0x0f, 0x0c, 0x0f,
+    0x3d, 0x09, 0x73, 0x09, 0x0d, 0x0a, 0x10, 0x1e,
+    0x2d, 0x13, 0x86, 0xba, 0x19, 0x0a, 0x36, 0x3c,
+    0x26, 0x14, 0x0d, 0x06, 0x07, 0x0a, 0x0b, 0x0f,
+    0x4a, 0x06, 0x0a, 0x0c, 0x2b, 0x0a, 0x0b, 0x0a,
+    0x06, 0x0a, 0x0a, 0x11, 0x0b, 0x0a, 0x0a, 0x1e,
+    0x0f, 0x0d, 0x0a, 0x0b, 0x22, 0x6a, 0x72, 0x0b,
+    0x0b, 0x22, 0x90, 0xca, 0x90, 0x92, 0x3c, 0x2c,
+    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x8d,
+    0x06, 0x0e, 0x6a, 0x0e, 0x0e, 0x5b, 0x2c, 0x3e,
+    0x0e, 0x0a, 0x5a, 0x0d, 0x0e, 0x3e, 0x0a, 0x06,
+    0x2e, 0x06, 0x4e, 0x36, 0x06, 0x58, 0x24, 0x06,
+    0x3a, 0x08, 0x08, 0x07, 0x5e, 0x45, 0x0a, 0x32,
+    0x2e, 0x2a, 0x43, 0x48, 0x5f, 0x2e, 0x06, 0x06,
+    0x07, 0x24, 0x06, 0x32, 0x06, 0x06, 0x46, 0x2e,
+    0x22, 0x06, 0x06, 0x1e, 0x4c, 0x06, 0x3a, 0x22,
+    0x42, 0x34, 0x42,
 };
 
 unsigned char linux_logo[] __initdata = {
-  0xBC, 0xAC, 0x7D, 0x95, 0xAF, 0x85, 0x2C, 0x2C,
-  0xAC, 0xD9, 0x95, 0x7D, 0x95, 0xAC, 0x2C, 0xAF,
-  0x7D, 0x48, 0xB2, 0xAC, 0x85, 0xDA, 0xDA, 0x2C,
-  0x7D, 0x48, 0x21, 0x2C, 0x8D, 0x2A, 0x8A, 0xDA,
-  0x85, 0x2C, 0xD9, 0xAC, 0x2C, 0x2C, 0xD9, 0xD9,
-  0xAF, 0x85, 0x85, 0x85, 0x8D, 0xBC, 0x2A, 0x2A,
-  0xBC, 0x8C, 0xBC, 0xAC, 0x7D, 0x95, 0xAF, 0x85,
-  0x2C, 0x2C, 0xAC, 0xD9, 0x95, 0x7D, 0x95, 0xAC,
-  0x2C, 0xAF, 0x7D, 0x48, 0xB2, 0xAC, 0x85, 0xDA,
-  0xDA, 0x2C, 0x7D, 0x48, 0x21, 0x2C, 0x8D, 0x2A,
-  0xAF, 0xA1, 0x48, 0x7D, 0xAF, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xD9, 0x95, 0x7D, 0x95, 0xAC, 0xD9, 0x7D,
-  0x48, 0xE9, 0x21, 0xAF, 0xDA, 0xDA, 0x85, 0x2C,
-  0xD9, 0xD9, 0xAC, 0xDA, 0x8A, 0xDA, 0x85, 0x2C,
-  0x2C, 0xAC, 0xD9, 0xAC, 0xAF, 0xAF, 0x2C, 0x2C,
-  0x2C, 0x85, 0x2C, 0x2C, 0x85, 0xDA, 0xDA, 0xDA,
-  0xDA, 0xDA, 0xAF, 0xA1, 0x48, 0x7D, 0xAF, 0x2C,
-  0x2C, 0xAC, 0xD9, 0xD9, 0x95, 0x7D, 0x95, 0xAC,
-  0xD9, 0x7D, 0x48, 0xE9, 0x21, 0xAF, 0xDA, 0xDA,
-  0x85, 0x2C, 0xD9, 0xD9, 0xAC, 0xDA, 0x8A, 0xDA,
-  0x7D, 0x48, 0x48, 0x7D, 0x2C, 0x85, 0x2C, 0xAF,
-  0xD9, 0xD9, 0x7D, 0x95, 0xD9, 0xD9, 0xD9, 0x7D,
-  0xB2, 0x21, 0xD9, 0x85, 0xDA, 0xDA, 0x85, 0x2C,
-  0xAF, 0x2C, 0x2C, 0xDA, 0x85, 0x85, 0x2C, 0x2C,
-  0xAC, 0xD9, 0xD9, 0xAF, 0xDA, 0x85, 0x2C, 0x2C,
-  0x85, 0xDA, 0xDA, 0x85, 0x85, 0xDA, 0x85, 0x85,
-  0x85, 0xAF, 0x7D, 0x48, 0x48, 0x7D, 0x2C, 0x85,
-  0x2C, 0xAF, 0xD9, 0xD9, 0x7D, 0x95, 0xD9, 0xD9,
-  0xD9, 0x7D, 0xB2, 0x21, 0xD9, 0x85, 0xDA, 0xDA,
-  0x85, 0x2C, 0xAF, 0x2C, 0x2C, 0xDA, 0xDA, 0x85,
-  0xA1, 0xE9, 0x48, 0x95, 0x85, 0xDA, 0x85, 0xAF,
-  0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9, 0x95, 0x95,
-  0xD9, 0xAC, 0x85, 0x85, 0xDA, 0xDA, 0x85, 0x2C,
-  0xAC, 0xAC, 0x2C, 0x2C, 0x85, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xD9, 0x2C, 0x91, 0x41, 0x20, 0x6B, 0x20,
-  0x6B, 0x20, 0x6B, 0xAE, 0x2C, 0x85, 0x2C, 0x2C,
-  0xAC, 0xD9, 0xA1, 0xE9, 0x48, 0x95, 0x85, 0xDA,
-  0x85, 0xAF, 0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9,
-  0x95, 0x95, 0xD9, 0xAC, 0x85, 0x85, 0xDA, 0xDA,
-  0x85, 0x2C, 0xAC, 0xAC, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xA1, 0xA1, 0xD6, 0xAF, 0xDA, 0xDA, 0x85, 0x2C,
-  0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9, 0xD9, 0xD9,
-  0x2C, 0x2C, 0xDA, 0xDA, 0xDA, 0x85, 0x2C, 0xD9,
-  0xD9, 0xD9, 0xD9, 0xAC, 0xAC, 0xAC, 0xAF, 0xAC,
-  0x2C, 0xB2, 0x88, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x6B, 0x80, 0x85, 0x2C,
-  0xD9, 0xD6, 0xA1, 0xA1, 0xD6, 0xAF, 0xDA, 0xDA,
-  0x85, 0x2C, 0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9,
-  0xD9, 0xD9, 0x2C, 0x2C, 0xDA, 0xDA, 0xDA, 0x85,
-  0x2C, 0xD9, 0xD9, 0xD9, 0xD9, 0xAF, 0xAF, 0xAF,
-  0xD6, 0xD6, 0xD9, 0x2C, 0xDA, 0xDA, 0x2C, 0xAC,
-  0xD9, 0x7D, 0x95, 0xD9, 0xD9, 0xD9, 0xAF, 0x2C,
-  0x85, 0x85, 0x85, 0x85, 0x2C, 0x2C, 0xAC, 0xD9,
-  0xD9, 0xD9, 0xAF, 0xAF, 0x2C, 0x2C, 0xAF, 0xDA,
-  0xAE, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x41, 0xE3, 0x20, 0x6B, 0x48,
-  0xAC, 0x95, 0xD6, 0xD6, 0xD9, 0x2C, 0xDA, 0xDA,
-  0x2C, 0xAC, 0xD9, 0x7D, 0x95, 0xD9, 0xD9, 0xD9,
-  0xAF, 0x2C, 0x85, 0x85, 0x85, 0x85, 0x2C, 0x2C,
-  0xAC, 0xD9, 0xD9, 0xD9, 0xAF, 0xAF, 0xAF, 0xAF,
-  0xD9, 0xD9, 0xD9, 0x2C, 0x85, 0x85, 0x2C, 0xD9,
-  0x7D, 0x21, 0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0x85,
-  0x85, 0x85, 0x85, 0x85, 0x2C, 0xAF, 0xAF, 0xAC,
-  0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x89,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x74, 0x43, 0x80, 0x41, 0x20,
-  0x9F, 0x2C, 0xD9, 0xD9, 0xD9, 0x2C, 0x85, 0x85,
-  0x2C, 0xD9, 0x7D, 0x21, 0xD6, 0xD9, 0xAF, 0x2C,
-  0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x2C, 0xAF,
-  0xAF, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xD9, 0x7D, 0xD9, 0xAF, 0x85, 0x85, 0x2C, 0xD9,
-  0xB2, 0x21, 0x7D, 0xD9, 0xAF, 0x2C, 0x85, 0x85,
-  0x85, 0x2C, 0x2C, 0x2C, 0x2C, 0xAF, 0xAF, 0xAC,
-  0xAF, 0xAC, 0xAF, 0xAF, 0xAC, 0xAC, 0x85, 0x41,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xAE, 0x48, 0x89, 0x74, 0x41,
-  0x6B, 0xD6, 0xD9, 0x7D, 0xD9, 0xAF, 0x85, 0x85,
-  0x2C, 0xD9, 0xB2, 0x21, 0x7D, 0xD9, 0xAF, 0x2C,
-  0x85, 0x85, 0x85, 0x2C, 0x2C, 0x2C, 0x2C, 0xAF,
-  0xAF, 0xAC, 0xAF, 0xAC, 0xAC, 0x2C, 0xAF, 0xAC,
-  0x2C, 0x7D, 0xD9, 0x2C, 0xDA, 0x85, 0x2C, 0x7D,
-  0xB2, 0xD6, 0xD9, 0xAF, 0x85, 0x85, 0x85, 0x85,
-  0xAF, 0xAC, 0xAC, 0xAF, 0xAF, 0xAC, 0xAC, 0xD9,
-  0x95, 0x7D, 0x95, 0x95, 0xD9, 0xD9, 0x48, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x6B, 0xAE, 0xE6, 0x80, 0x2B, 0x88,
-  0x20, 0x33, 0xDA, 0x95, 0xD9, 0x2C, 0xDA, 0x85,
-  0x2C, 0x7D, 0xB2, 0xD6, 0xD9, 0xAF, 0x85, 0x85,
-  0x85, 0x85, 0xAF, 0xAC, 0xAC, 0xAF, 0xAF, 0xAC,
-  0xAC, 0xD9, 0x95, 0x95, 0x7D, 0x95, 0x95, 0xD9,
-  0x85, 0xD9, 0x2C, 0x85, 0xDA, 0xDA, 0xD9, 0x21,
-  0xA1, 0xD9, 0xAF, 0x2C, 0x85, 0xDA, 0x85, 0xAF,
-  0xD9, 0xD9, 0xAC, 0xAC, 0xAC, 0xD9, 0x7D, 0xD6,
-  0xD6, 0x7D, 0x95, 0xD9, 0xD9, 0x85, 0xDB, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xDB, 0xE3, 0x6B, 0x20, 0x20,
-  0x20, 0x20, 0xE9, 0xD9, 0x2C, 0x85, 0xDA, 0xDA,
-  0xD9, 0x21, 0xA1, 0xD9, 0xAF, 0x2C, 0x85, 0xDA,
-  0x85, 0xAF, 0xD9, 0xD9, 0xAC, 0xAC, 0xAC, 0xD9,
-  0x7D, 0xD6, 0xD6, 0x7D, 0x95, 0xD9, 0xD9, 0xD9,
-  0xDA, 0x2C, 0x85, 0xDA, 0xDA, 0x85, 0x95, 0x21,
-  0x21, 0xD9, 0x85, 0x85, 0x85, 0x2C, 0x2C, 0xD9,
-  0x95, 0x95, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xAC, 0xAC, 0x2C, 0xAF, 0x2C, 0x85, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x88, 0xDA, 0x85, 0xDA, 0xDA, 0x85,
-  0x95, 0x21, 0x21, 0xD9, 0x85, 0x85, 0x85, 0x2C,
-  0x2C, 0xD9, 0x95, 0x95, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xD9, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xDA, 0x2C, 0x85, 0x85, 0x2C, 0xD9, 0xD6, 0xB2,
-  0x95, 0x2C, 0x85, 0x85, 0xAF, 0xAC, 0x95, 0x95,
-  0x7D, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0x2C, 0x85,
-  0x85, 0x85, 0x85, 0x85, 0x85, 0xAC, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xAC, 0x85, 0x85, 0x2C, 0xD9,
-  0xD6, 0xB2, 0x95, 0x2C, 0x85, 0x85, 0xAF, 0xAC,
-  0x95, 0x95, 0x7D, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
-  0x2C, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-  0x85, 0x2C, 0x2C, 0x2C, 0xAC, 0x95, 0xD6, 0x7D,
-  0xD9, 0x2C, 0x2C, 0xAF, 0x95, 0x7D, 0x7D, 0x95,
-  0x95, 0xD9, 0xD9, 0x95, 0xD9, 0xD9, 0x2C, 0x85,
-  0xDA, 0xDA, 0xDA, 0x85, 0x85, 0x21, 0x20, 0x20,
-  0x6B, 0x41, 0xDB, 0x6B, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x41, 0xDB, 0xDB, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xE6, 0x2C, 0x2C, 0xAC, 0x95,
-  0xD6, 0x7D, 0xD9, 0x2C, 0x2C, 0xAF, 0x95, 0x7D,
-  0x7D, 0x95, 0x95, 0xD9, 0xD9, 0x95, 0xD9, 0xD9,
-  0x2C, 0x85, 0xDA, 0xDA, 0xDA, 0x85, 0x2C, 0x2C,
-  0x2C, 0xAF, 0xAC, 0xD9, 0x95, 0xD6, 0xD6, 0xD9,
-  0x2C, 0x2C, 0x2C, 0xD9, 0xD6, 0xD6, 0xD9, 0xAF,
-  0xAC, 0x95, 0xD6, 0x7D, 0x7D, 0xD9, 0x2C, 0x85,
-  0xDA, 0xDA, 0x2C, 0xAF, 0xAF, 0x21, 0x20, 0x20,
-  0x88, 0x2B, 0x88, 0x74, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0xAE, 0x2D, 0x2D, 0x74, 0x74, 0x88, 0x20,
-  0x20, 0x20, 0x20, 0x80, 0xAC, 0xD9, 0x95, 0xD6,
-  0xD6, 0xD9, 0x2C, 0x2C, 0x2C, 0xD9, 0xD6, 0xD6,
-  0xD9, 0xAF, 0xAC, 0x95, 0xD6, 0x7D, 0x7D, 0xD9,
-  0x2C, 0xDA, 0xDA, 0x85, 0x2C, 0xAF, 0xAF, 0xAF,
-  0x2C, 0xAF, 0xD9, 0x95, 0xD6, 0xD6, 0x95, 0xAF,
-  0x2C, 0x2C, 0xD9, 0x95, 0xD6, 0x95, 0xAF, 0x2C,
-  0xAC, 0x7D, 0x21, 0x95, 0xD9, 0x2C, 0x85, 0x85,
-  0x85, 0xAF, 0xD9, 0x95, 0xD9, 0x7D, 0x20, 0x33,
-  0x7D, 0x8A, 0x7D, 0x5B, 0x6B, 0x20, 0x20, 0x6B,
-  0xE6, 0xD9, 0x85, 0x2A, 0xDA, 0x2B, 0x41, 0x20,
-  0x20, 0x20, 0x6B, 0x74, 0xD9, 0x95, 0xD6, 0xD6,
-  0x95, 0xAF, 0x2C, 0x2C, 0xD9, 0x95, 0xD6, 0x95,
-  0xAF, 0x2C, 0xAC, 0x7D, 0x21, 0x95, 0xD9, 0x2C,
-  0x85, 0x85, 0x85, 0x2C, 0xD9, 0xD9, 0xD9, 0xD9,
-  0x85, 0xD9, 0x7D, 0x21, 0x21, 0x7D, 0xAC, 0x2C,
-  0x2C, 0xAC, 0xD9, 0x7D, 0xD9, 0xAF, 0x2C, 0x85,
-  0xAC, 0x7D, 0x7D, 0xAC, 0x85, 0xDA, 0x8A, 0xDA,
-  0x85, 0xAF, 0xD9, 0x7D, 0xD9, 0x95, 0x20, 0x91,
-  0xBC, 0x73, 0xEE, 0x7D, 0x20, 0x20, 0x20, 0x80,
-  0x4D, 0x3D, 0x73, 0x73, 0xA3, 0xD6, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x2B, 0x7D, 0x21, 0x21, 0x7D,
-  0xAC, 0x2C, 0x2C, 0xAC, 0xD9, 0x7D, 0xD9, 0xAF,
-  0x2C, 0x85, 0xAC, 0x7D, 0x7D, 0xAC, 0x85, 0xDA,
-  0x8A, 0x8A, 0x85, 0xAC, 0xD9, 0x7D, 0xD9, 0xAC,
-  0x2C, 0xD9, 0xD6, 0xB2, 0xB2, 0x7D, 0xAF, 0x85,
-  0x2C, 0xD9, 0x95, 0x95, 0xAF, 0x2C, 0x2C, 0x2C,
-  0xD9, 0xD9, 0xAC, 0x85, 0x8D, 0x2A, 0x2A, 0xDA,
-  0xAF, 0xD9, 0x95, 0x95, 0xD9, 0xAC, 0x20, 0xAF,
-  0x2C, 0xE6, 0x8D, 0x73, 0xE3, 0x20, 0x20, 0x48,
-  0x5C, 0xDA, 0x5B, 0x43, 0xBC, 0x73, 0x2B, 0x20,
-  0x20, 0x20, 0x20, 0x41, 0xD6, 0xB2, 0xB2, 0x7D,
-  0xAF, 0x85, 0x2C, 0xD9, 0x95, 0x95, 0xAF, 0x2C,
-  0x2C, 0x2C, 0xD9, 0xD9, 0xAC, 0x85, 0x8A, 0x2A,
-  0x8D, 0xDA, 0xAF, 0xD9, 0x95, 0x95, 0xD9, 0xAF,
-  0xAC, 0xD9, 0xD6, 0xB2, 0x21, 0xD9, 0x2C, 0x85,
-  0x2C, 0xD9, 0x95, 0xD9, 0xAF, 0x2C, 0x2C, 0xAC,
-  0xAC, 0xAF, 0x85, 0x8D, 0xBC, 0xBC, 0xDA, 0xD9,
-  0xD6, 0xA1, 0xA1, 0x21, 0xD9, 0xAC, 0x20, 0x2A,
-  0xCC, 0xAE, 0x9F, 0xE4, 0xAE, 0x5B, 0x74, 0xA1,
-  0xE4, 0xAE, 0x20, 0x9F, 0x89, 0xE8, 0xE6, 0x20,
-  0x20, 0x20, 0x20, 0x41, 0xD6, 0xB2, 0x21, 0xD9,
-  0x2C, 0x85, 0x2C, 0xD9, 0x95, 0xD9, 0xAF, 0x2C,
-  0x2C, 0xAC, 0xAC, 0xAF, 0x85, 0x8D, 0xBC, 0x2A,
-  0xDA, 0xD9, 0xD6, 0xA1, 0xA1, 0x21, 0xD9, 0xD9,
-  0xD9, 0x95, 0x21, 0xA1, 0x21, 0xAC, 0x85, 0x85,
-  0xAC, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C, 0xAF, 0xAC,
-  0xAF, 0x85, 0x8A, 0x2A, 0x2A, 0xDA, 0xD9, 0xA1,
-  0x48, 0xE9, 0x48, 0x21, 0x95, 0xAC, 0x20, 0x2A,
-  0xDB, 0x41, 0x74, 0xBC, 0x2B, 0x7B, 0x7B, 0x80,
-  0x73, 0x41, 0x20, 0x6B, 0x2B, 0xE8, 0x2D, 0x20,
-  0x20, 0x20, 0x20, 0x33, 0x21, 0xA1, 0x21, 0xAC,
-  0x85, 0x85, 0xAC, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C,
-  0xAF, 0xAC, 0xAF, 0x85, 0x8A, 0xBC, 0x2A, 0xDA,
-  0xD9, 0xA1, 0x48, 0xE9, 0x48, 0x21, 0xD9, 0xD9,
-  0xA1, 0xB2, 0xB2, 0x48, 0xD6, 0xAC, 0x2C, 0x2C,
-  0xD9, 0x95, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
-  0x85, 0x8A, 0x8D, 0x8D, 0x85, 0x95, 0xA1, 0x6C,
-  0x6C, 0x48, 0xD6, 0xD9, 0x2C, 0x85, 0x20, 0x2C,
-  0x89, 0x20, 0x3C, 0xB9, 0xA7, 0x63, 0xD2, 0xB9,
-  0xC6, 0x9A, 0x20, 0x20, 0x43, 0x5C, 0xE6, 0x20,
-  0x20, 0x20, 0x20, 0x33, 0xB2, 0x48, 0xD6, 0xAC,
-  0x2C, 0x2C, 0xD9, 0x95, 0xAF, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x2C, 0x85, 0x8A, 0x8D, 0x8D, 0x85, 0x95,
-  0xA1, 0x6C, 0x6C, 0x48, 0xD6, 0xD9, 0xAF, 0xAC,
-  0xA1, 0xD6, 0x7D, 0xB2, 0xD6, 0xAF, 0x85, 0x85,
-  0xD9, 0x95, 0x2C, 0x85, 0xDA, 0x85, 0x85, 0x2C,
-  0x85, 0x8A, 0x8D, 0xDA, 0xD9, 0x48, 0x81, 0x2D,
-  0x48, 0xD6, 0xD9, 0xAC, 0x2C, 0x85, 0x20, 0x2D,
-  0xEE, 0x93, 0xD1, 0xA7, 0x3E, 0x3E, 0x3A, 0x25,
-  0x56, 0xAB, 0xAA, 0xC5, 0xEE, 0xEE, 0x33, 0x20,
-  0x20, 0x20, 0x20, 0x41, 0xD9, 0xB2, 0xD6, 0xAF,
-  0x85, 0x85, 0xD9, 0x95, 0x2C, 0x85, 0xDA, 0x85,
-  0x85, 0x2C, 0x85, 0x8A, 0x8D, 0xDA, 0xD9, 0x48,
-  0x81, 0x2D, 0x48, 0xD6, 0xD9, 0xAF, 0x2C, 0x2C,
-  0xAC, 0xAF, 0xD9, 0x7D, 0xD6, 0x2C, 0x85, 0x2C,
-  0xD9, 0xD9, 0x2C, 0xDA, 0xDA, 0xDA, 0x2C, 0x2C,
-  0x85, 0x8D, 0x8D, 0x2C, 0x21, 0x2D, 0x2D, 0xE9,
-  0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0xDA, 0x20, 0xE3,
-  0xB4, 0xBE, 0xF1, 0x3E, 0x9B, 0x22, 0x56, 0xF2,
-  0xBB, 0x7F, 0x56, 0xDC, 0x8F, 0x5A, 0x5F, 0x20,
-  0x20, 0x20, 0x20, 0x6B, 0x2C, 0x7D, 0xD6, 0x2C,
-  0x85, 0x2C, 0xD9, 0xD9, 0x2C, 0xDA, 0xDA, 0xDA,
-  0x2C, 0x2C, 0x85, 0x8D, 0x8A, 0x85, 0x21, 0x2D,
-  0x2D, 0xE9, 0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0x85,
-  0x2A, 0x85, 0xAC, 0x95, 0x95, 0x2C, 0x85, 0x85,
-  0xAC, 0xAF, 0x85, 0xDA, 0xDA, 0x85, 0x2C, 0x2C,
-  0xDA, 0x8A, 0x8A, 0xAF, 0xA1, 0x2D, 0xE9, 0xD6,
-  0xD9, 0xAC, 0x85, 0x85, 0x85, 0xDA, 0x20, 0x52,
-  0x55, 0xED, 0x57, 0x3E, 0x22, 0x56, 0x37, 0xBB,
-  0xBB, 0x58, 0x7F, 0x7F, 0x56, 0x5E, 0xC5, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x2C, 0x95, 0x95, 0x2C,
-  0x85, 0x85, 0xAC, 0xAF, 0x85, 0xDA, 0xDA, 0x85,
-  0x2C, 0x2C, 0xDA, 0x8D, 0xDA, 0xAF, 0xA1, 0x2D,
-  0xE9, 0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0x85, 0x85,
-  0xCD, 0xAF, 0xD9, 0x95, 0xD9, 0x2C, 0xDA, 0x85,
-  0xAF, 0xD9, 0x85, 0xDA, 0x85, 0x2C, 0xAC, 0xAF,
-  0x85, 0x8A, 0x85, 0xD9, 0x48, 0x48, 0xB2, 0x95,
-  0x95, 0xAC, 0x2C, 0x85, 0xDA, 0xDA, 0x6B, 0xB3,
-  0x46, 0x7C, 0x2E, 0x9B, 0x22, 0x56, 0xBB, 0x37,
-  0x58, 0x58, 0xF2, 0x3A, 0x46, 0x63, 0x64, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x2D, 0x95, 0xD9, 0x2C,
-  0xDA, 0x85, 0xAF, 0xD9, 0x85, 0xDA, 0x85, 0x2C,
-  0xAC, 0xAF, 0x85, 0xDA, 0x85, 0xD9, 0x48, 0x48,
-  0xB2, 0x95, 0x95, 0xD9, 0x85, 0xDA, 0x85, 0x85,
-  0xBC, 0xB2, 0xB2, 0x7D, 0xD9, 0x2C, 0xDA, 0x85,
-  0xAF, 0xD9, 0x85, 0xDA, 0x85, 0x85, 0xAF, 0x2C,
-  0x85, 0xDA, 0x2C, 0x7D, 0xA1, 0x48, 0xB2, 0x21,
-  0xD6, 0xD9, 0x85, 0xDA, 0x85, 0xDA, 0x41, 0x51,
-  0xB7, 0xEC, 0x2E, 0x22, 0x56, 0x37, 0xBB, 0xF2,
-  0x37, 0xEA, 0x2F, 0x2F, 0x77, 0xA7, 0x38, 0x20,
-  0x20, 0x6B, 0x20, 0x20, 0x5B, 0x2C, 0xD9, 0x2C,
-  0xDA, 0x85, 0xAF, 0xD9, 0x85, 0xDA, 0x85, 0x85,
-  0xAF, 0x2C, 0xDA, 0xDA, 0x2C, 0x7D, 0xA1, 0x48,
-  0xB2, 0x21, 0xD6, 0xD9, 0x2C, 0xDA, 0x85, 0xAF,
-  0x2C, 0x2D, 0x48, 0x7D, 0xAF, 0x2C, 0x85, 0x2C,
-  0xD9, 0xAC, 0xAF, 0x85, 0x85, 0x2C, 0x2C, 0x2C,
-  0x85, 0x2C, 0xD9, 0xD6, 0xA1, 0xA1, 0x48, 0xA1,
-  0x21, 0x2C, 0xDA, 0xDA, 0x2C, 0x85, 0x41, 0x98,
-  0xA2, 0xA7, 0x6F, 0xC9, 0x37, 0xF2, 0xF2, 0x9B,
-  0xB7, 0x66, 0x60, 0x4C, 0xED, 0x84, 0x3C, 0x20,
-  0x5B, 0x2D, 0x2B, 0x6B, 0x20, 0xAF, 0xAF, 0x2C,
-  0x85, 0x2C, 0xD9, 0xAC, 0xAF, 0x85, 0x85, 0x2C,
-  0x2C, 0x2C, 0x2C, 0x85, 0xD9, 0xD6, 0xA1, 0xA1,
-  0x48, 0xA1, 0xD6, 0xAF, 0xDA, 0x8A, 0x2C, 0xD9,
-  0xB2, 0x2D, 0x48, 0x95, 0x2C, 0x2C, 0x2C, 0x85,
-  0xAC, 0xAC, 0xAF, 0x85, 0xDA, 0x85, 0xAF, 0xAC,
-  0xAF, 0x2C, 0xD9, 0xD6, 0xD6, 0xD6, 0x21, 0xD6,
-  0xD9, 0xDA, 0x8D, 0xDA, 0xAF, 0x2C, 0x20, 0x88,
-  0x42, 0x51, 0x3F, 0x2F, 0x45, 0xB7, 0x66, 0x55,
-  0x46, 0x60, 0x5D, 0x36, 0xD8, 0x71, 0x43, 0x20,
-  0x20, 0x2D, 0xB2, 0x80, 0x20, 0x2D, 0x2C, 0x2C,
-  0x2C, 0x85, 0xAC, 0xAC, 0xAF, 0x85, 0xDA, 0x85,
-  0xAF, 0xAC, 0xAC, 0xAF, 0xD9, 0xD6, 0xD6, 0xD6,
-  0x21, 0xD6, 0xD9, 0xDA, 0x8D, 0x8A, 0x2C, 0xD9,
-  0xB2, 0x48, 0xD6, 0xAC, 0xAF, 0x2C, 0x2C, 0x85,
-  0x2C, 0xAC, 0x2C, 0xDA, 0xDA, 0x85, 0xAF, 0xD9,
-  0xD9, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xAC,
-  0x85, 0x8D, 0xBC, 0xDA, 0xD9, 0xDA, 0x20, 0xE3,
-  0xDA, 0x69, 0x96, 0xB5, 0xF1, 0x68, 0x5D, 0x82,
-  0xE1, 0xBE, 0x27, 0x8D, 0x4D, 0xD3, 0x7D, 0x20,
-  0x20, 0xDB, 0xA1, 0xCA, 0x20, 0x88, 0x85, 0x2C,
-  0x2C, 0x85, 0x2C, 0xAC, 0x2C, 0xDA, 0xDA, 0x85,
-  0xAF, 0xD9, 0xAC, 0xAF, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xD9, 0xAC, 0xDA, 0x8D, 0xBC, 0xDA, 0xD9, 0x95,
-  0xD9, 0x95, 0xAC, 0x2C, 0x2C, 0x2C, 0x2C, 0x85,
-  0x85, 0xAF, 0xAF, 0x85, 0x85, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x85,
-  0x8D, 0x2A, 0x2A, 0x85, 0xD9, 0x95, 0x20, 0xDB,
-  0x8D, 0x8D, 0x99, 0xB0, 0x35, 0xE5, 0x3F, 0x35,
-  0xB9, 0x50, 0x8A, 0x4D, 0x73, 0xE8, 0xA3, 0xCC,
-  0x20, 0x20, 0x33, 0x6B, 0x20, 0x20, 0xCC, 0x85,
-  0x2C, 0x85, 0x85, 0xAF, 0xAF, 0x85, 0x85, 0x85,
-  0x2C, 0xD9, 0xD9, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x85, 0x8A, 0x2A, 0x8D, 0x2C, 0xD9, 0xD9,
-  0xAF, 0xAF, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x85,
-  0x2C, 0xAF, 0xAF, 0xAF, 0x2C, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xAC, 0xAF, 0x2C, 0x85, 0x85, 0xDA, 0xDA,
-  0x8A, 0x8A, 0x85, 0xD9, 0x2C, 0x2B, 0x20, 0xAE,
-  0xA3, 0xBC, 0x8D, 0xC8, 0xA9, 0xC7, 0x92, 0x47,
-  0x8D, 0x8D, 0x7E, 0xE4, 0xE8, 0xE8, 0x5C, 0x2C,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6B, 0xAF,
-  0x2C, 0x85, 0x2C, 0xAF, 0xAF, 0xAF, 0x2C, 0x2C,
-  0x2C, 0xAF, 0xD9, 0xAC, 0x2C, 0x2C, 0x85, 0x85,
-  0x85, 0xDA, 0x8D, 0x8A, 0x85, 0xAC, 0x95, 0xD9,
-  0xAC, 0xAC, 0xAC, 0xAC, 0x2C, 0xAF, 0xAF, 0x2C,
-  0x2C, 0xAF, 0xAF, 0xAC, 0x2C, 0xAF, 0x2C, 0xAF,
-  0xD9, 0xAC, 0x2C, 0x2C, 0x85, 0x85, 0x85, 0x85,
-  0x85, 0x2C, 0xD9, 0xD9, 0x2D, 0x6B, 0x41, 0x2A,
-  0xE8, 0xA3, 0xC8, 0x8D, 0x8A, 0x8A, 0x8A, 0x8D,
-  0x4D, 0xA3, 0x3D, 0xE8, 0xE8, 0xE8, 0xE8, 0x5C,
-  0xAE, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xDB,
-  0xDA, 0x2C, 0x2C, 0xAF, 0xAF, 0xAC, 0xAC, 0xAF,
-  0x2C, 0xAC, 0xD9, 0xAC, 0x2C, 0x2C, 0x85, 0x85,
-  0x85, 0x85, 0x85, 0x2C, 0xD9, 0x95, 0x7D, 0xD9,
-  0x7D, 0x7D, 0xD9, 0xAC, 0xAC, 0xAF, 0xAF, 0xAF,
-  0x2C, 0x2C, 0xAC, 0xAC, 0xD9, 0xAC, 0xAC, 0xD9,
-  0x95, 0xD9, 0xAC, 0xAF, 0xAF, 0xAC, 0xAF, 0xAC,
-  0xD9, 0x7D, 0x7D, 0x7D, 0x33, 0x41, 0x2D, 0xE8,
-  0xE8, 0x5C, 0xD3, 0x8D, 0x8D, 0x8D, 0x8D, 0x7E,
-  0x3D, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xDA, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x81, 0x2C, 0x2C, 0x2C, 0xAC, 0xAC, 0xAC, 0xAC,
-  0xAC, 0xD9, 0x95, 0x95, 0xAC, 0xAF, 0xAF, 0xAF,
-  0xAF, 0xAC, 0xD9, 0x95, 0x7D, 0xD6, 0xD6, 0x7D,
-  0x21, 0xD6, 0x95, 0xD9, 0xD9, 0xAC, 0xAF, 0xAF,
-  0x2C, 0xAF, 0xAC, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9,
-  0x21, 0x21, 0x7D, 0x95, 0x95, 0x7D, 0xD6, 0x21,
-  0xB2, 0xA1, 0x2C, 0x88, 0x20, 0xE3, 0xA3, 0xE8,
-  0xE8, 0xE8, 0xE4, 0xEE, 0xD3, 0x7E, 0x73, 0x5C,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0x5C, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x2C, 0xAF, 0xAF, 0xAC, 0xD9, 0xD9, 0xD9,
-  0xD9, 0xD9, 0xD6, 0x21, 0x7D, 0x95, 0x95, 0x7D,
-  0xD6, 0xB2, 0xA1, 0xA1, 0xB2, 0xD6, 0x21, 0x21,
-  0x21, 0xD9, 0xD9, 0xD9, 0xAC, 0xAF, 0xAC, 0xAF,
-  0x2C, 0x2C, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9, 0x95,
-  0x7D, 0xB2, 0xD6, 0x95, 0xD9, 0x95, 0xD6, 0xA1,
-  0xA1, 0xAF, 0x5B, 0x20, 0x20, 0xD6, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0x5C, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0x48, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0xE3, 0x8A, 0x2C, 0xAC, 0xAC, 0xD9, 0xD9,
-  0xD9, 0x95, 0xD6, 0xB2, 0xD6, 0x95, 0xD9, 0x95,
-  0x21, 0xB2, 0xA1, 0xB2, 0xD6, 0xD6, 0xD6, 0xA1,
-  0xD9, 0x2C, 0x2C, 0x2C, 0xAF, 0xAF, 0xAC, 0xAF,
-  0x2C, 0x2C, 0xAF, 0xAC, 0xD9, 0xAC, 0xD9, 0xD9,
-  0xD9, 0x95, 0xAC, 0x2C, 0x2C, 0xAC, 0x95, 0x7D,
-  0xD9, 0x91, 0x20, 0x20, 0xE3, 0xA3, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0x85, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x2B, 0x8A, 0xAF, 0xAC, 0xD9, 0xAC,
-  0xD9, 0xD9, 0xD9, 0x95, 0xAC, 0x2C, 0x2C, 0xAC,
-  0x95, 0x7D, 0x95, 0x95, 0xD9, 0x95, 0x7D, 0x21,
-  0x2C, 0xDA, 0xDA, 0x85, 0x2C, 0xAF, 0xAF, 0xAF,
-  0xAF, 0xAF, 0x2C, 0xAF, 0xAF, 0xAC, 0xAC, 0xAC,
-  0xD9, 0xAF, 0x85, 0x85, 0x2C, 0xAF, 0xD9, 0xAF,
-  0x48, 0x20, 0x20, 0x20, 0xE6, 0xA3, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0x5C,
-  0xE4, 0x73, 0x41, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x2B, 0xDA, 0xAF, 0xAF, 0xAC,
-  0xAC, 0xAF, 0xD9, 0x2C, 0x85, 0x85, 0x2C, 0xAF,
-  0xD9, 0xD9, 0xAC, 0xAF, 0xAC, 0xD9, 0xD9, 0xD9,
-  0x85, 0xDA, 0xDA, 0x85, 0x2C, 0x2C, 0xAC, 0xAF,
-  0xAF, 0xAF, 0xAF, 0x2C, 0xAF, 0xAF, 0xAC, 0xAC,
-  0xAF, 0x2C, 0x2C, 0x2C, 0xAC, 0x95, 0x95, 0xA1,
-  0x20, 0x20, 0x20, 0x20, 0xE9, 0x8C, 0x5C, 0xE8,
-  0xE8, 0xE8, 0xE8, 0x3D, 0x73, 0x73, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE4, 0x73, 0x73, 0x73, 0xCD,
-  0x7E, 0xA3, 0x74, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x24, 0x85, 0xAF, 0xAF,
-  0xAC, 0xAC, 0xAC, 0xAF, 0x85, 0x2C, 0xAC, 0x95,
-  0x95, 0xD9, 0xAC, 0xAC, 0xAC, 0xD9, 0xAC, 0xAF,
-  0x8A, 0x8A, 0xDA, 0xDA, 0x85, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x2C, 0x2C, 0xAF, 0xAF, 0xAC, 0xAF, 0xAC,
-  0xAC, 0xAF, 0xAF, 0xD9, 0xD6, 0xD6, 0x2C, 0x88,
-  0x20, 0x20, 0x20, 0x88, 0xB2, 0xDA, 0x7E, 0x73,
-  0xE8, 0xE8, 0xE8, 0x3D, 0x73, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xA3, 0xCD, 0xD3, 0x2A, 0x2A,
-  0x2A, 0x8C, 0x8D, 0x88, 0x20, 0xE3, 0x6B, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x41, 0x85, 0xAF, 0xAC,
-  0xAC, 0xAC, 0xAC, 0xAF, 0xAC, 0xD9, 0x7D, 0xD6,
-  0x7D, 0x7D, 0xD9, 0x95, 0xD9, 0xAC, 0xAC, 0xAF,
-  0xD3, 0x8D, 0xDA, 0xDA, 0x85, 0x85, 0x2C, 0x2C,
-  0x2C, 0xAF, 0xAF, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xAF, 0xAF, 0xAC, 0xD9, 0x95, 0x7D, 0xAC, 0x20,
-  0x20, 0x20, 0x20, 0xDB, 0x2C, 0xA3, 0x5C, 0xE8,
-  0xE8, 0xE8, 0xE8, 0x5C, 0x3D, 0x3D, 0xE8, 0xE8,
-  0xE8, 0xE4, 0xE8, 0xE8, 0xE8, 0xE4, 0x73, 0xEE,
-  0xD3, 0x2A, 0xEE, 0xAC, 0x20, 0x33, 0x2B, 0xE3,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x9F, 0xAF, 0xD9,
-  0xD9, 0xAC, 0xAF, 0xAF, 0xAC, 0xD9, 0x95, 0x7D,
-  0xD9, 0x95, 0x95, 0x95, 0x95, 0xD9, 0xAF, 0xAF,
-  0x7E, 0x85, 0x85, 0x2C, 0x85, 0x85, 0x85, 0x2C,
-  0x2C, 0x2C, 0xAF, 0xD9, 0xD9, 0x95, 0xD9, 0xAC,
-  0xAC, 0xAF, 0xAF, 0xAC, 0xAC, 0xAC, 0x91, 0x20,
-  0x33, 0xE3, 0x41, 0x48, 0x73, 0x5C, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xA3, 0xD6, 0x6C, 0x85, 0xE8,
-  0xDA, 0xAE, 0xB2, 0xA3, 0x5C, 0xE8, 0xE8, 0xE8,
-  0x3D, 0xEE, 0x4D, 0xA3, 0x24, 0x20, 0x6B, 0xDB,
-  0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x85, 0x95,
-  0xD9, 0xD9, 0xAC, 0xAF, 0xAF, 0xAC, 0xD9, 0xAC,
-  0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xAC, 0xD9, 0xAC,
-  0x8A, 0xD9, 0xAC, 0xD9, 0xAC, 0xAC, 0x2C, 0x2C,
-  0xAF, 0xAF, 0xAF, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xAF, 0xAF, 0xAF, 0xAC, 0xAC, 0x85, 0x33, 0x20,
-  0xCC, 0x20, 0xE3, 0xA3, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xA3, 0xD9, 0x81, 0xAC, 0xDA, 0x2D, 0x5C,
-  0x48, 0x41, 0x88, 0x74, 0x21, 0xA3, 0xE8, 0xE8,
-  0xE8, 0xE8, 0x73, 0x8C, 0x8A, 0x20, 0x20, 0x20,
-  0xDB, 0x33, 0x20, 0x20, 0x20, 0x20, 0xE6, 0xD9,
-  0xD9, 0xAC, 0xAC, 0xAF, 0xAC, 0xAF, 0xAC, 0xAF,
-  0xAF, 0xAC, 0xD9, 0xAF, 0xD9, 0xAC, 0xAC, 0xAF,
-  0x85, 0xD9, 0x95, 0xD9, 0x95, 0xD9, 0xD9, 0xAC,
-  0xAF, 0xAC, 0xAF, 0xAF, 0x2C, 0xAF, 0x2C, 0x2C,
-  0xAF, 0xAF, 0xAF, 0xAC, 0xAC, 0x2C, 0x20, 0x5B,
-  0x33, 0x20, 0xD6, 0xE8, 0xE8, 0xE8, 0xE8, 0x73,
-  0xAF, 0x2D, 0xD9, 0xDA, 0xB2, 0x81, 0x81, 0xE4,
-  0xA1, 0x91, 0x2B, 0x88, 0x33, 0x80, 0xAF, 0x73,
-  0xE8, 0xE8, 0xE8, 0x5C, 0xA3, 0x80, 0x41, 0xCC,
-  0x2B, 0xCC, 0x20, 0x20, 0x20, 0x20, 0x88, 0xDA,
-  0x2C, 0x2C, 0x2C, 0xAF, 0xAF, 0xAC, 0xAC, 0xAF,
-  0xAF, 0xAF, 0xAF, 0xAC, 0xAF, 0xAF, 0xAF, 0x2C,
-  0x85, 0xD9, 0xD9, 0xD9, 0xD9, 0xAC, 0xAC, 0xD9,
-  0xD9, 0xD9, 0xAC, 0x2C, 0x2C, 0x2C, 0x85, 0x85,
-  0x85, 0x2C, 0x2C, 0xAF, 0x2C, 0x91, 0x20, 0xAE,
-  0x20, 0xDB, 0x3D, 0xE8, 0xE8, 0x5C, 0xB2, 0x80,
-  0xB2, 0xAF, 0x48, 0xB2, 0x48, 0x89, 0x89, 0x3D,
-  0x21, 0x48, 0x6C, 0x2D, 0x2B, 0x41, 0xE3, 0xAE,
-  0xD9, 0x5C, 0xE8, 0xE8, 0xE8, 0x95, 0x33, 0x80,
-  0xAE, 0x33, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x95,
-  0x85, 0x2C, 0x85, 0x2C, 0x2C, 0xAF, 0x2C, 0x2C,
-  0x2C, 0xAF, 0xAC, 0xAF, 0xAF, 0x2C, 0x2C, 0x2C,
-  0xDA, 0xAF, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C, 0x2C,
-  0xAC, 0xD9, 0xAC, 0xAF, 0x2C, 0x85, 0x2C, 0x85,
-  0x85, 0x2C, 0x2C, 0x2C, 0x8A, 0x41, 0xDB, 0x33,
-  0x20, 0x95, 0xE8, 0xE8, 0xE8, 0xA3, 0xDB, 0x88,
-  0xDB, 0x80, 0xD6, 0x7E, 0x85, 0x2D, 0xE6, 0x5C,
-  0x21, 0x48, 0xD9, 0x7E, 0xD6, 0x2B, 0xCC, 0xAC,
-  0x85, 0xBC, 0xE8, 0xE8, 0xE8, 0xCD, 0x88, 0x5B,
-  0x41, 0x20, 0xAE, 0x20, 0x20, 0x20, 0x20, 0x74,
-  0xDA, 0x85, 0x85, 0x85, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xAF, 0xAC, 0xD9, 0xD9, 0xAC, 0xAC, 0xAC, 0xD9,
-  0x8A, 0xAF, 0xAC, 0xAC, 0x2C, 0x85, 0x2C, 0xAF,
-  0xD9, 0xD9, 0xAF, 0xAF, 0xAF, 0x2C, 0xAF, 0x2C,
-  0x2C, 0x2C, 0x2C, 0xAF, 0x95, 0x20, 0x74, 0x20,
-  0x33, 0xA3, 0xE8, 0xE8, 0xE8, 0xE4, 0x7D, 0xCC,
-  0x6B, 0x33, 0xAE, 0x2C, 0x85, 0x2D, 0x9F, 0x73,
-  0xA1, 0x2D, 0x2C, 0xDA, 0x89, 0x48, 0xD3, 0xD9,
-  0x21, 0xA3, 0xE8, 0xE8, 0xE8, 0xE8, 0xE3, 0x20,
-  0x20, 0x20, 0xDB, 0x41, 0x20, 0x20, 0x20, 0x20,
-  0xDA, 0x2C, 0x2C, 0x2C, 0x2C, 0xAF, 0xAC, 0xAC,
-  0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0x95, 0x95, 0xD9,
-  0x2C, 0xD9, 0xD9, 0xAC, 0x2C, 0x2C, 0x85, 0xAF,
-  0xAF, 0xAF, 0xAC, 0xAC, 0xD9, 0xAC, 0xAF, 0xAC,
-  0xAC, 0x95, 0xD6, 0x7D, 0xAE, 0x88, 0x2B, 0x20,
-  0x6C, 0xE8, 0xE8, 0xE8, 0x73, 0xEE, 0x73, 0x2C,
-  0x89, 0x2B, 0x41, 0x33, 0xCC, 0xCC, 0x80, 0x3D,
-  0x2D, 0x74, 0x80, 0x48, 0x8D, 0x95, 0x48, 0x95,
-  0xEE, 0x5C, 0x5C, 0xE8, 0xE8, 0xE8, 0x24, 0x20,
-  0x20, 0x20, 0x5B, 0xDB, 0x20, 0x20, 0x20, 0x20,
-  0xAF, 0xAC, 0xD9, 0x95, 0xD6, 0xD6, 0xD6, 0x7D,
-  0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0xD9, 0xAC,
-  0xAC, 0xD9, 0xD9, 0xAC, 0x2C, 0x2C, 0x2C, 0xAF,
-  0xAC, 0xAC, 0xAC, 0xAC, 0xD9, 0xAC, 0xAC, 0xD9,
-  0xD6, 0x48, 0xE9, 0x95, 0x20, 0x2B, 0x41, 0x6B,
-  0x8D, 0xE8, 0xE8, 0xCD, 0x2B, 0x2B, 0x2C, 0x73,
-  0xCD, 0x48, 0xCA, 0x5B, 0x41, 0x5B, 0x74, 0xDA,
-  0x80, 0xE6, 0xC8, 0x85, 0xA1, 0x7D, 0x8D, 0x3D,
-  0x7E, 0xE9, 0x7D, 0xEE, 0xE8, 0xE8, 0x81, 0x20,
-  0x20, 0x20, 0xE3, 0xE3, 0x20, 0x20, 0x20, 0x20,
-  0x2D, 0xD9, 0xD6, 0x48, 0x6C, 0xE9, 0xA1, 0xD6,
-  0xD9, 0xD9, 0xAC, 0xD9, 0xD9, 0x95, 0xAC, 0x2C,
-  0x2C, 0x2C, 0x2C, 0xD9, 0xAC, 0x2C, 0x2C, 0x2C,
-  0xAF, 0x2C, 0xAF, 0xD9, 0xAC, 0xAF, 0xAF, 0x95,
-  0xB2, 0xE9, 0x21, 0x2B, 0x41, 0x2B, 0x20, 0x5B,
-  0x3D, 0xE8, 0xE8, 0x8D, 0x2B, 0x88, 0x5B, 0xE6,
-  0xBC, 0x73, 0x85, 0x89, 0x80, 0x5B, 0xE3, 0xAE,
-  0x2C, 0x8A, 0xD6, 0xB2, 0x2C, 0xA3, 0xA3, 0xD9,
-  0xA1, 0x2C, 0x85, 0x8D, 0xE8, 0xE8, 0x48, 0x20,
-  0x20, 0x20, 0xE3, 0x88, 0x20, 0x20, 0x20, 0x20,
-  0xAE, 0xD9, 0xB2, 0xE9, 0x6C, 0x48, 0xD6, 0xD9,
-  0x2C, 0x85, 0x2C, 0xD9, 0x7D, 0xD9, 0x2C, 0x85,
-  0x8D, 0x85, 0x2C, 0xAC, 0xAF, 0x2C, 0x2C, 0x85,
-  0x2C, 0x2C, 0xAF, 0xAC, 0xAC, 0xAF, 0xAF, 0xD9,
-  0xB2, 0x48, 0xB2, 0x20, 0x20, 0xCC, 0x20, 0x9F,
-  0xE8, 0xE8, 0xE8, 0xCD, 0x48, 0x89, 0xDB, 0x88,
-  0x2B, 0xE9, 0xCD, 0x2A, 0x48, 0x80, 0xAE, 0xAE,
-  0x7D, 0x48, 0x21, 0xEE, 0x3D, 0x2C, 0x48, 0x85,
-  0x2C, 0x95, 0x7D, 0x8C, 0xE8, 0xE8, 0xB2, 0x20,
-  0x20, 0x20, 0xDB, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0xDB, 0x2C, 0xB2, 0x48, 0x48, 0x7D, 0xD9, 0xAF,
-  0x85, 0x8A, 0x85, 0x7D, 0xB2, 0x95, 0x85, 0xDA,
-  0xD3, 0x85, 0xAF, 0xAC, 0x2C, 0x85, 0x85, 0x2C,
-  0xAC, 0xAC, 0xAC, 0xD9, 0xD9, 0xAC, 0x2C, 0x2C,
-  0xD9, 0xAC, 0x5B, 0x20, 0x20, 0xAE, 0x20, 0x2D,
-  0xE8, 0xE8, 0xE8, 0x7E, 0xD6, 0x48, 0xE9, 0xAE,
-  0x88, 0x5B, 0x80, 0x6C, 0xAE, 0xCA, 0x91, 0xE9,
-  0x43, 0x9F, 0xE6, 0x2C, 0x48, 0x21, 0xBC, 0x95,
-  0x95, 0xD6, 0x21, 0x7E, 0xE8, 0xE8, 0x7D, 0x20,
-  0x20, 0x20, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x6B, 0xDA, 0xD9, 0x48, 0xB2, 0xD9, 0x2C, 0x85,
-  0xDA, 0xDA, 0x2C, 0xA1, 0x48, 0xAC, 0xDA, 0x8D,
-  0x2A, 0xAC, 0x7D, 0x95, 0xAF, 0x85, 0x2C, 0x2C,
-  0xAC, 0xD9, 0x95, 0x7D, 0x95, 0xAC, 0x2C, 0xAF,
-  0x7D, 0xD6, 0x20, 0x20, 0x88, 0x9F, 0x20, 0xA1,
-  0xE8, 0xE8, 0xE8, 0xA3, 0xD6, 0x6C, 0xB2, 0x2C,
-  0x89, 0xE3, 0x88, 0xDB, 0xCC, 0x24, 0x7D, 0xEE,
-  0xB2, 0xCC, 0xAE, 0x2D, 0xDA, 0x2C, 0xD6, 0x2C,
-  0xB2, 0x2D, 0xD6, 0xEE, 0xE8, 0xE8, 0x95, 0x20,
-  0x20, 0x20, 0xDB, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x6B, 0xDA, 0x95, 0xA1, 0xB2, 0xAC, 0x85, 0x85,
-  0xDA, 0x2C, 0x95, 0xA1, 0x21, 0x2C, 0x8A, 0x2A,
-  0xAF, 0xA1, 0x48, 0xD6, 0xAF, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xD9, 0x95, 0x7D, 0x95, 0xAC, 0xD9, 0x7D,
-  0x48, 0xE6, 0x20, 0x20, 0x33, 0x89, 0x6B, 0x95,
-  0xE8, 0xE8, 0xE8, 0xA3, 0x21, 0x48, 0xAF, 0xAF,
-  0x9F, 0xE9, 0x43, 0x33, 0x33, 0x2D, 0xDA, 0xCD,
-  0xD6, 0xAE, 0x85, 0x2C, 0x7D, 0xD6, 0x91, 0xB8,
-  0xD4, 0x48, 0x7D, 0xA3, 0xE8, 0xE8, 0x95, 0x20,
-  0x20, 0x33, 0xE3, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x2C, 0x48, 0x6C, 0xB2, 0xAF, 0xDA, 0xDA,
-  0x85, 0xAF, 0xD9, 0x95, 0xAC, 0xDA, 0x8A, 0xDA,
-  0x7D, 0x48, 0x48, 0x7D, 0x2C, 0x85, 0x2C, 0xAF,
-  0xD9, 0xD9, 0x7D, 0x95, 0xD9, 0xD9, 0x95, 0xD6,
-  0x21, 0x24, 0x20, 0x20, 0x20, 0x5B, 0xDB, 0xAC,
-  0xE8, 0xE8, 0xE8, 0x3D, 0x7D, 0x48, 0xE6, 0x2D,
-  0x85, 0x81, 0x81, 0x48, 0xAE, 0xCA, 0x89, 0xCC,
-  0xAE, 0xDB, 0x2D, 0x95, 0x21, 0xCC, 0xDB, 0xAE,
-  0x91, 0xE9, 0x7D, 0x73, 0xE8, 0xE8, 0x48, 0x20,
-  0x6B, 0x74, 0x41, 0x88, 0x6B, 0x20, 0x20, 0x20,
-  0x6B, 0x95, 0xB2, 0xD6, 0xD9, 0x85, 0xDA, 0xDA,
-  0xDA, 0x2C, 0xAF, 0xAF, 0x2C, 0xDA, 0xDA, 0x85,
-  0xA1, 0xE9, 0x48, 0x95, 0x85, 0xDA, 0x85, 0xAC,
-  0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9, 0xD9, 0x95,
-  0x95, 0x6C, 0x41, 0x93, 0x93, 0x41, 0xDB, 0x95,
-  0xE8, 0xE8, 0xE8, 0x3D, 0x95, 0xD4, 0x6C, 0x21,
-  0x2D, 0x95, 0xCD, 0x2C, 0xD6, 0xD9, 0x6C, 0x91,
-  0x89, 0x7D, 0xAC, 0x2A, 0x8D, 0xE6, 0xCC, 0x88,
-  0x74, 0x48, 0xD9, 0xE4, 0xE8, 0xE8, 0xE6, 0x88,
-  0x2B, 0x88, 0x20, 0x33, 0xDB, 0x2B, 0xDB, 0x20,
-  0x91, 0x7D, 0xD9, 0xD9, 0x85, 0x85, 0xDA, 0xDA,
-  0x85, 0xAF, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xA1, 0xA1, 0xD6, 0xAF, 0x85, 0xDA, 0x85, 0x2C,
-  0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9, 0xD9, 0xAC,
-  0x2C, 0x47, 0x87, 0x3E, 0x3E, 0xA4, 0x7B, 0x80,
-  0xA3, 0xE8, 0xE8, 0x5C, 0x7D, 0x48, 0xE6, 0xD9,
-  0xBC, 0xEE, 0x7D, 0x43, 0xD6, 0x21, 0x43, 0x6C,
-  0x43, 0x7D, 0x7D, 0xB2, 0x8A, 0xEE, 0x2C, 0xCA,
-  0xAE, 0x48, 0x2C, 0xE4, 0xE8, 0x5C, 0xCC, 0x88,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x91, 0xE3,
-  0x21, 0xD9, 0x2C, 0x2C, 0xDA, 0xDA, 0xDA, 0x85,
-  0x2C, 0xAC, 0xD9, 0xD9, 0xAC, 0xAF, 0xAF, 0xAF,
-  0xD6, 0x7D, 0xD9, 0x2C, 0xDA, 0xDA, 0x85, 0xAC,
-  0xD9, 0x7D, 0x7D, 0xD9, 0xD9, 0xD9, 0x2C, 0x2C,
-  0xB8, 0x9C, 0xEC, 0x62, 0x6F, 0x62, 0x70, 0x3C,
-  0xAE, 0xCD, 0xE8, 0xE8, 0x8C, 0x7D, 0xC8, 0x3D,
-  0x8A, 0xE9, 0x2D, 0x9E, 0xA1, 0xD6, 0x48, 0x73,
-  0x81, 0xD6, 0xD6, 0xAE, 0x5B, 0x2D, 0xA3, 0xA3,
-  0x21, 0x21, 0xCD, 0xE8, 0xC0, 0x56, 0x31, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x33, 0xCC, 0xDB,
-  0x42, 0x85, 0x85, 0x85, 0x85, 0x85, 0x2C, 0x2C,
-  0xAC, 0xD9, 0xD9, 0xD9, 0xAC, 0xAF, 0xAF, 0xAF,
-  0xD9, 0x95, 0xAC, 0x2C, 0x85, 0x85, 0x2C, 0xD9,
-  0x7D, 0xD6, 0xD6, 0xD9, 0xAC, 0xAF, 0x8A, 0xBC,
-  0xC2, 0x68, 0x2E, 0x4B, 0xC9, 0x8B, 0x62, 0x87,
-  0x3C, 0x74, 0xBC, 0xE8, 0xE8, 0xE4, 0xEE, 0xA1,
-  0xE9, 0x21, 0xE6, 0x89, 0x48, 0x7D, 0xB2, 0x5C,
-  0x6C, 0x7D, 0x21, 0x80, 0xE3, 0x33, 0xCC, 0x2C,
-  0x3D, 0x3D, 0xE8, 0xE8, 0xEC, 0xCB, 0x5A, 0x6B,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x88, 0x41, 0x51,
-  0x49, 0x28, 0x85, 0x85, 0x85, 0x85, 0x2C, 0xAF,
-  0xAC, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xD9, 0x95, 0xD9, 0x2C, 0x85, 0x85, 0x2C, 0xD9,
-  0xB2, 0xB2, 0x2C, 0x2A, 0x79, 0x79, 0x97, 0x44,
-  0xED, 0x29, 0x32, 0x62, 0x4B, 0x62, 0x6F, 0x22,
-  0xF3, 0x6B, 0x33, 0x85, 0x73, 0xE4, 0x2D, 0x2B,
-  0xCC, 0x9F, 0xDA, 0xBC, 0x48, 0xD6, 0xA1, 0xE4,
-  0xE9, 0xD6, 0xD9, 0x2A, 0xB2, 0x2B, 0x2B, 0xA1,
-  0xB8, 0xE8, 0xE8, 0xE8, 0xEC, 0x3E, 0x30, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x6B, 0x54, 0xDC,
-  0xC9, 0x53, 0xBC, 0x2C, 0x2C, 0x2C, 0xAF, 0xAF,
-  0xAF, 0xAC, 0xAF, 0xAC, 0xAC, 0x2C, 0xAF, 0xAC,
-  0x2C, 0x7D, 0xD9, 0x2C, 0x85, 0xDA, 0xAF, 0x7D,
-  0xB2, 0xAC, 0xC6, 0xBA, 0x4C, 0xEF, 0xA7, 0xEF,
-  0xEC, 0x7A, 0x62, 0x4B, 0x62, 0x4B, 0x8B, 0x4B,
-  0x3A, 0x52, 0x20, 0x6B, 0x21, 0x73, 0xAC, 0x2B,
-  0x41, 0x33, 0x48, 0x67, 0xA1, 0xD6, 0xD6, 0x5C,
-  0xE9, 0xD6, 0x2C, 0xEE, 0xB2, 0x9F, 0x8A, 0x95,
-  0x4D, 0xE8, 0xE8, 0x3D, 0x7A, 0x57, 0xD1, 0x7B,
-  0x20, 0x20, 0x20, 0x20, 0x6B, 0xCF, 0xBA, 0x3E,
-  0x3E, 0xD0, 0xBC, 0xAC, 0xAC, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xD9, 0x95, 0x95, 0x7D, 0x95, 0x95, 0xD9,
-  0x85, 0xD9, 0xAF, 0xDA, 0xDA, 0x85, 0xAC, 0x21,
-  0xB2, 0x2A, 0xBA, 0x57, 0x2E, 0x2E, 0x2E, 0x7A,
-  0x32, 0x62, 0x8B, 0x4B, 0x8B, 0x4B, 0x4B, 0x4B,
-  0xC9, 0x4A, 0x5F, 0x20, 0x20, 0x2D, 0xA3, 0xD9,
-  0xCA, 0x88, 0xDB, 0x24, 0x48, 0x7D, 0xB2, 0xE4,
-  0x2D, 0x7D, 0x7D, 0x81, 0xA1, 0xDA, 0x21, 0xDA,
-  0xE4, 0xE8, 0xEE, 0xF1, 0x2E, 0x57, 0x82, 0x76,
-  0x52, 0x4F, 0x4F, 0x98, 0xDE, 0xB5, 0xEC, 0x2E,
-  0x3E, 0x6D, 0x85, 0x2C, 0xAC, 0xAC, 0xD9, 0xD9,
-  0x95, 0xD6, 0x7D, 0x7D, 0x95, 0xD9, 0xD9, 0xD9,
-  0xDA, 0x2C, 0x85, 0xDA, 0xDA, 0x2C, 0x95, 0xB2,
-  0x21, 0xB8, 0xED, 0x2E, 0x3E, 0x4B, 0xC9, 0x4B,
-  0x8B, 0x62, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x22, 0x6F, 0xCE, 0x20, 0x20, 0x20, 0x80, 0xCD,
-  0xDA, 0x2D, 0x2B, 0xDB, 0xE9, 0xD6, 0x95, 0x5C,
-  0x2D, 0x7D, 0x7D, 0xAF, 0xAF, 0xAC, 0xEE, 0x5C,
-  0xE8, 0xE8, 0xEB, 0x25, 0x7A, 0x57, 0x39, 0xE1,
-  0x83, 0xA8, 0x55, 0x83, 0x82, 0x57, 0x32, 0x8B,
-  0x62, 0x6D, 0xEB, 0x95, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xD9, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xDA, 0x2C, 0x85, 0x85, 0x85, 0xAC, 0xD6, 0x21,
-  0x95, 0x6E, 0xED, 0x57, 0x62, 0x4B, 0x8B, 0x4B,
-  0x4B, 0x62, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x62,
-  0x62, 0x62, 0x25, 0x3C, 0x20, 0x20, 0x20, 0xE3,
-  0x2A, 0xBC, 0x7D, 0xCA, 0x6C, 0xD6, 0x95, 0x3D,
-  0x81, 0x7D, 0xD6, 0xD6, 0xDA, 0x73, 0xE8, 0xE8,
-  0xE8, 0x4D, 0x94, 0xED, 0x72, 0x3A, 0xF1, 0xA7,
-  0x39, 0xED, 0x39, 0xEF, 0x57, 0x32, 0x8B, 0x4B,
-  0x62, 0x62, 0xA6, 0x2A, 0xD9, 0xD9, 0xD9, 0xD9,
-  0x2C, 0x2C, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-  0x85, 0x2C, 0x2C, 0xAF, 0xAC, 0x95, 0x21, 0x7D,
-  0xAC, 0x8C, 0x46, 0xC4, 0x62, 0x8B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x62, 0xC9, 0x30, 0x7B, 0x20, 0x20, 0x20,
-  0x41, 0x4D, 0x3D, 0x85, 0x48, 0x21, 0xDA, 0x3D,
-  0xE9, 0xD6, 0xD9, 0xCD, 0x5C, 0xE8, 0xE8, 0xE8,
-  0xE8, 0x4D, 0x71, 0x46, 0xEC, 0x2E, 0x72, 0xEC,
-  0x29, 0x29, 0x7C, 0x29, 0x2E, 0x4B, 0x4B, 0x62,
-  0x62, 0x4B, 0x3A, 0xAD, 0xE2, 0xAF, 0xD9, 0xD9,
-  0x2C, 0xDA, 0xDA, 0xDA, 0xDA, 0x85, 0x2C, 0x2C,
-  0x2C, 0xAF, 0xAC, 0xD9, 0x95, 0xD6, 0xD6, 0xD9,
-  0x2C, 0x8C, 0xBA, 0x7C, 0x2E, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x62, 0xC9, 0xDC, 0x34, 0x20, 0x20, 0x20,
-  0x20, 0xAC, 0xE8, 0x5C, 0x8C, 0xBC, 0xE4, 0xE8,
-  0xEE, 0x2A, 0xA3, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE4, 0x7E, 0x65, 0x46, 0x29, 0x62, 0x62, 0x2E,
-  0x2E, 0x72, 0x2E, 0x2E, 0x32, 0x4B, 0x4B, 0x62,
-  0x4B, 0x4B, 0x4B, 0x32, 0x61, 0x9D, 0x2C, 0xD9,
-  0x2C, 0x85, 0xDA, 0x85, 0x2C, 0xAF, 0xAF, 0xAF,
-  0x2C, 0xAC, 0xD9, 0x95, 0xD6, 0x7D, 0x95, 0xAC,
-  0x2C, 0xDA, 0x40, 0x7C, 0x2E, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x62, 0x62, 0x22, 0xB7, 0xCE, 0x20, 0x20,
-  0x20, 0x95, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0x5C,
-  0x3D, 0xE9, 0x9A, 0x46, 0x7C, 0x32, 0x8B, 0x62,
-  0x4B, 0x8B, 0x8B, 0x4B, 0x4B, 0x4B, 0x4B, 0x62,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x62, 0x61, 0x4E, 0xDA,
-  0x85, 0x85, 0x85, 0x2C, 0xD9, 0xD9, 0xD9, 0xD9,
-  0x85, 0xD9, 0x7D, 0x21, 0x21, 0xD6, 0xAC, 0x2C,
-  0x2C, 0xDA, 0xDD, 0x77, 0x8B, 0x62, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x3E, 0x8B, 0x32, 0xC9, 0x22, 0x68, 0x88, 0x33,
-  0xA1, 0x73, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0x5C, 0x5C, 0x5C, 0x5C, 0x3D,
-  0x89, 0x20, 0x54, 0x23, 0x29, 0x2E, 0x4B, 0x62,
-  0x4B, 0x3E, 0x4B, 0x62, 0x4B, 0x4B, 0x4B, 0x8B,
-  0x8B, 0xC9, 0x6F, 0x4B, 0x8B, 0x4B, 0x78, 0xE2,
-  0x8A, 0x8A, 0x85, 0xAC, 0xD9, 0x7D, 0xD9, 0xAC,
-  0x2C, 0xD9, 0xD6, 0xB2, 0x21, 0x7D, 0xAF, 0x85,
-  0x2C, 0xDA, 0x40, 0xEF, 0x62, 0x62, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x8B, 0x4B, 0xC9, 0x63, 0xB4, 0x5C,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0x5C, 0x5C, 0xCD, 0xAE,
-  0x20, 0x20, 0xCE, 0xE1, 0x57, 0x32, 0x4B, 0x4B,
-  0x8B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x8B, 0x4B, 0x62, 0x4B, 0x62, 0x2E, 0x61, 0x28,
-  0x8D, 0xDA, 0xAF, 0xD9, 0x95, 0x95, 0xD9, 0xAF,
-  0xAF, 0xD9, 0xD6, 0xB2, 0x21, 0xD9, 0x2C, 0x85,
-  0xAF, 0xEB, 0xE1, 0x57, 0x2E, 0x62, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x3E, 0x9B, 0x31, 0x6E,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0x5C, 0xE8, 0xE8, 0xE8, 0x3D, 0x7D, 0x33, 0x6B,
-  0x20, 0x20, 0x34, 0x23, 0x29, 0x3E, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x3E, 0x62, 0x62, 0x2E, 0xC4, 0x49, 0xD5,
-  0xDA, 0xD9, 0xD6, 0xA1, 0xA1, 0x21, 0xD9, 0xD9,
-  0xD9, 0x95, 0x21, 0x48, 0xD6, 0xAC, 0x85, 0x85,
-  0xAF, 0xB6, 0x5D, 0x2E, 0x32, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x62, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x62, 0x2E, 0x45, 0xDE,
-  0xDA, 0x5C, 0xE8, 0x5C, 0xE8, 0xE8, 0x5C, 0xE8,
-  0x5C, 0x5C, 0xA3, 0xAC, 0x2B, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x34, 0x23, 0x29, 0x62, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x62, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x3E, 0x3E, 0x63, 0x40, 0x97, 0x28, 0xDA,
-  0xD9, 0xA1, 0x48, 0xE9, 0x48, 0x21, 0xD9, 0xD9,
-  0xA1, 0xB2, 0xB2, 0xA1, 0x21, 0xAC, 0x85, 0x2C,
-  0xDA, 0x36, 0x77, 0x72, 0x62, 0x8B, 0x62, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x3E, 0xEC, 0x2F, 0x51,
-  0xE3, 0xAE, 0x48, 0x2C, 0xDA, 0xDA, 0x85, 0xAC,
-  0x48, 0x9E, 0x88, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x41, 0xA0, 0x23, 0x72, 0x2E, 0x4B, 0x4B,
-  0x4B, 0x62, 0x62, 0x4B, 0x4B, 0x4B, 0x2E, 0x8B,
-  0xF0, 0x4C, 0x40, 0xC2, 0x90, 0x8D, 0x85, 0xD9,
-  0xA1, 0x6C, 0x6C, 0x48, 0xD6, 0xD9, 0xAF, 0xAC,
-  0xA1, 0xD6, 0xD6, 0xB2, 0xD6, 0xAC, 0x85, 0x85,
-  0x4D, 0xBE, 0x39, 0x4C, 0x57, 0x2E, 0x2E, 0x2E,
-  0x3E, 0x3E, 0x62, 0x3E, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x8B, 0x8B, 0x57, 0x60, 0x76,
-  0x52, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x3C, 0xA0, 0x23, 0x7C, 0x2E, 0x4B, 0x4B,
-  0x8B, 0x62, 0x4B, 0x4B, 0x3E, 0x7A, 0xF0, 0x29,
-  0x36, 0x97, 0xBC, 0x8A, 0x8D, 0xDA, 0xD9, 0x48,
-  0x81, 0x2D, 0x48, 0xD6, 0xD9, 0xAF, 0x2C, 0x2C,
-  0xAC, 0xAF, 0xD9, 0x7D, 0x7D, 0x2C, 0x85, 0x85,
-  0x85, 0xB4, 0x66, 0x23, 0x46, 0x2F, 0x60, 0x68,
-  0x77, 0x29, 0x29, 0xF0, 0x2E, 0x2E, 0x62, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x32, 0x7C, 0x83, 0xB3,
-  0x54, 0x6B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x6B, 0x7B, 0xC3, 0xE7, 0x39, 0x72, 0x62, 0x62,
-  0x62, 0x62, 0x62, 0x2E, 0x29, 0x77, 0xA7, 0x36,
-  0xB8, 0x85, 0x85, 0x8D, 0x8D, 0x85, 0xB2, 0x2D,
-  0x2D, 0xE9, 0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0x85,
-  0x2A, 0x85, 0xAC, 0x95, 0x95, 0xAF, 0x85, 0x85,
-  0xAF, 0x8C, 0xDF, 0xC6, 0xB1, 0xD1, 0xE5, 0xE7,
-  0x83, 0x23, 0x5D, 0x60, 0x39, 0x77, 0xEC, 0x2E,
-  0x2E, 0x32, 0x32, 0x2E, 0x7C, 0x5D, 0x35, 0xA2,
-  0x54, 0x6B, 0x6B, 0x20, 0x6B, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x6B, 0x88, 0xC1, 0x35, 0xE1, 0x77, 0x57, 0x2E,
-  0x2E, 0x72, 0x29, 0x77, 0x60, 0xB5, 0x44, 0xE2,
-  0x2C, 0x2C, 0xDA, 0x8A, 0xDA, 0xAF, 0xA1, 0x2D,
-  0xE9, 0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0x85, 0x85,
-  0xEE, 0xAF, 0xD9, 0x7D, 0xD9, 0x2C, 0xDA, 0x85,
-  0xAC, 0xAF, 0x85, 0xDA, 0x8A, 0x2A, 0xE2, 0x50,
-  0x86, 0xD7, 0x75, 0x35, 0xA8, 0xE7, 0xE1, 0x5D,
-  0x68, 0x7C, 0xF1, 0x68, 0xE1, 0xBF, 0xA2, 0xC1,
-  0x52, 0x2B, 0x7D, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x85, 0x85, 0x85, 0x2C, 0x2C, 0x2C, 0x95,
-  0xE9, 0x74, 0xCE, 0xE0, 0xE7, 0x60, 0x77, 0x77,
-  0x7C, 0xEF, 0x5D, 0x23, 0x3F, 0xB6, 0x8A, 0x2C,
-  0xAC, 0xAF, 0x85, 0x8A, 0x85, 0xD9, 0x48, 0x48,
-  0xB2, 0x95, 0x95, 0xD9, 0x85, 0xDA, 0x85, 0x85,
-  0xD3, 0xB2, 0x21, 0x7D, 0xAC, 0x2C, 0xDA, 0x85,
-  0xAC, 0xAC, 0x85, 0x85, 0x85, 0x2C, 0xAF, 0x2C,
-  0xDA, 0x8C, 0x79, 0xC7, 0xB0, 0x51, 0xB3, 0x35,
-  0xBF, 0xE5, 0xE7, 0xA8, 0xE0, 0xA2, 0xC1, 0x34,
-  0x7D, 0x85, 0xAC, 0xD9, 0xAC, 0xAF, 0xAC, 0xAC,
-  0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0xAF, 0xAF, 0x85,
-  0xC8, 0xCD, 0x6A, 0x26, 0x35, 0x3F, 0x83, 0x23,
-  0x23, 0xE7, 0xBF, 0x96, 0xEB, 0xDA, 0xDA, 0x2C,
-  0x2C, 0x2C, 0x85, 0xDA, 0x2C, 0x7D, 0xA1, 0x48,
-  0xB2, 0x21, 0xD6, 0xD9, 0x2C, 0xDA, 0x85, 0xAF,
-  0xAF, 0x2D, 0xE9, 0x7D, 0xAC, 0x2C, 0x85, 0x2C,
-  0xD9, 0xD9, 0xAF, 0x85, 0x85, 0x85, 0x2C, 0x2C,
-  0x2C, 0x85, 0xD9, 0x21, 0xAC, 0x2C, 0xBD, 0xA5,
-  0xC3, 0xA2, 0xA2, 0xA2, 0x26, 0xC1, 0xCE, 0x2A,
-  0xAF, 0x95, 0xD9, 0x2C, 0x2C, 0x85, 0x2C, 0xAF,
-  0xAC, 0x2C, 0x85, 0x2C, 0xAF, 0x2C, 0x85, 0xDA,
-  0x8D, 0x2A, 0x85, 0x34, 0xC1, 0xB3, 0x76, 0x35,
-  0xE0, 0x30, 0xA5, 0xB6, 0x2C, 0x85, 0x85, 0x85,
-  0xAF, 0x2C, 0x85, 0x85, 0xD9, 0xD6, 0xA1, 0xA1,
-  0x48, 0xA1, 0xD6, 0xAF, 0xDA, 0x8A, 0x2C, 0xD9,
-  0xB2, 0x2D, 0x48, 0xD9, 0xAF, 0x2C, 0x2C, 0x85,
-  0xAF, 0xAC, 0x2C, 0x85, 0x85, 0x85, 0xAF, 0xAC,
-  0xAC, 0x2C, 0xD9, 0xD6, 0xD6, 0x21, 0xB2, 0x2C,
-  0xC8, 0x3B, 0x65, 0xC5, 0xCE, 0x8E, 0xC8, 0x2C,
-  0xD9, 0x95, 0xAC, 0x2C, 0x2C, 0x2C, 0xAF, 0xAC,
-  0xAC, 0xAF, 0x2C, 0x85, 0x2C, 0x2C, 0x2C, 0x85,
-  0xDA, 0x2C, 0xD6, 0xAF, 0x59, 0x65, 0xDE, 0xF3,
-  0xF3, 0x59, 0xBC, 0xAC, 0xAF, 0x85, 0x85, 0x85,
-  0xAF, 0xD9, 0xAF, 0x2C, 0xD9, 0xD6, 0xD6, 0xD6,
-  0x21, 0xD6, 0xD9, 0xDA, 0x8D, 0x8A, 0x2C, 0xD9,
-  0xB2, 0xA1, 0xD6, 0xAC, 0x2C, 0x2C, 0x2C, 0x85,
-  0x2C, 0xAC, 0x2C, 0xDA, 0xDA, 0x85, 0xAF, 0xD9,
-  0xD9, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xAC,
-  0x85, 0x2A, 0x4D, 0xBC, 0x85, 0xAC, 0xAF, 0xAF,
-  0xAC, 0xD9, 0xAF, 0x2C, 0xAF, 0xD9, 0xD9, 0xAC,
-  0xAC, 0xAF, 0x85, 0x2C, 0x85, 0x2C, 0x2C, 0x2C,
-  0x2C, 0xD9, 0xB2, 0xD4, 0xD6, 0x2C, 0x8A, 0xDA,
-  0xC8, 0x85, 0x2C, 0xAC, 0x2C, 0xDA, 0xDA, 0x85,
-  0xAF, 0xAC, 0xD9, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xD9, 0xAC, 0xDA, 0x8D, 0xBC, 0xDA, 0xD9, 0x95,
-  0x95, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C, 0x2C, 0x85,
-  0x2C, 0xAF, 0xAF, 0x85, 0x85, 0x85, 0x2C, 0xAC,
-  0xD9, 0xAF, 0xAF, 0xAF, 0x2C, 0x2C, 0x2C, 0x85,
-  0x8A, 0x2A, 0x8D, 0x2C, 0xD9, 0x95, 0xAC, 0xAC,
-  0xD9, 0xD9, 0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xAF,
-  0xAF, 0x2C, 0x85, 0x85, 0x85, 0x85, 0x85, 0x2C,
-  0x85, 0x2C, 0xD9, 0xD9, 0xD9, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x85, 0x85, 0xAF, 0xAF, 0x85, 0x85, 0x85,
-  0xAF, 0xD9, 0xD9, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x85, 0x8A, 0x2A, 0x8D, 0x2C, 0xD9, 0xD9,
-  0x2C, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
-  0x85, 0xAF, 0xAC, 0x2C, 0x2C, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xD9, 0xAF, 0x85, 0x85, 0x85, 0xDA, 0xDA,
-  0x8A, 0x8A, 0x85, 0xAC, 0xD9, 0xD9, 0xAC, 0xD9,
-  0xD6, 0xD6, 0x7D, 0x95, 0x7D, 0xD9, 0xAF, 0xAF,
-  0xAF, 0x2C, 0x85, 0x85, 0xDA, 0x85, 0x2C, 0x85,
-  0x85, 0x2C, 0xAF, 0xAC, 0xAF, 0xAF, 0x2C, 0x2C,
-  0x2C, 0x2C, 0x2C, 0xAF, 0xAC, 0x2C, 0x2C, 0x2C,
-  0x2C, 0xAF, 0xD9, 0xAC, 0xAF, 0x2C, 0x85, 0x85,
-  0x85, 0xDA, 0x8D, 0x8A, 0x85, 0xAC, 0x95, 0xD9
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22,
+    0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+    0x26, 0x26, 0x25, 0x28, 0x23, 0x22, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x25, 0x2a, 0x2b, 0x2c, 0x2d, 0x2d,
+    0x2d, 0x2e, 0x2c, 0x2b, 0x2a, 0x25, 0x28, 0x22,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x24, 0x2a, 0x2c, 0x2f, 0x2c, 0x30, 0x30, 0x24,
+    0x25, 0x27, 0x2b, 0x2c, 0x2f, 0x31, 0x32, 0x25,
+    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
+    0x33, 0x34, 0x35, 0x21, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x21, 0x2b, 0x2f, 0x2c,
+    0x30, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
+    0x2d, 0x27, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x31,
+    0x2d, 0x32, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x2a, 0x34,
+    0x25, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x23, 0x32, 0x27, 0x21, 0x36,
+    0x2a, 0x2d, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x22, 0x26, 0x2c, 0x35,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x25, 0x2f, 0x37, 0x32, 0x22,
+    0x36, 0x35, 0x31, 0x27, 0x22, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x22,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x26, 0x38, 0x38, 0x35, 0x25,
+    0x36, 0x21, 0x2d, 0x2b, 0x24, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x24, 0x39, 0x39, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x25, 0x2b, 0x30, 0x28, 0x22,
+    0x36, 0x36, 0x27, 0x34, 0x30, 0x23, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x26, 0x2d, 0x26, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x22, 0x22, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x2d, 0x33, 0x28, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x2b, 0x2c, 0x25, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x36, 0x36,
+    0x36, 0x21, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x21, 0x23, 0x22, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x28, 0x34, 0x27, 0x22, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
+    0x21, 0x21, 0x24, 0x27, 0x21, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x28, 0x27, 0x22, 0x33, 0x24, 0x36,
+    0x36, 0x36, 0x36, 0x22, 0x2f, 0x2a, 0x23, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
+    0x30, 0x3a, 0x38, 0x24, 0x24, 0x36, 0x36, 0x36,
+    0x23, 0x2f, 0x3b, 0x3c, 0x3d, 0x30, 0x25, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2f, 0x32, 0x23, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x23,
+    0x3e, 0x3f, 0x40, 0x3a, 0x22, 0x36, 0x36, 0x21,
+    0x41, 0x42, 0x43, 0x44, 0x45, 0x3e, 0x23, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2f, 0x33, 0x28, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x2b,
+    0x44, 0x40, 0x46, 0x47, 0x35, 0x36, 0x36, 0x26,
+    0x43, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x2e, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x34, 0x36, 0x4d,
+    0x4e, 0x25, 0x2f, 0x46, 0x4a, 0x22, 0x23, 0x32,
+    0x4f, 0x50, 0x21, 0x31, 0x51, 0x52, 0x53, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x21, 0x3a,
+    0x4d, 0x21, 0x31, 0x54, 0x55, 0x28, 0x30, 0x2b,
+    0x4b, 0x4d, 0x36, 0x23, 0x32, 0x50, 0x3f, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x38, 0x23, 0x37,
+    0x55, 0x36, 0x28, 0x3a, 0x56, 0x57, 0x57, 0x58,
+    0x3c, 0x4d, 0x36, 0x36, 0x36, 0x40, 0x40, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x29, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x51, 0x23, 0x35,
+    0x43, 0x25, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
+    0x5f, 0x60, 0x61, 0x36, 0x31, 0x47, 0x3b, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x2c, 0x25, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x22,
+    0x40, 0x62, 0x63, 0x5d, 0x64, 0x65, 0x66, 0x67,
+    0x68, 0x69, 0x66, 0x5e, 0x6a, 0x6b, 0x2a, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x33, 0x2e, 0x26, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x2f, 0x23, 0x36,
+    0x6c, 0x63, 0x6d, 0x64, 0x5c, 0x66, 0x69, 0x6e,
+    0x6f, 0x70, 0x71, 0x69, 0x69, 0x72, 0x6c, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x33, 0x34, 0x27, 0x22,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x34, 0x26, 0x73,
+    0x74, 0x75, 0x76, 0x64, 0x65, 0x77, 0x69, 0x78,
+    0x70, 0x71, 0x71, 0x71, 0x72, 0x5f, 0x5e, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x25, 0x38, 0x2a, 0x23,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x33, 0x79,
+    0x63, 0x7a, 0x7b, 0x5c, 0x66, 0x69, 0x6e, 0x7c,
+    0x71, 0x71, 0x69, 0x7d, 0x7e, 0x7a, 0x7f, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x21, 0x51, 0x2b, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x32, 0x24,
+    0x80, 0x81, 0x64, 0x82, 0x77, 0x69, 0x71, 0x71,
+    0x69, 0x83, 0x84, 0x85, 0x7a, 0x85, 0x86, 0x36,
+    0x21, 0x2b, 0x23, 0x36, 0x36, 0x39, 0x2e, 0x26,
+    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x2d, 0x33, 0x21,
+    0x87, 0x88, 0x89, 0x72, 0x67, 0x66, 0x5f, 0x89,
+    0x8a, 0x63, 0x85, 0x8b, 0x8c, 0x8d, 0x41, 0x36,
+    0x36, 0x2d, 0x3a, 0x35, 0x36, 0x24, 0x51, 0x32,
+    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x33, 0x21,
+    0x55, 0x8e, 0x8f, 0x8a, 0x7d, 0x5e, 0x90, 0x7e,
+    0x75, 0x75, 0x90, 0x62, 0x40, 0x3f, 0x49, 0x23,
+    0x36, 0x24, 0x3a, 0x3a, 0x24, 0x36, 0x2e, 0x31,
+    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x21, 0x28, 0x33, 0x37, 0x25, 0x22,
+    0x3b, 0x50, 0x8e, 0x8f, 0x90, 0x7e, 0x90, 0x63,
+    0x74, 0x91, 0x92, 0x42, 0x93, 0x4b, 0x45, 0x2c,
+    0x36, 0x36, 0x33, 0x39, 0x21, 0x36, 0x22, 0x51,
+    0x33, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x22, 0x27, 0x2e, 0x2e, 0x36, 0x21,
+    0x94, 0x3f, 0x50, 0x95, 0x96, 0x8f, 0x8f, 0x97,
+    0x8e, 0x42, 0x50, 0x43, 0x47, 0x48, 0x48, 0x98,
+    0x21, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39,
+    0x2e, 0x27, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x22, 0x24, 0x2b, 0x38, 0x28, 0x36, 0x32,
+    0x4c, 0x4b, 0x50, 0x50, 0x50, 0x42, 0x42, 0x50,
+    0x50, 0x40, 0x45, 0x99, 0x48, 0x48, 0x48, 0x48,
+    0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x23,
+    0x2f, 0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x28, 0x32, 0x51, 0x32, 0x28, 0x21, 0x98,
+    0x48, 0x47, 0x9a, 0x50, 0x50, 0x50, 0x50, 0x50,
+    0x9a, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x93, 0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x2a, 0x2f, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x23, 0x30, 0x2e, 0x2c, 0x36, 0x21, 0x51, 0x9b,
+    0x48, 0x48, 0x52, 0x3f, 0x50, 0x50, 0x40, 0x4b,
+    0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2d, 0x31, 0x27, 0x23, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+    0x27, 0x2c, 0x2d, 0x21, 0x36, 0x28, 0x44, 0x48,
+    0x48, 0x48, 0x48, 0x47, 0x46, 0x4f, 0x47, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x9c, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x28, 0x51, 0x39, 0x26, 0x22, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
+    0x35, 0x51, 0x28, 0x36, 0x36, 0x9d, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x9b, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x4f, 0x28, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x28, 0x38, 0x2b, 0x25, 0x22, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
+    0x51, 0x25, 0x36, 0x36, 0x23, 0x40, 0x9b, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x9b, 0x99, 0x2b, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x30, 0x2f, 0x33, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x23, 0x30, 0x34,
+    0x27, 0x36, 0x36, 0x36, 0x2a, 0x40, 0x47, 0x48,
+    0x48, 0x48, 0x48, 0x9b, 0x99, 0x99, 0x9b, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x47, 0x52,
+    0x46, 0x4f, 0x37, 0x21, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x30, 0x34, 0x2a, 0x23,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x22, 0x25, 0x39, 0x2c,
+    0x36, 0x36, 0x36, 0x21, 0x31, 0x4e, 0x9a, 0x4c,
+    0x47, 0x9b, 0x9b, 0x52, 0x46, 0x4f, 0x52, 0x9b,
+    0x9b, 0x9b, 0x47, 0x4f, 0x45, 0x9a, 0x93, 0x93,
+    0x3f, 0x93, 0x98, 0x28, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c, 0x26,
+    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x28,
+    0x36, 0x36, 0x36, 0x22, 0x38, 0x98, 0x44, 0x99,
+    0x9b, 0x48, 0x48, 0x9b, 0x4c, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x47, 0x52, 0x46, 0x43, 0x93,
+    0x40, 0x40, 0x43, 0x53, 0x21, 0x23, 0x33, 0x23,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x2f, 0x32,
+    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x24, 0x2b, 0x31, 0x36,
+    0x36, 0x22, 0x36, 0x24, 0x9e, 0x4f, 0x9b, 0x48,
+    0x48, 0x48, 0x48, 0x9b, 0x99, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x47,
+    0x4f, 0x9a, 0x3f, 0x46, 0x38, 0x36, 0x21, 0x30,
+    0x26, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c,
+    0x25, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x26, 0x2e, 0x33, 0x36,
+    0x25, 0x25, 0x36, 0x4d, 0x52, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x4f, 0x3e, 0x4d, 0x49, 0x48,
+    0x98, 0x2b, 0x55, 0x4f, 0x9b, 0x48, 0x48, 0x48,
+    0x48, 0x47, 0x44, 0x93, 0x43, 0x23, 0x36, 0x36,
+    0x26, 0x24, 0x36, 0x36, 0x36, 0x36, 0x28, 0x2f,
+    0x2a, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x51, 0x24, 0x36,
+    0x2a, 0x36, 0x28, 0x44, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x4f, 0x54, 0x38, 0x3d, 0x98, 0x37, 0x9b,
+    0x3a, 0x22, 0x23, 0x2a, 0x55, 0x4f, 0x48, 0x48,
+    0x48, 0x48, 0x9b, 0x4b, 0x44, 0x37, 0x36, 0x23,
+    0x28, 0x30, 0x22, 0x36, 0x36, 0x36, 0x36, 0x2d,
+    0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x21, 0x28, 0x2b, 0x34, 0x36, 0x25,
+    0x24, 0x36, 0x4a, 0x48, 0x48, 0x48, 0x48, 0x52,
+    0x53, 0x37, 0x54, 0x98, 0x55, 0x38, 0x38, 0x47,
+    0x4a, 0x2d, 0x30, 0x23, 0x28, 0x39, 0x53, 0x52,
+    0x48, 0x48, 0x48, 0x9b, 0x52, 0x3f, 0x21, 0x30,
+    0x35, 0x25, 0x30, 0x36, 0x36, 0x36, 0x36, 0x32,
+    0x2d, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x22, 0x26, 0x2e, 0x35, 0x36, 0x2a,
+    0x36, 0x24, 0x4f, 0x48, 0x48, 0x9b, 0x55, 0x39,
+    0x55, 0x53, 0x3a, 0x55, 0x3a, 0x51, 0x51, 0x47,
+    0x55, 0x3a, 0x4d, 0x37, 0x30, 0x22, 0x24, 0x2b,
+    0x54, 0x9b, 0x48, 0x48, 0x48, 0x47, 0x32, 0x30,
+    0x2a, 0x23, 0x30, 0x23, 0x36, 0x36, 0x36, 0x21,
+    0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x2a, 0x51, 0x28, 0x28, 0x25,
+    0x36, 0x3a, 0x48, 0x48, 0x48, 0x4f, 0x26, 0x23,
+    0x26, 0x39, 0x3e, 0x43, 0x49, 0x37, 0x2f, 0x9b,
+    0x55, 0x3a, 0x54, 0x43, 0x3e, 0x30, 0x32, 0x3d,
+    0x49, 0x3f, 0x48, 0x48, 0x48, 0x48, 0x38, 0x21,
+    0x36, 0x36, 0x22, 0x27, 0x36, 0x36, 0x36, 0x36,
+    0x2e, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x22, 0x25, 0x2c, 0x34, 0x36, 0x30, 0x21,
+    0x23, 0x43, 0x48, 0x48, 0x48, 0x47, 0x3b, 0x32,
+    0x21, 0x28, 0x2b, 0x9e, 0x49, 0x37, 0x2e, 0x52,
+    0x4a, 0x37, 0x9e, 0x98, 0x51, 0x3a, 0x93, 0x54,
+    0x55, 0x4f, 0x48, 0x48, 0x48, 0x48, 0x94, 0x36,
+    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
+    0x2a, 0x2e, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x2a, 0x51, 0x25, 0x21, 0x2a, 0x36,
+    0x2e, 0x9b, 0x48, 0x48, 0x52, 0x4b, 0x52, 0x9e,
+    0x51, 0x30, 0x22, 0x28, 0x32, 0x32, 0x39, 0x47,
+    0x37, 0x2a, 0x39, 0x3a, 0x50, 0x9f, 0x3a, 0x9f,
+    0x4b, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x98, 0x36,
+    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
+    0x22, 0x2f, 0x30, 0x22, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x22, 0x25, 0x2c, 0x34, 0x36, 0x24, 0x28, 0x36,
+    0x54, 0x48, 0x48, 0x45, 0x30, 0x30, 0x9e, 0x52,
+    0x45, 0x3a, 0x31, 0x25, 0x22, 0x25, 0x2a, 0x98,
+    0x39, 0x2f, 0x42, 0x49, 0x4a, 0x3b, 0x50, 0x47,
+    0x43, 0x9d, 0x3b, 0x4b, 0x48, 0x48, 0x9a, 0x36,
+    0x36, 0x36, 0x36, 0x30, 0x36, 0x36, 0x36, 0x36,
+    0x21, 0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x28, 0x32, 0x2f, 0x28, 0x36, 0x27, 0x22, 0x21,
+    0x43, 0x48, 0x48, 0x50, 0x30, 0x23, 0x25, 0x2f,
+    0x3f, 0x52, 0x49, 0x51, 0x39, 0x25, 0x24, 0x2b,
+    0x9e, 0x42, 0x3e, 0x55, 0x9e, 0x4f, 0x4f, 0x54,
+    0x4a, 0x9e, 0x49, 0x50, 0x48, 0x48, 0x4b, 0x21,
+    0x36, 0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x25, 0x2c, 0x39, 0x36, 0x36, 0x30, 0x22, 0x25,
+    0x52, 0x48, 0x48, 0x45, 0x3a, 0x51, 0x26, 0x23,
+    0x30, 0x9d, 0x45, 0x40, 0x3a, 0x39, 0x2b, 0x2b,
+    0x3b, 0x3a, 0x55, 0x4b, 0x47, 0x9e, 0x3a, 0x49,
+    0x9e, 0x9f, 0x3b, 0x9a, 0x48, 0x48, 0x4f, 0x21,
+    0x36, 0x36, 0x22, 0x26, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x30, 0x2d, 0x21, 0x36, 0x36, 0x32, 0x23, 0x2a,
+    0x47, 0x48, 0x48, 0x43, 0x3e, 0x3a, 0x9d, 0x2b,
+    0x23, 0x25, 0x39, 0x4d, 0x2b, 0x31, 0x2d, 0x9d,
+    0x34, 0x2e, 0x2f, 0x9e, 0x3a, 0x55, 0x3f, 0x9f,
+    0x9f, 0x3e, 0x55, 0x43, 0x48, 0x48, 0x4c, 0x22,
+    0x36, 0x36, 0x24, 0x23, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0x2e, 0x36, 0x36, 0x23, 0x31, 0x27, 0x39,
+    0x9b, 0x48, 0x48, 0x4f, 0x3e, 0x4d, 0x55, 0x9e,
+    0x51, 0x24, 0x23, 0x26, 0x32, 0x2c, 0x3b, 0x4b,
+    0x55, 0x32, 0x2b, 0x37, 0x98, 0x9e, 0x3e, 0x9e,
+    0x55, 0x37, 0x3e, 0x4b, 0x48, 0x48, 0x4c, 0x23,
+    0x36, 0x36, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x2b, 0x39, 0x36, 0x36, 0x36, 0x26, 0x32, 0x31,
+    0x9b, 0x48, 0x48, 0x4f, 0x55, 0x3a, 0x53, 0x53,
+    0x2e, 0x9d, 0x34, 0x28, 0x28, 0x37, 0x98, 0x45,
+    0x3e, 0x2b, 0x49, 0x9e, 0x3b, 0x3e, 0x2d, 0x6b,
+    0x4a, 0x3a, 0x3b, 0x4f, 0x48, 0x48, 0x46, 0x22,
+    0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x35, 0x39, 0x36, 0x36, 0x36, 0x36, 0x26, 0x2d,
+    0x9b, 0x48, 0x48, 0x47, 0x3b, 0x3a, 0x2f, 0x37,
+    0x49, 0x38, 0x38, 0x3a, 0x2b, 0x31, 0x51, 0x32,
+    0x2b, 0x26, 0x37, 0x9f, 0x55, 0x32, 0x26, 0x2b,
+    0x2d, 0x9d, 0x3b, 0x52, 0x48, 0x48, 0x9a, 0x36,
+    0x24, 0x27, 0xa0, 0x24, 0x25, 0x28, 0x21, 0x36,
+    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x25,
+    0x39, 0x4d, 0xa1, 0x84, 0x81, 0x57, 0x21, 0x39,
+    0x52, 0x48, 0x48, 0x47, 0x9f, 0x4a, 0x4d, 0x55,
+    0x37, 0x9f, 0x45, 0x9e, 0x3e, 0x54, 0x4d, 0x2d,
+    0x51, 0x3b, 0x3d, 0x40, 0x50, 0x2f, 0x32, 0x23,
+    0x2a, 0x3a, 0x54, 0x47, 0x48, 0x48, 0x53, 0x28,
+    0x23, 0x36, 0x36, 0x36, 0x21, 0x28, 0x2c, 0x30,
+    0x21, 0x38, 0x33, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x28, 0x30,
+    0x2d, 0xa2, 0x7a, 0xa3, 0xa4, 0xa4, 0x7f, 0x22,
+    0x51, 0x52, 0x48, 0x9b, 0x3b, 0x3a, 0x2f, 0x54,
+    0x3f, 0x4b, 0x3b, 0x34, 0x3e, 0x55, 0x34, 0x4d,
+    0x34, 0x3b, 0x3b, 0x55, 0x42, 0x4b, 0x9e, 0x31,
+    0x2b, 0x3a, 0x9e, 0x47, 0xa5, 0xa5, 0xa6, 0x61,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x30, 0x32,
+    0x25, 0x4d, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x24, 0x26, 0x30, 0x33, 0x31,
+    0x4d, 0x91, 0x5b, 0xa3, 0xa4, 0xa4, 0xa4, 0x5a,
+    0x21, 0x2e, 0x46, 0x48, 0x9a, 0x3b, 0x42, 0x47,
+    0x42, 0x9d, 0x37, 0x39, 0x4a, 0x3e, 0x3a, 0x52,
+    0x38, 0x3e, 0x3e, 0x2b, 0x25, 0x37, 0x4f, 0x4f,
+    0x55, 0x55, 0x45, 0xa7, 0xa8, 0x69, 0x66, 0xa9,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x26, 0x25,
+    0x83, 0xaa, 0x2c, 0x25, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x28, 0x30, 0x35, 0x2d, 0x2f, 0x37, 0x4a,
+    0x60, 0x85, 0xab, 0xac, 0xa4, 0xa4, 0xa4, 0x82,
+    0x86, 0x36, 0x32, 0x3f, 0x48, 0x47, 0x4b, 0x4a,
+    0x9d, 0x55, 0x2f, 0x51, 0x3a, 0x3b, 0x55, 0x9b,
+    0x4d, 0x3b, 0x55, 0x39, 0x24, 0x28, 0x32, 0x9e,
+    0x47, 0x47, 0x48, 0xad, 0xa3, 0xa8, 0xae, 0xaf,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x57,
+    0x77, 0x66, 0x34, 0x27, 0x22, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x23, 0x30, 0x31, 0xb0, 0x91, 0x7e, 0x90, 0x90,
+    0x8b, 0x5b, 0xa3, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0x5d, 0xb1, 0x36, 0x24, 0x53, 0x47, 0x37, 0x30,
+    0x32, 0x2e, 0x98, 0x3f, 0x3a, 0x3e, 0x4a, 0x47,
+    0x9d, 0x3e, 0x54, 0x40, 0x55, 0x30, 0x30, 0x4a,
+    0x6b, 0x9b, 0x99, 0xad, 0x64, 0x5c, 0x8b, 0xb1,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x73, 0x5d,
+    0x82, 0x5c, 0xb2, 0x2a, 0x23, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x24, 0x2b, 0xb0, 0x8b, 0x5b, 0x76, 0x5b, 0x5b,
+    0x7b, 0xa3, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa8, 0x5e, 0x22, 0x36, 0x21, 0x3a, 0x3d, 0x30,
+    0x22, 0x28, 0x3a, 0x44, 0x4a, 0x3e, 0x3e, 0x9b,
+    0x9d, 0x3e, 0x9e, 0x4b, 0x55, 0x2e, 0x42, 0x9f,
+    0x93, 0x4f, 0x3f, 0xb3, 0x7b, 0x7b, 0x85, 0x80,
+    0xa0, 0x36, 0x36, 0x36, 0x21, 0xb4, 0x7e, 0x7b,
+    0x64, 0x64, 0xb5, 0x35, 0x24, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x31, 0xb6, 0x5b, 0x64, 0xa3, 0xa3, 0xac,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0x66, 0xb7, 0x36, 0x36, 0x36, 0x2c, 0x54,
+    0x31, 0x23, 0x26, 0x2c, 0x3a, 0x3b, 0x55, 0x47,
+    0x37, 0x3b, 0x3b, 0x38, 0x4a, 0x98, 0x55, 0x98,
+    0x47, 0x9a, 0x3f, 0xb8, 0x76, 0x76, 0x7a, 0x63,
+    0xb9, 0xba, 0x86, 0xba, 0xbb, 0x90, 0x5b, 0x64,
+    0xa3, 0xa3, 0xbc, 0x2d, 0x27, 0x23, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x26, 0x2d, 0x91, 0x5b, 0x64, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa8, 0x83, 0xaf, 0x36, 0x36, 0x36, 0x30,
+    0x98, 0x37, 0x30, 0x26, 0x9d, 0x3e, 0x9f, 0x9b,
+    0x37, 0x3b, 0x3b, 0x53, 0x53, 0x3d, 0x4b, 0x48,
+    0x9b, 0x9a, 0x3f, 0xbd, 0x5b, 0x7b, 0xbe, 0x85,
+    0x7e, 0x90, 0x63, 0x90, 0x85, 0x5b, 0xa3, 0xa4,
+    0xa4, 0xac, 0x5d, 0xb5, 0x39, 0x26, 0x23, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2d, 0xbf, 0xbe, 0x64, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa8, 0x88, 0x36, 0x36, 0x36, 0x36,
+    0x2d, 0x3f, 0x3b, 0x31, 0x4d, 0x3e, 0x9f, 0x47,
+    0x38, 0x3b, 0x3e, 0x3e, 0x98, 0x52, 0x48, 0x48,
+    0x9b, 0x45, 0x3f, 0xc0, 0x6d, 0x7b, 0xab, 0xbe,
+    0x7a, 0x8b, 0x8b, 0x7a, 0x5b, 0x64, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa3, 0xc1, 0x37, 0x35, 0x26, 0x23,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2e, 0xbf, 0x7a, 0x7b, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa8, 0x72, 0x73, 0x36, 0x36, 0x36,
+    0x24, 0x52, 0x47, 0x49, 0x3a, 0x55, 0x98, 0x47,
+    0x9d, 0x3e, 0x54, 0x45, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x46, 0x42, 0xb6, 0x7a, 0x7b, 0x64, 0x7b,
+    0x76, 0x5b, 0x5b, 0x76, 0x7b, 0xa3, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xac, 0x64, 0xc1, 0x4d, 0x2c, 0x27,
+    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x25, 0x31, 0xc2, 0x8b, 0x7b, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa8, 0x89, 0xa0, 0x36, 0x36,
+    0x32, 0x47, 0x48, 0x9b, 0x9a, 0x3f, 0x47, 0x48,
+    0x4b, 0x40, 0x4f, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x4b, 0x2f, 0x8f, 0x7a, 0x7b, 0xa3, 0xac,
+    0xa3, 0x64, 0x64, 0xa3, 0xa3, 0xac, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0x5d, 0xc3, 0x2c,
+    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x25, 0x31, 0xc2, 0x85, 0x7b, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0x66, 0x57, 0x27, 0x4d,
+    0x4b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x99, 0x34, 0xa0, 0xb9, 0x7a, 0x7b, 0xa3, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0xc2,
+    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2d, 0xc2, 0x85, 0x7b, 0xac, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa8, 0x5f, 0x92, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x44,
+    0x35, 0x36, 0xaf, 0xbb, 0x7a, 0x7b, 0xac, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xac, 0xa3, 0xc0,
+    0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+    0x30, 0x2f, 0xb6, 0x8b, 0x7b, 0xac, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0x66, 0x89, 0x45,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x4e, 0x25,
+    0x36, 0x36, 0x61, 0xb9, 0x6d, 0x64, 0xac, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xac, 0x7b, 0xbe, 0xc3,
+    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0xc4, 0x63, 0xbe, 0xa3, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0x72, 0x81, 0xc5,
+    0x46, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x3f, 0x2c, 0x36, 0x36,
+    0x36, 0x36, 0xc6, 0x8f, 0x6d, 0x64, 0xac, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa3, 0xab, 0x8b, 0xb0, 0x2c,
+    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x35, 0x96, 0x75, 0xab, 0xa3, 0xac, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xac, 0x7b, 0x81, 0xb9,
+    0x73, 0x3b, 0x44, 0x9b, 0x48, 0x48, 0x48, 0x9b,
+    0x99, 0x43, 0x94, 0x2c, 0x21, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x73, 0xb9, 0x7a, 0x7b, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0x64, 0x76, 0x7a, 0x91, 0xb5, 0x31, 0x30,
+    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x39, 0x97, 0x75, 0xbe, 0x7b, 0x64, 0xa3, 0xa3,
+    0xac, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0x7b, 0x7a, 0xc7,
+    0xc8, 0x36, 0x21, 0x26, 0x2b, 0x39, 0x33, 0x30,
+    0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xc8, 0xbb, 0x8b, 0x7b, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0x64, 0x64,
+    0x76, 0x85, 0xbf, 0xb5, 0x34, 0x2b, 0x27, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0xc9, 0x63, 0x7e, 0x7a, 0x6d, 0xbe, 0x5b,
+    0x76, 0x7b, 0x64, 0x64, 0xa3, 0xac, 0xa4, 0xa4,
+    0xa4, 0xa4, 0xa4, 0xa4, 0xac, 0x76, 0x85, 0xb9,
+    0x79, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xca, 0xbb, 0x75, 0x76, 0xa3, 0xa4,
+    0xa4, 0xa4, 0xac, 0xa3, 0x64, 0x76, 0xbe, 0x8b,
+    0xb6, 0xb5, 0x2f, 0x35, 0x30, 0x24, 0x22, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+    0x27, 0x31, 0xcb, 0xc9, 0xbb, 0x74, 0x63, 0x90,
+    0x7e, 0x75, 0x8b, 0x6d, 0xbe, 0x76, 0x64, 0xa3,
+    0xac, 0xac, 0xac, 0xac, 0x64, 0x7a, 0x84, 0xcc,
+    0x79, 0xa0, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xc8, 0xcc, 0x63, 0x6d, 0x7b, 0x64,
+    0xac, 0xa3, 0x64, 0x7b, 0xbe, 0x75, 0x63, 0x96,
+    0x38, 0x39, 0x2a, 0x24, 0x23, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x28, 0x27, 0x35, 0x2d, 0x41, 0xb5, 0xc5, 0x8f,
+    0xb9, 0xbb, 0xc7, 0x74, 0x84, 0x90, 0x85, 0x6d,
+    0x5b, 0x7b, 0x7b, 0xab, 0x6d, 0x90, 0xb9, 0xcd,
+    0xca, 0x22, 0x36, 0x36, 0x28, 0x30, 0x30, 0x30,
+    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x25, 0x36,
+    0x36, 0x21, 0xb4, 0x80, 0xc7, 0x7e, 0x6d, 0x76,
+    0xab, 0x76, 0x6d, 0x85, 0x63, 0xb9, 0xb5, 0x34,
+    0x33, 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x24, 0x27, 0x2a, 0x35, 0x2e, 0x2f,
+    0x41, 0xce, 0xcf, 0x6c, 0x80, 0xcc, 0xb9, 0x74,
+    0x84, 0x90, 0x75, 0x7e, 0x74, 0x8f, 0xcd, 0x79,
+    0xc6, 0x2b, 0x9d, 0x41, 0x2f, 0x34, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x2f, 0x38,
+    0x4d, 0x37, 0xd0, 0xd1, 0x8f, 0x74, 0x63, 0x7e,
+    0x75, 0x7e, 0x63, 0xc7, 0x88, 0xc4, 0x31, 0x2a,
+    0x24, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x21, 0x22, 0x23, 0x24, 0x26, 0x30,
+    0x33, 0x39, 0x2e, 0x51, 0x41, 0xb2, 0x6c, 0xd1,
+    0x80, 0xcc, 0xcc, 0xcc, 0xd2, 0xd1, 0xb7, 0xd3,
+    0x41, 0x34, 0x35, 0x32, 0x30, 0x27, 0x27, 0x27,
+    0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x2a,
+    0x2b, 0x34, 0xd4, 0xca, 0xd5, 0x8f, 0xbb, 0xc7,
+    0xc7, 0xbb, 0xcc, 0x6c, 0x41, 0x39, 0x27, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22,
+    0x28, 0x24, 0x26, 0x2a, 0x33, 0x2c, 0x2f, 0x41,
+    0xd6, 0xb7, 0x79, 0x79, 0x79, 0xca, 0xd7, 0x51,
+    0x39, 0x30, 0x24, 0x23, 0x22, 0x22, 0x22, 0x22,
+    0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23,
+    0x24, 0x2a, 0x31, 0xd8, 0xc8, 0x79, 0xd1, 0x80,
+    0xd5, 0xba, 0xd9, 0x2f, 0x35, 0x26, 0x23, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x22, 0x23, 0x28, 0x25, 0x30, 0x2b,
+    0x31, 0x2f, 0xd4, 0xd8, 0xd8, 0x2f, 0x2e, 0x33,
+    0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x28, 0x27, 0x35, 0x34, 0xd8, 0xd8, 0xd8,
+    0xda, 0xd4, 0x2e, 0x33, 0x25, 0x23, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x23, 0x28,
+    0x26, 0x30, 0x32, 0x2b, 0x33, 0x2a, 0x26, 0x28,
+    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x25, 0x30, 0x33, 0x35, 0x35,
+    0x2b, 0x2a, 0x26, 0x28, 0x22, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x21, 0x22, 0x23, 0x28, 0x28, 0x23, 0x22, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x23, 0x28, 0x24, 0x24,
+    0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 };
 
-#define INCLUDE_LINUX_LOGOBW
-#define INCLUDE_LINUX_LOGO16
-#include <linux/linux_logo.h>
-
-#else
+#endif /* INCLUDE_LINUX_LOGO_DATA */
 
-/* prototypes only */
-extern unsigned char linux_logo_red[];
-extern unsigned char linux_logo_green[];
-extern unsigned char linux_logo_blue[];
-extern unsigned char linux_logo[];
-extern unsigned char linux_logo_bw[];
-extern unsigned char linux_logo16_red[];
-extern unsigned char linux_logo16_green[];
-extern unsigned char linux_logo16_blue[];
-extern unsigned char linux_logo16[];
+#include <linux/linux_logo.h>
 
-#endif
diff -u --recursive --new-file v2.4.5/linux/include/asm-mips64/socket.h linux/include/asm-mips64/socket.h
--- v2.4.5/linux/include/asm-mips64/socket.h	Sat Feb  3 11:26:44 2001
+++ linux/include/asm-mips64/socket.h	Wed Jun 20 21:00:55 2001
@@ -79,6 +79,7 @@
 					/* level.  For writing rarp and	*/
 					/* other similar things on the	*/
 					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
 #endif
 
 #endif /* _ASM_SOCKET_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-mips64/termios.h linux/include/asm-mips64/termios.h
--- v2.4.5/linux/include/asm-mips64/termios.h	Sat Feb  3 20:00:45 2001
+++ linux/include/asm-mips64/termios.h	Mon Jun 11 19:15:27 2001
@@ -101,6 +101,7 @@
 #define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
 #define N_HDLC		13	/* synchronous HDLC */
 #define N_SYNC_PPP	14	/* synchronous PPP */
+#define N_HCI		15  /* Bluetooth HCI UART */
 
 #ifdef __KERNEL__
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-parisc/linux_logo.h linux/include/asm-parisc/linux_logo.h
--- v2.4.5/linux/include/asm-parisc/linux_logo.h	Tue Dec  5 12:29:39 2000
+++ linux/include/asm-parisc/linux_logo.h	Mon Jun 11 19:15:27 2001
@@ -23,26 +23,5 @@
 
 #define linux_logo_banner "Linux/PA-RISC version " UTS_RELEASE
 
-#define LINUX_LOGO_COLORS 214
-
-#ifdef INCLUDE_LINUX_LOGO_DATA
-
-#define INCLUDE_LINUX_LOGOBW
-#define INCLUDE_LINUX_LOGO16
-
 #include <linux/linux_logo.h>
 
-#else
-
-/* prototypes only */
-extern unsigned char linux_logo_red[];
-extern unsigned char linux_logo_green[];
-extern unsigned char linux_logo_blue[];
-extern unsigned char linux_logo[];
-extern unsigned char linux_logo_bw[];
-extern unsigned char linux_logo16_red[];
-extern unsigned char linux_logo16_green[];
-extern unsigned char linux_logo16_blue[];
-extern unsigned char linux_logo16[];
-
-#endif
diff -u --recursive --new-file v2.4.5/linux/include/asm-parisc/socket.h linux/include/asm-parisc/socket.h
--- v2.4.5/linux/include/asm-parisc/socket.h	Sat Feb  3 11:26:44 2001
+++ linux/include/asm-parisc/socket.h	Wed Jun 20 21:00:55 2001
@@ -56,6 +56,7 @@
 				/* level.  For writing rarp and	*/
 				/* other similar things on the	*/
 				/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
 #endif
 
 #endif /* _ASM_SOCKET_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-parisc/termios.h linux/include/asm-parisc/termios.h
--- v2.4.5/linux/include/asm-parisc/termios.h	Sat Feb  3 20:00:45 2001
+++ linux/include/asm-parisc/termios.h	Mon Jun 11 19:15:27 2001
@@ -53,6 +53,7 @@
 #define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
 #define N_IRDA		11	/* Linux IR - http://irda.sourceforge.net/ */
 #define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
+#define N_HCI		15  /* Bluetooth HCI UART */
 
 #ifdef __KERNEL__
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-ppc/bitops.h linux/include/asm-ppc/bitops.h
--- v2.4.5/linux/include/asm-ppc/bitops.h	Mon May 21 15:02:06 2001
+++ linux/include/asm-ppc/bitops.h	Mon Jun 11 19:15:27 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.bitops.h 1.7 05/17/01 18:14:24 cort
+ * BK Id: SCCS/s.bitops.h 1.9 05/26/01 14:48:14 paulus
  */
 /*
  * bitops.h: Bit string operations on the ppc
@@ -24,12 +24,9 @@
 #define SMP_MB
 #endif /* CONFIG_SMP */
 
-#define __INLINE_BITOPS	1
-
-#if __INLINE_BITOPS
 /*
  * These used to be if'd out here because using : "cc" as a constraint
- * resulted in errors from egcs.  Things may be OK with gcc-2.95.
+ * resulted in errors from egcs.  Things appear to be OK with gcc-2.95.
  */
 static __inline__ void set_bit(int nr, volatile void * addr)
 {
@@ -80,6 +77,17 @@
 	: "cc");
 }
 
+/*
+ * non-atomic version
+ */
+static __inline__ void __clear_bit(int nr, volatile void *addr)
+{
+	unsigned long mask = 1 << (nr & 0x1f);
+	unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
+
+	*p &= ~mask;
+}
+
 static __inline__ void change_bit(int nr, volatile void *addr)
 {
 	unsigned long old;
@@ -97,6 +105,17 @@
 }
 
 /*
+ * non-atomic version
+ */
+static __inline__ void __change_bit(int nr, volatile void *addr)
+{
+	unsigned long mask = 1 << (nr & 0x1f);
+	unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
+
+	*p ^= mask;
+}
+
+/*
  * test_and_*_bit do imply a memory barrier (?)
  */
 static __inline__ int test_and_set_bit(int nr, volatile void *addr)
@@ -181,16 +200,19 @@
 
 	return (old & mask) != 0;
 }
-#else /* __INLINE_BITOPS */
 
-extern void set_bit(int nr, volatile void *addr);
-extern void clear_bit(int nr, volatile void *addr);
-extern void change_bit(int nr, volatile void *addr);
-extern int test_and_set_bit(int nr, volatile void *addr);
-extern int test_and_clear_bit(int nr, volatile void *addr);
-extern int test_and_change_bit(int nr, volatile void *addr);
+/*
+ * non-atomic version
+ */
+static __inline__ int __test_and_change_bit(int nr, volatile void *addr)
+{
+	unsigned long mask = 1 << (nr & 0x1f);
+	unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
+	unsigned long old = *p;
 
-#endif /* __INLINE_BITOPS */
+	*p = old ^ mask;
+	return (old & mask) != 0;
+}
 
 static __inline__ int test_bit(int nr, __const__ volatile void *addr)
 {
@@ -283,8 +305,6 @@
 	return result + ffz(tmp);
 }
 
-
-#define _EXT2_HAVE_ASM_BITOPS_
 
 #ifdef __KERNEL__
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-ppc/hardirq.h linux/include/asm-ppc/hardirq.h
--- v2.4.5/linux/include/asm-ppc/hardirq.h	Mon May 21 15:02:06 2001
+++ linux/include/asm-ppc/hardirq.h	Tue Jun 12 11:07:16 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.hardirq.h 1.7 05/17/01 18:14:24 cort
+ * BK Id: SCCS/s.hardirq.h 1.10 06/09/01 22:16:38 paulus
  */
 #ifdef __KERNEL__
 #ifndef __ASM_HARDIRQ_H
@@ -15,8 +15,7 @@
  * for uniformity.
  */
 typedef struct {
-	unsigned int __softirq_active;
-	unsigned int __softirq_mask;
+	unsigned long __softirq_pending;	/* set_bit is used on this */
 	unsigned int __local_irq_count;
 	unsigned int __local_bh_count;
 	unsigned int __syscall_count;
diff -u --recursive --new-file v2.4.5/linux/include/asm-ppc/linux_logo.h linux/include/asm-ppc/linux_logo.h
--- v2.4.5/linux/include/asm-ppc/linux_logo.h	Mon May 21 15:02:06 2001
+++ linux/include/asm-ppc/linux_logo.h	Mon Jun 11 19:15:27 2001
@@ -21,23 +21,7 @@
 
 #define LINUX_LOGO_HEIGHT	80
 #define LINUX_LOGO_WIDTH	80
-#define LINUX_LOGO_COLORS	214
 
-#ifdef INCLUDE_LINUX_LOGO_DATA
-
-#define INCLUDE_LINUX_LOGOBW
-#define INCLUDE_LINUX_LOGO16
 #include <linux/linux_logo.h>
 
-#else
-
-/* prototypes only */
-extern unsigned char linux_logo_red[];
-extern unsigned char linux_logo_green[];
-extern unsigned char linux_logo_blue[];
-extern unsigned char linux_logo[];
-extern unsigned char linux_logo_bw[];
-extern unsigned char linux_logo16[];
-
-#endif
 #endif /* __KERNEL__ */
diff -u --recursive --new-file v2.4.5/linux/include/asm-ppc/socket.h linux/include/asm-ppc/socket.h
--- v2.4.5/linux/include/asm-ppc/socket.h	Mon May 21 15:02:06 2001
+++ linux/include/asm-ppc/socket.h	Wed Jun 20 21:00:55 2001
@@ -67,6 +67,7 @@
 					/* level.  For writing rarp and	*/
 					/* other similar things on the	*/
 					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
 #endif
 
 #endif /* _ASM_SOCKET_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-ppc/softirq.h linux/include/asm-ppc/softirq.h
--- v2.4.5/linux/include/asm-ppc/softirq.h	Mon May 21 15:02:06 2001
+++ linux/include/asm-ppc/softirq.h	Tue Jun 12 11:07:16 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.softirq.h 1.5 05/17/01 18:14:25 cort
+ * BK Id: SCCS/s.softirq.h 1.10 06/09/01 22:16:38 paulus
  */
 #ifdef __KERNEL__
 #ifndef __ASM_SOFTIRQ_H
@@ -8,8 +8,29 @@
 #include <asm/atomic.h>
 #include <asm/hardirq.h>
 
-#define local_bh_disable()	do { local_bh_count(smp_processor_id())++; barrier(); } while (0)
-#define local_bh_enable()	do { barrier(); local_bh_count(smp_processor_id())--; } while (0)
+#define local_bh_disable()			\
+do {						\
+	local_bh_count(smp_processor_id())++;	\
+	barrier();				\
+} while (0)
+
+#define __local_bh_enable()			\
+do {						\
+	barrier();				\
+	local_bh_count(smp_processor_id())--;	\
+} while (0)
+
+#define local_bh_enable()				\
+do {							\
+	if (!--local_bh_count(smp_processor_id())	\
+	    && softirq_pending(smp_processor_id())) {	\
+		do_softirq();				\
+		__sti();				\
+	}						\
+} while (0)
+
+#define __cpu_raise_softirq(cpu, nr) set_bit((nr), &softirq_pending(cpu));
+#define raise_softirq(nr)	__cpu_raise_softirq(smp_processor_id(), (nr))
 
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-ppc/termios.h linux/include/asm-ppc/termios.h
--- v2.4.5/linux/include/asm-ppc/termios.h	Mon May 21 15:02:06 2001
+++ linux/include/asm-ppc/termios.h	Mon Jun 11 19:15:27 2001
@@ -193,6 +193,7 @@
 #define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
 #define N_HDLC		13	/* synchronous HDLC */
 #define N_SYNC_PPP	14
+#define N_HCI		15  /* Bluetooth HCI UART */
 
 #ifdef __KERNEL__
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-s390/socket.h linux/include/asm-s390/socket.h
--- v2.4.5/linux/include/asm-s390/socket.h	Sat Feb  3 11:26:44 2001
+++ linux/include/asm-s390/socket.h	Wed Jun 20 21:00:55 2001
@@ -66,6 +66,7 @@
 					/* level.  For writing rarp and	*/
 					/* other similar things on the	*/
 					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
 #endif
 
 #endif /* _ASM_SOCKET_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-s390/termios.h linux/include/asm-s390/termios.h
--- v2.4.5/linux/include/asm-s390/termios.h	Tue Feb 13 14:13:44 2001
+++ linux/include/asm-s390/termios.h	Mon Jun 11 19:15:27 2001
@@ -63,6 +63,7 @@
 #define N_IRDA		11	/* Linux IR - http://irda.sourceforge.net/ */
 #define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
 #define N_HDLC         13	/* synchronous HDLC */
+#define N_HCI		15  /* Bluetooth HCI UART */
 
 #ifdef __KERNEL__
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-s390x/socket.h linux/include/asm-s390x/socket.h
--- v2.4.5/linux/include/asm-s390x/socket.h	Fri Mar  2 11:12:06 2001
+++ linux/include/asm-s390x/socket.h	Wed Jun 20 21:00:55 2001
@@ -65,6 +65,7 @@
 					/* level.  For writing rarp and	*/
 					/* other similar things on the	*/
 					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
 #endif
 
 #endif /* _ASM_SOCKET_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-s390x/termios.h linux/include/asm-s390x/termios.h
--- v2.4.5/linux/include/asm-s390x/termios.h	Wed Apr 11 19:02:29 2001
+++ linux/include/asm-s390x/termios.h	Mon Jun 11 19:15:27 2001
@@ -63,6 +63,7 @@
 #define N_IRDA		11	/* Linux IR - http://irda.sourceforge.net/ */
 #define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
 #define N_HDLC         13	/* synchronous HDLC */
+#define N_BT		15	/* bluetooth */
 
 #ifdef __KERNEL__
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/bigsur.h linux/include/asm-sh/bigsur.h
--- v2.4.5/linux/include/asm-sh/bigsur.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-sh/bigsur.h	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,80 @@
+/*
+ *
+ * Hitachi Big Sur Eval Board support
+ *
+ * Dustin McIntire (dustin@sensoria.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * Derived from Hitachi SH7751 reference manual
+ * 
+ */
+
+#ifndef _ASM_BIGSUR_H_
+#define _ASM_BIGSUR_H_
+
+#include <asm/irq.h>
+#include <asm/hd64465.h>
+
+/* 7751 Internal IRQ's used by external CPLD controller */
+#define BIGSUR_IRQ_LOW	0
+#define BIGSUR_IRQ_NUM  14         /* External CPLD level 1 IRQs */
+#define BIGSUR_IRQ_HIGH (BIGSUR_IRQ_LOW + BIGSUR_IRQ_NUM)
+#define BIGSUR_2NDLVL_IRQ_LOW   (HD64465_IRQ_BASE+HD64465_IRQ_NUM)  
+#define BIGSUR_2NDLVL_IRQ_NUM   32 /* Level 2 IRQs = 4 regs * 8 bits */
+#define BIGSUR_2NDLVL_IRQ_HIGH  (BIGSUR_2NDLVL_IRQ_LOW + \
+                                 BIGSUR_2NDLVL_IRQ_NUM)
+
+/* PCI interrupt base number (A_INTA-A_INTD) */
+#define BIGSUR_SH7751_PCI_IRQ_BASE  (BIGSUR_2NDLVL_IRQ_LOW+10)  
+
+/* CPLD registers and external chip addresses */
+#define BIGSUR_HD64464_ADDR	0xB2000000
+#define BIGSUR_DGDR	0xB1FFFE00
+#define BIGSUR_BIDR	0xB1FFFD00
+#define BIGSUR_CSLR	0xB1FFFC00
+#define BIGSUR_SW1R	0xB1FFFB00
+#define BIGSUR_DBGR	0xB1FFFA00
+#define BIGSUR_BDTR	0xB1FFF900
+#define BIGSUR_BDRR	0xB1FFF800
+#define BIGSUR_PPR1	0xB1FFF700
+#define BIGSUR_PPR2	0xB1FFF600
+#define BIGSUR_IDE2	0xB1FFF500
+#define BIGSUR_IDE3	0xB1FFF400
+#define BIGSUR_SPCR	0xB1FFF300
+#define BIGSUR_ETHR	0xB1FE0000
+#define BIGSUR_PPDR	0xB1FDFF00
+#define BIGSUR_ICTL	0xB1FDFE00
+#define BIGSUR_ICMD	0xB1FDFD00
+#define BIGSUR_DMA0	0xB1FDFC00
+#define BIGSUR_DMA1	0xB1FDFB00
+#define BIGSUR_IRQ0	0xB1FDFA00
+#define BIGSUR_IRQ1	0xB1FDF900
+#define BIGSUR_IRQ2	0xB1FDF800
+#define BIGSUR_IRQ3	0xB1FDF700
+#define BIGSUR_IMR0	0xB1FDF600
+#define BIGSUR_IMR1	0xB1FDF500
+#define BIGSUR_IMR2	0xB1FDF400
+#define BIGSUR_IMR3	0xB1FDF300
+#define BIGSUR_IRLMR0	0xB1FDF200
+#define BIGSUR_IRLMR1	0xB1FDF100
+#define BIGSUR_V320USC_ADDR  0xB1000000
+#define BIGSUR_HD64465_ADDR  0xB0000000
+#define BIGSUR_INTERNAL_BASE 0xB0000000
+
+/* SMC ethernet card parameters */
+#define BIGSUR_ETHER_IOPORT		0x220
+
+/* IDE register paramters */
+#define BIGSUR_IDECMD_IOPORT	0x1f0
+#define BIGSUR_IDECTL_IOPORT	0x1f8
+
+/* LED bit position in BIGSUR_CSLR */
+#define BIGSUR_LED  (1<<4)
+
+/* PCI: default LOCAL memory window sizes (seen from PCI bus) */
+#define BIGSUR_LSR0_SIZE    (64*(1<<20)) //64MB
+#define BIGSUR_LSR1_SIZE    (64*(1<<20)) //64MB
+
+#endif /* _ASM_BIGSUR_H_ */
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/bitops.h linux/include/asm-sh/bitops.h
--- v2.4.5/linux/include/asm-sh/bitops.h	Mon Oct  2 11:57:34 2000
+++ linux/include/asm-sh/bitops.h	Wed Jun 27 13:55:29 2001
@@ -19,6 +19,16 @@
 	restore_flags(flags);
 }
 
+static __inline__ void __set_bit(int nr, volatile void * addr)
+{
+	int	mask;
+	volatile unsigned int *a = addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	*a |= mask;
+}
+
 /*
  * clear_bit() doesn't provide any barrier for the compiler.
  */
@@ -37,6 +47,16 @@
 	restore_flags(flags);
 }
 
+static __inline__ void __clear_bit(int nr, volatile void * addr)
+{
+	int	mask;
+	volatile unsigned int *a = addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	*a &= ~mask;
+}
+
 static __inline__ void change_bit(int nr, volatile void * addr)
 {
 	int	mask;
@@ -50,6 +70,16 @@
 	restore_flags(flags);
 }
 
+static __inline__ void __change_bit(int nr, volatile void * addr)
+{
+	int	mask;
+	volatile unsigned int *a = addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	*a ^= mask;
+}
+
 static __inline__ int test_and_set_bit(int nr, volatile void * addr)
 {
 	int	mask, retval;
@@ -66,6 +96,19 @@
 	return retval;
 }
 
+static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a |= mask;
+
+	return retval;
+}
+
 static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
 {
 	int	mask, retval;
@@ -82,6 +125,19 @@
 	return retval;
 }
 
+static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a &= ~mask;
+
+	return retval;
+}
+
 static __inline__ int test_and_change_bit(int nr, volatile void * addr)
 {
 	int	mask, retval;
@@ -98,6 +154,18 @@
 	return retval;
 }
 
+static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
+{
+	int	mask, retval;
+	volatile unsigned int *a = addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+
+	return retval;
+}
 
 static __inline__ int test_bit(int nr, const volatile void *addr)
 {
@@ -156,6 +224,23 @@
 
 #define find_first_zero_bit(addr, size) \
         find_next_zero_bit((addr), (size), 0)
+
+/*
+ * ffs: find first bit set. This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+
+#define ffs(x) generic_ffs(x)
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
 
 #ifdef __LITTLE_ENDIAN__
 #define ext2_set_bit(nr, addr) test_and_set_bit((nr), (addr))
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/bugs.h linux/include/asm-sh/bugs.h
--- v2.4.5/linux/include/asm-sh/bugs.h	Wed Apr 11 21:24:52 2001
+++ linux/include/asm-sh/bugs.h	Wed Jun 27 13:55:29 2001
@@ -32,7 +32,7 @@
 		break;
 	case CPU_SH7750:
 		*p++ = '4';
-		printk("CPU: SH7750\n");
+		printk("CPU: SH7750/SH7751\n");
 		break;
 	case CPU_ST40STB1:
 		*p++ = '4';
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/dc_sysasic.h linux/include/asm-sh/dc_sysasic.h
--- v2.4.5/linux/include/asm-sh/dc_sysasic.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-sh/dc_sysasic.h	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,35 @@
+/* include/asm-sh/dc_sysasic.h
+ *
+ * Definitions for the Dreamcast System ASIC and related peripherals.
+ *
+ * Copyright (c) 2001 M. R. Brown <mrbrown@linuxdc.org>
+ *
+ * This file is part of the LinuxDC project (www.linuxdc.org)
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ *
+ */
+
+#include <asm/irq.h>
+
+/* Hardware events -
+
+   Each of these events correspond to a bit within the Event Mask Registers/
+   Event Status Registers.  Because of the virtual IRQ numbering scheme, a
+   base offset must be used when calculating the virtual IRQ that each event
+   takes.
+*/
+
+#define HW_EVENT_IRQ_BASE  OFFCHIP_IRQ_BASE /* 48 */
+
+/* IRQ 13 */
+#define HW_EVENT_VSYNC     (HW_EVENT_IRQ_BASE +  5) /* VSync */
+#define HW_EVENT_MAPLE_DMA (HW_EVENT_IRQ_BASE + 12) /* Maple DMA complete */
+#define HW_EVENT_GDROM_DMA (HW_EVENT_IRQ_BASE + 14) /* GD-ROM DMA complete */
+
+/* IRQ 11 */
+#define HW_EVENT_GDROM_CMD (HW_EVENT_IRQ_BASE + 32) /* GD-ROM cmd. complete */
+#define HW_EVENT_AICA_SYS  (HW_EVENT_IRQ_BASE + 33) /* AICA-related */
+#define HW_EVENT_EXTERNAL  (HW_EVENT_IRQ_BASE + 35) /* Ext. (expansion) */
+
+#define HW_EVENT_IRQ_MAX (HW_EVENT_IRQ_BASE + 95)
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/hardirq.h linux/include/asm-sh/hardirq.h
--- v2.4.5/linux/include/asm-sh/hardirq.h	Fri Aug  4 16:15:37 2000
+++ linux/include/asm-sh/hardirq.h	Wed Jun 27 13:55:29 2001
@@ -6,8 +6,7 @@
 
 /* entry.S is sensitive to the offsets of these fields */
 typedef struct {
-	unsigned int __softirq_active;
-	unsigned int __softirq_mask;
+	unsigned int __softirq_pending;
 	unsigned int __local_irq_count;
 	unsigned int __local_bh_count;
 	unsigned int __syscall_count;
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/hd64465_gpio.h linux/include/asm-sh/hd64465_gpio.h
--- v2.4.5/linux/include/asm-sh/hd64465_gpio.h	Sun May 20 12:11:39 2001
+++ linux/include/asm-sh/hd64465_gpio.h	Wed Jun 27 13:55:29 2001
@@ -1,7 +1,7 @@
 #ifndef _ASM_SH_HD64465_GPIO_
 #define _ASM_SH_HD64465_GPIO_ 1
 /*
- * $Id: hd64465_gpio.h,v 1.1 2001/01/02 15:35:22 mjd Exp $
+ * $Id: hd64465_gpio.h,v 1.2 2001/05/24 00:14:13 gniibe Exp $
  *
  * Hitachi HD64465 companion chip: General Purpose IO pins support.
  * This layer enables other device drivers to configure GPIO
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/io.h linux/include/asm-sh/io.h
--- v2.4.5/linux/include/asm-sh/io.h	Wed Apr 11 21:24:52 2001
+++ linux/include/asm-sh/io.h	Wed Jun 27 13:55:29 2001
@@ -109,10 +109,10 @@
 
 # if defined(CONFIG_SH_HP600)
 #  include <asm/io_hd64461.h>
-# elif defined(CONFIG_SH_7750_OVERDRIVE)
-#  include <asm/io_od.h>
-# elif defined(CONFIG_SH_SOLUTION_ENGINE)
+# elif (defined(CONFIG_SH_SOLUTION_ENGINE) || defined(CONFIG_SH_7751_SOLUTION_ENGINE))
 #  include <asm/io_se.h>
+# elif defined(CONFIG_SH_SH2000)
+#  include <asm/io_sh2000.h>
 # elif defined(CONFIG_SH_DMIDA) || \
        defined(CONFIG_SH_STB1_HARP) || \
        defined(CONFIG_SH_STB1_OVERDRIVE)
@@ -123,6 +123,8 @@
 #  include <asm/io_dc.h>
 # elif defined(CONFIG_SH_CAT68701)
 #  include <asm/io_cat68701.h>
+# elif defined(CONFIG_SH_BIGSUR)
+#  include <asm/io_bigsur.h>
 # elif defined(CONFIG_SH_UNKNOWN)
 #  include <asm/io_unknown.h>
 # else
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/io_bigsur.h linux/include/asm-sh/io_bigsur.h
--- v2.4.5/linux/include/asm-sh/io_bigsur.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-sh/io_bigsur.h	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,89 @@
+/*
+ * include/asm-sh/io_bigsur.h
+ *
+ * By Dustin McIntire (dustin@sensoria.com) (c)2001
+ * Derived from io_hd64465.h, which bore the message:
+ * By Greg Banks <gbanks@pocketpenguins.com>
+ * (c) 2000 PocketPenguins Inc. 
+ * and from io_hd64461.h, which bore the message:
+ * Copyright 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * IO functions for a Hitachi Big Sur Evaluation Board.
+ */
+
+#ifndef _ASM_SH_IO_BIGSUR_H
+#define _ASM_SH_IO_BIGSUR_H
+
+#include <linux/types.h>
+#include <asm/io_generic.h>
+
+extern unsigned char bigsur_inb(unsigned long port);
+extern unsigned short bigsur_inw(unsigned long port);
+extern unsigned int bigsur_inl(unsigned long port);
+
+extern void bigsur_outb(unsigned char value, unsigned long port);
+extern void bigsur_outw(unsigned short value, unsigned long port);
+extern void bigsur_outl(unsigned int value, unsigned long port);
+
+extern unsigned char bigsur_inb_p(unsigned long port);
+extern void bigsur_outb_p(unsigned char value, unsigned long port);
+
+extern void bigsur_insb(unsigned long port, void *addr, unsigned long count);
+extern void bigsur_insw(unsigned long port, void *addr, unsigned long count);
+extern void bigsur_insl(unsigned long port, void *addr, unsigned long count);
+extern void bigsur_outsb(unsigned long port, const void *addr, unsigned long count);
+extern void bigsur_outsw(unsigned long port, const void *addr, unsigned long count);
+extern void bigsur_outsl(unsigned long port, const void *addr, unsigned long count);
+extern unsigned long bigsur_isa_port2addr(unsigned long offset);
+extern int bigsur_irq_demux(int irq);
+extern void bigsur_init_pci(void);
+/* Provision for generic secondary demux step -- used by PCMCIA code */
+extern void bigsur_register_irq_demux(int irq,
+		int (*demux)(int irq, void *dev), void *dev);
+extern void bigsur_unregister_irq_demux(int irq);
+/* Set this variable to 1 to see port traffic */
+extern int bigsur_io_debug;
+/* Map a range of ports to a range of kernel virtual memory. */
+extern void bigsur_port_map(u32 baseport, u32 nports, u32 addr, u8 shift);
+extern void bigsur_port_unmap(u32 baseport, u32 nports);
+
+#endif /* _ASM_SH_IO_BIGSUR_H */
+
+#ifdef __WANT_IO_DEF
+
+# define __inb			bigsur_inb
+# define __inw			bigsur_inw
+# define __inl			bigsur_inl
+# define __outb			bigsur_outb
+# define __outw			bigsur_outw
+# define __outl			bigsur_outl
+
+# define __inb_p		bigsur_inb_p
+# define __inw_p		bigsur_inw
+# define __inl_p		bigsur_inl
+# define __outb_p		bigsur_outb_p
+# define __outw_p		bigsur_outw
+# define __outl_p		bigsur_outl
+
+# define __insb			bigsur_insb
+# define __insw			bigsur_insw
+# define __insl			bigsur_insl
+# define __outsb		bigsur_outsb
+# define __outsw		bigsur_outsw
+# define __outsl		bigsur_outsl
+
+# define __readb		generic_readb
+# define __readw		generic_readw
+# define __readl		generic_readl
+# define __writeb		generic_writeb
+# define __writew		generic_writew
+# define __writel		generic_writel
+
+# define __isa_port2addr	bigsur_isa_port2addr
+# define __ioremap		generic_ioremap
+# define __iounmap		generic_iounmap
+
+#endif
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/io_od.h linux/include/asm-sh/io_od.h
--- v2.4.5/linux/include/asm-sh/io_od.h	Wed Apr 11 21:24:52 2001
+++ linux/include/asm-sh/io_od.h	Wed Dec 31 16:00:00 1969
@@ -1,77 +0,0 @@
-/*
- * include/asm-sh/io_od.h
- *
- * Copyright 2000 Stuart Menefy (stuart.menefy@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * IO functions for an STMicroelectronics Overdrive
- */
-
-#ifndef _ASM_SH_IO_OD_H
-#define _ASM_SH_IO_OD_H
-
-#include <asm/io_generic.h>
-
-extern unsigned char od_inb(unsigned long port);
-extern unsigned short od_inw(unsigned long port);
-extern unsigned int od_inl(unsigned long port);
-
-extern void od_outb(unsigned char value, unsigned long port);
-extern void od_outw(unsigned short value, unsigned long port);
-extern void od_outl(unsigned int value, unsigned long port);
-
-extern unsigned char od_inb_p(unsigned long port);
-extern unsigned short od_inw_p(unsigned long port);
-extern unsigned int od_inl_p(unsigned long port);
-extern void od_outb_p(unsigned char value, unsigned long port);
-extern void od_outw_p(unsigned short value, unsigned long port);
-extern void od_outl_p(unsigned int value, unsigned long port);
-
-extern void od_insb(unsigned long port, void *addr, unsigned long count);
-extern void od_insw(unsigned long port, void *addr, unsigned long count);
-extern void od_insl(unsigned long port, void *addr, unsigned long count);
-extern void od_outsb(unsigned long port, const void *addr, unsigned long count);
-extern void od_outsw(unsigned long port, const void *addr, unsigned long count);
-extern void od_outsl(unsigned long port, const void *addr, unsigned long count);
-
-extern unsigned long od_isa_port2addr(unsigned long offset);
-
-#ifdef __WANT_IO_DEF
-
-# define __inb			od_inb
-# define __inw			od_inw
-# define __inl			od_inl
-# define __outb			od_outb
-# define __outw			od_outw
-# define __outl			od_outl
-
-# define __inb_p		od_inb_p
-# define __inw_p		od_inw_p
-# define __inl_p		od_inl_p
-# define __outb_p		od_outb_p
-# define __outw_p		od_outw_p
-# define __outl_p		od_outl_p
-
-# define __insb			od_insb
-# define __insw			od_insw
-# define __insl			od_insl
-# define __outsb		od_outsb
-# define __outsw		od_outsw
-# define __outsl		od_outsl
-
-# define __readb		generic_readb
-# define __readw		generic_readw
-# define __readl		generic_readl
-# define __writeb		generic_writeb
-# define __writew		generic_writew
-# define __writel		generic_writel
-
-# define __isa_port2addr	od_isa_port2addr
-# define __ioremap		generic_ioremap
-# define __iounmap		generic_iounmap
-
-#endif
-
-#endif /* _ASM_SH_IO_OD_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/io_sh2000.h linux/include/asm-sh/io_sh2000.h
--- v2.4.5/linux/include/asm-sh/io_sh2000.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-sh/io_sh2000.h	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,56 @@
+/*
+ * include/asm-sh/io_sh2000.h
+ *
+ * Copyright 2000 Stuart Menefy (stuart.menefy@st.com)
+ *           2001 SUGIOKA Toshinobu (sugioka@itonet.co.jp)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * IO functions for use when we don't know what machine we are on
+ */
+
+#ifndef _ASM_SH_IO_SH2000_H
+#define _ASM_SH_IO_SH2000_H
+
+#include <asm/io_generic.h>
+
+unsigned long sh2000_isa_port2addr(unsigned long offset);
+
+#ifdef __WANT_IO_DEF
+
+# define __inb			generic_inb
+# define __inw			generic_inw
+# define __inl			generic_inl
+# define __outb			generic_outb
+# define __outw			generic_outw
+# define __outl			generic_outl
+
+# define __inb_p		generic_inb_p
+# define __inw_p		generic_inw
+# define __inl_p		generic_inl
+# define __outb_p		generic_outb_p
+# define __outw_p		generic_outw
+# define __outl_p		generic_outl
+
+# define __insb			generic_insb
+# define __insw			generic_insw
+# define __insl			generic_insl
+# define __outsb		generic_outsb
+# define __outsw		generic_outsw
+# define __outsl		generic_outsl
+
+# define __readb		generic_readb
+# define __readw		generic_readw
+# define __readl		generic_readl
+# define __writeb		generic_writeb
+# define __writew		generic_writew
+# define __writel		generic_writel
+
+# define __isa_port2addr	sh2000_isa_port2addr
+# define __ioremap		generic_ioremap
+# define __iounmap		generic_iounmap
+
+#endif
+
+#endif /* _ASM_SH_IO_SH2000_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/irq.h linux/include/asm-sh/irq.h
--- v2.4.5/linux/include/asm-sh/irq.h	Wed Apr 11 21:24:52 2001
+++ linux/include/asm-sh/irq.h	Wed Jun 27 13:55:29 2001
@@ -43,7 +43,8 @@
 #define DMA_PRIORITY	7
 
 #if defined (CONFIG_CPU_SUBTYPE_SH7707) || defined (CONFIG_CPU_SUBTYPE_SH7708) || \
-    defined (CONFIG_CPU_SUBTYPE_SH7709) || defined (CONFIG_CPU_SUBTYPE_SH7750)
+    defined (CONFIG_CPU_SUBTYPE_SH7709) || defined (CONFIG_CPU_SUBTYPE_SH7750) || \
+    defined (CONFIG_CPU_SUBTYPE_SH7751)
 #define SCI_ERI_IRQ	23
 #define SCI_RXI_IRQ	24
 #define SCI_TXI_IRQ	25
@@ -68,7 +69,8 @@
 #define IRDA_IPR_ADDR	INTC_IPRE
 #define IRDA_IPR_POS	2
 #define IRDA_PRIORITY	3
-#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_ST40STB1)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) || \
+      defined(CONFIG_CPU_SUBTYPE_ST40STB1)
 #define SCIF_ERI_IRQ	40
 #define SCIF_RXI_IRQ	41
 #define SCIF_BRI_IRQ	42
@@ -95,7 +97,7 @@
 
 /* 1. ONCHIP_NR_IRQS */
 #ifdef CONFIG_SH_GENERIC
-# define ONCHIP_NR_IRQS 89
+# define ONCHIP_NR_IRQS 144
 #else
 # if defined(CONFIG_CPU_SUBTYPE_SH7707)
 #  define ONCHIP_NR_IRQS 64
@@ -107,8 +109,10 @@
 #  define PINT_NR_IRQS   16
 # elif defined(CONFIG_CPU_SUBTYPE_SH7750)
 #  define ONCHIP_NR_IRQS 48	// Actually 44
+# elif defined(CONFIG_CPU_SUBTYPE_SH7751)
+#  define ONCHIP_NR_IRQS 72
 # elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
-#  define ONCHIP_NR_IRQS 89
+#  define ONCHIP_NR_IRQS 144
 # endif
 #endif
 
@@ -131,10 +135,14 @@
 #else
 # if defined(CONFIG_HD64461)
 #  define OFFCHIP_NR_IRQS 16
+# elif defined (CONFIG_SH_BIGSUR) /* must be before CONFIG_HD64465 */
+#  define OFFCHIP_NR_IRQS 48
 # elif defined(CONFIG_HD64465)
 #  define OFFCHIP_NR_IRQS 16
 # elif defined (CONFIG_SH_EC3104)
 #  define OFFCHIP_NR_IRQS 16
+# elif defined (CONFIG_SH_DREAMCAST)
+#  define OFFCHIP_NR_IRQS 96
 # else
 #  define OFFCHIP_NR_IRQS 0
 # endif
@@ -240,6 +248,16 @@
 #define __irq_demux(irq) irq
 #endif /* CONFIG_CPU_SUBTYPE_SH7707 || CONFIG_CPU_SUBTYPE_SH7709 */
 
+#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) || \
+    defined(CONFIG_CPU_SUBTYPE_ST40STB1)
+#define INTC_ICR        0xffd00000
+#define INTC_ICR_NMIL	(1<<15)
+#define INTC_ICR_MAI	(1<<14)
+#define INTC_ICR_NMIB	(1<<9)
+#define INTC_ICR_NMIE	(1<<8)
+#define INTC_ICR_IRLM	(1<<7)
+#endif
+
 #ifdef CONFIG_CPU_SUBTYPE_ST40STB1
 #define INTC2_FIRST_IRQ 64
 #define NR_INTC2_IRQS 25
@@ -266,6 +284,11 @@
 	return __irq_demux(irq);
 }
 
+#elif defined(CONFIG_SH_BIGSUR)
+
+extern int bigsur_irq_demux(int irq);
+#define irq_demux(irq) bigsur_irq_demux(irq)
+
 #elif defined(CONFIG_HD64461)
 
 extern int hd64461_irq_demux(int irq);
@@ -285,6 +308,11 @@
 
 extern int cat68701_irq_demux(int irq);
 #define irq_demux cat68701_irq_demux
+
+#elif defined(CONFIG_SH_DREAMCAST)
+
+extern int systemasic_irq_demux(int irq);
+#define irq_demux systemasic_irq_demux
 
 #else
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/linux_logo.h linux/include/asm-sh/linux_logo.h
--- v2.4.5/linux/include/asm-sh/linux_logo.h	Mon Jun 19 17:59:38 2000
+++ linux/include/asm-sh/linux_logo.h	Mon Jun 11 19:15:27 2001
@@ -23,26 +23,5 @@
 
 #define linux_logo_banner "Linux/SuperH version " UTS_RELEASE
 
-#define LINUX_LOGO_COLORS 214
-
-#ifdef INCLUDE_LINUX_LOGO_DATA
-
-#define INCLUDE_LINUX_LOGOBW
-#define INCLUDE_LINUX_LOGO16
-
 #include <linux/linux_logo.h>
 
-#else
-
-/* prototypes only */
-extern unsigned char linux_logo_red[];
-extern unsigned char linux_logo_green[];
-extern unsigned char linux_logo_blue[];
-extern unsigned char linux_logo[];
-extern unsigned char linux_logo_bw[];
-extern unsigned char linux_logo16_red[];
-extern unsigned char linux_logo16_green[];
-extern unsigned char linux_logo16_blue[];
-extern unsigned char linux_logo16[];
-
-#endif
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/machvec.h linux/include/asm-sh/machvec.h
--- v2.4.5/linux/include/asm-sh/machvec.h	Wed Apr 11 21:24:52 2001
+++ linux/include/asm-sh/machvec.h	Wed Jun 27 13:55:29 2001
@@ -72,8 +72,10 @@
 	unsigned int mv_hw_hp680 : 1;
 	unsigned int mv_hw_hp690 : 1;
 	unsigned int mv_hw_hd64461 : 1;
+	unsigned int mv_hw_sh2000 : 1;
 	unsigned int mv_hw_hd64465 : 1;
 	unsigned int mv_hw_dreamcast : 1;
+	unsigned int mv_hw_bigsur : 1;
 };
 
 extern struct sh_machine_vector sh_mv;
@@ -87,9 +89,12 @@
 #define MACH_HP690	(sh_mv.mv_hw_hp690)
 #define MACH_HD64461	(sh_mv.mv_hw_hd64461)
 #define MACH_HD64465	(sh_mv.mv_hw_hd64465)
+#define MACH_SH2000	(sh_mv.mv_hw_sh2000)
 #define MACH_DREAMCAST	(sh_mv.mv_hw_dreamcast)
+#define MACH_BIGSUR	(sh_mv.mv_hw_bigsur)
 #else
-# ifdef CONFIG_SH_SOLUTION_ENGINE
+# if defined(CONFIG_SH_SOLUTION_ENGINE) || \
+     defined(CONFIG_SH_7751_SOLUTION_ENGINE)
 #  define MACH_SE		1
 # else
 #  define MACH_SE		0
@@ -114,6 +119,7 @@
 # else
 #  define MACH_HP690		0
 # endif
+# endif
 # ifdef CONFIG_HD64461
 #  define MACH_HD64461		1
 # else
@@ -124,6 +130,11 @@
 # else
 #  define MACH_HD64465		0
 # endif
+# ifdef CONFIG_SH_SH2000
+#  define MACH_SH2000		1
+# else
+#  define MACH_SH2000		0
+# endif
 # ifdef CONFIG_SH_EC3104
 #  define MACH_EC3104		1
 # else
@@ -134,6 +145,10 @@
 # else
 #  define MACH_DREAMCAST	0
 # endif
+# ifdef CONFIG_SH_BIGSUR
+#  define MACH_BIGSUR		1
+# else
+#  define MACH_BIGSUR		0
 #endif
 
 #endif /* _ASM_SH_MACHVEC_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/mc146818rtc.h linux/include/asm-sh/mc146818rtc.h
--- v2.4.5/linux/include/asm-sh/mc146818rtc.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-sh/mc146818rtc.h	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,159 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef _ASM_MC146818RTC_H
+#define _ASM_MC146818RTC_H
+
+#include <asm/rtc.h>
+
+#define RTC_ALWAYS_BCD	1
+
+/* FIXME:RTC Interrupt feature is not implemented yet. */
+#undef  RTC_IRQ
+#define RTC_IRQ		0
+
+#if defined(__sh3__)
+#define RTC_PORT(n)		(R64CNT+(n)*2)
+#define CMOS_READ(addr)		__CMOS_READ(addr,b)
+#define CMOS_WRITE(val,addr)	__CMOS_WRITE(val,addr,b)
+
+#elif defined(__SH4__)
+#define RTC_PORT(n)		(R64CNT+(n)*4)
+#define CMOS_READ(addr)		__CMOS_READ(addr,w)
+#define CMOS_WRITE(val,addr)	__CMOS_WRITE(val,addr,w)
+#endif
+
+#define __CMOS_READ(addr, s) ({						\
+	unsigned char val=0, rcr1, rcr2, r64cnt, retry;			\
+	switch(addr) {							\
+		case RTC_SECONDS:					\
+			val = ctrl_inb(RSECCNT);			\
+			break;						\
+		case RTC_SECONDS_ALARM:					\
+			val = ctrl_inb(RSECAR);				\
+			break;						\
+		case RTC_MINUTES:					\
+			val = ctrl_inb(RMINCNT);			\
+			break;						\
+		case RTC_MINUTES_ALARM:					\
+			val = ctrl_inb(RMINAR);				\
+			break;						\
+		case RTC_HOURS:						\
+			val = ctrl_inb(RHRCNT);				\
+			break;						\
+		case RTC_HOURS_ALARM:					\
+			val = ctrl_inb(RHRAR);				\
+			break;						\
+		case RTC_DAY_OF_WEEK:					\
+			val = ctrl_inb(RWKCNT);				\
+			break;						\
+		case RTC_DAY_OF_MONTH:					\
+			val = ctrl_inb(RDAYCNT);			\
+			break;						\
+		case RTC_MONTH:						\
+			val = ctrl_inb(RMONCNT);			\
+			break;						\
+		case RTC_YEAR:						\
+			val = ctrl_in##s(RYRCNT);			\
+			break;						\
+		case RTC_REG_A: /* RTC_FREQ_SELECT */			\
+			rcr2 = ctrl_inb(RCR2);				\
+			val = (rcr2 & RCR2_PESMASK) >> 4;		\
+			rcr1 = ctrl_inb(RCR1);				\
+			rcr1 = (rcr1 & (RCR1_CIE | RCR1_AIE)) | RCR1_AF;\
+			retry = 0;					\
+			do {						\
+				ctrl_outb(rcr1, RCR1); /* clear CF */	\
+				r64cnt = ctrl_inb(R64CNT);		\
+			} while((ctrl_inb(RCR1) & RCR1_CF) && retry++ < 1000);\
+			r64cnt ^= RTC_BIT_INVERTED;			\
+			if(r64cnt == 0x7f || r64cnt == 0)		\
+				val |= RTC_UIP;				\
+			break;						\
+		case RTC_REG_B:	/* RTC_CONTROL */			\
+			rcr1 = ctrl_inb(RCR1);				\
+			rcr2 = ctrl_inb(RCR2);				\
+			if(rcr1 & RCR1_CIE)	val |= RTC_UIE;		\
+			if(rcr1 & RCR1_AIE)	val |= RTC_AIE;		\
+			if(rcr2 & RCR2_PESMASK)	val |= RTC_PIE;		\
+			if(!(rcr2 & RCR2_START))val |= RTC_SET;		\
+			val |= RTC_24H;					\
+			break;						\
+		case RTC_REG_C:	/* RTC_INTR_FLAGS */			\
+			rcr1 = ctrl_inb(RCR1);				\
+			rcr1 &= ~(RCR1_CF | RCR1_AF);			\
+			ctrl_outb(rcr1, RCR1);				\
+			rcr2 = ctrl_inb(RCR2);				\
+			rcr2 &= ~RCR2_PEF;				\
+			ctrl_outb(rcr2, RCR2);				\
+			break;						\
+		case RTC_REG_D:	/* RTC_VALID */				\
+			/* Always valid ... */				\
+			val = RTC_VRT;					\
+			break;						\
+		default:						\
+			break;						\
+	}								\
+	val;								\
+})
+
+#define __CMOS_WRITE(val, addr, s) ({					\
+	unsigned char rcr1,rcr2;					\
+	switch(addr) {							\
+		case RTC_SECONDS:					\
+			ctrl_outb(val, RSECCNT);			\
+			break;						\
+		case RTC_SECONDS_ALARM:					\
+			ctrl_outb(val, RSECAR);				\
+			break;						\
+		case RTC_MINUTES:					\
+			ctrl_outb(val, RMINCNT);			\
+			break;						\
+		case RTC_MINUTES_ALARM:					\
+			ctrl_outb(val, RMINAR);				\
+			break;						\
+		case RTC_HOURS:						\
+			ctrl_outb(val, RHRCNT);				\
+			break;						\
+		case RTC_HOURS_ALARM:					\
+			ctrl_outb(val, RHRAR);				\
+			break;						\
+		case RTC_DAY_OF_WEEK:					\
+			ctrl_outb(val, RWKCNT);				\
+			break;						\
+		case RTC_DAY_OF_MONTH:					\
+			ctrl_outb(val, RDAYCNT);			\
+			break;						\
+		case RTC_MONTH:						\
+			ctrl_outb(val, RMONCNT);			\
+			break;						\
+		case RTC_YEAR:						\
+			ctrl_out##s((ctrl_in##s(RYRCNT) & 0xff00) | (val & 0xff), RYRCNT);\
+			break;						\
+		case RTC_REG_A: /* RTC_FREQ_SELECT */			\
+			rcr2 = ctrl_inb(RCR2);				\
+			if((val & RTC_DIV_CTL) == RTC_DIV_RESET2)	\
+				rcr2 |= RCR2_RESET;			\
+			ctrl_outb(rcr2, RCR2);				\
+			break;						\
+		case RTC_REG_B:	/* RTC_CONTROL */			\
+			rcr1 = (ctrl_inb(RCR1) & 0x99) | RCR1_AF;	\
+			if(val & RTC_AIE) rcr1 |= RCR1_AIE;		\
+			else              rcr1 &= ~RCR1_AIE;		\
+			if(val & RTC_UIE) rcr1 |= RCR1_CIE;		\
+			else              rcr1 &= ~RCR1_CIE;		\
+			ctrl_outb(rcr1, RCR1);				\
+			rcr2 = ctrl_inb(RCR2);				\
+			if(val & RTC_SET) rcr2 &= ~RCR2_START;		\
+			else              rcr2 |= RCR2_START;		\
+			ctrl_outb(rcr2, RCR2);				\
+			break;						\
+		case RTC_REG_C:	/* RTC_INTR_FLAGS */			\
+			break;						\
+		case RTC_REG_D:	/* RTC_VALID */				\
+			break;						\
+		default:						\
+			break;						\
+	}								\
+})
+#endif /* _ASM_MC146818RTC_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/pci-sh7751.h linux/include/asm-sh/pci-sh7751.h
--- v2.4.5/linux/include/asm-sh/pci-sh7751.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-sh/pci-sh7751.h	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,281 @@
+/*
+ *	Low-Level PCI Support for SH7751 targets
+ *
+ *  Dustin McIntire (dustin@sensoria.com) (c) 2001
+ *	
+ *  May be copied or modified under the terms of the GNU General Public
+ *  License.  See linux/COPYING for more information.
+ *
+ */
+
+#ifndef _PCI_SH7751_H_
+#define _PCI_SH7751_H_
+
+#include <linux/pci.h>
+
+/* set debug level 4=verbose...1=terse */
+//#define DEBUG_PCI 3
+#undef DEBUG_PCI
+
+#ifdef DEBUG_PCI
+#define PCIDBG(n, x...) { if(DEBUG_PCI>=n) printk(x); }
+#else
+#define PCIDBG(n, x...)
+#endif
+
+/* startup values */
+#define PCI_PROBE_BIOS 1
+#define PCI_PROBE_CONF1 2
+#define PCI_PROBE_CONF2 4
+#define PCI_NO_SORT 0x100
+#define PCI_BIOS_SORT 0x200
+#define PCI_NO_CHECKS 0x400
+#define PCI_ASSIGN_ROMS 0x1000
+#define PCI_BIOS_IRQ_SCAN 0x2000
+
+/* Platform Specific Values */
+#define SH7751_VENDOR_ID             0x1054
+#define SH7751_DEVICE_ID             0x3505
+
+/* SH7751 Specific Values */
+#define SH7751_PCI_CONFIG_BASE	     0xFD000000  /* Config space base addr */
+#define SH7751_PCI_CONFIG_SIZE       0x1000000   /* Config space size */
+#define SH7751_PCI_MEMORY_BASE	     0xFD000000  /* Memory space base addr */
+#define SH7751_PCI_MEM_SIZE          0x01000000  /* Size of Memory window */
+#define SH7751_PCI_IO_BASE           0xFE240000  /* IO space base address */
+#define SH7751_PCI_IO_SIZE           0x40000     /* Size of IO window */
+
+#define SH7751_PCIREG_BASE           0xFE200000  /* PCI regs base address */
+#define PCI_REG(n)                  (SH7751_PCIREG_BASE+ n)
+
+#define SH7751_PCICONF0            0x0           /* PCI Config Reg 0 */
+  #define SH7751_PCICONF0_DEVID      0xFFFF0000  /* Device ID */
+  #define SH7751_PCICONF0_VNDID      0x0000FFFF  /* Vendor ID */
+#define SH7751_PCICONF1            0x4           /* PCI Config Reg 1 */
+  #define SH7751_PCICONF1_DPE        0x80000000  /* Data Parity Error */
+  #define SH7751_PCICONF1_SSE        0x40000000  /* System Error Status */
+  #define SH7751_PCICONF1_RMA        0x20000000  /* Master Abort */
+  #define SH7751_PCICONF1_RTA        0x10000000  /* Target Abort Rx Status */
+  #define SH7751_PCICONF1_STA        0x08000000  /* Target Abort Exec Status */
+  #define SH7751_PCICONF1_DEV        0x06000000  /* Timing Status */
+  #define SH7751_PCICONF1_DPD        0x01000000  /* Data Parity Status */
+  #define SH7751_PCICONF1_FBBC       0x00800000  /* Back 2 Back Status */
+  #define SH7751_PCICONF1_UDF        0x00400000  /* User Defined Status */
+  #define SH7751_PCICONF1_66M        0x00200000  /* 66Mhz Operation Status */
+  #define SH7751_PCICONF1_PM         0x00100000  /* Power Management Status */
+  #define SH7751_PCICONF1_PBBE       0x00000200  /* Back 2 Back Control */
+  #define SH7751_PCICONF1_SER        0x00000100  /* SERR Output Control */
+  #define SH7751_PCICONF1_WCC        0x00000080  /* Wait Cycle Control */
+  #define SH7751_PCICONF1_PER        0x00000040  /* Parity Error Response */
+  #define SH7751_PCICONF1_VPS        0x00000020  /* VGA Pallet Snoop */
+  #define SH7751_PCICONF1_MWIE       0x00000010  /* Memory Write+Invalidate */
+  #define SH7751_PCICONF1_SPC        0x00000008  /* Special Cycle Control */
+  #define SH7751_PCICONF1_BUM        0x00000004  /* Bus Master Control */
+  #define SH7751_PCICONF1_MES        0x00000002  /* Memory Space Control */
+  #define SH7751_PCICONF1_IOS        0x00000001  /* I/O Space Control */
+#define SH7751_PCICONF2            0x8           /* PCI Config Reg 2 */
+  #define SH7751_PCICONF2_BCC        0xFF000000  /* Base Class Code */
+  #define SH7751_PCICONF2_SCC        0x00FF0000  /* Sub-Class Code */
+  #define SH7751_PCICONF2_RLPI       0x0000FF00  /* Programming Interface */
+  #define SH7751_PCICONF2_REV        0x000000FF  /* Revision ID */
+#define SH7751_PCICONF3            0xC           /* PCI Config Reg 3 */ 
+  #define SH7751_PCICONF3_BIST7      0x80000000  /* Bist Supported */
+  #define SH7751_PCICONF3_BIST6      0x40000000  /* Bist Executing */
+  #define SH7751_PCICONF3_BIST3_0    0x0F000000  /* Bist Passed */
+  #define SH7751_PCICONF3_HD7        0x00800000  /* Single Funtion device */
+  #define SH7751_PCICONF3_HD6_0      0x007F0000  /* Configuration Layout */
+  #define SH7751_PCICONF3_LAT        0x0000FF00  /* Latency Timer */
+  #define SH7751_PCICONF3_CLS        0x000000FF  /* Cache Line Size */
+#define SH7751_PCICONF4            0x10          /* PCI Config Reg 4 */
+  #define SH7751_PCICONF4_BASE       0xFFFFFFFC  /* I/O Space Base Addr */
+  #define SH7751_PCICONF4_ASI        0x00000001  /* Address Space Type */
+#define SH7751_PCICONF5            0x14          /* PCI Config Reg 5 */
+  #define SH7751_PCICONF5_BASE       0xFFFFFFF0  /* Mem Space Base Addr */
+  #define SH7751_PCICONF5_LAP        0x00000008  /* Prefetch Enabled */
+  #define SH7751_PCICONF5_LAT        0x00000006  /* Local Memory type */
+  #define SH7751_PCICONF5_ASI        0x00000001  /* Address Space Type */  
+#define SH7751_PCICONF6            0x18          /* PCI Config Reg 6 */
+  #define SH7751_PCICONF6_BASE       0xFFFFFFF0  /* Mem Space Base Addr */
+  #define SH7751_PCICONF6_LAP        0x00000008  /* Prefetch Enabled */
+  #define SH7751_PCICONF6_LAT        0x00000006  /* Local Memory type */
+  #define SH7751_PCICONF6_ASI        0x00000001  /* Address Space Type */  
+/* PCICONF7 - PCICONF10 are undefined */
+#define SH7751_PCICONF11           0x2C          /* PCI Config Reg 11 */
+  #define SH7751_PCICONF11_SSID      0xFFFF0000  /* Subsystem ID */
+  #define SH7751_PCICONF11_SVID      0x0000FFFF  /* Subsystem Vendor ID */
+/* PCICONF12 is undefined */
+#define SH7751_PCICONF13           0x34          /* PCI Config Reg 13 */
+  #define SH7751_PCICONF13_CPTR      0x000000FF  /* PM function pointer */
+/* PCICONF14 is undefined */
+#define SH7751_PCICONF15           0x3C          /* PCI Config Reg 15 */
+  #define SH7751_PCICONF15_IPIN      0x000000FF  /* Interrupt Pin */
+#define SH7751_PCICONF16           0x40          /* PCI Config Reg 16 */
+  #define SH7751_PCICONF16_PMES      0xF8000000  /* PME Support */
+  #define SH7751_PCICONF16_D2S       0x04000000  /* D2 Support */
+  #define SH7751_PCICONF16_D1S       0x02000000  /* D1 Support */
+  #define SH7751_PCICONF16_DSI       0x00200000  /* Bit Device Init. */
+  #define SH7751_PCICONF16_PMCK      0x00080000  /* Clock for PME req. */
+  #define SH7751_PCICONF16_VER       0x00070000  /* PM Version */
+  #define SH7751_PCICONF16_NIP       0x0000FF00  /* Next Item Pointer */
+  #define SH7751_PCICONF16_CID       0x000000FF  /* Capability Identifier */
+#define SH7751_PCICONF17           0x44          /* PCI Config Reg 17 */
+  #define SH7751_PCICONF17_DATA      0xFF000000  /* Data field for PM */
+  #define SH7751_PCICONF17_PMES      0x00800000  /* PME Status */
+  #define SH7751_PCICONF17_DSCL      0x00600000  /* Data Scaling Value */
+  #define SH7751_PCICONF17_DSEL      0x001E0000  /* Data Select */
+  #define SH7751_PCICONF17_PMEN      0x00010000  /* PME Enable */
+  #define SH7751_PCICONF17_PWST      0x00000003  /* Power State */
+/* SH7715 Internal PCI Registers */
+#define SH7751_PCICR               0x100         /* PCI Control Register */
+  #define SH7751_PCICR_PREFIX        0xA5000000  /* CR prefix for write */
+  #define SH7751_PCICR_TRSB          0x00000200  /* Target Read Single */
+  #define SH7751_PCICR_BSWP          0x00000100  /* Target Byte Swap */
+  #define SH7751_PCICR_PLUP          0x00000080  /* Enable PCI Pullup */
+  #define SH7751_PCICR_ARBM          0x00000040  /* PCI Arbitration Mode */
+  #define SH7751_PCICR_MD            0x00000030  /* MD9 and MD10 status */
+  #define SH7751_PCICR_SERR          0x00000008  /* SERR output assert */
+  #define SH7751_PCICR_INTA          0x00000004  /* INTA output assert */
+  #define SH7751_PCICR_PRST          0x00000002  /* PCI Reset Assert */
+  #define SH7751_PCICR_CFIN          0x00000001  /* Central Fun. Init Done */
+#define SH7751_PCILSR0             0x104         /* PCI Local Space Register0 */
+#define SH7751_PCILSR1             0x108         /* PCI Local Space Register1 */
+#define SH7751_PCILAR0             0x10C         /* PCI Local Address Register1 */
+#define SH7751_PCILAR1             0x110         /* PCI Local Address Register1 */
+#define SH7751_PCIINT              0x114         /* PCI Interrupt Register */
+  #define SH7751_PCIINT_MLCK         0x00008000  /* Master Lock Error */
+  #define SH7751_PCIINT_TABT         0x00004000  /* Target Abort Error */
+  #define SH7751_PCIINT_TRET         0x00000200  /* Target Retry Error */
+  #define SH7751_PCIINT_MFDE         0x00000100  /* Master Func. Disable Error */
+  #define SH7751_PCIINT_PRTY         0x00000080  /* Address Parity Error */
+  #define SH7751_PCIINT_SERR         0x00000040  /* SERR Detection Error */
+  #define SH7751_PCIINT_TWDP         0x00000020  /* Tgt. Write Parity Error */
+  #define SH7751_PCIINT_TRDP         0x00000010  /* Tgt. Read Parity Error Det. */
+  #define SH7751_PCIINT_MTABT        0x00000008  /* Master-Tgt. Abort Error */
+  #define SH7751_PCIINT_MMABT        0x00000004  /* Master-Master Abort Error */
+  #define SH7751_PCIINT_MWPD         0x00000002  /* Master Write PERR Detect */
+  #define SH7751_PCIINT_MRPD         0x00000002  /* Master Read PERR Detect */
+#define SH7751_PCIINTM             0x118         /* PCI Interrupt Mask Register */
+#define SH7751_PCIALR              0x11C         /* Error Address Register */
+#define SH7751_PCICLR              0x120         /* Error Command/Data Register */
+  #define SH7751_PCICLR_MPIO         0x80000000  /* Error Command/Data Register */
+  #define SH7751_PCICLR_MDMA0        0x40000000  /* DMA0 Transfer Error */
+  #define SH7751_PCICLR_MDMA1        0x20000000  /* DMA1 Transfer Error */
+  #define SH7751_PCICLR_MDMA2        0x10000000  /* DMA2 Transfer Error */
+  #define SH7751_PCICLR_MDMA3        0x08000000  /* DMA3 Transfer Error */
+  #define SH7751_PCICLR_TGT          0x04000000  /* Target Transfer Error */
+  #define SH7751_PCICLR_CMDL         0x0000000F  /* PCI Command at Error */
+#define SH7751_PCIAINT             0x130         /* Arbiter Interrupt Register */
+  #define SH7751_PCIAINT_MBKN        0x00002000  /* Master Broken Interrupt */
+  #define SH7751_PCIAINT_TBTO        0x00001000  /* Target Bus Time Out */
+  #define SH7751_PCIAINT_MBTO        0x00001000  /* Master Bus Time Out */
+  #define SH7751_PCIAINT_TABT        0x00000008  /* Target Abort */
+  #define SH7751_PCIAINT_MABT        0x00000004  /* Master Abort */
+  #define SH7751_PCIAINT_RDPE        0x00000002  /* Read Data Parity Error */
+  #define SH7751_PCIAINT_WDPE        0x00000002  /* Write Data Parity Error */
+#define SH7751_PCIAINTM            0x134         /* Arbiter Int. Mask Register */
+#define SH7751_PCIBMLR             0x138         /* Error Bus Master Register */
+  #define SH7751_PCIBMLR_REQ4        0x00000010  /* REQ4 bus master at error */
+  #define SH7751_PCIBMLR_REQ3        0x00000008  /* REQ3 bus master at error */
+  #define SH7751_PCIBMLR_REQ2        0x00000004  /* REQ2 bus master at error */
+  #define SH7751_PCIBMLR_REQ1        0x00000002  /* REQ1 bus master at error */
+  #define SH7751_PCIBMLR_REQ0        0x00000001  /* REQ0 bus master at error */
+#define SH7751_PCIDMABT            0x140         /* DMA Transfer Arb. Register */
+  #define SH7751_PCIDMABT_RRBN       0x00000001  /* DMA Arbitor Round-Robin */
+#define SH7751_PCIDPA0             0x180         /* DMA0 Transfer Addr. Register */
+#define SH7751_PCIDLA0             0x184         /* DMA0 Local Addr. Register */
+#define SH7751_PCIDTC0             0x188         /* DMA0 Transfer Cnt. Register */
+#define SH7751_PCIDCR0             0x18C         /* DMA0 Control Register */
+  #define SH7751_PCIDCR_ALGN         0x00000600  /* DMA Alignment Mode */
+  #define SH7751_PCIDCR_MAST         0x00000100  /* DMA Termination Type */
+  #define SH7751_PCIDCR_INTM         0x00000080  /* DMA Interrupt Done Mask*/
+  #define SH7751_PCIDCR_INTS         0x00000040  /* DMA Interrupt Done Status */
+  #define SH7751_PCIDCR_LHLD         0x00000020  /* Local Address Control */
+  #define SH7751_PCIDCR_PHLD         0x00000010  /* PCI Address Control*/
+  #define SH7751_PCIDCR_IOSEL        0x00000008  /* PCI Address Space Type */
+  #define SH7751_PCIDCR_DIR          0x00000004  /* DMA Transfer Direction */
+  #define SH7751_PCIDCR_STOP         0x00000002  /* Force DMA Stop */
+  #define SH7751_PCIDCR_STRT         0x00000001  /* DMA Start */
+#define SH7751_PCIDPA1             0x190         /* DMA1 Transfer Addr. Register */
+#define SH7751_PCIDLA1             0x194         /* DMA1 Local Addr. Register */
+#define SH7751_PCIDTC1             0x198         /* DMA1 Transfer Cnt. Register */
+#define SH7751_PCIDCR1             0x19C         /* DMA1 Control Register */
+#define SH7751_PCIDPA2             0x1A0         /* DMA2 Transfer Addr. Register */
+#define SH7751_PCIDLA2             0x1A4         /* DMA2 Local Addr. Register */
+#define SH7751_PCIDTC2             0x1A8         /* DMA2 Transfer Cnt. Register */
+#define SH7751_PCIDCR2             0x1AC         /* DMA2 Control Register */
+#define SH7751_PCIDPA3             0x1B0         /* DMA3 Transfer Addr. Register */
+#define SH7751_PCIDLA3             0x1B4         /* DMA3 Local Addr. Register */
+#define SH7751_PCIDTC3             0x1B8         /* DMA3 Transfer Cnt. Register */
+#define SH7751_PCIDCR3             0x1BC         /* DMA3 Control Register */
+#define SH7751_PCIPAR              0x1C0         /* PIO Address Register */
+  #define SH7751_PCIPAR_CFGEN        0x80000000  /* Configuration Enable */
+  #define SH7751_PCIPAR_BUSNO        0x00FF0000  /* Config. Bus Number */
+  #define SH7751_PCIPAR_DEVNO        0x0000FF00  /* Config. Device Number */
+  #define SH7751_PCIPAR_REGAD        0x000000FC  /* Register Address Number */
+#define SH7751_PCIMBR              0x1C4         /* Memory Base Address Register */
+  #define SH7751_PCIMBR_MASK         0xFF000000  /* Memory Space Mask */
+  #define SH7751_PCIMBR_LOCK         0x00000001  /* Lock Memory Space */
+#define SH7751_PCIIOBR             0x1C8         /* I/O Base Address Register */
+  #define SH7751_PCIIOBR_MASK         0xFFFC0000 /* IO Space Mask */
+  #define SH7751_PCIIOBR_LOCK         0x00000001 /* Lock IO Space */
+#define SH7751_PCIPINT             0x1CC         /* Power Mgmnt Int. Register */
+  #define SH7751_PCIPINT_D3           0x00000002 /* D3 Pwr Mgmt. Interrupt */
+  #define SH7751_PCIPINT_D0           0x00000001 /* D0 Pwr Mgmt. Interrupt */  
+#define SH7751_PCIPINTM            0x1D0         /* Power Mgmnt Mask Register */
+#define SH7751_PCICLKR             0x1D4         /* Clock Ctrl. Register */
+  #define SH7751_PCICLKR_PCSTP        0x00000002 /* PCI Clock Stop */
+  #define SH7751_PCICLKR_BCSTP        0x00000002 /* BCLK Clock Stop */
+/* For definitions of BCR, MCR see ... */
+#define SH7751_PCIBCR1             0x1E0         /* Memory BCR1 Register */
+#define SH7751_PCIBCR2             0x1E4         /* Memory BCR2 Register */
+#define SH7751_PCIWCR1             0x1E8         /* Wait Control 1 Register */
+#define SH7751_PCIWCR2             0x1EC         /* Wait Control 2 Register */
+#define SH7751_PCIWCR3             0x1F0         /* Wait Control 3 Register */
+#define SH7751_PCIMCR              0x1F4         /* Memory Control Register */
+#define SH7751_PCIPCTR             0x200         /* Port Control Register */
+  #define SH7751_PCIPCTR_P2EN        0x000400000 /* Port 2 Enable */
+  #define SH7751_PCIPCTR_P1EN        0x000200000 /* Port 1 Enable */
+  #define SH7751_PCIPCTR_P0EN        0x000100000 /* Port 0 Enable */
+  #define SH7751_PCIPCTR_P2UP        0x000000020 /* Port2 Pull Up Enable */
+  #define SH7751_PCIPCTR_P2IO        0x000000010 /* Port2 Output Enable */
+  #define SH7751_PCIPCTR_P1UP        0x000000008 /* Port1 Pull Up Enable */
+  #define SH7751_PCIPCTR_P1IO        0x000000004 /* Port1 Output Enable */
+  #define SH7751_PCIPCTR_P0UP        0x000000002 /* Port0 Pull Up Enable */
+  #define SH7751_PCIPCTR_P0IO        0x000000001 /* Port0 Output Enable */
+#define SH7751_PCIPDTR             0x204         /* Port Data Register */
+  #define SH7751_PCIPDTR_PB5         0x000000020 /* Port 5 Enable */
+  #define SH7751_PCIPDTR_PB4         0x000000010 /* Port 4 Enable */
+  #define SH7751_PCIPDTR_PB3         0x000000008 /* Port 3 Enable */
+  #define SH7751_PCIPDTR_PB2         0x000000004 /* Port 2 Enable */
+  #define SH7751_PCIPDTR_PB1         0x000000002 /* Port 1 Enable */
+  #define SH7751_PCIPDTR_PB0         0x000000001 /* Port 0 Enable */
+#define SH7751_PCIPDR              0x220         /* Port IO Data Register */
+
+/* Memory Control Registers */
+#define SH7751_BCR1                0xFF800000    /* Memory BCR1 Register */
+#define SH7751_BCR2                0xFF800004    /* Memory BCR2 Register */
+#define SH7751_WCR1                0xFF800008    /* Wait Control 1 Register */
+#define SH7751_WCR2                0xFF80000C    /* Wait Control 2 Register */
+#define SH7751_WCR3                0xFF800010    /* Wait Control 3 Register */
+#define SH7751_MCR                 0xFF800014    /* Memory Control Register */
+
+/* General Memory Config Addresses */
+#define SH7751_CS0_BASE_ADDR       0x0
+#define SH7751_MEM_REGION_SIZE     0x04000000
+#define SH7751_CS1_BASE_ADDR       (SH7751_CS0_BASE_ADDR + SH7751_MEM_REGION_SIZE)
+#define SH7751_CS2_BASE_ADDR       (SH7751_CS1_BASE_ADDR + SH7751_MEM_REGION_SIZE)
+#define SH7751_CS3_BASE_ADDR       (SH7751_CS2_BASE_ADDR + SH7751_MEM_REGION_SIZE)
+#define SH7751_CS4_BASE_ADDR       (SH7751_CS3_BASE_ADDR + SH7751_MEM_REGION_SIZE)
+#define SH7751_CS5_BASE_ADDR       (SH7751_CS4_BASE_ADDR + SH7751_MEM_REGION_SIZE)
+#define SH7751_CS6_BASE_ADDR       (SH7751_CS5_BASE_ADDR + SH7751_MEM_REGION_SIZE)
+
+/* General PCI values */
+#define SH7751_PCI_HOST_BRIDGE		0x6
+
+/* External functions defined per platform i.e. Big Sur, SE... (these could be routed 
+ * through the machine vectors... */
+extern int pcibios_init_platform(void);
+extern int pcibios_map_platform_irq(u8 slot, u8 pin);
+
+#endif /* _PCI_SH7751_H_ */
+
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/pci.h linux/include/asm-sh/pci.h
--- v2.4.5/linux/include/asm-sh/pci.h	Wed May 16 10:31:27 2001
+++ linux/include/asm-sh/pci.h	Wed Jun 27 13:55:29 2001
@@ -9,19 +9,33 @@
 
 #define pcibios_assign_all_busses()	1
 
+#if defined(CONFIG_CPU_SUBTYPE_ST40STB1)
 /* These are currently the correct values for the STM overdrive board. 
  * We need some way of setting this on a board specific way, it will 
  * not be the same on other boards I think
  */
-#if 1 /* def CONFIG_SH_7750_OVERDRIVE || def CONFIG_CPU_SUBTYPE_ST40STB1 */
 #define PCIBIOS_MIN_IO		0x2000
 #define PCIBIOS_MIN_MEM		0x10000000
+
+#elif defined(CONFIG_SH_DREAMCAST)
+#define PCIBIOS_MIN_IO		0x2000
+#define PCIBIOS_MIN_MEM		0x10000000
+#elif defined(CONFIG_SH_BIGSUR) && defined(CONFIG_CPU_SUBTYPE_SH7751)
+#define PCIBIOS_MIN_IO		0x2000
+#define PCIBIOS_MIN_MEM		0xFD000000
+
+#elif defined(CONFIG_SH_7751_SOLUTION_ENGINE) && defined(CONFIG_CPU_SUBTYPE_SH7751)
+#define PCIBIOS_MIN_IO          0x4000
+#define PCIBIOS_MIN_MEM         0xFD000000
 #endif
 
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
+struct pci_dev;
+
+extern void pcibios_set_master(struct pci_dev *dev);
+//static inline void pcibios_set_master(struct pci_dev *dev)
+//{
 	/* No special bus mastering setup handling */
-}
+//}
 
 static inline void pcibios_penalize_isa_irq(int irq)
 {
@@ -37,8 +51,6 @@
 #include <asm/scatterlist.h>
 #include <linux/string.h>
 #include <asm/io.h>
-
-struct pci_dev;
 
 /* Allocate and map kernel buffer using consistent mode DMA for a device.
  * hwdev should be valid struct pci_dev pointer for PCI devices,
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/pgalloc.h linux/include/asm-sh/pgalloc.h
--- v2.4.5/linux/include/asm-sh/pgalloc.h	Mon Apr 23 15:28:07 2001
+++ linux/include/asm-sh/pgalloc.h	Wed Jun 27 13:55:29 2001
@@ -17,7 +17,7 @@
  * Allocate and free page tables.
  */
 
-static __inline__ pgd_t *get_pgd_slow(void)
+static inline pgd_t *get_pgd_slow(void)
 {
 	unsigned int pgd_size = (USER_PTRS_PER_PGD * sizeof(pgd_t));
 	pgd_t *pgd = (pgd_t *)kmalloc(pgd_size, GFP_KERNEL);
@@ -28,7 +28,7 @@
 	return pgd;
 }
 
-static __inline__ pgd_t *get_pgd_fast(void)
+static inline pgd_t *get_pgd_fast(void)
 {
 	unsigned long *ret;
 
@@ -41,14 +41,14 @@
 	return (pgd_t *)ret;
 }
 
-static __inline__ void free_pgd_fast(pgd_t *pgd)
+static inline void free_pgd_fast(pgd_t *pgd)
 {
 	*(unsigned long *)pgd = (unsigned long) pgd_quicklist;
 	pgd_quicklist = (unsigned long *) pgd;
 	pgtable_cache_size++;
 }
 
-static __inline__ void free_pgd_slow(pgd_t *pgd)
+static inline void free_pgd_slow(pgd_t *pgd)
 {
 	kfree(pgd);
 }
@@ -69,33 +69,33 @@
 
 	if ((ret = (unsigned long *)pte_quicklist) != NULL) {
 		pte_quicklist = (unsigned long *)(*ret);
-		ret[0] = ret[1];
+		ret[0] = 0;
 		pgtable_cache_size--;
 	}
 	return (pte_t *)ret;
 }
 
-static __inline__ void pte_free_fast(pte_t *pte)
+static inline void pte_free_fast(pte_t *pte)
 {
 	*(unsigned long *)pte = (unsigned long) pte_quicklist;
 	pte_quicklist = (unsigned long *) pte;
 	pgtable_cache_size++;
 }
 
-static __inline__ void pte_free_slow(pte_t *pte)
+static inline void pte_free_slow(pte_t *pte)
 {
 	free_page((unsigned long)pte);
 }
 
-#define pte_free(pte)		pte_free_slow(pte)
-#define pgd_free(pgd)		free_pgd_slow(pgd)
+#define pte_free(pte)		pte_free_fast(pte)
+#define pgd_free(pgd)		free_pgd_fast(pgd)
 #define pgd_alloc(mm)		get_pgd_fast()
 
 /*
  * allocating and freeing a pmd is trivial: the 1-entry pmd is
  * inside the pgd, so has no extra memory associated with it.
  */
-static __inline__ void pmd_free(pmd_t * pmd)
+static inline void pmd_free(pmd_t * pmd)
 {
 }
 
@@ -116,7 +116,7 @@
  *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
  *  - flush_tlb_page(vma, vmaddr) flushes one page
  *  - flush_tlb_range(mm, start, end) flushes a range of pages
- *
+ *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  */
 
 extern void flush_tlb(void);
@@ -126,9 +126,9 @@
 			    unsigned long end);
 extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
 
-static __inline__ void flush_tlb_pgtables(struct mm_struct *mm,
-					  unsigned long start, unsigned long end)
-{
+static inline void flush_tlb_pgtables(struct mm_struct *mm,
+				      unsigned long start, unsigned long end)
+{ /* Nothing to do */
 }
 
 #endif /* __ASM_SH_PGALLOC_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/pgtable-2level.h linux/include/asm-sh/pgtable-2level.h
--- v2.4.5/linux/include/asm-sh/pgtable-2level.h	Wed Apr 11 21:24:52 2001
+++ linux/include/asm-sh/pgtable-2level.h	Wed Jun 27 13:55:29 2001
@@ -17,6 +17,7 @@
 
 #define PTRS_PER_PTE	1024
 
+#ifndef __ASSEMBLY__
 #define pte_ERROR(e) \
 	printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
 #define pmd_ERROR(e) \
@@ -32,7 +33,7 @@
 static inline int pgd_none(pgd_t pgd)		{ return 0; }
 static inline int pgd_bad(pgd_t pgd)		{ return 0; }
 static inline int pgd_present(pgd_t pgd)	{ return 1; }
-static inline void pgd_clear (pgd_t * pgd) 	{ }
+static inline void pgd_clear (pgd_t * pgdp) 	{ pgd_val(*(pgdp)) = 0; }
 
 /*
  * Certain architectures need to do special things when PTEs
@@ -54,5 +55,6 @@
 {
 	return (pmd_t *) dir;
 }
+#endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_SH_PGTABLE_2LEVEL_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/pgtable.h linux/include/asm-sh/pgtable.h
--- v2.4.5/linux/include/asm-sh/pgtable.h	Wed Apr 11 21:24:52 2001
+++ linux/include/asm-sh/pgtable.h	Wed Jun 27 13:55:29 2001
@@ -3,6 +3,8 @@
 
 /* Copyright (C) 1999 Niibe Yutaka */
 
+#include <asm/pgtable-2level.h>
+
 /*
  * This file contains the functions and defines necessary to modify and use
  * the SuperH page table tree.
@@ -12,7 +14,7 @@
 #include <asm/addrspace.h>
 #include <linux/threads.h>
 
-extern pgd_t swapper_pg_dir[1024];
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 extern void paging_init(void);
 
 #if defined(__sh3__)
@@ -70,8 +72,6 @@
 
 #endif /* !__ASSEMBLY__ */
 
-#include <asm/pgtable-2level.h>
-
 #define __beep() asm("")
 
 #define PMD_SIZE	(1UL << PMD_SHIFT)
@@ -82,13 +82,6 @@
 #define USER_PTRS_PER_PGD	(TASK_SIZE/PGDIR_SIZE)
 #define FIRST_USER_PGD_NR	0
 
-#define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
-#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
-
-#define TWOLEVEL_PGDIR_SHIFT	22
-#define BOOT_USER_PGD_PTRS (PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
-#define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
-
 #ifndef __ASSEMBLY__
 #define VMALLOC_START	P3SEG
 #define VMALLOC_VMADDR(x) ((unsigned long)(x))
@@ -123,7 +116,15 @@
 
 
 /* Mask which drop software flags */
+#if defined(__sh3__)
+/*
+ * MMU on SH-3 has bug on SH-bit: We can't use it if MMUCR.IX=1.
+ * Work around: Just drop SH-bit.
+ */
+#define _PAGE_FLAGS_HARDWARE_MASK	0x1ffff1fc
+#else
 #define _PAGE_FLAGS_HARDWARE_MASK	0x1ffff1fe
+#endif
 /* Hardware flags: SZ=1 (4k-byte) */
 #define _PAGE_FLAGS_HARD		0x00000010
 
@@ -240,9 +241,6 @@
 /* to find an entry in a kernel page-table-directory */
 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
-#define __pmd_offset(address) \
-		(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
-
 /* Find an entry in the third-level page table.. */
 #define __pte_offset(address) \
 		((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
@@ -263,6 +261,12 @@
 #define pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
 #define swp_entry_to_pte(x)	((pte_t) { (x).val })
 
+/*
+ * Routines for update of PTE 
+ *
+ * We just can use generic implementation, as SuperH has no SMP feature.
+ * (We needed atomic implementation for SMP)
+ */
 #include <asm-generic/pgtable.h>
 
 #endif /* !__ASSEMBLY__ */
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/processor.h linux/include/asm-sh/processor.h
--- v2.4.5/linux/include/asm-sh/processor.h	Wed Apr 11 21:24:52 2001
+++ linux/include/asm-sh/processor.h	Wed Jun 27 13:55:29 2001
@@ -23,7 +23,7 @@
 enum cpu_type {
 	CPU_SH7708,		/* Represents 7707, 7708, 7708S, 7708R, 7709 */
 	CPU_SH7729,		/* Represents 7709A, 7729 */
-	CPU_SH7750,
+	CPU_SH7750,     /* Represents 7750, 7751 */
 	CPU_ST40STB1,
 	CPU_SH_NONE
 };
@@ -38,6 +38,9 @@
 	unsigned long *pte_quick;
 	unsigned long pgtable_cache_sz;
 	unsigned int cpu_clock, master_clock, bus_clock, module_clock;
+#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
+	unsigned int memory_clock;
+#endif
 };
 
 extern struct sh_cpuinfo boot_cpu_data;
@@ -76,7 +79,7 @@
 
 struct sh_fpu_hard_struct {
 	unsigned long fp_regs[16];
-	unsigned long long xd_regs[8];
+	unsigned long xfp_regs[16];
 	unsigned long fpscr;
 	unsigned long fpul;
 
@@ -86,7 +89,7 @@
 /* Dummy fpu emulator  */
 struct sh_fpu_soft_struct {
 	unsigned long fp_regs[16];
-	unsigned long long xd_regs[8];
+	unsigned long xfp_regs[16];
 	unsigned long fpscr;
 	unsigned long fpul;
 
@@ -112,7 +115,7 @@
 };
 
 #define INIT_MMAP \
-{ &init_mm, 0x80000000, 0xa0000000, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
+{ &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
 
 #define INIT_THREAD  {						\
 	sizeof(init_stack) + (long) &init_stack, /* sp */	\
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/rtc.h linux/include/asm-sh/rtc.h
--- v2.4.5/linux/include/asm-sh/rtc.h	Thu Jan  4 13:19:13 2001
+++ linux/include/asm-sh/rtc.h	Wed Jun 27 13:55:29 2001
@@ -9,4 +9,60 @@
 extern void sh_rtc_gettimeofday(struct timeval *tv);
 extern int sh_rtc_settimeofday(const struct timeval *tv);
 
+/* RCR1 Bits */
+#define RCR1_CF		0x80	/* Carry Flag             */
+#define RCR1_CIE	0x10	/* Carry Interrupt Enable */
+#define RCR1_AIE	0x08	/* Alarm Interrupt Enable */
+#define RCR1_AF		0x01	/* Alarm Flag             */
+
+/* RCR2 Bits */
+#define RCR2_PEF	0x80	/* PEriodic interrupt Flag */
+#define RCR2_PESMASK	0x70	/* Periodic interrupt Set  */
+#define RCR2_RTCEN	0x08	/* ENable RTC              */
+#define RCR2_ADJ	0x04	/* ADJustment (30-second)  */
+#define RCR2_RESET	0x02	/* Reset bit               */
+#define RCR2_START	0x01	/* Start bit               */
+
+#if defined(__sh3__)
+/* SH-3 RTC */
+#define R64CNT  	0xfffffec0
+#define RSECCNT 	0xfffffec2
+#define RMINCNT 	0xfffffec4
+#define RHRCNT  	0xfffffec6
+#define RWKCNT  	0xfffffec8
+#define RDAYCNT 	0xfffffeca
+#define RMONCNT 	0xfffffecc
+#define RYRCNT  	0xfffffece
+#define RSECAR  	0xfffffed0
+#define RMINAR  	0xfffffed2
+#define RHRAR   	0xfffffed4
+#define RWKAR   	0xfffffed6
+#define RDAYAR  	0xfffffed8
+#define RMONAR  	0xfffffeda
+#define RCR1    	0xfffffedc
+#define RCR2    	0xfffffede
+
+#define RTC_BIT_INVERTED	0	/* No bug on SH7708, SH7709A */
+#elif defined(__SH4__)
+/* SH-4 RTC */
+#define R64CNT  	0xffc80000
+#define RSECCNT 	0xffc80004
+#define RMINCNT 	0xffc80008
+#define RHRCNT  	0xffc8000c
+#define RWKCNT  	0xffc80010
+#define RDAYCNT 	0xffc80014
+#define RMONCNT 	0xffc80018
+#define RYRCNT  	0xffc8001c  /* 16bit */
+#define RSECAR  	0xffc80020
+#define RMINAR  	0xffc80024
+#define RHRAR   	0xffc80028
+#define RWKAR   	0xffc8002c
+#define RDAYAR  	0xffc80030
+#define RMONAR  	0xffc80034
+#define RCR1    	0xffc80038
+#define RCR2    	0xffc8003c
+
+#define RTC_BIT_INVERTED	0x40	/* bug on SH7750, SH7750S */
+#endif
+
 #endif /* _ASM_RTC_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/semaphore.h linux/include/asm-sh/semaphore.h
--- v2.4.5/linux/include/asm-sh/semaphore.h	Tue Apr 17 17:19:31 2001
+++ linux/include/asm-sh/semaphore.h	Wed Jun 27 13:55:29 2001
@@ -3,6 +3,7 @@
 
 #include <linux/linkage.h>
 
+#ifdef __KERNEL__
 /*
  * SMP- and interrupt-safe semaphores.
  *
@@ -84,13 +85,10 @@
 asmlinkage int  __down_interruptible(struct semaphore * sem);
 asmlinkage int  __down_trylock(struct semaphore * sem);
 asmlinkage void __up(struct semaphore * sem);
-extern struct rw_semaphore *__down_read(struct rw_semaphore *sem, int carry);
-extern struct rw_semaphore *__down_write(struct rw_semaphore *sem, int carry);
-asmlinkage struct rw_semaphore *__rwsem_wake(struct rw_semaphore *sem);
 
 extern spinlock_t semaphore_wake_lock;
 
-extern __inline__ void down(struct semaphore * sem)
+static inline void down(struct semaphore * sem)
 {
 #if WAITQUEUE_DEBUG
 	CHECK_MAGIC(sem->__magic);
@@ -100,7 +98,7 @@
 		__down(sem);
 }
 
-extern __inline__ int down_interruptible(struct semaphore * sem)
+static inline int down_interruptible(struct semaphore * sem)
 {
 	int ret = 0;
 #if WAITQUEUE_DEBUG
@@ -112,7 +110,7 @@
 	return ret;
 }
 
-extern __inline__ int down_trylock(struct semaphore * sem)
+static inline int down_trylock(struct semaphore * sem)
 {
 	int ret = 0;
 #if WAITQUEUE_DEBUG
@@ -128,7 +126,7 @@
  * Note! This is subtle. We jump to wake people up only if
  * the semaphore was negative (== somebody was waiting on it).
  */
-extern __inline__ void up(struct semaphore * sem)
+static inline void up(struct semaphore * sem)
 {
 #if WAITQUEUE_DEBUG
 	CHECK_MAGIC(sem->__magic);
@@ -137,4 +135,5 @@
 		__up(sem);
 }
 
+#endif
 #endif /* __ASM_SH_SEMAPHORE_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/serial-bigsur.h linux/include/asm-sh/serial-bigsur.h
--- v2.4.5/linux/include/asm-sh/serial-bigsur.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-sh/serial-bigsur.h	Wed Jun 27 13:55:29 2001
@@ -0,0 +1,30 @@
+/*
+ * include/asm-sh/serial-bigsur.h
+ *
+ * Configuration details for Big Sur 16550 based serial ports 
+ * i.e. HD64465, PCMCIA, etc.
+ */
+
+#ifndef _ASM_SERIAL_BIGSUR_H
+#define _ASM_SERIAL_BIGSUR_H
+#include <asm/hd64465.h>
+
+#define BASE_BAUD (3379200 / 16)
+
+/* Leave 2 spare for possible PCMCIA serial cards */
+#define RS_TABLE_SIZE  3
+
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+
+#define STD_SERIAL_PORT_DEFNS                   \
+        /* UART CLK   PORT IRQ     FLAGS        */                      \
+        { 0, BASE_BAUD, 0x3F8, HD64465_IRQ_UART, STD_COM_FLAGS } /* ttyS0 */ 
+
+
+#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS
+
+/* XXX: This should be moved ino irq.h */
+#define irq_cannonicalize(x) (x)
+
+#endif /* _ASM_SERIAL_BIGSUR_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/serial.h linux/include/asm-sh/serial.h
--- v2.4.5/linux/include/asm-sh/serial.h	Wed Apr 11 21:24:52 2001
+++ linux/include/asm-sh/serial.h	Wed Jun 27 13:55:29 2001
@@ -12,8 +12,9 @@
 
 #ifdef CONFIG_SH_EC3104
 #include <asm/serial-ec3104.h>
+#elif defined (CONFIG_SH_BIGSUR)
+#include <asm/serial-bigsur.h>
 #else
-
 /*
  * This assumes you have a 1.8432 MHz clock for your UART.
  *
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/socket.h linux/include/asm-sh/socket.h
--- v2.4.5/linux/include/asm-sh/socket.h	Sat Feb  3 11:26:44 2001
+++ linux/include/asm-sh/socket.h	Wed Jun 20 21:00:55 2001
@@ -58,6 +58,7 @@
 					/* level.  For writing rarp and	*/
 					/* other similar things on the	*/
 					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
 #endif
 
 #endif /* __ASM_SH_SOCKET_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/softirq.h linux/include/asm-sh/softirq.h
--- v2.4.5/linux/include/asm-sh/softirq.h	Fri Aug  4 16:15:37 2000
+++ linux/include/asm-sh/softirq.h	Wed Jun 27 13:55:29 2001
@@ -4,11 +4,29 @@
 #include <asm/atomic.h>
 #include <asm/hardirq.h>
 
-#define cpu_bh_disable(cpu)	do { local_bh_count(cpu)++; barrier(); } while (0)
-#define cpu_bh_enable(cpu)	do { barrier(); local_bh_count(cpu)--; } while (0)
+#define local_bh_disable()			\
+do {						\
+	local_bh_count(smp_processor_id())++;	\
+	barrier();				\
+} while (0)
 
-#define local_bh_disable()	cpu_bh_disable(smp_processor_id())
-#define local_bh_enable()	cpu_bh_enable(smp_processor_id())
+#define __local_bh_enable()			\
+do {						\
+	barrier();				\
+	local_bh_count(smp_processor_id())--;	\
+} while (0)
+
+#define local_bh_enable()				\
+do {							\
+	if (!--local_bh_count(smp_processor_id())	\
+	    && softirq_pending(smp_processor_id())) {	\
+		do_softirq();				\
+		__sti();				\
+	}						\
+} while (0)
+
+#define __cpu_raise_softirq(cpu, nr) set_bit((nr), &softirq_pending(cpu));
+#define raise_softirq(nr)	__cpu_raise_softirq(smp_processor_id(), (nr))
 
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/string.h linux/include/asm-sh/string.h
--- v2.4.5/linux/include/asm-sh/string.h	Mon Oct  2 11:57:34 2000
+++ linux/include/asm-sh/string.h	Wed Jun 27 13:55:29 2001
@@ -7,7 +7,7 @@
  */
 
 #define __HAVE_ARCH_STRCPY
-extern __inline__ char *strcpy(char *__dest, const char *__src)
+static __inline__ char *strcpy(char *__dest, const char *__src)
 {
 	register char *__xdest = __dest;
 	unsigned long __dummy;
@@ -26,7 +26,7 @@
 }
 
 #define __HAVE_ARCH_STRNCPY
-extern __inline__ char *strncpy(char *__dest, const char *__src, size_t __n)
+static __inline__ char *strncpy(char *__dest, const char *__src, size_t __n)
 {
 	register char *__xdest = __dest;
 	unsigned long __dummy;
@@ -52,7 +52,7 @@
 }
 
 #define __HAVE_ARCH_STRCMP
-extern __inline__ int strcmp(const char *__cs, const char *__ct)
+static __inline__ int strcmp(const char *__cs, const char *__ct)
 {
 	register int __res;
 	unsigned long __dummy;
@@ -78,7 +78,7 @@
 }
 
 #define __HAVE_ARCH_STRNCMP
-extern __inline__ int strncmp(const char *__cs, const char *__ct, size_t __n)
+static __inline__ int strncmp(const char *__cs, const char *__ct, size_t __n)
 {
 	register int __res;
 	unsigned long __dummy;
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/termios.h linux/include/asm-sh/termios.h
--- v2.4.5/linux/include/asm-sh/termios.h	Sat Feb  3 20:00:45 2001
+++ linux/include/asm-sh/termios.h	Mon Jun 11 19:15:27 2001
@@ -55,6 +55,7 @@
 #define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
 #define N_HDLC		13	/* synchronous HDLC */
 #define N_SYNC_PPP	14
+#define N_HCI		15  /* Bluetooth HCI UART */
 
 #ifdef __KERNEL__
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/user.h linux/include/asm-sh/user.h
--- v2.4.5/linux/include/asm-sh/user.h	Mon Mar 27 10:26:15 2000
+++ linux/include/asm-sh/user.h	Wed Jun 27 13:55:29 2001
@@ -31,7 +31,7 @@
 
 struct user_fpu_struct {
 	unsigned long fp_regs[16];
-	unsigned long long xd_regs[8];
+	unsigned long xfp_regs[16];
 	unsigned long fpscr;
 	unsigned long fpul;
 };
diff -u --recursive --new-file v2.4.5/linux/include/asm-sparc/audioio.h linux/include/asm-sparc/audioio.h
--- v2.4.5/linux/include/asm-sparc/audioio.h	Tue Oct 10 10:33:52 2000
+++ linux/include/asm-sparc/audioio.h	Mon Jun 11 19:15:27 2001
@@ -428,9 +428,6 @@
 extern int unregister_sparcaudio_driver(struct sparcaudio_driver *, int);
 extern void sparcaudio_output_done(struct sparcaudio_driver *, int);
 extern void sparcaudio_input_done(struct sparcaudio_driver *, int);
-extern int amd7930_init(void);
-extern int cs4231_init(void);
-extern int dbri_init(void);
 
 #endif
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-sparc/hardirq.h linux/include/asm-sparc/hardirq.h
--- v2.4.5/linux/include/asm-sparc/hardirq.h	Mon Aug 28 21:20:03 2000
+++ linux/include/asm-sparc/hardirq.h	Tue Jun 12 11:08:46 2001
@@ -14,8 +14,8 @@
 
 /* entry.S is sensitive to the offsets of these fields */
 typedef struct {
-	unsigned int __softirq_active;
-	unsigned int __softirq_mask;
+	unsigned int __softirq_pending;
+	unsigned int __unused_1;
 #ifndef CONFIG_SMP
 	unsigned int __local_irq_count;
 #else
diff -u --recursive --new-file v2.4.5/linux/include/asm-sparc/linux_logo.h linux/include/asm-sparc/linux_logo.h
--- v2.4.5/linux/include/asm-sparc/linux_logo.h	Wed Sep 30 14:16:33 1998
+++ linux/include/asm-sparc/linux_logo.h	Tue Jun 12 11:08:46 2001
@@ -1,4 +1,4 @@
-/* $Id: linux_logo.h,v 1.6 1998/08/20 04:44:39 ecd Exp $
+/* $Id: linux_logo.h,v 1.7 2001/06/08 23:01:58 davem Exp $
  * include/asm-sparc/linux_logo.h: This is a linux logo
  *                                 to be displayed on boot.
  *
@@ -23,1025 +23,912 @@
 
 #define linux_logo_banner "Linux/SPARC version " UTS_RELEASE
 
-#define LINUX_LOGO_COLORS 219
+#define __HAVE_ARCH_LINUX_LOGO
+#define __HAVE_ARCH_LINUX_LOGO16
+
+#define LINUX_LOGO_COLORS	221
 
 #ifdef INCLUDE_LINUX_LOGO_DATA
 
 unsigned char linux_logo_red[] __initdata = {
-  0x03, 0x9E, 0xEC, 0xEE, 0xC4, 0xDA, 0x50, 0xC9,
-  0xC5, 0xED, 0x65, 0xE3, 0xE3, 0xF4, 0x24, 0xA4,
-  0xEC, 0xEE, 0x94, 0xE5, 0xE3, 0x6A, 0xA6, 0xC4,
-  0xDC, 0xE5, 0x13, 0xF3, 0xD1, 0xFD, 0xE2, 0xDB,
-  0xA0, 0xC2, 0xEC, 0xB8, 0xC2, 0xD5, 0xF2, 0xF4,
-  0xC5, 0x3E, 0xF1, 0x1B, 0x55, 0xF5, 0xCF, 0xF7,
-  0xA9, 0xB4, 0xEB, 0x6C, 0x0A, 0x74, 0xB4, 0xF7,
-  0xF0, 0xF5, 0xD4, 0xF2, 0xCE, 0xF5, 0xC7, 0x26,
-  0x5B, 0xF4, 0xBC, 0x7F, 0xAB, 0x82, 0x94, 0xE5,
-  0xFC, 0x3A, 0xF2, 0xFD, 0xF0, 0x1C, 0xEF, 0xD4,
-  0xF3, 0x0F, 0xED, 0xF7, 0xC9, 0x49, 0xC3, 0xBA,
-  0xC8, 0xD4, 0xE7, 0xF3, 0xF5, 0xA7, 0xEC, 0xF9,
-  0xFA, 0x0A, 0xF5, 0xCF, 0xFC, 0xEA, 0xE1, 0xA6,
-  0xD6, 0xBC, 0xF8, 0xF7, 0xB4, 0xEB, 0xDC, 0x84,
-  0xCE, 0xBA, 0x45, 0xD6, 0x86, 0x50, 0x96, 0xC6,
-  0x8C, 0x6E, 0xE8, 0x60, 0x3C, 0x70, 0xF0, 0x93,
-  0x7C, 0xDA, 0xDA, 0x9C, 0xBA, 0x6D, 0x4D, 0x2B,
-  0x2F, 0x8B, 0xE0, 0xCC, 0xDA, 0x5C, 0x3D, 0xEE,
-  0xDB, 0x46, 0xAC, 0x96, 0xCE, 0xD1, 0xE3, 0xF1,
-  0x96, 0x7A, 0x80, 0xB2, 0xBA, 0xB6, 0xD2, 0x1E,
-  0x7E, 0xAA, 0xC4, 0xF0, 0x96, 0x65, 0x9E, 0xC2,
-  0xAA, 0xF5, 0xF2, 0xE9, 0xE6, 0xD1, 0x35, 0xC7,
-  0xF6, 0xB6, 0xE8, 0x82, 0xBE, 0xC2, 0xF2, 0x9E,
-  0xC7, 0xB4, 0x0F, 0xF7, 0xE8, 0xD8, 0xCC, 0x9C,
-  0xD8, 0xD8, 0xA0, 0xEA, 0xC6, 0xA8, 0xE0, 0xEC,
-  0xD1, 0xF7, 0xF4, 0xFC, 0x75, 0xBD, 0xDC, 0xDD,
-  0xCC, 0xE1, 0xFA, 0xEE, 0xAA, 0xEC, 0xF2, 0xB8,
-  0xE2, 0xCD, 0x87
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
+    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
+    0xc3, 0x65, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
+    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
+    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x76, 0x79,
+    0x62, 0x36, 0x9a, 0xe2, 0xec, 0xe1, 0xb8, 0xd7,
+    0xaf, 0x25, 0xbc, 0xc0, 0xef, 0xea, 0xe8, 0xe8,
+    0xf5, 0xf1, 0xda, 0xd3, 0x79, 0xdb, 0xf4, 0xf6,
+    0xf6, 0xf6, 0xe2, 0x3d, 0xb4, 0xce, 0xe6, 0xee,
+    0xf6, 0x68, 0xd8, 0xec, 0xf5, 0xc6, 0xc8, 0x9c,
+    0x89, 0xd2, 0xee, 0xcb, 0xb9, 0xd2, 0x66, 0x5e,
+    0x8b, 0xbe, 0xa8, 0xd5, 0xca, 0xb6, 0xae, 0x9c,
+    0xc5, 0xbe, 0xbe, 0xca, 0x90, 0xb2, 0x9a, 0xa8,
+    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0xfe,
+    0xf6, 0xec, 0xfe, 0xd2, 0xea, 0xf5, 0xf2, 0xf2,
+    0xe9, 0xee, 0xf6, 0xf2, 0xee, 0xf6, 0xda, 0xd4,
+    0xfa, 0xca, 0xf2, 0xf6, 0xfe, 0xf2, 0xda, 0xe4,
+    0xf6, 0xdd, 0xf2, 0xee, 0xfa, 0xf0, 0x12, 0x4a,
+    0xd6, 0xf2, 0x8e, 0xf2, 0xf6, 0xf6, 0xb5, 0xf1,
+    0x26, 0x9a, 0xea, 0xf6, 0xe0, 0xd2, 0x16, 0x9a,
+    0x2e, 0xd2, 0x70, 0xd6, 0x46, 0x7c, 0xb4, 0x62,
+    0xda, 0xee, 0xd6, 0xa3, 0x74, 0xa7, 0xa2, 0xe0,
+    0xae, 0xbe, 0xce, 0xe2, 0xa3, 0x8e, 0x6d, 0x8e,
+    0x32, 0xaf, 0x50, 0x9e, 0x5b, 0x8a, 0x98, 0x82,
+    0x7a, 0x82, 0x56, 0x7c, 0x8a, 0x56, 0x5e, 0x86,
+    0x6a, 0x52, 0x59, 0x64, 0x5e,
 };
 
 unsigned char linux_logo_green[] __initdata = {
-  0x03, 0x88, 0xC4, 0xE2, 0x85, 0xC2, 0x44, 0xA3,
-  0xA9, 0xD3, 0x65, 0xA6, 0xC5, 0xF3, 0x24, 0xA4,
-  0xB4, 0xD6, 0x63, 0xD5, 0xB7, 0x44, 0x86, 0x94,
-  0xC2, 0xE4, 0x14, 0xB6, 0xD2, 0xFB, 0xD4, 0xB2,
-  0x73, 0x96, 0xDB, 0x92, 0xC2, 0x95, 0xC2, 0xDA,
-  0xA4, 0x36, 0xD4, 0x0E, 0x55, 0xF4, 0xC4, 0xE9,
-  0x75, 0xB4, 0xBC, 0x52, 0x0A, 0x74, 0x84, 0xEB,
-  0xDC, 0xDA, 0xA2, 0xD6, 0x9B, 0xBD, 0xB7, 0x12,
-  0x44, 0xCA, 0x8C, 0x65, 0x7B, 0x54, 0x94, 0xAB,
-  0xF4, 0x25, 0xC4, 0xFD, 0xE4, 0x1C, 0xDD, 0xAB,
-  0xBD, 0x06, 0xCB, 0xD6, 0xCA, 0x33, 0x8C, 0xA2,
-  0x92, 0x9C, 0xBC, 0xDB, 0xCD, 0x6E, 0xEC, 0xEE,
-  0xBC, 0x03, 0xDA, 0xCE, 0xF4, 0xB6, 0xDB, 0x92,
-  0xAD, 0xBC, 0xDE, 0xD5, 0x7B, 0xAE, 0x9D, 0x84,
-  0xB6, 0x96, 0x44, 0xBA, 0x6E, 0x3C, 0x7A, 0xB2,
-  0x8C, 0x4C, 0xCE, 0x4C, 0x3C, 0x5A, 0xCA, 0x6D,
-  0x7C, 0xCE, 0xDA, 0x9C, 0xAA, 0x6D, 0x4D, 0x2B,
-  0x1B, 0x5E, 0xCB, 0xAC, 0xBE, 0x5C, 0x2E, 0xDC,
-  0xBD, 0x3E, 0xAC, 0x82, 0xB6, 0xBE, 0xD3, 0xBD,
-  0x72, 0x62, 0x6C, 0x82, 0x92, 0x9E, 0xB0, 0x13,
-  0x4A, 0x8E, 0xBE, 0xCE, 0x86, 0x45, 0x6B, 0xAA,
-  0x9A, 0xC5, 0xC6, 0xDA, 0xC5, 0xC4, 0x34, 0x9B,
-  0xCC, 0xAC, 0xC4, 0x76, 0x9A, 0x9E, 0xEE, 0x62,
-  0xC6, 0x76, 0x0D, 0xE4, 0xDA, 0xD5, 0xA5, 0x92,
-  0xCD, 0xB2, 0x7C, 0xCC, 0xBE, 0x7E, 0xDC, 0xD6,
-  0xB9, 0xE3, 0xD4, 0xF6, 0x55, 0x82, 0xA4, 0xAA,
-  0x8D, 0xBB, 0xCE, 0xD5, 0x8A, 0xDB, 0xD4, 0x8B,
-  0xCA, 0x93, 0x63
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
+    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
+    0xc3, 0x62, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
+    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
+    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x62, 0x5c,
+    0x4e, 0x26, 0x72, 0xaa, 0xba, 0xaf, 0x90, 0xae,
+    0x92, 0x1a, 0xa4, 0x85, 0xb6, 0xbe, 0xc3, 0xc8,
+    0xcf, 0xd0, 0xc2, 0xce, 0x57, 0xa2, 0xd6, 0xda,
+    0xda, 0xd7, 0xb8, 0x2a, 0x7b, 0x91, 0xae, 0xca,
+    0xda, 0x45, 0x9e, 0xb2, 0xd7, 0x9b, 0x90, 0x76,
+    0x5c, 0xa2, 0xbe, 0xa6, 0x85, 0x96, 0x4e, 0x46,
+    0x66, 0x92, 0x7a, 0x9a, 0x96, 0x9d, 0x9a, 0x6b,
+    0x8a, 0x8e, 0xb2, 0xca, 0x90, 0xa6, 0x79, 0x7c,
+    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0xfa,
+    0xea, 0xd7, 0xf6, 0xbc, 0xda, 0xde, 0xda, 0xe6,
+    0xca, 0xd8, 0xea, 0xe0, 0xcc, 0xf2, 0xce, 0xb2,
+    0xee, 0xa2, 0xd6, 0xe6, 0xf6, 0xd7, 0xc5, 0xb8,
+    0xc6, 0xb9, 0xce, 0xde, 0xce, 0xc6, 0x0e, 0x36,
+    0xae, 0xbe, 0x86, 0xba, 0xbe, 0xe6, 0x8e, 0xc4,
+    0x1e, 0x8e, 0xae, 0xba, 0xb2, 0xa6, 0x12, 0x7a,
+    0x20, 0xc6, 0x64, 0xaa, 0x2f, 0x70, 0x85, 0x46,
+    0xce, 0xd6, 0xa6, 0x6e, 0x51, 0x72, 0x92, 0xa6,
+    0x87, 0x96, 0xa2, 0xd6, 0x85, 0x7a, 0x6a, 0x6e,
+    0x22, 0x76, 0x36, 0x76, 0x3c, 0x6e, 0x63, 0x53,
+    0x66, 0x62, 0x42, 0x50, 0x56, 0x42, 0x56, 0x56,
+    0x56, 0x3e, 0x51, 0x52, 0x56,
 };
 
 unsigned char linux_logo_blue[] __initdata = {
-  0x04, 0x28, 0x10, 0x8C, 0x0B, 0x84, 0x14, 0x1A,
-  0x77, 0x1F, 0x64, 0x0E, 0x85, 0xD2, 0x24, 0xA4,
-  0x0F, 0x54, 0x0C, 0x7C, 0x3F, 0x04, 0x20, 0x0D,
-  0x54, 0xDF, 0x14, 0x0D, 0xD1, 0xE9, 0xB0, 0x11,
-  0x0A, 0x40, 0x57, 0x14, 0xC3, 0x0C, 0x04, 0x12,
-  0x50, 0x0C, 0x7D, 0x05, 0x55, 0xF2, 0xBA, 0xC7,
-  0x09, 0xB4, 0x0E, 0x24, 0x0B, 0x74, 0x0C, 0xB6,
-  0x80, 0x48, 0x10, 0x34, 0x0F, 0x0C, 0xA0, 0x04,
-  0x19, 0x10, 0x0E, 0x14, 0x0E, 0x05, 0x94, 0x0E,
-  0xCA, 0x0B, 0x46, 0xFB, 0xB4, 0x1C, 0x9B, 0x1A,
-  0x21, 0x09, 0x14, 0x4D, 0xCB, 0x08, 0x11, 0x7C,
-  0x20, 0x10, 0x24, 0x66, 0x79, 0x07, 0xEA, 0xC9,
-  0x0C, 0x08, 0x38, 0xC4, 0xD8, 0x24, 0xBE, 0x6C,
-  0x51, 0xBB, 0x8C, 0x36, 0x0A, 0x0F, 0x0C, 0x84,
-  0x3C, 0x54, 0x44, 0x7C, 0x28, 0x0E, 0x28, 0x7F,
-  0x8C, 0x0F, 0x54, 0x24, 0x3C, 0x18, 0x54, 0x17,
-  0x7C, 0x9C, 0xDA, 0x9C, 0x7C, 0x6C, 0x4D, 0x2C,
-  0x09, 0x0E, 0x8A, 0x50, 0x4C, 0x5B, 0x14, 0xAC,
-  0x19, 0x3C, 0xAC, 0x5C, 0x64, 0x97, 0x94, 0x37,
-  0x29, 0x3C, 0x44, 0x3C, 0x2C, 0x7C, 0x70, 0x07,
-  0x04, 0x29, 0xB2, 0x64, 0x74, 0x07, 0x07, 0x2C,
-  0x74, 0x2E, 0x6C, 0xA4, 0x29, 0x9E, 0x34, 0x27,
-  0x2F, 0x98, 0x48, 0x5C, 0x0C, 0x5C, 0xE8, 0x04,
-  0xC2, 0x0C, 0x0A, 0xB2, 0x74, 0xCB, 0x46, 0x78,
-  0xB4, 0x5C, 0x18, 0x80, 0x8C, 0x24, 0xD9, 0xAC,
-  0x87, 0x99, 0x1D, 0xE8, 0x14, 0x0D, 0x10, 0x17,
-  0x0A, 0x67, 0x3C, 0x68, 0x3C, 0x69, 0x90, 0x22,
-  0x6C, 0x0D, 0x17
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x01, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x06, 0x65,
+    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
+    0xc3, 0x59, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
+    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
+    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x2e, 0x08,
+    0x0a, 0x06, 0x0a, 0x0b, 0x0b, 0x0f, 0x0c, 0x0f,
+    0x3d, 0x09, 0x73, 0x09, 0x0d, 0x0a, 0x10, 0x1e,
+    0x2d, 0x13, 0x86, 0xba, 0x19, 0x0a, 0x36, 0x3c,
+    0x26, 0x14, 0x0d, 0x06, 0x07, 0x0a, 0x0b, 0x0f,
+    0x4a, 0x06, 0x0a, 0x0c, 0x2b, 0x0a, 0x0b, 0x0a,
+    0x06, 0x0a, 0x0a, 0x11, 0x0b, 0x0a, 0x0a, 0x1e,
+    0x0f, 0x0d, 0x0a, 0x0b, 0x22, 0x6a, 0x72, 0x0b,
+    0x0b, 0x22, 0x90, 0xca, 0x90, 0x92, 0x3c, 0x2c,
+    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0xea,
+    0xb6, 0x7c, 0xda, 0x8e, 0xa6, 0x87, 0x66, 0xb6,
+    0x81, 0x6a, 0xc6, 0x9a, 0x5b, 0xd2, 0xb6, 0x6a,
+    0xca, 0x45, 0x92, 0xb2, 0xca, 0x52, 0x8a, 0x3e,
+    0x2e, 0x66, 0x66, 0xae, 0x3e, 0x47, 0x06, 0x0e,
+    0x52, 0x36, 0x6a, 0x0e, 0x0e, 0xbe, 0x2c, 0x0e,
+    0x0a, 0x5a, 0x0d, 0x0e, 0x3e, 0x0a, 0x06, 0x2e,
+    0x06, 0x9e, 0x4e, 0x36, 0x06, 0x58, 0x24, 0x06,
+    0x9e, 0xae, 0x3a, 0x08, 0x08, 0x07, 0x5e, 0x0a,
+    0x32, 0x2e, 0x2a, 0xb2, 0x43, 0x48, 0x5f, 0x2e,
+    0x06, 0x06, 0x07, 0x24, 0x06, 0x32, 0x06, 0x06,
+    0x46, 0x2e, 0x22, 0x06, 0x06, 0x1e, 0x4c, 0x06,
+    0x3a, 0x22, 0x42, 0x34, 0x42,
 };
 
 unsigned char linux_logo[] __initdata = {
-  0xD8, 0xA3, 0x98, 0x98, 0xA3, 0xB2, 0x2F, 0x2F,
-  0xA3, 0x66, 0x98, 0x98, 0x98, 0xA3, 0x2F, 0xA3,
-  0x98, 0x55, 0xA0, 0xA3, 0xB2, 0x51, 0x51, 0x2F,
-  0x98, 0x55, 0x8F, 0x2F, 0x89, 0x44, 0x89, 0x51,
-  0xB2, 0x2F, 0x66, 0xA3, 0x2F, 0x2F, 0x66, 0x66,
-  0xA3, 0xB2, 0xB2, 0xB2, 0x89, 0xD8, 0x44, 0x44,
-  0xD8, 0x83, 0xD8, 0xA3, 0x98, 0x98, 0xA3, 0xB2,
-  0x2F, 0x2F, 0xA3, 0x66, 0x98, 0x98, 0x98, 0xA3,
-  0x2F, 0xA3, 0x98, 0x55, 0xA0, 0xA3, 0xB2, 0x51,
-  0x51, 0x2F, 0x98, 0x55, 0x8F, 0x2F, 0x89, 0x44,
-  0xA3, 0x55, 0x55, 0x98, 0x2F, 0x2F, 0x2F, 0xA3,
-  0x66, 0x66, 0x98, 0x98, 0x66, 0x66, 0x66, 0x98,
-  0x55, 0xA5, 0x8F, 0xA3, 0x51, 0x51, 0xB2, 0x2F,
-  0x66, 0x66, 0xA3, 0x51, 0x89, 0x51, 0xB2, 0x2F,
-  0x2F, 0xA3, 0x66, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F,
-  0xB2, 0xB2, 0x2F, 0x2F, 0xB2, 0x51, 0x51, 0x51,
-  0x51, 0x51, 0xA3, 0x55, 0x55, 0x98, 0x2F, 0x2F,
-  0x2F, 0xA3, 0x66, 0x66, 0x98, 0x98, 0x66, 0x66,
-  0x66, 0x98, 0x55, 0xA5, 0x8F, 0xA3, 0x51, 0x51,
-  0xB2, 0x2F, 0x66, 0x66, 0xA3, 0x51, 0x89, 0x51,
-  0x98, 0xA5, 0x55, 0x8F, 0x2F, 0xB2, 0x2F, 0xA3,
-  0x66, 0x66, 0x98, 0x8F, 0x66, 0x66, 0x66, 0x98,
-  0xA0, 0x8F, 0xA3, 0xB2, 0x51, 0x51, 0xB2, 0x2F,
-  0xA3, 0xA3, 0x2F, 0xB2, 0x51, 0xB2, 0x2F, 0x2F,
-  0xA3, 0x66, 0x98, 0xA3, 0x51, 0xB2, 0x2F, 0xA3,
-  0xB2, 0x51, 0x51, 0xB2, 0xB2, 0x51, 0xB2, 0xB2,
-  0xB2, 0x2F, 0x98, 0xA5, 0x55, 0x8F, 0x2F, 0xB2,
-  0x2F, 0xA3, 0x66, 0x66, 0x98, 0x8F, 0x66, 0x66,
-  0x66, 0x98, 0xA0, 0x8F, 0xA3, 0xB2, 0x51, 0x51,
-  0xB2, 0x2F, 0xA3, 0xA3, 0x2F, 0x51, 0x51, 0xB2,
-  0xA0, 0xA5, 0x55, 0x66, 0xB2, 0x51, 0xB2, 0xA3,
-  0x66, 0x66, 0x98, 0x66, 0x66, 0x66, 0x98, 0x98,
-  0x66, 0xA3, 0x2F, 0xB2, 0x51, 0x51, 0xB2, 0xA3,
-  0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0xA3,
-  0x66, 0x98, 0xB2, 0x4C, 0x54, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xCE, 0x2F, 0xB2, 0x2F, 0x2F,
-  0xA3, 0x98, 0xA0, 0xA5, 0x55, 0x66, 0xB2, 0x51,
-  0xB2, 0xA3, 0x66, 0x66, 0x98, 0x66, 0x66, 0x66,
-  0x98, 0x98, 0x66, 0xA3, 0x2F, 0xB2, 0x51, 0x51,
-  0xB2, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F,
-  0xA0, 0xA0, 0x8F, 0xA3, 0xB2, 0x51, 0xB2, 0x2F,
-  0x66, 0x66, 0x98, 0x66, 0x66, 0x66, 0x66, 0x66,
-  0xA3, 0x2F, 0x51, 0x51, 0x51, 0xB2, 0x2F, 0xA3,
-  0x66, 0x66, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3,
-  0x2F, 0xA0, 0xDA, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x9C, 0xB2, 0xA3,
-  0x66, 0x98, 0xA0, 0xA0, 0x8F, 0xA3, 0xB2, 0x51,
-  0xB2, 0x2F, 0x66, 0x66, 0x98, 0x66, 0x66, 0x66,
-  0x66, 0x66, 0xA3, 0x2F, 0x51, 0x51, 0x51, 0xB2,
-  0x2F, 0xA3, 0x66, 0x66, 0x66, 0xA3, 0xA3, 0xA3,
-  0x8F, 0x8F, 0x66, 0x2F, 0x51, 0x51, 0xB2, 0xA3,
-  0x66, 0x98, 0x98, 0x66, 0x66, 0x66, 0x2F, 0x2F,
-  0xB2, 0x51, 0xB2, 0xB2, 0x2F, 0x2F, 0xA3, 0x66,
-  0x66, 0x66, 0xA3, 0xA3, 0x2F, 0xA3, 0xA3, 0xB2,
-  0x9C, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xDA, 0x3A, 0x20, 0x54, 0x55,
-  0xA3, 0x98, 0x8F, 0x8F, 0x66, 0x2F, 0x51, 0x51,
-  0xB2, 0xA3, 0x66, 0x98, 0x98, 0x66, 0x66, 0x66,
-  0x2F, 0x2F, 0xB2, 0x51, 0xB2, 0xB2, 0x2F, 0x2F,
-  0xA3, 0x66, 0x66, 0x66, 0x2F, 0xA3, 0x2F, 0x2F,
-  0x66, 0x66, 0xA3, 0x2F, 0xB2, 0xB2, 0x2F, 0x66,
-  0x8F, 0x8F, 0x8F, 0x66, 0xA3, 0xA3, 0xB2, 0xB2,
-  0xB2, 0xB2, 0xB2, 0xB2, 0x2F, 0xA3, 0xA3, 0xA3,
-  0xA3, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0xAD,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xA7, 0x4C, 0xCE, 0xDA, 0x20,
-  0xA6, 0x2F, 0x66, 0x66, 0xA3, 0x2F, 0xB2, 0xB2,
-  0x2F, 0x66, 0x8F, 0x8F, 0x8F, 0x66, 0xA3, 0xA3,
-  0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0x2F, 0xA3,
-  0xA3, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F,
-  0xA3, 0x98, 0x66, 0x2F, 0xB2, 0xB2, 0x2F, 0x98,
-  0x8F, 0x8F, 0x98, 0x66, 0xA3, 0xB2, 0xB2, 0xB2,
-  0x2F, 0x2F, 0x2F, 0x2F, 0xA3, 0x2F, 0xA3, 0xA3,
-  0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0x51, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xCE, 0x55, 0xAD, 0xA7, 0x54,
-  0x20, 0x8F, 0xA3, 0x98, 0x66, 0x2F, 0xB2, 0xB2,
-  0x2F, 0x98, 0x8F, 0x8F, 0x98, 0x66, 0xA3, 0xB2,
-  0xB2, 0xB2, 0x2F, 0x2F, 0x2F, 0x2F, 0xA3, 0x2F,
-  0xA3, 0xA3, 0xA3, 0x2F, 0xA3, 0xA3, 0xA3, 0xA3,
-  0xA3, 0x8F, 0x66, 0x2F, 0xB2, 0x51, 0x2F, 0x98,
-  0xA0, 0x8F, 0x66, 0xA3, 0x2F, 0x51, 0x51, 0xB2,
-  0xA3, 0xA3, 0xA3, 0x2F, 0xA3, 0xA3, 0x66, 0x66,
-  0x98, 0x98, 0x98, 0x66, 0x98, 0x66, 0x55, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xCE, 0x4C, 0x9C, 0x2E, 0xDA,
-  0x20, 0xDA, 0x51, 0x8F, 0x66, 0x2F, 0xB2, 0x51,
-  0x2F, 0x98, 0xA0, 0x8F, 0x66, 0xA3, 0x2F, 0x51,
-  0x51, 0xB2, 0xA3, 0xA3, 0xA3, 0x2F, 0xA3, 0xA3,
-  0x66, 0x66, 0x98, 0x98, 0x98, 0x98, 0x98, 0x66,
-  0x51, 0x66, 0x2F, 0xB2, 0x51, 0xB2, 0xA3, 0xA0,
-  0xA0, 0x66, 0xA3, 0xB2, 0xB2, 0xB2, 0xB2, 0xA3,
-  0x66, 0x66, 0x66, 0xA3, 0xA3, 0x66, 0x98, 0x98,
-  0x98, 0x98, 0x98, 0x66, 0x66, 0xB2, 0x6D, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x6D, 0x3A, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0xA5, 0x66, 0x2F, 0xB2, 0x51, 0xB2,
-  0xA3, 0xA0, 0xA0, 0x66, 0xA3, 0xB2, 0xB2, 0xB2,
-  0xB2, 0xA3, 0x66, 0x66, 0x66, 0xA3, 0xA3, 0x66,
-  0x98, 0x98, 0x8F, 0x98, 0x66, 0x66, 0x66, 0x66,
-  0x51, 0x2F, 0xB2, 0x51, 0x51, 0x2F, 0x66, 0xA0,
-  0x8F, 0xA3, 0x2F, 0xB2, 0xB2, 0x2F, 0x2F, 0x66,
-  0x98, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
-  0x66, 0x2F, 0xA3, 0x2F, 0x2F, 0x51, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0xDA, 0x51, 0xB2, 0x51, 0x51, 0x2F,
-  0x66, 0xA0, 0x8F, 0xA3, 0x2F, 0xB2, 0xB2, 0x2F,
-  0x2F, 0x66, 0x98, 0x66, 0x66, 0x66, 0x66, 0x66,
-  0x66, 0x66, 0x66, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F,
-  0x51, 0x2F, 0xB2, 0x51, 0x2F, 0xA3, 0x8F, 0x8F,
-  0x98, 0xA3, 0xB2, 0xB2, 0x2F, 0xA3, 0x98, 0x66,
-  0x98, 0x98, 0x66, 0x66, 0x66, 0x66, 0xA3, 0x2F,
-  0xB2, 0xB2, 0x51, 0xB2, 0xB2, 0x66, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xA3, 0xB2, 0x51, 0x2F, 0xA3,
-  0x8F, 0x8F, 0x98, 0xA3, 0xB2, 0xB2, 0x2F, 0xA3,
-  0x98, 0x66, 0x98, 0x98, 0x66, 0x66, 0x66, 0x66,
-  0xA3, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2,
-  0xB2, 0x2F, 0xA3, 0x2F, 0x66, 0x98, 0x8F, 0x98,
-  0xA3, 0x2F, 0x2F, 0xA3, 0x98, 0x98, 0x98, 0x98,
-  0x66, 0x98, 0x66, 0x98, 0x66, 0xA3, 0x2F, 0xB2,
-  0x51, 0x51, 0x51, 0xB2, 0xB2, 0x8F, 0x20, 0x20,
-  0x20, 0x54, 0x6D, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x54, 0x6D, 0x6D, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x4C, 0xA3, 0x2F, 0x66, 0x98,
-  0x8F, 0x98, 0xA3, 0x2F, 0x2F, 0xA3, 0x98, 0x98,
-  0x98, 0x98, 0x66, 0x98, 0x66, 0x98, 0x66, 0xA3,
-  0x2F, 0xB2, 0x51, 0x51, 0x51, 0xB2, 0x2F, 0x2F,
-  0x2F, 0xA3, 0xA3, 0x66, 0x98, 0x98, 0x8F, 0x98,
-  0x2F, 0x2F, 0x2F, 0x66, 0x8F, 0x8F, 0x98, 0xA3,
-  0x66, 0x66, 0x8F, 0x98, 0x98, 0x66, 0x2F, 0xB2,
-  0x51, 0xB2, 0x2F, 0xA3, 0xA3, 0xA0, 0x20, 0x20,
-  0xDA, 0x2E, 0x3A, 0xA7, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0xCE, 0x2A, 0x2A, 0x2E, 0xA7, 0xDA, 0x20,
-  0x20, 0x20, 0x20, 0x9C, 0xA3, 0x66, 0x98, 0x98,
-  0x8F, 0x98, 0x2F, 0x2F, 0x2F, 0x66, 0x8F, 0x8F,
-  0x98, 0xA3, 0x66, 0x66, 0x8F, 0x98, 0x98, 0x66,
-  0x2F, 0xB2, 0x51, 0xB2, 0x2F, 0x2F, 0xA3, 0xA3,
-  0xB2, 0xA3, 0x66, 0x98, 0x8F, 0x8F, 0x66, 0xA3,
-  0x2F, 0x2F, 0x66, 0x98, 0x98, 0x66, 0x2F, 0x2F,
-  0xA3, 0x98, 0x8F, 0x98, 0x66, 0x2F, 0xB2, 0xB2,
-  0xB2, 0xA3, 0x66, 0x66, 0x66, 0x98, 0x20, 0x3A,
-  0x98, 0x89, 0x8F, 0x6D, 0x20, 0x20, 0x20, 0x20,
-  0x4C, 0x66, 0x51, 0x44, 0x51, 0x2E, 0x54, 0x20,
-  0x20, 0x20, 0x20, 0xA7, 0x66, 0x98, 0x8F, 0x8F,
-  0x66, 0xA3, 0x2F, 0x2F, 0x66, 0x98, 0x98, 0x66,
-  0x2F, 0x2F, 0xA3, 0x98, 0x8F, 0x98, 0x66, 0x2F,
-  0xB2, 0xB2, 0xB2, 0xA3, 0x66, 0x66, 0x66, 0xA3,
-  0x2F, 0x66, 0x98, 0x8F, 0x8F, 0x98, 0x66, 0x2F,
-  0x2F, 0xA3, 0x66, 0x98, 0x98, 0xA3, 0x2F, 0xB2,
-  0xA3, 0x8F, 0x98, 0xA3, 0xB2, 0x51, 0x89, 0x89,
-  0xB2, 0xA3, 0x66, 0x98, 0x66, 0x98, 0x20, 0xA6,
-  0x44, 0x39, 0xE6, 0x98, 0x20, 0x20, 0x20, 0x9C,
-  0x74, 0xD6, 0x7E, 0xD6, 0x39, 0x8F, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x2E, 0x98, 0x8F, 0x8F, 0x98,
-  0x66, 0x2F, 0x2F, 0xA3, 0x66, 0x98, 0x98, 0xA3,
-  0x2F, 0xB2, 0x66, 0x98, 0x8F, 0xA3, 0xB2, 0x51,
-  0x89, 0x89, 0xB2, 0xA3, 0x66, 0x98, 0x66, 0x66,
-  0x2F, 0x66, 0x8F, 0xA0, 0x8F, 0x98, 0xA3, 0xB2,
-  0x2F, 0x66, 0x66, 0x66, 0xA3, 0x2F, 0x2F, 0x2F,
-  0x66, 0x98, 0xA3, 0xB2, 0x89, 0x44, 0x89, 0x51,
-  0x2F, 0x66, 0x98, 0x98, 0xA3, 0x66, 0x20, 0x2F,
-  0x2F, 0xAD, 0x89, 0xD6, 0x3A, 0x20, 0x20, 0x55,
-  0x6B, 0x51, 0x6D, 0x4C, 0xD8, 0xD6, 0x2E, 0x20,
-  0x20, 0x20, 0x20, 0x54, 0x8F, 0xA0, 0x8F, 0x98,
-  0xA3, 0xB2, 0x2F, 0x66, 0x66, 0x66, 0xA3, 0x2F,
-  0xB2, 0x2F, 0x66, 0x66, 0xA3, 0xB2, 0x89, 0x44,
-  0x89, 0x51, 0x2F, 0x66, 0x98, 0x98, 0xA3, 0xA3,
-  0xA3, 0x66, 0x8F, 0xA0, 0x8F, 0x66, 0x2F, 0xB2,
-  0xA3, 0x66, 0x98, 0x66, 0xA3, 0x2F, 0x2F, 0xA3,
-  0xA3, 0x2F, 0xB2, 0x89, 0xD8, 0xD8, 0x51, 0x66,
-  0x8F, 0xA0, 0xA0, 0x8F, 0x98, 0xA3, 0x20, 0x44,
-  0xA7, 0xCE, 0xA6, 0x4D, 0xCE, 0x6D, 0xA7, 0xA0,
-  0x6B, 0xA7, 0x20, 0x92, 0xAD, 0x6B, 0x4C, 0x20,
-  0x20, 0x20, 0x20, 0x54, 0x98, 0xA0, 0x8F, 0x66,
-  0x2F, 0xB2, 0xA3, 0x66, 0x98, 0x66, 0xA3, 0x2F,
-  0x2F, 0xA3, 0xA3, 0xA3, 0xB2, 0x89, 0xD8, 0xD8,
-  0x51, 0x66, 0x8F, 0xA0, 0xA0, 0x8F, 0x98, 0x66,
-  0x66, 0x66, 0x8F, 0x55, 0x8F, 0xA3, 0xB2, 0xB2,
-  0xA3, 0x66, 0x66, 0xA3, 0x2F, 0xA3, 0xA3, 0xA3,
-  0xA3, 0xB2, 0x89, 0x44, 0x44, 0x51, 0x66, 0xA0,
-  0x55, 0xA5, 0x55, 0x8F, 0x66, 0xA3, 0x20, 0x44,
-  0x6D, 0x54, 0xA7, 0x74, 0x2E, 0x4B, 0xBF, 0x9C,
-  0x7E, 0xDA, 0x20, 0x54, 0x2E, 0x6B, 0x2A, 0x20,
-  0x20, 0x20, 0x20, 0x3A, 0x8F, 0x55, 0x8F, 0xA3,
-  0xB2, 0xB2, 0xA3, 0x66, 0x66, 0xA3, 0xA3, 0x2F,
-  0xA3, 0xA3, 0xA3, 0xB2, 0x89, 0x44, 0x44, 0x51,
-  0x66, 0xA0, 0xA5, 0xA5, 0x55, 0x8F, 0x66, 0x66,
-  0xA0, 0xA0, 0xA0, 0xA0, 0x8F, 0xA3, 0x2F, 0xB2,
-  0x66, 0x98, 0xA3, 0x2F, 0x2F, 0xB2, 0x2F, 0x2F,
-  0xB2, 0x51, 0x89, 0x89, 0xB2, 0x98, 0xA0, 0x2A,
-  0xA5, 0x55, 0x98, 0x66, 0xA3, 0xB2, 0x20, 0x2F,
-  0x4C, 0x20, 0x4B, 0xBB, 0xCF, 0x6F, 0x27, 0x36,
-  0x93, 0xCE, 0x20, 0x20, 0xA6, 0x3D, 0x4C, 0x20,
-  0x20, 0x20, 0x20, 0xDA, 0xA0, 0xA0, 0x8F, 0xA3,
-  0x2F, 0xB2, 0x66, 0x98, 0xA3, 0x2F, 0xB2, 0x2F,
-  0x2F, 0x2F, 0xB2, 0x51, 0x89, 0x89, 0xB2, 0x98,
-  0xA0, 0x2A, 0xA5, 0xA0, 0x8F, 0x66, 0xA3, 0xA3,
-  0xA0, 0x8F, 0x8F, 0xA0, 0x8F, 0xA3, 0xB2, 0x2F,
-  0x66, 0x98, 0x2F, 0xB2, 0xB2, 0xB2, 0xB2, 0x2F,
-  0xB2, 0x89, 0x44, 0x51, 0x66, 0x55, 0xAD, 0x2A,
-  0x55, 0x8F, 0x66, 0xA3, 0x2F, 0xB2, 0x20, 0x2A,
-  0xE6, 0x95, 0xE5, 0x5A, 0x52, 0x52, 0x3F, 0x27,
-  0x22, 0xC7, 0x9D, 0x60, 0xA2, 0xA2, 0x3A, 0x20,
-  0x20, 0x20, 0x20, 0x54, 0x66, 0xA0, 0x8F, 0xA3,
-  0xB2, 0x2F, 0x66, 0x98, 0x2F, 0xB2, 0xB2, 0xB2,
-  0xB2, 0x2F, 0xB2, 0x89, 0x44, 0x51, 0x66, 0x55,
-  0x2A, 0x2A, 0xA5, 0x8F, 0x66, 0xA3, 0x2F, 0x2F,
-  0xA3, 0xA3, 0x66, 0x98, 0x98, 0x2F, 0xB2, 0xB2,
-  0xA3, 0xA3, 0x2F, 0x51, 0x51, 0x51, 0x2F, 0x2F,
-  0x51, 0x89, 0x89, 0x2F, 0x8F, 0x2A, 0x2A, 0xA5,
-  0x8F, 0x66, 0xA3, 0xB2, 0x2F, 0x51, 0x20, 0x6D,
-  0x77, 0xF7, 0xEE, 0x30, 0xB0, 0x72, 0x72, 0x5B,
-  0x82, 0xEA, 0x72, 0xB0, 0x90, 0x96, 0x71, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x2F, 0x98, 0x98, 0x2F,
-  0xB2, 0xB2, 0x66, 0xA3, 0x2F, 0x51, 0x51, 0xB2,
-  0xB2, 0x2F, 0x51, 0x89, 0x89, 0x2F, 0x8F, 0x2A,
-  0xAD, 0xA5, 0x98, 0x66, 0xA3, 0xB2, 0x2F, 0xB2,
-  0xD8, 0xB2, 0xA3, 0x98, 0x98, 0x2F, 0xB2, 0xB2,
-  0x66, 0xA3, 0xB2, 0x51, 0x51, 0xB2, 0x2F, 0xA3,
-  0x51, 0x89, 0x89, 0xA3, 0xA0, 0x2A, 0xA5, 0x8F,
-  0x66, 0xA3, 0x2F, 0xB2, 0xB2, 0x51, 0x20, 0x69,
-  0x64, 0xF9, 0x3F, 0x52, 0x52, 0x72, 0x29, 0x82,
-  0x47, 0x47, 0x47, 0x8B, 0x72, 0xB7, 0x60, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x2F, 0x98, 0x98, 0x2F,
-  0xB2, 0xB2, 0xA3, 0xA3, 0xB2, 0x89, 0x51, 0x2F,
-  0x2F, 0xA3, 0x51, 0x89, 0x89, 0xA3, 0xA0, 0x2A,
-  0xA5, 0x8F, 0x66, 0xA3, 0x2F, 0xB2, 0xB2, 0xB2,
-  0xDD, 0xA3, 0x66, 0x98, 0x66, 0x2F, 0xB2, 0xB2,
-  0xA3, 0xA3, 0xB2, 0x51, 0xB2, 0x2F, 0xA3, 0x2F,
-  0xB2, 0x89, 0xB2, 0x66, 0xA0, 0xA5, 0x8F, 0x98,
-  0x66, 0x66, 0xB2, 0x51, 0x51, 0x51, 0x81, 0xFA,
-  0x62, 0xEE, 0x30, 0x52, 0x22, 0x72, 0x82, 0x82,
-  0x47, 0x47, 0xEA, 0x3F, 0x37, 0x6F, 0x26, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x2A, 0x98, 0x66, 0x2F,
-  0x51, 0xB2, 0xA3, 0x66, 0xB2, 0x51, 0x51, 0xB2,
-  0xA3, 0x2F, 0xB2, 0x89, 0xB2, 0x66, 0x55, 0x55,
-  0x8F, 0x98, 0x66, 0xA3, 0xB2, 0x51, 0x51, 0xB2,
-  0x74, 0xA0, 0x8F, 0x98, 0x66, 0xB2, 0xB2, 0xB2,
-  0xA3, 0xA3, 0x2F, 0x51, 0x51, 0x2F, 0xA3, 0x2F,
-  0xB2, 0x51, 0xA3, 0x98, 0xA0, 0x55, 0xA0, 0xA0,
-  0x8F, 0x66, 0x2F, 0x51, 0xB2, 0x51, 0x54, 0xA9,
-  0x62, 0xEF, 0x52, 0x22, 0x72, 0x29, 0xEA, 0xEA,
-  0x29, 0x22, 0x37, 0x37, 0x8E, 0xCF, 0x49, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x6D, 0x2F, 0x66, 0x2F,
-  0x51, 0xB2, 0xA3, 0x66, 0x2F, 0xB2, 0xB2, 0x2F,
-  0xA3, 0x2F, 0xB2, 0x51, 0x2F, 0x98, 0xA0, 0x55,
-  0xA0, 0xA0, 0x8F, 0x66, 0x2F, 0x51, 0xB2, 0xA3,
-  0xA3, 0x2A, 0xA5, 0x98, 0xA3, 0x2F, 0xB2, 0x2F,
-  0x66, 0x66, 0x2F, 0xB2, 0xB2, 0xB2, 0x2F, 0x2F,
-  0xB2, 0x2F, 0xA3, 0x8F, 0xA0, 0xA0, 0xA0, 0xA0,
-  0x8F, 0xA3, 0x51, 0x51, 0x2F, 0xB2, 0x54, 0xA8,
-  0x65, 0x5C, 0x52, 0x22, 0x29, 0x29, 0x29, 0xB0,
-  0x62, 0x56, 0xF9, 0x79, 0xF9, 0xBB, 0x4B, 0x20,
-  0x6D, 0xA5, 0x2E, 0x20, 0x20, 0xA3, 0xA3, 0x2F,
-  0xB2, 0x2F, 0xA3, 0x66, 0x2F, 0xB2, 0xB2, 0xB2,
-  0x2F, 0x2F, 0xB2, 0x2F, 0x66, 0x8F, 0xA0, 0xA0,
-  0x55, 0xA0, 0x8F, 0xA3, 0x51, 0x51, 0x2F, 0xA3,
-  0xA0, 0x2A, 0x55, 0x66, 0xA3, 0x2F, 0xB2, 0xB2,
-  0xA3, 0x66, 0xA3, 0xB2, 0xB2, 0xB2, 0xA3, 0x66,
-  0xA3, 0xA3, 0x66, 0x8F, 0x8F, 0x8F, 0xA0, 0x98,
-  0xA3, 0x51, 0x89, 0x89, 0xA3, 0x2F, 0x20, 0x54,
-  0xDF, 0xFA, 0x40, 0x37, 0xD4, 0x43, 0x56, 0x64,
-  0x76, 0xF9, 0x78, 0x41, 0x5E, 0x5E, 0x4C, 0x20,
-  0x20, 0xAD, 0x8F, 0x9C, 0x20, 0xA5, 0xA3, 0x2F,
-  0x2F, 0x2F, 0xA3, 0x66, 0x2F, 0xB2, 0xB2, 0xB2,
-  0xA3, 0x66, 0xA3, 0x2F, 0x66, 0x8F, 0x8F, 0x8F,
-  0x8F, 0x8F, 0xA3, 0x51, 0x89, 0x51, 0xA3, 0x66,
-  0xA0, 0xA0, 0x8F, 0xA3, 0x2F, 0x2F, 0x2F, 0xB2,
-  0x2F, 0xA3, 0x2F, 0xB2, 0x51, 0xB2, 0x2F, 0x66,
-  0xA3, 0xA3, 0x66, 0x66, 0x66, 0x66, 0x66, 0xA3,
-  0xB2, 0x89, 0xD8, 0x51, 0x66, 0x51, 0x20, 0x6D,
-  0x51, 0x77, 0x9F, 0xF7, 0xEE, 0x8E, 0xF9, 0xF0,
-  0x24, 0xF7, 0x77, 0x5E, 0x74, 0xD8, 0x98, 0x20,
-  0x20, 0x2E, 0x55, 0x92, 0x20, 0x54, 0x51, 0x2F,
-  0x2F, 0xB2, 0xB2, 0xA3, 0x2F, 0x51, 0x51, 0xB2,
-  0xA3, 0xA3, 0x66, 0xA3, 0x66, 0x66, 0x66, 0x66,
-  0x66, 0xA3, 0xB2, 0x89, 0xD8, 0x51, 0xA3, 0x98,
-  0x98, 0x66, 0x66, 0xA3, 0x2F, 0x2F, 0x2F, 0xB2,
-  0xB2, 0x2F, 0x2F, 0xB2, 0xB2, 0x2F, 0x2F, 0x66,
-  0x66, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0xB2,
-  0x89, 0xD8, 0x89, 0xB2, 0x66, 0x66, 0x20, 0x6D,
-  0x89, 0xC2, 0xA4, 0x96, 0xC6, 0x64, 0x50, 0x40,
-  0xF4, 0x97, 0x89, 0x74, 0x7E, 0x6B, 0x39, 0xA7,
-  0x20, 0x20, 0x3A, 0x54, 0x20, 0x20, 0xA7, 0x51,
-  0x2F, 0xB2, 0xB2, 0xA3, 0xA3, 0xB2, 0xB2, 0xB2,
-  0xA3, 0xA3, 0x66, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F,
-  0x2F, 0xB2, 0x89, 0xD8, 0x44, 0x2F, 0x66, 0x66,
-  0x2F, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F, 0xB2,
-  0x2F, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0xA3,
-  0x66, 0xA3, 0x2F, 0xB2, 0xB2, 0xB2, 0x51, 0x51,
-  0x89, 0x89, 0xB2, 0x66, 0x2F, 0x6D, 0x20, 0xCE,
-  0x39, 0x74, 0x89, 0x5E, 0xBD, 0x87, 0xC8, 0xD1,
-  0x89, 0x44, 0x3C, 0x4D, 0x6B, 0x6B, 0x6B, 0x2F,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xA3,
-  0x2F, 0x2F, 0x2F, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F,
-  0x2F, 0xA3, 0x66, 0x66, 0x2F, 0xB2, 0xB2, 0xB2,
-  0x51, 0x51, 0x89, 0x89, 0xB2, 0xA3, 0x98, 0x66,
-  0xA3, 0x66, 0x66, 0xA3, 0xA3, 0xA3, 0xA3, 0x2F,
-  0x2F, 0xA3, 0xA3, 0xA3, 0x2F, 0xA3, 0x2F, 0xA3,
-  0x66, 0x66, 0x2F, 0x2F, 0xB2, 0xB2, 0xB2, 0xB2,
-  0xB2, 0x2F, 0x66, 0x66, 0x2A, 0x20, 0x54, 0x44,
-  0x6B, 0x39, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-  0xD8, 0x39, 0x4D, 0x6B, 0x6B, 0x6B, 0x6B, 0x4D,
-  0x9C, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D,
-  0x51, 0x2F, 0x2F, 0x2F, 0xA3, 0xA3, 0xA3, 0x2F,
-  0xA3, 0xA3, 0x66, 0xA3, 0x2F, 0xB2, 0xB2, 0xB2,
-  0xB2, 0xB2, 0xB2, 0x2F, 0x66, 0x98, 0x98, 0x66,
-  0x98, 0x98, 0x66, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3,
-  0x2F, 0x2F, 0xA3, 0xA3, 0x66, 0xA3, 0xA3, 0x66,
-  0x98, 0x66, 0x66, 0x2F, 0xA3, 0xA3, 0xA3, 0xA3,
-  0x66, 0x98, 0x98, 0x98, 0x3A, 0x54, 0x2A, 0x6B,
-  0x6B, 0x6B, 0x83, 0x44, 0x89, 0x89, 0x44, 0x3C,
-  0xD6, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0xB2, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0xAD, 0x2F, 0x2F, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3,
-  0xA3, 0x66, 0x66, 0x98, 0x66, 0xA3, 0xA3, 0xA3,
-  0xA3, 0xA3, 0x66, 0x98, 0x8F, 0x8F, 0x8F, 0x98,
-  0x8F, 0x98, 0x98, 0x66, 0xA3, 0xA3, 0xA3, 0xA3,
-  0x2F, 0xA3, 0xA3, 0x66, 0x66, 0x66, 0x66, 0x66,
-  0x8F, 0x8F, 0x8F, 0x98, 0x98, 0x98, 0x8F, 0xA0,
-  0xA0, 0xA0, 0xA3, 0xDA, 0x20, 0x3A, 0x39, 0x6B,
-  0x6B, 0x6B, 0x4D, 0xA2, 0x74, 0x3C, 0x7E, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x6B, 0x2E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x2F, 0x2F, 0xA3, 0x66, 0x66, 0x66, 0x66,
-  0x66, 0x98, 0x8F, 0x8F, 0x98, 0x98, 0x98, 0x98,
-  0x8F, 0xA0, 0xA0, 0xA0, 0x8F, 0x8F, 0x8F, 0xA0,
-  0x8F, 0x66, 0x66, 0xA3, 0x66, 0xA3, 0xA3, 0x2F,
-  0x2F, 0x2F, 0xA3, 0xA3, 0x66, 0x66, 0x66, 0x98,
-  0x98, 0xA0, 0x98, 0x66, 0x66, 0x98, 0x8F, 0xA0,
-  0xA0, 0xA3, 0x2E, 0x20, 0x20, 0x8F, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x3D, 0x6B, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x6B, 0x55, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x3A, 0x51, 0x2F, 0xA3, 0x66, 0x66, 0x66,
-  0x66, 0x66, 0x98, 0x8F, 0x8F, 0x98, 0x66, 0x98,
-  0x8F, 0xA0, 0xA0, 0x8F, 0x8F, 0x8F, 0x8F, 0xA0,
-  0x66, 0x2F, 0x2F, 0x2F, 0x2F, 0xA3, 0xA3, 0xA3,
-  0x2F, 0x2F, 0xA3, 0xA3, 0x66, 0xA3, 0x66, 0x66,
-  0x66, 0x98, 0xA3, 0x2F, 0x2F, 0xA3, 0x66, 0x8F,
-  0x66, 0xA6, 0x20, 0x20, 0x6D, 0x39, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x6B, 0xB2, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x2E, 0x89, 0xA3, 0xA3, 0x66, 0x66,
-  0x66, 0x66, 0x98, 0x98, 0xA3, 0x2F, 0x2F, 0xA3,
-  0x66, 0x8F, 0x98, 0x98, 0x66, 0x98, 0x98, 0x8F,
-  0x2F, 0x51, 0xB2, 0xB2, 0x2F, 0xA3, 0xA3, 0xA3,
-  0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3,
-  0xA3, 0xA3, 0x2F, 0xB2, 0x2F, 0xA3, 0x66, 0x2F,
-  0x55, 0x20, 0x20, 0x20, 0x4C, 0x39, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x4D, 0x7E, 0x54, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x2E, 0x51, 0xA3, 0xA3, 0xA3,
-  0xA3, 0xA3, 0xA3, 0x2F, 0xB2, 0xB2, 0x2F, 0xA3,
-  0x66, 0x66, 0xA3, 0xA3, 0xA3, 0xA3, 0x66, 0x66,
-  0xB2, 0x51, 0x51, 0xB2, 0xB2, 0xA3, 0x2F, 0xA3,
-  0x2F, 0x2F, 0x2F, 0xA3, 0xA3, 0xA3, 0xA3, 0x66,
-  0xA3, 0x2F, 0xB2, 0x2F, 0xA3, 0x98, 0x98, 0xA0,
-  0x20, 0x20, 0x20, 0x20, 0xA5, 0x83, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x4D, 0x7E, 0x4D, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x4D, 0x4D, 0xD6, 0x7E, 0xDD,
-  0x3C, 0x39, 0xA7, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x92, 0xB2, 0xA3, 0xA3,
-  0xA3, 0x66, 0xA3, 0x2F, 0x2F, 0x2F, 0xA3, 0x98,
-  0x98, 0x66, 0xA3, 0xA3, 0x66, 0x66, 0x66, 0xA3,
-  0x89, 0x89, 0x51, 0xB2, 0xB2, 0x2F, 0x2F, 0x2F,
-  0x2F, 0xA3, 0xA3, 0x2F, 0xA3, 0xA3, 0xA3, 0xA3,
-  0xA3, 0xA3, 0xA3, 0x66, 0x8F, 0x8F, 0x2F, 0xDA,
-  0x20, 0x20, 0x20, 0xDA, 0xA0, 0x51, 0x3C, 0x7E,
-  0x6B, 0x6B, 0x6B, 0x4D, 0x7E, 0x6B, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x7E, 0x3C, 0xD8, 0x44, 0xD8,
-  0x44, 0x83, 0x89, 0xDA, 0x20, 0x3A, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0xB2, 0xA3, 0xA3,
-  0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0x66, 0x8F, 0x8F,
-  0x98, 0x98, 0x98, 0x98, 0x66, 0xA3, 0xA3, 0x2F,
-  0x3C, 0x89, 0x89, 0x51, 0xB2, 0xB2, 0x2F, 0x2F,
-  0x2F, 0x2F, 0xA3, 0xA3, 0x66, 0x66, 0x66, 0xA3,
-  0xA3, 0xA3, 0xA3, 0x66, 0x98, 0x98, 0xA3, 0x20,
-  0x20, 0x20, 0x20, 0x6D, 0x2F, 0xE6, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x3D, 0xD6, 0x3D,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x4D, 0x7E, 0xA2,
-  0x74, 0x44, 0xA2, 0xA3, 0x20, 0x3A, 0x2E, 0x6D,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0xA6, 0xA3, 0x66,
-  0x66, 0x66, 0xA3, 0x2F, 0xA3, 0x66, 0x66, 0x98,
-  0x66, 0x66, 0x98, 0x98, 0x98, 0x66, 0xA3, 0xA3,
-  0x83, 0xB2, 0x2F, 0x2F, 0xB2, 0xB2, 0xB2, 0x2F,
-  0x2F, 0x2F, 0xA3, 0x66, 0x66, 0x98, 0x98, 0x66,
-  0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0x66, 0xA6, 0x20,
-  0x3A, 0x3A, 0x54, 0x55, 0x7E, 0x6B, 0x6B, 0x6B,
-  0x4D, 0x3D, 0x6B, 0x6B, 0x6B, 0x57, 0x33, 0xEB,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x4D, 0xA2, 0x74, 0x39, 0x92, 0x20, 0x20, 0x6D,
-  0x2E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x98,
-  0x98, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0x66, 0x66,
-  0x66, 0x66, 0x66, 0x66, 0x66, 0xA3, 0x66, 0xA3,
-  0x89, 0xA3, 0x66, 0x66, 0xA3, 0xA3, 0x2F, 0x2F,
-  0xA3, 0x2F, 0xA3, 0xA3, 0x66, 0x66, 0x66, 0xA3,
-  0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xB2, 0x3A, 0x20,
-  0xA7, 0x20, 0x3A, 0x39, 0x6B, 0x6B, 0x6B, 0x6B,
-  0xB5, 0xCB, 0x6B, 0x6B, 0x3D, 0x8A, 0x42, 0x3D,
-  0x6B, 0x6B, 0x6B, 0x84, 0x6C, 0x4D, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x7E, 0x83, 0x51, 0x20, 0x20, 0x20,
-  0x6D, 0x3A, 0x20, 0x20, 0x20, 0x20, 0xAD, 0x66,
-  0x66, 0x66, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3,
-  0xA3, 0xA3, 0xA3, 0xA3, 0x66, 0xA3, 0xA3, 0xA3,
-  0xB2, 0x98, 0x66, 0x66, 0x98, 0x66, 0x66, 0xA3,
-  0xA3, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F,
-  0xA3, 0x2F, 0xA3, 0xA3, 0xA3, 0x2F, 0x20, 0x6D,
-  0x3A, 0x20, 0x98, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0xAA, 0x33, 0x6B, 0x6B, 0x3D, 0xF5, 0x7B, 0x3D,
-  0x6B, 0x6B, 0x4F, 0x4A, 0x58, 0x3D, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x7E, 0x7E, 0x9C, 0x54, 0xA7,
-  0x2E, 0xA7, 0x20, 0x20, 0x20, 0x20, 0x54, 0x51,
-  0x2F, 0x2F, 0xA3, 0x2F, 0xA3, 0xA3, 0xA3, 0xA3,
-  0x2F, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0x2F,
-  0xB2, 0x66, 0x66, 0x66, 0x66, 0xA3, 0x66, 0xA3,
-  0x66, 0x66, 0xA3, 0x2F, 0x2F, 0xB2, 0x2F, 0xB2,
-  0x2F, 0x2F, 0x2F, 0xA3, 0x2F, 0xA6, 0x20, 0xCE,
-  0x20, 0x6D, 0x4D, 0x6B, 0xD6, 0x7E, 0x6B, 0x6B,
-  0x6E, 0x9A, 0x57, 0x6B, 0x2D, 0x7B, 0x7B, 0x3D,
-  0x6B, 0x84, 0xF5, 0x7B, 0x84, 0x6B, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x98, 0x3A, 0x9C,
-  0xCE, 0x3A, 0x2E, 0x20, 0x20, 0x20, 0x20, 0x98,
-  0xB2, 0xB2, 0x2F, 0x2F, 0x2F, 0xA3, 0x2F, 0x2F,
-  0x2F, 0xA3, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F,
-  0x89, 0xA3, 0x66, 0x66, 0xA3, 0x2F, 0x2F, 0xA3,
-  0x66, 0x66, 0xA3, 0xA3, 0x2F, 0x2F, 0xB2, 0xB2,
-  0xB2, 0x2F, 0x2F, 0x2F, 0x89, 0x54, 0x6D, 0x3A,
-  0x20, 0x98, 0x6B, 0x6B, 0xE0, 0xB4, 0x6B, 0x6B,
-  0x2D, 0x9E, 0x4A, 0x3D, 0x84, 0xF5, 0xF5, 0x84,
-  0x6B, 0x6E, 0x59, 0x6C, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x3D, 0x6B, 0x6B, 0x6B, 0x6B, 0xDD, 0xDA, 0x6D,
-  0x54, 0x20, 0xCE, 0x20, 0x20, 0x20, 0x20, 0xA7,
-  0x51, 0xB2, 0xB2, 0xB2, 0x2F, 0xB2, 0x2F, 0x2F,
-  0x2F, 0x66, 0x66, 0xA3, 0xA3, 0xA3, 0xA3, 0x66,
-  0x89, 0xA3, 0xA3, 0xA3, 0x2F, 0xB2, 0xB2, 0x2F,
-  0x66, 0x66, 0xA3, 0xA3, 0x2F, 0xA3, 0xA3, 0x2F,
-  0xB2, 0x2F, 0x2F, 0xA3, 0x98, 0x20, 0xA7, 0x20,
-  0x3A, 0x7E, 0x6B, 0x6B, 0x7F, 0xDE, 0xF6, 0x3D,
-  0x6B, 0xDB, 0x8A, 0xDB, 0xE9, 0xF3, 0xF3, 0xDB,
-  0x68, 0xF3, 0x73, 0x7F, 0x6B, 0x6B, 0x57, 0x58,
-  0xDC, 0x2D, 0x6B, 0x6B, 0x6B, 0x6B, 0x3A, 0x20,
-  0x20, 0x20, 0x6D, 0x54, 0x20, 0x20, 0x20, 0x20,
-  0x51, 0x2F, 0x2F, 0x2F, 0xA3, 0xA3, 0xA3, 0x66,
-  0xA3, 0x66, 0x98, 0x98, 0x66, 0x98, 0x98, 0x66,
-  0x2F, 0x66, 0x66, 0xA3, 0x2F, 0xB2, 0x2F, 0xA3,
-  0xA3, 0xA3, 0xA3, 0xA3, 0x66, 0xA3, 0xA3, 0xA3,
-  0x66, 0x98, 0x8F, 0x98, 0xCE, 0xDA, 0x2E, 0x20,
-  0x2A, 0x6B, 0x6B, 0x6B, 0x6B, 0x2C, 0x34, 0xCB,
-  0xEB, 0x6C, 0x31, 0x59, 0x82, 0x82, 0x8B, 0x82,
-  0xF3, 0x73, 0xE9, 0x6B, 0x3D, 0x6E, 0xF3, 0x4A,
-  0x4F, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x92, 0x20,
-  0x20, 0x20, 0x6D, 0x6D, 0x20, 0x20, 0x20, 0x20,
-  0xA3, 0xA3, 0x66, 0x98, 0x98, 0x8F, 0x8F, 0x98,
-  0x98, 0x98, 0x98, 0x66, 0x98, 0x66, 0x66, 0xA3,
-  0xA3, 0x66, 0x66, 0x66, 0xA3, 0x2F, 0x2F, 0xA3,
-  0xA3, 0xA3, 0x66, 0x66, 0xA3, 0xA3, 0xA3, 0x66,
-  0x8F, 0x55, 0xA5, 0x98, 0x20, 0x2E, 0x54, 0x54,
-  0x89, 0x6B, 0x6B, 0x6B, 0x6B, 0x84, 0xE3, 0x4A,
-  0x58, 0x42, 0x5B, 0x8B, 0x82, 0x82, 0x82, 0x82,
-  0x82, 0x59, 0x58, 0x57, 0x57, 0x59, 0x7B, 0x84,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0xAD, 0x20,
-  0x20, 0x20, 0x3A, 0x3A, 0x20, 0x20, 0x20, 0x20,
-  0x2A, 0x66, 0x8F, 0x55, 0xA5, 0xA5, 0xA0, 0x8F,
-  0x66, 0xA3, 0xA3, 0x66, 0x98, 0x66, 0x66, 0x2F,
-  0x2F, 0x2F, 0x2F, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F,
-  0xA3, 0x2F, 0xA3, 0xA3, 0x66, 0xA3, 0xA3, 0x66,
-  0x8F, 0xA5, 0x8F, 0x2E, 0x20, 0x2E, 0x20, 0x3A,
-  0x4D, 0x6B, 0xE6, 0x84, 0x3D, 0x6B, 0xEB, 0x4A,
-  0xC9, 0x8B, 0x8B, 0x31, 0x59, 0x82, 0x59, 0x59,
-  0x5B, 0x82, 0x59, 0x73, 0x7B, 0xDC, 0x57, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x55, 0x20,
-  0x20, 0x20, 0x6D, 0xDA, 0x20, 0x20, 0x20, 0x20,
-  0x9C, 0x66, 0x8F, 0xA5, 0xA5, 0x55, 0x8F, 0x66,
-  0x2F, 0xB2, 0x2F, 0x66, 0x98, 0x98, 0x2F, 0x51,
-  0x89, 0xB2, 0x2F, 0xA3, 0xA3, 0xB2, 0xB2, 0xB2,
-  0x2F, 0x2F, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0x66,
-  0x8F, 0xA5, 0x8F, 0x20, 0x20, 0xA7, 0x20, 0xA6,
-  0x6B, 0x6B, 0xE4, 0x48, 0x2C, 0xDB, 0x4F, 0x9E,
-  0xD0, 0xD0, 0x8B, 0x82, 0x82, 0x82, 0x82, 0x82,
-  0x59, 0x82, 0x82, 0x73, 0x7B, 0x68, 0x6B, 0x3D,
-  0x68, 0x68, 0x84, 0x3D, 0x6B, 0x6B, 0xA0, 0x20,
-  0x20, 0x20, 0x6D, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x6D, 0x2F, 0xA0, 0xA5, 0x55, 0x98, 0x66, 0xA3,
-  0xB2, 0x89, 0xB2, 0x98, 0x8F, 0x98, 0x2F, 0x51,
-  0x74, 0xB2, 0xA3, 0xA3, 0x2F, 0x2F, 0xB2, 0x2F,
-  0xA3, 0xA3, 0xA3, 0x66, 0x66, 0xA3, 0x2F, 0xA3,
-  0x98, 0xA3, 0x6D, 0x20, 0x20, 0xCE, 0x20, 0x2A,
-  0x6B, 0x6B, 0xEB, 0x2C, 0xE1, 0xF1, 0x7C, 0xD0,
-  0x8B, 0x8B, 0x82, 0x82, 0x82, 0x82, 0x82, 0x59,
-  0x82, 0x82, 0x42, 0x82, 0x31, 0x57, 0x4F, 0x7B,
-  0x7B, 0xF5, 0xF6, 0xDB, 0x6B, 0x6B, 0x98, 0x20,
-  0x20, 0x20, 0x2E, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x51, 0x66, 0xA0, 0xA0, 0x66, 0x2F, 0xB2,
-  0xB2, 0x51, 0x2F, 0xA0, 0x55, 0xA3, 0x51, 0x89,
-  0x44, 0xA3, 0x98, 0x98, 0x2F, 0x2F, 0x2F, 0xA3,
-  0xA3, 0x66, 0x98, 0x98, 0x98, 0xA3, 0x2F, 0x2F,
-  0x98, 0x8F, 0x20, 0x20, 0x3A, 0xA6, 0x20, 0xA0,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x7F, 0x7F, 0xC3, 0xC9,
-  0xD0, 0xD0, 0x29, 0x59, 0x82, 0x73, 0x82, 0x73,
-  0x59, 0x59, 0x59, 0x59, 0x59, 0x58, 0xAF, 0xF5,
-  0x8A, 0x68, 0xEB, 0x6B, 0x6B, 0x6B, 0x98, 0x20,
-  0x20, 0x20, 0x6D, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x51, 0x98, 0x55, 0xA0, 0xA3, 0xB2, 0x51,
-  0x51, 0x2F, 0x98, 0x55, 0x8F, 0xB2, 0x89, 0x44,
-  0xA3, 0x55, 0x55, 0x98, 0xA3, 0xB2, 0x2F, 0xA3,
-  0x66, 0x66, 0x98, 0x8F, 0x66, 0xA3, 0x66, 0x98,
-  0x55, 0x4C, 0x20, 0x20, 0xDA, 0xAD, 0x20, 0x98,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x3D, 0x9A, 0xD0,
-  0xF2, 0x8B, 0x8B, 0x8B, 0x73, 0x82, 0x5B, 0x82,
-  0x82, 0x59, 0x59, 0x73, 0x73, 0x58, 0x3D, 0x3D,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x66, 0x20,
-  0x20, 0x3A, 0x3A, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x2F, 0x55, 0xA5, 0x8F, 0xA3, 0x51, 0x51,
-  0xB2, 0xA3, 0x66, 0x66, 0xA3, 0xB2, 0x89, 0x51,
-  0x98, 0xA5, 0x55, 0x8F, 0x2F, 0xB2, 0xB2, 0xA3,
-  0x66, 0x66, 0x98, 0x98, 0x98, 0x66, 0x66, 0x8F,
-  0x8F, 0x92, 0x20, 0x20, 0x20, 0x6D, 0x6D, 0xA3,
-  0x6B, 0x6B, 0xEB, 0x7F, 0x4F, 0xDB, 0xD2, 0xC9,
-  0xC9, 0xD0, 0x8B, 0x8B, 0x73, 0x82, 0x59, 0x8B,
-  0x59, 0x82, 0x59, 0x59, 0x73, 0xF5, 0xEB, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x55, 0x20,
-  0x20, 0xA7, 0x54, 0xDA, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x98, 0xA0, 0x8F, 0xA3, 0xB2, 0x51, 0x51,
-  0x51, 0x2F, 0xA3, 0xA3, 0xB2, 0xB2, 0x51, 0xB2,
-  0xA0, 0xA5, 0x55, 0x66, 0x2F, 0x51, 0x2F, 0xA3,
-  0x66, 0x66, 0x66, 0x98, 0x66, 0x66, 0x98, 0x98,
-  0x98, 0x2A, 0x54, 0x95, 0x95, 0x71, 0x2E, 0x98,
-  0x6B, 0x6B, 0x4D, 0x28, 0xDE, 0x88, 0xB7, 0x70,
-  0xC9, 0xC9, 0xD0, 0xF2, 0x8B, 0x8B, 0x8B, 0x59,
-  0x59, 0x59, 0x59, 0x5B, 0x59, 0xF3, 0x57, 0xE9,
-  0xDB, 0x84, 0x6B, 0x6B, 0x6B, 0x6B, 0x4C, 0xDA,
-  0x2E, 0xDA, 0x20, 0xDA, 0x2E, 0x2E, 0x6D, 0x20,
-  0x4C, 0x98, 0x66, 0xA3, 0x2F, 0xB2, 0x51, 0x51,
-  0xB2, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F,
-  0xA0, 0xA0, 0x8F, 0x2F, 0xB2, 0x89, 0xB2, 0xA3,
-  0x66, 0x66, 0x98, 0x66, 0x66, 0x66, 0x66, 0xA3,
-  0x2F, 0xD1, 0xE2, 0x52, 0x52, 0xF4, 0xBF, 0x9C,
-  0x39, 0x6B, 0x6B, 0x6B, 0x7F, 0x4F, 0xE3, 0x6A,
-  0xD0, 0xC9, 0xC9, 0xD0, 0xD0, 0x8B, 0x8B, 0x82,
-  0x5B, 0x5B, 0x73, 0x8B, 0x59, 0x23, 0x6E, 0x31,
-  0x59, 0x7B, 0xDB, 0x84, 0x68, 0x7F, 0xAE, 0x54,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0xA6, 0x3A,
-  0xA0, 0xA3, 0xA3, 0x2F, 0x51, 0x51, 0x51, 0xB2,
-  0x2F, 0xA3, 0x66, 0x66, 0xA3, 0xA3, 0xA3, 0xA3,
-  0x8F, 0x8F, 0x66, 0x2F, 0x51, 0x51, 0xB2, 0xA3,
-  0x66, 0x98, 0x98, 0x66, 0x66, 0xA3, 0x2F, 0x2F,
-  0x3C, 0x88, 0x8D, 0x52, 0x52, 0x5D, 0xF7, 0xBF,
-  0xCE, 0xA2, 0x6B, 0x6B, 0x6B, 0x6B, 0x7F, 0x85,
-  0x70, 0xC9, 0xC9, 0xC9, 0xD0, 0xEA, 0x8B, 0x5B,
-  0x82, 0xEA, 0x82, 0x82, 0x42, 0x57, 0x3D, 0x68,
-  0x68, 0x57, 0x4A, 0x34, 0x22, 0xCC, 0x21, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0xDA, 0xA7, 0x6D,
-  0xDF, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0x2F, 0x2F,
-  0xA3, 0x66, 0x66, 0x66, 0xA3, 0xA3, 0x2F, 0x2F,
-  0x66, 0x66, 0xA3, 0x2F, 0xB2, 0xB2, 0x2F, 0x66,
-  0x8F, 0x8F, 0x8F, 0x98, 0xA3, 0xA3, 0x89, 0xD8,
-  0x25, 0x5C, 0x3B, 0x5D, 0x52, 0x80, 0x70, 0x36,
-  0x71, 0xA7, 0x44, 0x6B, 0x84, 0xCB, 0xAA, 0xF3,
-  0xC9, 0xC9, 0xC9, 0xC9, 0xD0, 0x8B, 0x5B, 0x5B,
-  0x5B, 0xEA, 0x82, 0x47, 0x7B, 0x68, 0x3D, 0x3D,
-  0x6B, 0x3D, 0x6C, 0x2B, 0x80, 0x61, 0x96, 0x81,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0xDA, 0x63,
-  0xAC, 0x6C, 0xB2, 0xB2, 0xB2, 0xB2, 0x2F, 0xA3,
-  0xA3, 0x66, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F,
-  0x66, 0x98, 0x66, 0xA3, 0xB2, 0xB2, 0x2F, 0x66,
-  0x8F, 0x8F, 0x2F, 0xD8, 0xE4, 0xCD, 0xAA, 0xB4,
-  0x78, 0x2B, 0x3B, 0x70, 0x46, 0x5D, 0x5D, 0x52,
-  0x9D, 0x81, 0x3A, 0xA3, 0xCD, 0x48, 0xBE, 0x4F,
-  0xC3, 0xC9, 0xD0, 0xD0, 0xD0, 0xEA, 0x5B, 0x8B,
-  0x5B, 0x82, 0x8B, 0x59, 0x4A, 0xF3, 0x33, 0x7F,
-  0x3D, 0x6B, 0x4F, 0x6F, 0x5D, 0x52, 0x63, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x75, 0x85,
-  0x72, 0xDC, 0xD8, 0x2F, 0xA3, 0x2F, 0xA3, 0xA3,
-  0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3,
-  0xA3, 0x98, 0x66, 0x2F, 0xB2, 0x51, 0xA3, 0x98,
-  0xA0, 0xA3, 0x93, 0xCF, 0x79, 0x27, 0x5C, 0x79,
-  0x2B, 0x30, 0x80, 0x80, 0x5D, 0x5D, 0x5D, 0x5D,
-  0x3F, 0x69, 0x20, 0x20, 0x2A, 0xD6, 0x3D, 0x6B,
-  0x84, 0xE3, 0x34, 0xB7, 0xC9, 0xD0, 0xD0, 0xF2,
-  0xD0, 0x8B, 0x31, 0x68, 0x68, 0x6E, 0x31, 0x33,
-  0x7F, 0x7E, 0xA1, 0x6F, 0x52, 0x8D, 0xE5, 0xBF,
-  0x20, 0x20, 0x20, 0x20, 0x81, 0xA8, 0x78, 0x52,
-  0x52, 0xD2, 0xD8, 0xA3, 0xA3, 0x2F, 0x2F, 0xA3,
-  0xA3, 0x66, 0x98, 0x98, 0x98, 0x98, 0x98, 0x66,
-  0x51, 0x66, 0x2F, 0x51, 0x51, 0xB2, 0xA3, 0xA0,
-  0xA0, 0x44, 0x78, 0xEF, 0x52, 0x30, 0x30, 0x30,
-  0x3B, 0x70, 0x5D, 0x5D, 0x5D, 0x80, 0x5D, 0x5D,
-  0x46, 0xC1, 0x71, 0x20, 0x81, 0xB1, 0xDD, 0x3D,
-  0xA1, 0xE7, 0xDB, 0xCA, 0xD2, 0x6A, 0x6A, 0x6A,
-  0xF3, 0xE9, 0xDB, 0x8A, 0x84, 0x3D, 0x84, 0xDC,
-  0x25, 0x44, 0xB5, 0xEE, 0x30, 0xEF, 0xF0, 0x32,
-  0x69, 0x5F, 0x4B, 0xA8, 0x99, 0x56, 0x67, 0x30,
-  0x30, 0x34, 0xB2, 0x2F, 0xA3, 0xA3, 0x66, 0x66,
-  0x98, 0x8F, 0x98, 0x98, 0x66, 0x66, 0x66, 0x66,
-  0x51, 0x2F, 0xB2, 0x51, 0x51, 0x2F, 0x66, 0xA0,
-  0x8F, 0xE0, 0xF9, 0x8D, 0x52, 0x5D, 0x46, 0x5D,
-  0x80, 0x5D, 0x80, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D,
-  0x52, 0x52, 0x60, 0x81, 0x20, 0x20, 0x6D, 0xD1,
-  0x48, 0xE7, 0x6B, 0x33, 0xF6, 0x7F, 0x7F, 0xDB,
-  0x84, 0x6B, 0x6C, 0x6A, 0xF3, 0xEB, 0x6B, 0x3D,
-  0x4F, 0xD8, 0xCD, 0x79, 0x30, 0x67, 0xF9, 0x24,
-  0xED, 0xD9, 0x8C, 0xED, 0x37, 0x2B, 0x3B, 0x5D,
-  0x80, 0x85, 0x4E, 0x98, 0x66, 0x66, 0x66, 0x66,
-  0x66, 0x66, 0x66, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F,
-  0x51, 0x2F, 0xB2, 0xB2, 0xB2, 0xA3, 0x8F, 0x8F,
-  0x98, 0xE0, 0xF0, 0x67, 0x5D, 0x80, 0x80, 0x5D,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x80, 0x5D, 0x5D, 0x5D,
-  0x5D, 0x70, 0x27, 0x4B, 0x20, 0x81, 0x71, 0x3A,
-  0xB5, 0xEB, 0x3D, 0xF1, 0xE1, 0x84, 0x84, 0xF1,
-  0xE3, 0x3D, 0x6B, 0x6C, 0x34, 0xE7, 0x6B, 0x6B,
-  0xD6, 0x74, 0x5E, 0x78, 0x67, 0x30, 0xEE, 0x5C,
-  0xF9, 0xF9, 0x45, 0x5C, 0x2B, 0x3B, 0x5D, 0x5D,
-  0x5D, 0x5D, 0xF8, 0x44, 0x66, 0x66, 0x66, 0x66,
-  0x2F, 0x2F, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2,
-  0xB2, 0x2F, 0xA3, 0xA3, 0xA3, 0x98, 0x8F, 0x98,
-  0x66, 0x83, 0x76, 0x67, 0x30, 0x80, 0x5D, 0x80,
-  0x5D, 0x5D, 0x80, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D,
-  0x80, 0x5D, 0x22, 0xFA, 0x20, 0x81, 0x20, 0x20,
-  0xA5, 0x6B, 0x6B, 0xE8, 0xBE, 0x3D, 0x6B, 0x2C,
-  0xE1, 0xEB, 0x6B, 0x3D, 0x3E, 0xA1, 0x6B, 0x6B,
-  0x4D, 0x74, 0xE8, 0x62, 0x67, 0x30, 0x8D, 0x67,
-  0xEE, 0xEE, 0xEE, 0x67, 0x30, 0x80, 0x5D, 0x5D,
-  0x52, 0x5D, 0x85, 0xAC, 0x3E, 0xA3, 0x66, 0x66,
-  0x2F, 0x51, 0x51, 0x51, 0x51, 0xB2, 0x2F, 0x2F,
-  0x2F, 0xA3, 0xA3, 0x66, 0x98, 0x8F, 0x8F, 0x66,
-  0x2F, 0x83, 0xBC, 0xEE, 0x5D, 0x5D, 0x5D, 0x5D,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x80, 0x5D, 0x5D,
-  0x5D, 0x5D, 0x22, 0xB0, 0xAE, 0x81, 0x20, 0x20,
-  0x4C, 0x3D, 0xEB, 0x39, 0x57, 0x6B, 0x6B, 0x3E,
-  0x97, 0x3D, 0x6B, 0x3D, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x3D, 0x3C, 0xBA, 0x62, 0xEE, 0x5D, 0x5D, 0x30,
-  0x30, 0x8D, 0x8D, 0x30, 0x52, 0x5D, 0x5D, 0x80,
-  0x5D, 0x5D, 0x5D, 0x85, 0xB0, 0x6E, 0x2F, 0x66,
-  0x2F, 0xB2, 0x51, 0xB2, 0x2F, 0x2F, 0xA3, 0xA3,
-  0xB2, 0xA3, 0x66, 0x98, 0x98, 0x8F, 0x98, 0xA3,
-  0x2F, 0x51, 0xDE, 0x8E, 0x30, 0x5D, 0x5D, 0x5D,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D,
-  0x52, 0x80, 0x5D, 0x22, 0x43, 0x4B, 0x20, 0x6D,
-  0x44, 0x6B, 0x6B, 0x3D, 0x6B, 0x6B, 0x6B, 0x4D,
-  0x3D, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x3D, 0x6B,
-  0x4D, 0x2A, 0xAE, 0x76, 0xEE, 0x30, 0x80, 0x80,
-  0x80, 0x80, 0x80, 0x80, 0x5D, 0x5D, 0x5D, 0x80,
-  0x5D, 0x5D, 0x80, 0x80, 0x5D, 0x7A, 0xB6, 0x51,
-  0xB2, 0xB2, 0xB2, 0xA3, 0x66, 0x66, 0x66, 0xA3,
-  0x2F, 0x66, 0x98, 0x8F, 0xA0, 0x98, 0xA3, 0x2F,
-  0x2F, 0x51, 0xAB, 0x8E, 0x5D, 0x5D, 0x5D, 0x5D,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x80,
-  0x5D, 0x80, 0x5D, 0x52, 0x52, 0x94, 0x2F, 0x7E,
-  0x6B, 0x3D, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x7E,
-  0xAD, 0x54, 0xAE, 0x24, 0x2B, 0x3B, 0x5D, 0x52,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x80, 0x5D, 0x5D, 0x80,
-  0x5D, 0x52, 0x52, 0x5D, 0x5D, 0x5D, 0xD2, 0x3E,
-  0x89, 0x89, 0xB2, 0xA3, 0x66, 0x98, 0x66, 0x66,
-  0x2F, 0x66, 0x8F, 0x8F, 0xA0, 0x98, 0xA3, 0xB2,
-  0x2F, 0x51, 0xDE, 0x79, 0x5D, 0x80, 0x5D, 0x5D,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D,
-  0x5D, 0x5D, 0x80, 0x5D, 0x52, 0x6F, 0xA4, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x4D, 0xA2, 0xCE,
-  0x20, 0x20, 0x95, 0x24, 0x67, 0x3B, 0x80, 0x80,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D,
-  0x80, 0x5D, 0x5D, 0x5D, 0x5D, 0x30, 0xB0, 0x86,
-  0x89, 0x51, 0x2F, 0x66, 0x98, 0x98, 0xA3, 0xA3,
-  0xA3, 0x66, 0x8F, 0xA0, 0x8F, 0x66, 0x2F, 0xB2,
-  0x2F, 0x4E, 0x76, 0x2B, 0x30, 0x5D, 0x5D, 0x5D,
-  0x80, 0x80, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D,
-  0x80, 0x5D, 0x5D, 0x5D, 0x46, 0x52, 0x21, 0x74,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x7E, 0x98, 0x3A, 0x20,
-  0x20, 0x81, 0x60, 0xED, 0x2B, 0x52, 0x5D, 0x5D,
-  0x80, 0x5D, 0x5D, 0x80, 0x5D, 0x5D, 0x5D, 0x80,
-  0x22, 0x5D, 0x5D, 0x5D, 0x8D, 0x2B, 0x38, 0x39,
-  0x51, 0x66, 0x8F, 0xA0, 0xA0, 0x8F, 0x98, 0x66,
-  0x66, 0x66, 0x8F, 0x55, 0x8F, 0xA3, 0xB2, 0xB2,
-  0xA3, 0xE8, 0xF9, 0x30, 0x3B, 0x80, 0x5D, 0x5D,
-  0x5D, 0x80, 0x80, 0x5D, 0x5D, 0x5D, 0x80, 0x5D,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x52, 0x30, 0xD4, 0x99,
-  0x51, 0x4D, 0x6B, 0x6B, 0x6B, 0x6B, 0x4D, 0x6B,
-  0x6B, 0x6B, 0x7E, 0xA3, 0x2E, 0x20, 0x20, 0x20,
-  0x20, 0x81, 0xC5, 0xED, 0x2B, 0x3B, 0x5D, 0x5D,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x80, 0x5D, 0x5D, 0x80,
-  0x5D, 0x52, 0x52, 0x6F, 0xDE, 0x2C, 0x39, 0x51,
-  0x66, 0xA0, 0xA5, 0xA5, 0x55, 0x8F, 0x66, 0x66,
-  0xA0, 0xA0, 0xA0, 0xA0, 0x8F, 0xA3, 0x2F, 0x2F,
-  0x51, 0xD5, 0x45, 0x8D, 0x3B, 0x5D, 0x80, 0x5D,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D,
-  0x80, 0x5D, 0x5D, 0x5D, 0x52, 0x67, 0x37, 0xA9,
-  0x3A, 0xCE, 0xA0, 0x2F, 0x51, 0x51, 0xB2, 0xA3,
-  0xA5, 0x9C, 0x54, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x54, 0x99, 0xED, 0x67, 0x30, 0x5D, 0x5D,
-  0x5D, 0x80, 0x5D, 0x5D, 0x5D, 0x5D, 0x3B, 0x80,
-  0x8D, 0x79, 0x48, 0x2C, 0x39, 0x44, 0xB2, 0x66,
-  0xA0, 0x2A, 0xA5, 0xA0, 0x8F, 0x66, 0xA3, 0xA3,
-  0xA0, 0x8F, 0x8F, 0xA0, 0x8F, 0xA3, 0xB2, 0xB2,
-  0xD8, 0xBC, 0x45, 0xEE, 0x67, 0x8D, 0x30, 0x30,
-  0x52, 0x52, 0x80, 0x5D, 0x5D, 0x5D, 0x5D, 0x80,
-  0x5D, 0x5D, 0x5D, 0x80, 0x3B, 0x67, 0xF9, 0x32,
-  0x69, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0xBF, 0xEC, 0xED, 0x2B, 0x30, 0x5D, 0x5D,
-  0x80, 0x5D, 0x5D, 0x5D, 0x52, 0x30, 0x67, 0x2B,
-  0xCF, 0xAA, 0xD8, 0x89, 0x89, 0x51, 0x66, 0x55,
-  0x2A, 0x2A, 0xA5, 0x8F, 0x66, 0xA3, 0x2F, 0x2F,
-  0xA3, 0xA3, 0x66, 0x98, 0x98, 0x2F, 0xB2, 0x2F,
-  0xD1, 0x28, 0x56, 0xED, 0x62, 0x37, 0x5C, 0x79,
-  0x8E, 0x2B, 0x2B, 0x30, 0x30, 0x30, 0x5D, 0x5D,
-  0x5D, 0x5D, 0x5D, 0x80, 0x3B, 0xEE, 0x56, 0xA9,
-  0x75, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x5F, 0x99, 0xD9, 0x45, 0x8D, 0x3B, 0x5D,
-  0x5D, 0x3B, 0x5D, 0x8D, 0x2B, 0x79, 0x79, 0x41,
-  0x83, 0xB2, 0xB2, 0x89, 0x89, 0x2F, 0xA0, 0x2A,
-  0xAD, 0xA5, 0x98, 0x66, 0xA3, 0xB2, 0x2F, 0xB2,
-  0xD8, 0xB2, 0xA3, 0x98, 0x98, 0x2F, 0x51, 0xB2,
-  0xA3, 0x83, 0x3E, 0x25, 0xD5, 0xE5, 0x50, 0x8C,
-  0xED, 0x24, 0x24, 0xF0, 0x45, 0x8E, 0x2B, 0x30,
-  0x30, 0x5D, 0x3B, 0x30, 0xEE, 0xF0, 0xC6, 0x65,
-  0x75, 0x71, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x4B, 0xC5, 0x7D, 0x24, 0xEE, 0x67, 0x30,
-  0x30, 0x8D, 0x67, 0x8E, 0xF9, 0xF7, 0x97, 0xDD,
-  0x2F, 0x2F, 0x51, 0x89, 0x89, 0x2F, 0x55, 0x2A,
-  0xA5, 0x8F, 0x66, 0xA3, 0x2F, 0xB2, 0xB2, 0xB2,
-  0xDD, 0xA3, 0x66, 0x98, 0x66, 0x2F, 0xB2, 0xB2,
-  0xA3, 0xA3, 0xB2, 0x51, 0x89, 0x44, 0xE0, 0x5E,
-  0x91, 0x9F, 0x9F, 0x7D, 0x7D, 0xD9, 0x24, 0xF0,
-  0x79, 0x8E, 0xEE, 0x8E, 0x24, 0x40, 0x65, 0x35,
-  0x69, 0x2E, 0x98, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F,
-  0x2F, 0xB2, 0xB2, 0xB2, 0x2F, 0x2F, 0x2F, 0x98,
-  0xA5, 0xA7, 0x95, 0xD7, 0x8C, 0xF0, 0x8E, 0x8E,
-  0xEE, 0x79, 0xF0, 0xED, 0x50, 0xE8, 0x89, 0x2F,
-  0xA3, 0xA3, 0xB2, 0x89, 0xB2, 0x66, 0xA0, 0x55,
-  0x8F, 0x98, 0x66, 0xA3, 0xB2, 0x51, 0x51, 0xB2,
-  0x74, 0xA0, 0xA0, 0x98, 0x66, 0xB2, 0xB2, 0xB2,
-  0xA3, 0xA3, 0x2F, 0xB2, 0xB2, 0xB2, 0xA3, 0x2F,
-  0x51, 0x83, 0xE4, 0x87, 0xB8, 0xFA, 0xA9, 0xC6,
-  0x40, 0x64, 0x64, 0x50, 0xD7, 0x65, 0x35, 0x60,
-  0x98, 0xB2, 0x66, 0x66, 0xA3, 0x2F, 0xA3, 0xA3,
-  0xA3, 0x2F, 0x2F, 0x2F, 0x2F, 0xA3, 0x2F, 0xB2,
-  0x89, 0xDD, 0x9B, 0xC0, 0x7D, 0x50, 0x8C, 0xED,
-  0xED, 0x8C, 0x40, 0x9F, 0x4E, 0x51, 0xB2, 0x2F,
-  0x2F, 0x2F, 0xB2, 0x51, 0xA3, 0x98, 0xA0, 0x55,
-  0xA0, 0xA0, 0x8F, 0x66, 0x2F, 0x51, 0xB2, 0xA3,
-  0xA3, 0x2A, 0x55, 0x98, 0xA3, 0x2F, 0xB2, 0x2F,
-  0x66, 0x66, 0x2F, 0xB2, 0xD1, 0x2F, 0x2F, 0xA3,
-  0xB2, 0xB2, 0xA3, 0x8F, 0xA3, 0x2F, 0xD1, 0x94,
-  0xEC, 0x65, 0x65, 0xC0, 0xC0, 0x35, 0x95, 0xC2,
-  0xA3, 0x98, 0x66, 0xA3, 0x2F, 0x2F, 0x2F, 0xA3,
-  0xA3, 0x2F, 0xB2, 0x2F, 0x2F, 0x2F, 0x2F, 0x51,
-  0x89, 0x44, 0xD1, 0x60, 0x35, 0xA9, 0x32, 0xC6,
-  0xD7, 0x32, 0x94, 0x44, 0x2F, 0xB2, 0xB2, 0xB2,
-  0xA3, 0x2F, 0xB2, 0x2F, 0xA3, 0x8F, 0xA0, 0xA0,
-  0x55, 0xA0, 0x8F, 0xA3, 0x51, 0x51, 0x2F, 0xA3,
-  0x8F, 0x2A, 0x55, 0x66, 0xA3, 0x2F, 0x2F, 0xB2,
-  0xA3, 0x66, 0x2F, 0xB2, 0x51, 0xB2, 0x2F, 0x66,
-  0xA3, 0xA3, 0x66, 0x8F, 0x8F, 0x8F, 0xA0, 0x2F,
-  0x5E, 0xDF, 0xB9, 0x60, 0x95, 0xD3, 0x89, 0x2F,
-  0xA3, 0x66, 0xA3, 0x2F, 0xB2, 0x2F, 0xA3, 0xA3,
-  0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0xB2,
-  0x51, 0x2F, 0x8F, 0x2F, 0xC4, 0xB9, 0x9B, 0xEC,
-  0x53, 0xB3, 0x4E, 0xA3, 0x2F, 0xB2, 0xB2, 0xB2,
-  0xA3, 0x66, 0xA3, 0xA3, 0x66, 0x8F, 0x8F, 0x8F,
-  0x8F, 0x8F, 0xA3, 0x51, 0x89, 0x51, 0xA3, 0x66,
-  0xA0, 0x55, 0x8F, 0xA3, 0x2F, 0x2F, 0x2F, 0xB2,
-  0x2F, 0xA3, 0x2F, 0x51, 0x51, 0xB2, 0xA3, 0x66,
-  0x66, 0xA3, 0x66, 0x66, 0x66, 0x66, 0x66, 0xA3,
-  0xB2, 0xC2, 0x74, 0xD8, 0xB2, 0xA3, 0xA3, 0xA3,
-  0x66, 0x66, 0x2F, 0x2F, 0xA3, 0x66, 0x66, 0x66,
-  0xA3, 0xA3, 0xB2, 0xB2, 0xB2, 0xB2, 0x2F, 0xB2,
-  0x2F, 0x66, 0xA0, 0x55, 0x98, 0x2F, 0x89, 0x89,
-  0x89, 0xB2, 0x2F, 0xA3, 0x2F, 0x51, 0x51, 0xB2,
-  0x2F, 0x66, 0xA3, 0xA3, 0x66, 0x66, 0x66, 0x66,
-  0x66, 0xA3, 0xB2, 0x89, 0xD8, 0x51, 0xA3, 0x98,
-  0x66, 0x98, 0x66, 0x2F, 0x2F, 0x2F, 0x2F, 0xB2,
-  0xB2, 0xA3, 0xA3, 0xB2, 0xB2, 0xB2, 0x2F, 0xA3,
-  0x66, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0xB2,
-  0x89, 0xD8, 0x89, 0x2F, 0x66, 0x66, 0xA3, 0xA3,
-  0x98, 0x98, 0x66, 0x66, 0x98, 0x98, 0x66, 0xA3,
-  0x2F, 0xA3, 0xB2, 0xB2, 0xB2, 0xB2, 0x2F, 0x2F,
-  0xB2, 0x2F, 0x66, 0x98, 0x66, 0xA3, 0x2F, 0x2F,
-  0x2F, 0xB2, 0x2F, 0xA3, 0xA3, 0xB2, 0xB2, 0x2F,
-  0x2F, 0x66, 0x66, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F,
-  0x2F, 0xB2, 0x89, 0xD8, 0x44, 0x2F, 0x66, 0x66,
-  0xA3, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F,
-  0x2F, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0xA3,
-  0x66, 0xA3, 0x2F, 0xB2, 0xB2, 0xB2, 0x51, 0x51,
-  0x89, 0x89, 0xB2, 0xA3, 0x98, 0x66, 0xA3, 0x66,
-  0x98, 0x98, 0x98, 0x98, 0x98, 0x66, 0xA3, 0x2F,
-  0xA3, 0x2F, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2,
-  0xB2, 0x2F, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F,
-  0x2F, 0xB2, 0xB2, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F,
-  0x2F, 0xA3, 0x66, 0xA3, 0x2F, 0xB2, 0xB2, 0xB2,
-  0x51, 0x51, 0x89, 0x89, 0xB2, 0xA3, 0x98, 0x66
-};
-
-unsigned char linux_logo_bw[] __initdata = {
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F,
-  0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFE, 0x3F, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xC7, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xC3,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF,
-  0xFB, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFD, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF,
-  0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xF9, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xF9, 0xCF, 0xC3, 0xF8, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x87, 0x81, 0xF9,
-  0xF8, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xA7,
-  0x99, 0xF9, 0xC2, 0x40, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xF9, 0xF3, 0xBC, 0xF9, 0x90, 0x00, 0x1F, 0xFF,
-  0xFF, 0xFF, 0xF9, 0xE3, 0xBC, 0xF9, 0xA0, 0x00,
-  0x8F, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, 0x3C, 0xF9,
-  0x83, 0xE0, 0x2F, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0,
-  0x19, 0xF0, 0x1F, 0xFE, 0x0F, 0xFF, 0xFF, 0xFF,
-  0xF9, 0xC0, 0x03, 0xF0, 0x3F, 0xF7, 0x8F, 0xFF,
-  0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, 0x7F, 0xF7,
-  0xC7, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8,
-  0x6F, 0xF7, 0xE7, 0xFF, 0xFF, 0xFF, 0xF9, 0x80,
-  0x01, 0xF8, 0x7F, 0xF7, 0xE7, 0xFF, 0xFF, 0xFF,
-  0xF9, 0xC0, 0x21, 0xD8, 0x7F, 0xE7, 0xEF, 0xFF,
-  0xFF, 0xFF, 0xF9, 0xB1, 0x80, 0xEC, 0x7B, 0xFF,
-  0xEF, 0xFF, 0xFF, 0xFF, 0xF1, 0x90, 0x00, 0xE4,
-  0x7B, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xF1, 0x8C,
-  0xC0, 0x7C, 0x79, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF,
-  0xE3, 0x80, 0x00, 0x7C, 0x7C, 0xFF, 0xCF, 0xFF,
-  0xFF, 0xFF, 0xE3, 0x80, 0x00, 0x7F, 0x77, 0xFF,
-  0xDF, 0xFF, 0xFF, 0xFF, 0x87, 0x00, 0x00, 0x3F,
-  0x3F, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0x0E, 0x00,
-  0x00, 0x3F, 0xBF, 0xFF, 0x9F, 0xFF, 0xFF, 0xFF,
-  0x1E, 0x00, 0x00, 0x1F, 0x9F, 0xFF, 0x3F, 0xFF,
-  0xFF, 0xFE, 0x1C, 0x00, 0x00, 0x1F, 0x9F, 0xFF,
-  0x7F, 0xFF, 0xFF, 0xFE, 0x3C, 0x00, 0x00, 0x1F,
-  0x8F, 0xFE, 0x7F, 0xFF, 0xFF, 0xFC, 0x7C, 0x00,
-  0x00, 0x0F, 0xC7, 0xFC, 0xFF, 0xFF, 0xFF, 0xFC,
-  0xF8, 0x00, 0x00, 0x0F, 0xF7, 0xF9, 0xFF, 0xFF,
-  0xFF, 0xFC, 0xF8, 0x00, 0x00, 0x07, 0xFB, 0xF3,
-  0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0x00, 0x00, 0x07,
-  0xFD, 0xE7, 0xFF, 0xFF, 0xFF, 0xF9, 0xF0, 0x00,
-  0x00, 0x03, 0xFE, 0x8F, 0xFF, 0xFF, 0xFF, 0xF1,
-  0xF0, 0x00, 0x00, 0x03, 0xFE, 0x1F, 0xFF, 0xFF,
-  0xFF, 0xF1, 0xE0, 0x00, 0x00, 0x00, 0xFF, 0xBF,
-  0xFF, 0xFF, 0xFF, 0xE3, 0xE0, 0x00, 0x00, 0x00,
-  0xFE, 0xBF, 0xFF, 0xFF, 0xFF, 0xE3, 0xC0, 0x00,
-  0x00, 0x00, 0xFE, 0x3F, 0xFF, 0xFF, 0xFF, 0xC7,
-  0xC0, 0x00, 0x00, 0x01, 0xFE, 0xBF, 0xFF, 0xFF,
-  0xFF, 0xC7, 0x80, 0x00, 0x00, 0x01, 0xFE, 0x9F,
-  0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x00, 0x01,
-  0xFE, 0x07, 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00,
-  0x00, 0x01, 0xFE, 0x87, 0xFF, 0xFF, 0xFF, 0x9F,
-  0x80, 0x00, 0x00, 0x01, 0xFD, 0x33, 0xFF, 0xFF,
-  0xFF, 0x9F, 0x80, 0x00, 0x00, 0x01, 0x80, 0xF3,
-  0xFF, 0xFF, 0xFF, 0x9E, 0x80, 0x00, 0x00, 0x03,
-  0x8B, 0xF9, 0xFF, 0xFF, 0xFF, 0x9F, 0x80, 0x00,
-  0x00, 0x02, 0x27, 0xF8, 0xFF, 0xFF, 0xFF, 0x99,
-  0x80, 0x00, 0x00, 0x00, 0x07, 0xF8, 0xFF, 0xFF,
-  0xFF, 0x00, 0x80, 0x00, 0x00, 0x01, 0x8F, 0xF8,
-  0xFF, 0xFF, 0xFE, 0x20, 0x60, 0x00, 0x00, 0x00,
-  0xE3, 0xF8, 0xFF, 0xFF, 0xF8, 0x00, 0x30, 0x00,
-  0x00, 0x00, 0xF8, 0x78, 0xFF, 0xFF, 0xC0, 0x40,
-  0x38, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x7F, 0xFF,
-  0x81, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xFC, 0x20,
-  0x7F, 0xFF, 0x90, 0x00, 0x1E, 0x00, 0x00, 0x00,
-  0x78, 0x10, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0x80,
-  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00,
-  0x07, 0xC0, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF,
-  0xC0, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x04,
-  0x7F, 0xFF, 0x80, 0x00, 0x03, 0xC0, 0x00, 0x10,
-  0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x01, 0x80,
-  0x00, 0x30, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00,
-  0x00, 0x00, 0x00, 0x70, 0x00, 0x01, 0x4F, 0xFF,
-  0x80, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00,
-  0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x80, 0x03, 0xF0,
-  0x00, 0x00, 0x8F, 0xFF, 0x80, 0x00, 0x00, 0x40,
-  0x0F, 0xF0, 0x00, 0x04, 0x1F, 0xFF, 0x80, 0x00,
-  0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x10, 0x1F, 0xFF,
-  0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x40,
-  0xFF, 0xFF, 0x98, 0x00, 0x00, 0xFF, 0xFF, 0xF0,
-  0x00, 0x83, 0xFF, 0xFF, 0x81, 0xE0, 0x01, 0xFF,
-  0xFF, 0xF8, 0x02, 0x07, 0xFF, 0xFF, 0x80, 0x3F,
-  0x07, 0xE0, 0x00, 0x1C, 0x0C, 0x1F, 0xFF, 0xFF,
-  0xF8, 0x03, 0xFF, 0x80, 0x00, 0x1F, 0x78, 0x1F,
-  0xFF, 0xFF, 0xFF, 0x80, 0x7F, 0x00, 0x07, 0x0F,
-  0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0x0C, 0x07,
-  0xFF, 0x83, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0x00, 0x1F, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22,
+    0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+    0x26, 0x26, 0x25, 0x28, 0x23, 0x22, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x25, 0x2a, 0x2b, 0x2c, 0x2d, 0x2d,
+    0x2d, 0x2e, 0x2c, 0x2b, 0x2a, 0x25, 0x28, 0x22,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x24, 0x2a, 0x2c, 0x2f, 0x2c, 0x30, 0x30, 0x24,
+    0x25, 0x27, 0x2b, 0x2c, 0x2f, 0x31, 0x32, 0x25,
+    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
+    0x33, 0x34, 0x35, 0x21, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x21, 0x2b, 0x2f, 0x2c,
+    0x30, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
+    0x2d, 0x27, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x31,
+    0x2d, 0x32, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x2a, 0x34,
+    0x25, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x23, 0x32, 0x27, 0x21, 0x36,
+    0x2a, 0x2d, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x22, 0x26, 0x2c, 0x35,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x25, 0x2f, 0x37, 0x32, 0x22,
+    0x36, 0x35, 0x31, 0x27, 0x22, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x22,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x26, 0x38, 0x38, 0x35, 0x25,
+    0x36, 0x21, 0x2d, 0x2b, 0x24, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x24, 0x39, 0x39, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x25, 0x2b, 0x30, 0x28, 0x22,
+    0x36, 0x36, 0x27, 0x34, 0x30, 0x23, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x26, 0x2d, 0x26, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x22, 0x22, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x2d, 0x33, 0x28, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x2b, 0x2c, 0x25, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x36, 0x36,
+    0x36, 0x21, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x21, 0x23, 0x22, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x28, 0x34, 0x27, 0x22, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
+    0x21, 0x21, 0x24, 0x27, 0x21, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x28, 0x27, 0x22, 0x33, 0x24, 0x36,
+    0x36, 0x36, 0x36, 0x22, 0x2f, 0x2a, 0x23, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
+    0x30, 0x3a, 0x38, 0x24, 0x24, 0x36, 0x36, 0x36,
+    0x23, 0x2f, 0x3b, 0x3c, 0x3d, 0x30, 0x25, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2f, 0x32, 0x23, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x23,
+    0x3e, 0x3f, 0x40, 0x3a, 0x22, 0x36, 0x36, 0x21,
+    0x41, 0x42, 0x43, 0x44, 0x45, 0x3e, 0x23, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2f, 0x33, 0x28, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x2b,
+    0x44, 0x40, 0x46, 0x47, 0x35, 0x36, 0x36, 0x26,
+    0x43, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x2e, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x34, 0x36, 0x4d,
+    0x4e, 0x25, 0x2f, 0x46, 0x4a, 0x22, 0x23, 0x32,
+    0x4f, 0x50, 0x21, 0x31, 0x51, 0x52, 0x53, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x21, 0x3a,
+    0x4d, 0x21, 0x31, 0x54, 0x55, 0x28, 0x30, 0x2b,
+    0x4b, 0x4d, 0x36, 0x23, 0x32, 0x50, 0x3f, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x38, 0x23, 0x37,
+    0x55, 0x36, 0x28, 0x3a, 0x56, 0x57, 0x57, 0x58,
+    0x3c, 0x4d, 0x36, 0x36, 0x36, 0x40, 0x40, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x29, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x51, 0x23, 0x35,
+    0x43, 0x25, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
+    0x5f, 0x60, 0x61, 0x36, 0x31, 0x47, 0x3b, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x2c, 0x25, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x22,
+    0x40, 0x62, 0x63, 0x5d, 0x64, 0x65, 0x66, 0x67,
+    0x68, 0x69, 0x66, 0x5e, 0x6a, 0x6b, 0x2a, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x33, 0x2e, 0x26, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x2f, 0x23, 0x36,
+    0x6c, 0x63, 0x6d, 0x64, 0x5c, 0x66, 0x69, 0x6e,
+    0x6f, 0x70, 0x71, 0x69, 0x69, 0x72, 0x6c, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x33, 0x34, 0x27, 0x22,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x34, 0x26, 0x73,
+    0x74, 0x75, 0x76, 0x64, 0x65, 0x77, 0x69, 0x78,
+    0x70, 0x71, 0x71, 0x71, 0x72, 0x5f, 0x5e, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x25, 0x38, 0x2a, 0x23,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x33, 0x79,
+    0x63, 0x7a, 0x7b, 0x5c, 0x66, 0x69, 0x6e, 0x7c,
+    0x71, 0x71, 0x69, 0x7d, 0x7e, 0x7a, 0x7f, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x21, 0x51, 0x2b, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x32, 0x24,
+    0x80, 0x81, 0x64, 0x82, 0x77, 0x69, 0x71, 0x71,
+    0x69, 0x83, 0x84, 0x85, 0x7a, 0x85, 0x86, 0x36,
+    0x21, 0x2b, 0x23, 0x36, 0x36, 0x39, 0x2e, 0x26,
+    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x2d, 0x33, 0x21,
+    0x87, 0x88, 0x89, 0x72, 0x67, 0x66, 0x5f, 0x89,
+    0x8a, 0x63, 0x85, 0x8b, 0x8c, 0x8d, 0x41, 0x36,
+    0x36, 0x2d, 0x3a, 0x35, 0x36, 0x24, 0x51, 0x32,
+    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x33, 0x21,
+    0x55, 0x8e, 0x8f, 0x8a, 0x7d, 0x5e, 0x90, 0x7e,
+    0x75, 0x75, 0x90, 0x62, 0x40, 0x3f, 0x49, 0x23,
+    0x36, 0x24, 0x3a, 0x3a, 0x24, 0x36, 0x2e, 0x31,
+    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x21, 0x28, 0x33, 0x37, 0x25, 0x22,
+    0x3b, 0x50, 0x8e, 0x8f, 0x90, 0x7e, 0x90, 0x63,
+    0x74, 0x91, 0x92, 0x42, 0x93, 0x4b, 0x45, 0x2c,
+    0x36, 0x36, 0x33, 0x39, 0x21, 0x36, 0x22, 0x51,
+    0x33, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x22, 0x27, 0x2e, 0x2e, 0x36, 0x21,
+    0x94, 0x3f, 0x50, 0x95, 0x96, 0x8f, 0x8f, 0x97,
+    0x8e, 0x42, 0x50, 0x43, 0x47, 0x48, 0x48, 0x98,
+    0x21, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39,
+    0x2e, 0x27, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x22, 0x24, 0x2b, 0x38, 0x28, 0x36, 0x32,
+    0x4c, 0x4b, 0x50, 0x50, 0x50, 0x42, 0x42, 0x50,
+    0x50, 0x40, 0x45, 0x99, 0x48, 0x48, 0x48, 0x48,
+    0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x23,
+    0x2f, 0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x28, 0x32, 0x51, 0x32, 0x28, 0x21, 0x98,
+    0x48, 0x47, 0x9a, 0x50, 0x50, 0x50, 0x50, 0x50,
+    0x9a, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x93, 0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x2a, 0x2f, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x23, 0x30, 0x2e, 0x2c, 0x36, 0x21, 0x51, 0x9b,
+    0x48, 0x48, 0x52, 0x3f, 0x50, 0x50, 0x40, 0x4b,
+    0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2d, 0x31, 0x27, 0x23, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+    0x27, 0x2c, 0x2d, 0x21, 0x36, 0x28, 0x44, 0x48,
+    0x48, 0x48, 0x48, 0x47, 0x46, 0x4f, 0x47, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x9c, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x28, 0x51, 0x39, 0x26, 0x22, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
+    0x35, 0x51, 0x28, 0x36, 0x36, 0x9d, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x9b, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x4f, 0x28, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x28, 0x38, 0x2b, 0x25, 0x22, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
+    0x51, 0x25, 0x36, 0x36, 0x23, 0x40, 0x9b, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x9b, 0x99, 0x2b, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x30, 0x2f, 0x33, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x23, 0x30, 0x34,
+    0x27, 0x36, 0x36, 0x36, 0x2a, 0x40, 0x47, 0x48,
+    0x48, 0x48, 0x48, 0x9b, 0x99, 0x99, 0x9b, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x47, 0x52,
+    0x46, 0x4f, 0x37, 0x21, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x30, 0x34, 0x2a, 0x23,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x22, 0x25, 0x39, 0x2c,
+    0x36, 0x36, 0x36, 0x21, 0x31, 0x4e, 0x9a, 0x4c,
+    0x47, 0x9b, 0x9b, 0x52, 0x46, 0x4f, 0x52, 0x9b,
+    0x9b, 0x9b, 0x47, 0x4f, 0x45, 0x9a, 0x93, 0x93,
+    0x3f, 0x93, 0x98, 0x28, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c, 0x26,
+    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x28,
+    0x36, 0x36, 0x36, 0x22, 0x38, 0x98, 0x44, 0x99,
+    0x9b, 0x48, 0x48, 0x9b, 0x4c, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x47, 0x52, 0x46, 0x43, 0x93,
+    0x40, 0x40, 0x43, 0x53, 0x21, 0x23, 0x33, 0x23,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x2f, 0x32,
+    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x24, 0x2b, 0x31, 0x36,
+    0x36, 0x22, 0x36, 0x24, 0x9e, 0x4f, 0x9b, 0x48,
+    0x48, 0x48, 0x48, 0x9b, 0x99, 0x9f, 0x52, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x47,
+    0x4f, 0x9a, 0x3f, 0x46, 0x38, 0x36, 0x21, 0x30,
+    0x26, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c,
+    0x25, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x26, 0x2e, 0x33, 0x36,
+    0x25, 0x25, 0x36, 0x4d, 0x52, 0x48, 0x48, 0x48,
+    0x47, 0x9f, 0x48, 0x48, 0x48, 0xa0, 0xa1, 0xa2,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x47, 0x44, 0x93, 0x43, 0x23, 0x36, 0x36,
+    0x26, 0x24, 0x36, 0x36, 0x36, 0x36, 0x28, 0x2f,
+    0x2a, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x51, 0x24, 0x36,
+    0x2a, 0x36, 0x28, 0x44, 0x48, 0x48, 0x48, 0x48,
+    0xa3, 0xa4, 0x48, 0x48, 0x9f, 0xa5, 0xa6, 0x9f,
+    0x48, 0x48, 0x48, 0xa2, 0xa7, 0x47, 0x48, 0x48,
+    0x48, 0x48, 0x9b, 0x4b, 0x44, 0x37, 0x36, 0x23,
+    0x28, 0x30, 0x22, 0x36, 0x36, 0x36, 0x36, 0x2d,
+    0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x21, 0x28, 0x2b, 0x34, 0x36, 0x25,
+    0x24, 0x36, 0x4a, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0xa8, 0xa1, 0x48, 0x48, 0x9f, 0xa9, 0xa6, 0x9f,
+    0x48, 0x48, 0xaa, 0xa1, 0xa5, 0x9f, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x9b, 0x52, 0x3f, 0x21, 0x30,
+    0x35, 0x25, 0x30, 0x36, 0x36, 0x36, 0x36, 0x32,
+    0x2d, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x22, 0x26, 0x2e, 0x35, 0x36, 0x2a,
+    0x36, 0x24, 0x4f, 0x48, 0x52, 0x52, 0x48, 0x48,
+    0xab, 0xac, 0xa0, 0x48, 0xad, 0xa6, 0xa6, 0x9f,
+    0x48, 0xa2, 0xa9, 0xa6, 0xa2, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x47, 0x32, 0x30,
+    0x2a, 0x23, 0x30, 0x23, 0x36, 0x36, 0x36, 0x21,
+    0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x2a, 0x51, 0x28, 0x28, 0x25,
+    0x36, 0x3a, 0x48, 0x48, 0xae, 0xaf, 0x48, 0x48,
+    0xad, 0xac, 0xa1, 0x9f, 0xa2, 0xa9, 0xa9, 0xa2,
+    0x48, 0xab, 0x78, 0xa7, 0x48, 0x48, 0x48, 0x48,
+    0x9f, 0x48, 0x48, 0x48, 0x48, 0x48, 0x38, 0x21,
+    0x36, 0x36, 0x22, 0x27, 0x36, 0x36, 0x36, 0x36,
+    0x2e, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x22, 0x25, 0x2c, 0x34, 0x36, 0x30, 0x21,
+    0x23, 0x43, 0x48, 0x48, 0xb0, 0xb1, 0xb2, 0x9f,
+    0x48, 0xb3, 0xa5, 0xb3, 0xab, 0xa9, 0xa9, 0xb3,
+    0xb4, 0xa9, 0xb5, 0xb0, 0x48, 0x48, 0xa0, 0xa5,
+    0xa1, 0xad, 0x48, 0x48, 0x48, 0x48, 0x94, 0x36,
+    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
+    0x2a, 0x2e, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x2a, 0x51, 0x25, 0x21, 0x2a, 0x36,
+    0x2e, 0x9b, 0x48, 0x48, 0x48, 0xb6, 0xb7, 0xa4,
+    0xa2, 0xa7, 0xb5, 0x78, 0x6f, 0x6f, 0x6e, 0x6f,
+    0xa9, 0xb5, 0xab, 0x48, 0x9f, 0xab, 0xa9, 0xa1,
+    0xaa, 0x48, 0x48, 0x48, 0x48, 0x48, 0x98, 0x36,
+    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
+    0x22, 0x2f, 0x30, 0x22, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x22, 0x25, 0x2c, 0x34, 0x36, 0x24, 0x28, 0x36,
+    0x54, 0x48, 0x48, 0x48, 0x48, 0xa2, 0xa8, 0xa1,
+    0xa5, 0xa6, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f,
+    0x6f, 0x78, 0xa5, 0xa0, 0xa0, 0x78, 0xa6, 0xa2,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36,
+    0x36, 0x36, 0x36, 0x30, 0x36, 0x36, 0x36, 0x36,
+    0x21, 0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x28, 0x32, 0x2f, 0x28, 0x36, 0x27, 0x22, 0x21,
+    0x43, 0x48, 0x4b, 0xa2, 0x9f, 0x48, 0xa2, 0xa1,
+    0xb8, 0x6e, 0x6e, 0xb5, 0x78, 0x6f, 0x78, 0x78,
+    0x6e, 0x6f, 0x78, 0xb5, 0xa6, 0xa1, 0xa0, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4b, 0x21,
+    0x36, 0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x25, 0x2c, 0x39, 0x36, 0x36, 0x30, 0x22, 0x25,
+    0x52, 0x48, 0xa3, 0xb1, 0xb6, 0xb3, 0xaa, 0xac,
+    0x68, 0x68, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
+    0x78, 0x6f, 0x6f, 0xb5, 0xa6, 0xb4, 0x48, 0x9f,
+    0xb4, 0xb4, 0xa2, 0x9f, 0x48, 0x48, 0x4f, 0x21,
+    0x36, 0x36, 0x22, 0x26, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x30, 0x2d, 0x21, 0x36, 0x36, 0x32, 0x23, 0x2a,
+    0x47, 0x48, 0xa2, 0xb6, 0xaf, 0xb9, 0xba, 0x68,
+    0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x78,
+    0x6f, 0x6f, 0xa6, 0x6f, 0xb5, 0xa0, 0xaa, 0xa6,
+    0xa6, 0xa9, 0xb2, 0xb3, 0x48, 0x48, 0x4c, 0x22,
+    0x36, 0x36, 0x24, 0x23, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0x2e, 0x36, 0x36, 0x23, 0x31, 0x27, 0x39,
+    0x9b, 0x48, 0x48, 0x48, 0xb0, 0xb0, 0xba, 0xb8,
+    0x68, 0x68, 0x69, 0x78, 0x6f, 0xb5, 0x6f, 0xb5,
+    0x78, 0x78, 0x78, 0x78, 0x78, 0xa5, 0xbb, 0xa9,
+    0xa5, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4c, 0x23,
+    0x36, 0x36, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x2b, 0x39, 0x36, 0x36, 0x36, 0x26, 0x32, 0x31,
+    0x9b, 0x48, 0x48, 0x48, 0x48, 0x9f, 0xac, 0x68,
+    0xbc, 0x6e, 0x6e, 0x6e, 0xb5, 0x6f, 0x6e, 0x6f,
+    0x6f, 0x78, 0x78, 0xb5, 0xb5, 0xa5, 0x9f, 0x9f,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x46, 0x22,
+    0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x35, 0x39, 0x36, 0x36, 0x36, 0x36, 0x26, 0x2d,
+    0x9b, 0x48, 0x48, 0xb0, 0xaa, 0xb3, 0xbd, 0xb8,
+    0xb8, 0x68, 0x6e, 0x6e, 0xb5, 0x6f, 0x78, 0x6e,
+    0x78, 0x6f, 0x78, 0x78, 0xb5, 0xa9, 0xa2, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36,
+    0x24, 0x27, 0xbe, 0x24, 0x25, 0x28, 0x21, 0x36,
+    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x25,
+    0x39, 0x4d, 0xbf, 0x84, 0x81, 0x57, 0x21, 0x39,
+    0x52, 0x48, 0x48, 0x62, 0xb1, 0xc0, 0xc1, 0xc1,
+    0xb8, 0xb8, 0x68, 0xbc, 0x6e, 0x6e, 0x6e, 0x78,
+    0x78, 0x78, 0x78, 0x6e, 0x78, 0xa9, 0xa0, 0xab,
+    0xb3, 0xa2, 0x48, 0x48, 0x48, 0x48, 0x53, 0x28,
+    0x23, 0x36, 0x36, 0x36, 0x21, 0x28, 0x2c, 0x30,
+    0x21, 0x38, 0x33, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x28, 0x30,
+    0x2d, 0xc2, 0x7a, 0xc3, 0xc4, 0xc4, 0x7f, 0x22,
+    0x51, 0x52, 0x48, 0x48, 0xb0, 0xaa, 0xa8, 0xbd,
+    0x68, 0xb8, 0xb8, 0x68, 0x68, 0x6e, 0x6e, 0x6f,
+    0x6e, 0x6e, 0xb5, 0x6e, 0x78, 0xab, 0xab, 0xb5,
+    0x78, 0xa6, 0xb3, 0xc5, 0xac, 0xac, 0xc6, 0x61,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x30, 0x32,
+    0x25, 0x4d, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x24, 0x26, 0x30, 0x33, 0x31,
+    0x4d, 0x91, 0x5b, 0xc3, 0xc4, 0xc4, 0xc4, 0x5a,
+    0x21, 0x2e, 0x46, 0x48, 0x48, 0x48, 0xb0, 0x64,
+    0xc1, 0xb8, 0xb8, 0xb8, 0x68, 0x71, 0x6e, 0x6e,
+    0x6f, 0x71, 0x6f, 0x6f, 0xa6, 0xa0, 0x9f, 0xb4,
+    0xb4, 0xa0, 0xa1, 0xb7, 0xc7, 0x69, 0x66, 0xc8,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x26, 0x25,
+    0x83, 0xc9, 0x2c, 0x25, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x28, 0x30, 0x35, 0x2d, 0x2f, 0x37, 0x4a,
+    0x60, 0x85, 0xca, 0xcb, 0xc4, 0xc4, 0xc4, 0x82,
+    0x86, 0x36, 0x32, 0x3f, 0xa2, 0xa4, 0xa8, 0xa9,
+    0xb8, 0xb8, 0xb8, 0xb8, 0x68, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x71, 0x6f, 0x71, 0xa6, 0xb4, 0x9f, 0x9f,
+    0x48, 0x48, 0x48, 0xcc, 0xc3, 0xc7, 0xcd, 0xce,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x57,
+    0x77, 0x66, 0x34, 0x27, 0x22, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x23, 0x30, 0x31, 0xcf, 0x91, 0x7e, 0x90, 0x90,
+    0x8b, 0x5b, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0x5d, 0xd0, 0x36, 0x24, 0xd1, 0xb1, 0xaf, 0xaa,
+    0xba, 0xb8, 0x68, 0x68, 0x68, 0x71, 0x6e, 0x6e,
+    0x6e, 0x6f, 0x6e, 0x78, 0xa1, 0xa9, 0xa1, 0xb0,
+    0x9f, 0x9b, 0x99, 0xcc, 0x64, 0x5c, 0x8b, 0xd0,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x73, 0x5d,
+    0x82, 0x5c, 0xd2, 0x2a, 0x23, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x24, 0x2b, 0xcf, 0x8b, 0x5b, 0x76, 0x5b, 0x5b,
+    0x7b, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc7, 0x5e, 0x22, 0x36, 0x21, 0x3a, 0x99, 0x48,
+    0xa2, 0xa8, 0xb7, 0xc1, 0xb8, 0x68, 0x68, 0xbc,
+    0x68, 0x6e, 0xb5, 0xb4, 0xb4, 0xab, 0xb5, 0xa1,
+    0xb0, 0x4f, 0x3f, 0xd3, 0x7b, 0x7b, 0x85, 0x80,
+    0xbe, 0x36, 0x36, 0x36, 0x21, 0xd4, 0x7e, 0x7b,
+    0x64, 0x64, 0xd5, 0x35, 0x24, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x31, 0xd6, 0x5b, 0x64, 0xc3, 0xc3, 0xcb,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0x66, 0xd7, 0x36, 0x36, 0x36, 0x2c, 0x4b,
+    0xd8, 0xd9, 0xb3, 0xa8, 0xbd, 0xbd, 0xbd, 0xbd,
+    0xa9, 0xab, 0xb3, 0xa5, 0xa2, 0x9f, 0xa2, 0xa1,
+    0x6a, 0x9a, 0x3f, 0xda, 0x76, 0x76, 0x7a, 0x63,
+    0xdb, 0xdc, 0x86, 0xdc, 0xdd, 0x90, 0x5b, 0x64,
+    0xc3, 0xc3, 0xde, 0x2d, 0x27, 0x23, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x26, 0x2d, 0x91, 0x5b, 0x64, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc7, 0x83, 0xce, 0x36, 0x36, 0x36, 0x30,
+    0xb1, 0xd9, 0x48, 0xa1, 0xb2, 0xb0, 0xb0, 0xb3,
+    0xa2, 0x48, 0xa7, 0xbd, 0xa9, 0xa2, 0x48, 0x9f,
+    0xaa, 0x9a, 0x3f, 0xb1, 0x5b, 0x7b, 0xdf, 0x85,
+    0x7e, 0x90, 0x63, 0x90, 0x85, 0x5b, 0xc3, 0xc4,
+    0xc4, 0xcb, 0x5d, 0xd5, 0x39, 0x26, 0x23, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2d, 0xe0, 0xdf, 0x64, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc7, 0x88, 0x36, 0x36, 0x36, 0x36,
+    0x2d, 0x9b, 0x48, 0xb9, 0xaf, 0xa2, 0xa2, 0xb9,
+    0xa8, 0x9f, 0x48, 0xa7, 0xb7, 0xd9, 0x48, 0x48,
+    0x9b, 0x45, 0x3f, 0xe1, 0x6d, 0x7b, 0xca, 0xdf,
+    0x7a, 0x8b, 0x8b, 0x7a, 0x5b, 0x64, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc3, 0xe2, 0x37, 0x35, 0x26, 0x23,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2e, 0xe0, 0x7a, 0x7b, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc7, 0x72, 0x73, 0x36, 0x36, 0x36,
+    0x24, 0x52, 0x48, 0xa3, 0xaf, 0x9f, 0x48, 0xb6,
+    0xaf, 0xa2, 0x48, 0x9f, 0xe3, 0xd8, 0x48, 0x48,
+    0x48, 0x46, 0x42, 0xd6, 0x7a, 0x7b, 0x64, 0x7b,
+    0x76, 0x5b, 0x5b, 0x76, 0x7b, 0xc3, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xcb, 0x64, 0xe2, 0x4d, 0x2c, 0x27,
+    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x25, 0x31, 0xe4, 0x8b, 0x7b, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc7, 0x89, 0xbe, 0x36, 0x36,
+    0x32, 0x47, 0x48, 0x4f, 0xa0, 0x48, 0x48, 0xe3,
+    0x92, 0x9f, 0x48, 0x9f, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x4b, 0x2f, 0x8f, 0x7a, 0x7b, 0xc3, 0xcb,
+    0xc3, 0x64, 0x64, 0xc3, 0xc3, 0xcb, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0x5d, 0xe5, 0x2c,
+    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x25, 0x31, 0xe4, 0x85, 0x7b, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0x66, 0x57, 0x27, 0x4d,
+    0x4b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x99, 0x34, 0xbe, 0xdb, 0x7a, 0x7b, 0xc3, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0xe4,
+    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2d, 0xe4, 0x85, 0x7b, 0xcb, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc7, 0x5f, 0x92, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x44,
+    0x35, 0x36, 0xce, 0xdd, 0x7a, 0x7b, 0xcb, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0xc3, 0xe1,
+    0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+    0x30, 0x2f, 0xd6, 0x8b, 0x7b, 0xcb, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0x66, 0x89, 0x45,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x4e, 0x25,
+    0x36, 0x36, 0x61, 0xdb, 0x6d, 0x64, 0xcb, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0x7b, 0xdf, 0xe5,
+    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0xe6, 0x63, 0xdf, 0xc3, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0x72, 0x81, 0xe7,
+    0x46, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x3f, 0x2c, 0x36, 0x36,
+    0x36, 0x36, 0xe8, 0x8f, 0x6d, 0x64, 0xcb, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc3, 0xca, 0x8b, 0xcf, 0x2c,
+    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x35, 0x96, 0x75, 0xca, 0xc3, 0xcb, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0x7b, 0x81, 0xdb,
+    0x73, 0x3b, 0x44, 0x9b, 0x48, 0x48, 0x48, 0x9b,
+    0x99, 0x43, 0x94, 0x2c, 0x21, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x73, 0xdb, 0x7a, 0x7b, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0x64, 0x76, 0x7a, 0x91, 0xd5, 0x31, 0x30,
+    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x39, 0x97, 0x75, 0xdf, 0x7b, 0x64, 0xc3, 0xc3,
+    0xcb, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0x7b, 0x7a, 0xe9,
+    0xea, 0x36, 0x21, 0x26, 0x2b, 0x39, 0x33, 0x30,
+    0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xea, 0xdd, 0x8b, 0x7b, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0x64, 0x64,
+    0x76, 0x85, 0xe0, 0xd5, 0x34, 0x2b, 0x27, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0xeb, 0x63, 0x7e, 0x7a, 0x6d, 0xdf, 0x5b,
+    0x76, 0x7b, 0x64, 0x64, 0xc3, 0xcb, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0x76, 0x85, 0xdb,
+    0x79, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xec, 0xdd, 0x75, 0x76, 0xc3, 0xc4,
+    0xc4, 0xc4, 0xcb, 0xc3, 0x64, 0x76, 0xdf, 0x8b,
+    0xd6, 0xd5, 0x2f, 0x35, 0x30, 0x24, 0x22, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+    0x27, 0x31, 0xed, 0xeb, 0xdd, 0x74, 0x63, 0x90,
+    0x7e, 0x75, 0x8b, 0x6d, 0xdf, 0x76, 0x64, 0xc3,
+    0xcb, 0xcb, 0xcb, 0xcb, 0x64, 0x7a, 0x84, 0xee,
+    0x79, 0xbe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xea, 0xee, 0x63, 0x6d, 0x7b, 0x64,
+    0xcb, 0xc3, 0x64, 0x7b, 0xdf, 0x75, 0x63, 0x96,
+    0x38, 0x39, 0x2a, 0x24, 0x23, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x28, 0x27, 0x35, 0x2d, 0x41, 0xd5, 0xe7, 0x8f,
+    0xdb, 0xdd, 0xe9, 0x74, 0x84, 0x90, 0x85, 0x6d,
+    0x5b, 0x7b, 0x7b, 0xca, 0x6d, 0x90, 0xdb, 0xef,
+    0xec, 0x22, 0x36, 0x36, 0x28, 0x30, 0x30, 0x30,
+    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x25, 0x36,
+    0x36, 0x21, 0xd4, 0x80, 0xe9, 0x7e, 0x6d, 0x76,
+    0xca, 0x76, 0x6d, 0x85, 0x63, 0xdb, 0xd5, 0x34,
+    0x33, 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x24, 0x27, 0x2a, 0x35, 0x2e, 0x2f,
+    0x41, 0xf0, 0xf1, 0x6c, 0x80, 0xee, 0xdb, 0x74,
+    0x84, 0x90, 0x75, 0x7e, 0x74, 0x8f, 0xef, 0x79,
+    0xe8, 0x2b, 0x9d, 0x41, 0x2f, 0x34, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x2f, 0x38,
+    0x4d, 0x37, 0xf2, 0xf3, 0x8f, 0x74, 0x63, 0x7e,
+    0x75, 0x7e, 0x63, 0xe9, 0x88, 0xe6, 0x31, 0x2a,
+    0x24, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x21, 0x22, 0x23, 0x24, 0x26, 0x30,
+    0x33, 0x39, 0x2e, 0x51, 0x41, 0xd2, 0x6c, 0xf3,
+    0x80, 0xee, 0xee, 0xee, 0xf4, 0xf3, 0xd7, 0xf5,
+    0x41, 0x34, 0x35, 0x32, 0x30, 0x27, 0x27, 0x27,
+    0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x2a,
+    0x2b, 0x34, 0xf6, 0xec, 0xf7, 0x8f, 0xdd, 0xe9,
+    0xe9, 0xdd, 0xee, 0x6c, 0x41, 0x39, 0x27, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22,
+    0x28, 0x24, 0x26, 0x2a, 0x33, 0x2c, 0x2f, 0x41,
+    0xf8, 0xd7, 0x79, 0x79, 0x79, 0xec, 0xf9, 0x51,
+    0x39, 0x30, 0x24, 0x23, 0x22, 0x22, 0x22, 0x22,
+    0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23,
+    0x24, 0x2a, 0x31, 0xfa, 0xea, 0x79, 0xf3, 0x80,
+    0xf7, 0xdc, 0xfb, 0x2f, 0x35, 0x26, 0x23, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x22, 0x23, 0x28, 0x25, 0x30, 0x2b,
+    0x31, 0x2f, 0xf6, 0xfa, 0xfa, 0x2f, 0x2e, 0x33,
+    0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x28, 0x27, 0x35, 0x34, 0xfa, 0xfa, 0xfa,
+    0xfc, 0xf6, 0x2e, 0x33, 0x25, 0x23, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x23, 0x28,
+    0x26, 0x30, 0x32, 0x2b, 0x33, 0x2a, 0x26, 0x28,
+    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x25, 0x30, 0x33, 0x35, 0x35,
+    0x2b, 0x2a, 0x26, 0x28, 0x22, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x21, 0x22, 0x23, 0x28, 0x28, 0x23, 0x22, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x23, 0x28, 0x24, 0x24,
+    0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 };
 
-unsigned char linux_logo16_red[1];
-unsigned char linux_logo16_green[1];
-unsigned char linux_logo16_blue[1];
 unsigned char linux_logo16[1];
 
-#else
+#endif /* INCLUDE_LINUX_LOGO_DATA */
 
-/* prototypes only */
-extern unsigned char linux_logo_red[];
-extern unsigned char linux_logo_green[];
-extern unsigned char linux_logo_blue[];
-extern unsigned char linux_logo[];
-extern unsigned char linux_logo_bw[];
-extern unsigned char linux_logo16_red[];
-extern unsigned char linux_logo16_green[];
-extern unsigned char linux_logo16_blue[];
-extern unsigned char linux_logo16[];
+#include <linux/linux_logo.h>
 
-#endif
diff -u --recursive --new-file v2.4.5/linux/include/asm-sparc/socket.h linux/include/asm-sparc/socket.h
--- v2.4.5/linux/include/asm-sparc/socket.h	Sat Feb  3 11:26:44 2001
+++ linux/include/asm-sparc/socket.h	Wed Jun 20 21:00:55 2001
@@ -1,4 +1,4 @@
-/* $Id: socket.h,v 1.16 2001/01/30 07:48:30 davem Exp $ */
+/* $Id: socket.h,v 1.17 2001/06/13 16:25:03 davem Exp $ */
 #ifndef _ASM_SOCKET_H
 #define _ASM_SOCKET_H
 
@@ -63,6 +63,7 @@
 					/* level.  For writing rarp and	*/
 					/* other similar things on the	*/
 					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
 #endif
 
 #endif /* _ASM_SOCKET_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-sparc/softirq.h linux/include/asm-sparc/softirq.h
--- v2.4.5/linux/include/asm-sparc/softirq.h	Sun Aug  6 12:42:21 2000
+++ linux/include/asm-sparc/softirq.h	Tue Jun 12 11:08:46 2001
@@ -14,8 +14,21 @@
 #include <asm/hardirq.h>
 
 #define local_bh_disable()	(local_bh_count(smp_processor_id())++)
-#define local_bh_enable()	(local_bh_count(smp_processor_id())--)
-
+#define __local_bh_enable()	(local_bh_count(smp_processor_id())--)
+#define local_bh_enable()			  \
+do { if (!--local_bh_count(smp_processor_id()) && \
+	 softirq_pending(smp_processor_id())) {   \
+		do_softirq();			  \
+		__sti();			  \
+     }						  \
+} while (0)
+#define __cpu_raise_softirq(cpu, nr)	(softirq_pending(cpu) |= (1<<nr))
+#define raise_softirq(nr)				\
+do {	unsigned long flags;				\
+	local_irq_save(flags);				\
+	__cpu_raise_softirq(smp_processor_id(), nr);	\
+	local_irq_restore(flags);			\
+} while (0)
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
 #endif	/* __SPARC_SOFTIRQ_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-sparc/termios.h linux/include/asm-sparc/termios.h
--- v2.4.5/linux/include/asm-sparc/termios.h	Fri Feb  9 11:37:03 2001
+++ linux/include/asm-sparc/termios.h	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-/* $Id: termios.h,v 1.31 2001/02/05 05:54:29 davem Exp $ */
+/* $Id: termios.h,v 1.32 2001/06/01 08:12:11 davem Exp $ */
 #ifndef _SPARC_TERMIOS_H
 #define _SPARC_TERMIOS_H
 
@@ -70,6 +70,7 @@
 #define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
 #define N_HDLC		13	/* synchronous HDLC */
 #define N_SYNC_PPP	14	/* synchronous PPP */
+#define N_HCI		15  /* Bluetooth HCI UART */
 
 #ifdef __KERNEL__
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-sparc64/audioio.h linux/include/asm-sparc64/audioio.h
--- v2.4.5/linux/include/asm-sparc64/audioio.h	Tue Oct 10 10:33:52 2000
+++ linux/include/asm-sparc64/audioio.h	Mon Jun 11 19:15:27 2001
@@ -428,8 +428,6 @@
 extern int unregister_sparcaudio_driver(struct sparcaudio_driver *, int);
 extern void sparcaudio_output_done(struct sparcaudio_driver *, int);
 extern void sparcaudio_input_done(struct sparcaudio_driver *, int);
-extern int amd7930_init(void);
-extern int cs4231_init(void);
 
 #endif
 
diff -u --recursive --new-file v2.4.5/linux/include/asm-sparc64/auxio.h linux/include/asm-sparc64/auxio.h
--- v2.4.5/linux/include/asm-sparc64/auxio.h	Mon Dec 20 22:05:52 1999
+++ linux/include/asm-sparc64/auxio.h	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-/* $Id: auxio.h,v 1.2 1999/09/21 14:39:25 davem Exp $
+/* $Id: auxio.h,v 1.3 2001/06/05 08:16:34 davem Exp $
  * auxio.h:  Definitions and code for the Auxiliary I/O register.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -7,6 +7,7 @@
 #define _SPARC64_AUXIO_H
 
 #include <asm/system.h>
+#include <asm/io.h>
 
 /* FIXME: All of this should be checked for sun4u. It has /sbus/auxio, but
    I don't know whether it is the same and don't have a floppy */
diff -u --recursive --new-file v2.4.5/linux/include/asm-sparc64/bitops.h linux/include/asm-sparc64/bitops.h
--- v2.4.5/linux/include/asm-sparc64/bitops.h	Thu Apr 26 22:17:26 2001
+++ linux/include/asm-sparc64/bitops.h	Wed Jun 20 21:00:55 2001
@@ -1,4 +1,4 @@
-/* $Id: bitops.h,v 1.33 2001/04/24 01:09:12 davem Exp $
+/* $Id: bitops.h,v 1.36 2001/06/14 12:34:49 davem Exp $
  * bitops.h: Bit string operations on the V9.
  *
  * Copyright 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -20,13 +20,46 @@
 #define clear_bit(nr,addr)		((void)___test_and_clear_bit(nr,addr))
 #define change_bit(nr,addr)		((void)___test_and_change_bit(nr,addr))
 
-/* "non-atomic" versions, nothing special for now... */
-#define __set_bit(X,Y)		set_bit(X,Y)
-#define __clear_bit(X,Y)	clear_bit(X,Y)
-#define __change_bit(X,Y)	change_bit(X,Y)
-#define __test_and_set_bit(X,Y)		test_and_set_bit(X,Y)
-#define __test_and_clear_bit(X,Y)	test_and_clear_bit(X,Y)
-#define __test_and_change_bit(X,Y)	test_and_change_bit(X,Y)
+/* "non-atomic" versions... */
+#define __set_bit(X,Y)					\
+do {	unsigned long __nr = (X);			\
+	long *__m = ((long *) (Y)) + (__nr >> 6);	\
+	*__m |= (1UL << (__nr & 63));			\
+} while (0)
+#define __clear_bit(X,Y)				\
+do {	unsigned long __nr = (X);			\
+	long *__m = ((long *) (Y)) + (__nr >> 6);	\
+	*__m &= ~(1UL << (__nr & 63));			\
+} while (0)
+#define __change_bit(X,Y)				\
+do {	unsigned long __nr = (X);			\
+	long *__m = ((long *) (Y)) + (__nr >> 6);	\
+	*__m ^= (1UL << (__nr & 63));			\
+} while (0)
+#define __test_and_set_bit(X,Y)				\
+({	unsigned long __nr = (X);			\
+	long *__m = ((long *) (Y)) + (__nr >> 6);	\
+	long __old = *__m;				\
+	long __mask = (1UL << (__nr & 63));		\
+	*__m = (__old | __mask);			\
+	((__old & __mask) != 0);			\
+})
+#define __test_and_clear_bit(X,Y)			\
+({	unsigned long __nr = (X);			\
+	long *__m = ((long *) (Y)) + (__nr >> 6);	\
+	long __old = *__m;				\
+	long __mask = (1UL << (__nr & 63));		\
+	*__m = (__old & ~__mask);			\
+	((__old & __mask) != 0);			\
+})
+#define __test_and_change_bit(X,Y)			\
+({	unsigned long __nr = (X);			\
+	long *__m = ((long *) (Y)) + (__nr >> 6);	\
+	long __old = *__m;				\
+	long __mask = (1UL << (__nr & 63));		\
+	*__m = (__old ^ __mask);			\
+	((__old & __mask) != 0);			\
+})
 
 #define smp_mb__before_clear_bit()	do { } while(0)
 #define smp_mb__after_clear_bit()	do { } while(0)
diff -u --recursive --new-file v2.4.5/linux/include/asm-sparc64/hardirq.h linux/include/asm-sparc64/hardirq.h
--- v2.4.5/linux/include/asm-sparc64/hardirq.h	Wed Aug 23 09:30:13 2000
+++ linux/include/asm-sparc64/hardirq.h	Tue Jun 12 11:08:46 2001
@@ -13,8 +13,8 @@
 
 /* entry.S is sensitive to the offsets of these fields */
 typedef struct {
-	unsigned int __softirq_active;
-	unsigned int __softirq_mask;
+	unsigned int __softirq_pending;
+	unsigned int __unused_1;
 #ifndef CONFIG_SMP
 	unsigned int __local_irq_count;
 #else
diff -u --recursive --new-file v2.4.5/linux/include/asm-sparc64/linux_logo.h linux/include/asm-sparc64/linux_logo.h
--- v2.4.5/linux/include/asm-sparc64/linux_logo.h	Tue Aug  4 16:03:35 1998
+++ linux/include/asm-sparc64/linux_logo.h	Tue Jun 12 11:08:46 2001
@@ -1,4 +1,4 @@
-/* $Id: linux_logo.h,v 1.6 1998/07/30 16:30:48 jj Exp $
+/* $Id: linux_logo.h,v 1.7 2001/06/08 23:01:58 davem Exp $
  * include/asm-sparc64/linux_logo.h: This is a linux logo
  *                                   to be displayed on boot.
  *
@@ -23,1025 +23,912 @@
 
 #define linux_logo_banner "Linux/UltraSPARC version " UTS_RELEASE
 
-#define LINUX_LOGO_COLORS 219
+#define __HAVE_ARCH_LINUX_LOGO
+#define __HAVE_ARCH_LINUX_LOGO16
+
+#define LINUX_LOGO_COLORS	221
 
 #ifdef INCLUDE_LINUX_LOGO_DATA
 
 unsigned char linux_logo_red[] __initdata = {
-  0x03, 0x9E, 0xEC, 0xEE, 0xC4, 0xDA, 0x50, 0xC9,
-  0xC5, 0xED, 0x65, 0xE3, 0xE3, 0xF4, 0x24, 0xA4,
-  0xEC, 0xEE, 0x94, 0xE5, 0xE3, 0x6A, 0xA6, 0xC4,
-  0xDC, 0xE5, 0x13, 0xF3, 0xD1, 0xFD, 0xE2, 0xDB,
-  0xA0, 0xC2, 0xEC, 0xB8, 0xC2, 0xD5, 0xF2, 0xF4,
-  0xC5, 0x3E, 0xF1, 0x1B, 0x55, 0xF5, 0xCF, 0xF7,
-  0xA9, 0xB4, 0xEB, 0x6C, 0x0A, 0x74, 0xB4, 0xF7,
-  0xF0, 0xF5, 0xD4, 0xF2, 0xCE, 0xF5, 0xC7, 0x26,
-  0x5B, 0xF4, 0xBC, 0x7F, 0xAB, 0x82, 0x94, 0xE5,
-  0xFC, 0x3A, 0xF2, 0xFD, 0xF0, 0x1C, 0xEF, 0xD4,
-  0xF3, 0x0F, 0xED, 0xF7, 0xC9, 0x49, 0xC3, 0xBA,
-  0xC8, 0xD4, 0xE7, 0xF3, 0xF5, 0xA7, 0xEC, 0xF9,
-  0xFA, 0x0A, 0xF5, 0xCF, 0xFC, 0xEA, 0xE1, 0xA6,
-  0xD6, 0xBC, 0xF8, 0xF7, 0xB4, 0xEB, 0xDC, 0x84,
-  0xCE, 0xBA, 0x45, 0xD6, 0x86, 0x50, 0x96, 0xC6,
-  0x8C, 0x6E, 0xE8, 0x60, 0x3C, 0x70, 0xF0, 0x93,
-  0x7C, 0xDA, 0xDA, 0x9C, 0xBA, 0x6D, 0x4D, 0x2B,
-  0x2F, 0x8B, 0xE0, 0xCC, 0xDA, 0x5C, 0x3D, 0xEE,
-  0xDB, 0x46, 0xAC, 0x96, 0xCE, 0xD1, 0xE3, 0xF1,
-  0x96, 0x7A, 0x80, 0xB2, 0xBA, 0xB6, 0xD2, 0x1E,
-  0x7E, 0xAA, 0xC4, 0xF0, 0x96, 0x65, 0x9E, 0xC2,
-  0xAA, 0xF5, 0xF2, 0xE9, 0xE6, 0xD1, 0x35, 0xC7,
-  0xF6, 0xB6, 0xE8, 0x82, 0xBE, 0xC2, 0xF2, 0x9E,
-  0xC7, 0xB4, 0x0F, 0xF7, 0xE8, 0xD8, 0xCC, 0x9C,
-  0xD8, 0xD8, 0xA0, 0xEA, 0xC6, 0xA8, 0xE0, 0xEC,
-  0xD1, 0xF7, 0xF4, 0xFC, 0x75, 0xBD, 0xDC, 0xDD,
-  0xCC, 0xE1, 0xFA, 0xEE, 0xAA, 0xEC, 0xF2, 0xB8,
-  0xE2, 0xCD, 0x87
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
+    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
+    0xc3, 0x65, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
+    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
+    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x76, 0x79,
+    0x62, 0x36, 0x9a, 0xe2, 0xec, 0xe1, 0xb8, 0xd7,
+    0xaf, 0x25, 0xbc, 0xc0, 0xef, 0xea, 0xe8, 0xe8,
+    0xf5, 0xf1, 0xda, 0xd3, 0x79, 0xdb, 0xf4, 0xf6,
+    0xf6, 0xf6, 0xe2, 0x3d, 0xb4, 0xce, 0xe6, 0xee,
+    0xf6, 0x68, 0xd8, 0xec, 0xf5, 0xc6, 0xc8, 0x9c,
+    0x89, 0xd2, 0xee, 0xcb, 0xb9, 0xd2, 0x66, 0x5e,
+    0x8b, 0xbe, 0xa8, 0xd5, 0xca, 0xb6, 0xae, 0x9c,
+    0xc5, 0xbe, 0xbe, 0xca, 0x90, 0xb2, 0x9a, 0xa8,
+    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0xfe,
+    0xf6, 0xec, 0xfe, 0xd2, 0xea, 0xf5, 0xf2, 0xf2,
+    0xe9, 0xee, 0xf6, 0xf2, 0xee, 0xf6, 0xda, 0xd4,
+    0xfa, 0xca, 0xf2, 0xf6, 0xfe, 0xf2, 0xda, 0xe4,
+    0xf6, 0xdd, 0xf2, 0xee, 0xfa, 0xf0, 0x12, 0x4a,
+    0xd6, 0xf2, 0x8e, 0xf2, 0xf6, 0xf6, 0xb5, 0xf1,
+    0x26, 0x9a, 0xea, 0xf6, 0xe0, 0xd2, 0x16, 0x9a,
+    0x2e, 0xd2, 0x70, 0xd6, 0x46, 0x7c, 0xb4, 0x62,
+    0xda, 0xee, 0xd6, 0xa3, 0x74, 0xa7, 0xa2, 0xe0,
+    0xae, 0xbe, 0xce, 0xe2, 0xa3, 0x8e, 0x6d, 0x8e,
+    0x32, 0xaf, 0x50, 0x9e, 0x5b, 0x8a, 0x98, 0x82,
+    0x7a, 0x82, 0x56, 0x7c, 0x8a, 0x56, 0x5e, 0x86,
+    0x6a, 0x52, 0x59, 0x64, 0x5e,
 };
 
 unsigned char linux_logo_green[] __initdata = {
-  0x03, 0x88, 0xC4, 0xE2, 0x85, 0xC2, 0x44, 0xA3,
-  0xA9, 0xD3, 0x65, 0xA6, 0xC5, 0xF3, 0x24, 0xA4,
-  0xB4, 0xD6, 0x63, 0xD5, 0xB7, 0x44, 0x86, 0x94,
-  0xC2, 0xE4, 0x14, 0xB6, 0xD2, 0xFB, 0xD4, 0xB2,
-  0x73, 0x96, 0xDB, 0x92, 0xC2, 0x95, 0xC2, 0xDA,
-  0xA4, 0x36, 0xD4, 0x0E, 0x55, 0xF4, 0xC4, 0xE9,
-  0x75, 0xB4, 0xBC, 0x52, 0x0A, 0x74, 0x84, 0xEB,
-  0xDC, 0xDA, 0xA2, 0xD6, 0x9B, 0xBD, 0xB7, 0x12,
-  0x44, 0xCA, 0x8C, 0x65, 0x7B, 0x54, 0x94, 0xAB,
-  0xF4, 0x25, 0xC4, 0xFD, 0xE4, 0x1C, 0xDD, 0xAB,
-  0xBD, 0x06, 0xCB, 0xD6, 0xCA, 0x33, 0x8C, 0xA2,
-  0x92, 0x9C, 0xBC, 0xDB, 0xCD, 0x6E, 0xEC, 0xEE,
-  0xBC, 0x03, 0xDA, 0xCE, 0xF4, 0xB6, 0xDB, 0x92,
-  0xAD, 0xBC, 0xDE, 0xD5, 0x7B, 0xAE, 0x9D, 0x84,
-  0xB6, 0x96, 0x44, 0xBA, 0x6E, 0x3C, 0x7A, 0xB2,
-  0x8C, 0x4C, 0xCE, 0x4C, 0x3C, 0x5A, 0xCA, 0x6D,
-  0x7C, 0xCE, 0xDA, 0x9C, 0xAA, 0x6D, 0x4D, 0x2B,
-  0x1B, 0x5E, 0xCB, 0xAC, 0xBE, 0x5C, 0x2E, 0xDC,
-  0xBD, 0x3E, 0xAC, 0x82, 0xB6, 0xBE, 0xD3, 0xBD,
-  0x72, 0x62, 0x6C, 0x82, 0x92, 0x9E, 0xB0, 0x13,
-  0x4A, 0x8E, 0xBE, 0xCE, 0x86, 0x45, 0x6B, 0xAA,
-  0x9A, 0xC5, 0xC6, 0xDA, 0xC5, 0xC4, 0x34, 0x9B,
-  0xCC, 0xAC, 0xC4, 0x76, 0x9A, 0x9E, 0xEE, 0x62,
-  0xC6, 0x76, 0x0D, 0xE4, 0xDA, 0xD5, 0xA5, 0x92,
-  0xCD, 0xB2, 0x7C, 0xCC, 0xBE, 0x7E, 0xDC, 0xD6,
-  0xB9, 0xE3, 0xD4, 0xF6, 0x55, 0x82, 0xA4, 0xAA,
-  0x8D, 0xBB, 0xCE, 0xD5, 0x8A, 0xDB, 0xD4, 0x8B,
-  0xCA, 0x93, 0x63
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
+    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
+    0xc3, 0x62, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
+    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
+    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x62, 0x5c,
+    0x4e, 0x26, 0x72, 0xaa, 0xba, 0xaf, 0x90, 0xae,
+    0x92, 0x1a, 0xa4, 0x85, 0xb6, 0xbe, 0xc3, 0xc8,
+    0xcf, 0xd0, 0xc2, 0xce, 0x57, 0xa2, 0xd6, 0xda,
+    0xda, 0xd7, 0xb8, 0x2a, 0x7b, 0x91, 0xae, 0xca,
+    0xda, 0x45, 0x9e, 0xb2, 0xd7, 0x9b, 0x90, 0x76,
+    0x5c, 0xa2, 0xbe, 0xa6, 0x85, 0x96, 0x4e, 0x46,
+    0x66, 0x92, 0x7a, 0x9a, 0x96, 0x9d, 0x9a, 0x6b,
+    0x8a, 0x8e, 0xb2, 0xca, 0x90, 0xa6, 0x79, 0x7c,
+    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0xfa,
+    0xea, 0xd7, 0xf6, 0xbc, 0xda, 0xde, 0xda, 0xe6,
+    0xca, 0xd8, 0xea, 0xe0, 0xcc, 0xf2, 0xce, 0xb2,
+    0xee, 0xa2, 0xd6, 0xe6, 0xf6, 0xd7, 0xc5, 0xb8,
+    0xc6, 0xb9, 0xce, 0xde, 0xce, 0xc6, 0x0e, 0x36,
+    0xae, 0xbe, 0x86, 0xba, 0xbe, 0xe6, 0x8e, 0xc4,
+    0x1e, 0x8e, 0xae, 0xba, 0xb2, 0xa6, 0x12, 0x7a,
+    0x20, 0xc6, 0x64, 0xaa, 0x2f, 0x70, 0x85, 0x46,
+    0xce, 0xd6, 0xa6, 0x6e, 0x51, 0x72, 0x92, 0xa6,
+    0x87, 0x96, 0xa2, 0xd6, 0x85, 0x7a, 0x6a, 0x6e,
+    0x22, 0x76, 0x36, 0x76, 0x3c, 0x6e, 0x63, 0x53,
+    0x66, 0x62, 0x42, 0x50, 0x56, 0x42, 0x56, 0x56,
+    0x56, 0x3e, 0x51, 0x52, 0x56,
 };
 
 unsigned char linux_logo_blue[] __initdata = {
-  0x04, 0x28, 0x10, 0x8C, 0x0B, 0x84, 0x14, 0x1A,
-  0x77, 0x1F, 0x64, 0x0E, 0x85, 0xD2, 0x24, 0xA4,
-  0x0F, 0x54, 0x0C, 0x7C, 0x3F, 0x04, 0x20, 0x0D,
-  0x54, 0xDF, 0x14, 0x0D, 0xD1, 0xE9, 0xB0, 0x11,
-  0x0A, 0x40, 0x57, 0x14, 0xC3, 0x0C, 0x04, 0x12,
-  0x50, 0x0C, 0x7D, 0x05, 0x55, 0xF2, 0xBA, 0xC7,
-  0x09, 0xB4, 0x0E, 0x24, 0x0B, 0x74, 0x0C, 0xB6,
-  0x80, 0x48, 0x10, 0x34, 0x0F, 0x0C, 0xA0, 0x04,
-  0x19, 0x10, 0x0E, 0x14, 0x0E, 0x05, 0x94, 0x0E,
-  0xCA, 0x0B, 0x46, 0xFB, 0xB4, 0x1C, 0x9B, 0x1A,
-  0x21, 0x09, 0x14, 0x4D, 0xCB, 0x08, 0x11, 0x7C,
-  0x20, 0x10, 0x24, 0x66, 0x79, 0x07, 0xEA, 0xC9,
-  0x0C, 0x08, 0x38, 0xC4, 0xD8, 0x24, 0xBE, 0x6C,
-  0x51, 0xBB, 0x8C, 0x36, 0x0A, 0x0F, 0x0C, 0x84,
-  0x3C, 0x54, 0x44, 0x7C, 0x28, 0x0E, 0x28, 0x7F,
-  0x8C, 0x0F, 0x54, 0x24, 0x3C, 0x18, 0x54, 0x17,
-  0x7C, 0x9C, 0xDA, 0x9C, 0x7C, 0x6C, 0x4D, 0x2C,
-  0x09, 0x0E, 0x8A, 0x50, 0x4C, 0x5B, 0x14, 0xAC,
-  0x19, 0x3C, 0xAC, 0x5C, 0x64, 0x97, 0x94, 0x37,
-  0x29, 0x3C, 0x44, 0x3C, 0x2C, 0x7C, 0x70, 0x07,
-  0x04, 0x29, 0xB2, 0x64, 0x74, 0x07, 0x07, 0x2C,
-  0x74, 0x2E, 0x6C, 0xA4, 0x29, 0x9E, 0x34, 0x27,
-  0x2F, 0x98, 0x48, 0x5C, 0x0C, 0x5C, 0xE8, 0x04,
-  0xC2, 0x0C, 0x0A, 0xB2, 0x74, 0xCB, 0x46, 0x78,
-  0xB4, 0x5C, 0x18, 0x80, 0x8C, 0x24, 0xD9, 0xAC,
-  0x87, 0x99, 0x1D, 0xE8, 0x14, 0x0D, 0x10, 0x17,
-  0x0A, 0x67, 0x3C, 0x68, 0x3C, 0x69, 0x90, 0x22,
-  0x6C, 0x0D, 0x17
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x01, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x06, 0x65,
+    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
+    0xc3, 0x59, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
+    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
+    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x2e, 0x08,
+    0x0a, 0x06, 0x0a, 0x0b, 0x0b, 0x0f, 0x0c, 0x0f,
+    0x3d, 0x09, 0x73, 0x09, 0x0d, 0x0a, 0x10, 0x1e,
+    0x2d, 0x13, 0x86, 0xba, 0x19, 0x0a, 0x36, 0x3c,
+    0x26, 0x14, 0x0d, 0x06, 0x07, 0x0a, 0x0b, 0x0f,
+    0x4a, 0x06, 0x0a, 0x0c, 0x2b, 0x0a, 0x0b, 0x0a,
+    0x06, 0x0a, 0x0a, 0x11, 0x0b, 0x0a, 0x0a, 0x1e,
+    0x0f, 0x0d, 0x0a, 0x0b, 0x22, 0x6a, 0x72, 0x0b,
+    0x0b, 0x22, 0x90, 0xca, 0x90, 0x92, 0x3c, 0x2c,
+    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0xea,
+    0xb6, 0x7c, 0xda, 0x8e, 0xa6, 0x87, 0x66, 0xb6,
+    0x81, 0x6a, 0xc6, 0x9a, 0x5b, 0xd2, 0xb6, 0x6a,
+    0xca, 0x45, 0x92, 0xb2, 0xca, 0x52, 0x8a, 0x3e,
+    0x2e, 0x66, 0x66, 0xae, 0x3e, 0x47, 0x06, 0x0e,
+    0x52, 0x36, 0x6a, 0x0e, 0x0e, 0xbe, 0x2c, 0x0e,
+    0x0a, 0x5a, 0x0d, 0x0e, 0x3e, 0x0a, 0x06, 0x2e,
+    0x06, 0x9e, 0x4e, 0x36, 0x06, 0x58, 0x24, 0x06,
+    0x9e, 0xae, 0x3a, 0x08, 0x08, 0x07, 0x5e, 0x0a,
+    0x32, 0x2e, 0x2a, 0xb2, 0x43, 0x48, 0x5f, 0x2e,
+    0x06, 0x06, 0x07, 0x24, 0x06, 0x32, 0x06, 0x06,
+    0x46, 0x2e, 0x22, 0x06, 0x06, 0x1e, 0x4c, 0x06,
+    0x3a, 0x22, 0x42, 0x34, 0x42,
 };
 
 unsigned char linux_logo[] __initdata = {
-  0xD8, 0xA3, 0x98, 0x98, 0xA3, 0xB2, 0x2F, 0x2F,
-  0xA3, 0x66, 0x98, 0x98, 0x98, 0xA3, 0x2F, 0xA3,
-  0x98, 0x55, 0xA0, 0xA3, 0xB2, 0x51, 0x51, 0x2F,
-  0x98, 0x55, 0x8F, 0x2F, 0x89, 0x44, 0x89, 0x51,
-  0xB2, 0x2F, 0x66, 0xA3, 0x2F, 0x2F, 0x66, 0x66,
-  0xA3, 0xB2, 0xB2, 0xB2, 0x89, 0xD8, 0x44, 0x44,
-  0xD8, 0x83, 0xD8, 0xA3, 0x98, 0x98, 0xA3, 0xB2,
-  0x2F, 0x2F, 0xA3, 0x66, 0x98, 0x98, 0x98, 0xA3,
-  0x2F, 0xA3, 0x98, 0x55, 0xA0, 0xA3, 0xB2, 0x51,
-  0x51, 0x2F, 0x98, 0x55, 0x8F, 0x2F, 0x89, 0x44,
-  0xA3, 0x55, 0x55, 0x98, 0x2F, 0x2F, 0x2F, 0xA3,
-  0x66, 0x66, 0x98, 0x98, 0x66, 0x66, 0x66, 0x98,
-  0x55, 0xA5, 0x8F, 0xA3, 0x51, 0x51, 0xB2, 0x2F,
-  0x66, 0x66, 0xA3, 0x51, 0x89, 0x51, 0xB2, 0x2F,
-  0x2F, 0xA3, 0x66, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F,
-  0xB2, 0xB2, 0x2F, 0x2F, 0xB2, 0x51, 0x51, 0x51,
-  0x51, 0x51, 0xA3, 0x55, 0x55, 0x98, 0x2F, 0x2F,
-  0x2F, 0xA3, 0x66, 0x66, 0x98, 0x98, 0x66, 0x66,
-  0x66, 0x98, 0x55, 0xA5, 0x8F, 0xA3, 0x51, 0x51,
-  0xB2, 0x2F, 0x66, 0x66, 0xA3, 0x51, 0x89, 0x51,
-  0x98, 0xA5, 0x55, 0x8F, 0x2F, 0xB2, 0x2F, 0xA3,
-  0x66, 0x66, 0x98, 0x8F, 0x66, 0x66, 0x66, 0x98,
-  0xA0, 0x8F, 0xA3, 0xB2, 0x51, 0x51, 0xB2, 0x2F,
-  0xA3, 0xA3, 0x2F, 0xB2, 0x51, 0xB2, 0x2F, 0x2F,
-  0xA3, 0x66, 0x98, 0xA3, 0x51, 0xB2, 0x2F, 0xA3,
-  0xB2, 0x51, 0x51, 0xB2, 0xB2, 0x51, 0xB2, 0xB2,
-  0xB2, 0x2F, 0x98, 0xA5, 0x55, 0x8F, 0x2F, 0xB2,
-  0x2F, 0xA3, 0x66, 0x66, 0x98, 0x8F, 0x66, 0x66,
-  0x66, 0x98, 0xA0, 0x8F, 0xA3, 0xB2, 0x51, 0x51,
-  0xB2, 0x2F, 0xA3, 0xA3, 0x2F, 0x51, 0x51, 0xB2,
-  0xA0, 0xA5, 0x55, 0x66, 0xB2, 0x51, 0xB2, 0xA3,
-  0x66, 0x66, 0x98, 0x66, 0x66, 0x66, 0x98, 0x98,
-  0x66, 0xA3, 0x2F, 0xB2, 0x51, 0x51, 0xB2, 0xA3,
-  0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0xA3,
-  0x66, 0x98, 0xB2, 0x4C, 0x54, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xCE, 0x2F, 0xB2, 0x2F, 0x2F,
-  0xA3, 0x98, 0xA0, 0xA5, 0x55, 0x66, 0xB2, 0x51,
-  0xB2, 0xA3, 0x66, 0x66, 0x98, 0x66, 0x66, 0x66,
-  0x98, 0x98, 0x66, 0xA3, 0x2F, 0xB2, 0x51, 0x51,
-  0xB2, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F,
-  0xA0, 0xA0, 0x8F, 0xA3, 0xB2, 0x51, 0xB2, 0x2F,
-  0x66, 0x66, 0x98, 0x66, 0x66, 0x66, 0x66, 0x66,
-  0xA3, 0x2F, 0x51, 0x51, 0x51, 0xB2, 0x2F, 0xA3,
-  0x66, 0x66, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3,
-  0x2F, 0xA0, 0xDA, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x9C, 0xB2, 0xA3,
-  0x66, 0x98, 0xA0, 0xA0, 0x8F, 0xA3, 0xB2, 0x51,
-  0xB2, 0x2F, 0x66, 0x66, 0x98, 0x66, 0x66, 0x66,
-  0x66, 0x66, 0xA3, 0x2F, 0x51, 0x51, 0x51, 0xB2,
-  0x2F, 0xA3, 0x66, 0x66, 0x66, 0xA3, 0xA3, 0xA3,
-  0x8F, 0x8F, 0x66, 0x2F, 0x51, 0x51, 0xB2, 0xA3,
-  0x66, 0x98, 0x98, 0x66, 0x66, 0x66, 0x2F, 0x2F,
-  0xB2, 0x51, 0xB2, 0xB2, 0x2F, 0x2F, 0xA3, 0x66,
-  0x66, 0x66, 0xA3, 0xA3, 0x2F, 0xA3, 0xA3, 0xB2,
-  0x9C, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xDA, 0x3A, 0x20, 0x54, 0x55,
-  0xA3, 0x98, 0x8F, 0x8F, 0x66, 0x2F, 0x51, 0x51,
-  0xB2, 0xA3, 0x66, 0x98, 0x98, 0x66, 0x66, 0x66,
-  0x2F, 0x2F, 0xB2, 0x51, 0xB2, 0xB2, 0x2F, 0x2F,
-  0xA3, 0x66, 0x66, 0x66, 0x2F, 0xA3, 0x2F, 0x2F,
-  0x66, 0x66, 0xA3, 0x2F, 0xB2, 0xB2, 0x2F, 0x66,
-  0x8F, 0x8F, 0x8F, 0x66, 0xA3, 0xA3, 0xB2, 0xB2,
-  0xB2, 0xB2, 0xB2, 0xB2, 0x2F, 0xA3, 0xA3, 0xA3,
-  0xA3, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0xAD,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xA7, 0x4C, 0xCE, 0xDA, 0x20,
-  0xA6, 0x2F, 0x66, 0x66, 0xA3, 0x2F, 0xB2, 0xB2,
-  0x2F, 0x66, 0x8F, 0x8F, 0x8F, 0x66, 0xA3, 0xA3,
-  0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0x2F, 0xA3,
-  0xA3, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F,
-  0xA3, 0x98, 0x66, 0x2F, 0xB2, 0xB2, 0x2F, 0x98,
-  0x8F, 0x8F, 0x98, 0x66, 0xA3, 0xB2, 0xB2, 0xB2,
-  0x2F, 0x2F, 0x2F, 0x2F, 0xA3, 0x2F, 0xA3, 0xA3,
-  0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0x51, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xCE, 0x55, 0xAD, 0xA7, 0x54,
-  0x20, 0x8F, 0xA3, 0x98, 0x66, 0x2F, 0xB2, 0xB2,
-  0x2F, 0x98, 0x8F, 0x8F, 0x98, 0x66, 0xA3, 0xB2,
-  0xB2, 0xB2, 0x2F, 0x2F, 0x2F, 0x2F, 0xA3, 0x2F,
-  0xA3, 0xA3, 0xA3, 0x2F, 0xA3, 0xA3, 0xA3, 0xA3,
-  0xA3, 0x8F, 0x66, 0x2F, 0xB2, 0x51, 0x2F, 0x98,
-  0xA0, 0x8F, 0x66, 0xA3, 0x2F, 0x51, 0x51, 0xB2,
-  0xA3, 0xA3, 0xA3, 0x2F, 0xA3, 0xA3, 0x66, 0x66,
-  0x98, 0x98, 0x98, 0x66, 0x98, 0x66, 0x55, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xCE, 0x4C, 0x9C, 0x2E, 0xDA,
-  0x20, 0xDA, 0x51, 0x8F, 0x66, 0x2F, 0xB2, 0x51,
-  0x2F, 0x98, 0xA0, 0x8F, 0x66, 0xA3, 0x2F, 0x51,
-  0x51, 0xB2, 0xA3, 0xA3, 0xA3, 0x2F, 0xA3, 0xA3,
-  0x66, 0x66, 0x98, 0x98, 0x98, 0x98, 0x98, 0x66,
-  0x51, 0x66, 0x2F, 0xB2, 0x51, 0xB2, 0xA3, 0xA0,
-  0xA0, 0x66, 0xA3, 0xB2, 0xB2, 0xB2, 0xB2, 0xA3,
-  0x66, 0x66, 0x66, 0xA3, 0xA3, 0x66, 0x98, 0x98,
-  0x98, 0x98, 0x98, 0x66, 0x66, 0xB2, 0x6D, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x6D, 0x3A, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0xA5, 0x66, 0x2F, 0xB2, 0x51, 0xB2,
-  0xA3, 0xA0, 0xA0, 0x66, 0xA3, 0xB2, 0xB2, 0xB2,
-  0xB2, 0xA3, 0x66, 0x66, 0x66, 0xA3, 0xA3, 0x66,
-  0x98, 0x98, 0x8F, 0x98, 0x66, 0x66, 0x66, 0x66,
-  0x51, 0x2F, 0xB2, 0x51, 0x51, 0x2F, 0x66, 0xA0,
-  0x8F, 0xA3, 0x2F, 0xB2, 0xB2, 0x2F, 0x2F, 0x66,
-  0x98, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
-  0x66, 0x2F, 0xA3, 0x2F, 0x2F, 0x51, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0xDA, 0x51, 0xB2, 0x51, 0x51, 0x2F,
-  0x66, 0xA0, 0x8F, 0xA3, 0x2F, 0xB2, 0xB2, 0x2F,
-  0x2F, 0x66, 0x98, 0x66, 0x66, 0x66, 0x66, 0x66,
-  0x66, 0x66, 0x66, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F,
-  0x51, 0x2F, 0xB2, 0x51, 0x2F, 0xA3, 0x8F, 0x8F,
-  0x98, 0xA3, 0xB2, 0xB2, 0x2F, 0xA3, 0x98, 0x66,
-  0x98, 0x98, 0x66, 0x66, 0x66, 0x66, 0xA3, 0x2F,
-  0xB2, 0xB2, 0x51, 0xB2, 0xB2, 0x66, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xA3, 0xB2, 0x51, 0x2F, 0xA3,
-  0x8F, 0x8F, 0x98, 0xA3, 0xB2, 0xB2, 0x2F, 0xA3,
-  0x98, 0x66, 0x98, 0x98, 0x66, 0x66, 0x66, 0x66,
-  0xA3, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2,
-  0xB2, 0x2F, 0xA3, 0x2F, 0x66, 0x98, 0x8F, 0x98,
-  0xA3, 0x2F, 0x2F, 0xA3, 0x98, 0x98, 0x98, 0x98,
-  0x66, 0x98, 0x66, 0x98, 0x66, 0xA3, 0x2F, 0xB2,
-  0x51, 0x51, 0x51, 0xB2, 0xB2, 0x8F, 0x20, 0x20,
-  0x20, 0x54, 0x6D, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x54, 0x6D, 0x6D, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x4C, 0xA3, 0x2F, 0x66, 0x98,
-  0x8F, 0x98, 0xA3, 0x2F, 0x2F, 0xA3, 0x98, 0x98,
-  0x98, 0x98, 0x66, 0x98, 0x66, 0x98, 0x66, 0xA3,
-  0x2F, 0xB2, 0x51, 0x51, 0x51, 0xB2, 0x2F, 0x2F,
-  0x2F, 0xA3, 0xA3, 0x66, 0x98, 0x98, 0x8F, 0x98,
-  0x2F, 0x2F, 0x2F, 0x66, 0x8F, 0x8F, 0x98, 0xA3,
-  0x66, 0x66, 0x8F, 0x98, 0x98, 0x66, 0x2F, 0xB2,
-  0x51, 0xB2, 0x2F, 0xA3, 0xA3, 0xA0, 0x20, 0x20,
-  0xDA, 0x2E, 0x3A, 0xA7, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0xCE, 0x2A, 0x2A, 0x2E, 0xA7, 0xDA, 0x20,
-  0x20, 0x20, 0x20, 0x9C, 0xA3, 0x66, 0x98, 0x98,
-  0x8F, 0x98, 0x2F, 0x2F, 0x2F, 0x66, 0x8F, 0x8F,
-  0x98, 0xA3, 0x66, 0x66, 0x8F, 0x98, 0x98, 0x66,
-  0x2F, 0xB2, 0x51, 0xB2, 0x2F, 0x2F, 0xA3, 0xA3,
-  0xB2, 0xA3, 0x66, 0x98, 0x8F, 0x8F, 0x66, 0xA3,
-  0x2F, 0x2F, 0x66, 0x98, 0x98, 0x66, 0x2F, 0x2F,
-  0xA3, 0x98, 0x8F, 0x98, 0x66, 0x2F, 0xB2, 0xB2,
-  0xB2, 0xA3, 0x66, 0x66, 0x66, 0x98, 0x20, 0x3A,
-  0x98, 0x89, 0x8F, 0x6D, 0x20, 0x20, 0x20, 0x20,
-  0x4C, 0x66, 0x51, 0x44, 0x51, 0x2E, 0x54, 0x20,
-  0x20, 0x20, 0x20, 0xA7, 0x66, 0x98, 0x8F, 0x8F,
-  0x66, 0xA3, 0x2F, 0x2F, 0x66, 0x98, 0x98, 0x66,
-  0x2F, 0x2F, 0xA3, 0x98, 0x8F, 0x98, 0x66, 0x2F,
-  0xB2, 0xB2, 0xB2, 0xA3, 0x66, 0x66, 0x66, 0xA3,
-  0x2F, 0x66, 0x98, 0x8F, 0x8F, 0x98, 0x66, 0x2F,
-  0x2F, 0xA3, 0x66, 0x98, 0x98, 0xA3, 0x2F, 0xB2,
-  0xA3, 0x8F, 0x98, 0xA3, 0xB2, 0x51, 0x89, 0x89,
-  0xB2, 0xA3, 0x66, 0x98, 0x66, 0x98, 0x20, 0xA6,
-  0x44, 0x39, 0xE6, 0x98, 0x20, 0x20, 0x20, 0x9C,
-  0x74, 0xD6, 0x7E, 0xD6, 0x39, 0x8F, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x2E, 0x98, 0x8F, 0x8F, 0x98,
-  0x66, 0x2F, 0x2F, 0xA3, 0x66, 0x98, 0x98, 0xA3,
-  0x2F, 0xB2, 0x66, 0x98, 0x8F, 0xA3, 0xB2, 0x51,
-  0x89, 0x89, 0xB2, 0xA3, 0x66, 0x98, 0x66, 0x66,
-  0x2F, 0x66, 0x8F, 0xA0, 0x8F, 0x98, 0xA3, 0xB2,
-  0x2F, 0x66, 0x66, 0x66, 0xA3, 0x2F, 0x2F, 0x2F,
-  0x66, 0x98, 0xA3, 0xB2, 0x89, 0x44, 0x89, 0x51,
-  0x2F, 0x66, 0x98, 0x98, 0xA3, 0x66, 0x20, 0x2F,
-  0x2F, 0xAD, 0x89, 0xD6, 0x3A, 0x20, 0x20, 0x55,
-  0x6B, 0x51, 0x6D, 0x4C, 0xD8, 0xD6, 0x2E, 0x20,
-  0x20, 0x20, 0x20, 0x54, 0x8F, 0xA0, 0x8F, 0x98,
-  0xA3, 0xB2, 0x2F, 0x66, 0x66, 0x66, 0xA3, 0x2F,
-  0xB2, 0x2F, 0x66, 0x66, 0xA3, 0xB2, 0x89, 0x44,
-  0x89, 0x51, 0x2F, 0x66, 0x98, 0x98, 0xA3, 0xA3,
-  0xA3, 0x66, 0x8F, 0xA0, 0x8F, 0x66, 0x2F, 0xB2,
-  0xA3, 0x66, 0x98, 0x66, 0xA3, 0x2F, 0x2F, 0xA3,
-  0xA3, 0x2F, 0xB2, 0x89, 0xD8, 0xD8, 0x51, 0x66,
-  0x8F, 0xA0, 0xA0, 0x8F, 0x98, 0xA3, 0x20, 0x44,
-  0xA7, 0xCE, 0xA6, 0x4D, 0xCE, 0x6D, 0xA7, 0xA0,
-  0x6B, 0xA7, 0x20, 0x92, 0xAD, 0x6B, 0x4C, 0x20,
-  0x20, 0x20, 0x20, 0x54, 0x98, 0xA0, 0x8F, 0x66,
-  0x2F, 0xB2, 0xA3, 0x66, 0x98, 0x66, 0xA3, 0x2F,
-  0x2F, 0xA3, 0xA3, 0xA3, 0xB2, 0x89, 0xD8, 0xD8,
-  0x51, 0x66, 0x8F, 0xA0, 0xA0, 0x8F, 0x98, 0x66,
-  0x66, 0x66, 0x8F, 0x55, 0x8F, 0xA3, 0xB2, 0xB2,
-  0xA3, 0x66, 0x66, 0xA3, 0x2F, 0xA3, 0xA3, 0xA3,
-  0xA3, 0xB2, 0x89, 0x44, 0x44, 0x51, 0x66, 0xA0,
-  0x55, 0xA5, 0x55, 0x8F, 0x66, 0xA3, 0x20, 0x44,
-  0x6D, 0x54, 0xA7, 0x74, 0x2E, 0x4B, 0xBF, 0x9C,
-  0x7E, 0xDA, 0x20, 0x54, 0x2E, 0x6B, 0x2A, 0x20,
-  0x20, 0x20, 0x20, 0x3A, 0x8F, 0x55, 0x8F, 0xA3,
-  0xB2, 0xB2, 0xA3, 0x66, 0x66, 0xA3, 0xA3, 0x2F,
-  0xA3, 0xA3, 0xA3, 0xB2, 0x89, 0x44, 0x44, 0x51,
-  0x66, 0xA0, 0xA5, 0xA5, 0x55, 0x8F, 0x66, 0x66,
-  0xA0, 0xA0, 0xA0, 0xA0, 0x8F, 0xA3, 0x2F, 0xB2,
-  0x66, 0x98, 0xA3, 0x2F, 0x2F, 0xB2, 0x2F, 0x2F,
-  0xB2, 0x51, 0x89, 0x89, 0xB2, 0x98, 0xA0, 0x2A,
-  0xA5, 0x55, 0x98, 0x66, 0xA3, 0xB2, 0x20, 0x2F,
-  0x4C, 0x20, 0x4B, 0xBB, 0xCF, 0x6F, 0x27, 0x36,
-  0x93, 0xCE, 0x20, 0x20, 0xA6, 0x3D, 0x4C, 0x20,
-  0x20, 0x20, 0x20, 0xDA, 0xA0, 0xA0, 0x8F, 0xA3,
-  0x2F, 0xB2, 0x66, 0x98, 0xA3, 0x2F, 0xB2, 0x2F,
-  0x2F, 0x2F, 0xB2, 0x51, 0x89, 0x89, 0xB2, 0x98,
-  0xA0, 0x2A, 0xA5, 0xA0, 0x8F, 0x66, 0xA3, 0xA3,
-  0xA0, 0x8F, 0x8F, 0xA0, 0x8F, 0xA3, 0xB2, 0x2F,
-  0x66, 0x98, 0x2F, 0xB2, 0xB2, 0xB2, 0xB2, 0x2F,
-  0xB2, 0x89, 0x44, 0x51, 0x66, 0x55, 0xAD, 0x2A,
-  0x55, 0x8F, 0x66, 0xA3, 0x2F, 0xB2, 0x20, 0x2A,
-  0xE6, 0x95, 0xE5, 0x5A, 0x52, 0x52, 0x3F, 0x27,
-  0x22, 0xC7, 0x9D, 0x60, 0xA2, 0xA2, 0x3A, 0x20,
-  0x20, 0x20, 0x20, 0x54, 0x66, 0xA0, 0x8F, 0xA3,
-  0xB2, 0x2F, 0x66, 0x98, 0x2F, 0xB2, 0xB2, 0xB2,
-  0xB2, 0x2F, 0xB2, 0x89, 0x44, 0x51, 0x66, 0x55,
-  0x2A, 0x2A, 0xA5, 0x8F, 0x66, 0xA3, 0x2F, 0x2F,
-  0xA3, 0xA3, 0x66, 0x98, 0x98, 0x2F, 0xB2, 0xB2,
-  0xA3, 0xA3, 0x2F, 0x51, 0x51, 0x51, 0x2F, 0x2F,
-  0x51, 0x89, 0x89, 0x2F, 0x8F, 0x2A, 0x2A, 0xA5,
-  0x8F, 0x66, 0xA3, 0xB2, 0x2F, 0x51, 0x20, 0x6D,
-  0x77, 0xF7, 0xEE, 0x30, 0xB0, 0x72, 0x72, 0x5B,
-  0x82, 0xEA, 0x72, 0xB0, 0x90, 0x96, 0x71, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x2F, 0x98, 0x98, 0x2F,
-  0xB2, 0xB2, 0x66, 0xA3, 0x2F, 0x51, 0x51, 0xB2,
-  0xB2, 0x2F, 0x51, 0x89, 0x89, 0x2F, 0x8F, 0x2A,
-  0xAD, 0xA5, 0x98, 0x66, 0xA3, 0xB2, 0x2F, 0xB2,
-  0xD8, 0xB2, 0xA3, 0x98, 0x98, 0x2F, 0xB2, 0xB2,
-  0x66, 0xA3, 0xB2, 0x51, 0x51, 0xB2, 0x2F, 0xA3,
-  0x51, 0x89, 0x89, 0xA3, 0xA0, 0x2A, 0xA5, 0x8F,
-  0x66, 0xA3, 0x2F, 0xB2, 0xB2, 0x51, 0x20, 0x69,
-  0x64, 0xF9, 0x3F, 0x52, 0x52, 0x72, 0x29, 0x82,
-  0x47, 0x47, 0x47, 0x8B, 0x72, 0xB7, 0x60, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x2F, 0x98, 0x98, 0x2F,
-  0xB2, 0xB2, 0xA3, 0xA3, 0xB2, 0x89, 0x51, 0x2F,
-  0x2F, 0xA3, 0x51, 0x89, 0x89, 0xA3, 0xA0, 0x2A,
-  0xA5, 0x8F, 0x66, 0xA3, 0x2F, 0xB2, 0xB2, 0xB2,
-  0xDD, 0xA3, 0x66, 0x98, 0x66, 0x2F, 0xB2, 0xB2,
-  0xA3, 0xA3, 0xB2, 0x51, 0xB2, 0x2F, 0xA3, 0x2F,
-  0xB2, 0x89, 0xB2, 0x66, 0xA0, 0xA5, 0x8F, 0x98,
-  0x66, 0x66, 0xB2, 0x51, 0x51, 0x51, 0x81, 0xFA,
-  0x62, 0xEE, 0x30, 0x52, 0x22, 0x72, 0x82, 0x82,
-  0x47, 0x47, 0xEA, 0x3F, 0x37, 0x6F, 0x26, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x2A, 0x98, 0x66, 0x2F,
-  0x51, 0xB2, 0xA3, 0x66, 0xB2, 0x51, 0x51, 0xB2,
-  0xA3, 0x2F, 0xB2, 0x89, 0xB2, 0x66, 0x55, 0x55,
-  0x8F, 0x98, 0x66, 0xA3, 0xB2, 0x51, 0x51, 0xB2,
-  0x74, 0xA0, 0x8F, 0x98, 0x66, 0xB2, 0xB2, 0xB2,
-  0xA3, 0xA3, 0x2F, 0x51, 0x51, 0x2F, 0xA3, 0x2F,
-  0xB2, 0x51, 0xA3, 0x98, 0xA0, 0x55, 0xA0, 0xA0,
-  0x8F, 0x66, 0x2F, 0x51, 0xB2, 0x51, 0x54, 0xA9,
-  0x62, 0xEF, 0x52, 0x22, 0x72, 0x29, 0xEA, 0xEA,
-  0x29, 0x22, 0x37, 0x37, 0x8E, 0xCF, 0x49, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x6D, 0x2F, 0x66, 0x2F,
-  0x51, 0xB2, 0xA3, 0x66, 0x2F, 0xB2, 0xB2, 0x2F,
-  0xA3, 0x2F, 0xB2, 0x51, 0x2F, 0x98, 0xA0, 0x55,
-  0xA0, 0xA0, 0x8F, 0x66, 0x2F, 0x51, 0xB2, 0xA3,
-  0xA3, 0x2A, 0xA5, 0x98, 0xA3, 0x2F, 0xB2, 0x2F,
-  0x66, 0x66, 0x2F, 0xB2, 0xB2, 0xB2, 0x2F, 0x2F,
-  0xB2, 0x2F, 0xA3, 0x8F, 0xA0, 0xA0, 0xA0, 0xA0,
-  0x8F, 0xA3, 0x51, 0x51, 0x2F, 0xB2, 0x54, 0xA8,
-  0x65, 0x5C, 0x52, 0x22, 0x29, 0x29, 0x29, 0xB0,
-  0x62, 0x56, 0xF9, 0x79, 0xF9, 0xBB, 0x4B, 0x20,
-  0x6D, 0xA5, 0x2E, 0x20, 0x20, 0xA3, 0xA3, 0x2F,
-  0xB2, 0x2F, 0xA3, 0x66, 0x2F, 0xB2, 0xB2, 0xB2,
-  0x2F, 0x2F, 0xB2, 0x2F, 0x66, 0x8F, 0xA0, 0xA0,
-  0x55, 0xA0, 0x8F, 0xA3, 0x51, 0x51, 0x2F, 0xA3,
-  0xA0, 0x2A, 0x55, 0x66, 0xA3, 0x2F, 0xB2, 0xB2,
-  0xA3, 0x66, 0xA3, 0xB2, 0xB2, 0xB2, 0xA3, 0x66,
-  0xA3, 0xA3, 0x66, 0x8F, 0x8F, 0x8F, 0xA0, 0x98,
-  0xA3, 0x51, 0x89, 0x89, 0xA3, 0x2F, 0x20, 0x54,
-  0xDF, 0xFA, 0x40, 0x37, 0xD4, 0x43, 0x56, 0x64,
-  0x76, 0xF9, 0x78, 0x41, 0x5E, 0x5E, 0x4C, 0x20,
-  0x20, 0xAD, 0x8F, 0x9C, 0x20, 0xA5, 0xA3, 0x2F,
-  0x2F, 0x2F, 0xA3, 0x66, 0x2F, 0xB2, 0xB2, 0xB2,
-  0xA3, 0x66, 0xA3, 0x2F, 0x66, 0x8F, 0x8F, 0x8F,
-  0x8F, 0x8F, 0xA3, 0x51, 0x89, 0x51, 0xA3, 0x66,
-  0xA0, 0xA0, 0x8F, 0xA3, 0x2F, 0x2F, 0x2F, 0xB2,
-  0x2F, 0xA3, 0x2F, 0xB2, 0x51, 0xB2, 0x2F, 0x66,
-  0xA3, 0xA3, 0x66, 0x66, 0x66, 0x66, 0x66, 0xA3,
-  0xB2, 0x89, 0xD8, 0x51, 0x66, 0x51, 0x20, 0x6D,
-  0x51, 0x77, 0x9F, 0xF7, 0xEE, 0x8E, 0xF9, 0xF0,
-  0x24, 0xF7, 0x77, 0x5E, 0x74, 0xD8, 0x98, 0x20,
-  0x20, 0x2E, 0x55, 0x92, 0x20, 0x54, 0x51, 0x2F,
-  0x2F, 0xB2, 0xB2, 0xA3, 0x2F, 0x51, 0x51, 0xB2,
-  0xA3, 0xA3, 0x66, 0xA3, 0x66, 0x66, 0x66, 0x66,
-  0x66, 0xA3, 0xB2, 0x89, 0xD8, 0x51, 0xA3, 0x98,
-  0x98, 0x66, 0x66, 0xA3, 0x2F, 0x2F, 0x2F, 0xB2,
-  0xB2, 0x2F, 0x2F, 0xB2, 0xB2, 0x2F, 0x2F, 0x66,
-  0x66, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0xB2,
-  0x89, 0xD8, 0x89, 0xB2, 0x66, 0x66, 0x20, 0x6D,
-  0x89, 0xC2, 0xA4, 0x96, 0xC6, 0x64, 0x50, 0x40,
-  0xF4, 0x97, 0x89, 0x74, 0x7E, 0x6B, 0x39, 0xA7,
-  0x20, 0x20, 0x3A, 0x54, 0x20, 0x20, 0xA7, 0x51,
-  0x2F, 0xB2, 0xB2, 0xA3, 0xA3, 0xB2, 0xB2, 0xB2,
-  0xA3, 0xA3, 0x66, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F,
-  0x2F, 0xB2, 0x89, 0xD8, 0x44, 0x2F, 0x66, 0x66,
-  0x2F, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F, 0xB2,
-  0x2F, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0xA3,
-  0x66, 0xA3, 0x2F, 0xB2, 0xB2, 0xB2, 0x51, 0x51,
-  0x89, 0x89, 0xB2, 0x66, 0x2F, 0x6D, 0x20, 0xCE,
-  0x39, 0x74, 0x89, 0x5E, 0xBD, 0x87, 0xC8, 0xD1,
-  0x89, 0x44, 0x3C, 0x4D, 0x6B, 0x6B, 0x6B, 0x2F,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xA3,
-  0x2F, 0x2F, 0x2F, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F,
-  0x2F, 0xA3, 0x66, 0x66, 0x2F, 0xB2, 0xB2, 0xB2,
-  0x51, 0x51, 0x89, 0x89, 0xB2, 0xA3, 0x98, 0x66,
-  0xA3, 0x66, 0x66, 0xA3, 0xA3, 0xA3, 0xA3, 0x2F,
-  0x2F, 0xA3, 0xA3, 0xA3, 0x2F, 0xA3, 0x2F, 0xA3,
-  0x66, 0x66, 0x2F, 0x2F, 0xB2, 0xB2, 0xB2, 0xB2,
-  0xB2, 0x2F, 0x66, 0x66, 0x2A, 0x20, 0x54, 0x44,
-  0x6B, 0x39, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-  0xD8, 0x39, 0x4D, 0x6B, 0x6B, 0x6B, 0x6B, 0x4D,
-  0x9C, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D,
-  0x51, 0x2F, 0x2F, 0x2F, 0xA3, 0xA3, 0xA3, 0x2F,
-  0xA3, 0xA3, 0x66, 0xA3, 0x2F, 0xB2, 0xB2, 0xB2,
-  0xB2, 0xB2, 0xB2, 0x2F, 0x66, 0x98, 0x98, 0x66,
-  0x98, 0x98, 0x66, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3,
-  0x2F, 0x2F, 0xA3, 0xA3, 0x66, 0xA3, 0xA3, 0x66,
-  0x98, 0x66, 0x66, 0x2F, 0xA3, 0xA3, 0xA3, 0xA3,
-  0x66, 0x98, 0x98, 0x98, 0x3A, 0x54, 0x2A, 0x6B,
-  0x6B, 0x6B, 0x83, 0x44, 0x89, 0x89, 0x44, 0x3C,
-  0xD6, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0xB2, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0xAD, 0x2F, 0x2F, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3,
-  0xA3, 0x66, 0x66, 0x98, 0x66, 0xA3, 0xA3, 0xA3,
-  0xA3, 0xA3, 0x66, 0x98, 0x8F, 0x8F, 0x8F, 0x98,
-  0x8F, 0x98, 0x98, 0x66, 0xA3, 0xA3, 0xA3, 0xA3,
-  0x2F, 0xA3, 0xA3, 0x66, 0x66, 0x66, 0x66, 0x66,
-  0x8F, 0x8F, 0x8F, 0x98, 0x98, 0x98, 0x8F, 0xA0,
-  0xA0, 0xA0, 0xA3, 0xDA, 0x20, 0x3A, 0x39, 0x6B,
-  0x6B, 0x6B, 0x4D, 0xA2, 0x74, 0x3C, 0x7E, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x6B, 0x2E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x2F, 0x2F, 0xA3, 0x66, 0x66, 0x66, 0x66,
-  0x66, 0x98, 0x8F, 0x8F, 0x98, 0x98, 0x98, 0x98,
-  0x8F, 0xA0, 0xA0, 0xA0, 0x8F, 0x8F, 0x8F, 0xA0,
-  0x8F, 0x66, 0x66, 0xA3, 0x66, 0xA3, 0xA3, 0x2F,
-  0x2F, 0x2F, 0xA3, 0xA3, 0x66, 0x66, 0x66, 0x98,
-  0x98, 0xA0, 0x98, 0x66, 0x66, 0x98, 0x8F, 0xA0,
-  0xA0, 0xA3, 0x2E, 0x20, 0x20, 0x8F, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x3D, 0x6B, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x6B, 0x55, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x3A, 0x51, 0x2F, 0xA3, 0x66, 0x66, 0x66,
-  0x66, 0x66, 0x98, 0x8F, 0x8F, 0x98, 0x66, 0x98,
-  0x8F, 0xA0, 0xA0, 0x8F, 0x8F, 0x8F, 0x8F, 0xA0,
-  0x66, 0x2F, 0x2F, 0x2F, 0x2F, 0xA3, 0xA3, 0xA3,
-  0x2F, 0x2F, 0xA3, 0xA3, 0x66, 0xA3, 0x66, 0x66,
-  0x66, 0x98, 0xA3, 0x2F, 0x2F, 0xA3, 0x66, 0x8F,
-  0x66, 0xA6, 0x20, 0x20, 0x6D, 0x39, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x6B, 0xB2, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x2E, 0x89, 0xA3, 0xA3, 0x66, 0x66,
-  0x66, 0x66, 0x98, 0x98, 0xA3, 0x2F, 0x2F, 0xA3,
-  0x66, 0x8F, 0x98, 0x98, 0x66, 0x98, 0x98, 0x8F,
-  0x2F, 0x51, 0xB2, 0xB2, 0x2F, 0xA3, 0xA3, 0xA3,
-  0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3,
-  0xA3, 0xA3, 0x2F, 0xB2, 0x2F, 0xA3, 0x66, 0x2F,
-  0x55, 0x20, 0x20, 0x20, 0x4C, 0x39, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x4D, 0x7E, 0x54, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x2E, 0x51, 0xA3, 0xA3, 0xA3,
-  0xA3, 0xA3, 0xA3, 0x2F, 0xB2, 0xB2, 0x2F, 0xA3,
-  0x66, 0x66, 0xA3, 0xA3, 0xA3, 0xA3, 0x66, 0x66,
-  0xB2, 0x51, 0x51, 0xB2, 0xB2, 0xA3, 0x2F, 0xA3,
-  0x2F, 0x2F, 0x2F, 0xA3, 0xA3, 0xA3, 0xA3, 0x66,
-  0xA3, 0x2F, 0xB2, 0x2F, 0xA3, 0x98, 0x98, 0xA0,
-  0x20, 0x20, 0x20, 0x20, 0xA5, 0x83, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x4D, 0x7E, 0x4D, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x4D, 0x4D, 0xD6, 0x7E, 0xDD,
-  0x3C, 0x39, 0xA7, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x92, 0xB2, 0xA3, 0xA3,
-  0xA3, 0x66, 0xA3, 0x2F, 0x2F, 0x2F, 0xA3, 0x98,
-  0x98, 0x66, 0xA3, 0xA3, 0x66, 0x66, 0x66, 0xA3,
-  0x89, 0x89, 0x51, 0xB2, 0xB2, 0x2F, 0x2F, 0x2F,
-  0x2F, 0xA3, 0xA3, 0x2F, 0xA3, 0xA3, 0xA3, 0xA3,
-  0xA3, 0xA3, 0xA3, 0x66, 0x8F, 0x8F, 0x2F, 0xDA,
-  0x20, 0x20, 0x20, 0xDA, 0xA0, 0x51, 0x3C, 0x7E,
-  0x6B, 0x6B, 0x6B, 0x4D, 0x7E, 0x6B, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x7E, 0x3C, 0xD8, 0x44, 0xD8,
-  0x44, 0x83, 0x89, 0xDA, 0x20, 0x3A, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0xB2, 0xA3, 0xA3,
-  0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0x66, 0x8F, 0x8F,
-  0x98, 0x98, 0x98, 0x98, 0x66, 0xA3, 0xA3, 0x2F,
-  0x3C, 0x89, 0x89, 0x51, 0xB2, 0xB2, 0x2F, 0x2F,
-  0x2F, 0x2F, 0xA3, 0xA3, 0x66, 0x66, 0x66, 0xA3,
-  0xA3, 0xA3, 0xA3, 0x66, 0x98, 0x98, 0xA3, 0x20,
-  0x20, 0x20, 0x20, 0x6D, 0x2F, 0xE6, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x3D, 0xD6, 0x3D,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x4D, 0x7E, 0xA2,
-  0x74, 0x44, 0xA2, 0xA3, 0x20, 0x3A, 0x2E, 0x6D,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0xA6, 0xA3, 0x66,
-  0x66, 0x66, 0xA3, 0x2F, 0xA3, 0x66, 0x66, 0x98,
-  0x66, 0x66, 0x98, 0x98, 0x98, 0x66, 0xA3, 0xA3,
-  0x83, 0xB2, 0x2F, 0x2F, 0xB2, 0xB2, 0xB2, 0x2F,
-  0x2F, 0x2F, 0xA3, 0x66, 0x66, 0x98, 0x98, 0x66,
-  0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0x66, 0xA6, 0x20,
-  0x3A, 0x3A, 0x54, 0x55, 0x7E, 0x6B, 0x6B, 0x6B,
-  0x4D, 0x3D, 0x6B, 0x6B, 0x6B, 0x57, 0x33, 0xEB,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x4D, 0xA2, 0x74, 0x39, 0x92, 0x20, 0x20, 0x6D,
-  0x2E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x98,
-  0x98, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0x66, 0x66,
-  0x66, 0x66, 0x66, 0x66, 0x66, 0xA3, 0x66, 0xA3,
-  0x89, 0xA3, 0x66, 0x66, 0xA3, 0xA3, 0x2F, 0x2F,
-  0xA3, 0x2F, 0xA3, 0xA3, 0x66, 0x66, 0x66, 0xA3,
-  0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xB2, 0x3A, 0x20,
-  0xA7, 0x20, 0x3A, 0x39, 0x6B, 0x6B, 0x6B, 0x6B,
-  0xB5, 0xCB, 0x6B, 0x6B, 0x3D, 0x8A, 0x42, 0x3D,
-  0x6B, 0x6B, 0x6B, 0x84, 0x6C, 0x4D, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x7E, 0x83, 0x51, 0x20, 0x20, 0x20,
-  0x6D, 0x3A, 0x20, 0x20, 0x20, 0x20, 0xAD, 0x66,
-  0x66, 0x66, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3,
-  0xA3, 0xA3, 0xA3, 0xA3, 0x66, 0xA3, 0xA3, 0xA3,
-  0xB2, 0x98, 0x66, 0x66, 0x98, 0x66, 0x66, 0xA3,
-  0xA3, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F,
-  0xA3, 0x2F, 0xA3, 0xA3, 0xA3, 0x2F, 0x20, 0x6D,
-  0x3A, 0x20, 0x98, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0xAA, 0x33, 0x6B, 0x6B, 0x3D, 0xF5, 0x7B, 0x3D,
-  0x6B, 0x6B, 0x4F, 0x4A, 0x58, 0x3D, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x7E, 0x7E, 0x9C, 0x54, 0xA7,
-  0x2E, 0xA7, 0x20, 0x20, 0x20, 0x20, 0x54, 0x51,
-  0x2F, 0x2F, 0xA3, 0x2F, 0xA3, 0xA3, 0xA3, 0xA3,
-  0x2F, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0x2F,
-  0xB2, 0x66, 0x66, 0x66, 0x66, 0xA3, 0x66, 0xA3,
-  0x66, 0x66, 0xA3, 0x2F, 0x2F, 0xB2, 0x2F, 0xB2,
-  0x2F, 0x2F, 0x2F, 0xA3, 0x2F, 0xA6, 0x20, 0xCE,
-  0x20, 0x6D, 0x4D, 0x6B, 0xD6, 0x7E, 0x6B, 0x6B,
-  0x6E, 0x9A, 0x57, 0x6B, 0x2D, 0x7B, 0x7B, 0x3D,
-  0x6B, 0x84, 0xF5, 0x7B, 0x84, 0x6B, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x98, 0x3A, 0x9C,
-  0xCE, 0x3A, 0x2E, 0x20, 0x20, 0x20, 0x20, 0x98,
-  0xB2, 0xB2, 0x2F, 0x2F, 0x2F, 0xA3, 0x2F, 0x2F,
-  0x2F, 0xA3, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F,
-  0x89, 0xA3, 0x66, 0x66, 0xA3, 0x2F, 0x2F, 0xA3,
-  0x66, 0x66, 0xA3, 0xA3, 0x2F, 0x2F, 0xB2, 0xB2,
-  0xB2, 0x2F, 0x2F, 0x2F, 0x89, 0x54, 0x6D, 0x3A,
-  0x20, 0x98, 0x6B, 0x6B, 0xE0, 0xB4, 0x6B, 0x6B,
-  0x2D, 0x9E, 0x4A, 0x3D, 0x84, 0xF5, 0xF5, 0x84,
-  0x6B, 0x6E, 0x59, 0x6C, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x3D, 0x6B, 0x6B, 0x6B, 0x6B, 0xDD, 0xDA, 0x6D,
-  0x54, 0x20, 0xCE, 0x20, 0x20, 0x20, 0x20, 0xA7,
-  0x51, 0xB2, 0xB2, 0xB2, 0x2F, 0xB2, 0x2F, 0x2F,
-  0x2F, 0x66, 0x66, 0xA3, 0xA3, 0xA3, 0xA3, 0x66,
-  0x89, 0xA3, 0xA3, 0xA3, 0x2F, 0xB2, 0xB2, 0x2F,
-  0x66, 0x66, 0xA3, 0xA3, 0x2F, 0xA3, 0xA3, 0x2F,
-  0xB2, 0x2F, 0x2F, 0xA3, 0x98, 0x20, 0xA7, 0x20,
-  0x3A, 0x7E, 0x6B, 0x6B, 0x7F, 0xDE, 0xF6, 0x3D,
-  0x6B, 0xDB, 0x8A, 0xDB, 0xE9, 0xF3, 0xF3, 0xDB,
-  0x68, 0xF3, 0x73, 0x7F, 0x6B, 0x6B, 0x57, 0x58,
-  0xDC, 0x2D, 0x6B, 0x6B, 0x6B, 0x6B, 0x3A, 0x20,
-  0x20, 0x20, 0x6D, 0x54, 0x20, 0x20, 0x20, 0x20,
-  0x51, 0x2F, 0x2F, 0x2F, 0xA3, 0xA3, 0xA3, 0x66,
-  0xA3, 0x66, 0x98, 0x98, 0x66, 0x98, 0x98, 0x66,
-  0x2F, 0x66, 0x66, 0xA3, 0x2F, 0xB2, 0x2F, 0xA3,
-  0xA3, 0xA3, 0xA3, 0xA3, 0x66, 0xA3, 0xA3, 0xA3,
-  0x66, 0x98, 0x8F, 0x98, 0xCE, 0xDA, 0x2E, 0x20,
-  0x2A, 0x6B, 0x6B, 0x6B, 0x6B, 0x2C, 0x34, 0xCB,
-  0xEB, 0x6C, 0x31, 0x59, 0x82, 0x82, 0x8B, 0x82,
-  0xF3, 0x73, 0xE9, 0x6B, 0x3D, 0x6E, 0xF3, 0x4A,
-  0x4F, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x92, 0x20,
-  0x20, 0x20, 0x6D, 0x6D, 0x20, 0x20, 0x20, 0x20,
-  0xA3, 0xA3, 0x66, 0x98, 0x98, 0x8F, 0x8F, 0x98,
-  0x98, 0x98, 0x98, 0x66, 0x98, 0x66, 0x66, 0xA3,
-  0xA3, 0x66, 0x66, 0x66, 0xA3, 0x2F, 0x2F, 0xA3,
-  0xA3, 0xA3, 0x66, 0x66, 0xA3, 0xA3, 0xA3, 0x66,
-  0x8F, 0x55, 0xA5, 0x98, 0x20, 0x2E, 0x54, 0x54,
-  0x89, 0x6B, 0x6B, 0x6B, 0x6B, 0x84, 0xE3, 0x4A,
-  0x58, 0x42, 0x5B, 0x8B, 0x82, 0x82, 0x82, 0x82,
-  0x82, 0x59, 0x58, 0x57, 0x57, 0x59, 0x7B, 0x84,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0xAD, 0x20,
-  0x20, 0x20, 0x3A, 0x3A, 0x20, 0x20, 0x20, 0x20,
-  0x2A, 0x66, 0x8F, 0x55, 0xA5, 0xA5, 0xA0, 0x8F,
-  0x66, 0xA3, 0xA3, 0x66, 0x98, 0x66, 0x66, 0x2F,
-  0x2F, 0x2F, 0x2F, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F,
-  0xA3, 0x2F, 0xA3, 0xA3, 0x66, 0xA3, 0xA3, 0x66,
-  0x8F, 0xA5, 0x8F, 0x2E, 0x20, 0x2E, 0x20, 0x3A,
-  0x4D, 0x6B, 0xE6, 0x84, 0x3D, 0x6B, 0xEB, 0x4A,
-  0xC9, 0x8B, 0x8B, 0x31, 0x59, 0x82, 0x59, 0x59,
-  0x5B, 0x82, 0x59, 0x73, 0x7B, 0xDC, 0x57, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x55, 0x20,
-  0x20, 0x20, 0x6D, 0xDA, 0x20, 0x20, 0x20, 0x20,
-  0x9C, 0x66, 0x8F, 0xA5, 0xA5, 0x55, 0x8F, 0x66,
-  0x2F, 0xB2, 0x2F, 0x66, 0x98, 0x98, 0x2F, 0x51,
-  0x89, 0xB2, 0x2F, 0xA3, 0xA3, 0xB2, 0xB2, 0xB2,
-  0x2F, 0x2F, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0x66,
-  0x8F, 0xA5, 0x8F, 0x20, 0x20, 0xA7, 0x20, 0xA6,
-  0x6B, 0x6B, 0xE4, 0x48, 0x2C, 0xDB, 0x4F, 0x9E,
-  0xD0, 0xD0, 0x8B, 0x82, 0x82, 0x82, 0x82, 0x82,
-  0x59, 0x82, 0x82, 0x73, 0x7B, 0x68, 0x6B, 0x3D,
-  0x68, 0x68, 0x84, 0x3D, 0x6B, 0x6B, 0xA0, 0x20,
-  0x20, 0x20, 0x6D, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x6D, 0x2F, 0xA0, 0xA5, 0x55, 0x98, 0x66, 0xA3,
-  0xB2, 0x89, 0xB2, 0x98, 0x8F, 0x98, 0x2F, 0x51,
-  0x74, 0xB2, 0xA3, 0xA3, 0x2F, 0x2F, 0xB2, 0x2F,
-  0xA3, 0xA3, 0xA3, 0x66, 0x66, 0xA3, 0x2F, 0xA3,
-  0x98, 0xA3, 0x6D, 0x20, 0x20, 0xCE, 0x20, 0x2A,
-  0x6B, 0x6B, 0xEB, 0x2C, 0xE1, 0xF1, 0x7C, 0xD0,
-  0x8B, 0x8B, 0x82, 0x82, 0x82, 0x82, 0x82, 0x59,
-  0x82, 0x82, 0x42, 0x82, 0x31, 0x57, 0x4F, 0x7B,
-  0x7B, 0xF5, 0xF6, 0xDB, 0x6B, 0x6B, 0x98, 0x20,
-  0x20, 0x20, 0x2E, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x51, 0x66, 0xA0, 0xA0, 0x66, 0x2F, 0xB2,
-  0xB2, 0x51, 0x2F, 0xA0, 0x55, 0xA3, 0x51, 0x89,
-  0x44, 0xA3, 0x98, 0x98, 0x2F, 0x2F, 0x2F, 0xA3,
-  0xA3, 0x66, 0x98, 0x98, 0x98, 0xA3, 0x2F, 0x2F,
-  0x98, 0x8F, 0x20, 0x20, 0x3A, 0xA6, 0x20, 0xA0,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x7F, 0x7F, 0xC3, 0xC9,
-  0xD0, 0xD0, 0x29, 0x59, 0x82, 0x73, 0x82, 0x73,
-  0x59, 0x59, 0x59, 0x59, 0x59, 0x58, 0xAF, 0xF5,
-  0x8A, 0x68, 0xEB, 0x6B, 0x6B, 0x6B, 0x98, 0x20,
-  0x20, 0x20, 0x6D, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x51, 0x98, 0x55, 0xA0, 0xA3, 0xB2, 0x51,
-  0x51, 0x2F, 0x98, 0x55, 0x8F, 0xB2, 0x89, 0x44,
-  0xA3, 0x55, 0x55, 0x98, 0xA3, 0xB2, 0x2F, 0xA3,
-  0x66, 0x66, 0x98, 0x8F, 0x66, 0xA3, 0x66, 0x98,
-  0x55, 0x4C, 0x20, 0x20, 0xDA, 0xAD, 0x20, 0x98,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x3D, 0x9A, 0xD0,
-  0xF2, 0x8B, 0x8B, 0x8B, 0x73, 0x82, 0x5B, 0x82,
-  0x82, 0x59, 0x59, 0x73, 0x73, 0x58, 0x3D, 0x3D,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x66, 0x20,
-  0x20, 0x3A, 0x3A, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x2F, 0x55, 0xA5, 0x8F, 0xA3, 0x51, 0x51,
-  0xB2, 0xA3, 0x66, 0x66, 0xA3, 0xB2, 0x89, 0x51,
-  0x98, 0xA5, 0x55, 0x8F, 0x2F, 0xB2, 0xB2, 0xA3,
-  0x66, 0x66, 0x98, 0x98, 0x98, 0x66, 0x66, 0x8F,
-  0x8F, 0x92, 0x20, 0x20, 0x20, 0x6D, 0x6D, 0xA3,
-  0x6B, 0x6B, 0xEB, 0x7F, 0x4F, 0xDB, 0xD2, 0xC9,
-  0xC9, 0xD0, 0x8B, 0x8B, 0x73, 0x82, 0x59, 0x8B,
-  0x59, 0x82, 0x59, 0x59, 0x73, 0xF5, 0xEB, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x55, 0x20,
-  0x20, 0xA7, 0x54, 0xDA, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x98, 0xA0, 0x8F, 0xA3, 0xB2, 0x51, 0x51,
-  0x51, 0x2F, 0xA3, 0xA3, 0xB2, 0xB2, 0x51, 0xB2,
-  0xA0, 0xA5, 0x55, 0x66, 0x2F, 0x51, 0x2F, 0xA3,
-  0x66, 0x66, 0x66, 0x98, 0x66, 0x66, 0x98, 0x98,
-  0x98, 0x2A, 0x54, 0x95, 0x95, 0x71, 0x2E, 0x98,
-  0x6B, 0x6B, 0x4D, 0x28, 0xDE, 0x88, 0xB7, 0x70,
-  0xC9, 0xC9, 0xD0, 0xF2, 0x8B, 0x8B, 0x8B, 0x59,
-  0x59, 0x59, 0x59, 0x5B, 0x59, 0xF3, 0x57, 0xE9,
-  0xDB, 0x84, 0x6B, 0x6B, 0x6B, 0x6B, 0x4C, 0xDA,
-  0x2E, 0xDA, 0x20, 0xDA, 0x2E, 0x2E, 0x6D, 0x20,
-  0x4C, 0x98, 0x66, 0xA3, 0x2F, 0xB2, 0x51, 0x51,
-  0xB2, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F,
-  0xA0, 0xA0, 0x8F, 0x2F, 0xB2, 0x89, 0xB2, 0xA3,
-  0x66, 0x66, 0x98, 0x66, 0x66, 0x66, 0x66, 0xA3,
-  0x2F, 0xD1, 0xE2, 0x52, 0x52, 0xF4, 0xBF, 0x9C,
-  0x39, 0x6B, 0x6B, 0x6B, 0x7F, 0x4F, 0xE3, 0x6A,
-  0xD0, 0xC9, 0xC9, 0xD0, 0xD0, 0x8B, 0x8B, 0x82,
-  0x5B, 0x5B, 0x73, 0x8B, 0x59, 0x23, 0x6E, 0x31,
-  0x59, 0x7B, 0xDB, 0x84, 0x68, 0x7F, 0xAE, 0x54,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0xA6, 0x3A,
-  0xA0, 0xA3, 0xA3, 0x2F, 0x51, 0x51, 0x51, 0xB2,
-  0x2F, 0xA3, 0x66, 0x66, 0xA3, 0xA3, 0xA3, 0xA3,
-  0x8F, 0x8F, 0x66, 0x2F, 0x51, 0x51, 0xB2, 0xA3,
-  0x66, 0x98, 0x98, 0x66, 0x66, 0xA3, 0x2F, 0x2F,
-  0x3C, 0x88, 0x8D, 0x52, 0x52, 0x5D, 0xF7, 0xBF,
-  0xCE, 0xA2, 0x6B, 0x6B, 0x6B, 0x6B, 0x7F, 0x85,
-  0x70, 0xC9, 0xC9, 0xC9, 0xD0, 0xEA, 0x8B, 0x5B,
-  0x82, 0xEA, 0x82, 0x82, 0x42, 0x57, 0x3D, 0x68,
-  0x68, 0x57, 0x4A, 0x34, 0x22, 0xCC, 0x21, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0xDA, 0xA7, 0x6D,
-  0xDF, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0x2F, 0x2F,
-  0xA3, 0x66, 0x66, 0x66, 0xA3, 0xA3, 0x2F, 0x2F,
-  0x66, 0x66, 0xA3, 0x2F, 0xB2, 0xB2, 0x2F, 0x66,
-  0x8F, 0x8F, 0x8F, 0x98, 0xA3, 0xA3, 0x89, 0xD8,
-  0x25, 0x5C, 0x3B, 0x5D, 0x52, 0x80, 0x70, 0x36,
-  0x71, 0xA7, 0x44, 0x6B, 0x84, 0xCB, 0xAA, 0xF3,
-  0xC9, 0xC9, 0xC9, 0xC9, 0xD0, 0x8B, 0x5B, 0x5B,
-  0x5B, 0xEA, 0x82, 0x47, 0x7B, 0x68, 0x3D, 0x3D,
-  0x6B, 0x3D, 0x6C, 0x2B, 0x80, 0x61, 0x96, 0x81,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3A, 0xDA, 0x63,
-  0xAC, 0x6C, 0xB2, 0xB2, 0xB2, 0xB2, 0x2F, 0xA3,
-  0xA3, 0x66, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F,
-  0x66, 0x98, 0x66, 0xA3, 0xB2, 0xB2, 0x2F, 0x66,
-  0x8F, 0x8F, 0x2F, 0xD8, 0xE4, 0xCD, 0xAA, 0xB4,
-  0x78, 0x2B, 0x3B, 0x70, 0x46, 0x5D, 0x5D, 0x52,
-  0x9D, 0x81, 0x3A, 0xA3, 0xCD, 0x48, 0xBE, 0x4F,
-  0xC3, 0xC9, 0xD0, 0xD0, 0xD0, 0xEA, 0x5B, 0x8B,
-  0x5B, 0x82, 0x8B, 0x59, 0x4A, 0xF3, 0x33, 0x7F,
-  0x3D, 0x6B, 0x4F, 0x6F, 0x5D, 0x52, 0x63, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x75, 0x85,
-  0x72, 0xDC, 0xD8, 0x2F, 0xA3, 0x2F, 0xA3, 0xA3,
-  0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3,
-  0xA3, 0x98, 0x66, 0x2F, 0xB2, 0x51, 0xA3, 0x98,
-  0xA0, 0xA3, 0x93, 0xCF, 0x79, 0x27, 0x5C, 0x79,
-  0x2B, 0x30, 0x80, 0x80, 0x5D, 0x5D, 0x5D, 0x5D,
-  0x3F, 0x69, 0x20, 0x20, 0x2A, 0xD6, 0x3D, 0x6B,
-  0x84, 0xE3, 0x34, 0xB7, 0xC9, 0xD0, 0xD0, 0xF2,
-  0xD0, 0x8B, 0x31, 0x68, 0x68, 0x6E, 0x31, 0x33,
-  0x7F, 0x7E, 0xA1, 0x6F, 0x52, 0x8D, 0xE5, 0xBF,
-  0x20, 0x20, 0x20, 0x20, 0x81, 0xA8, 0x78, 0x52,
-  0x52, 0xD2, 0xD8, 0xA3, 0xA3, 0x2F, 0x2F, 0xA3,
-  0xA3, 0x66, 0x98, 0x98, 0x98, 0x98, 0x98, 0x66,
-  0x51, 0x66, 0x2F, 0x51, 0x51, 0xB2, 0xA3, 0xA0,
-  0xA0, 0x44, 0x78, 0xEF, 0x52, 0x30, 0x30, 0x30,
-  0x3B, 0x70, 0x5D, 0x5D, 0x5D, 0x80, 0x5D, 0x5D,
-  0x46, 0xC1, 0x71, 0x20, 0x81, 0xB1, 0xDD, 0x3D,
-  0xA1, 0xE7, 0xDB, 0xCA, 0xD2, 0x6A, 0x6A, 0x6A,
-  0xF3, 0xE9, 0xDB, 0x8A, 0x84, 0x3D, 0x84, 0xDC,
-  0x25, 0x44, 0xB5, 0xEE, 0x30, 0xEF, 0xF0, 0x32,
-  0x69, 0x5F, 0x4B, 0xA8, 0x99, 0x56, 0x67, 0x30,
-  0x30, 0x34, 0xB2, 0x2F, 0xA3, 0xA3, 0x66, 0x66,
-  0x98, 0x8F, 0x98, 0x98, 0x66, 0x66, 0x66, 0x66,
-  0x51, 0x2F, 0xB2, 0x51, 0x51, 0x2F, 0x66, 0xA0,
-  0x8F, 0xE0, 0xF9, 0x8D, 0x52, 0x5D, 0x46, 0x5D,
-  0x80, 0x5D, 0x80, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D,
-  0x52, 0x52, 0x60, 0x81, 0x20, 0x20, 0x6D, 0xD1,
-  0x48, 0xE7, 0x6B, 0x33, 0xF6, 0x7F, 0x7F, 0xDB,
-  0x84, 0x6B, 0x6C, 0x6A, 0xF3, 0xEB, 0x6B, 0x3D,
-  0x4F, 0xD8, 0xCD, 0x79, 0x30, 0x67, 0xF9, 0x24,
-  0xED, 0xD9, 0x8C, 0xED, 0x37, 0x2B, 0x3B, 0x5D,
-  0x80, 0x85, 0x4E, 0x98, 0x66, 0x66, 0x66, 0x66,
-  0x66, 0x66, 0x66, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F,
-  0x51, 0x2F, 0xB2, 0xB2, 0xB2, 0xA3, 0x8F, 0x8F,
-  0x98, 0xE0, 0xF0, 0x67, 0x5D, 0x80, 0x80, 0x5D,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x80, 0x5D, 0x5D, 0x5D,
-  0x5D, 0x70, 0x27, 0x4B, 0x20, 0x81, 0x71, 0x3A,
-  0xB5, 0xEB, 0x3D, 0xF1, 0xE1, 0x84, 0x84, 0xF1,
-  0xE3, 0x3D, 0x6B, 0x6C, 0x34, 0xE7, 0x6B, 0x6B,
-  0xD6, 0x74, 0x5E, 0x78, 0x67, 0x30, 0xEE, 0x5C,
-  0xF9, 0xF9, 0x45, 0x5C, 0x2B, 0x3B, 0x5D, 0x5D,
-  0x5D, 0x5D, 0xF8, 0x44, 0x66, 0x66, 0x66, 0x66,
-  0x2F, 0x2F, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2,
-  0xB2, 0x2F, 0xA3, 0xA3, 0xA3, 0x98, 0x8F, 0x98,
-  0x66, 0x83, 0x76, 0x67, 0x30, 0x80, 0x5D, 0x80,
-  0x5D, 0x5D, 0x80, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D,
-  0x80, 0x5D, 0x22, 0xFA, 0x20, 0x81, 0x20, 0x20,
-  0xA5, 0x6B, 0x6B, 0xE8, 0xBE, 0x3D, 0x6B, 0x2C,
-  0xE1, 0xEB, 0x6B, 0x3D, 0x3E, 0xA1, 0x6B, 0x6B,
-  0x4D, 0x74, 0xE8, 0x62, 0x67, 0x30, 0x8D, 0x67,
-  0xEE, 0xEE, 0xEE, 0x67, 0x30, 0x80, 0x5D, 0x5D,
-  0x52, 0x5D, 0x85, 0xAC, 0x3E, 0xA3, 0x66, 0x66,
-  0x2F, 0x51, 0x51, 0x51, 0x51, 0xB2, 0x2F, 0x2F,
-  0x2F, 0xA3, 0xA3, 0x66, 0x98, 0x8F, 0x8F, 0x66,
-  0x2F, 0x83, 0xBC, 0xEE, 0x5D, 0x5D, 0x5D, 0x5D,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x80, 0x5D, 0x5D,
-  0x5D, 0x5D, 0x22, 0xB0, 0xAE, 0x81, 0x20, 0x20,
-  0x4C, 0x3D, 0xEB, 0x39, 0x57, 0x6B, 0x6B, 0x3E,
-  0x97, 0x3D, 0x6B, 0x3D, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x3D, 0x3C, 0xBA, 0x62, 0xEE, 0x5D, 0x5D, 0x30,
-  0x30, 0x8D, 0x8D, 0x30, 0x52, 0x5D, 0x5D, 0x80,
-  0x5D, 0x5D, 0x5D, 0x85, 0xB0, 0x6E, 0x2F, 0x66,
-  0x2F, 0xB2, 0x51, 0xB2, 0x2F, 0x2F, 0xA3, 0xA3,
-  0xB2, 0xA3, 0x66, 0x98, 0x98, 0x8F, 0x98, 0xA3,
-  0x2F, 0x51, 0xDE, 0x8E, 0x30, 0x5D, 0x5D, 0x5D,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D,
-  0x52, 0x80, 0x5D, 0x22, 0x43, 0x4B, 0x20, 0x6D,
-  0x44, 0x6B, 0x6B, 0x3D, 0x6B, 0x6B, 0x6B, 0x4D,
-  0x3D, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x3D, 0x6B,
-  0x4D, 0x2A, 0xAE, 0x76, 0xEE, 0x30, 0x80, 0x80,
-  0x80, 0x80, 0x80, 0x80, 0x5D, 0x5D, 0x5D, 0x80,
-  0x5D, 0x5D, 0x80, 0x80, 0x5D, 0x7A, 0xB6, 0x51,
-  0xB2, 0xB2, 0xB2, 0xA3, 0x66, 0x66, 0x66, 0xA3,
-  0x2F, 0x66, 0x98, 0x8F, 0xA0, 0x98, 0xA3, 0x2F,
-  0x2F, 0x51, 0xAB, 0x8E, 0x5D, 0x5D, 0x5D, 0x5D,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x80,
-  0x5D, 0x80, 0x5D, 0x52, 0x52, 0x94, 0x2F, 0x7E,
-  0x6B, 0x3D, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x7E,
-  0xAD, 0x54, 0xAE, 0x24, 0x2B, 0x3B, 0x5D, 0x52,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x80, 0x5D, 0x5D, 0x80,
-  0x5D, 0x52, 0x52, 0x5D, 0x5D, 0x5D, 0xD2, 0x3E,
-  0x89, 0x89, 0xB2, 0xA3, 0x66, 0x98, 0x66, 0x66,
-  0x2F, 0x66, 0x8F, 0x8F, 0xA0, 0x98, 0xA3, 0xB2,
-  0x2F, 0x51, 0xDE, 0x79, 0x5D, 0x80, 0x5D, 0x5D,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D,
-  0x5D, 0x5D, 0x80, 0x5D, 0x52, 0x6F, 0xA4, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x4D, 0xA2, 0xCE,
-  0x20, 0x20, 0x95, 0x24, 0x67, 0x3B, 0x80, 0x80,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D,
-  0x80, 0x5D, 0x5D, 0x5D, 0x5D, 0x30, 0xB0, 0x86,
-  0x89, 0x51, 0x2F, 0x66, 0x98, 0x98, 0xA3, 0xA3,
-  0xA3, 0x66, 0x8F, 0xA0, 0x8F, 0x66, 0x2F, 0xB2,
-  0x2F, 0x4E, 0x76, 0x2B, 0x30, 0x5D, 0x5D, 0x5D,
-  0x80, 0x80, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D,
-  0x80, 0x5D, 0x5D, 0x5D, 0x46, 0x52, 0x21, 0x74,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
-  0x6B, 0x6B, 0x6B, 0x6B, 0x7E, 0x98, 0x3A, 0x20,
-  0x20, 0x81, 0x60, 0xED, 0x2B, 0x52, 0x5D, 0x5D,
-  0x80, 0x5D, 0x5D, 0x80, 0x5D, 0x5D, 0x5D, 0x80,
-  0x22, 0x5D, 0x5D, 0x5D, 0x8D, 0x2B, 0x38, 0x39,
-  0x51, 0x66, 0x8F, 0xA0, 0xA0, 0x8F, 0x98, 0x66,
-  0x66, 0x66, 0x8F, 0x55, 0x8F, 0xA3, 0xB2, 0xB2,
-  0xA3, 0xE8, 0xF9, 0x30, 0x3B, 0x80, 0x5D, 0x5D,
-  0x5D, 0x80, 0x80, 0x5D, 0x5D, 0x5D, 0x80, 0x5D,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x52, 0x30, 0xD4, 0x99,
-  0x51, 0x4D, 0x6B, 0x6B, 0x6B, 0x6B, 0x4D, 0x6B,
-  0x6B, 0x6B, 0x7E, 0xA3, 0x2E, 0x20, 0x20, 0x20,
-  0x20, 0x81, 0xC5, 0xED, 0x2B, 0x3B, 0x5D, 0x5D,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x80, 0x5D, 0x5D, 0x80,
-  0x5D, 0x52, 0x52, 0x6F, 0xDE, 0x2C, 0x39, 0x51,
-  0x66, 0xA0, 0xA5, 0xA5, 0x55, 0x8F, 0x66, 0x66,
-  0xA0, 0xA0, 0xA0, 0xA0, 0x8F, 0xA3, 0x2F, 0x2F,
-  0x51, 0xD5, 0x45, 0x8D, 0x3B, 0x5D, 0x80, 0x5D,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D,
-  0x80, 0x5D, 0x5D, 0x5D, 0x52, 0x67, 0x37, 0xA9,
-  0x3A, 0xCE, 0xA0, 0x2F, 0x51, 0x51, 0xB2, 0xA3,
-  0xA5, 0x9C, 0x54, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x54, 0x99, 0xED, 0x67, 0x30, 0x5D, 0x5D,
-  0x5D, 0x80, 0x5D, 0x5D, 0x5D, 0x5D, 0x3B, 0x80,
-  0x8D, 0x79, 0x48, 0x2C, 0x39, 0x44, 0xB2, 0x66,
-  0xA0, 0x2A, 0xA5, 0xA0, 0x8F, 0x66, 0xA3, 0xA3,
-  0xA0, 0x8F, 0x8F, 0xA0, 0x8F, 0xA3, 0xB2, 0xB2,
-  0xD8, 0xBC, 0x45, 0xEE, 0x67, 0x8D, 0x30, 0x30,
-  0x52, 0x52, 0x80, 0x5D, 0x5D, 0x5D, 0x5D, 0x80,
-  0x5D, 0x5D, 0x5D, 0x80, 0x3B, 0x67, 0xF9, 0x32,
-  0x69, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0xBF, 0xEC, 0xED, 0x2B, 0x30, 0x5D, 0x5D,
-  0x80, 0x5D, 0x5D, 0x5D, 0x52, 0x30, 0x67, 0x2B,
-  0xCF, 0xAA, 0xD8, 0x89, 0x89, 0x51, 0x66, 0x55,
-  0x2A, 0x2A, 0xA5, 0x8F, 0x66, 0xA3, 0x2F, 0x2F,
-  0xA3, 0xA3, 0x66, 0x98, 0x98, 0x2F, 0xB2, 0x2F,
-  0xD1, 0x28, 0x56, 0xED, 0x62, 0x37, 0x5C, 0x79,
-  0x8E, 0x2B, 0x2B, 0x30, 0x30, 0x30, 0x5D, 0x5D,
-  0x5D, 0x5D, 0x5D, 0x80, 0x3B, 0xEE, 0x56, 0xA9,
-  0x75, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x5F, 0x99, 0xD9, 0x45, 0x8D, 0x3B, 0x5D,
-  0x5D, 0x3B, 0x5D, 0x8D, 0x2B, 0x79, 0x79, 0x41,
-  0x83, 0xB2, 0xB2, 0x89, 0x89, 0x2F, 0xA0, 0x2A,
-  0xAD, 0xA5, 0x98, 0x66, 0xA3, 0xB2, 0x2F, 0xB2,
-  0xD8, 0xB2, 0xA3, 0x98, 0x98, 0x2F, 0x51, 0xB2,
-  0xA3, 0x83, 0x3E, 0x25, 0xD5, 0xE5, 0x50, 0x8C,
-  0xED, 0x24, 0x24, 0xF0, 0x45, 0x8E, 0x2B, 0x30,
-  0x30, 0x5D, 0x3B, 0x30, 0xEE, 0xF0, 0xC6, 0x65,
-  0x75, 0x71, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x4B, 0xC5, 0x7D, 0x24, 0xEE, 0x67, 0x30,
-  0x30, 0x8D, 0x67, 0x8E, 0xF9, 0xF7, 0x97, 0xDD,
-  0x2F, 0x2F, 0x51, 0x89, 0x89, 0x2F, 0x55, 0x2A,
-  0xA5, 0x8F, 0x66, 0xA3, 0x2F, 0xB2, 0xB2, 0xB2,
-  0xDD, 0xA3, 0x66, 0x98, 0x66, 0x2F, 0xB2, 0xB2,
-  0xA3, 0xA3, 0xB2, 0x51, 0x89, 0x44, 0xE0, 0x5E,
-  0x91, 0x9F, 0x9F, 0x7D, 0x7D, 0xD9, 0x24, 0xF0,
-  0x79, 0x8E, 0xEE, 0x8E, 0x24, 0x40, 0x65, 0x35,
-  0x69, 0x2E, 0x98, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F,
-  0x2F, 0xB2, 0xB2, 0xB2, 0x2F, 0x2F, 0x2F, 0x98,
-  0xA5, 0xA7, 0x95, 0xD7, 0x8C, 0xF0, 0x8E, 0x8E,
-  0xEE, 0x79, 0xF0, 0xED, 0x50, 0xE8, 0x89, 0x2F,
-  0xA3, 0xA3, 0xB2, 0x89, 0xB2, 0x66, 0xA0, 0x55,
-  0x8F, 0x98, 0x66, 0xA3, 0xB2, 0x51, 0x51, 0xB2,
-  0x74, 0xA0, 0xA0, 0x98, 0x66, 0xB2, 0xB2, 0xB2,
-  0xA3, 0xA3, 0x2F, 0xB2, 0xB2, 0xB2, 0xA3, 0x2F,
-  0x51, 0x83, 0xE4, 0x87, 0xB8, 0xFA, 0xA9, 0xC6,
-  0x40, 0x64, 0x64, 0x50, 0xD7, 0x65, 0x35, 0x60,
-  0x98, 0xB2, 0x66, 0x66, 0xA3, 0x2F, 0xA3, 0xA3,
-  0xA3, 0x2F, 0x2F, 0x2F, 0x2F, 0xA3, 0x2F, 0xB2,
-  0x89, 0xDD, 0x9B, 0xC0, 0x7D, 0x50, 0x8C, 0xED,
-  0xED, 0x8C, 0x40, 0x9F, 0x4E, 0x51, 0xB2, 0x2F,
-  0x2F, 0x2F, 0xB2, 0x51, 0xA3, 0x98, 0xA0, 0x55,
-  0xA0, 0xA0, 0x8F, 0x66, 0x2F, 0x51, 0xB2, 0xA3,
-  0xA3, 0x2A, 0x55, 0x98, 0xA3, 0x2F, 0xB2, 0x2F,
-  0x66, 0x66, 0x2F, 0xB2, 0xD1, 0x2F, 0x2F, 0xA3,
-  0xB2, 0xB2, 0xA3, 0x8F, 0xA3, 0x2F, 0xD1, 0x94,
-  0xEC, 0x65, 0x65, 0xC0, 0xC0, 0x35, 0x95, 0xC2,
-  0xA3, 0x98, 0x66, 0xA3, 0x2F, 0x2F, 0x2F, 0xA3,
-  0xA3, 0x2F, 0xB2, 0x2F, 0x2F, 0x2F, 0x2F, 0x51,
-  0x89, 0x44, 0xD1, 0x60, 0x35, 0xA9, 0x32, 0xC6,
-  0xD7, 0x32, 0x94, 0x44, 0x2F, 0xB2, 0xB2, 0xB2,
-  0xA3, 0x2F, 0xB2, 0x2F, 0xA3, 0x8F, 0xA0, 0xA0,
-  0x55, 0xA0, 0x8F, 0xA3, 0x51, 0x51, 0x2F, 0xA3,
-  0x8F, 0x2A, 0x55, 0x66, 0xA3, 0x2F, 0x2F, 0xB2,
-  0xA3, 0x66, 0x2F, 0xB2, 0x51, 0xB2, 0x2F, 0x66,
-  0xA3, 0xA3, 0x66, 0x8F, 0x8F, 0x8F, 0xA0, 0x2F,
-  0x5E, 0xDF, 0xB9, 0x60, 0x95, 0xD3, 0x89, 0x2F,
-  0xA3, 0x66, 0xA3, 0x2F, 0xB2, 0x2F, 0xA3, 0xA3,
-  0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0xB2,
-  0x51, 0x2F, 0x8F, 0x2F, 0xC4, 0xB9, 0x9B, 0xEC,
-  0x53, 0xB3, 0x4E, 0xA3, 0x2F, 0xB2, 0xB2, 0xB2,
-  0xA3, 0x66, 0xA3, 0xA3, 0x66, 0x8F, 0x8F, 0x8F,
-  0x8F, 0x8F, 0xA3, 0x51, 0x89, 0x51, 0xA3, 0x66,
-  0xA0, 0x55, 0x8F, 0xA3, 0x2F, 0x2F, 0x2F, 0xB2,
-  0x2F, 0xA3, 0x2F, 0x51, 0x51, 0xB2, 0xA3, 0x66,
-  0x66, 0xA3, 0x66, 0x66, 0x66, 0x66, 0x66, 0xA3,
-  0xB2, 0xC2, 0x74, 0xD8, 0xB2, 0xA3, 0xA3, 0xA3,
-  0x66, 0x66, 0x2F, 0x2F, 0xA3, 0x66, 0x66, 0x66,
-  0xA3, 0xA3, 0xB2, 0xB2, 0xB2, 0xB2, 0x2F, 0xB2,
-  0x2F, 0x66, 0xA0, 0x55, 0x98, 0x2F, 0x89, 0x89,
-  0x89, 0xB2, 0x2F, 0xA3, 0x2F, 0x51, 0x51, 0xB2,
-  0x2F, 0x66, 0xA3, 0xA3, 0x66, 0x66, 0x66, 0x66,
-  0x66, 0xA3, 0xB2, 0x89, 0xD8, 0x51, 0xA3, 0x98,
-  0x66, 0x98, 0x66, 0x2F, 0x2F, 0x2F, 0x2F, 0xB2,
-  0xB2, 0xA3, 0xA3, 0xB2, 0xB2, 0xB2, 0x2F, 0xA3,
-  0x66, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0xB2,
-  0x89, 0xD8, 0x89, 0x2F, 0x66, 0x66, 0xA3, 0xA3,
-  0x98, 0x98, 0x66, 0x66, 0x98, 0x98, 0x66, 0xA3,
-  0x2F, 0xA3, 0xB2, 0xB2, 0xB2, 0xB2, 0x2F, 0x2F,
-  0xB2, 0x2F, 0x66, 0x98, 0x66, 0xA3, 0x2F, 0x2F,
-  0x2F, 0xB2, 0x2F, 0xA3, 0xA3, 0xB2, 0xB2, 0x2F,
-  0x2F, 0x66, 0x66, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F,
-  0x2F, 0xB2, 0x89, 0xD8, 0x44, 0x2F, 0x66, 0x66,
-  0xA3, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0x2F,
-  0x2F, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F, 0xA3,
-  0x66, 0xA3, 0x2F, 0xB2, 0xB2, 0xB2, 0x51, 0x51,
-  0x89, 0x89, 0xB2, 0xA3, 0x98, 0x66, 0xA3, 0x66,
-  0x98, 0x98, 0x98, 0x98, 0x98, 0x66, 0xA3, 0x2F,
-  0xA3, 0x2F, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2,
-  0xB2, 0x2F, 0xA3, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F,
-  0x2F, 0xB2, 0xB2, 0xA3, 0xA3, 0x2F, 0x2F, 0x2F,
-  0x2F, 0xA3, 0x66, 0xA3, 0x2F, 0xB2, 0xB2, 0xB2,
-  0x51, 0x51, 0x89, 0x89, 0xB2, 0xA3, 0x98, 0x66
-};
-
-unsigned char linux_logo_bw[] __initdata = {
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F,
-  0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFE, 0x3F, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xC7, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xC3,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF,
-  0xFB, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFD, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF,
-  0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xF9, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xF9, 0xCF, 0xC3, 0xF8, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x87, 0x81, 0xF9,
-  0xF8, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xA7,
-  0x99, 0xF9, 0xC2, 0x40, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xF9, 0xF3, 0xBC, 0xF9, 0x90, 0x00, 0x1F, 0xFF,
-  0xFF, 0xFF, 0xF9, 0xE3, 0xBC, 0xF9, 0xA0, 0x00,
-  0x8F, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, 0x3C, 0xF9,
-  0x83, 0xE0, 0x2F, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0,
-  0x19, 0xF0, 0x1F, 0xFE, 0x0F, 0xFF, 0xFF, 0xFF,
-  0xF9, 0xC0, 0x03, 0xF0, 0x3F, 0xF7, 0x8F, 0xFF,
-  0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, 0x7F, 0xF7,
-  0xC7, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8,
-  0x6F, 0xF7, 0xE7, 0xFF, 0xFF, 0xFF, 0xF9, 0x80,
-  0x01, 0xF8, 0x7F, 0xF7, 0xE7, 0xFF, 0xFF, 0xFF,
-  0xF9, 0xC0, 0x21, 0xD8, 0x7F, 0xE7, 0xEF, 0xFF,
-  0xFF, 0xFF, 0xF9, 0xB1, 0x80, 0xEC, 0x7B, 0xFF,
-  0xEF, 0xFF, 0xFF, 0xFF, 0xF1, 0x90, 0x00, 0xE4,
-  0x7B, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xF1, 0x8C,
-  0xC0, 0x7C, 0x79, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF,
-  0xE3, 0x80, 0x00, 0x7C, 0x7C, 0xFF, 0xCF, 0xFF,
-  0xFF, 0xFF, 0xE3, 0x80, 0x00, 0x7F, 0x77, 0xFF,
-  0xDF, 0xFF, 0xFF, 0xFF, 0x87, 0x00, 0x00, 0x3F,
-  0x3F, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0x0E, 0x00,
-  0x00, 0x3F, 0xBF, 0xFF, 0x9F, 0xFF, 0xFF, 0xFF,
-  0x1E, 0x00, 0x00, 0x1F, 0x9F, 0xFF, 0x3F, 0xFF,
-  0xFF, 0xFE, 0x1C, 0x00, 0x00, 0x1F, 0x9F, 0xFF,
-  0x7F, 0xFF, 0xFF, 0xFE, 0x3C, 0x00, 0x00, 0x1F,
-  0x8F, 0xFE, 0x7F, 0xFF, 0xFF, 0xFC, 0x7C, 0x00,
-  0x00, 0x0F, 0xC7, 0xFC, 0xFF, 0xFF, 0xFF, 0xFC,
-  0xF8, 0x00, 0x00, 0x0F, 0xF7, 0xF9, 0xFF, 0xFF,
-  0xFF, 0xFC, 0xF8, 0x00, 0x00, 0x07, 0xFB, 0xF3,
-  0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0x00, 0x00, 0x07,
-  0xFD, 0xE7, 0xFF, 0xFF, 0xFF, 0xF9, 0xF0, 0x00,
-  0x00, 0x03, 0xFE, 0x8F, 0xFF, 0xFF, 0xFF, 0xF1,
-  0xF0, 0x00, 0x00, 0x03, 0xFE, 0x1F, 0xFF, 0xFF,
-  0xFF, 0xF1, 0xE0, 0x00, 0x00, 0x00, 0xFF, 0xBF,
-  0xFF, 0xFF, 0xFF, 0xE3, 0xE0, 0x00, 0x00, 0x00,
-  0xFE, 0xBF, 0xFF, 0xFF, 0xFF, 0xE3, 0xC0, 0x00,
-  0x00, 0x00, 0xFE, 0x3F, 0xFF, 0xFF, 0xFF, 0xC7,
-  0xC0, 0x00, 0x00, 0x01, 0xFE, 0xBF, 0xFF, 0xFF,
-  0xFF, 0xC7, 0x80, 0x00, 0x00, 0x01, 0xFE, 0x9F,
-  0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x00, 0x01,
-  0xFE, 0x07, 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00,
-  0x00, 0x01, 0xFE, 0x87, 0xFF, 0xFF, 0xFF, 0x9F,
-  0x80, 0x00, 0x00, 0x01, 0xFD, 0x33, 0xFF, 0xFF,
-  0xFF, 0x9F, 0x80, 0x00, 0x00, 0x01, 0x80, 0xF3,
-  0xFF, 0xFF, 0xFF, 0x9E, 0x80, 0x00, 0x00, 0x03,
-  0x8B, 0xF9, 0xFF, 0xFF, 0xFF, 0x9F, 0x80, 0x00,
-  0x00, 0x02, 0x27, 0xF8, 0xFF, 0xFF, 0xFF, 0x99,
-  0x80, 0x00, 0x00, 0x00, 0x07, 0xF8, 0xFF, 0xFF,
-  0xFF, 0x00, 0x80, 0x00, 0x00, 0x01, 0x8F, 0xF8,
-  0xFF, 0xFF, 0xFE, 0x20, 0x60, 0x00, 0x00, 0x00,
-  0xE3, 0xF8, 0xFF, 0xFF, 0xF8, 0x00, 0x30, 0x00,
-  0x00, 0x00, 0xF8, 0x78, 0xFF, 0xFF, 0xC0, 0x40,
-  0x38, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x7F, 0xFF,
-  0x81, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xFC, 0x20,
-  0x7F, 0xFF, 0x90, 0x00, 0x1E, 0x00, 0x00, 0x00,
-  0x78, 0x10, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0x80,
-  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00,
-  0x07, 0xC0, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF,
-  0xC0, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x04,
-  0x7F, 0xFF, 0x80, 0x00, 0x03, 0xC0, 0x00, 0x10,
-  0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x01, 0x80,
-  0x00, 0x30, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00,
-  0x00, 0x00, 0x00, 0x70, 0x00, 0x01, 0x4F, 0xFF,
-  0x80, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00,
-  0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x80, 0x03, 0xF0,
-  0x00, 0x00, 0x8F, 0xFF, 0x80, 0x00, 0x00, 0x40,
-  0x0F, 0xF0, 0x00, 0x04, 0x1F, 0xFF, 0x80, 0x00,
-  0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x10, 0x1F, 0xFF,
-  0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x40,
-  0xFF, 0xFF, 0x98, 0x00, 0x00, 0xFF, 0xFF, 0xF0,
-  0x00, 0x83, 0xFF, 0xFF, 0x81, 0xE0, 0x01, 0xFF,
-  0xFF, 0xF8, 0x02, 0x07, 0xFF, 0xFF, 0x80, 0x3F,
-  0x07, 0xE0, 0x00, 0x1C, 0x0C, 0x1F, 0xFF, 0xFF,
-  0xF8, 0x03, 0xFF, 0x80, 0x00, 0x1F, 0x78, 0x1F,
-  0xFF, 0xFF, 0xFF, 0x80, 0x7F, 0x00, 0x07, 0x0F,
-  0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0x0C, 0x07,
-  0xFF, 0x83, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0x00, 0x1F, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22,
+    0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+    0x26, 0x26, 0x25, 0x28, 0x23, 0x22, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x25, 0x2a, 0x2b, 0x2c, 0x2d, 0x2d,
+    0x2d, 0x2e, 0x2c, 0x2b, 0x2a, 0x25, 0x28, 0x22,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x24, 0x2a, 0x2c, 0x2f, 0x2c, 0x30, 0x30, 0x24,
+    0x25, 0x27, 0x2b, 0x2c, 0x2f, 0x31, 0x32, 0x25,
+    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
+    0x33, 0x34, 0x35, 0x21, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x21, 0x2b, 0x2f, 0x2c,
+    0x30, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
+    0x2d, 0x27, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x31,
+    0x2d, 0x32, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x2a, 0x34,
+    0x25, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x23, 0x32, 0x27, 0x21, 0x36,
+    0x2a, 0x2d, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x22, 0x26, 0x2c, 0x35,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x25, 0x2f, 0x37, 0x32, 0x22,
+    0x36, 0x35, 0x31, 0x27, 0x22, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x22,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x26, 0x38, 0x38, 0x35, 0x25,
+    0x36, 0x21, 0x2d, 0x2b, 0x24, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x24, 0x39, 0x39, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x25, 0x2b, 0x30, 0x28, 0x22,
+    0x36, 0x36, 0x27, 0x34, 0x30, 0x23, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x26, 0x2d, 0x26, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x22, 0x22, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x2d, 0x33, 0x28, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x2b, 0x2c, 0x25, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x36, 0x36,
+    0x36, 0x21, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x21, 0x23, 0x22, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x28, 0x34, 0x27, 0x22, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
+    0x21, 0x21, 0x24, 0x27, 0x21, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x28, 0x27, 0x22, 0x33, 0x24, 0x36,
+    0x36, 0x36, 0x36, 0x22, 0x2f, 0x2a, 0x23, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
+    0x30, 0x3a, 0x38, 0x24, 0x24, 0x36, 0x36, 0x36,
+    0x23, 0x2f, 0x3b, 0x3c, 0x3d, 0x30, 0x25, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2f, 0x32, 0x23, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x23,
+    0x3e, 0x3f, 0x40, 0x3a, 0x22, 0x36, 0x36, 0x21,
+    0x41, 0x42, 0x43, 0x44, 0x45, 0x3e, 0x23, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2f, 0x33, 0x28, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x2b,
+    0x44, 0x40, 0x46, 0x47, 0x35, 0x36, 0x36, 0x26,
+    0x43, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x2e, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x34, 0x36, 0x4d,
+    0x4e, 0x25, 0x2f, 0x46, 0x4a, 0x22, 0x23, 0x32,
+    0x4f, 0x50, 0x21, 0x31, 0x51, 0x52, 0x53, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x21, 0x3a,
+    0x4d, 0x21, 0x31, 0x54, 0x55, 0x28, 0x30, 0x2b,
+    0x4b, 0x4d, 0x36, 0x23, 0x32, 0x50, 0x3f, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x38, 0x23, 0x37,
+    0x55, 0x36, 0x28, 0x3a, 0x56, 0x57, 0x57, 0x58,
+    0x3c, 0x4d, 0x36, 0x36, 0x36, 0x40, 0x40, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x29, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x51, 0x23, 0x35,
+    0x43, 0x25, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
+    0x5f, 0x60, 0x61, 0x36, 0x31, 0x47, 0x3b, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x2c, 0x25, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x22,
+    0x40, 0x62, 0x63, 0x5d, 0x64, 0x65, 0x66, 0x67,
+    0x68, 0x69, 0x66, 0x5e, 0x6a, 0x6b, 0x2a, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x33, 0x2e, 0x26, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x2f, 0x23, 0x36,
+    0x6c, 0x63, 0x6d, 0x64, 0x5c, 0x66, 0x69, 0x6e,
+    0x6f, 0x70, 0x71, 0x69, 0x69, 0x72, 0x6c, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x33, 0x34, 0x27, 0x22,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x34, 0x26, 0x73,
+    0x74, 0x75, 0x76, 0x64, 0x65, 0x77, 0x69, 0x78,
+    0x70, 0x71, 0x71, 0x71, 0x72, 0x5f, 0x5e, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x25, 0x38, 0x2a, 0x23,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x33, 0x79,
+    0x63, 0x7a, 0x7b, 0x5c, 0x66, 0x69, 0x6e, 0x7c,
+    0x71, 0x71, 0x69, 0x7d, 0x7e, 0x7a, 0x7f, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x21, 0x51, 0x2b, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x32, 0x24,
+    0x80, 0x81, 0x64, 0x82, 0x77, 0x69, 0x71, 0x71,
+    0x69, 0x83, 0x84, 0x85, 0x7a, 0x85, 0x86, 0x36,
+    0x21, 0x2b, 0x23, 0x36, 0x36, 0x39, 0x2e, 0x26,
+    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x2d, 0x33, 0x21,
+    0x87, 0x88, 0x89, 0x72, 0x67, 0x66, 0x5f, 0x89,
+    0x8a, 0x63, 0x85, 0x8b, 0x8c, 0x8d, 0x41, 0x36,
+    0x36, 0x2d, 0x3a, 0x35, 0x36, 0x24, 0x51, 0x32,
+    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x33, 0x21,
+    0x55, 0x8e, 0x8f, 0x8a, 0x7d, 0x5e, 0x90, 0x7e,
+    0x75, 0x75, 0x90, 0x62, 0x40, 0x3f, 0x49, 0x23,
+    0x36, 0x24, 0x3a, 0x3a, 0x24, 0x36, 0x2e, 0x31,
+    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x21, 0x28, 0x33, 0x37, 0x25, 0x22,
+    0x3b, 0x50, 0x8e, 0x8f, 0x90, 0x7e, 0x90, 0x63,
+    0x74, 0x91, 0x92, 0x42, 0x93, 0x4b, 0x45, 0x2c,
+    0x36, 0x36, 0x33, 0x39, 0x21, 0x36, 0x22, 0x51,
+    0x33, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x22, 0x27, 0x2e, 0x2e, 0x36, 0x21,
+    0x94, 0x3f, 0x50, 0x95, 0x96, 0x8f, 0x8f, 0x97,
+    0x8e, 0x42, 0x50, 0x43, 0x47, 0x48, 0x48, 0x98,
+    0x21, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39,
+    0x2e, 0x27, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x22, 0x24, 0x2b, 0x38, 0x28, 0x36, 0x32,
+    0x4c, 0x4b, 0x50, 0x50, 0x50, 0x42, 0x42, 0x50,
+    0x50, 0x40, 0x45, 0x99, 0x48, 0x48, 0x48, 0x48,
+    0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x23,
+    0x2f, 0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x28, 0x32, 0x51, 0x32, 0x28, 0x21, 0x98,
+    0x48, 0x47, 0x9a, 0x50, 0x50, 0x50, 0x50, 0x50,
+    0x9a, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x93, 0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x2a, 0x2f, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x23, 0x30, 0x2e, 0x2c, 0x36, 0x21, 0x51, 0x9b,
+    0x48, 0x48, 0x52, 0x3f, 0x50, 0x50, 0x40, 0x4b,
+    0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2d, 0x31, 0x27, 0x23, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+    0x27, 0x2c, 0x2d, 0x21, 0x36, 0x28, 0x44, 0x48,
+    0x48, 0x48, 0x48, 0x47, 0x46, 0x4f, 0x47, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x9c, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x28, 0x51, 0x39, 0x26, 0x22, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
+    0x35, 0x51, 0x28, 0x36, 0x36, 0x9d, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x9b, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x4f, 0x28, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x28, 0x38, 0x2b, 0x25, 0x22, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
+    0x51, 0x25, 0x36, 0x36, 0x23, 0x40, 0x9b, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x9b, 0x99, 0x2b, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x30, 0x2f, 0x33, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x23, 0x30, 0x34,
+    0x27, 0x36, 0x36, 0x36, 0x2a, 0x40, 0x47, 0x48,
+    0x48, 0x48, 0x48, 0x9b, 0x99, 0x99, 0x9b, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x47, 0x52,
+    0x46, 0x4f, 0x37, 0x21, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x30, 0x34, 0x2a, 0x23,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x22, 0x25, 0x39, 0x2c,
+    0x36, 0x36, 0x36, 0x21, 0x31, 0x4e, 0x9a, 0x4c,
+    0x47, 0x9b, 0x9b, 0x52, 0x46, 0x4f, 0x52, 0x9b,
+    0x9b, 0x9b, 0x47, 0x4f, 0x45, 0x9a, 0x93, 0x93,
+    0x3f, 0x93, 0x98, 0x28, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c, 0x26,
+    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x28,
+    0x36, 0x36, 0x36, 0x22, 0x38, 0x98, 0x44, 0x99,
+    0x9b, 0x48, 0x48, 0x9b, 0x4c, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x47, 0x52, 0x46, 0x43, 0x93,
+    0x40, 0x40, 0x43, 0x53, 0x21, 0x23, 0x33, 0x23,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x2f, 0x32,
+    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x24, 0x2b, 0x31, 0x36,
+    0x36, 0x22, 0x36, 0x24, 0x9e, 0x4f, 0x9b, 0x48,
+    0x48, 0x48, 0x48, 0x9b, 0x99, 0x9f, 0x52, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x47,
+    0x4f, 0x9a, 0x3f, 0x46, 0x38, 0x36, 0x21, 0x30,
+    0x26, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c,
+    0x25, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x26, 0x2e, 0x33, 0x36,
+    0x25, 0x25, 0x36, 0x4d, 0x52, 0x48, 0x48, 0x48,
+    0x47, 0x9f, 0x48, 0x48, 0x48, 0xa0, 0xa1, 0xa2,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x47, 0x44, 0x93, 0x43, 0x23, 0x36, 0x36,
+    0x26, 0x24, 0x36, 0x36, 0x36, 0x36, 0x28, 0x2f,
+    0x2a, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x51, 0x24, 0x36,
+    0x2a, 0x36, 0x28, 0x44, 0x48, 0x48, 0x48, 0x48,
+    0xa3, 0xa4, 0x48, 0x48, 0x9f, 0xa5, 0xa6, 0x9f,
+    0x48, 0x48, 0x48, 0xa2, 0xa7, 0x47, 0x48, 0x48,
+    0x48, 0x48, 0x9b, 0x4b, 0x44, 0x37, 0x36, 0x23,
+    0x28, 0x30, 0x22, 0x36, 0x36, 0x36, 0x36, 0x2d,
+    0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x21, 0x28, 0x2b, 0x34, 0x36, 0x25,
+    0x24, 0x36, 0x4a, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0xa8, 0xa1, 0x48, 0x48, 0x9f, 0xa9, 0xa6, 0x9f,
+    0x48, 0x48, 0xaa, 0xa1, 0xa5, 0x9f, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x9b, 0x52, 0x3f, 0x21, 0x30,
+    0x35, 0x25, 0x30, 0x36, 0x36, 0x36, 0x36, 0x32,
+    0x2d, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x22, 0x26, 0x2e, 0x35, 0x36, 0x2a,
+    0x36, 0x24, 0x4f, 0x48, 0x52, 0x52, 0x48, 0x48,
+    0xab, 0xac, 0xa0, 0x48, 0xad, 0xa6, 0xa6, 0x9f,
+    0x48, 0xa2, 0xa9, 0xa6, 0xa2, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x47, 0x32, 0x30,
+    0x2a, 0x23, 0x30, 0x23, 0x36, 0x36, 0x36, 0x21,
+    0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x2a, 0x51, 0x28, 0x28, 0x25,
+    0x36, 0x3a, 0x48, 0x48, 0xae, 0xaf, 0x48, 0x48,
+    0xad, 0xac, 0xa1, 0x9f, 0xa2, 0xa9, 0xa9, 0xa2,
+    0x48, 0xab, 0x78, 0xa7, 0x48, 0x48, 0x48, 0x48,
+    0x9f, 0x48, 0x48, 0x48, 0x48, 0x48, 0x38, 0x21,
+    0x36, 0x36, 0x22, 0x27, 0x36, 0x36, 0x36, 0x36,
+    0x2e, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x22, 0x25, 0x2c, 0x34, 0x36, 0x30, 0x21,
+    0x23, 0x43, 0x48, 0x48, 0xb0, 0xb1, 0xb2, 0x9f,
+    0x48, 0xb3, 0xa5, 0xb3, 0xab, 0xa9, 0xa9, 0xb3,
+    0xb4, 0xa9, 0xb5, 0xb0, 0x48, 0x48, 0xa0, 0xa5,
+    0xa1, 0xad, 0x48, 0x48, 0x48, 0x48, 0x94, 0x36,
+    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
+    0x2a, 0x2e, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x2a, 0x51, 0x25, 0x21, 0x2a, 0x36,
+    0x2e, 0x9b, 0x48, 0x48, 0x48, 0xb6, 0xb7, 0xa4,
+    0xa2, 0xa7, 0xb5, 0x78, 0x6f, 0x6f, 0x6e, 0x6f,
+    0xa9, 0xb5, 0xab, 0x48, 0x9f, 0xab, 0xa9, 0xa1,
+    0xaa, 0x48, 0x48, 0x48, 0x48, 0x48, 0x98, 0x36,
+    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
+    0x22, 0x2f, 0x30, 0x22, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x22, 0x25, 0x2c, 0x34, 0x36, 0x24, 0x28, 0x36,
+    0x54, 0x48, 0x48, 0x48, 0x48, 0xa2, 0xa8, 0xa1,
+    0xa5, 0xa6, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f,
+    0x6f, 0x78, 0xa5, 0xa0, 0xa0, 0x78, 0xa6, 0xa2,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36,
+    0x36, 0x36, 0x36, 0x30, 0x36, 0x36, 0x36, 0x36,
+    0x21, 0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x28, 0x32, 0x2f, 0x28, 0x36, 0x27, 0x22, 0x21,
+    0x43, 0x48, 0x4b, 0xa2, 0x9f, 0x48, 0xa2, 0xa1,
+    0xb8, 0x6e, 0x6e, 0xb5, 0x78, 0x6f, 0x78, 0x78,
+    0x6e, 0x6f, 0x78, 0xb5, 0xa6, 0xa1, 0xa0, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4b, 0x21,
+    0x36, 0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x25, 0x2c, 0x39, 0x36, 0x36, 0x30, 0x22, 0x25,
+    0x52, 0x48, 0xa3, 0xb1, 0xb6, 0xb3, 0xaa, 0xac,
+    0x68, 0x68, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
+    0x78, 0x6f, 0x6f, 0xb5, 0xa6, 0xb4, 0x48, 0x9f,
+    0xb4, 0xb4, 0xa2, 0x9f, 0x48, 0x48, 0x4f, 0x21,
+    0x36, 0x36, 0x22, 0x26, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x30, 0x2d, 0x21, 0x36, 0x36, 0x32, 0x23, 0x2a,
+    0x47, 0x48, 0xa2, 0xb6, 0xaf, 0xb9, 0xba, 0x68,
+    0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x78,
+    0x6f, 0x6f, 0xa6, 0x6f, 0xb5, 0xa0, 0xaa, 0xa6,
+    0xa6, 0xa9, 0xb2, 0xb3, 0x48, 0x48, 0x4c, 0x22,
+    0x36, 0x36, 0x24, 0x23, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0x2e, 0x36, 0x36, 0x23, 0x31, 0x27, 0x39,
+    0x9b, 0x48, 0x48, 0x48, 0xb0, 0xb0, 0xba, 0xb8,
+    0x68, 0x68, 0x69, 0x78, 0x6f, 0xb5, 0x6f, 0xb5,
+    0x78, 0x78, 0x78, 0x78, 0x78, 0xa5, 0xbb, 0xa9,
+    0xa5, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4c, 0x23,
+    0x36, 0x36, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x2b, 0x39, 0x36, 0x36, 0x36, 0x26, 0x32, 0x31,
+    0x9b, 0x48, 0x48, 0x48, 0x48, 0x9f, 0xac, 0x68,
+    0xbc, 0x6e, 0x6e, 0x6e, 0xb5, 0x6f, 0x6e, 0x6f,
+    0x6f, 0x78, 0x78, 0xb5, 0xb5, 0xa5, 0x9f, 0x9f,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x46, 0x22,
+    0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x35, 0x39, 0x36, 0x36, 0x36, 0x36, 0x26, 0x2d,
+    0x9b, 0x48, 0x48, 0xb0, 0xaa, 0xb3, 0xbd, 0xb8,
+    0xb8, 0x68, 0x6e, 0x6e, 0xb5, 0x6f, 0x78, 0x6e,
+    0x78, 0x6f, 0x78, 0x78, 0xb5, 0xa9, 0xa2, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36,
+    0x24, 0x27, 0xbe, 0x24, 0x25, 0x28, 0x21, 0x36,
+    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x25,
+    0x39, 0x4d, 0xbf, 0x84, 0x81, 0x57, 0x21, 0x39,
+    0x52, 0x48, 0x48, 0x62, 0xb1, 0xc0, 0xc1, 0xc1,
+    0xb8, 0xb8, 0x68, 0xbc, 0x6e, 0x6e, 0x6e, 0x78,
+    0x78, 0x78, 0x78, 0x6e, 0x78, 0xa9, 0xa0, 0xab,
+    0xb3, 0xa2, 0x48, 0x48, 0x48, 0x48, 0x53, 0x28,
+    0x23, 0x36, 0x36, 0x36, 0x21, 0x28, 0x2c, 0x30,
+    0x21, 0x38, 0x33, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x28, 0x30,
+    0x2d, 0xc2, 0x7a, 0xc3, 0xc4, 0xc4, 0x7f, 0x22,
+    0x51, 0x52, 0x48, 0x48, 0xb0, 0xaa, 0xa8, 0xbd,
+    0x68, 0xb8, 0xb8, 0x68, 0x68, 0x6e, 0x6e, 0x6f,
+    0x6e, 0x6e, 0xb5, 0x6e, 0x78, 0xab, 0xab, 0xb5,
+    0x78, 0xa6, 0xb3, 0xc5, 0xac, 0xac, 0xc6, 0x61,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x30, 0x32,
+    0x25, 0x4d, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x24, 0x26, 0x30, 0x33, 0x31,
+    0x4d, 0x91, 0x5b, 0xc3, 0xc4, 0xc4, 0xc4, 0x5a,
+    0x21, 0x2e, 0x46, 0x48, 0x48, 0x48, 0xb0, 0x64,
+    0xc1, 0xb8, 0xb8, 0xb8, 0x68, 0x71, 0x6e, 0x6e,
+    0x6f, 0x71, 0x6f, 0x6f, 0xa6, 0xa0, 0x9f, 0xb4,
+    0xb4, 0xa0, 0xa1, 0xb7, 0xc7, 0x69, 0x66, 0xc8,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x26, 0x25,
+    0x83, 0xc9, 0x2c, 0x25, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x28, 0x30, 0x35, 0x2d, 0x2f, 0x37, 0x4a,
+    0x60, 0x85, 0xca, 0xcb, 0xc4, 0xc4, 0xc4, 0x82,
+    0x86, 0x36, 0x32, 0x3f, 0xa2, 0xa4, 0xa8, 0xa9,
+    0xb8, 0xb8, 0xb8, 0xb8, 0x68, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x71, 0x6f, 0x71, 0xa6, 0xb4, 0x9f, 0x9f,
+    0x48, 0x48, 0x48, 0xcc, 0xc3, 0xc7, 0xcd, 0xce,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x57,
+    0x77, 0x66, 0x34, 0x27, 0x22, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x23, 0x30, 0x31, 0xcf, 0x91, 0x7e, 0x90, 0x90,
+    0x8b, 0x5b, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0x5d, 0xd0, 0x36, 0x24, 0xd1, 0xb1, 0xaf, 0xaa,
+    0xba, 0xb8, 0x68, 0x68, 0x68, 0x71, 0x6e, 0x6e,
+    0x6e, 0x6f, 0x6e, 0x78, 0xa1, 0xa9, 0xa1, 0xb0,
+    0x9f, 0x9b, 0x99, 0xcc, 0x64, 0x5c, 0x8b, 0xd0,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x73, 0x5d,
+    0x82, 0x5c, 0xd2, 0x2a, 0x23, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x24, 0x2b, 0xcf, 0x8b, 0x5b, 0x76, 0x5b, 0x5b,
+    0x7b, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc7, 0x5e, 0x22, 0x36, 0x21, 0x3a, 0x99, 0x48,
+    0xa2, 0xa8, 0xb7, 0xc1, 0xb8, 0x68, 0x68, 0xbc,
+    0x68, 0x6e, 0xb5, 0xb4, 0xb4, 0xab, 0xb5, 0xa1,
+    0xb0, 0x4f, 0x3f, 0xd3, 0x7b, 0x7b, 0x85, 0x80,
+    0xbe, 0x36, 0x36, 0x36, 0x21, 0xd4, 0x7e, 0x7b,
+    0x64, 0x64, 0xd5, 0x35, 0x24, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x31, 0xd6, 0x5b, 0x64, 0xc3, 0xc3, 0xcb,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0x66, 0xd7, 0x36, 0x36, 0x36, 0x2c, 0x4b,
+    0xd8, 0xd9, 0xb3, 0xa8, 0xbd, 0xbd, 0xbd, 0xbd,
+    0xa9, 0xab, 0xb3, 0xa5, 0xa2, 0x9f, 0xa2, 0xa1,
+    0x6a, 0x9a, 0x3f, 0xda, 0x76, 0x76, 0x7a, 0x63,
+    0xdb, 0xdc, 0x86, 0xdc, 0xdd, 0x90, 0x5b, 0x64,
+    0xc3, 0xc3, 0xde, 0x2d, 0x27, 0x23, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x26, 0x2d, 0x91, 0x5b, 0x64, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc7, 0x83, 0xce, 0x36, 0x36, 0x36, 0x30,
+    0xb1, 0xd9, 0x48, 0xa1, 0xb2, 0xb0, 0xb0, 0xb3,
+    0xa2, 0x48, 0xa7, 0xbd, 0xa9, 0xa2, 0x48, 0x9f,
+    0xaa, 0x9a, 0x3f, 0xb1, 0x5b, 0x7b, 0xdf, 0x85,
+    0x7e, 0x90, 0x63, 0x90, 0x85, 0x5b, 0xc3, 0xc4,
+    0xc4, 0xcb, 0x5d, 0xd5, 0x39, 0x26, 0x23, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2d, 0xe0, 0xdf, 0x64, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc7, 0x88, 0x36, 0x36, 0x36, 0x36,
+    0x2d, 0x9b, 0x48, 0xb9, 0xaf, 0xa2, 0xa2, 0xb9,
+    0xa8, 0x9f, 0x48, 0xa7, 0xb7, 0xd9, 0x48, 0x48,
+    0x9b, 0x45, 0x3f, 0xe1, 0x6d, 0x7b, 0xca, 0xdf,
+    0x7a, 0x8b, 0x8b, 0x7a, 0x5b, 0x64, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc3, 0xe2, 0x37, 0x35, 0x26, 0x23,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2e, 0xe0, 0x7a, 0x7b, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc7, 0x72, 0x73, 0x36, 0x36, 0x36,
+    0x24, 0x52, 0x48, 0xa3, 0xaf, 0x9f, 0x48, 0xb6,
+    0xaf, 0xa2, 0x48, 0x9f, 0xe3, 0xd8, 0x48, 0x48,
+    0x48, 0x46, 0x42, 0xd6, 0x7a, 0x7b, 0x64, 0x7b,
+    0x76, 0x5b, 0x5b, 0x76, 0x7b, 0xc3, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xcb, 0x64, 0xe2, 0x4d, 0x2c, 0x27,
+    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x25, 0x31, 0xe4, 0x8b, 0x7b, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc7, 0x89, 0xbe, 0x36, 0x36,
+    0x32, 0x47, 0x48, 0x4f, 0xa0, 0x48, 0x48, 0xe3,
+    0x92, 0x9f, 0x48, 0x9f, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x4b, 0x2f, 0x8f, 0x7a, 0x7b, 0xc3, 0xcb,
+    0xc3, 0x64, 0x64, 0xc3, 0xc3, 0xcb, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0x5d, 0xe5, 0x2c,
+    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x25, 0x31, 0xe4, 0x85, 0x7b, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0x66, 0x57, 0x27, 0x4d,
+    0x4b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x99, 0x34, 0xbe, 0xdb, 0x7a, 0x7b, 0xc3, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0xe4,
+    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2d, 0xe4, 0x85, 0x7b, 0xcb, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc7, 0x5f, 0x92, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x44,
+    0x35, 0x36, 0xce, 0xdd, 0x7a, 0x7b, 0xcb, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0xc3, 0xe1,
+    0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+    0x30, 0x2f, 0xd6, 0x8b, 0x7b, 0xcb, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0x66, 0x89, 0x45,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x4e, 0x25,
+    0x36, 0x36, 0x61, 0xdb, 0x6d, 0x64, 0xcb, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0x7b, 0xdf, 0xe5,
+    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0xe6, 0x63, 0xdf, 0xc3, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0x72, 0x81, 0xe7,
+    0x46, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x3f, 0x2c, 0x36, 0x36,
+    0x36, 0x36, 0xe8, 0x8f, 0x6d, 0x64, 0xcb, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc3, 0xca, 0x8b, 0xcf, 0x2c,
+    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x35, 0x96, 0x75, 0xca, 0xc3, 0xcb, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0x7b, 0x81, 0xdb,
+    0x73, 0x3b, 0x44, 0x9b, 0x48, 0x48, 0x48, 0x9b,
+    0x99, 0x43, 0x94, 0x2c, 0x21, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x73, 0xdb, 0x7a, 0x7b, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0x64, 0x76, 0x7a, 0x91, 0xd5, 0x31, 0x30,
+    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x39, 0x97, 0x75, 0xdf, 0x7b, 0x64, 0xc3, 0xc3,
+    0xcb, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0x7b, 0x7a, 0xe9,
+    0xea, 0x36, 0x21, 0x26, 0x2b, 0x39, 0x33, 0x30,
+    0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xea, 0xdd, 0x8b, 0x7b, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0x64, 0x64,
+    0x76, 0x85, 0xe0, 0xd5, 0x34, 0x2b, 0x27, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0xeb, 0x63, 0x7e, 0x7a, 0x6d, 0xdf, 0x5b,
+    0x76, 0x7b, 0x64, 0x64, 0xc3, 0xcb, 0xc4, 0xc4,
+    0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0x76, 0x85, 0xdb,
+    0x79, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xec, 0xdd, 0x75, 0x76, 0xc3, 0xc4,
+    0xc4, 0xc4, 0xcb, 0xc3, 0x64, 0x76, 0xdf, 0x8b,
+    0xd6, 0xd5, 0x2f, 0x35, 0x30, 0x24, 0x22, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+    0x27, 0x31, 0xed, 0xeb, 0xdd, 0x74, 0x63, 0x90,
+    0x7e, 0x75, 0x8b, 0x6d, 0xdf, 0x76, 0x64, 0xc3,
+    0xcb, 0xcb, 0xcb, 0xcb, 0x64, 0x7a, 0x84, 0xee,
+    0x79, 0xbe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xea, 0xee, 0x63, 0x6d, 0x7b, 0x64,
+    0xcb, 0xc3, 0x64, 0x7b, 0xdf, 0x75, 0x63, 0x96,
+    0x38, 0x39, 0x2a, 0x24, 0x23, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x28, 0x27, 0x35, 0x2d, 0x41, 0xd5, 0xe7, 0x8f,
+    0xdb, 0xdd, 0xe9, 0x74, 0x84, 0x90, 0x85, 0x6d,
+    0x5b, 0x7b, 0x7b, 0xca, 0x6d, 0x90, 0xdb, 0xef,
+    0xec, 0x22, 0x36, 0x36, 0x28, 0x30, 0x30, 0x30,
+    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x25, 0x36,
+    0x36, 0x21, 0xd4, 0x80, 0xe9, 0x7e, 0x6d, 0x76,
+    0xca, 0x76, 0x6d, 0x85, 0x63, 0xdb, 0xd5, 0x34,
+    0x33, 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x24, 0x27, 0x2a, 0x35, 0x2e, 0x2f,
+    0x41, 0xf0, 0xf1, 0x6c, 0x80, 0xee, 0xdb, 0x74,
+    0x84, 0x90, 0x75, 0x7e, 0x74, 0x8f, 0xef, 0x79,
+    0xe8, 0x2b, 0x9d, 0x41, 0x2f, 0x34, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x2f, 0x38,
+    0x4d, 0x37, 0xf2, 0xf3, 0x8f, 0x74, 0x63, 0x7e,
+    0x75, 0x7e, 0x63, 0xe9, 0x88, 0xe6, 0x31, 0x2a,
+    0x24, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x21, 0x22, 0x23, 0x24, 0x26, 0x30,
+    0x33, 0x39, 0x2e, 0x51, 0x41, 0xd2, 0x6c, 0xf3,
+    0x80, 0xee, 0xee, 0xee, 0xf4, 0xf3, 0xd7, 0xf5,
+    0x41, 0x34, 0x35, 0x32, 0x30, 0x27, 0x27, 0x27,
+    0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x2a,
+    0x2b, 0x34, 0xf6, 0xec, 0xf7, 0x8f, 0xdd, 0xe9,
+    0xe9, 0xdd, 0xee, 0x6c, 0x41, 0x39, 0x27, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22,
+    0x28, 0x24, 0x26, 0x2a, 0x33, 0x2c, 0x2f, 0x41,
+    0xf8, 0xd7, 0x79, 0x79, 0x79, 0xec, 0xf9, 0x51,
+    0x39, 0x30, 0x24, 0x23, 0x22, 0x22, 0x22, 0x22,
+    0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23,
+    0x24, 0x2a, 0x31, 0xfa, 0xea, 0x79, 0xf3, 0x80,
+    0xf7, 0xdc, 0xfb, 0x2f, 0x35, 0x26, 0x23, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x22, 0x23, 0x28, 0x25, 0x30, 0x2b,
+    0x31, 0x2f, 0xf6, 0xfa, 0xfa, 0x2f, 0x2e, 0x33,
+    0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x28, 0x27, 0x35, 0x34, 0xfa, 0xfa, 0xfa,
+    0xfc, 0xf6, 0x2e, 0x33, 0x25, 0x23, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x23, 0x28,
+    0x26, 0x30, 0x32, 0x2b, 0x33, 0x2a, 0x26, 0x28,
+    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x25, 0x30, 0x33, 0x35, 0x35,
+    0x2b, 0x2a, 0x26, 0x28, 0x22, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x21, 0x22, 0x23, 0x28, 0x28, 0x23, 0x22, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x23, 0x28, 0x24, 0x24,
+    0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 };
 
-unsigned char linux_logo16_red[0];
-unsigned char linux_logo16_green[0];
-unsigned char linux_logo16_blue[0];
 unsigned char linux_logo16[0];
 
-#else
+#endif /* INCLUDE_LINUX_LOGO_DATA */
 
-/* prototypes only */
-extern unsigned char linux_logo_red[];
-extern unsigned char linux_logo_green[];
-extern unsigned char linux_logo_blue[];
-extern unsigned char linux_logo[];
-extern unsigned char linux_logo_bw[];
-extern unsigned char linux_logo16_red[];
-extern unsigned char linux_logo16_green[];
-extern unsigned char linux_logo16_blue[];
-extern unsigned char linux_logo16[];
+#include <linux/linux_logo.h>
 
-#endif
diff -u --recursive --new-file v2.4.5/linux/include/asm-sparc64/sab82532.h linux/include/asm-sparc64/sab82532.h
--- v2.4.5/linux/include/asm-sparc64/sab82532.h	Fri Apr 14 09:37:10 2000
+++ linux/include/asm-sparc64/sab82532.h	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-/* $Id: sab82532.h,v 1.6 2000/04/13 07:22:35 ecd Exp $
+/* $Id: sab82532.h,v 1.7 2001/05/23 23:09:10 ecd Exp $
  * sab82532.h: Register Definitions for the Siemens SAB82532 DUSCC
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
@@ -9,6 +9,7 @@
 
 #include <linux/types.h>
 #include <linux/serial.h>
+#include <linux/circ_buf.h>
 
 struct sab82532_async_rd_regs {
 	u8	rfifo[0x20];	/* Receive FIFO				*/
@@ -150,7 +151,7 @@
 	int				 close_delay;
 	unsigned short			 closing_wait;
 	unsigned short			 closing_wait2;
-	int				 all_sent;
+	unsigned long			 irqflags;
 	int				 is_console;
 	unsigned char			 interrupt_mask0;
 	unsigned char			 interrupt_mask1;
@@ -166,10 +167,7 @@
 	int				 blocked_open;
 	long				 session;
 	long				 pgrp;
-	unsigned char			*xmit_buf;
-	int				 xmit_head;
-	int				 xmit_tail;
-	int				 xmit_cnt;
+	struct circ_buf			 xmit;
 	struct tq_struct		 tqueue;
 	struct tq_struct		 tqueue_hangup;
 	struct async_icount		 icount;
@@ -181,6 +179,11 @@
 	struct sab82532			*next;
 	struct sab82532			*prev;
 };
+
+
+/* irqflags bits */
+#define SAB82532_ALLS			0x00000001
+#define SAB82532_XPR			0x00000002
 
 
 /* RFIFO Status Byte */
diff -u --recursive --new-file v2.4.5/linux/include/asm-sparc64/socket.h linux/include/asm-sparc64/socket.h
--- v2.4.5/linux/include/asm-sparc64/socket.h	Sat Feb  3 11:26:44 2001
+++ linux/include/asm-sparc64/socket.h	Wed Jun 20 21:00:55 2001
@@ -1,4 +1,4 @@
-/* $Id: socket.h,v 1.9 2001/01/30 07:48:30 davem Exp $ */
+/* $Id: socket.h,v 1.10 2001/06/13 16:25:03 davem Exp $ */
 #ifndef _ASM_SOCKET_H
 #define _ASM_SOCKET_H
 
@@ -63,6 +63,7 @@
 					/* level.  For writing rarp and	*/
 					/* other similar things on the	*/
 					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
 #endif
 
 #endif /* _ASM_SOCKET_H */
diff -u --recursive --new-file v2.4.5/linux/include/asm-sparc64/softirq.h linux/include/asm-sparc64/softirq.h
--- v2.4.5/linux/include/asm-sparc64/softirq.h	Sun Aug  6 12:42:21 2000
+++ linux/include/asm-sparc64/softirq.h	Tue Jun 12 11:08:46 2001
@@ -11,8 +11,21 @@
 #include <asm/system.h>		/* for membar() */
 
 #define local_bh_disable()	(local_bh_count(smp_processor_id())++)
-#define local_bh_enable()	(local_bh_count(smp_processor_id())--)
-
+#define __local_bh_enable()	(local_bh_count(smp_processor_id())--)
+#define local_bh_enable()			  \
+do { if (!--local_bh_count(smp_processor_id()) && \
+	 softirq_pending(smp_processor_id())) {   \
+		do_softirq();			  \
+		__sti();			  \
+     }						  \
+} while (0)
+#define __cpu_raise_softirq(cpu, nr)	(softirq_pending(cpu) |= (1<<nr))
+#define raise_softirq(nr)				\
+do {	unsigned long flags;				\
+	local_irq_save(flags);				\
+	__cpu_raise_softirq(smp_processor_id(), nr);	\
+	local_irq_restore(flags);			\
+} while (0)
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
 #endif /* !(__SPARC64_SOFTIRQ_H) */
diff -u --recursive --new-file v2.4.5/linux/include/asm-sparc64/string.h linux/include/asm-sparc64/string.h
--- v2.4.5/linux/include/asm-sparc64/string.h	Mon Oct 30 14:34:12 2000
+++ linux/include/asm-sparc64/string.h	Tue Jun 12 11:08:46 2001
@@ -1,4 +1,4 @@
-/* $Id: string.h,v 1.18 2000/10/30 21:01:41 davem Exp $
+/* $Id: string.h,v 1.19 2001/06/05 20:56:33 davem Exp $
  * string.h: External definitions for optimized assembly string
  *           routines for the Linux Kernel.
  *
@@ -105,6 +105,7 @@
 })
 
 #define __HAVE_ARCH_MEMCMP
+extern int memcmp(const void *,const void *,__kernel_size_t);
 
 /* Now the str*() stuff... */
 #define __HAVE_ARCH_STRLEN
diff -u --recursive --new-file v2.4.5/linux/include/asm-sparc64/termios.h linux/include/asm-sparc64/termios.h
--- v2.4.5/linux/include/asm-sparc64/termios.h	Fri Feb  9 11:37:03 2001
+++ linux/include/asm-sparc64/termios.h	Mon Jun 11 19:15:27 2001
@@ -1,4 +1,4 @@
-/* $Id: termios.h,v 1.10 2001/02/05 05:54:29 davem Exp $ */
+/* $Id: termios.h,v 1.11 2001/06/01 08:12:11 davem Exp $ */
 #ifndef _SPARC64_TERMIOS_H
 #define _SPARC64_TERMIOS_H
 
@@ -70,6 +70,7 @@
 #define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
 #define N_HDLC		13	/* synchronous HDLC */
 #define N_SYNC_PPP	14	/* synchronous PPP */
+#define N_HCI		15  /* Bluetooth HCI UART */
 
 #ifdef __KERNEL__
 
diff -u --recursive --new-file v2.4.5/linux/include/linux/acpi.h linux/include/linux/acpi.h
--- v2.4.5/linux/include/linux/acpi.h	Fri Feb  9 11:45:58 2001
+++ linux/include/linux/acpi.h	Wed Jun 20 17:47:40 2001
@@ -155,7 +155,7 @@
 	ACPI_FACS,
 	ACPI_XSDT,
 	ACPI_PMTIMER,
-	ACPI_BATTERY,
+	ACPI_BATT,
 };
 
 #define ACPI_SLP_TYP_DISABLED	(~0UL)
diff -u --recursive --new-file v2.4.5/linux/include/linux/coda_cache.h linux/include/linux/coda_cache.h
--- v2.4.5/linux/include/linux/coda_cache.h	Tue Sep 19 15:08:59 2000
+++ linux/include/linux/coda_cache.h	Tue Jun 12 11:06:54 2001
@@ -19,4 +19,4 @@
 /* for downcalls and attributes and lookups */
 void coda_flag_inode_children(struct inode *inode, int flag);
 
-#endif _CFSNC_HEADER_
+#endif /* _CFSNC_HEADER_ */
diff -u --recursive --new-file v2.4.5/linux/include/linux/dcache.h linux/include/linux/dcache.h
--- v2.4.5/linux/include/linux/dcache.h	Fri May 25 18:01:26 2001
+++ linux/include/linux/dcache.h	Wed Jun 27 16:01:21 2001
@@ -68,12 +68,12 @@
 	unsigned int d_flags;
 	struct inode  * d_inode;	/* Where the name belongs to - NULL is negative */
 	struct dentry * d_parent;	/* parent directory */
-	struct list_head d_vfsmnt;
 	struct list_head d_hash;	/* lookup hash list */
 	struct list_head d_lru;		/* d_count = 0 LRU list */
 	struct list_head d_child;	/* child of parent list */
 	struct list_head d_subdirs;	/* our children */
 	struct list_head d_alias;	/* inode alias list */
+	int d_mounted;
 	struct qstr d_name;
 	unsigned long d_time;		/* used by d_revalidate */
 	struct dentry_operations  *d_op;
@@ -265,9 +265,10 @@
 
 static __inline__ int d_mountpoint(struct dentry *dentry)
 {
-	return !list_empty(&dentry->d_vfsmnt);
+	return dentry->d_mounted;
 }
 
+extern struct vfsmount *lookup_mnt(struct vfsmount *, struct dentry *);
 #endif /* __KERNEL__ */
 
 #endif	/* __LINUX_DCACHE_H */
diff -u --recursive --new-file v2.4.5/linux/include/linux/devfs_fs_kernel.h linux/include/linux/devfs_fs_kernel.h
--- v2.4.5/linux/include/linux/devfs_fs_kernel.h	Fri May 25 18:01:28 2001
+++ linux/include/linux/devfs_fs_kernel.h	Wed Jun 27 16:01:22 2001
@@ -163,7 +163,7 @@
 {
     return -ENOSYS;
 }
-static inline void *devfs_get_info (devfs_handle_t de, unsigned long size)
+static inline void *devfs_get_info (devfs_handle_t de)
 {
     return NULL;
 }
diff -u --recursive --new-file v2.4.5/linux/include/linux/ext2_fs.h linux/include/linux/ext2_fs.h
--- v2.4.5/linux/include/linux/ext2_fs.h	Fri May 25 18:01:27 2001
+++ linux/include/linux/ext2_fs.h	Wed Jun 27 16:01:21 2001
@@ -498,16 +498,17 @@
  * Ext2 directory file types.  Only the low 3 bits are used.  The
  * other bits are reserved for now.
  */
-#define EXT2_FT_UNKNOWN		0
-#define EXT2_FT_REG_FILE	1
-#define EXT2_FT_DIR		2
-#define EXT2_FT_CHRDEV		3
-#define EXT2_FT_BLKDEV 		4
-#define EXT2_FT_FIFO		5
-#define EXT2_FT_SOCK		6
-#define EXT2_FT_SYMLINK		7
-
-#define EXT2_FT_MAX		8
+enum {
+	EXT2_FT_UNKNOWN,
+	EXT2_FT_REG_FILE,
+	EXT2_FT_DIR,
+	EXT2_FT_CHRDEV,
+	EXT2_FT_BLKDEV,
+	EXT2_FT_FIFO,
+	EXT2_FT_SOCK,
+	EXT2_FT_SYMLINK,
+	EXT2_FT_MAX
+};
 
 /*
  * EXT2_DIR_PAD defines the directory entries boundaries
@@ -552,9 +553,6 @@
 extern unsigned long ext2_count_free (struct buffer_head *, unsigned);
 
 /* dir.c */
-extern int ext2_check_dir_entry (const char *, struct inode *,
-				 struct ext2_dir_entry_2 *, struct buffer_head *,
-				 unsigned long);
 
 /* file.c */
 extern int ext2_read (struct inode *, struct file *, char *, int);
@@ -613,6 +611,14 @@
 
 /* dir.c */
 extern struct file_operations ext2_dir_operations;
+extern int ext2_add_link (struct dentry *, struct inode *);
+extern ino_t ext2_inode_by_name(struct inode *, struct dentry *);
+extern int ext2_make_empty(struct inode *, struct inode *);
+extern struct ext2_dir_entry_2 * ext2_find_entry (struct inode *,struct dentry *, struct page **);
+extern int ext2_delete_entry (struct ext2_dir_entry_2 *, struct page *);
+extern int ext2_empty_dir (struct inode *);
+extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **);
+extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *);
 
 /* file.c */
 extern struct inode_operations ext2_file_inode_operations;
diff -u --recursive --new-file v2.4.5/linux/include/linux/fs.h linux/include/linux/fs.h
--- v2.4.5/linux/include/linux/fs.h	Fri May 25 18:01:28 2001
+++ linux/include/linux/fs.h	Wed Jun 27 16:01:22 2001
@@ -204,15 +204,22 @@
 
 extern void buffer_init(unsigned long);
 extern void inode_init(unsigned long);
+extern void mnt_init(unsigned long);
 
 /* bh state bits */
-#define BH_Uptodate	0	/* 1 if the buffer contains valid data */
-#define BH_Dirty	1	/* 1 if the buffer is dirty */
-#define BH_Lock		2	/* 1 if the buffer is locked */
-#define BH_Req		3	/* 0 if the buffer has been invalidated */
-#define BH_Mapped	4	/* 1 if the buffer has a disk mapping */
-#define BH_New		5	/* 1 if the buffer is new and not yet written out */
-#define BH_Protected	6	/* 1 if the buffer is protected */
+enum bh_state_bits {
+	BH_Uptodate,	/* 1 if the buffer contains valid data */
+	BH_Dirty,	/* 1 if the buffer is dirty */
+	BH_Lock,	/* 1 if the buffer is locked */
+	BH_Req,		/* 0 if the buffer has been invalidated */
+	BH_Mapped,	/* 1 if the buffer has a disk mapping */
+	BH_New,		/* 1 if the buffer is new and not yet written out */
+	BH_Protected,	/* 1 if the buffer is protected */
+
+	BH_PrivateStart,/* not a state bit, but the first bit available
+			 * for private allocation by other entities
+			 */
+};
 
 /*
  * Try to keep the most commonly used fields in single cache lines (16
@@ -835,6 +842,31 @@
 	int (*remount_fs) (struct super_block *, int *, char *);
 	void (*clear_inode) (struct inode *);
 	void (*umount_begin) (struct super_block *);
+
+	/* Following are for knfsd to interact with "interesting" filesystems
+	 * Currently just reiserfs, but possibly FAT and others later
+	 *
+	 * fh_to_dentry is given a filehandle fragement with length, and a type flag
+	 *   and must return a dentry for the referenced object or, if "parent" is
+	 *   set, a dentry for the parent of the object.
+	 *   If a dentry cannot be found, a "root" dentry should be created and
+	 *   flaged as DCACHE_NFSD_DISCONNECTED. nfsd_iget is an example implementation.
+	 *
+	 * dentry_to_fh is given a dentry and must generate the filesys specific
+	 *   part of the file handle.  Available length is passed in *lenp and used
+	 *   length should be returned therein.
+	 *   If need_parent is set, then dentry_to_fh should encode sufficient information
+	 *   to find the (current) parent.
+	 *   dentry_to_fh should return a 1byte "type" which will be passed back in
+	 *   the fhtype arguement to fh_to_dentry.  Type of 0 is reserved.
+	 *   If filesystem was exportable before the introduction of fh_to_dentry,
+	 *   types 1 and 2 should be used is that same way as the generic code.
+	 *   Type 255 means error.
+	 *
+	 * Lengths are in units of 4bytes, not bytes.
+	 */
+	struct dentry * (*fh_to_dentry)(struct super_block *sb, __u32 *fh, int len, int fhtype, int parent);
+	int (*dentry_to_fh)(struct dentry *, __u32 *fh, int *lenp, int need_parent);
 };
 
 /* Inode state bits.. */
@@ -1312,7 +1344,6 @@
 
 extern struct file_system_type *get_fs_type(const char *name);
 extern struct super_block *get_super(kdev_t);
-extern void put_super(kdev_t);
 static inline int is_mounted(kdev_t dev)
 {
 	struct super_block *sb = get_super(dev);
diff -u --recursive --new-file v2.4.5/linux/include/linux/ibmtr.h linux/include/linux/ibmtr.h
--- v2.4.5/linux/include/linux/ibmtr.h	Sun Apr  2 15:38:54 2000
+++ linux/include/linux/ibmtr.h	Wed Jun 20 11:13:18 2001
@@ -1,3 +1,6 @@
+#ifndef __LINUX_IBMTR_H__
+#define __LINUX_IBMTR_H__
+
 /* Definitions for an IBM Token Ring card. */
 /* This file is distributed under the GNU GPL   */
 
@@ -452,3 +455,4 @@
 	unsigned char funct_address[4];
 };
 
+#endif /* __LINUX_IBMTR_H__ */
diff -u --recursive --new-file v2.4.5/linux/include/linux/if_arp.h linux/include/linux/if_arp.h
--- v2.4.5/linux/include/linux/if_arp.h	Fri May 25 18:02:10 2001
+++ linux/include/linux/if_arp.h	Wed Jun 27 16:02:35 2001
@@ -79,6 +79,7 @@
 #define ARPHRD_FCFABRIC	787		/* Fibrechannel fabric		*/
 	/* 787->799 reserved for fibrechannel media types */
 #define ARPHRD_IEEE802_TR 800		/* Magic type ident for TR	*/
+#define ARPHRD_IEEE80211 801		/* IEEE 802.11			*/
 
 #define ARPHRD_VOID	  0xFFFF	/* Void type, nothing is known */
 
diff -u --recursive --new-file v2.4.5/linux/include/linux/if_hippi.h linux/include/linux/if_hippi.h
--- v2.4.5/linux/include/linux/if_hippi.h	Fri May 25 18:02:32 2001
+++ linux/include/linux/if_hippi.h	Wed Jun 27 16:03:57 2001
@@ -110,13 +110,13 @@
 struct hippi_le_hdr
 {
 #if defined (__BIG_ENDIAN_BITFIELD)
-	unsigned long	fc:3;
-	unsigned long	double_wide:1;
-	unsigned long	message_type:4;
+	__u8		fc:3;
+	__u8		double_wide:1;
+	__u8		message_type:4;
 #elif defined(__LITTLE_ENDIAN_BITFIELD)
-	unsigned long	message_type:4;
-	unsigned long	double_wide:1;
-	unsigned long	fc:3;
+	__u8		message_type:4;
+	__u8		double_wide:1;
+	__u8		fc:3;
 #endif
 	__u8		dest_switch_addr[3];
 #if defined (__BIG_ENDIAN_BITFIELD)
diff -u --recursive --new-file v2.4.5/linux/include/linux/if_tun.h linux/include/linux/if_tun.h
--- v2.4.5/linux/include/linux/if_tun.h	Wed Aug 23 09:30:13 2000
+++ linux/include/linux/if_tun.h	Mon Jun 11 19:15:27 2001
@@ -12,7 +12,7 @@
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  *  GNU General Public License for more details.
  *
- *  $Id: if_tun.h,v 1.1 2000/08/23 05:59:28 davem Exp $
+ *  $Id: if_tun.h,v 1.2 2001/06/01 18:39:47 davem Exp $
  */
 
 #ifndef __IF_TUN_H
@@ -32,15 +32,18 @@
 #endif
 
 struct tun_struct {
-	char 			name[8];
+	char 			*name;
 	unsigned long 		flags;
+	int			attached;
+	uid_t			owner;
 
-	struct fasync_struct    *fasync;
 	wait_queue_head_t	read_wait;
+	struct sk_buff_head	readq;
 
 	struct net_device	dev;
-	struct sk_buff_head	txq;
-        struct net_device_stats	stats;
+	struct net_device_stats	stats;
+
+	struct fasync_struct    *fasync;
 
 #ifdef TUN_DEBUG	
 	int debug;
@@ -53,14 +56,8 @@
 
 #endif /* __KERNEL__ */
 
-/* Number of devices */
-#define TUN_MAX_DEV	255
-
-/* TX queue size */
-#define TUN_TXQ_SIZE	10
-
-/* Max frame size */
-#define TUN_MAX_FRAME	4096
+/* Read queue size */
+#define TUN_READQ_SIZE	10
 
 /* TUN device flags */
 #define TUN_TUN_DEV 	0x0001	
@@ -70,22 +67,25 @@
 #define TUN_FASYNC	0x0010
 #define TUN_NOCHECKSUM	0x0020
 #define TUN_NO_PI	0x0040
-
-#define TUN_IFF_SET	0x1000
+#define TUN_ONE_QUEUE	0x0080
+#define TUN_PERSIST 	0x0100	
 
 /* Ioctl defines */
-#define TUNSETNOCSUM (('T'<< 8) | 200) 
-#define TUNSETDEBUG  (('T'<< 8) | 201) 
-#define TUNSETIFF    (('T'<< 8) | 202) 
+#define TUNSETNOCSUM  _IOW('T', 200, int) 
+#define TUNSETDEBUG   _IOW('T', 201, int) 
+#define TUNSETIFF     _IOW('T', 202, int) 
+#define TUNSETPERSIST _IOW('T', 203, int) 
+#define TUNSETOWNER   _IOW('T', 204, int)
 
 /* TUNSETIFF ifr flags */
 #define IFF_TUN		0x0001
 #define IFF_TAP		0x0002
 #define IFF_NO_PI	0x1000
+#define IFF_ONE_QUEUE	0x2000
 
 struct tun_pi {
-   unsigned short flags;
-   unsigned short proto;
+	unsigned short flags;
+	unsigned short proto;
 };
 #define TUN_PKT_STRIP	0x0001
 
diff -u --recursive --new-file v2.4.5/linux/include/linux/interrupt.h linux/include/linux/interrupt.h
--- v2.4.5/linux/include/linux/interrupt.h	Fri May 25 18:01:27 2001
+++ linux/include/linux/interrupt.h	Wed Jun 27 16:01:22 2001
@@ -74,22 +74,6 @@
 asmlinkage void do_softirq(void);
 extern void open_softirq(int nr, void (*action)(struct softirq_action*), void *data);
 
-static inline void __cpu_raise_softirq(int cpu, int nr)
-{
-	softirq_active(cpu) |= (1<<nr);
-}
-
-
-/* I do not want to use atomic variables now, so that cli/sti */
-static inline void raise_softirq(int nr)
-{
-	unsigned long flags;
-
-	local_irq_save(flags);
-	__cpu_raise_softirq(smp_processor_id(), nr);
-	local_irq_restore(flags);
-}
-
 extern void softirq_init(void);
 
 
@@ -133,7 +117,7 @@
 enum
 {
 	TASKLET_STATE_SCHED,	/* Tasklet is scheduled for execution */
-	TASKLET_STATE_RUN	/* Tasklet is running (SMP only) */
+	TASKLET_STATE_RUN	/* Tasklet is running */
 };
 
 struct tasklet_head
@@ -144,44 +128,12 @@
 extern struct tasklet_head tasklet_vec[NR_CPUS];
 extern struct tasklet_head tasklet_hi_vec[NR_CPUS];
 
-#ifdef CONFIG_SMP
 #define tasklet_trylock(t) (!test_and_set_bit(TASKLET_STATE_RUN, &(t)->state))
-#define tasklet_unlock_wait(t) while (test_bit(TASKLET_STATE_RUN, &(t)->state)) { barrier(); }
 #define tasklet_unlock(t) clear_bit(TASKLET_STATE_RUN, &(t)->state)
-#else
-#define tasklet_trylock(t) 1
-#define tasklet_unlock_wait(t) do { } while (0)
-#define tasklet_unlock(t) do { } while (0)
-#endif
-
-static inline void tasklet_schedule(struct tasklet_struct *t)
-{
-	if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
-		int cpu = smp_processor_id();
-		unsigned long flags;
-
-		local_irq_save(flags);
-		t->next = tasklet_vec[cpu].list;
-		tasklet_vec[cpu].list = t;
-		__cpu_raise_softirq(cpu, TASKLET_SOFTIRQ);
-		local_irq_restore(flags);
-	}
-}
-
-static inline void tasklet_hi_schedule(struct tasklet_struct *t)
-{
-	if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
-		int cpu = smp_processor_id();
-		unsigned long flags;
-
-		local_irq_save(flags);
-		t->next = tasklet_hi_vec[cpu].list;
-		tasklet_hi_vec[cpu].list = t;
-		__cpu_raise_softirq(cpu, HI_SOFTIRQ);
-		local_irq_restore(flags);
-	}
-}
+#define tasklet_unlock_wait(t) while (test_bit(TASKLET_STATE_RUN, &(t)->state)) { barrier(); }
 
+extern void tasklet_schedule(struct tasklet_struct *t);
+extern void tasklet_hi_schedule(struct tasklet_struct *t);
 
 static inline void tasklet_disable_nosync(struct tasklet_struct *t)
 {
@@ -196,7 +148,14 @@
 
 static inline void tasklet_enable(struct tasklet_struct *t)
 {
-	atomic_dec(&t->count);
+	if (atomic_dec_and_test(&t->count))
+		tasklet_schedule(t);
+}
+
+static inline void tasklet_hi_enable(struct tasklet_struct *t)
+{
+	if (atomic_dec_and_test(&t->count))
+		tasklet_hi_schedule(t);
 }
 
 extern void tasklet_kill(struct tasklet_struct *t);
diff -u --recursive --new-file v2.4.5/linux/include/linux/irq.h linux/include/linux/irq.h
--- v2.4.5/linux/include/linux/irq.h	Fri May 25 18:01:27 2001
+++ linux/include/linux/irq.h	Wed Jun 27 16:01:22 2001
@@ -62,7 +62,4 @@
 extern hw_irq_controller no_irq_type;  /* needed in every arch ? */
 extern void no_action(int cpl, void *dev_id, struct pt_regs *regs);
 
-extern volatile unsigned long irq_err_count;
-
 #endif /* __asm_h */
-
diff -u --recursive --new-file v2.4.5/linux/include/linux/irq_cpustat.h linux/include/linux/irq_cpustat.h
--- v2.4.5/linux/include/linux/irq_cpustat.h	Fri May 25 18:01:26 2001
+++ linux/include/linux/irq_cpustat.h	Wed Jun 27 16:01:21 2001
@@ -26,8 +26,7 @@
 #endif	
 
   /* arch independent irq_stat fields */
-#define softirq_active(cpu)	__IRQ_STAT((cpu), __softirq_active)
-#define softirq_mask(cpu)	__IRQ_STAT((cpu), __softirq_mask)
+#define softirq_pending(cpu)	__IRQ_STAT((cpu), __softirq_pending)
 #define local_irq_count(cpu)	__IRQ_STAT((cpu), __local_irq_count)
 #define local_bh_count(cpu)	__IRQ_STAT((cpu), __local_bh_count)
 #define syscall_count(cpu)	__IRQ_STAT((cpu), __syscall_count)
diff -u --recursive --new-file v2.4.5/linux/include/linux/kernel.h linux/include/linux/kernel.h
--- v2.4.5/linux/include/linux/kernel.h	Sun May 20 12:11:39 2001
+++ linux/include/linux/kernel.h	Tue Jun 12 11:51:43 2001
@@ -125,6 +125,7 @@
 	unsigned long totalswap;	/* Total swap space size */
 	unsigned long freeswap;		/* swap space still available */
 	unsigned short procs;		/* Number of current processes */
+	unsigned short pad;		/* explicit padding for m68k */
 	unsigned long totalhigh;	/* Total high memory size */
 	unsigned long freehigh;		/* Available high memory size */
 	unsigned int mem_unit;		/* Memory unit size in bytes */
diff -u --recursive --new-file v2.4.5/linux/include/linux/linux_logo.h linux/include/linux/linux_logo.h
--- v2.4.5/linux/include/linux/linux_logo.h	Wed Sep 30 14:16:33 1998
+++ linux/include/linux/linux_logo.h	Mon Jun 11 19:15:27 2001
@@ -18,1428 +18,1403 @@
  * but should contain %s to display the version
  */
 
-#if LINUX_LOGO_COLORS == 214
+#ifndef __HAVE_ARCH_LINUX_LOGO
+#define LINUX_LOGO_COLORS	187
+#endif
+
+#ifdef INCLUDE_LINUX_LOGO_DATA
+
+#ifndef __HAVE_ARCH_LINUX_LOGO
 
 unsigned char linux_logo_red[] __initdata = {
-  0x02, 0x9E, 0xE9, 0xC4, 0x50, 0xC9, 0xC4, 0xE9,
-  0x65, 0xE3, 0xC2, 0x25, 0xA4, 0xEC, 0x90, 0xA6,
-  0xC4, 0x6A, 0xD1, 0xF3, 0x12, 0xED, 0xA0, 0xC2,
-  0xB8, 0xD5, 0xDB, 0xD2, 0x3E, 0x16, 0xEB, 0x54,
-  0xA9, 0xCD, 0xF5, 0x0A, 0xBA, 0xB3, 0xDC, 0x74,
-  0xCE, 0xF6, 0xD3, 0xC5, 0xEA, 0xB8, 0xED, 0x5E,
-  0xE5, 0x26, 0xF4, 0xA9, 0x82, 0x94, 0xE6, 0x38,
-  0xF2, 0x0F, 0x7F, 0x49, 0xE5, 0xF4, 0xD3, 0xC3,
-  0xC2, 0x1E, 0xD5, 0xC6, 0xA4, 0xFA, 0x0A, 0xBA,
-  0xD4, 0xEB, 0xEA, 0xEC, 0xA8, 0xBC, 0xB4, 0xDC,
-  0x84, 0xE4, 0xCE, 0xEC, 0x92, 0xCD, 0xDC, 0x8B,
-  0xCC, 0x1E, 0xF6, 0xB2, 0x60, 0x2A, 0x96, 0x52,
-  0x0F, 0xBD, 0xFA, 0xCC, 0xB8, 0x7A, 0x4C, 0xD2,
-  0x06, 0xEF, 0x44, 0x64, 0xF4, 0xBA, 0xCE, 0xE6,
-  0x8A, 0x6F, 0x3C, 0x70, 0x7C, 0x9C, 0xBA, 0xDF,
-  0x2C, 0x4D, 0x3B, 0xCA, 0xDE, 0xCE, 0xEE, 0x46,
-  0x6A, 0xAC, 0x96, 0xE5, 0x96, 0x7A, 0xBA, 0xB6,
-  0xE2, 0x7E, 0xAA, 0xC5, 0x96, 0x9E, 0xC2, 0xAA,
-  0xDA, 0x35, 0xB6, 0x82, 0x88, 0xBE, 0xC2, 0x9E,
-  0xB4, 0xD5, 0xDA, 0x9C, 0xA0, 0xD0, 0xA8, 0xC7,
-  0x72, 0xF2, 0xDB, 0x76, 0xDC, 0xBE, 0xAA, 0xF4,
-  0x87, 0x2F, 0x53, 0x8E, 0x36, 0xCE, 0xE6, 0xCA,
-  0xCB, 0xE4, 0xD6, 0xAA, 0x42, 0x5D, 0xB4, 0x59,
-  0x1C, 0xC8, 0x96, 0x6C, 0xDA, 0xCE, 0xE6, 0xCB,
-  0x96, 0x16, 0xFA, 0xBE, 0xAE, 0xFE, 0x6E, 0xD6,
-  0xCE, 0xB6, 0xE5, 0xED, 0xDB, 0xDC, 0xF4, 0x72,
-  0x1F, 0xAE, 0xE6, 0xC2, 0xCA, 0xC4
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
+    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
+    0xc3, 0x65, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
+    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
+    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x76, 0x79,
+    0x62, 0x36, 0x9a, 0xe2, 0xec, 0xe1, 0xb8, 0xd7,
+    0xaf, 0x25, 0xbc, 0xc0, 0xef, 0xea, 0xe8, 0xe8,
+    0xf5, 0xf1, 0xda, 0xd3, 0x79, 0xdb, 0xf4, 0xf6,
+    0xf6, 0xf6, 0xe2, 0x3d, 0xb4, 0xce, 0xe6, 0xee,
+    0xf6, 0x68, 0xd8, 0xec, 0xf5, 0xc6, 0xc8, 0x9c,
+    0x89, 0xd2, 0xee, 0xcb, 0xb9, 0xd2, 0x66, 0x5e,
+    0x8b, 0xbe, 0xa8, 0xd5, 0xca, 0xb6, 0xae, 0x9c,
+    0xc5, 0xbe, 0xbe, 0xca, 0x90, 0xb2, 0x9a, 0xa8,
+    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x12,
+    0x4a, 0x8e, 0xf2, 0xf6, 0xf6, 0xee, 0xb5, 0xe4,
+    0xf1, 0x26, 0x9a, 0xea, 0xf6, 0xe0, 0xd2, 0x16,
+    0x9a, 0x2e, 0x70, 0xd6, 0x46, 0x7c, 0xb4, 0x62,
+    0xd6, 0xa3, 0x74, 0xa7, 0xa2, 0xca, 0xe0, 0xae,
+    0xbe, 0xce, 0xa3, 0x8e, 0x6d, 0x8e, 0x32, 0xaf,
+    0x50, 0x9e, 0x5b, 0x8a, 0x98, 0x82, 0x7a, 0x82,
+    0x56, 0x7c, 0x8a, 0x56, 0x5e, 0x86, 0x6a, 0x52,
+    0x59, 0x64, 0x5e,
 };
 
 unsigned char linux_logo_green[] __initdata = {
-  0x02, 0x88, 0xC4, 0x85, 0x44, 0xA2, 0xA8, 0xE5,
-  0x65, 0xA6, 0xC2, 0x24, 0xA4, 0xB4, 0x62, 0x86,
-  0x94, 0x44, 0xD2, 0xB6, 0x12, 0xD4, 0x73, 0x96,
-  0x92, 0x95, 0xB2, 0xC2, 0x36, 0x0E, 0xBC, 0x54,
-  0x75, 0xA5, 0xF5, 0x0A, 0xB2, 0x83, 0xC2, 0x74,
-  0x9B, 0xBD, 0xA2, 0xCA, 0xDA, 0x8C, 0xCB, 0x42,
-  0xAC, 0x12, 0xDA, 0x7B, 0x54, 0x94, 0xD2, 0x24,
-  0xBE, 0x06, 0x65, 0x33, 0xBB, 0xBC, 0xAB, 0x8C,
-  0x92, 0x1E, 0x9B, 0xB6, 0x6E, 0xFB, 0x04, 0xA2,
-  0xC8, 0xBD, 0xAD, 0xEC, 0x92, 0xBC, 0x7B, 0x9D,
-  0x84, 0xC4, 0xC4, 0xB4, 0x6C, 0x93, 0xA3, 0x5E,
-  0x8D, 0x13, 0xD6, 0x82, 0x4C, 0x2A, 0x7A, 0x5A,
-  0x0D, 0x82, 0xBB, 0xCC, 0x8B, 0x6A, 0x3C, 0xBE,
-  0x06, 0xC4, 0x44, 0x45, 0xDB, 0x96, 0xB6, 0xDE,
-  0x8A, 0x4D, 0x3C, 0x5A, 0x7C, 0x9C, 0xAA, 0xCB,
-  0x1C, 0x4D, 0x2E, 0xB2, 0xBE, 0xAA, 0xDE, 0x3E,
-  0x6A, 0xAC, 0x82, 0xE5, 0x72, 0x62, 0x92, 0x9E,
-  0xCA, 0x4A, 0x8E, 0xBE, 0x86, 0x6B, 0xAA, 0x9A,
-  0xBE, 0x34, 0xAB, 0x76, 0x6E, 0x9A, 0x9E, 0x62,
-  0x76, 0xCE, 0xD3, 0x92, 0x7C, 0xB8, 0x7E, 0xC6,
-  0x5E, 0xE2, 0xC3, 0x54, 0xAA, 0x9E, 0x8A, 0xCA,
-  0x63, 0x2D, 0x3B, 0x8E, 0x1A, 0x9E, 0xC2, 0xA6,
-  0xCB, 0xDC, 0xD6, 0x8E, 0x26, 0x5C, 0xB4, 0x45,
-  0x1C, 0xB8, 0x6E, 0x4C, 0xBC, 0xAE, 0xD6, 0x92,
-  0x63, 0x16, 0xF6, 0x8C, 0x7A, 0xFE, 0x6E, 0xBA,
-  0xC6, 0x86, 0xAA, 0xAE, 0xDB, 0xA4, 0xD4, 0x56,
-  0x0E, 0x6E, 0xB6, 0xB2, 0xBE, 0xBE
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
+    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
+    0xc3, 0x62, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
+    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
+    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x62, 0x5c,
+    0x4e, 0x26, 0x72, 0xaa, 0xba, 0xaf, 0x90, 0xae,
+    0x92, 0x1a, 0xa4, 0x85, 0xb6, 0xbe, 0xc3, 0xc8,
+    0xcf, 0xd0, 0xc2, 0xce, 0x57, 0xa2, 0xd6, 0xda,
+    0xda, 0xd7, 0xb8, 0x2a, 0x7b, 0x91, 0xae, 0xca,
+    0xda, 0x45, 0x9e, 0xb2, 0xd7, 0x9b, 0x90, 0x76,
+    0x5c, 0xa2, 0xbe, 0xa6, 0x85, 0x96, 0x4e, 0x46,
+    0x66, 0x92, 0x7a, 0x9a, 0x96, 0x9d, 0x9a, 0x6b,
+    0x8a, 0x8e, 0xb2, 0xca, 0x90, 0xa6, 0x79, 0x7c,
+    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x0e,
+    0x36, 0x86, 0xba, 0xbe, 0xe6, 0xcc, 0x8e, 0xb8,
+    0xc4, 0x1e, 0x8e, 0xae, 0xba, 0xb2, 0xa6, 0x12,
+    0x7a, 0x20, 0x64, 0xaa, 0x2f, 0x70, 0x85, 0x46,
+    0xa6, 0x6e, 0x51, 0x72, 0x92, 0xa2, 0xa6, 0x87,
+    0x96, 0xa2, 0x85, 0x7a, 0x6a, 0x6e, 0x22, 0x76,
+    0x36, 0x76, 0x3c, 0x6e, 0x63, 0x53, 0x66, 0x62,
+    0x42, 0x50, 0x56, 0x42, 0x56, 0x56, 0x56, 0x3e,
+    0x51, 0x52, 0x56,
 };
 
 unsigned char linux_logo_blue[] __initdata = {
-  0x04, 0x28, 0x10, 0x0B, 0x14, 0x14, 0x74, 0xC7,
-  0x64, 0x0E, 0xC3, 0x24, 0xA4, 0x0C, 0x10, 0x20,
-  0x0D, 0x04, 0xD1, 0x0D, 0x13, 0x22, 0x0A, 0x40,
-  0x14, 0x0C, 0x11, 0x94, 0x0C, 0x08, 0x0B, 0x56,
-  0x09, 0x47, 0xF4, 0x0B, 0x9C, 0x07, 0x54, 0x74,
-  0x0F, 0x0C, 0x0F, 0xC7, 0x6C, 0x14, 0x14, 0x11,
-  0x0B, 0x04, 0x12, 0x0C, 0x05, 0x94, 0x94, 0x0A,
-  0x34, 0x09, 0x14, 0x08, 0x2F, 0x15, 0x19, 0x11,
-  0x28, 0x0C, 0x0B, 0x94, 0x08, 0xFA, 0x08, 0x7C,
-  0xBC, 0x15, 0x0A, 0xEC, 0x64, 0xBB, 0x0A, 0x0C,
-  0x84, 0x2C, 0xA0, 0x15, 0x10, 0x0D, 0x0B, 0x0E,
-  0x0A, 0x07, 0x10, 0x3C, 0x24, 0x2C, 0x28, 0x5C,
-  0x0A, 0x0D, 0x0A, 0xC1, 0x22, 0x4C, 0x10, 0x94,
-  0x04, 0x0F, 0x45, 0x08, 0x31, 0x54, 0x3C, 0xBC,
-  0x8C, 0x09, 0x3C, 0x18, 0x7C, 0x9C, 0x7C, 0x91,
-  0x0C, 0x4D, 0x17, 0x74, 0x0C, 0x48, 0x9C, 0x3C,
-  0x6A, 0xAC, 0x5C, 0xE3, 0x29, 0x3C, 0x2C, 0x7C,
-  0x6C, 0x04, 0x14, 0xA9, 0x74, 0x07, 0x2C, 0x74,
-  0x4C, 0x34, 0x97, 0x5C, 0x38, 0x0C, 0x5C, 0x04,
-  0x0C, 0xBA, 0xBC, 0x78, 0x18, 0x88, 0x24, 0xC2,
-  0x3C, 0xB4, 0x87, 0x0C, 0x14, 0x4C, 0x3C, 0x10,
-  0x17, 0x2C, 0x0A, 0x8C, 0x04, 0x1C, 0x44, 0x2C,
-  0xCD, 0xD8, 0xD4, 0x34, 0x0C, 0x5B, 0xB4, 0x1E,
-  0x1D, 0xAC, 0x24, 0x18, 0x20, 0x5C, 0xB4, 0x1C,
-  0x09, 0x14, 0xFC, 0x0C, 0x10, 0xFC, 0x6C, 0x7C,
-  0xB4, 0x1C, 0x15, 0x17, 0xDB, 0x18, 0x21, 0x24,
-  0x04, 0x04, 0x44, 0x8C, 0x8C, 0xB7
+    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
+    0x12, 0x01, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
+    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x06, 0x65,
+    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
+    0xc3, 0x59, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
+    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
+    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x2e, 0x08,
+    0x0a, 0x06, 0x0a, 0x0b, 0x0b, 0x0f, 0x0c, 0x0f,
+    0x3d, 0x09, 0x73, 0x09, 0x0d, 0x0a, 0x10, 0x1e,
+    0x2d, 0x13, 0x86, 0xba, 0x19, 0x0a, 0x36, 0x3c,
+    0x26, 0x14, 0x0d, 0x06, 0x07, 0x0a, 0x0b, 0x0f,
+    0x4a, 0x06, 0x0a, 0x0c, 0x2b, 0x0a, 0x0b, 0x0a,
+    0x06, 0x0a, 0x0a, 0x11, 0x0b, 0x0a, 0x0a, 0x1e,
+    0x0f, 0x0d, 0x0a, 0x0b, 0x22, 0x6a, 0x72, 0x0b,
+    0x0b, 0x22, 0x90, 0xca, 0x90, 0x92, 0x3c, 0x2c,
+    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x06,
+    0x0e, 0x6a, 0x0e, 0x0e, 0xbe, 0x5b, 0x2c, 0x3e,
+    0x0e, 0x0a, 0x5a, 0x0d, 0x0e, 0x3e, 0x0a, 0x06,
+    0x2e, 0x06, 0x4e, 0x36, 0x06, 0x58, 0x24, 0x06,
+    0x3a, 0x08, 0x08, 0x07, 0x5e, 0x45, 0x0a, 0x32,
+    0x2e, 0x2a, 0x43, 0x48, 0x5f, 0x2e, 0x06, 0x06,
+    0x07, 0x24, 0x06, 0x32, 0x06, 0x06, 0x46, 0x2e,
+    0x22, 0x06, 0x06, 0x1e, 0x4c, 0x06, 0x3a, 0x22,
+    0x42, 0x34, 0x42,
 };
 
 unsigned char linux_logo[] __initdata = {
-  0xBF, 0x95, 0x90, 0xCB, 0x95, 0xA1, 0x2C, 0x2C,
-  0x95, 0x55, 0xCB, 0x90, 0xCB, 0x95, 0x2C, 0x95,
-  0xCB, 0x47, 0x94, 0x95, 0xA1, 0xD6, 0xD6, 0x2C,
-  0x90, 0x47, 0x70, 0x2C, 0x6D, 0x2A, 0x6D, 0xD6,
-  0xA1, 0x2C, 0x55, 0x95, 0x2C, 0x2C, 0x55, 0x55,
-  0x95, 0xA1, 0xA1, 0xA1, 0x6D, 0xBF, 0x2A, 0x2A,
-  0xBF, 0x83, 0xBF, 0x95, 0x90, 0xCB, 0x95, 0xA1,
-  0x2C, 0x2C, 0x95, 0x55, 0xCB, 0x90, 0xCB, 0x95,
-  0x2C, 0x95, 0xCB, 0x47, 0x94, 0x95, 0xA1, 0xD6,
-  0xD6, 0x2C, 0x90, 0x47, 0x70, 0x2C, 0x6D, 0x2A,
-  0x95, 0x47, 0x47, 0x90, 0x2C, 0x2C, 0x2C, 0x95,
-  0x55, 0x55, 0xCB, 0x90, 0xCB, 0x55, 0x55, 0xCB,
-  0x47, 0xE6, 0x70, 0x95, 0xD6, 0xD6, 0xA1, 0x2C,
-  0x55, 0x55, 0x95, 0xD6, 0x6D, 0xD6, 0xA1, 0x2C,
-  0x2C, 0x95, 0x55, 0x95, 0x95, 0x95, 0x2C, 0x2C,
-  0xA1, 0xA1, 0x2C, 0x2C, 0xA1, 0xD6, 0xD6, 0xD6,
-  0xD6, 0xD6, 0x95, 0x47, 0x47, 0x90, 0x2C, 0x2C,
-  0x2C, 0x95, 0x55, 0x55, 0xCB, 0x90, 0xCB, 0x55,
-  0x55, 0xCB, 0x47, 0xE6, 0x70, 0x95, 0xD6, 0xD6,
-  0xA1, 0x2C, 0x55, 0x55, 0x95, 0xD6, 0x6D, 0xD6,
-  0x90, 0x47, 0x47, 0x70, 0x2C, 0xA1, 0x2C, 0x95,
-  0x55, 0x55, 0x90, 0xCB, 0x55, 0x55, 0x55, 0x70,
-  0x94, 0x70, 0x95, 0xA1, 0xD6, 0xD6, 0xA1, 0x2C,
-  0x95, 0x95, 0x2C, 0xA1, 0xD6, 0xA1, 0x2C, 0x2C,
-  0x95, 0x55, 0xCB, 0x95, 0xD6, 0xA1, 0x2C, 0x95,
-  0xA1, 0xD6, 0xD6, 0xA1, 0xA1, 0xD6, 0xA1, 0xA1,
-  0xA1, 0x2C, 0x90, 0x47, 0x47, 0x70, 0x2C, 0xA1,
-  0x2C, 0x95, 0x55, 0x55, 0x90, 0xCB, 0x55, 0x55,
-  0x55, 0x70, 0x94, 0x70, 0x95, 0xA1, 0xD6, 0xD6,
-  0xA1, 0x2C, 0x95, 0x95, 0x2C, 0xD6, 0xD6, 0xA1,
-  0x94, 0xA0, 0x47, 0x55, 0x2C, 0xD6, 0xA1, 0x95,
-  0x55, 0x55, 0xCB, 0xCB, 0x55, 0x55, 0xCB, 0xCB,
-  0x55, 0x95, 0x2C, 0xA1, 0xD6, 0xD6, 0xA1, 0x2C,
-  0x95, 0x95, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x95,
-  0x55, 0x55, 0x2C, 0x3F, 0x80, 0x20, 0x88, 0x88,
-  0x88, 0x20, 0x88, 0xB1, 0x2C, 0xA1, 0x2C, 0x2C,
-  0x95, 0xCB, 0x94, 0xA0, 0x47, 0x55, 0x2C, 0xD6,
-  0xA1, 0x95, 0x55, 0x55, 0xCB, 0xCB, 0x55, 0x55,
-  0xCB, 0xCB, 0x55, 0x95, 0x2C, 0xA1, 0xD6, 0xD6,
-  0xA1, 0x2C, 0x95, 0x95, 0x2C, 0x2C, 0x2C, 0x2C,
-  0x94, 0x94, 0x70, 0x2C, 0xA1, 0xD6, 0xA1, 0x2C,
-  0x55, 0x55, 0xCB, 0x55, 0x55, 0x55, 0x55, 0x55,
-  0x95, 0x2C, 0xD6, 0xD6, 0xD6, 0xA1, 0x2C, 0x95,
-  0x55, 0x55, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-  0x2C, 0x94, 0x80, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x88, 0x92, 0xA1, 0x95,
-  0x55, 0x90, 0x94, 0x94, 0x70, 0x2C, 0xA1, 0xD6,
-  0xA1, 0x2C, 0x55, 0x55, 0xCB, 0x55, 0x55, 0x55,
-  0x55, 0x55, 0x95, 0x2C, 0xD6, 0xD6, 0xD6, 0xA1,
-  0x2C, 0x95, 0x55, 0x55, 0x55, 0x95, 0x95, 0x95,
-  0x70, 0x70, 0x55, 0x2C, 0xD6, 0xD6, 0xA1, 0x95,
-  0x55, 0x90, 0xCB, 0xCB, 0x55, 0x55, 0x2C, 0x2C,
-  0xA1, 0xD6, 0xA1, 0xA1, 0x2C, 0x2C, 0x95, 0x55,
-  0x55, 0x55, 0x95, 0x95, 0x2C, 0x95, 0x95, 0xD6,
-  0xB1, 0x88, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x80, 0x34, 0x88, 0x43, 0x47,
-  0x95, 0xCB, 0x70, 0x70, 0x55, 0x2C, 0xD6, 0xD6,
-  0xA1, 0x95, 0x55, 0x90, 0xCB, 0xCB, 0x55, 0x55,
-  0x2C, 0x2C, 0xA1, 0xD6, 0xA1, 0xA1, 0xA1, 0x2C,
-  0x55, 0x55, 0x55, 0x55, 0x2C, 0x95, 0x2C, 0x2C,
-  0x55, 0x55, 0x95, 0x2C, 0xA1, 0xA1, 0x2C, 0x55,
-  0x90, 0x70, 0x90, 0x55, 0x95, 0x95, 0xA1, 0xA1,
-  0xA1, 0xA1, 0xA1, 0xA1, 0x2C, 0x95, 0x95, 0x95,
-  0x95, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0xD5,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x88, 0x7D, 0x3F, 0xB1, 0x80, 0x20,
-  0x99, 0x2C, 0x55, 0x55, 0x95, 0x2C, 0xA1, 0xA1,
-  0x2C, 0x55, 0x90, 0x70, 0x90, 0x55, 0x95, 0x95,
-  0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0x2C, 0x2C, 0x2C,
-  0x95, 0x55, 0x95, 0x95, 0x2C, 0x2C, 0x2C, 0x2C,
-  0x95, 0x90, 0x55, 0x2C, 0xA1, 0xA1, 0x95, 0xCB,
-  0x70, 0x94, 0x90, 0x55, 0x95, 0xA1, 0xA1, 0xA1,
-  0x2C, 0x2C, 0x2C, 0x2C, 0x95, 0x95, 0x95, 0x95,
-  0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0xA1, 0x88,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xB1, 0x47, 0xD5, 0x7D, 0x43,
-  0x20, 0x70, 0x95, 0x90, 0x55, 0x2C, 0xA1, 0xA1,
-  0x95, 0xCB, 0x70, 0x94, 0x90, 0x55, 0x95, 0xA1,
-  0xA1, 0xA1, 0x2C, 0x95, 0x2C, 0x2C, 0x95, 0x95,
-  0x95, 0x95, 0x95, 0x2C, 0x95, 0x95, 0x95, 0x95,
-  0x95, 0x90, 0x55, 0x2C, 0xD6, 0xD6, 0x2C, 0x90,
-  0x94, 0x70, 0x55, 0x95, 0x2C, 0xD6, 0xD6, 0xA1,
-  0x95, 0x95, 0x95, 0x2C, 0x2C, 0x95, 0x55, 0x55,
-  0xCB, 0xCB, 0xCB, 0x55, 0xCB, 0x55, 0x47, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x88, 0xB1, 0x3F, 0x92, 0x2B, 0x80,
-  0x20, 0x80, 0xD6, 0x70, 0x55, 0x2C, 0xD6, 0xD6,
-  0x2C, 0x90, 0x94, 0x70, 0x55, 0x95, 0x2C, 0xD6,
-  0xD6, 0xA1, 0x2C, 0x95, 0x95, 0x2C, 0x2C, 0x95,
-  0x95, 0x55, 0x90, 0xCB, 0xCB, 0xCB, 0xCB, 0x55,
-  0xD6, 0x55, 0x95, 0xA1, 0xD6, 0xA1, 0x55, 0x70,
-  0x94, 0x55, 0x95, 0xA1, 0xA1, 0xA1, 0xA1, 0x95,
-  0x55, 0x55, 0x55, 0x95, 0x55, 0x55, 0xCB, 0x90,
-  0x70, 0x90, 0xCB, 0x55, 0x55, 0xA1, 0xD8, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x88, 0xD8, 0xE1, 0x88, 0x20, 0x20,
-  0x88, 0x88, 0xE6, 0x55, 0x2C, 0xA1, 0xD6, 0xA1,
-  0x55, 0x70, 0x94, 0x55, 0x95, 0xA1, 0xA1, 0xA1,
-  0xA1, 0x95, 0x55, 0x55, 0x95, 0x95, 0x55, 0x55,
-  0x90, 0x90, 0x90, 0x90, 0xCB, 0x55, 0x55, 0x55,
-  0xD6, 0x2C, 0xA1, 0xD6, 0xD6, 0xA1, 0xCB, 0x70,
-  0x70, 0x95, 0x2C, 0xA1, 0xA1, 0x2C, 0x2C, 0x55,
-  0xCB, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
-  0x55, 0x95, 0x2C, 0x95, 0x2C, 0xD6, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x80, 0xD6, 0xA1, 0xD6, 0xD6, 0xA1,
-  0xCB, 0x70, 0x70, 0x95, 0x2C, 0xA1, 0xA1, 0x2C,
-  0x2C, 0x55, 0xCB, 0xCB, 0x55, 0x55, 0x55, 0x55,
-  0x55, 0x55, 0x55, 0x95, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xD6, 0xA1, 0xA1, 0xA1, 0xA1, 0x55, 0x70, 0x94,
-  0xCB, 0x95, 0xA1, 0xA1, 0x2C, 0x95, 0xCB, 0x55,
-  0x90, 0xCB, 0x55, 0x55, 0x55, 0x55, 0x95, 0xA1,
-  0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0x95, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x88, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x88, 0x95, 0xA1, 0xA1, 0xA1, 0x55,
-  0x70, 0x94, 0xCB, 0x95, 0xA1, 0xA1, 0x2C, 0x95,
-  0xCB, 0xCB, 0x90, 0xCB, 0x55, 0x55, 0x55, 0x55,
-  0x95, 0x2C, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1,
-  0x2C, 0x2C, 0x2C, 0x95, 0x95, 0xCB, 0x70, 0x70,
-  0x95, 0x2C, 0x2C, 0x95, 0xCB, 0x70, 0x90, 0xCB,
-  0xCB, 0x55, 0x55, 0xCB, 0x55, 0x55, 0x2C, 0xD6,
-  0xD6, 0xD6, 0xD6, 0xA1, 0x2C, 0x70, 0x20, 0x20,
-  0x88, 0x43, 0xD8, 0x43, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x88, 0x88, 0x43, 0x2B, 0xD8, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x3F, 0x2C, 0x95, 0x95, 0xCB,
-  0x70, 0x70, 0x95, 0x2C, 0x2C, 0x95, 0xCB, 0x90,
-  0x90, 0xCB, 0x55, 0xCB, 0x55, 0xCB, 0x55, 0x95,
-  0x2C, 0xD6, 0xD6, 0xD6, 0xD6, 0xA1, 0x2C, 0x2C,
-  0xA1, 0x95, 0x95, 0x55, 0xCB, 0x70, 0x90, 0x55,
-  0x2C, 0x2C, 0x2C, 0x55, 0x70, 0x70, 0x55, 0x95,
-  0x95, 0xCB, 0x90, 0x90, 0x90, 0x95, 0x2C, 0xA1,
-  0xD6, 0xD6, 0x2C, 0x2C, 0x95, 0x70, 0x20, 0x20,
-  0x80, 0x2B, 0x34, 0x2B, 0x88, 0x20, 0x20, 0x20,
-  0x88, 0xB1, 0x28, 0x28, 0x2B, 0x7D, 0x80, 0x20,
-  0x20, 0x20, 0x20, 0x92, 0x95, 0x55, 0xCB, 0x70,
-  0x90, 0x55, 0x2C, 0x2C, 0x2C, 0x55, 0x70, 0x70,
-  0x55, 0x95, 0x55, 0x55, 0x90, 0x90, 0x90, 0x55,
-  0x2C, 0xA1, 0xD6, 0xA1, 0x2C, 0x2C, 0x95, 0x95,
-  0xA1, 0x95, 0x55, 0xCB, 0x90, 0x70, 0xCB, 0x95,
-  0xA1, 0x95, 0x95, 0xCB, 0x90, 0xCB, 0x95, 0x2C,
-  0x95, 0x70, 0x70, 0x90, 0x55, 0x2C, 0xA1, 0xA1,
-  0x2C, 0x2C, 0x55, 0xCB, 0x55, 0x90, 0x20, 0x34,
-  0x90, 0x6D, 0x70, 0xD8, 0x43, 0x20, 0x20, 0x88,
-  0x3F, 0x55, 0xA1, 0x2A, 0xD6, 0x7D, 0x43, 0x20,
-  0x20, 0x20, 0x88, 0x7D, 0x55, 0xCB, 0x90, 0x70,
-  0xCB, 0x95, 0xA1, 0x95, 0x95, 0xCB, 0x70, 0xCB,
-  0x95, 0xA1, 0x95, 0x70, 0x70, 0xCB, 0x55, 0x2C,
-  0xA1, 0xA1, 0xA1, 0x95, 0x55, 0x55, 0x55, 0x95,
-  0x2C, 0x55, 0x90, 0x70, 0x94, 0x90, 0x95, 0x2C,
-  0x2C, 0x95, 0xCB, 0x90, 0x55, 0x95, 0xA1, 0xA1,
-  0x95, 0x90, 0x90, 0x95, 0xA1, 0xD6, 0xD6, 0x6D,
-  0xA1, 0x95, 0x55, 0xCB, 0x55, 0xCB, 0x20, 0x99,
-  0xBF, 0xA3, 0xA3, 0x90, 0x20, 0x20, 0x20, 0x92,
-  0x83, 0x6B, 0x6B, 0x6B, 0xA3, 0x70, 0x88, 0x20,
-  0x20, 0x20, 0x20, 0x2B, 0x90, 0x70, 0x94, 0x90,
-  0x95, 0x2C, 0x2C, 0x95, 0xCB, 0x90, 0x55, 0x95,
-  0xA1, 0x2C, 0x55, 0x90, 0x90, 0x95, 0xA1, 0xD6,
-  0xD6, 0x6D, 0xA1, 0x95, 0x55, 0xCB, 0x55, 0x55,
-  0x2C, 0x55, 0x70, 0x70, 0x94, 0x90, 0x95, 0x2C,
-  0x2C, 0x55, 0xCB, 0xCB, 0x95, 0x2C, 0x2C, 0x2C,
-  0x55, 0x55, 0x95, 0xA1, 0x6D, 0xBF, 0x6D, 0xD6,
-  0x95, 0x55, 0x90, 0xCB, 0x55, 0x95, 0x88, 0x95,
-  0x2C, 0x3F, 0x6D, 0x6B, 0x34, 0x20, 0x20, 0x47,
-  0x65, 0xD6, 0xE1, 0x3F, 0x2A, 0x6B, 0x2B, 0x20,
-  0x20, 0x20, 0x20, 0x43, 0x70, 0x70, 0x94, 0x90,
-  0x95, 0x2C, 0x2C, 0x55, 0x55, 0x55, 0x95, 0x2C,
-  0xA1, 0x2C, 0x55, 0xCB, 0x95, 0xA1, 0x6D, 0xBF,
-  0x6D, 0xD6, 0x2C, 0x55, 0x90, 0xCB, 0x95, 0x95,
-  0x95, 0x55, 0x70, 0x94, 0x70, 0x55, 0x2C, 0xA1,
-  0x2C, 0x55, 0xCB, 0x55, 0x2C, 0x95, 0x2C, 0x95,
-  0x95, 0x95, 0xA1, 0x6D, 0xBF, 0x2A, 0xD6, 0x95,
-  0x70, 0x94, 0x94, 0x70, 0x55, 0x55, 0x20, 0xBF,
-  0xC9, 0xB1, 0x99, 0x42, 0xB1, 0x61, 0x7D, 0x94,
-  0x65, 0xB1, 0x88, 0x99, 0xD5, 0xE5, 0x7F, 0x20,
-  0x20, 0x20, 0x20, 0x43, 0x70, 0x94, 0x70, 0x55,
-  0x2C, 0xA1, 0x2C, 0x55, 0x90, 0x55, 0x2C, 0x95,
-  0x2C, 0x95, 0x95, 0x2C, 0xA1, 0x6D, 0xBF, 0xBF,
-  0xD6, 0x55, 0x70, 0x94, 0x94, 0x70, 0xCB, 0x55,
-  0x55, 0xCB, 0x70, 0x94, 0x70, 0x95, 0xA1, 0xA1,
-  0x95, 0x55, 0x55, 0x95, 0x2C, 0x95, 0x95, 0x95,
-  0x95, 0xA1, 0x6D, 0x2A, 0x2A, 0xD6, 0x55, 0x94,
-  0xE6, 0xE6, 0x47, 0x70, 0x55, 0x95, 0x20, 0x2A,
-  0xD8, 0x43, 0xC9, 0x83, 0x98, 0x79, 0x34, 0x9F,
-  0x6B, 0x43, 0x20, 0x88, 0x2B, 0x65, 0xA0, 0x20,
-  0x20, 0x20, 0x20, 0xE1, 0x70, 0x94, 0x70, 0x95,
-  0xA1, 0xA1, 0x95, 0x55, 0x55, 0x95, 0x2C, 0x95,
-  0x95, 0x95, 0x95, 0xA1, 0x6D, 0xBF, 0x2A, 0xD6,
-  0x55, 0x94, 0xE6, 0xE6, 0x47, 0x70, 0x55, 0x55,
-  0x94, 0x70, 0x94, 0x47, 0x70, 0x95, 0x2C, 0x2C,
-  0x95, 0xCB, 0x95, 0x2C, 0x2C, 0xA1, 0x2C, 0x2C,
-  0xA1, 0xD6, 0x6D, 0x6D, 0xA1, 0xCB, 0x47, 0x28,
-  0xE6, 0x47, 0x70, 0x55, 0x95, 0xA1, 0x20, 0x2C,
-  0x7F, 0x88, 0xF0, 0xC6, 0x25, 0x5E, 0xCF, 0x2F,
-  0xE7, 0x9A, 0x20, 0x88, 0x99, 0x65, 0x3F, 0x20,
-  0x20, 0x20, 0x20, 0x34, 0x94, 0x47, 0x70, 0x95,
-  0xA1, 0x2C, 0x55, 0xCB, 0x95, 0x2C, 0x2C, 0xA1,
-  0x2C, 0x2C, 0xA1, 0xD6, 0x6D, 0x6D, 0xA1, 0xCB,
-  0x94, 0x28, 0xA0, 0x47, 0x70, 0x55, 0x95, 0x95,
-  0x47, 0x70, 0x90, 0x94, 0x70, 0x95, 0xA1, 0x2C,
-  0x55, 0x55, 0x2C, 0xA1, 0xA1, 0xA1, 0xA1, 0x2C,
-  0xA1, 0x6D, 0x2A, 0xD6, 0x55, 0x47, 0x28, 0x28,
-  0x47, 0x70, 0x55, 0x95, 0x2C, 0xA1, 0x20, 0x28,
-  0xEC, 0x86, 0xBE, 0x48, 0x3E, 0x3E, 0x3A, 0x25,
-  0x4E, 0xAE, 0x93, 0xD7, 0xEC, 0xD1, 0x34, 0x20,
-  0x20, 0x20, 0x20, 0x43, 0x55, 0x94, 0x70, 0x95,
-  0xA1, 0xA1, 0x55, 0xCB, 0x2C, 0xA1, 0xA1, 0xA1,
-  0xA1, 0x2C, 0xA1, 0x6D, 0x6D, 0xD6, 0x55, 0x47,
-  0x28, 0x28, 0x47, 0x70, 0x55, 0x95, 0x2C, 0x2C,
-  0x95, 0x95, 0x55, 0x90, 0xCB, 0x2C, 0xA1, 0xA1,
-  0x55, 0x55, 0x2C, 0xD6, 0xD6, 0xA1, 0xA1, 0x2C,
-  0xD6, 0x6D, 0x6D, 0xA1, 0x70, 0x28, 0xD5, 0xE6,
-  0x70, 0x55, 0x95, 0x2C, 0xA1, 0xD6, 0x20, 0xE1,
-  0x26, 0x84, 0x76, 0x73, 0x9C, 0x22, 0x4E, 0x35,
-  0x8C, 0x7A, 0x4E, 0xDC, 0x8E, 0x7E, 0x3D, 0x88,
-  0x20, 0x20, 0x20, 0x88, 0x2C, 0x90, 0x90, 0x95,
-  0xA1, 0x2C, 0x55, 0x55, 0x2C, 0xD6, 0xD6, 0xD6,
-  0x2C, 0x2C, 0xD6, 0x2A, 0x6D, 0x2C, 0x70, 0x28,
-  0xD5, 0xE6, 0x70, 0x55, 0x95, 0xA1, 0x2C, 0xA1,
-  0xBF, 0xA1, 0x95, 0xCB, 0xCB, 0x2C, 0xA1, 0xA1,
-  0x95, 0x95, 0xA1, 0xD6, 0xD6, 0xA1, 0x2C, 0x95,
-  0xD6, 0x6D, 0xD6, 0x95, 0x94, 0x28, 0xE6, 0x70,
-  0x55, 0x95, 0xA1, 0xA1, 0xA1, 0xD6, 0x20, 0x57,
-  0xE4, 0xDF, 0x50, 0x3E, 0x22, 0x4E, 0x35, 0x8C,
-  0x8C, 0x52, 0x52, 0x7A, 0x4E, 0x58, 0xD7, 0x20,
-  0x20, 0x20, 0x20, 0x88, 0x2C, 0xCB, 0x55, 0x2C,
-  0xA1, 0xA1, 0x95, 0x95, 0xA1, 0xD6, 0xD6, 0xA1,
-  0x2C, 0x95, 0xA1, 0x6D, 0x6D, 0x95, 0x47, 0xA0,
-  0xE6, 0x70, 0x55, 0x95, 0x2C, 0xA1, 0xA1, 0xA1,
-  0xD2, 0x95, 0x55, 0x90, 0x55, 0x2C, 0xD6, 0xA1,
-  0x95, 0x95, 0xA1, 0xD6, 0xD6, 0x2C, 0x95, 0x2C,
-  0xA1, 0x6D, 0xA1, 0x55, 0x94, 0x47, 0x94, 0xCB,
-  0x55, 0x95, 0x2C, 0xA1, 0xD6, 0xD6, 0x59, 0xC8,
-  0xE3, 0x76, 0x2D, 0x3E, 0x22, 0x4E, 0x8C, 0x35,
-  0x52, 0x52, 0xEE, 0x3A, 0x4D, 0xED, 0x24, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x28, 0xCB, 0x55, 0x2C,
-  0xD6, 0xA1, 0x95, 0x95, 0xA1, 0xD6, 0xA1, 0x2C,
-  0x95, 0x2C, 0xD6, 0x6D, 0xA1, 0x55, 0x94, 0xE6,
-  0x70, 0xCB, 0x55, 0x95, 0xA1, 0xD6, 0xD6, 0xA1,
-  0xD0, 0x94, 0x94, 0x90, 0x55, 0x2C, 0xA1, 0xA1,
-  0x55, 0x95, 0xA1, 0xA1, 0xA1, 0x2C, 0x95, 0x2C,
-  0xA1, 0xD6, 0x2C, 0x70, 0x94, 0x94, 0x94, 0x94,
-  0x70, 0x55, 0xA1, 0xD6, 0xA1, 0xD6, 0x88, 0x77,
-  0x38, 0xC4, 0x3E, 0x69, 0x4E, 0x35, 0x8C, 0xEE,
-  0x35, 0x89, 0x30, 0x30, 0x4A, 0x48, 0x3C, 0x20,
-  0x20, 0x88, 0x20, 0x20, 0xD8, 0x2C, 0x55, 0x2C,
-  0xD6, 0xA1, 0x95, 0x95, 0x2C, 0xD6, 0xA1, 0x2C,
-  0x95, 0x2C, 0xA1, 0xD6, 0x2C, 0x90, 0x94, 0x47,
-  0x94, 0x94, 0x70, 0x55, 0x2C, 0xD6, 0xA1, 0x95,
-  0x95, 0x28, 0x47, 0x90, 0x95, 0x2C, 0xA1, 0x2C,
-  0x95, 0x55, 0x95, 0xA1, 0xD6, 0xA1, 0x2C, 0x2C,
-  0xA1, 0xA1, 0x55, 0x70, 0x94, 0x47, 0x94, 0x94,
-  0x70, 0x2C, 0xD6, 0xD6, 0x2C, 0xA1, 0x43, 0x98,
-  0x54, 0x48, 0x3E, 0x22, 0x35, 0xEE, 0xEE, 0x9C,
-  0x4D, 0x45, 0x75, 0x4A, 0xDF, 0x7B, 0x3D, 0x20,
-  0xD8, 0x28, 0x2B, 0x88, 0x20, 0x95, 0x95, 0x2C,
-  0xA1, 0x2C, 0x55, 0x55, 0x2C, 0xA1, 0xD6, 0xA1,
-  0x2C, 0x95, 0xA1, 0x2C, 0x55, 0x70, 0x94, 0x94,
-  0x94, 0x94, 0x70, 0x95, 0xD6, 0xD6, 0x2C, 0x95,
-  0x70, 0x28, 0x47, 0x55, 0x95, 0x2C, 0x2C, 0x2C,
-  0x95, 0x95, 0x95, 0xA1, 0xA1, 0xA1, 0x95, 0x55,
-  0x95, 0x95, 0x55, 0x70, 0x70, 0x70, 0x94, 0x70,
-  0x55, 0xD6, 0x6D, 0xD6, 0x95, 0x2C, 0x20, 0x43,
-  0xBB, 0xC8, 0x36, 0x30, 0x30, 0x38, 0x45, 0x6E,
-  0xE3, 0x75, 0x78, 0x37, 0xBD, 0xD9, 0x3F, 0x20,
-  0x88, 0xD5, 0x70, 0xB1, 0x88, 0xA0, 0x95, 0x2C,
-  0x2C, 0xA1, 0x95, 0x55, 0x95, 0xA1, 0xA1, 0xA1,
-  0x2C, 0x55, 0x95, 0x2C, 0x55, 0x70, 0x70, 0x70,
-  0x94, 0x70, 0x55, 0xD6, 0x6D, 0x6D, 0x95, 0x55,
-  0x94, 0x47, 0x70, 0x95, 0x2C, 0x2C, 0x2C, 0xA1,
-  0x2C, 0x95, 0x2C, 0xA1, 0xD6, 0xA1, 0x2C, 0x55,
-  0x55, 0x95, 0x95, 0x55, 0x55, 0x55, 0x55, 0x95,
-  0xA1, 0x6D, 0x4B, 0xD6, 0x55, 0xD6, 0x20, 0xD8,
-  0xD6, 0x67, 0xDA, 0x4D, 0xED, 0x62, 0x78, 0x78,
-  0x23, 0x84, 0x67, 0xF5, 0x4B, 0xBF, 0x90, 0x88,
-  0x88, 0x2B, 0x47, 0x99, 0x20, 0x43, 0xD6, 0x2C,
-  0x2C, 0xA1, 0x2C, 0x95, 0x2C, 0xA1, 0xD6, 0xA1,
-  0x95, 0x95, 0x55, 0x95, 0x55, 0x55, 0x55, 0x55,
-  0x55, 0x95, 0xD6, 0x6D, 0xBF, 0xD6, 0x55, 0xCB,
-  0x55, 0x55, 0x55, 0x2C, 0x2C, 0x2C, 0x2C, 0xA1,
-  0x2C, 0x2C, 0x2C, 0xA1, 0xA1, 0x2C, 0x2C, 0x95,
-  0x55, 0x95, 0x95, 0x2C, 0x2C, 0x2C, 0x2C, 0xA1,
-  0x6D, 0x2A, 0x2A, 0xA1, 0x55, 0x55, 0x20, 0xD8,
-  0x6D, 0xAB, 0x96, 0x7E, 0x64, 0x53, 0x36, 0x36,
-  0xC6, 0x63, 0x6D, 0xD0, 0x6B, 0xE5, 0xA3, 0x7D,
-  0x20, 0x88, 0x80, 0x88, 0x20, 0x20, 0xC9, 0xA1,
-  0x2C, 0xA1, 0xA1, 0x2C, 0x2C, 0xA1, 0xA1, 0xA1,
-  0x95, 0x95, 0x55, 0x95, 0x95, 0x2C, 0x2C, 0x2C,
-  0x2C, 0xA1, 0x6D, 0xBF, 0x6D, 0xA1, 0x55, 0x55,
-  0x95, 0x95, 0x95, 0x95, 0x2C, 0x2C, 0x2C, 0xA1,
-  0xA1, 0x95, 0x95, 0x2C, 0x2C, 0x2C, 0x2C, 0x95,
-  0x55, 0x55, 0x2C, 0x2C, 0xA1, 0xA1, 0xD6, 0xD6,
-  0x6D, 0x6D, 0xA1, 0x55, 0x2C, 0xD8, 0x20, 0xB1,
-  0xA3, 0x4B, 0x6D, 0xD9, 0xA7, 0x6C, 0xAF, 0xB2,
-  0x6D, 0x2A, 0x83, 0x42, 0xE5, 0xE5, 0x65, 0x2C,
-  0x20, 0x20, 0x88, 0x20, 0x20, 0x20, 0x88, 0x95,
-  0x2C, 0xA1, 0x2C, 0x95, 0x95, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x95, 0x55, 0x55, 0x2C, 0x2C, 0xA1, 0xA1,
-  0xD6, 0xD6, 0x6D, 0x6D, 0xA1, 0x55, 0xCB, 0x55,
-  0x95, 0x55, 0x95, 0x95, 0x2C, 0x2C, 0x95, 0x2C,
-  0x2C, 0x95, 0x95, 0x95, 0x95, 0x95, 0x2C, 0x95,
-  0x55, 0x95, 0x2C, 0x2C, 0xA1, 0xA1, 0xD6, 0xA1,
-  0xA1, 0x2C, 0x55, 0x55, 0x28, 0x88, 0x43, 0x2A,
-  0xE5, 0xA3, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D,
-  0xBF, 0xA3, 0x42, 0xE5, 0xE5, 0xE5, 0xE5, 0x65,
-  0xB1, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xD8,
-  0xD6, 0x2C, 0x2C, 0x95, 0x95, 0x95, 0x95, 0x2C,
-  0x95, 0x95, 0x55, 0x95, 0x2C, 0x2C, 0xA1, 0xA1,
-  0xA1, 0xA1, 0xA1, 0x2C, 0x95, 0x90, 0x90, 0x55,
-  0x90, 0xCB, 0x55, 0x95, 0x95, 0x95, 0x95, 0x95,
-  0x2C, 0x2C, 0x95, 0x55, 0x95, 0x95, 0x95, 0x55,
-  0x55, 0xCB, 0x55, 0x2C, 0x95, 0x95, 0x95, 0x95,
-  0x55, 0x90, 0x90, 0x90, 0xE1, 0x43, 0x28, 0xE5,
-  0xE5, 0x65, 0xD0, 0x6D, 0x6D, 0x6D, 0x2A, 0xD2,
-  0x42, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xD6, 0x20, 0x20, 0x20, 0x20, 0x20, 0x88, 0x88,
-  0xD5, 0x2C, 0x2C, 0x2C, 0x95, 0x55, 0x95, 0x95,
-  0x95, 0x55, 0x55, 0xCB, 0x55, 0x95, 0x2C, 0x95,
-  0x95, 0x95, 0x55, 0x90, 0x70, 0x70, 0x70, 0x90,
-  0x70, 0x70, 0xCB, 0x55, 0x55, 0x95, 0x95, 0x95,
-  0x2C, 0x95, 0x95, 0x55, 0x55, 0x55, 0x55, 0xCB,
-  0x70, 0x70, 0x70, 0xCB, 0x90, 0x90, 0x70, 0x94,
-  0x94, 0x94, 0x2C, 0x80, 0x20, 0xE1, 0xA3, 0xE5,
-  0xE5, 0xE5, 0x42, 0xEC, 0xD0, 0x83, 0xA3, 0x65,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0x65, 0x7D, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x88, 0x2C, 0x95, 0x95, 0x95, 0x55, 0x55, 0x55,
-  0x55, 0xCB, 0x70, 0x70, 0x90, 0x90, 0x90, 0x90,
-  0x70, 0x94, 0x94, 0x94, 0x70, 0x70, 0x70, 0x70,
-  0x70, 0x55, 0x55, 0x55, 0x95, 0x95, 0x95, 0x95,
-  0x2C, 0x2C, 0x95, 0x55, 0x55, 0x55, 0x55, 0x55,
-  0x90, 0x70, 0x90, 0x55, 0x55, 0xCB, 0x70, 0x94,
-  0x94, 0x95, 0xD8, 0x20, 0x88, 0x70, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0x65, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0x47, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0xE1, 0x6D, 0x2C, 0x95, 0x55, 0x55, 0x55,
-  0x55, 0x55, 0x90, 0x70, 0x70, 0x55, 0x55, 0xCB,
-  0x70, 0x94, 0x94, 0x94, 0x70, 0x90, 0x70, 0x94,
-  0x55, 0x2C, 0x2C, 0x2C, 0x95, 0x2C, 0x95, 0x95,
-  0x2C, 0x2C, 0x2C, 0x55, 0x55, 0x55, 0x55, 0x55,
-  0xCB, 0xCB, 0x95, 0x2C, 0x2C, 0x95, 0x55, 0x90,
-  0x55, 0x99, 0x20, 0x20, 0xE1, 0xA3, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xD6, 0x88, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x2B, 0x6D, 0x95, 0x95, 0x55, 0x55,
-  0x55, 0x55, 0xCB, 0x55, 0x95, 0x2C, 0x2C, 0x95,
-  0x55, 0x90, 0xCB, 0xCB, 0xCB, 0xCB, 0x90, 0x70,
-  0x2C, 0xD6, 0xD6, 0x2C, 0x2C, 0x95, 0x95, 0x95,
-  0x95, 0x95, 0x95, 0x2C, 0x95, 0x95, 0x95, 0x95,
-  0x95, 0x95, 0x2C, 0xA1, 0x2C, 0x95, 0x55, 0x95,
-  0xE6, 0x88, 0x20, 0x20, 0x3F, 0xA3, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0x42, 0xA3, 0x88, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x88, 0x2B, 0xD6, 0x95, 0x95, 0x95,
-  0x95, 0x95, 0x95, 0x95, 0x2C, 0xA1, 0x2C, 0x95,
-  0x55, 0x55, 0x95, 0x95, 0x95, 0x55, 0x55, 0x55,
-  0xA1, 0xD6, 0xD6, 0xA1, 0x2C, 0x2C, 0x95, 0x2C,
-  0x2C, 0x2C, 0x95, 0x2C, 0x95, 0x95, 0x55, 0x95,
-  0x95, 0x2C, 0x2C, 0x2C, 0x95, 0xCB, 0xCB, 0x94,
-  0x20, 0x20, 0x20, 0x20, 0xE6, 0x83, 0x65, 0xE5,
-  0xE5, 0xE5, 0xE5, 0x42, 0x6B, 0x6B, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0x42, 0x6B, 0x6B, 0xA3, 0xD2,
-  0xD2, 0x6B, 0xC9, 0x20, 0x20, 0x88, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x88, 0x8A, 0xA1, 0x95, 0x95,
-  0x95, 0x55, 0x95, 0x2C, 0xA1, 0x2C, 0x95, 0xCB,
-  0xCB, 0x55, 0x95, 0x95, 0x95, 0x55, 0x55, 0x95,
-  0x6D, 0x6D, 0x6D, 0xD6, 0xA1, 0x2C, 0x2C, 0x95,
-  0x2C, 0x95, 0x2C, 0x95, 0x95, 0x95, 0x95, 0x95,
-  0x95, 0x95, 0x95, 0x55, 0x70, 0x70, 0x2C, 0x80,
-  0x88, 0x20, 0x20, 0x80, 0x94, 0xD6, 0x32, 0x6B,
-  0xE5, 0xE5, 0xE5, 0x42, 0x6B, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xA3, 0xD2, 0xD0, 0xBF, 0x2A,
-  0x2A, 0xD0, 0x6D, 0x34, 0x20, 0xE1, 0x88, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x88, 0xA1, 0x95, 0x95,
-  0x95, 0x95, 0x95, 0x95, 0x95, 0x55, 0x70, 0x70,
-  0x70, 0x90, 0xCB, 0xCB, 0xCB, 0x95, 0x95, 0x2C,
-  0xD0, 0x6D, 0xD6, 0xD6, 0xA1, 0xA1, 0xA1, 0x2C,
-  0x2C, 0x2C, 0x2C, 0x95, 0x55, 0x55, 0x55, 0x95,
-  0x95, 0x2C, 0x95, 0x55, 0xCB, 0xCB, 0x95, 0x88,
-  0x20, 0x20, 0x88, 0xD8, 0x2C, 0xD1, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0x65, 0x65, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0x42, 0x6B, 0xEC,
-  0xBF, 0x2A, 0xEC, 0x95, 0x20, 0x34, 0x2B, 0xE1,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x99, 0x95, 0x55,
-  0x55, 0x55, 0x95, 0x95, 0x95, 0x55, 0xCB, 0xCB,
-  0x55, 0x55, 0xCB, 0xCB, 0xCB, 0x55, 0x95, 0x95,
-  0x32, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0x2C, 0x2C,
-  0xA1, 0x95, 0x95, 0x95, 0x55, 0xCB, 0xCB, 0x55,
-  0x95, 0x95, 0x95, 0x95, 0x95, 0x55, 0x99, 0x20,
-  0xE1, 0xE1, 0x43, 0x47, 0x6B, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0x42, 0xEC, 0xBF, 0xA3, 0x8A, 0x20, 0x88, 0xD8,
-  0x2B, 0x20, 0x20, 0x20, 0x88, 0x88, 0x2C, 0xCB,
-  0xCB, 0x95, 0x95, 0x2C, 0x95, 0x95, 0x55, 0x95,
-  0x55, 0x55, 0x55, 0x55, 0x55, 0x95, 0x55, 0x95,
-  0x6D, 0x55, 0x55, 0x55, 0x95, 0x95, 0x2C, 0x95,
-  0x2C, 0x95, 0x95, 0x55, 0x55, 0x55, 0x55, 0x95,
-  0x95, 0x95, 0x95, 0x95, 0x95, 0xA1, 0x34, 0x20,
-  0xC9, 0x20, 0xE1, 0xA3, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xA3, 0x83, 0x6D, 0x20, 0x88, 0x88,
-  0x2B, 0x34, 0x20, 0x20, 0x20, 0x88, 0xD5, 0x55,
-  0x55, 0x55, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-  0x95, 0x95, 0x95, 0x95, 0x55, 0x55, 0x95, 0x95,
-  0x2C, 0x55, 0xCB, 0x55, 0xCB, 0x55, 0x55, 0x95,
-  0x95, 0x95, 0x95, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x95, 0x95, 0x55, 0x95, 0x2C, 0x20, 0xD8,
-  0xE1, 0x20, 0x70, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0x65, 0xA3, 0x92, 0x43, 0x7D,
-  0xD8, 0xC9, 0x88, 0x20, 0x20, 0x20, 0x43, 0xD6,
-  0x2C, 0x2C, 0x95, 0x95, 0x95, 0x55, 0x95, 0x2C,
-  0x95, 0x95, 0x95, 0x95, 0x95, 0x2C, 0x95, 0x2C,
-  0xA1, 0x55, 0x55, 0x55, 0x55, 0x95, 0x95, 0x55,
-  0x55, 0x55, 0x95, 0x95, 0x2C, 0x2C, 0xA1, 0x2C,
-  0xA1, 0x2C, 0x2C, 0x95, 0x2C, 0x99, 0x88, 0xB1,
-  0x20, 0xD8, 0x42, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xCB, 0x34, 0x8A,
-  0xC9, 0x34, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x90,
-  0xA1, 0xA1, 0xA1, 0x2C, 0x2C, 0x95, 0x95, 0x2C,
-  0x2C, 0x95, 0x95, 0x95, 0x95, 0x2C, 0x2C, 0x2C,
-  0xD6, 0x2C, 0x55, 0x55, 0x95, 0x2C, 0x2C, 0x2C,
-  0x55, 0xCB, 0x55, 0x2C, 0x2C, 0xA1, 0x2C, 0xA1,
-  0xA1, 0xA1, 0x2C, 0x2C, 0x6D, 0x43, 0xD8, 0x80,
-  0x88, 0xCB, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0x32, 0x80, 0xE1,
-  0x80, 0x20, 0xB1, 0x20, 0x20, 0x20, 0x20, 0xC9,
-  0xD6, 0xA1, 0xA1, 0xA1, 0x2C, 0xA1, 0x2C, 0x2C,
-  0x2C, 0x55, 0x55, 0x55, 0x95, 0x95, 0x95, 0x55,
-  0xD6, 0x95, 0x95, 0x95, 0x2C, 0xA1, 0x2C, 0x2C,
-  0x95, 0x95, 0x95, 0x95, 0x95, 0x2C, 0x95, 0x2C,
-  0x2C, 0x2C, 0x2C, 0x95, 0xCB, 0x20, 0xC9, 0x20,
-  0xE1, 0xA3, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0x42, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xD8, 0x20,
-  0x20, 0x20, 0x2B, 0x43, 0x20, 0x20, 0x20, 0x88,
-  0xD6, 0x2C, 0x2C, 0x2C, 0x95, 0x95, 0x95, 0x55,
-  0x95, 0x55, 0x55, 0xCB, 0x55, 0xCB, 0xCB, 0x55,
-  0x2C, 0x55, 0x55, 0x95, 0x2C, 0x2C, 0xA1, 0x95,
-  0x55, 0x95, 0x55, 0x95, 0x95, 0x95, 0x95, 0x95,
-  0x55, 0xCB, 0x70, 0xCB, 0xC9, 0x80, 0x2B, 0x20,
-  0xA0, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0x42, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0x92, 0x20,
-  0x20, 0x20, 0xE1, 0xD8, 0x20, 0x20, 0x20, 0x20,
-  0x95, 0x95, 0x55, 0xCB, 0x90, 0x90, 0x70, 0x90,
-  0x90, 0x90, 0xCB, 0xCB, 0xCB, 0xCB, 0x55, 0x95,
-  0x95, 0x55, 0x55, 0x95, 0x95, 0x2C, 0x2C, 0x2C,
-  0x95, 0x95, 0x55, 0x55, 0x55, 0x95, 0x95, 0x55,
-  0x90, 0x47, 0xA0, 0x55, 0x20, 0x2B, 0x43, 0x88,
-  0x6D, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0x6B, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0x28, 0x20,
-  0x20, 0x20, 0xE1, 0xE1, 0x20, 0x20, 0x20, 0x20,
-  0x28, 0x55, 0x90, 0x47, 0xA0, 0x47, 0x94, 0x70,
-  0x55, 0x95, 0x95, 0x55, 0xCB, 0x55, 0x55, 0x2C,
-  0x2C, 0x2C, 0x95, 0x95, 0x95, 0x2C, 0x2C, 0x2C,
-  0x95, 0x2C, 0x95, 0x95, 0x95, 0x95, 0x95, 0x55,
-  0x94, 0xE6, 0x70, 0x2B, 0x88, 0x2B, 0x88, 0xE1,
-  0x65, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0x6B, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0x47, 0x20,
-  0x20, 0x20, 0xE1, 0x34, 0x20, 0x20, 0x20, 0x20,
-  0xB1, 0x95, 0x94, 0xE6, 0xA0, 0x47, 0x70, 0x55,
-  0x2C, 0xA1, 0x2C, 0x55, 0x90, 0xCB, 0x2C, 0xD6,
-  0x6D, 0xA1, 0x2C, 0x95, 0x95, 0xA1, 0x2C, 0xA1,
-  0x2C, 0x2C, 0x95, 0x95, 0x95, 0x95, 0x95, 0x55,
-  0x70, 0xE6, 0x70, 0x20, 0x20, 0x7D, 0x20, 0x8A,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0x65, 0xA3, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0x94, 0x20,
-  0x20, 0x20, 0xD8, 0x88, 0x20, 0x20, 0x20, 0x20,
-  0xD8, 0x2C, 0x94, 0x47, 0x47, 0x90, 0x95, 0x95,
-  0xA1, 0x6D, 0xA1, 0x90, 0x94, 0x55, 0x2C, 0xD6,
-  0xD0, 0xA1, 0x95, 0x95, 0x2C, 0x2C, 0xA1, 0x2C,
-  0x95, 0x95, 0x55, 0x55, 0x55, 0x95, 0x2C, 0x2C,
-  0xCB, 0x95, 0xD8, 0x20, 0x20, 0xB1, 0x88, 0x28,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE2, 0xA3, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xCB, 0x20,
-  0x20, 0x20, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x88, 0xD6, 0x55, 0x47, 0x94, 0x55, 0x2C, 0xA1,
-  0xA1, 0xD6, 0x95, 0x94, 0x94, 0x55, 0xD6, 0x6D,
-  0xBF, 0x95, 0x90, 0xCB, 0x2C, 0x2C, 0x2C, 0x2C,
-  0x55, 0x95, 0xCB, 0x90, 0x90, 0x95, 0x2C, 0x95,
-  0x90, 0x70, 0x20, 0x20, 0x34, 0x8A, 0x20, 0x94,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0x65, 0x6B, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xCB, 0x20,
-  0x20, 0x88, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x88, 0xD6, 0xCB, 0x47, 0x94, 0x55, 0xA1, 0xD6,
-  0xD6, 0x2C, 0xCB, 0x47, 0x70, 0xA1, 0x6D, 0x2A,
-  0x95, 0x47, 0x47, 0x70, 0x95, 0xA1, 0x2C, 0x95,
-  0x55, 0x55, 0x90, 0x90, 0x55, 0x55, 0x55, 0x90,
-  0x47, 0xD5, 0x20, 0x20, 0x80, 0xD5, 0x43, 0xCB,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0x42, 0x6B, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xCB, 0x20,
-  0x20, 0x80, 0x34, 0x20, 0x20, 0x20, 0x88, 0x20,
-  0x20, 0x2C, 0x47, 0xE6, 0x70, 0x2C, 0xD6, 0xD6,
-  0xA1, 0x2C, 0x55, 0xCB, 0x95, 0xA1, 0x6D, 0xD6,
-  0x90, 0x47, 0x47, 0x90, 0x2C, 0xA1, 0x2C, 0x95,
-  0x55, 0x55, 0x90, 0x90, 0x55, 0x55, 0x55, 0x70,
-  0x94, 0x8A, 0x20, 0x88, 0x88, 0xE1, 0xD8, 0x95,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE2, 0x42, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0x47, 0x20,
-  0x43, 0x7D, 0x43, 0x80, 0x88, 0x20, 0x20, 0x20,
-  0x88, 0xCB, 0x94, 0x70, 0x55, 0xA1, 0xD6, 0xD6,
-  0xA1, 0x2C, 0x2C, 0x95, 0xA1, 0xA1, 0xD6, 0xA1,
-  0x94, 0xE6, 0x47, 0x55, 0x2C, 0xD6, 0xA1, 0x95,
-  0x55, 0x55, 0xCB, 0xCB, 0x55, 0x55, 0xCB, 0xCB,
-  0x55, 0xA0, 0x43, 0x86, 0x86, 0x43, 0xD8, 0xCB,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0x65, 0x6B, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0x3F, 0x80,
-  0xD8, 0x80, 0x88, 0x34, 0xD8, 0x2B, 0xD8, 0x20,
-  0x99, 0x90, 0x55, 0x95, 0x2C, 0xA1, 0xD6, 0xD6,
-  0xA1, 0x95, 0x95, 0x95, 0x2C, 0x2C, 0x2C, 0x2C,
-  0x94, 0x94, 0x70, 0x2C, 0xA1, 0xD6, 0xA1, 0x2C,
-  0x55, 0x55, 0xCB, 0x55, 0x55, 0x55, 0x55, 0x55,
-  0x95, 0x44, 0xBC, 0x3E, 0x5D, 0xD3, 0x79, 0x92,
-  0xA3, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0x65, 0x42, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0x65, 0x9A, 0x34,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x99, 0xE1,
-  0x70, 0x55, 0x95, 0xA1, 0xD6, 0xD6, 0xD6, 0xA1,
-  0x2C, 0x95, 0x55, 0x55, 0x95, 0x95, 0x95, 0x95,
-  0x70, 0x70, 0x55, 0x2C, 0xD6, 0xD6, 0xA1, 0x95,
-  0x55, 0x90, 0xCB, 0xCB, 0x55, 0x55, 0x2C, 0x2C,
-  0x32, 0x9D, 0xEB, 0x5D, 0x69, 0x49, 0x84, 0xF0,
-  0xB1, 0xEC, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0x42, 0x6B, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xC1, 0x4E, 0x21, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x34, 0xC9, 0xD8,
-  0xBB, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0x2C, 0x2C,
-  0x95, 0x55, 0x55, 0x55, 0x95, 0x95, 0x2C, 0x2C,
-  0x55, 0xCB, 0x95, 0x2C, 0xA1, 0xA1, 0x2C, 0x55,
-  0x90, 0x70, 0x90, 0x55, 0x95, 0x95, 0x6D, 0xD0,
-  0xC2, 0x48, 0x6A, 0x49, 0x69, 0x82, 0x5D, 0x2F,
-  0x59, 0x7D, 0xBF, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0x65, 0x6B, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xEA, 0xC7, 0x7E, 0x66,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x34, 0x43, 0x5A,
-  0x46, 0x27, 0xA1, 0xA1, 0xA1, 0xA1, 0x2C, 0x95,
-  0x95, 0x55, 0x95, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
-  0x95, 0x90, 0x55, 0x2C, 0xA1, 0xA1, 0x95, 0x55,
-  0x94, 0x94, 0x2C, 0x2A, 0x72, 0x3B, 0x56, 0xDD,
-  0xDF, 0x29, 0x5D, 0x49, 0x89, 0x5D, 0x3E, 0x69,
-  0x93, 0x66, 0x34, 0xA1, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0x65, 0x42, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xEA, 0x3E, 0x5A, 0x66,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x5B, 0x73,
-  0x89, 0x4C, 0xBF, 0x2C, 0x95, 0x2C, 0x2C, 0x95,
-  0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-  0x2C, 0x70, 0x55, 0x2C, 0xD6, 0xD6, 0x2C, 0xCB,
-  0x70, 0x55, 0xE7, 0x60, 0x4A, 0x48, 0xCD, 0x4A,
-  0x29, 0x73, 0x5D, 0x82, 0x49, 0x49, 0x49, 0x49,
-  0x3A, 0x57, 0x88, 0x88, 0x70, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0x42, 0x73, 0x50, 0xBE, 0x79,
-  0x20, 0x20, 0x20, 0x20, 0x66, 0xCC, 0x37, 0x9C,
-  0x3E, 0xCE, 0xBF, 0x95, 0x95, 0x95, 0x2C, 0x95,
-  0x95, 0x55, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0x55,
-  0xA1, 0x55, 0x95, 0xA1, 0xD6, 0xA1, 0x55, 0x94,
-  0x94, 0xE8, 0x60, 0xC4, 0x3E, 0x2D, 0x2D, 0x2D,
-  0x33, 0x5D, 0x82, 0x49, 0x49, 0x49, 0x49, 0x49,
-  0x89, 0xAA, 0x59, 0x20, 0x20, 0x28, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xEC, 0x4A, 0x2D, 0x50, 0x78, 0x2E,
-  0x57, 0x51, 0xF0, 0x57, 0x31, 0x4D, 0x50, 0x2D,
-  0x5D, 0xF2, 0xA1, 0x2C, 0x95, 0x95, 0x55, 0x55,
-  0x90, 0x90, 0x70, 0x90, 0xCB, 0x55, 0x55, 0x55,
-  0x6D, 0x2C, 0xA1, 0xD6, 0xD6, 0xA1, 0x55, 0x94,
-  0x70, 0xB9, 0x75, 0x50, 0x3E, 0x49, 0x49, 0x49,
-  0x5D, 0x82, 0x49, 0x49, 0x82, 0x49, 0x49, 0x49,
-  0x89, 0x69, 0x4F, 0x20, 0x20, 0x20, 0x8A, 0x42,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0x83, 0x4A, 0x3A, 0x50, 0x62, 0x23,
-  0x81, 0xB8, 0xB8, 0xE9, 0x5F, 0x29, 0x33, 0x5D,
-  0x5D, 0x73, 0xE8, 0xCB, 0x55, 0x55, 0x55, 0x55,
-  0x55, 0x55, 0x95, 0x95, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xD6, 0xA1, 0xA1, 0xA1, 0xA1, 0x55, 0x70, 0x70,
-  0xCB, 0x68, 0x75, 0x50, 0x82, 0x49, 0x49, 0x49,
-  0x5D, 0x49, 0x49, 0x5D, 0x49, 0x49, 0x5D, 0x82,
-  0x69, 0x5D, 0x25, 0xF0, 0x20, 0x20, 0x20, 0xE1,
-  0x2A, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0x4B, 0xF4, 0xDF, 0x50, 0x73, 0x76, 0x48,
-  0x75, 0xDF, 0x75, 0x62, 0xC4, 0x33, 0x82, 0x49,
-  0x5D, 0x5D, 0xA8, 0xF5, 0x55, 0x55, 0x55, 0x55,
-  0x2C, 0x2C, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1,
-  0x2C, 0x2C, 0x2C, 0x95, 0x95, 0xCB, 0x70, 0x70,
-  0x95, 0x83, 0x5F, 0xEA, 0x2D, 0x49, 0x49, 0x49,
-  0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,
-  0x5D, 0x49, 0x22, 0x5A, 0x79, 0x20, 0x20, 0x20,
-  0x80, 0xD2, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0x65, 0xD0, 0x63, 0x5F, 0x29, 0x2D, 0x2D, 0xEA,
-  0x29, 0x29, 0x76, 0x50, 0x2D, 0x82, 0x49, 0x49,
-  0x3E, 0x49, 0x5C, 0xB0, 0xBA, 0x95, 0x55, 0x55,
-  0x2C, 0xA1, 0xD6, 0xD6, 0xD6, 0xA1, 0x2C, 0x2C,
-  0xA1, 0x95, 0x95, 0x55, 0xCB, 0x70, 0x70, 0x55,
-  0x2C, 0x83, 0x60, 0x76, 0x5D, 0x49, 0x49, 0x49,
-  0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,
-  0x49, 0x5D, 0x89, 0xDC, 0x8B, 0x20, 0x20, 0x20,
-  0x20, 0x95, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE2, 0x32, 0x85, 0xE3, 0x29, 0x2D, 0x33, 0x2D,
-  0x2D, 0x2D, 0x6A, 0x2D, 0x33, 0x5D, 0x49, 0x82,
-  0x49, 0x49, 0x82, 0x73, 0x5C, 0x9E, 0x2C, 0x55,
-  0x2C, 0xA1, 0xD6, 0xA1, 0x2C, 0x2C, 0x95, 0x95,
-  0x2C, 0x95, 0x55, 0xCB, 0x90, 0x90, 0xCB, 0x95,
-  0x2C, 0x6D, 0x41, 0x6F, 0x3E, 0x49, 0x49, 0x49,
-  0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,
-  0x49, 0x82, 0x3E, 0x4E, 0x38, 0xCA, 0x20, 0x20,
-  0x20, 0x55, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0x65,
-  0x42, 0xA0, 0xD4, 0xE3, 0x29, 0x2D, 0x82, 0x5D,
-  0x5D, 0x82, 0x82, 0x49, 0x49, 0x49, 0x49, 0x49,
-  0x49, 0x3E, 0x49, 0x49, 0x49, 0x5C, 0x56, 0xD6,
-  0xA1, 0xA1, 0xA1, 0x95, 0x55, 0x55, 0x55, 0x95,
-  0xA1, 0x55, 0x90, 0x70, 0x94, 0x70, 0x95, 0x2C,
-  0x2C, 0xD6, 0xDD, 0x6F, 0x33, 0x49, 0x49, 0x49,
-  0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,
-  0x5D, 0x5D, 0x82, 0x69, 0x22, 0x62, 0x80, 0x34,
-  0x94, 0x6B, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0x65, 0xE5, 0x65, 0x6B,
-  0xD5, 0x88, 0x5B, 0xE3, 0x29, 0x5D, 0x5D, 0x5D,
-  0x5D, 0x5D, 0x5D, 0x5D, 0x49, 0x49, 0x49, 0x82,
-  0x49, 0x49, 0x89, 0x49, 0x82, 0x49, 0x71, 0xBA,
-  0x6D, 0x6D, 0xA1, 0x95, 0x55, 0xCB, 0x55, 0x55,
-  0x2C, 0x55, 0x70, 0x70, 0x70, 0x90, 0x95, 0xA1,
-  0x2C, 0xA1, 0x41, 0x76, 0x5D, 0x5D, 0x49, 0x49,
-  0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,
-  0x49, 0x5D, 0x82, 0x5D, 0x89, 0x5E, 0x96, 0x65,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0xE5, 0xE5, 0xE5, 0xE5, 0x65, 0x65, 0xEC, 0xB1,
-  0x20, 0x20, 0xCA, 0x23, 0x29, 0x33, 0x49, 0x5D,
-  0x49, 0x82, 0x49, 0x49, 0x49, 0x49, 0x49, 0x82,
-  0x49, 0x82, 0x5D, 0x5D, 0x5D, 0x2D, 0x5C, 0x8F,
-  0x6D, 0xD6, 0x2C, 0x55, 0x90, 0xCB, 0x95, 0x95,
-  0x95, 0x55, 0x70, 0x94, 0x70, 0x55, 0x2C, 0xA1,
-  0x95, 0xE8, 0x5F, 0x76, 0x33, 0x5D, 0x49, 0x49,
-  0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,
-  0x49, 0x49, 0x49, 0x49, 0x3E, 0x9C, 0x2F, 0x68,
-  0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-  0x65, 0xE5, 0x65, 0xE5, 0x6B, 0x90, 0x80, 0x20,
-  0x20, 0x20, 0x4F, 0x81, 0x50, 0x3E, 0x49, 0x49,
-  0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,
-  0x69, 0x69, 0x49, 0x5D, 0x2D, 0xC4, 0x46, 0xA3,
-  0xD6, 0x55, 0x70, 0x94, 0x94, 0x70, 0xCB, 0x55,
-  0x55, 0xCB, 0x70, 0x47, 0x70, 0x95, 0xA1, 0xA1,
-  0x95, 0xBD, 0x75, 0x2D, 0x33, 0x49, 0x49, 0x49,
-  0x49, 0x49, 0x5D, 0x49, 0x49, 0x49, 0x49, 0x49,
-  0x49, 0x49, 0x49, 0x49, 0x5D, 0x2D, 0xB5, 0xDB,
-  0xD6, 0x65, 0xE5, 0x65, 0xE5, 0xE5, 0x65, 0xE5,
-  0x65, 0x65, 0x6B, 0x95, 0x2B, 0x88, 0x20, 0x20,
-  0x20, 0x20, 0x8B, 0x81, 0x29, 0x33, 0x49, 0x49,
-  0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,
-  0x49, 0x3E, 0x3E, 0x5E, 0x41, 0x97, 0x27, 0xD6,
-  0x55, 0x94, 0xE6, 0xE6, 0x47, 0x70, 0x55, 0x55,
-  0x94, 0x70, 0x94, 0x94, 0x70, 0x55, 0xA1, 0x2C,
-  0x6D, 0xC5, 0x39, 0x6A, 0x5D, 0x5D, 0x49, 0x49,
-  0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,
-  0x49, 0x49, 0x49, 0x49, 0x3E, 0xEA, 0x30, 0x77,
-  0xE1, 0xC9, 0x94, 0x2C, 0xD6, 0xD6, 0xA1, 0x55,
-  0x47, 0x9F, 0x43, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x80, 0x91, 0x81, 0x6A, 0x2D, 0x49, 0x49,
-  0x49, 0x5D, 0x5D, 0x49, 0x49, 0x5D, 0x5D, 0x82,
-  0xEB, 0x4A, 0x41, 0xC2, 0x8F, 0xF5, 0xA1, 0x55,
-  0x94, 0x28, 0xA0, 0x47, 0x70, 0x55, 0x95, 0x95,
-  0x47, 0x70, 0x70, 0x94, 0x90, 0x95, 0xA1, 0x2C,
-  0xE8, 0xA6, 0x39, 0x76, 0x50, 0x50, 0x2D, 0x2D,
-  0x3E, 0x3E, 0x5D, 0x3E, 0x5D, 0x5D, 0x49, 0x82,
-  0x49, 0x49, 0x49, 0x82, 0x82, 0x50, 0x75, 0xE0,
-  0x57, 0x20, 0x88, 0x88, 0x20, 0x20, 0x88, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x79, 0x91, 0x81, 0x76, 0x33, 0x49, 0x49,
-  0x5D, 0x82, 0x49, 0x49, 0x3E, 0x6A, 0xEA, 0x29,
-  0xDF, 0x97, 0xBF, 0x6D, 0x6D, 0xD6, 0x55, 0x47,
-  0x28, 0x28, 0x47, 0x70, 0x55, 0x95, 0x2C, 0x2C,
-  0x95, 0x95, 0x55, 0x90, 0x90, 0x95, 0xA1, 0xA1,
-  0xD6, 0x26, 0x45, 0x81, 0x5F, 0x30, 0x48, 0x6F,
-  0x6F, 0x29, 0x29, 0x6A, 0x2D, 0x2D, 0x5D, 0x49,
-  0x49, 0x49, 0x49, 0x49, 0x2D, 0x76, 0x6E, 0x77,
-  0x5B, 0x66, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x79, 0xA9, 0xB8, 0x39, 0x50, 0x5D, 0x5D,
-  0x5D, 0x5D, 0x3E, 0x2D, 0x29, 0x76, 0xCD, 0x37,
-  0xB9, 0xA1, 0xA1, 0x6D, 0x6D, 0x2C, 0x94, 0x28,
-  0xD5, 0xE6, 0x70, 0x55, 0x95, 0xA1, 0x2C, 0xA1,
-  0xBF, 0xA1, 0x95, 0xCB, 0x55, 0x95, 0xA1, 0x2C,
-  0x95, 0x83, 0xDE, 0x87, 0xB6, 0xBE, 0x40, 0x6E,
-  0x81, 0x81, 0x78, 0x78, 0x39, 0x6F, 0xEA, 0x2D,
-  0x2D, 0x33, 0x33, 0x33, 0x76, 0x30, 0x64, 0x54,
-  0x5B, 0x66, 0x20, 0x20, 0x66, 0x20, 0x88, 0x20,
-  0x20, 0x20, 0x88, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x88, 0x34, 0x8B, 0xF1, 0x23, 0x6F, 0x50, 0x2D,
-  0x2D, 0x6A, 0x29, 0x6F, 0x78, 0x84, 0x9B, 0xD2,
-  0x2C, 0x2C, 0xD6, 0x6D, 0x6D, 0x2C, 0x47, 0xA0,
-  0xE6, 0x70, 0x55, 0x95, 0x2C, 0xA1, 0xA1, 0xA1,
-  0xD2, 0x95, 0x55, 0xCB, 0x55, 0x2C, 0xD6, 0xA1,
-  0x95, 0x95, 0xA1, 0xD6, 0x6D, 0x6D, 0xBA, 0xF3,
-  0x8D, 0x36, 0x74, 0x36, 0xF1, 0xB8, 0x23, 0x78,
-  0x62, 0x4A, 0x29, 0x62, 0x23, 0xF1, 0x54, 0x31,
-  0x57, 0x2B, 0x90, 0x95, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xA1, 0xA1, 0xA1, 0xA1, 0x2C, 0x2C, 0x2C, 0xCB,
-  0xE6, 0x7D, 0xCA, 0xB7, 0xB8, 0x75, 0x6F, 0x6F,
-  0x76, 0x6F, 0x78, 0x81, 0x53, 0xBD, 0x6D, 0x2C,
-  0x95, 0x95, 0xA1, 0x6D, 0xA1, 0x55, 0x94, 0xE6,
-  0x70, 0xCB, 0x55, 0x95, 0xA1, 0xD6, 0xD6, 0xA1,
-  0xD0, 0x94, 0x94, 0x90, 0x95, 0x2C, 0xD6, 0xA1,
-  0x95, 0x55, 0x2C, 0xA1, 0xD6, 0xA1, 0x95, 0x2C,
-  0xD6, 0x68, 0xAB, 0x6C, 0xA4, 0x77, 0x77, 0xAD,
-  0x40, 0x53, 0x6E, 0x40, 0xB7, 0x54, 0x31, 0xD7,
-  0xAC, 0xD6, 0x55, 0x55, 0x95, 0x95, 0x95, 0x55,
-  0x95, 0x2C, 0x2C, 0xA1, 0x95, 0x95, 0x2C, 0xA1,
-  0x6D, 0xD2, 0x7C, 0x54, 0xAD, 0x40, 0x6E, 0x81,
-  0x81, 0x6E, 0x36, 0xDA, 0xE8, 0xD6, 0xD6, 0x2C,
-  0x2C, 0x2C, 0xA1, 0xD6, 0x95, 0x90, 0x94, 0x47,
-  0x94, 0x94, 0x70, 0x55, 0x2C, 0xD6, 0xA1, 0x95,
-  0x95, 0x28, 0x47, 0x90, 0x95, 0x2C, 0xA1, 0x2C,
-  0x55, 0x95, 0x2C, 0xA1, 0xA1, 0x2C, 0x2C, 0x2C,
-  0x2C, 0xA1, 0x55, 0x70, 0x95, 0x2C, 0xB2, 0xB4,
-  0xC3, 0xC3, 0x54, 0x54, 0xA9, 0x31, 0xCA, 0x2A,
-  0x95, 0x90, 0x55, 0x95, 0x2C, 0xA1, 0x2C, 0x95,
-  0x95, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0xD6,
-  0x6D, 0x2A, 0xB2, 0x4F, 0x31, 0x2E, 0xE0, 0xAD,
-  0xB7, 0xC8, 0xB4, 0xF5, 0x2C, 0xA1, 0xA1, 0xA1,
-  0x95, 0x2C, 0xA1, 0x2C, 0x95, 0x70, 0x94, 0x94,
-  0x94, 0x94, 0x70, 0x95, 0xD6, 0xD6, 0x2C, 0x95,
-  0x94, 0x28, 0x47, 0xCB, 0x95, 0x2C, 0xA1, 0xA1,
-  0x95, 0x55, 0x2C, 0xA1, 0xD6, 0xA1, 0x95, 0x95,
-  0x95, 0x2C, 0x55, 0x70, 0x70, 0x70, 0x94, 0x2C,
-  0x63, 0xBB, 0xA5, 0xD7, 0xCA, 0xB3, 0x6D, 0x2C,
-  0x55, 0x55, 0x95, 0x2C, 0x2C, 0x2C, 0x95, 0x95,
-  0x95, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0xA1,
-  0xD6, 0x2C, 0x70, 0x95, 0xAC, 0xC0, 0xDB, 0xEF,
-  0xEF, 0xA2, 0xE8, 0x95, 0x95, 0xA1, 0xD6, 0xA1,
-  0x95, 0x55, 0x2C, 0x95, 0x55, 0x70, 0x70, 0x70,
-  0x94, 0x70, 0x55, 0xD6, 0x6D, 0x6D, 0x95, 0x55,
-  0x70, 0x47, 0x70, 0x95, 0x2C, 0x2C, 0x2C, 0xA1,
-  0x2C, 0x95, 0x2C, 0xA1, 0xD6, 0xA1, 0x95, 0x55,
-  0x55, 0x95, 0x55, 0x55, 0x55, 0x55, 0x55, 0x95,
-  0xA1, 0xF5, 0xBF, 0xBF, 0xA1, 0x95, 0x95, 0x95,
-  0x95, 0x55, 0x2C, 0x2C, 0x95, 0x55, 0x55, 0x95,
-  0x95, 0x95, 0xA1, 0xA1, 0xA1, 0xA1, 0x2C, 0xA1,
-  0x2C, 0x55, 0x70, 0x94, 0x90, 0x2C, 0x6D, 0x6D,
-  0x6D, 0xA1, 0x2C, 0x95, 0x2C, 0xA1, 0xD6, 0xA1,
-  0x2C, 0x55, 0x55, 0x95, 0x55, 0x55, 0x55, 0x55,
-  0x55, 0x95, 0xD6, 0x6D, 0xBF, 0xD6, 0x55, 0xCB,
-  0x55, 0x55, 0x55, 0x2C, 0x2C, 0x2C, 0x2C, 0xA1,
-  0xA1, 0x95, 0x2C, 0xA1, 0xA1, 0xA1, 0x2C, 0x95,
-  0x55, 0x95, 0x95, 0x2C, 0x2C, 0x2C, 0x2C, 0xA1,
-  0x6D, 0xBF, 0x6D, 0x2C, 0x55, 0x55, 0x95, 0x95,
-  0xCB, 0xCB, 0x55, 0x55, 0xCB, 0x55, 0x55, 0x95,
-  0x95, 0x2C, 0x2C, 0xA1, 0xA1, 0xA1, 0x2C, 0x2C,
-  0xA1, 0x95, 0xCB, 0xCB, 0x95, 0x95, 0x2C, 0x2C,
-  0x2C, 0xA1, 0x2C, 0x2C, 0x2C, 0xA1, 0xA1, 0x2C,
-  0x2C, 0x95, 0x55, 0x95, 0x95, 0x2C, 0x2C, 0x2C,
-  0x2C, 0xA1, 0x6D, 0xBF, 0x6D, 0xA1, 0x55, 0x55,
-  0x95, 0x95, 0x95, 0x95, 0x2C, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x95, 0x95, 0x95, 0x2C, 0x2C, 0x2C, 0x95,
-  0x55, 0x95, 0x2C, 0x2C, 0xA1, 0xA1, 0xD6, 0xD6,
-  0x6D, 0x6D, 0xA1, 0x95, 0xCB, 0x55, 0x95, 0x55,
-  0x90, 0x70, 0xCB, 0xCB, 0x90, 0xCB, 0x95, 0x95,
-  0x2C, 0x2C, 0xA1, 0xD6, 0xA1, 0xA1, 0xA1, 0xA1,
-  0xA1, 0xA1, 0x2C, 0x95, 0x95, 0x2C, 0x2C, 0x2C,
-  0x2C, 0xA1, 0x2C, 0x95, 0x95, 0x95, 0x2C, 0x2C,
-  0x2C, 0x95, 0x55, 0x55, 0x2C, 0x2C, 0xA1, 0xA1,
-  0xD6, 0xD6, 0x6D, 0x6D, 0xA1, 0x55, 0xCB, 0x55
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22,
+    0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+    0x26, 0x26, 0x25, 0x28, 0x23, 0x22, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x25, 0x2a, 0x2b, 0x2c, 0x2d, 0x2d,
+    0x2d, 0x2e, 0x2c, 0x2b, 0x2a, 0x25, 0x28, 0x22,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x24, 0x2a, 0x2c, 0x2f, 0x2c, 0x30, 0x30, 0x24,
+    0x25, 0x27, 0x2b, 0x2c, 0x2f, 0x31, 0x32, 0x25,
+    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
+    0x33, 0x34, 0x35, 0x21, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x21, 0x2b, 0x2f, 0x2c,
+    0x30, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
+    0x2d, 0x27, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x31,
+    0x2d, 0x32, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x2a, 0x34,
+    0x25, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x23, 0x32, 0x27, 0x21, 0x36,
+    0x2a, 0x2d, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x22, 0x26, 0x2c, 0x35,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x25, 0x2f, 0x37, 0x32, 0x22,
+    0x36, 0x35, 0x31, 0x27, 0x22, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x22,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x26, 0x38, 0x38, 0x35, 0x25,
+    0x36, 0x21, 0x2d, 0x2b, 0x24, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x24, 0x39, 0x39, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x25, 0x2b, 0x30, 0x28, 0x22,
+    0x36, 0x36, 0x27, 0x34, 0x30, 0x23, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x26, 0x2d, 0x26, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x22, 0x22, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x2d, 0x33, 0x28, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x2b, 0x2c, 0x25, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x36, 0x36,
+    0x36, 0x21, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x21, 0x23, 0x22, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x28, 0x34, 0x27, 0x22, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
+    0x21, 0x21, 0x24, 0x27, 0x21, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x28, 0x27, 0x22, 0x33, 0x24, 0x36,
+    0x36, 0x36, 0x36, 0x22, 0x2f, 0x2a, 0x23, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
+    0x30, 0x3a, 0x38, 0x24, 0x24, 0x36, 0x36, 0x36,
+    0x23, 0x2f, 0x3b, 0x3c, 0x3d, 0x30, 0x25, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2f, 0x32, 0x23, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x23,
+    0x3e, 0x3f, 0x40, 0x3a, 0x22, 0x36, 0x36, 0x21,
+    0x41, 0x42, 0x43, 0x44, 0x45, 0x3e, 0x23, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2f, 0x33, 0x28, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x2b,
+    0x44, 0x40, 0x46, 0x47, 0x35, 0x36, 0x36, 0x26,
+    0x43, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x2e, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x32, 0x34, 0x36, 0x4d,
+    0x4e, 0x25, 0x2f, 0x46, 0x4a, 0x22, 0x23, 0x32,
+    0x4f, 0x50, 0x21, 0x31, 0x51, 0x52, 0x53, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x21, 0x3a,
+    0x4d, 0x21, 0x31, 0x54, 0x55, 0x28, 0x30, 0x2b,
+    0x4b, 0x4d, 0x36, 0x23, 0x32, 0x50, 0x3f, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x20, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x38, 0x23, 0x37,
+    0x55, 0x36, 0x28, 0x3a, 0x56, 0x57, 0x57, 0x58,
+    0x3c, 0x4d, 0x36, 0x36, 0x36, 0x40, 0x40, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x29, 0x29, 0x29, 0x20, 0x29, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x51, 0x23, 0x35,
+    0x43, 0x25, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
+    0x5f, 0x60, 0x61, 0x36, 0x31, 0x47, 0x3b, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x31, 0x2c, 0x25, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x22,
+    0x40, 0x62, 0x63, 0x5d, 0x64, 0x65, 0x66, 0x67,
+    0x68, 0x69, 0x66, 0x5e, 0x6a, 0x6b, 0x2a, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x33, 0x2e, 0x26, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x2f, 0x23, 0x36,
+    0x6c, 0x63, 0x6d, 0x64, 0x5c, 0x66, 0x69, 0x6e,
+    0x6f, 0x70, 0x71, 0x69, 0x69, 0x72, 0x6c, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x33, 0x34, 0x27, 0x22,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x34, 0x26, 0x73,
+    0x74, 0x75, 0x76, 0x64, 0x65, 0x77, 0x69, 0x78,
+    0x70, 0x71, 0x71, 0x71, 0x72, 0x5f, 0x5e, 0x21,
+    0x36, 0x36, 0x36, 0x36, 0x25, 0x38, 0x2a, 0x23,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x33, 0x79,
+    0x63, 0x7a, 0x7b, 0x5c, 0x66, 0x69, 0x6e, 0x7c,
+    0x71, 0x71, 0x69, 0x7d, 0x7e, 0x7a, 0x7f, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x21, 0x51, 0x2b, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x32, 0x24,
+    0x80, 0x81, 0x64, 0x82, 0x77, 0x69, 0x71, 0x71,
+    0x69, 0x83, 0x84, 0x85, 0x7a, 0x85, 0x86, 0x36,
+    0x21, 0x2b, 0x23, 0x36, 0x36, 0x39, 0x2e, 0x26,
+    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x27, 0x2d, 0x33, 0x21,
+    0x87, 0x88, 0x89, 0x72, 0x67, 0x66, 0x5f, 0x89,
+    0x8a, 0x63, 0x85, 0x8b, 0x8c, 0x8d, 0x41, 0x36,
+    0x36, 0x2d, 0x3a, 0x35, 0x36, 0x24, 0x51, 0x32,
+    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x33, 0x21,
+    0x55, 0x8e, 0x8f, 0x8a, 0x7d, 0x5e, 0x90, 0x7e,
+    0x75, 0x75, 0x90, 0x62, 0x40, 0x3f, 0x49, 0x23,
+    0x36, 0x24, 0x3a, 0x3a, 0x24, 0x36, 0x2e, 0x31,
+    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x21, 0x28, 0x33, 0x37, 0x25, 0x22,
+    0x3b, 0x50, 0x8e, 0x8f, 0x90, 0x7e, 0x90, 0x63,
+    0x74, 0x91, 0x92, 0x42, 0x93, 0x4b, 0x45, 0x2c,
+    0x36, 0x36, 0x33, 0x39, 0x21, 0x36, 0x22, 0x51,
+    0x33, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x22, 0x27, 0x2e, 0x2e, 0x36, 0x21,
+    0x94, 0x3f, 0x50, 0x95, 0x96, 0x8f, 0x8f, 0x97,
+    0x8e, 0x42, 0x50, 0x43, 0x47, 0x48, 0x48, 0x98,
+    0x21, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39,
+    0x2e, 0x27, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x22, 0x24, 0x2b, 0x38, 0x28, 0x36, 0x32,
+    0x4c, 0x4b, 0x50, 0x50, 0x50, 0x42, 0x42, 0x50,
+    0x50, 0x40, 0x45, 0x99, 0x48, 0x48, 0x48, 0x48,
+    0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x23,
+    0x2f, 0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x28, 0x32, 0x51, 0x32, 0x28, 0x21, 0x98,
+    0x48, 0x47, 0x9a, 0x50, 0x50, 0x50, 0x50, 0x50,
+    0x9a, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x93, 0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x2a, 0x2f, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x23, 0x30, 0x2e, 0x2c, 0x36, 0x21, 0x51, 0x9b,
+    0x48, 0x48, 0x52, 0x3f, 0x50, 0x50, 0x40, 0x4b,
+    0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2d, 0x31, 0x27, 0x23, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+    0x27, 0x2c, 0x2d, 0x21, 0x36, 0x28, 0x44, 0x48,
+    0x48, 0x48, 0x48, 0x47, 0x46, 0x4f, 0x47, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x9c, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x28, 0x51, 0x39, 0x26, 0x22, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
+    0x35, 0x51, 0x28, 0x36, 0x36, 0x9d, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x9b, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x4f, 0x28, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x28, 0x38, 0x2b, 0x25, 0x22, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
+    0x51, 0x25, 0x36, 0x36, 0x23, 0x40, 0x9b, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x9b, 0x99, 0x2b, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x30, 0x2f, 0x33, 0x24, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x23, 0x30, 0x34,
+    0x27, 0x36, 0x36, 0x36, 0x2a, 0x40, 0x47, 0x48,
+    0x48, 0x48, 0x48, 0x9b, 0x99, 0x99, 0x9b, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x47, 0x52,
+    0x46, 0x4f, 0x37, 0x21, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x30, 0x34, 0x2a, 0x23,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x22, 0x25, 0x39, 0x2c,
+    0x36, 0x36, 0x36, 0x21, 0x31, 0x4e, 0x9a, 0x4c,
+    0x47, 0x9b, 0x9b, 0x52, 0x46, 0x4f, 0x52, 0x9b,
+    0x9b, 0x9b, 0x47, 0x4f, 0x45, 0x9a, 0x93, 0x93,
+    0x3f, 0x93, 0x98, 0x28, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c, 0x26,
+    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x28,
+    0x36, 0x36, 0x36, 0x22, 0x38, 0x98, 0x44, 0x99,
+    0x9b, 0x48, 0x48, 0x9b, 0x4c, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x47, 0x52, 0x46, 0x43, 0x93,
+    0x40, 0x40, 0x43, 0x53, 0x21, 0x23, 0x33, 0x23,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x2f, 0x32,
+    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x24, 0x2b, 0x31, 0x36,
+    0x36, 0x22, 0x36, 0x24, 0x9e, 0x4f, 0x9b, 0x48,
+    0x48, 0x48, 0x48, 0x9b, 0x99, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x47,
+    0x4f, 0x9a, 0x3f, 0x46, 0x38, 0x36, 0x21, 0x30,
+    0x26, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c,
+    0x25, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x22, 0x26, 0x2e, 0x33, 0x36,
+    0x25, 0x25, 0x36, 0x4d, 0x52, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x47, 0x44, 0x93, 0x43, 0x23, 0x36, 0x36,
+    0x26, 0x24, 0x36, 0x36, 0x36, 0x36, 0x28, 0x2f,
+    0x2a, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x23, 0x2a, 0x51, 0x24, 0x36,
+    0x2a, 0x36, 0x28, 0x44, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x9b, 0x4b, 0x44, 0x37, 0x36, 0x23,
+    0x28, 0x30, 0x22, 0x36, 0x36, 0x36, 0x36, 0x2d,
+    0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x21, 0x28, 0x2b, 0x34, 0x36, 0x25,
+    0x24, 0x36, 0x4a, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x9b, 0x52, 0x3f, 0x21, 0x30,
+    0x35, 0x25, 0x30, 0x36, 0x36, 0x36, 0x36, 0x32,
+    0x2d, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x22, 0x26, 0x2e, 0x35, 0x36, 0x2a,
+    0x36, 0x24, 0x4f, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x9b, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x47, 0x32, 0x30,
+    0x2a, 0x23, 0x30, 0x23, 0x36, 0x36, 0x36, 0x21,
+    0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x2a, 0x51, 0x28, 0x28, 0x25,
+    0x36, 0x3a, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x9b, 0x52, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x38, 0x21,
+    0x36, 0x36, 0x22, 0x27, 0x36, 0x36, 0x36, 0x36,
+    0x2e, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x22, 0x25, 0x2c, 0x34, 0x36, 0x30, 0x21,
+    0x23, 0x43, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x47, 0x99, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x94, 0x36,
+    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
+    0x2a, 0x2e, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x2a, 0x51, 0x25, 0x21, 0x2a, 0x36,
+    0x2e, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x99, 0x99, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x98, 0x36,
+    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
+    0x22, 0x2f, 0x30, 0x22, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x22, 0x25, 0x2c, 0x34, 0x36, 0x24, 0x28, 0x36,
+    0x54, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x4c, 0x99, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36,
+    0x36, 0x36, 0x36, 0x30, 0x36, 0x36, 0x36, 0x36,
+    0x21, 0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x28, 0x32, 0x2f, 0x28, 0x36, 0x27, 0x22, 0x21,
+    0x43, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x4c, 0x99, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4b, 0x21,
+    0x36, 0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x25, 0x2c, 0x39, 0x36, 0x36, 0x30, 0x22, 0x25,
+    0x52, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x4f, 0x52, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4f, 0x21,
+    0x36, 0x36, 0x22, 0x26, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x30, 0x2d, 0x21, 0x36, 0x36, 0x32, 0x23, 0x2a,
+    0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x4f, 0x99, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4c, 0x22,
+    0x36, 0x36, 0x24, 0x23, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0x2e, 0x36, 0x36, 0x23, 0x31, 0x27, 0x39,
+    0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x4f, 0x47, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4c, 0x23,
+    0x36, 0x36, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x2b, 0x39, 0x36, 0x36, 0x36, 0x26, 0x32, 0x31,
+    0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x4f, 0x47, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x46, 0x22,
+    0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x35, 0x39, 0x36, 0x36, 0x36, 0x36, 0x26, 0x2d,
+    0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x4f, 0x47, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36,
+    0x24, 0x27, 0x9f, 0x24, 0x25, 0x28, 0x21, 0x36,
+    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x25,
+    0x39, 0x4d, 0xa0, 0x84, 0x81, 0x57, 0x21, 0x39,
+    0x52, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x4f, 0x47, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x53, 0x28,
+    0x23, 0x36, 0x36, 0x36, 0x21, 0x28, 0x2c, 0x30,
+    0x21, 0x38, 0x33, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x28, 0x30,
+    0x2d, 0xa1, 0x7a, 0xa2, 0xa3, 0xa3, 0x7f, 0x22,
+    0x51, 0x52, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0xa4, 0xa5, 0xa5, 0xa6, 0x61,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x30, 0x32,
+    0x25, 0x4d, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x24, 0x26, 0x30, 0x33, 0x31,
+    0x4d, 0x91, 0x5b, 0xa2, 0xa3, 0xa3, 0xa3, 0x5a,
+    0x21, 0x2e, 0x46, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0xa7, 0xa8, 0x69, 0x66, 0xa9,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x26, 0x25,
+    0x83, 0xaa, 0x2c, 0x25, 0x21, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x28, 0x30, 0x35, 0x2d, 0x2f, 0x37, 0x4a,
+    0x60, 0x85, 0xab, 0xac, 0xa3, 0xa3, 0xa3, 0x82,
+    0x86, 0x36, 0x32, 0x3f, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x4c, 0x99, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0xad, 0xa2, 0xa8, 0xae, 0xaf,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x57,
+    0x77, 0x66, 0x34, 0x27, 0x22, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x23, 0x30, 0x31, 0xb0, 0x91, 0x7e, 0x90, 0x90,
+    0x8b, 0x5b, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+    0x5d, 0xb1, 0x36, 0x24, 0x53, 0x9b, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x9b, 0x99, 0xad, 0x64, 0x5c, 0x8b, 0xb1,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x73, 0x5d,
+    0x82, 0x5c, 0xb2, 0x2a, 0x23, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x24, 0x2b, 0xb0, 0x8b, 0x5b, 0x76, 0x5b, 0x5b,
+    0x7b, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+    0xa8, 0x5e, 0x22, 0x36, 0x21, 0x3a, 0x99, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x4f, 0x3f, 0xb3, 0x7b, 0x7b, 0x85, 0x80,
+    0x9f, 0x36, 0x36, 0x36, 0x21, 0xb4, 0x7e, 0x7b,
+    0x64, 0x64, 0xb5, 0x35, 0x24, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x31, 0xb6, 0x5b, 0x64, 0xa2, 0xa2, 0xac,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+    0xa3, 0x66, 0xb7, 0x36, 0x36, 0x36, 0x2c, 0x4b,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x9a, 0x3f, 0xb8, 0x76, 0x76, 0x7a, 0x63,
+    0xb9, 0xba, 0x86, 0xba, 0xbb, 0x90, 0x5b, 0x64,
+    0xa2, 0xa2, 0xbc, 0x2d, 0x27, 0x23, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x26, 0x2d, 0x91, 0x5b, 0x64, 0xa3, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+    0xa3, 0xa8, 0x83, 0xaf, 0x36, 0x36, 0x36, 0x30,
+    0x44, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x9b, 0x9a, 0x3f, 0xbd, 0x5b, 0x7b, 0xbe, 0x85,
+    0x7e, 0x90, 0x63, 0x90, 0x85, 0x5b, 0xa2, 0xa3,
+    0xa3, 0xac, 0x5d, 0xb5, 0x39, 0x26, 0x23, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2d, 0xbf, 0xbe, 0x64, 0xa3, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa8, 0x88, 0x36, 0x36, 0x36, 0x36,
+    0x2d, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x9b, 0x45, 0x3f, 0xc0, 0x6d, 0x7b, 0xab, 0xbe,
+    0x7a, 0x8b, 0x8b, 0x7a, 0x5b, 0x64, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa2, 0xc1, 0x37, 0x35, 0x26, 0x23,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2e, 0xbf, 0x7a, 0x7b, 0xa3, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa8, 0x72, 0x73, 0x36, 0x36, 0x36,
+    0x24, 0x52, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x46, 0x42, 0xb6, 0x7a, 0x7b, 0x64, 0x7b,
+    0x76, 0x5b, 0x5b, 0x76, 0x7b, 0xa2, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xac, 0x64, 0xc1, 0x4d, 0x2c, 0x27,
+    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x25, 0x31, 0xc2, 0x8b, 0x7b, 0xa3, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa8, 0x89, 0x9f, 0x36, 0x36,
+    0x32, 0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x4b, 0x2f, 0x8f, 0x7a, 0x7b, 0xa2, 0xac,
+    0xa2, 0x64, 0x64, 0xa2, 0xa2, 0xac, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0x5d, 0xc3, 0x2c,
+    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x25, 0x31, 0xc2, 0x85, 0x7b, 0xa3, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0x66, 0x57, 0x27, 0x4d,
+    0x4b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x99, 0x34, 0x9f, 0xb9, 0x7a, 0x7b, 0xa2, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xc2,
+    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+    0x26, 0x2d, 0xc2, 0x85, 0x7b, 0xac, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa8, 0x5f, 0x92, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x44,
+    0x35, 0x36, 0xaf, 0xbb, 0x7a, 0x7b, 0xac, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0xa2, 0xc0,
+    0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+    0x30, 0x2f, 0xb6, 0x8b, 0x7b, 0xac, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x66, 0x89, 0x45,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x4e, 0x25,
+    0x36, 0x36, 0x61, 0xb9, 0x6d, 0x64, 0xac, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0x7b, 0xbe, 0xc3,
+    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0xc4, 0x63, 0xbe, 0xa2, 0xa3, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0x72, 0x81, 0xc5,
+    0x46, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+    0x48, 0x48, 0x48, 0x48, 0x3f, 0x2c, 0x36, 0x36,
+    0x36, 0x36, 0xc6, 0x8f, 0x6d, 0x64, 0xac, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa2, 0xab, 0x8b, 0xb0, 0x2c,
+    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x35, 0x96, 0x75, 0xab, 0xa2, 0xac, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0x7b, 0x81, 0xb9,
+    0x73, 0x3b, 0x44, 0x9b, 0x48, 0x48, 0x48, 0x9b,
+    0x99, 0x43, 0x94, 0x2c, 0x21, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x73, 0xb9, 0x7a, 0x7b, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+    0xa3, 0x64, 0x76, 0x7a, 0x91, 0xb5, 0x31, 0x30,
+    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+    0x39, 0x97, 0x75, 0xbe, 0x7b, 0x64, 0xa2, 0xa2,
+    0xac, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x7b, 0x7a, 0xc7,
+    0xc8, 0x36, 0x21, 0x26, 0x2b, 0x39, 0x33, 0x30,
+    0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xc8, 0xbb, 0x8b, 0x7b, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0x64, 0x64,
+    0x76, 0x85, 0xbf, 0xb5, 0x34, 0x2b, 0x27, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+    0x33, 0xc9, 0x63, 0x7e, 0x7a, 0x6d, 0xbe, 0x5b,
+    0x76, 0x7b, 0x64, 0x64, 0xa2, 0xac, 0xa3, 0xa3,
+    0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0x76, 0x85, 0xb9,
+    0x79, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xca, 0xbb, 0x75, 0x76, 0xa2, 0xa3,
+    0xa3, 0xa3, 0xac, 0xa2, 0x64, 0x76, 0xbe, 0x8b,
+    0xb6, 0xb5, 0x2f, 0x35, 0x30, 0x24, 0x22, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+    0x27, 0x31, 0xcb, 0xc9, 0xbb, 0x74, 0x63, 0x90,
+    0x7e, 0x75, 0x8b, 0x6d, 0xbe, 0x76, 0x64, 0xa2,
+    0xac, 0xac, 0xac, 0xac, 0x64, 0x7a, 0x84, 0xcc,
+    0x79, 0x9f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x21, 0xc8, 0xcc, 0x63, 0x6d, 0x7b, 0x64,
+    0xac, 0xa2, 0x64, 0x7b, 0xbe, 0x75, 0x63, 0x96,
+    0x38, 0x39, 0x2a, 0x24, 0x23, 0x21, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x28, 0x27, 0x35, 0x2d, 0x41, 0xb5, 0xc5, 0x8f,
+    0xb9, 0xbb, 0xc7, 0x74, 0x84, 0x90, 0x85, 0x6d,
+    0x5b, 0x7b, 0x7b, 0xab, 0x6d, 0x90, 0xb9, 0xcd,
+    0xca, 0x22, 0x36, 0x36, 0x28, 0x30, 0x30, 0x30,
+    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x25, 0x36,
+    0x36, 0x21, 0xb4, 0x80, 0xc7, 0x7e, 0x6d, 0x76,
+    0xab, 0x76, 0x6d, 0x85, 0x63, 0xb9, 0xb5, 0x34,
+    0x33, 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x23, 0x24, 0x27, 0x2a, 0x35, 0x2e, 0x2f,
+    0x41, 0xce, 0xcf, 0x6c, 0x80, 0xcc, 0xb9, 0x74,
+    0x84, 0x90, 0x75, 0x7e, 0x74, 0x8f, 0xcd, 0x79,
+    0xc6, 0x2b, 0x9d, 0x41, 0x2f, 0x34, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x2f, 0x38,
+    0x4d, 0x37, 0xd0, 0xd1, 0x8f, 0x74, 0x63, 0x7e,
+    0x75, 0x7e, 0x63, 0xc7, 0x88, 0xc4, 0x31, 0x2a,
+    0x24, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x21, 0x22, 0x23, 0x24, 0x26, 0x30,
+    0x33, 0x39, 0x2e, 0x51, 0x41, 0xb2, 0x6c, 0xd1,
+    0x80, 0xcc, 0xcc, 0xcc, 0xd2, 0xd1, 0xb7, 0xd3,
+    0x41, 0x34, 0x35, 0x32, 0x30, 0x27, 0x27, 0x27,
+    0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x2a,
+    0x2b, 0x34, 0xd4, 0xca, 0xd5, 0x8f, 0xbb, 0xc7,
+    0xc7, 0xbb, 0xcc, 0x6c, 0x41, 0x39, 0x27, 0x28,
+    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22,
+    0x28, 0x24, 0x26, 0x2a, 0x33, 0x2c, 0x2f, 0x41,
+    0xd6, 0xb7, 0x79, 0x79, 0x79, 0xca, 0xd7, 0x51,
+    0x39, 0x30, 0x24, 0x23, 0x22, 0x22, 0x22, 0x22,
+    0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23,
+    0x24, 0x2a, 0x31, 0xd8, 0xc8, 0x79, 0xd1, 0x80,
+    0xd5, 0xba, 0xd9, 0x2f, 0x35, 0x26, 0x23, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x22, 0x23, 0x28, 0x25, 0x30, 0x2b,
+    0x31, 0x2f, 0xd4, 0xd8, 0xd8, 0x2f, 0x2e, 0x33,
+    0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x21, 0x28, 0x27, 0x35, 0x34, 0xd8, 0xd8, 0xd8,
+    0xda, 0xd4, 0x2e, 0x33, 0x25, 0x23, 0x21, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x23, 0x28,
+    0x26, 0x30, 0x32, 0x2b, 0x33, 0x2a, 0x26, 0x28,
+    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x21, 0x23, 0x25, 0x30, 0x33, 0x35, 0x35,
+    0x2b, 0x2a, 0x26, 0x28, 0x22, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+    0x21, 0x22, 0x23, 0x28, 0x28, 0x23, 0x22, 0x21,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x21, 0x23, 0x28, 0x24, 0x24,
+    0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 };
 
-#endif
+#endif /* !__HAVE_ARCH_LINUX_LOGO */
 
-#ifdef INCLUDE_LINUX_LOGOBW
+#ifndef __HAVE_ARCH_LINUX_LOGOBW
 
 unsigned char linux_logo_bw[] __initdata = {
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F,
-  0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFE, 0x3F, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xC7, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xC3,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF,
-  0xFB, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFD, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF1,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF,
-  0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xF9, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xF9, 0xCF, 0xC3, 0xF8, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x87, 0x81, 0xF9,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xA7,
-  0x99, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xF9, 0xF3, 0xBC, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xF9, 0xE3, 0xBC, 0xF9, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0, 0x3C, 0xF9,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xB0,
-  0x19, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xF9, 0xC0, 0x03, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x80, 0x01, 0xF8,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x80,
-  0x01, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xF9, 0xC0, 0x21, 0xD8, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xF9, 0xB1, 0x80, 0xEC, 0xC0, 0x1F,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x90, 0x00, 0xE4,
-  0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x8C,
-  0xC0, 0x7C, 0x04, 0x81, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xE3, 0x80, 0x00, 0x7C, 0x40, 0x11, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xE3, 0x80, 0x00, 0x7F, 0xD2, 0x29,
-  0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0x00, 0x00, 0x3F,
-  0x80, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0x0E, 0x00,
-  0x00, 0x3F, 0x80, 0x19, 0xFF, 0xFF, 0xFF, 0xFF,
-  0x1E, 0x00, 0x00, 0x1F, 0x80, 0x19, 0xFF, 0xFF,
-  0xFF, 0xFE, 0x1C, 0x00, 0x00, 0x1E, 0x80, 0x19,
-  0xFF, 0xFF, 0xFF, 0xFE, 0x3C, 0x00, 0x00, 0x1E,
-  0x80, 0x11, 0xFF, 0xFF, 0xFF, 0xFC, 0x7C, 0x00,
-  0x00, 0x0F, 0x80, 0x11, 0xFF, 0xFF, 0xFF, 0xFC,
-  0xF8, 0x00, 0x00, 0x0E, 0x80, 0x11, 0xFF, 0xFF,
-  0xFF, 0xFC, 0xF8, 0x00, 0x00, 0x06, 0x00, 0x11,
-  0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0x00, 0x00, 0x06,
-  0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF9, 0xF0, 0x00,
-  0x00, 0x02, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xF1,
-  0xF0, 0x00, 0x00, 0x02, 0x80, 0x10, 0xFF, 0xFF,
-  0xFF, 0xF1, 0xE0, 0x00, 0x00, 0x00, 0x97, 0x10,
-  0xFF, 0xFF, 0xFF, 0xE3, 0xE0, 0x00, 0x00, 0x00,
-  0xDF, 0xF0, 0xFF, 0xFF, 0xFF, 0xE3, 0xC0, 0x00,
-  0x00, 0x00, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xC7,
-  0xC0, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF,
-  0xFF, 0xC7, 0x80, 0x00, 0x00, 0x01, 0xFF, 0xF8,
-  0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x00, 0x01,
-  0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0x00,
-  0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x9F,
-  0x80, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF,
-  0xFF, 0x9F, 0x80, 0x00, 0x00, 0x01, 0x80, 0x18,
-  0xFF, 0xFF, 0xFF, 0x9E, 0x80, 0x00, 0x00, 0x03,
-  0xA8, 0x11, 0xFF, 0xFF, 0xFF, 0x9F, 0x80, 0x00,
-  0x00, 0x02, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x99,
-  0x80, 0x00, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF,
-  0xFF, 0x00, 0x80, 0x00, 0x00, 0x01, 0xC0, 0x01,
-  0xFF, 0xFF, 0xFE, 0x20, 0x60, 0x00, 0x00, 0x00,
-  0xFF, 0xC3, 0xFF, 0xFF, 0xF8, 0x00, 0x30, 0x00,
-  0x00, 0x00, 0xFF, 0x0F, 0xFF, 0xFF, 0xC0, 0x40,
-  0x38, 0x00, 0x00, 0x00, 0xFE, 0x47, 0xFF, 0xFF,
-  0x81, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xFC, 0x23,
-  0xFF, 0xFF, 0x90, 0x00, 0x1E, 0x00, 0x00, 0x00,
-  0x78, 0x11, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0x80,
-  0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00,
-  0x07, 0xC0, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF,
-  0xC0, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x04,
-  0x7F, 0xFF, 0x80, 0x00, 0x03, 0xC0, 0x00, 0x10,
-  0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x01, 0x80,
-  0x00, 0x30, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00,
-  0x00, 0x00, 0x00, 0x70, 0x00, 0x01, 0x4F, 0xFF,
-  0x80, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00,
-  0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x80, 0x03, 0xF0,
-  0x00, 0x00, 0x8F, 0xFF, 0x80, 0x00, 0x00, 0x40,
-  0x0F, 0xF0, 0x00, 0x04, 0x1F, 0xFF, 0x80, 0x00,
-  0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x10, 0x1F, 0xFF,
-  0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x40,
-  0xFF, 0xFF, 0x98, 0x00, 0x00, 0xFF, 0xFF, 0xF0,
-  0x00, 0x83, 0xFF, 0xFF, 0x81, 0xE0, 0x01, 0xFF,
-  0xFF, 0xF8, 0x02, 0x07, 0xFF, 0xFF, 0x80, 0x3F,
-  0x07, 0xE0, 0x00, 0x1C, 0x0C, 0x1F, 0xFF, 0xFF,
-  0xF8, 0x03, 0xFF, 0x80, 0x00, 0x1F, 0x78, 0x1F,
-  0xFF, 0xFF, 0xFF, 0x80, 0x7F, 0x00, 0x07, 0x0F,
-  0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0x0C, 0x07,
-  0xFF, 0x83, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0x00, 0x1F, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xcf, 0xf3, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xbf, 0xfc, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfd, 0xff, 0xf3, 0xdf, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfd, 0xff, 0xf7, 0xef, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x9f, 0x87, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x0f, 0x03, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x67, 0x33, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xe7, 0x79, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xf7, 0x79, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xff, 0xf9, 0xf7, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x60, 0x3b, 0xf7, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x89, 0x07, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x00, 0x03, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x00, 0x0d, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x80, 0x33, 0xfd, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xc0, 0xc3, 0xfd, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xff, 0x0d, 0xdd, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x40, 0x31, 0xee, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf7, 0x20, 0xc1, 0xee, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf7, 0x1f, 0x00, 0xff, 0x7f, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x7f, 0xbf, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xee, 0x00, 0x00, 0x7f, 0xbf, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xde, 0x00, 0x00, 0x7f, 0xdf, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xbc, 0x00, 0x00, 0x3f, 0xef, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x3f, 0xf7, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x1f, 0xf7, 0xff, 0xff,
+    0xff, 0xff, 0xfe, 0xff, 0x1c, 0x07, 0xdf, 0xfb, 0xff, 0xff,
+    0xff, 0xff, 0xfd, 0xfc, 0x08, 0x0f, 0xef, 0xfd, 0xff, 0xff,
+    0xff, 0xff, 0xfd, 0xf8, 0x00, 0x01, 0xef, 0xfd, 0xff, 0xff,
+    0xff, 0xff, 0xfb, 0xf0, 0x00, 0x00, 0x7f, 0xfe, 0xff, 0xff,
+    0xff, 0xff, 0xfb, 0xe0, 0x00, 0x00, 0x1f, 0xfe, 0xff, 0xff,
+    0xff, 0xff, 0xf7, 0xe0, 0x00, 0x00, 0x07, 0xbf, 0x7f, 0xff,
+    0xff, 0xff, 0xf7, 0xc0, 0x00, 0x00, 0x03, 0xbf, 0x7f, 0xff,
+    0xff, 0xff, 0xef, 0xc0, 0x00, 0x00, 0x03, 0xdf, 0xbf, 0xff,
+    0xff, 0xff, 0xef, 0x80, 0x00, 0x00, 0x03, 0xdf, 0xbf, 0xff,
+    0xff, 0xff, 0xdf, 0x80, 0x00, 0x00, 0x03, 0xdf, 0xbf, 0xff,
+    0xff, 0xff, 0xdf, 0x80, 0x00, 0x00, 0x01, 0xef, 0xdf, 0xff,
+    0xff, 0xff, 0xdf, 0x80, 0x00, 0x00, 0x01, 0xef, 0xdf, 0xff,
+    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
+    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
+    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
+    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
+    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x03, 0x03, 0xdf, 0xff,
+    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x02, 0xfd, 0xdf, 0xff,
+    0xff, 0xff, 0xa3, 0x80, 0x00, 0x00, 0x1f, 0xff, 0xdf, 0xff,
+    0xff, 0xff, 0xc1, 0xc0, 0x00, 0x00, 0x11, 0xff, 0x3f, 0xff,
+    0xff, 0xff, 0x80, 0xe0, 0x00, 0x00, 0x21, 0xfe, 0x3f, 0xff,
+    0xff, 0xff, 0x00, 0x70, 0x00, 0x00, 0x21, 0xfc, 0x3f, 0xff,
+    0xff, 0xfe, 0x00, 0x3c, 0x00, 0x00, 0x20, 0xf8, 0x3f, 0xff,
+    0xff, 0xf0, 0x00, 0x3e, 0x00, 0x00, 0x20, 0x00, 0x3f, 0xff,
+    0xff, 0xc0, 0x00, 0x1f, 0x00, 0x00, 0x20, 0x00, 0x3f, 0xff,
+    0xff, 0xc0, 0x00, 0x1f, 0x80, 0x00, 0x20, 0x00, 0x1f, 0xff,
+    0xff, 0xc0, 0x00, 0x0f, 0x80, 0x00, 0x20, 0x00, 0x07, 0xff,
+    0xff, 0xc0, 0x00, 0x07, 0x80, 0x00, 0x20, 0x00, 0x03, 0xff,
+    0xff, 0xc0, 0x00, 0x07, 0x80, 0x00, 0x60, 0x00, 0x01, 0xff,
+    0xff, 0xc0, 0x00, 0x02, 0x00, 0x00, 0xe0, 0x00, 0x01, 0xff,
+    0xff, 0xc0, 0x00, 0x01, 0x00, 0x01, 0xe0, 0x00, 0x01, 0xff,
+    0xff, 0xc0, 0x00, 0x00, 0x80, 0x07, 0xe0, 0x00, 0x03, 0xff,
+    0xff, 0xc0, 0x00, 0x00, 0x80, 0x3f, 0xe0, 0x00, 0x0f, 0xff,
+    0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x1f, 0xff,
+    0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x7f, 0xff,
+    0xff, 0xe0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0xff, 0xff,
+    0xff, 0xfc, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x03, 0xff, 0xff,
+    0xff, 0xff, 0xc0, 0x00, 0x70, 0x00, 0xc0, 0x07, 0xff, 0xff,
+    0xff, 0xff, 0xfc, 0x00, 0x8f, 0xff, 0x20, 0x0f, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 };
 
-#endif
+#endif /* !__HAVE_ARCH_LINUX_LOGOBW */
 
-#ifdef INCLUDE_LINUX_LOGO16
+#ifndef __HAVE_ARCH_LINUX_LOGO16
 
-unsigned char linux_logo16_red[] __initdata = {
-    0x00, 0x90, 0xb0, 0x9c, 0xf7, 0x35, 0x83, 0xa5,
-    0x65, 0x8f, 0x98, 0xc9, 0xdb, 0xe1, 0xe7, 0xf8
+unsigned char linux_logo16[] __initdata = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x88, 0x88, 0x88, 0x80, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x88, 0x80, 0x00, 0x00, 0x08, 0x88, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80,
+    0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x08, 0x70, 0x00, 0x00, 0x00, 0x77, 0x70, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x87, 0x77, 0x00, 0x00, 0x07, 0xff, 0xf7, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+    0x77, 0xff, 0x00, 0x00, 0x7f, 0x77, 0xf7, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+    0x70, 0x0f, 0x80, 0x00, 0xf7, 0x08, 0x7f, 0x70,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+    0x80, 0x07, 0x80, 0x00, 0xf8, 0x00, 0x8f, 0x70,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+    0x70, 0x07, 0x88, 0x88, 0xf8, 0x00, 0x8f, 0x70,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0xf0, 0x06, 0xe6, 0xe6, 0xe6, 0x00, 0x8f, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x77, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x77, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x06, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x60,
+    0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x60,
+    0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66, 0x66, 0x80,
+    0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80,
+    0x86, 0xe6, 0xe6, 0xe6, 0x66, 0x66, 0x66, 0x80,
+    0x08, 0x78, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80,
+    0x86, 0x66, 0x66, 0x66, 0x66, 0x66, 0x77, 0x70,
+    0x00, 0x77, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x87, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, 0x78,
+    0x00, 0x88, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x87, 0x76, 0x66, 0x66, 0x77, 0x77, 0xff, 0xf7,
+    0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08,
+    0xff, 0x77, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff,
+    0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07,
+    0xff, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff,
+    0x70, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x8f,
+    0xff, 0xf7, 0x77, 0x77, 0xff, 0xff, 0xff, 0xff,
+    0xf0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x7f,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf8, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x87, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x77,
+    0xff, 0xf7, 0x77, 0xff, 0xff, 0xff, 0x77, 0x77,
+    0x77, 0x78, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0x7f,
+    0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x77,
+    0x77, 0x78, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x7f, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x77, 0x00, 0x08, 0x80, 0x00, 0x00, 0x80,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x80, 0x80, 0x08, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x77, 0x80, 0x00, 0x08, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x08, 0x00, 0x80, 0x07, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0x78, 0x00, 0x08, 0x80, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x08, 0x08, 0x00, 0x8f, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xf7, 0x08, 0x80, 0x80, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x08, 0x08, 0x08, 0x7f, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xf7, 0x08, 0x80, 0x80, 0x00, 0x00,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x08, 0x07, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x80, 0x00, 0x08, 0x00, 0x00,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x80, 0x0f, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x70, 0x00, 0x08, 0x00, 0x00,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x08, 0x00, 0x80, 0x8f, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x70, 0x00, 0x08, 0x00, 0x00,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x08, 0x08, 0x00, 0x7f, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x70, 0x00, 0x08, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x80, 0x08, 0x00, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x08, 0x00, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x08, 0x08, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x08, 0x08, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x88, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x08, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf0, 0x88, 0x88, 0x80, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x06, 0xe6, 0x00, 0x8f, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x08, 0x80,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x6e, 0x6e, 0x60, 0x08, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x88,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x06, 0xe6, 0xe6, 0xe6, 0x00, 0x8f, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xfe, 0x6e, 0x60, 0x00, 0x00, 0x00, 0x00,
+    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x60, 0x08, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xf6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x06,
+    0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe0, 0x00, 0x8f, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xfe, 0x6e, 0x60, 0x00, 0x00, 0x00, 0x0e,
+    0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x00, 0x08, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x76, 0xe6, 0xe6, 0x00, 0x00, 0x00, 0xe6,
+    0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe0, 0x00, 0x8f,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x7e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x60, 0x00, 0x08,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x76, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00,
+    0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x7e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x60, 0x00,
+    0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x76, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe0, 0x00,
+    0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x8e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x88,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0x78, 0x86, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xef,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7,
+    0x80, 0x06, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78,
+    0x00, 0x06, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x80,
+    0x00, 0x06, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x0e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66,
+    0x67, 0xff, 0xff, 0xff, 0xff, 0x78, 0x80, 0x00,
+    0x00, 0x86, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x06, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x86, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0x66, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x0e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66,
+    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x86, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x86, 0x6e, 0x6e, 0x6e, 0x6e, 0x66, 0x66,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66,
+    0x66, 0x66, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66,
+    0x60, 0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0x80,
+    0x00, 0x06, 0x66, 0xe6, 0xe6, 0xe6, 0x66, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x66, 0x66, 0x66, 0x66, 0xe6, 0xe6, 0x66,
+    0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+    0x88, 0x86, 0x66, 0x6e, 0x6e, 0x66, 0x60, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x06, 0x66, 0x66, 0x66, 0x66,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x06, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x06, 0x66, 0x66, 0x60,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x66, 0x66, 0x66, 0x60, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 };
 
-unsigned char linux_logo16_green[] __initdata = {
-    0x00, 0x90, 0xb0, 0x9c, 0xf7, 0x2e, 0x83, 0xa5,
-    0x65, 0x6e, 0x98, 0x89, 0xbf, 0xac, 0xda, 0xf8
-};
+#endif /* !__HAVE_ARCH_LINUX_LOGO16 */
 
-unsigned char linux_logo16_blue[] __initdata = {
-    0x00, 0x90, 0xaf, 0x9c, 0xf7, 0x2b, 0x82, 0xa5,
-    0x65, 0x41, 0x97, 0x1e, 0x60, 0x29, 0xa5, 0xf8
-};
+#else /* !INCLUDE_LINUX_LOGO_DATA */
 
-unsigned char linux_logo16[] __initdata = {
-    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa1, 0x11, 0x11,
-    0x61, 0x16, 0x66, 0x66, 0x11, 0x11, 0x11, 0x11,
-    0x11, 0x11, 0x1a, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-    0xaa, 0xaa, 0xaa, 0xaa, 0x33, 0xa8, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x87, 0x77, 0x77, 0x77, 0x77,
-    0x77, 0x77, 0x73, 0x33, 0x33, 0x3a, 0xaa, 0xaa,
-    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-    0xaa, 0xaa, 0xa3, 0x33, 0x33, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x77,
-    0x77, 0x27, 0x77, 0x77, 0x77, 0x33, 0x3a, 0xaa,
-    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-    0xaa, 0xa3, 0x33, 0x33, 0x30, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x55, 0x50, 0x08, 0x33, 0x77, 0x77,
-    0x77, 0x72, 0x72, 0x27, 0x77, 0x77, 0x33, 0x33,
-    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-    0xa3, 0x33, 0x33, 0x77, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x58, 0x85, 0x00, 0x11, 0x11, 0xaa,
-    0xa3, 0x37, 0x77, 0x72, 0x22, 0x22, 0x77, 0x73,
-    0x33, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa3,
-    0x33, 0x37, 0x77, 0x33, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x56, 0x85, 0x00, 0x06, 0x66, 0x11,
-    0x11, 0x1a, 0xa3, 0x37, 0x77, 0x72, 0x22, 0x77,
-    0x73, 0x33, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x33,
-    0x33, 0x33, 0x33, 0x30, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x55, 0x00, 0x00, 0x06, 0x66, 0x66,
-    0x66, 0x66, 0x11, 0x1a, 0xa3, 0x77, 0x72, 0x22,
-    0x77, 0x73, 0x3a, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x33, 0x33,
-    0x33, 0x33, 0x33, 0xa0, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,
-    0x66, 0x66, 0x66, 0x66, 0x11, 0xa3, 0x77, 0x22,
-    0x22, 0x77, 0x33, 0x33, 0xaa, 0xaa, 0xaa, 0xaa,
-    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x33, 0x33, 0x33,
-    0x33, 0x3a, 0xa1, 0x10, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x33,
-    0xaa, 0x11, 0x16, 0x66, 0x66, 0x61, 0x1a, 0x37,
-    0x22, 0x22, 0x77, 0x33, 0x3a, 0xaa, 0xaa, 0xaa,
-    0xaa, 0xaa, 0xaa, 0xaa, 0xa3, 0x33, 0x33, 0x33,
-    0x3a, 0xa1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x22,
-    0x22, 0x77, 0x3a, 0x11, 0x66, 0x66, 0x66, 0x1a,
-    0x37, 0x22, 0x22, 0x77, 0x33, 0x3a, 0xaa, 0xaa,
-    0xaa, 0xaa, 0xaa, 0xaa, 0x33, 0x33, 0x33, 0x3a,
-    0xa1, 0x11, 0x11, 0x10, 0x00, 0x00, 0x50, 0x00,
-    0x00, 0x05, 0x80, 0x50, 0x00, 0x00, 0x07, 0x72,
-    0x22, 0x22, 0x22, 0x73, 0xa1, 0x66, 0x66, 0x61,
-    0x1a, 0x77, 0x22, 0x27, 0x73, 0x33, 0xaa, 0xaa,
-    0xaa, 0xaa, 0xaa, 0xaa, 0x33, 0x33, 0x3a, 0xaa,
-    0x11, 0x11, 0x1a, 0xa0, 0x08, 0x71, 0x05, 0x00,
-    0x00, 0x12, 0x22, 0x50, 0x00, 0x00, 0x07, 0x77,
-    0x77, 0x72, 0x22, 0x22, 0x27, 0x31, 0x16, 0x66,
-    0x61, 0x13, 0x77, 0x22, 0x77, 0x33, 0x3a, 0xaa,
-    0xaa, 0xaa, 0xaa, 0xa3, 0x33, 0x33, 0xaa, 0xa1,
-    0x11, 0x1a, 0x33, 0x70, 0x07, 0x2e, 0x70, 0x00,
-    0x01, 0x44, 0x42, 0x60, 0x00, 0x00, 0x02, 0x22,
-    0x22, 0x22, 0x22, 0x22, 0x22, 0x27, 0x31, 0x66,
-    0x66, 0x61, 0xa3, 0x72, 0x22, 0x77, 0x33, 0xaa,
-    0xaa, 0xaa, 0xa3, 0x33, 0x33, 0xaa, 0xaa, 0x11,
-    0x1a, 0x33, 0x77, 0x30, 0x04, 0x82, 0x40, 0x00,
-    0x54, 0x48, 0x54, 0x40, 0x00, 0x00, 0x01, 0xaa,
-    0x32, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x31,
-    0x66, 0x66, 0x11, 0x37, 0x22, 0x27, 0x73, 0x3a,
-    0xaa, 0xaa, 0xa3, 0x33, 0x3a, 0xaa, 0xaa, 0xaa,
-    0xa3, 0x77, 0xaa, 0x10, 0x50, 0x08, 0x46, 0x05,
-    0x54, 0x80, 0x50, 0x42, 0x00, 0x00, 0x08, 0x66,
-    0x66, 0x1a, 0x32, 0x22, 0x22, 0x22, 0x22, 0x27,
-    0x31, 0x66, 0x66, 0x13, 0x72, 0x22, 0x77, 0x33,
-    0xaa, 0xaa, 0xaa, 0x33, 0xaa, 0xa1, 0xaa, 0xa3,
-    0x37, 0xa1, 0x1a, 0x30, 0x50, 0x06, 0x26, 0x00,
-    0x54, 0x00, 0x00, 0x44, 0x00, 0x00, 0x08, 0xe2,
-    0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x22, 0x22,
-    0x27, 0xa6, 0x66, 0x61, 0xa7, 0x72, 0x27, 0x73,
-    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x33,
-    0x31, 0x11, 0x37, 0x70, 0x02, 0x00, 0xab, 0xbb,
-    0xb6, 0x00, 0x00, 0xf4, 0x00, 0x00, 0xee, 0xee,
-    0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x22,
-    0x22, 0x23, 0x16, 0x66, 0x1a, 0x37, 0x22, 0x77,
-    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa3, 0x3a,
-    0x11, 0xa7, 0x33, 0x10, 0x04, 0x09, 0xbd, 0xdd,
-    0xbd, 0xd0, 0x04, 0x45, 0x00, 0x0e, 0xee, 0xee,
-    0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x22,
-    0x22, 0x22, 0x71, 0x66, 0x66, 0x13, 0x72, 0x27,
-    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x33, 0x11,
-    0xa3, 0x73, 0xa1, 0x60, 0x08, 0xbd, 0xdd, 0xdd,
-    0xdd, 0xdd, 0xdb, 0x90, 0x00, 0x02, 0xec, 0xee,
-    0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xce, 0x22,
-    0x22, 0x22, 0x27, 0xa6, 0x66, 0x61, 0x37, 0x27,
-    0x1a, 0xaa, 0xaa, 0xaa, 0xaa, 0xa3, 0xa1, 0x1a,
-    0x33, 0xa1, 0x16, 0x60, 0x0b, 0xbd, 0xdd, 0xdd,
-    0xcd, 0xdd, 0xdd, 0xd9, 0x00, 0x00, 0xec, 0xcc,
-    0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0xa2,
-    0x22, 0x22, 0x22, 0x7a, 0x66, 0x66, 0x13, 0x77,
-    0x1a, 0xaa, 0xaa, 0xaa, 0xaa, 0x3a, 0x11, 0x33,
-    0xaa, 0x11, 0x66, 0x60, 0x9b, 0xdd, 0xdd, 0xdd,
-    0xcd, 0xdd, 0xdb, 0xb9, 0x00, 0x00, 0xec, 0xcc,
-    0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xee, 0x61,
-    0x72, 0x22, 0x22, 0x22, 0xa1, 0x66, 0x61, 0x37,
-    0x1a, 0xaa, 0xaa, 0xaa, 0xa3, 0xa1, 0x13, 0x3a,
-    0x11, 0x11, 0x11, 0x10, 0x5b, 0xdd, 0xdd, 0xdc,
-    0xdd, 0xdd, 0xbd, 0xd9, 0x00, 0x00, 0xec, 0xcc,
-    0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xee, 0x86,
-    0x17, 0x22, 0x22, 0x22, 0x23, 0x16, 0x66, 0xaa,
-    0xaa, 0xa3, 0x3a, 0xaa, 0xaa, 0x1a, 0x3a, 0xa1,
-    0x11, 0x11, 0x1a, 0x70, 0x05, 0xbd, 0xdd, 0xdd,
-    0xdb, 0x5b, 0xdd, 0xb0, 0x00, 0x60, 0x2e, 0xcc,
-    0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xe6, 0x88,
-    0x66, 0x32, 0x22, 0x22, 0x22, 0x36, 0x66, 0x11,
-    0x33, 0x33, 0x3a, 0xaa, 0x11, 0xaa, 0xaa, 0xa1,
-    0x11, 0x1a, 0x3a, 0x60, 0x02, 0x99, 0xbb, 0xb9,
-    0x9b, 0xbb, 0xbc, 0x22, 0x00, 0x86, 0x5e, 0xcc,
-    0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xe1, 0x68,
-    0x86, 0x63, 0x22, 0x22, 0x22, 0x2a, 0x66, 0x66,
-    0x33, 0x33, 0xaa, 0xaa, 0x1a, 0xaa, 0xaa, 0x11,
-    0x1a, 0xa7, 0x68, 0x80, 0x02, 0x2b, 0xbd, 0xbb,
-    0xbb, 0xb9, 0x22, 0x22, 0x00, 0x06, 0x6e, 0xcc,
-    0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc7, 0xa6,
-    0x88, 0x86, 0x32, 0x22, 0x22, 0x27, 0xa6, 0x66,
-    0x33, 0x3a, 0xaa, 0xa1, 0xaa, 0xaa, 0xa1, 0x11,
-    0xa3, 0xa6, 0x88, 0x80, 0x02, 0x22, 0x9b, 0xbb,
-    0xbb, 0x22, 0x24, 0xf4, 0x60, 0x00, 0x0c, 0xcc,
-    0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc2, 0x21,
-    0x68, 0x88, 0x63, 0x22, 0x22, 0x22, 0x71, 0x66,
-    0x33, 0x3a, 0x11, 0x11, 0xaa, 0xaa, 0x11, 0xaa,
-    0x71, 0x88, 0x88, 0x00, 0x02, 0xe2, 0x26, 0x99,
-    0x22, 0x22, 0x4f, 0xf4, 0x40, 0x00, 0x0c, 0xcc,
-    0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x22, 0x22,
-    0x16, 0x88, 0x86, 0xa2, 0x22, 0x22, 0x27, 0x11,
-    0x33, 0xa1, 0x11, 0x11, 0xaa, 0x31, 0x1a, 0xa3,
-    0x68, 0x88, 0x81, 0x00, 0x54, 0x42, 0x22, 0x22,
-    0x22, 0x44, 0xff, 0xff, 0x48, 0x00, 0x00, 0x99,
-    0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x99, 0x22, 0x22,
-    0x21, 0x88, 0x88, 0x6a, 0x22, 0x22, 0x22, 0x31,
-    0x3a, 0xa1, 0x11, 0x1a, 0xa3, 0x11, 0x33, 0x36,
-    0x88, 0x86, 0x30, 0x00, 0x4f, 0x44, 0x22, 0x22,
-    0x24, 0xff, 0xff, 0xff, 0x44, 0x00, 0x00, 0x99,
-    0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x95, 0x22, 0x72,
-    0x22, 0x18, 0x88, 0x86, 0x32, 0x22, 0x22, 0x27,
-    0xaa, 0x11, 0x11, 0x1a, 0x31, 0x13, 0x33, 0x68,
-    0x88, 0x6a, 0x00, 0x02, 0x4f, 0x4f, 0x42, 0x24,
-    0x4f, 0xff, 0xff, 0xff, 0xf4, 0x50, 0x00, 0x99,
-    0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x99, 0x22, 0x73,
-    0x72, 0x26, 0x88, 0x88, 0x63, 0x22, 0x22, 0x22,
-    0x11, 0x11, 0x11, 0xa3, 0xa1, 0x73, 0xa6, 0x88,
-    0x81, 0xa5, 0x00, 0x04, 0x4f, 0x4f, 0x44, 0x4f,
-    0xff, 0xff, 0xff, 0xff, 0xf4, 0x40, 0x00, 0x99,
-    0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x99, 0x12, 0x27,
-    0xaa, 0x22, 0x68, 0x55, 0x86, 0x72, 0x22, 0x22,
-    0x11, 0x11, 0x1a, 0x33, 0x13, 0x3a, 0x18, 0x88,
-    0x1a, 0x10, 0x00, 0x44, 0x4f, 0x4f, 0xff, 0x4f,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x99,
-    0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x99, 0x61, 0x22,
-    0x3a, 0xa2, 0x26, 0x85, 0x58, 0x67, 0x22, 0x22,
-    0x61, 0x61, 0x1a, 0x7a, 0x37, 0x31, 0x88, 0x81,
-    0x11, 0x00, 0x05, 0xe4, 0x44, 0xff, 0xff, 0xff,
-    0x4f, 0xf4, 0x44, 0xff, 0xff, 0xf5, 0x00, 0x99,
-    0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x99, 0x88, 0x12,
-    0x2a, 0xaa, 0x72, 0x68, 0x55, 0x81, 0x22, 0x22,
-    0x66, 0x61, 0xa3, 0x33, 0x73, 0x16, 0x88, 0x11,
-    0x10, 0x00, 0x08, 0x74, 0x44, 0x4f, 0x44, 0x44,
-    0xf4, 0xf4, 0x44, 0x44, 0xe2, 0x44, 0x00, 0x99,
-    0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x99, 0x88, 0x81,
-    0x22, 0xaa, 0xa7, 0x26, 0x85, 0x88, 0x12, 0x22,
-    0x66, 0x61, 0x37, 0xa7, 0x3a, 0x66, 0x66, 0x11,
-    0x80, 0x00, 0x0a, 0x72, 0x44, 0x4f, 0x44, 0x4f,
-    0xff, 0x44, 0x44, 0x22, 0x22, 0x24, 0x00, 0x99,
-    0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x99, 0x85, 0x88,
-    0x12, 0x2a, 0xaa, 0x22, 0x68, 0x58, 0x63, 0x22,
-    0x66, 0x1a, 0x73, 0x77, 0x31, 0x66, 0x61, 0x11,
-    0x00, 0x00, 0x07, 0x44, 0xff, 0x4f, 0xf4, 0x4f,
-    0xff, 0x4f, 0x44, 0xf4, 0x42, 0x22, 0x40, 0x9b,
-    0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb9, 0x85, 0x55,
-    0x81, 0x27, 0xaa, 0xa2, 0x78, 0x88, 0x86, 0x72,
-    0x66, 0x13, 0x77, 0x73, 0x11, 0x66, 0x61, 0x76,
-    0x00, 0x50, 0x84, 0xf4, 0xff, 0x4f, 0xf4, 0xff,
-    0xff, 0x4f, 0x44, 0xff, 0x4f, 0x42, 0x40, 0x9b,
-    0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb9, 0x68, 0x55,
-    0x58, 0x12, 0x3a, 0xaa, 0x23, 0x88, 0x88, 0xa7,
-    0x66, 0xa7, 0x77, 0x7a, 0x16, 0x66, 0x1a, 0x15,
-    0x05, 0x00, 0x4f, 0xf4, 0xff, 0x4f, 0xf4, 0xff,
-    0xff, 0x4f, 0x44, 0xff, 0x4f, 0x44, 0x24, 0x9b,
-    0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb9, 0x26, 0x55,
-    0x55, 0x81, 0x23, 0xaa, 0x32, 0x18, 0x88, 0x6a,
-    0x61, 0x37, 0x77, 0x31, 0x66, 0x66, 0x17, 0x60,
-    0x05, 0x08, 0x4f, 0xf4, 0xff, 0x4f, 0xf4, 0xff,
-    0xff, 0x4f, 0x44, 0xff, 0x4f, 0x4f, 0x4e, 0x99,
-    0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x99, 0xa2, 0x65,
-    0x55, 0x58, 0xa2, 0x7a, 0xa2, 0x26, 0x88, 0x61,
-    0x61, 0x32, 0x27, 0xa1, 0x66, 0x61, 0x31, 0x60,
-    0x00, 0x04, 0x4f, 0xf4, 0xff, 0x44, 0x44, 0xff,
-    0xff, 0x4f, 0x44, 0xff, 0x4f, 0x44, 0xf4, 0x99,
-    0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x9b, 0xaa, 0x26,
-    0x55, 0x55, 0x87, 0x27, 0x33, 0x27, 0x68, 0x61,
-    0x1a, 0x72, 0x27, 0xa6, 0x66, 0x6a, 0x71, 0x00,
-    0x80, 0x84, 0xff, 0xf4, 0xff, 0x44, 0x44, 0xff,
-    0xff, 0x4f, 0x44, 0xff, 0x4f, 0x44, 0xf4, 0x99,
-    0x9b, 0x9b, 0x99, 0xb9, 0xb9, 0x99, 0xaa, 0xa2,
-    0x85, 0x55, 0x56, 0x22, 0x27, 0x22, 0x36, 0x66,
-    0x13, 0x22, 0x23, 0x16, 0x86, 0x63, 0x73, 0x00,
-    0x00, 0x44, 0xf4, 0xf4, 0xff, 0x44, 0x44, 0xff,
-    0xff, 0x4f, 0x44, 0xff, 0x4f, 0x4f, 0x4f, 0x99,
-    0x9b, 0x99, 0x99, 0x99, 0xb9, 0x99, 0xaa, 0xaa,
-    0x28, 0x55, 0x58, 0x12, 0x22, 0x22, 0x21, 0x11,
-    0xa3, 0x27, 0x7a, 0x66, 0x86, 0x17, 0x75, 0x05,
-    0x05, 0xff, 0xf4, 0xf4, 0xff, 0x44, 0x44, 0xff,
-    0xff, 0x4f, 0x44, 0x4f, 0x4f, 0x44, 0x4f, 0x99,
-    0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x3a, 0xaa,
-    0xa2, 0x85, 0x58, 0x67, 0x72, 0x22, 0x27, 0xa1,
-    0x37, 0x27, 0x7a, 0x68, 0x86, 0xa2, 0x70, 0x00,
-    0x02, 0xff, 0xf4, 0xf4, 0xff, 0x44, 0x44, 0x4f,
-    0xff, 0x4f, 0x44, 0xf4, 0xf4, 0xf4, 0xf4, 0x99,
-    0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x23, 0xaa,
-    0xa7, 0x78, 0x88, 0x81, 0x77, 0x22, 0x27, 0x3a,
-    0x72, 0x73, 0x71, 0x68, 0x66, 0x32, 0x50, 0x00,
-    0x04, 0x4f, 0xf4, 0xf4, 0xff, 0x44, 0x44, 0x4f,
-    0xff, 0x4f, 0x44, 0xf4, 0xf4, 0xf4, 0x44, 0x95,
-    0x99, 0x99, 0x99, 0x99, 0x99, 0x55, 0x12, 0x3a,
-    0xaa, 0x21, 0x88, 0x81, 0x77, 0x27, 0x73, 0x73,
-    0x72, 0x33, 0x36, 0x86, 0x61, 0x72, 0x00, 0x00,
-    0x04, 0x44, 0xf4, 0xf4, 0xf4, 0x44, 0x44, 0x4f,
-    0xff, 0x4f, 0x44, 0xff, 0x4f, 0x4f, 0x44, 0x55,
-    0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x8a, 0x27,
-    0xaa, 0x77, 0x68, 0x61, 0x23, 0x71, 0x11, 0x3a,
-    0x27, 0xa3, 0x36, 0x86, 0x61, 0x20, 0x00, 0x00,
-    0x04, 0xf4, 0xf4, 0xf4, 0xf4, 0x44, 0x44, 0x4f,
-    0xff, 0x4f, 0x44, 0xff, 0x4f, 0x4f, 0x41, 0x59,
-    0x99, 0x99, 0x99, 0x99, 0x99, 0x95, 0x58, 0x77,
-    0x27, 0x32, 0x36, 0x63, 0x23, 0x71, 0x66, 0x11,
-    0x27, 0x13, 0xa6, 0x86, 0x6a, 0x20, 0x00, 0x50,
-    0x04, 0x4f, 0x4f, 0x4f, 0x4f, 0x44, 0x44, 0x4f,
-    0xff, 0x4f, 0x44, 0xff, 0x4f, 0x4f, 0x41, 0x99,
-    0x9b, 0xbb, 0xbb, 0xbb, 0xb9, 0x99, 0x68, 0x13,
-    0x32, 0x22, 0x73, 0xa7, 0x2a, 0x31, 0x88, 0x66,
-    0x7a, 0x13, 0x18, 0x66, 0x63, 0x20, 0x00, 0x06,
-    0x0f, 0x4f, 0x4f, 0x4f, 0x4f, 0x44, 0x44, 0x4f,
-    0xff, 0x4f, 0x44, 0xff, 0x4f, 0x4f, 0x49, 0x95,
-    0xa9, 0xa9, 0x99, 0x97, 0x92, 0x99, 0x65, 0x6a,
-    0x17, 0x22, 0x23, 0x72, 0x27, 0xaa, 0x88, 0x88,
-    0xa1, 0x17, 0x68, 0x66, 0x67, 0x70, 0x00, 0x05,
-    0x0f, 0x4f, 0x4f, 0x4f, 0x4f, 0x44, 0x44, 0x4f,
-    0xff, 0x4f, 0x44, 0xff, 0xf4, 0xf4, 0x49, 0x9c,
-    0x2e, 0xee, 0xee, 0xee, 0xee, 0xa9, 0x65, 0x8a,
-    0x1a, 0xaa, 0x37, 0x72, 0x27, 0x37, 0x88, 0x88,
-    0x11, 0x17, 0x68, 0x66, 0x67, 0x10, 0x9d, 0xd0,
-    0x84, 0x44, 0xff, 0x4f, 0x4f, 0x44, 0xf4, 0x4f,
-    0xff, 0x4f, 0x44, 0xff, 0xf4, 0xf4, 0x4f, 0x69,
-    0xcc, 0xee, 0xee, 0xee, 0xec, 0x99, 0x88, 0x63,
-    0x61, 0x68, 0x61, 0x72, 0x22, 0x7a, 0x68, 0x88,
-    0x11, 0x17, 0x88, 0x66, 0x12, 0x1b, 0xdd, 0xdd,
-    0x02, 0x44, 0x4f, 0x4f, 0x4f, 0x44, 0x44, 0x4f,
-    0xff, 0x4f, 0x44, 0xff, 0xff, 0x4f, 0x4c, 0xc5,
-    0x0c, 0xc1, 0x11, 0x1c, 0xc0, 0x26, 0x66, 0x17,
-    0x66, 0x88, 0x88, 0x12, 0x22, 0x23, 0xa8, 0x88,
-    0x11, 0x13, 0x88, 0x66, 0x17, 0xbb, 0xdd, 0xdd,
-    0xd0, 0x8f, 0xff, 0xf4, 0xf4, 0x44, 0xf4, 0x4f,
-    0xff, 0x4f, 0x44, 0xf4, 0x4f, 0x44, 0xdd, 0xdd,
-    0x00, 0x00, 0x00, 0x05, 0x9d, 0x21, 0x66, 0x27,
-    0xa6, 0x65, 0x58, 0x67, 0x22, 0x27, 0x28, 0x88,
-    0x11, 0xaa, 0x86, 0x68, 0x1a, 0xbb, 0xdd, 0xdd,
-    0xdb, 0x05, 0xf4, 0xf4, 0xf4, 0xf4, 0x44, 0x4f,
-    0xff, 0x4f, 0x44, 0xf4, 0xf4, 0xf4, 0xdd, 0xdb,
-    0x00, 0x00, 0x00, 0x00, 0xdd, 0xda, 0x66, 0x22,
-    0x71, 0x15, 0x55, 0x81, 0x22, 0x22, 0x76, 0x88,
-    0x11, 0x31, 0x88, 0x88, 0xab, 0xbd, 0xdd, 0xdd,
-    0xdd, 0x00, 0x04, 0x44, 0xff, 0xff, 0x4f, 0x4f,
-    0xff, 0x4f, 0x44, 0xf4, 0xf4, 0x44, 0xdd, 0xdb,
-    0x00, 0x00, 0x00, 0x0b, 0xdd, 0xda, 0x11, 0x22,
-    0x23, 0x68, 0x55, 0x86, 0x22, 0x22, 0x7a, 0x88,
-    0x1a, 0x71, 0x88, 0x89, 0xbb, 0xdd, 0xdd, 0xdd,
-    0xdd, 0xd0, 0x00, 0x4f, 0x44, 0xff, 0x4f, 0x4f,
-    0xff, 0x4f, 0x44, 0xf4, 0xff, 0xe2, 0xdd, 0xdb,
-    0x90, 0x00, 0x05, 0xbd, 0xdd, 0xb8, 0x63, 0x22,
-    0x27, 0xa6, 0x55, 0x88, 0x77, 0x22, 0x22, 0x88,
-    0x1a, 0x28, 0xbd, 0xdb, 0xdd, 0xdd, 0xdd, 0xdd,
-    0xdd, 0xdb, 0x00, 0x07, 0x44, 0x4f, 0x4f, 0x4f,
-    0xff, 0x4f, 0x44, 0x4f, 0x4f, 0x22, 0xdd, 0xdb,
-    0xbb, 0x9b, 0xbb, 0xbd, 0xdd, 0xd5, 0x86, 0x22,
-    0x22, 0x77, 0x85, 0x88, 0x17, 0x22, 0x22, 0x88,
-    0xaa, 0x2b, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
-    0xdd, 0xdd, 0x00, 0x00, 0x54, 0x4f, 0x4f, 0x4f,
-    0xff, 0x4f, 0x44, 0xf4, 0x44, 0x22, 0xbd, 0xdd,
-    0xbb, 0xbb, 0xbb, 0xdd, 0xdd, 0xdd, 0x88, 0x72,
-    0x27, 0x22, 0x88, 0x88, 0x67, 0x72, 0x22, 0x18,
-    0x33, 0x2d, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
-    0xdd, 0xdd, 0xd0, 0x00, 0x05, 0x4f, 0x4f, 0x4f,
-    0xff, 0x4f, 0x44, 0x44, 0x4f, 0x22, 0xbd, 0xdd,
-    0xdb, 0xbb, 0xdd, 0xdd, 0xdd, 0xdd, 0x88, 0x17,
-    0x27, 0x72, 0x68, 0x88, 0x87, 0x32, 0x22, 0x36,
-    0x37, 0x2d, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
-    0xdd, 0xdd, 0xd5, 0x00, 0x00, 0x4f, 0x4f, 0x4f,
-    0xff, 0xf4, 0xf4, 0xf4, 0xf4, 0x22, 0xbb, 0xdd,
-    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xd8, 0x67,
-    0x72, 0x77, 0x38, 0x88, 0x83, 0x37, 0x22, 0x26,
-    0x72, 0x2b, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
-    0xdd, 0xdd, 0xdd, 0x00, 0x00, 0x4f, 0x4f, 0x4f,
-    0xff, 0xf4, 0xf4, 0xf4, 0x44, 0x25, 0xbb, 0xdd,
-    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xd3,
-    0x32, 0x73, 0x76, 0x88, 0x81, 0x33, 0x22, 0x2a,
-    0x22, 0x2b, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
-    0xdd, 0xdd, 0xdd, 0xb0, 0x54, 0x4f, 0x4f, 0x4f,
-    0xff, 0xf4, 0xf4, 0xff, 0x44, 0x00, 0xbb, 0xdd,
-    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
-    0xa7, 0x73, 0x26, 0x88, 0x86, 0x7a, 0x72, 0x27,
-    0x22, 0x2b, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
-    0xdd, 0xdd, 0xdd, 0xdb, 0x44, 0xff, 0x4f, 0x4f,
-    0xff, 0xf4, 0xf4, 0x44, 0x40, 0x05, 0xbb, 0xdd,
-    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
-    0x13, 0x23, 0x21, 0x68, 0x86, 0x17, 0x72, 0x22,
-    0x22, 0x2b, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
-    0xdd, 0xdd, 0xdd, 0xdb, 0x44, 0x4f, 0x4f, 0x4f,
-    0xff, 0xff, 0x44, 0x42, 0x00, 0x05, 0xbd, 0xdd,
-    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
-    0x87, 0x27, 0x27, 0x16, 0x66, 0x67, 0x22, 0x22,
-    0x72, 0x7b, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
-    0xdd, 0xdd, 0xdd, 0xdd, 0x94, 0x44, 0x44, 0x44,
-    0x44, 0x44, 0x44, 0x00, 0x00, 0x05, 0xbb, 0xdd,
-    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xb8,
-    0x86, 0x22, 0x22, 0x7a, 0x68, 0x81, 0x22, 0x22,
-    0x37, 0x7b, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
-    0xdd, 0xdd, 0xdd, 0xdb, 0xb5, 0x44, 0x44, 0x44,
-    0x44, 0x47, 0x00, 0x00, 0x00, 0x05, 0xbd, 0xdd,
-    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xd8, 0x68,
-    0x58, 0x72, 0x22, 0x27, 0x18, 0x86, 0x72, 0x22,
-    0x1a, 0xbb, 0xbd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
-    0xdd, 0xdd, 0xdd, 0xdb, 0xb5, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xbb, 0xdd,
-    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xb9, 0x18, 0x85,
-    0x58, 0x12, 0x22, 0x36, 0x18, 0x88, 0x32, 0x22,
-    0x61, 0x3b, 0xbb, 0xbb, 0xbd, 0xdd, 0xdd, 0xdd,
-    0xdd, 0xdd, 0xdd, 0xdb, 0xb9, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xbb, 0xdd,
-    0xdd, 0xdd, 0xdd, 0xdd, 0xb9, 0x7a, 0x68, 0x85,
-    0x88, 0x62, 0x27, 0x16, 0x18, 0x88, 0x12, 0x27,
-    0x86, 0x18, 0x9b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbd,
-    0xdd, 0xdd, 0xdd, 0xbb, 0xb5, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xbb, 0xbd,
-    0xdd, 0xdd, 0xdb, 0xbb, 0x87, 0x31, 0x68, 0x65,
-    0x88, 0x82, 0x23, 0x16, 0x18, 0x88, 0x12, 0x23,
-    0x88, 0x67, 0x27, 0xa8, 0x9b, 0xbb, 0xbb, 0xbb,
-    0xbd, 0xdd, 0xbb, 0xbb, 0x95, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x9b, 0xbb,
-    0xbb, 0xbb, 0xbb, 0x96, 0x87, 0x16, 0x68, 0x18,
-    0x88, 0x62, 0x31, 0x66, 0x18, 0x88, 0x62, 0x73,
-    0x88, 0x63, 0x27, 0x33, 0x65, 0x55, 0x99, 0x9b,
-    0xbb, 0xbb, 0xbb, 0x99, 0x55, 0x0a, 0xa1, 0x86,
-    0x81, 0x68, 0x88, 0x55, 0x58, 0x85, 0x9b, 0xbb,
-    0xbb, 0xbb, 0x95, 0x88, 0x83, 0x66, 0x66, 0x18,
-    0x66, 0x82, 0xa1, 0x66, 0x18, 0x88, 0x62, 0x33,
-    0x88, 0x81, 0x27, 0x7a, 0x18, 0x58, 0x86, 0x85,
-    0x99, 0x99, 0x99, 0x95, 0x53, 0x2a, 0xaa, 0x88,
-    0x67, 0x31, 0x68, 0x55, 0x58, 0x85, 0x59, 0xbb,
-    0xbb, 0xb9, 0x58, 0x68, 0x83, 0x66, 0x61, 0x16,
-    0x66, 0x62, 0x16, 0x66, 0x68, 0x88, 0x62, 0xaa,
-    0x88, 0x86, 0x27, 0x77, 0x78, 0x55, 0x88, 0x22,
-    0x25, 0x55, 0x95, 0x55, 0x6a, 0xa2, 0x2a, 0x88,
-    0x62, 0x27, 0x37, 0x38, 0x88, 0x87, 0x55, 0x59,
-    0x95, 0x58, 0x16, 0x88, 0x8a, 0x66, 0x63, 0x68,
-    0x86, 0x67, 0x66, 0x66, 0x68, 0x88, 0x12, 0x11,
-    0x88, 0x88, 0x72, 0x77, 0x78, 0x85, 0x58, 0x17,
-    0x23, 0x32, 0x55, 0x55, 0x81, 0x13, 0x73, 0x66,
-    0x62, 0x7a, 0xaa, 0x38, 0x88, 0x58, 0x27, 0x55,
-    0x58, 0x32, 0x38, 0x88, 0x81, 0x66, 0xa2, 0x88,
-    0x86, 0x61, 0x66, 0x61, 0x66, 0x68, 0x13, 0x11,
-    0x88, 0x88, 0x12, 0x22, 0x71, 0x85, 0x58, 0x62,
-    0x23, 0xa2, 0x68, 0x88, 0x81, 0x66, 0x88, 0x88,
-    0x63, 0x2a, 0xaa, 0x28, 0x88, 0x55, 0x86, 0x61,
-    0x66, 0x66, 0x68, 0x88, 0x66, 0x66, 0x77, 0x88,
-    0x68, 0x16, 0x66, 0x62, 0x66, 0x68, 0xa1, 0x61,
-    0x88, 0x88, 0x62, 0x22, 0x22, 0x85, 0x55, 0x83,
-    0x72, 0x37, 0xa8, 0x88, 0x61, 0x66, 0x85, 0x55,
-    0x86, 0x23, 0xaa, 0x71, 0x88, 0x85, 0x88, 0x66,
-    0x88, 0x86, 0x88, 0x88, 0x16, 0x61, 0x21, 0x88,
-    0x66, 0xa6, 0x86, 0x17, 0x66, 0x66, 0x31, 0x61,
-    0x88, 0x88, 0x87, 0x72, 0x22, 0x68, 0x55, 0x86,
-    0x77, 0x77, 0x36, 0x88, 0x13, 0x68, 0x85, 0x55,
-    0x58, 0x12, 0x73, 0x72, 0x76, 0x88, 0x88, 0x68,
-    0x88, 0x88, 0x88, 0x66, 0x36, 0x63, 0x26, 0x86,
-    0x86, 0x36, 0x86, 0x11, 0x66, 0x66, 0x76, 0x61,
-    0x88, 0x88, 0x81, 0x22, 0x22, 0x38, 0x85, 0x58,
-    0x37, 0x22, 0x21, 0x68, 0xa2, 0x31, 0x68, 0x55,
-    0x55, 0x81, 0x22, 0x22, 0xa8, 0x88, 0x88, 0x68,
-    0x86, 0x88, 0x68, 0x81, 0x36, 0x17, 0x21, 0x68,
-    0x86, 0x16, 0x66, 0x26, 0x66, 0x61, 0x36, 0x66,
-    0x68, 0x88, 0x86, 0x27, 0x22, 0x28, 0x88, 0x88,
-    0x17, 0x72, 0x2a, 0x66, 0xa2, 0x22, 0x36, 0x55,
-    0x55, 0x58, 0x37, 0x3a, 0x16, 0x66, 0x66, 0x66,
-    0x66, 0x18, 0x88, 0x67, 0x16, 0x12, 0x71, 0x68,
-    0x81, 0x68, 0x61, 0x76, 0x66, 0x6a, 0x16, 0x66,
-    0x88, 0x88, 0x86, 0x77, 0x22, 0x26, 0x88, 0x88,
-    0x13, 0x37, 0x71, 0x66, 0xa2, 0x33, 0x2a, 0x85,
-    0x55, 0x55, 0x17, 0x73, 0x16, 0x66, 0x66, 0x68,
-    0x63, 0x88, 0x88, 0xa2, 0x66, 0xa2, 0xa6, 0x88,
-    0x61, 0x68, 0x6a, 0x76, 0x66, 0x6a, 0x66, 0x6a
-};
+/* prototypes only */
+extern unsigned char linux_logo_red[];
+extern unsigned char linux_logo_green[];
+extern unsigned char linux_logo_blue[];
+extern unsigned char linux_logo[];
+extern unsigned char linux_logo_bw[];
+extern unsigned char linux_logo16[];
+
+#endif /* !INCLUDE_LINUX_LOGO_DATA */
 
-#endif
diff -u --recursive --new-file v2.4.5/linux/include/linux/mii.h linux/include/linux/mii.h
--- v2.4.5/linux/include/linux/mii.h	Wed May 16 10:25:38 2001
+++ linux/include/linux/mii.h	Wed Jun 27 14:15:30 2001
@@ -8,6 +8,8 @@
 #ifndef __LINUX_MII_H__
 #define __LINUX_MII_H__
 
+#include <linux/types.h>
+
 /* Inside the Happy Meal transceiver is the physical layer, they use an
  * implementations for National Semiconductor, part number DP83840VCE.
  * You can retrieve the data sheets and programming docs for this beast
@@ -125,6 +127,16 @@
 #define CSCONFIG_TCDISABLE      0x2000  /* Disable timeout counter     */
 #define CSCONFIG_RESV4          0x4000  /* Unused...                   */
 #define CSCONFIG_NDISABLE       0x8000  /* Disable NRZI                */
+
+
+/* This structure is used in all SIOCxMIIxxx ioctl calls */
+struct mii_ioctl_data {
+	u16		phy_id;
+	u16		reg_num;
+	u16		val_in;
+	u16		val_out;
+};
+
 
 /**
  * mii_nway_result
diff -u --recursive --new-file v2.4.5/linux/include/linux/mm.h linux/include/linux/mm.h
--- v2.4.5/linux/include/linux/mm.h	Fri May 25 18:01:28 2001
+++ linux/include/linux/mm.h	Wed Jun 27 16:01:22 2001
@@ -10,6 +10,7 @@
 #include <linux/string.h>
 #include <linux/list.h>
 #include <linux/mmzone.h>
+#include <linux/swap.h>
 
 extern unsigned long max_mapnr;
 extern unsigned long num_physpages;
@@ -39,32 +40,37 @@
  * library, the executable area etc).
  */
 struct vm_area_struct {
-	struct mm_struct * vm_mm;	/* VM area parameters */
-	unsigned long vm_start;
-	unsigned long vm_end;
+	struct mm_struct * vm_mm;	/* The address space we belong to. */
+	unsigned long vm_start;		/* Our start address within vm_mm. */
+	unsigned long vm_end;		/* Our end address within vm_mm. */
 
 	/* linked list of VM areas per task, sorted by address */
 	struct vm_area_struct *vm_next;
 
-	pgprot_t vm_page_prot;
-	unsigned long vm_flags;
+	pgprot_t vm_page_prot;		/* Access permissions of this VMA. */
+	unsigned long vm_flags;		/* Flags, listed below. */
 
 	/* AVL tree of VM areas per task, sorted by address */
 	short vm_avl_height;
 	struct vm_area_struct * vm_avl_left;
 	struct vm_area_struct * vm_avl_right;
 
-	/* For areas with an address space and backing store,
+	/*
+	 * For areas with an address space and backing store,
 	 * one of the address_space->i_mmap{,shared} lists,
 	 * for shm areas, the list of attaches, otherwise unused.
 	 */
 	struct vm_area_struct *vm_next_share;
 	struct vm_area_struct **vm_pprev_share;
 
+	/* Function pointers to deal with this struct. */
 	struct vm_operations_struct * vm_ops;
-	unsigned long vm_pgoff;		/* offset in PAGE_SIZE units, *not* PAGE_CACHE_SIZE */
-	struct file * vm_file;
-	unsigned long vm_raend;
+
+	/* Information about our backing store: */
+	unsigned long vm_pgoff;		/* Offset (within vm_file) in PAGE_SIZE
+					   units, *not* PAGE_CACHE_SIZE */
+	struct file * vm_file;		/* File we map to (can be NULL). */
+	unsigned long vm_raend;		/* XXX: put full readahead info here. */
 	void * vm_private_data;		/* was vm_pte (shared mem) */
 };
 
@@ -90,6 +96,7 @@
 #define VM_LOCKED	0x00002000
 #define VM_IO           0x00004000	/* Memory mapped I/O or similar */
 
+					/* Used by sys_madvise() */
 #define VM_SEQ_READ	0x00008000	/* App will access data sequentially */
 #define VM_RAND_READ	0x00010000	/* App will not benefit from clustered reads */
 
@@ -124,37 +131,144 @@
 };
 
 /*
+ * Each physical page in the system has a struct page associated with
+ * it to keep track of whatever it is we are using the page for at the
+ * moment. Note that we have no way to track which tasks are using
+ * a page.
+ *
  * Try to keep the most commonly accessed fields in single cache lines
  * here (16 bytes or greater).  This ordering should be particularly
  * beneficial on 32-bit processors.
  *
  * The first line is data used in page cache lookup, the second line
  * is used for linear searches (eg. clock algorithm scans). 
+ *
+ * TODO: make this structure smaller, it could be as small as 32 bytes.
  */
 typedef struct page {
-	struct list_head list;
-	struct address_space *mapping;
-	unsigned long index;
-	struct page *next_hash;
-	atomic_t count;
-	unsigned long flags;	/* atomic flags, some possibly updated asynchronously */
-	struct list_head lru;
-	unsigned long age;
-	wait_queue_head_t wait;
-	struct page **pprev_hash;
-	struct buffer_head * buffers;
-	void *virtual; /* non-NULL if kmapped */
-	struct zone_struct *zone;
+	struct list_head list;		/* ->mapping has some page lists. */
+	struct address_space *mapping;	/* The inode (or ...) we belong to. */
+	unsigned long index;		/* Our offset within mapping. */
+	struct page *next_hash;		/* Next page sharing our hash bucket in
+					   the pagecache hash table. */
+	atomic_t count;			/* Usage count, see below. */
+	unsigned long flags;		/* atomic flags, some possibly
+					   updated asynchronously */
+	struct list_head lru;		/* Pageout list, eg. active_list;
+					   protected by pagemap_lru_lock !! */
+	unsigned long age;		/* Page aging counter. */
+	wait_queue_head_t wait;		/* Page locked?  Stand in line... */
+	struct page **pprev_hash;	/* Complement to *next_hash. */
+	struct buffer_head * buffers;	/* Buffer maps us to a disk block. */
+	void *virtual;			/* Kernel virtual address (NULL if
+					   not kmapped, ie. highmem) */
+	struct zone_struct *zone;	/* Memory zone we are in. */
 } mem_map_t;
 
+/*
+ * Methods to modify the page usage count.
+ *
+ * What counts for a page usage:
+ * - cache mapping   (page->mapping)
+ * - disk mapping    (page->buffers)
+ * - page mapped in a task's page tables, each mapping
+ *   is counted separately
+ *
+ * Also, many kernel routines increase the page count before a critical
+ * routine so they can be sure the page doesn't go away from under them.
+ */
 #define get_page(p)		atomic_inc(&(p)->count)
 #define put_page(p)		__free_page(p)
 #define put_page_testzero(p) 	atomic_dec_and_test(&(p)->count)
 #define page_count(p)		atomic_read(&(p)->count)
 #define set_page_count(p,v) 	atomic_set(&(p)->count, v)
 
-/* Page flag bit values */
-#define PG_locked		 0
+/*
+ * Various page->flags bits:
+ *
+ * PG_reserved is set for special pages, which can never be swapped
+ * out. Some of them might not even exist (eg. empty_bad_page)...
+ *
+ * Multiple processes may "see" the same page. E.g. for untouched
+ * mappings of /dev/null, all processes see the same page full of
+ * zeroes, and text pages of executables and shared libraries have
+ * only one copy in memory, at most, normally.
+ *
+ * For the non-reserved pages, page->count denotes a reference count.
+ *   page->count == 0 means the page is free.
+ *   page->count == 1 means the page is used for exactly one purpose
+ *   (e.g. a private data page of one process).
+ *
+ * A page may be used for kmalloc() or anyone else who does a
+ * __get_free_page(). In this case the page->count is at least 1, and
+ * all other fields are unused but should be 0 or NULL. The
+ * management of this page is the responsibility of the one who uses
+ * it.
+ *
+ * The other pages (we may call them "process pages") are completely
+ * managed by the Linux memory manager: I/O, buffers, swapping etc.
+ * The following discussion applies only to them.
+ *
+ * A page may belong to an inode's memory mapping. In this case,
+ * page->mapping is the pointer to the inode, and page->offset is the
+ * file offset of the page (not necessarily a multiple of PAGE_SIZE).
+ *
+ * A page may have buffers allocated to it. In this case,
+ * page->buffers is a circular list of these buffer heads. Else,
+ * page->buffers == NULL.
+ *
+ * For pages belonging to inodes, the page->count is the number of
+ * attaches, plus 1 if buffers are allocated to the page, plus one
+ * for the page cache itself.
+ *
+ * All pages belonging to an inode are in these doubly linked lists:
+ * mapping->clean_pages, mapping->dirty_pages and mapping->locked_pages;
+ * using the page->list list_head. These fields are also used for
+ * freelist managemet (when page->count==0).
+ *
+ * There is also a hash table mapping (inode,offset) to the page
+ * in memory if present. The lists for this hash table use the fields
+ * page->next_hash and page->pprev_hash.
+ *
+ * All process pages can do I/O:
+ * - inode pages may need to be read from disk,
+ * - inode pages which have been modified and are MAP_SHARED may need
+ *   to be written to disk,
+ * - private pages which have been modified may need to be swapped out
+ *   to swap space and (later) to be read back into memory.
+ * During disk I/O, PG_locked is used. This bit is set before I/O
+ * and reset when I/O completes. page->wait is a wait queue of all
+ * tasks waiting for the I/O on this page to complete.
+ * PG_uptodate tells whether the page's contents is valid.
+ * When a read completes, the page becomes uptodate, unless a disk I/O
+ * error happened.
+ *
+ * For choosing which pages to swap out, inode pages carry a
+ * PG_referenced bit, which is set any time the system accesses
+ * that page through the (inode,offset) hash table. This referenced
+ * bit, together with the referenced bit in the page tables, is used
+ * to manipulate page->age and move the page across the active,
+ * inactive_dirty and inactive_clean lists.
+ *
+ * Note that the referenced bit, the page->lru list_head and the
+ * active, inactive_dirty and inactive_clean lists are protected by
+ * the pagemap_lru_lock, and *NOT* by the usual PG_locked bit!
+ *
+ * PG_skip is used on sparc/sparc64 architectures to "skip" certain
+ * parts of the address space.
+ *
+ * PG_error is set to indicate that an I/O error occurred on this page.
+ *
+ * PG_arch_1 is an architecture specific page state bit.  The generic
+ * code guarentees that this bit is cleared for a page when it first
+ * is entered into the page cache.
+ *
+ * PG_highmem pages are not permanently mapped into the kernel virtual
+ * address space, they need to be kmapped separately for doing IO on
+ * the pages. The struct page (these bits with information) are always
+ * mapped into kernel address space...
+ */
+#define PG_locked		 0	/* Page is locked. Don't touch. */
 #define PG_error		 1
 #define PG_referenced		 2
 #define PG_uptodate		 3
@@ -167,6 +281,7 @@
 #define PG_skip			10
 #define PG_inactive_clean	11
 #define PG_highmem		12
+#define PG_checked		13	/* kill me in 2.5.<early>. */
 				/* bits 21-29 unused */
 #define PG_arch_1		30
 #define PG_reserved		31
@@ -181,6 +296,8 @@
 #define PageLocked(page)	test_bit(PG_locked, &(page)->flags)
 #define LockPage(page)		set_bit(PG_locked, &(page)->flags)
 #define TryLockPage(page)	test_and_set_bit(PG_locked, &(page)->flags)
+#define PageChecked(page)	test_bit(PG_checked, &(page)->flags)
+#define SetPageChecked(page)	set_bit(PG_checked, &(page)->flags)
 
 extern void __set_page_dirty(struct page *);
 
@@ -254,81 +371,7 @@
 #define NOPAGE_SIGBUS	(NULL)
 #define NOPAGE_OOM	((struct page *) (-1))
 
-
-/*
- * Various page->flags bits:
- *
- * PG_reserved is set for a page which must never be accessed (which
- * may not even be present).
- *
- * PG_DMA has been removed, page->zone now tells exactly wether the
- * page is suited to do DMAing into.
- *
- * Multiple processes may "see" the same page. E.g. for untouched
- * mappings of /dev/null, all processes see the same page full of
- * zeroes, and text pages of executables and shared libraries have
- * only one copy in memory, at most, normally.
- *
- * For the non-reserved pages, page->count denotes a reference count.
- *   page->count == 0 means the page is free.
- *   page->count == 1 means the page is used for exactly one purpose
- *   (e.g. a private data page of one process).
- *
- * A page may be used for kmalloc() or anyone else who does a
- * __get_free_page(). In this case the page->count is at least 1, and
- * all other fields are unused but should be 0 or NULL. The
- * management of this page is the responsibility of the one who uses
- * it.
- *
- * The other pages (we may call them "process pages") are completely
- * managed by the Linux memory manager: I/O, buffers, swapping etc.
- * The following discussion applies only to them.
- *
- * A page may belong to an inode's memory mapping. In this case,
- * page->inode is the pointer to the inode, and page->offset is the
- * file offset of the page (not necessarily a multiple of PAGE_SIZE).
- *
- * A page may have buffers allocated to it. In this case,
- * page->buffers is a circular list of these buffer heads. Else,
- * page->buffers == NULL.
- *
- * For pages belonging to inodes, the page->count is the number of
- * attaches, plus 1 if buffers are allocated to the page.
- *
- * All pages belonging to an inode make up a doubly linked list
- * inode->i_pages, using the fields page->next and page->prev. (These
- * fields are also used for freelist management when page->count==0.)
- * There is also a hash table mapping (inode,offset) to the page
- * in memory if present. The lists for this hash table use the fields
- * page->next_hash and page->pprev_hash.
- *
- * All process pages can do I/O:
- * - inode pages may need to be read from disk,
- * - inode pages which have been modified and are MAP_SHARED may need
- *   to be written to disk,
- * - private pages which have been modified may need to be swapped out
- *   to swap space and (later) to be read back into memory.
- * During disk I/O, PG_locked is used. This bit is set before I/O
- * and reset when I/O completes. page->wait is a wait queue of all
- * tasks waiting for the I/O on this page to complete.
- * PG_uptodate tells whether the page's contents is valid.
- * When a read completes, the page becomes uptodate, unless a disk I/O
- * error happened.
- *
- * For choosing which pages to swap out, inode pages carry a
- * PG_referenced bit, which is set any time the system accesses
- * that page through the (inode,offset) hash table.
- *
- * PG_skip is used on sparc/sparc64 architectures to "skip" certain
- * parts of the address space.
- *
- * PG_error is set to indicate that an I/O error occurred on this page.
- *
- * PG_arch_1 is an architecture specific page state bit.  The generic
- * code guarentees that this bit is cleared for a page when it first
- * is entered into the page cache.
- */
-
+/* The array of struct pages */
 extern mem_map_t * mem_map;
 
 /*
@@ -337,10 +380,10 @@
  * can allocate highmem pages, the *get*page*() variants return
  * virtual kernel addresses to the allocated page(s).
  */
-extern struct page * FASTCALL(__alloc_pages(zonelist_t *zonelist, unsigned long order));
+extern struct page * FASTCALL(_alloc_pages(unsigned int gfp_mask, unsigned long order));
+extern struct page * FASTCALL(__alloc_pages(unsigned int gfp_mask, unsigned long order, zonelist_t *zonelist));
 extern struct page * alloc_pages_node(int nid, int gfp_mask, unsigned long order);
 
-#ifndef CONFIG_DISCONTIGMEM
 static inline struct page * alloc_pages(int gfp_mask, unsigned long order)
 {
 	/*
@@ -348,11 +391,8 @@
 	 */
 	if (order >= MAX_ORDER)
 		return NULL;
-	return __alloc_pages(contig_page_data.node_zonelists+(gfp_mask), order);
+	return _alloc_pages(gfp_mask, order);
 }
-#else /* !CONFIG_DISCONTIGMEM */
-extern struct page * alloc_pages(int gfp_mask, unsigned long order);
-#endif /* !CONFIG_DISCONTIGMEM */
 
 #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
 
@@ -427,6 +467,23 @@
 extern void si_meminfo(struct sysinfo * val);
 extern void swapin_readahead(swp_entry_t);
 
+/*
+ * Work out if there are any other processes sharing this
+ * swap cache page. Never mind the buffers.
+ */
+static inline int exclusive_swap_page(struct page *page)
+{
+	unsigned int count;
+
+	if (!PageLocked(page))
+		BUG();
+	if (!PageSwapCache(page))
+		return 0;
+	count = page_count(page) - !!page->buffers;	/*  2: us + swap cache */
+	count += swap_count(page);			/* +1: just swap cache */
+	return count == 3;				/* =3: total */
+}
+
 /* mmap.c */
 extern void lock_vma_mappings(struct vm_area_struct *);
 extern void unlock_vma_mappings(struct vm_area_struct *);
@@ -471,18 +528,17 @@
 /*
  * GFP bitmasks..
  */
-#define __GFP_WAIT	0x01
-#define __GFP_HIGH	0x02
-#define __GFP_IO	0x04
-#define __GFP_DMA	0x08
-#ifdef CONFIG_HIGHMEM
-#define __GFP_HIGHMEM	0x10
-#else
-#define __GFP_HIGHMEM	0x0 /* noop */
-#endif
+/* Zone modifiers in GFP_ZONEMASK (see linux/mmzone.h - low four bits) */
+#define __GFP_DMA	0x01
+#define __GFP_HIGHMEM	0x02
+
+/* Action modifiers - doesn't change the zoning */
+#define __GFP_WAIT	0x10
+#define __GFP_HIGH	0x20
+#define __GFP_IO	0x40
+#define __GFP_BUFFER	0x80
 
-
-#define GFP_BUFFER	(__GFP_HIGH | __GFP_WAIT)
+#define GFP_BUFFER	(__GFP_HIGH | __GFP_WAIT | __GFP_BUFFER)
 #define GFP_ATOMIC	(__GFP_HIGH)
 #define GFP_USER	(             __GFP_WAIT | __GFP_IO)
 #define GFP_HIGHUSER	(             __GFP_WAIT | __GFP_IO | __GFP_HIGHMEM)
@@ -533,11 +589,6 @@
 }
 
 extern struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr);
-
-#define buffer_under_min()	(atomic_read(&buffermem_pages) * 100 < \
-				buffer_mem.min_percent * num_physpages)
-#define pgcache_under_min()	(atomic_read(&page_cache_size) * 100 < \
-				page_cache.min_percent * num_physpages)
 
 #endif /* __KERNEL__ */
 
diff -u --recursive --new-file v2.4.5/linux/include/linux/mmzone.h linux/include/linux/mmzone.h
--- v2.4.5/linux/include/linux/mmzone.h	Fri May 25 18:01:27 2001
+++ linux/include/linux/mmzone.h	Wed Jun 27 16:01:22 2001
@@ -78,10 +78,9 @@
  */
 typedef struct zonelist_struct {
 	zone_t * zones [MAX_NR_ZONES+1]; // NULL delimited
-	int gfp_mask;
 } zonelist_t;
 
-#define NR_GFPINDEX		0x20
+#define GFP_ZONEMASK	0x0f
 
 /*
  * The pg_data_t structure is used in machines with CONFIG_DISCONTIGMEM
@@ -97,7 +96,7 @@
 struct bootmem_data;
 typedef struct pglist_data {
 	zone_t node_zones[MAX_NR_ZONES];
-	zonelist_t node_zonelists[NR_GFPINDEX];
+	zonelist_t node_zonelists[GFP_ZONEMASK+1];
 	struct page *node_mem_map;
 	unsigned long *valid_addr_bitmap;
 	struct bootmem_data *bdata;
diff -u --recursive --new-file v2.4.5/linux/include/linux/mount.h linux/include/linux/mount.h
--- v2.4.5/linux/include/linux/mount.h	Fri May 25 12:36:42 2001
+++ linux/include/linux/mount.h	Mon Jun 11 19:15:27 2001
@@ -14,12 +14,11 @@
 
 struct vfsmount
 {
+	struct list_head mnt_hash;
+	struct vfsmount *mnt_parent;	/* fs we are mounted on */
 	struct dentry *mnt_mountpoint;	/* dentry of mountpoint */
 	struct dentry *mnt_root;	/* root of the mounted tree */
-	struct vfsmount *mnt_parent;	/* fs we are mounted on */
 	struct list_head mnt_instances;	/* other vfsmounts of the same fs */
-	struct list_head mnt_clash;	/* those who are mounted on (other */
-					/* instances) of the same dentry */
 	struct super_block *mnt_sb;	/* pointer to superblock */
 	struct list_head mnt_mounts;	/* list of children, anchored here */
 	struct list_head mnt_child;	/* and going through their mnt_child */
diff -u --recursive --new-file v2.4.5/linux/include/linux/mtd/cfi.h linux/include/linux/mtd/cfi.h
--- v2.4.5/linux/include/linux/mtd/cfi.h	Mon Dec 11 13:16:46 2000
+++ linux/include/linux/mtd/cfi.h	Tue Jun 12 10:30:27 2001
@@ -1,14 +1,160 @@
 
 /* Common Flash Interface structures 
  * See http://support.intel.com/design/flash/technote/index.htm
- * $Id: cfi.h,v 1.6 2000/07/03 13:29:16 dwmw2 Exp $
+ * $Id: cfi.h,v 1.21 2001/06/03 01:32:57 nico Exp $
  */
 
 #ifndef __MTD_CFI_H__
 #define __MTD_CFI_H__
 
+#include <linux/config.h>
+#include <linux/delay.h>
 #include <linux/types.h>
 #include <linux/mtd/flashchip.h>
+#include <linux/mtd/cfi_endian.h>
+
+/*
+ * You can optimize the code size and performance by defining only 
+ * the geometry(ies) available on your hardware.
+ * CFIDEV_INTERLEAVE_n, where  represents the interleave (number of chips to fill the bus width)
+ * CFIDEV_BUSWIDTH_n, where n is the bus width in bytes (1, 2 or 4 bytes)
+ *
+ * By default, all (known) geometries are supported.
+ */
+
+#ifndef CONFIG_MTD_CFI_GEOMETRY
+
+#define CFIDEV_INTERLEAVE_1 (1)
+#define CFIDEV_INTERLEAVE_2 (2)
+#define CFIDEV_INTERLEAVE_4 (4)
+
+#define CFIDEV_BUSWIDTH_1 (1)
+#define CFIDEV_BUSWIDTH_2 (2)
+#define CFIDEV_BUSWIDTH_4 (4)
+
+#else
+
+#ifdef CONFIG_MTD_CFI_I1
+#define CFIDEV_INTERLEAVE_1 (1)
+#endif
+#ifdef CONFIG_MTD_CFI_I2
+#define CFIDEV_INTERLEAVE_2 (2)
+#endif
+#ifdef CONFIG_MTD_CFI_I4
+#define CFIDEV_INTERLEAVE_4 (4)
+#endif
+
+#ifdef CONFIG_MTD_CFI_B1
+#define CFIDEV_BUSWIDTH_1 (1)
+#endif
+#ifdef CONFIG_MTD_CFI_B2
+#define CFIDEV_BUSWIDTH_2 (2)
+#endif
+#ifdef CONFIG_MTD_CFI_B4
+#define CFIDEV_BUSWIDTH_4 (4)
+#endif
+
+#endif
+
+/*
+ * The following macros are used to select the code to execute:
+ *   cfi_buswidth_is_*()
+ *   cfi_interleave_is_*()
+ *   [where * is either 1, 2 or 4]
+ * Those macros should be used with 'if' statements.  If only one of few
+ * geometry arrangements are selected, they expand to constants thus allowing
+ * the compiler (most of them being 0) to optimize away all the unneeded code,
+ * while still validating the syntax (which is not possible with embedded 
+ * #if ... #endif constructs).
+ */
+
+#ifdef CFIDEV_INTERLEAVE_1
+# ifdef CFIDEV_INTERLEAVE
+#  undef CFIDEV_INTERLEAVE
+#  define CFIDEV_INTERLEAVE (cfi->interleave)
+# else
+#  define CFIDEV_INTERLEAVE CFIDEV_INTERLEAVE_1
+# endif
+# define cfi_interleave_is_1() (CFIDEV_INTERLEAVE == CFIDEV_INTERLEAVE_1)
+#else
+# define cfi_interleave_is_1() (0)
+#endif
+
+#ifdef CFIDEV_INTERLEAVE_2
+# ifdef CFIDEV_INTERLEAVE
+#  undef CFIDEV_INTERLEAVE
+#  define CFIDEV_INTERLEAVE (cfi->interleave)
+# else
+#  define CFIDEV_INTERLEAVE CFIDEV_INTERLEAVE_2
+# endif
+# define cfi_interleave_is_2() (CFIDEV_INTERLEAVE == CFIDEV_INTERLEAVE_2)
+#else
+# define cfi_interleave_is_2() (0)
+#endif
+
+#ifdef CFIDEV_INTERLEAVE_4
+# ifdef CFIDEV_INTERLEAVE
+#  undef CFIDEV_INTERLEAVE
+#  define CFIDEV_INTERLEAVE (cfi->interleave)
+# else
+#  define CFIDEV_INTERLEAVE CFIDEV_INTERLEAVE_4
+# endif
+# define cfi_interleave_is_4() (CFIDEV_INTERLEAVE == CFIDEV_INTERLEAVE_4)
+#else
+# define cfi_interleave_is_4() (0)
+#endif
+
+#ifndef CFIDEV_INTERLEAVE
+#error You must define at least one interleave to support!
+#endif
+
+#ifdef CFIDEV_BUSWIDTH_1
+# ifdef CFIDEV_BUSWIDTH
+#  undef CFIDEV_BUSWIDTH
+#  define CFIDEV_BUSWIDTH (map->buswidth)
+# else
+#  define CFIDEV_BUSWIDTH CFIDEV_BUSWIDTH_1
+# endif
+# define cfi_buswidth_is_1() (CFIDEV_BUSWIDTH == CFIDEV_BUSWIDTH_1)
+#else
+# define cfi_buswidth_is_1() (0)
+#endif
+
+#ifdef CFIDEV_BUSWIDTH_2
+# ifdef CFIDEV_BUSWIDTH
+#  undef CFIDEV_BUSWIDTH
+#  define CFIDEV_BUSWIDTH (map->buswidth)
+# else
+#  define CFIDEV_BUSWIDTH CFIDEV_BUSWIDTH_2
+# endif
+# define cfi_buswidth_is_2() (CFIDEV_BUSWIDTH == CFIDEV_BUSWIDTH_2)
+#else
+# define cfi_buswidth_is_2() (0)
+#endif
+
+#ifdef CFIDEV_BUSWIDTH_4
+# ifdef CFIDEV_BUSWIDTH
+#  undef CFIDEV_BUSWIDTH
+#  define CFIDEV_BUSWIDTH (map->buswidth)
+# else
+#  define CFIDEV_BUSWIDTH CFIDEV_BUSWIDTH_4
+# endif
+# define cfi_buswidth_is_4() (CFIDEV_BUSWIDTH == CFIDEV_BUSWIDTH_4)
+#else
+# define cfi_buswidth_is_4() (0)
+#endif
+
+#ifndef CFIDEV_BUSWIDTH
+#error You must define at least one bus width to support!
+#endif
+
+/* NB: these values must represents the number of bytes needed to meet the 
+ *     device type (x8, x16, x32).  Eg. a 32 bit device is 4 x 8 bytes. 
+ *     These numbers are used in calculations.
+ */
+#define CFI_DEVICETYPE_X8  (8 / 8)
+#define CFI_DEVICETYPE_X16 (16 / 8)
+#define CFI_DEVICETYPE_X32 (32 / 8)
 
 /* NB: We keep these structures in memory in HOST byteorder, except
  * where individually noted.
@@ -37,7 +183,7 @@
   __u16 InterfaceDesc;
   __u16 MaxBufWriteSize;
   __u8  NumEraseRegions;
-  __u32 EraseRegionInfo[1]; /* Not host ordered */
+  __u32 EraseRegionInfo[0]; /* Not host ordered */
 } __attribute__((packed));
 
 /* Extended Query Structure for both PRI and ALT */
@@ -82,20 +228,164 @@
 #define P_ID_RESERVED 65535
 
 
+#define CFI_MODE_CFI	0
+#define CFI_MODE_JEDEC	1
+
 struct cfi_private {
 	__u16 cmdset;
 	void *cmdset_priv;
 	int interleave;
+	int device_type;
+	int cfi_mode;		/* Are we a JEDEC device pretending to be CFI? */
+	int addr_unlock1;
+	int addr_unlock2;
+	int fast_prog;
 	struct mtd_info *(*cmdset_setup)(struct map_info *);
-	struct cfi_ident cfiq; /* For now only one. We insist that all devs
+	struct cfi_ident *cfiq; /* For now only one. We insist that all devs
 				  must be of the same type. */
+	__u8 mfr, id;
 	int numchips;
 	unsigned long chipshift; /* Because they're of the same type */
 	const char *im_name;	 /* inter_module name for cmdset_setup */
 	struct flchip chips[0];  /* per-chip data structure for each chip */
-	/* do not add extra fields after "chips" */
 };
 
 #define MAX_CFI_CHIPS 8 /* Entirely arbitrary to avoid realloc() */
+
+/*
+ * Returns the command address according to the given geometry.
+ */
+static inline __u32 cfi_build_cmd_addr(__u32 cmd_ofs, int interleave, int type)
+{
+	return (cmd_ofs * type) * interleave;
+}
+
+/*
+ * Transforms the CFI command for the given geometry (bus width & interleave.
+ */
+static inline __u32 cfi_build_cmd(u_char cmd, struct map_info *map, struct cfi_private *cfi)
+{
+	__u32 val = 0;
+
+	if (cfi_buswidth_is_1()) {
+		/* 1 x8 device */
+		val = cmd;
+	} else if (cfi_buswidth_is_2()) {
+		if (cfi_interleave_is_1()) {
+			/* 1 x16 device in x16 mode */
+			val = cpu_to_cfi16(cmd);
+		} else if (cfi_interleave_is_2()) {
+			/* 2 (x8, x16 or x32) devices in x8 mode */
+			val = cpu_to_cfi16((cmd << 8) | cmd);
+		}
+	} else if (cfi_buswidth_is_4()) {
+		if (cfi_interleave_is_1()) {
+			/* 1 x32 device in x32 mode */
+			val = cpu_to_cfi32(cmd);
+		} else if (cfi_interleave_is_2()) {
+			/* 2 x16 device in x16 mode */
+			val = cpu_to_cfi32((cmd << 16) | cmd);
+		} else if (cfi_interleave_is_4()) {
+			/* 4 (x8, x16 or x32) devices in x8 mode */
+			val = (cmd << 16) | cmd;
+			val = cpu_to_cfi32((val << 8) | val);
+		}
+	}
+	return val;
+}
+#define CMD(x)  cfi_build_cmd((x), map, cfi)
+
+/*
+ * Read a value according to the bus width.
+ */
+
+static inline __u32 cfi_read(struct map_info *map, __u32 addr)
+{
+	if (cfi_buswidth_is_1()) {
+		return map->read8(map, addr);
+	} else if (cfi_buswidth_is_2()) {
+		return map->read16(map, addr);
+	} else if (cfi_buswidth_is_4()) {
+		return map->read32(map, addr);
+	} else {
+		return 0;
+	}
+}
+
+/*
+ * Write a value according to the bus width.
+ */
+
+static inline void cfi_write(struct map_info *map, __u32 val, __u32 addr)
+{
+	if (cfi_buswidth_is_1()) {
+		map->write8(map, val, addr);
+	} else if (cfi_buswidth_is_2()) {
+		map->write16(map, val, addr);
+	} else if (cfi_buswidth_is_4()) {
+		map->write32(map, val, addr);
+	}
+}
+
+/*
+ * Sends a CFI command to a bank of flash for the given geometry.
+ *
+ * Returns the offset in flash where the command was written.
+ * If prev_val is non-null, it will be set to the value at the command address,
+ * before the command was written.
+ */
+static inline __u32 cfi_send_gen_cmd(u_char cmd, __u32 cmd_addr, __u32 base,
+				struct map_info *map, struct cfi_private *cfi,
+				int type, __u32 *prev_val)
+{
+	__u32 val;
+	__u32 addr = base + cfi_build_cmd_addr(cmd_addr, CFIDEV_INTERLEAVE, type);
+
+	val = cfi_build_cmd(cmd, map, cfi);
+
+	if (prev_val)
+		*prev_val = cfi_read(map, addr);
+
+	cfi_write(map, val, addr);
+
+	return addr - base;
+}
+
+static inline __u8 cfi_read_query(struct map_info *map, __u32 addr)
+{
+	if (cfi_buswidth_is_1()) {
+		return map->read8(map, addr);
+	} else if (cfi_buswidth_is_2()) {
+		return cfi16_to_cpu(map->read16(map, addr));
+	} else if (cfi_buswidth_is_4()) {
+		return cfi32_to_cpu(map->read32(map, addr));
+	} else {
+		return 0;
+	}
+}
+
+#ifndef min
+#define min(x,y) ( (x)<(y)?(x):(y) )
+#endif
+
+static inline void cfi_udelay(int us)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+	if (current->need_resched)
+		schedule();
+	else
+#endif
+		udelay(us);
+}
+static inline void cfi_spin_lock(spinlock_t *mutex)
+{
+	spin_lock_bh(mutex);
+}
+
+static inline void cfi_spin_unlock(spinlock_t *mutex)
+{
+	spin_unlock_bh(mutex);
+}
+
 
 #endif /* __MTD_CFI_H__ */
diff -u --recursive --new-file v2.4.5/linux/include/linux/mtd/cfi_endian.h linux/include/linux/mtd/cfi_endian.h
--- v2.4.5/linux/include/linux/mtd/cfi_endian.h	Wed Dec 31 16:00:00 1969
+++ linux/include/linux/mtd/cfi_endian.h	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,141 @@
+/*
+ * $Id: cfi_endian.h,v 1.9 2001/04/23 21:19:11 nico Exp $
+ *
+ * It seems that some helpful people decided to make life easier
+ * for software engineers who aren't capable of dealing with the 
+ * concept of byteswapping, and advise engineers to swap the bytes
+ * by wiring the data lines up to flash chips from BE hosts backwards.
+ *
+ * So we have ugly stuff here to disable the byteswapping where necessary.
+ * I'm not going to try to do this dynamically.
+ *
+ * At first I thought these guys were on crack, but then I discovered the
+ * LART. 
+ *
+ */
+
+#include <asm/byteorder.h>
+
+#ifndef CONFIG_MTD_CFI_ADV_OPTIONS
+
+#define CFI_HOST_ENDIAN
+
+#else
+
+#ifdef CONFIG_MTD_CFI_NOSWAP
+#define CFI_HOST_ENDIAN
+#endif
+
+#ifdef CONFIG_MTD_CFI_LE_BYTE_SWAP
+#define CFI_LITTLE_ENDIAN
+#endif
+
+#ifdef CONFIG_MTD_CFI_BE_BYTE_SWAP
+#define CFI_BIG_ENDIAN
+#endif
+
+#ifdef CONFIG_MTD_CFI_LART_BIT_SWAP
+#define CFI_LART_ENDIAN
+#endif
+
+#endif
+
+#if defined(CFI_LITTLE_ENDIAN)
+#define cpu_to_cfi8(x) (x)
+#define cfi8_to_cpu(x) (x)
+#define cpu_to_cfi16(x) cpu_to_le16(x)
+#define cpu_to_cfi32(x) cpu_to_le32(x)
+#define cfi16_to_cpu(x) le16_to_cpu(x)
+#define cfi32_to_cpu(x) le32_to_cpu(x)
+#elif defined (CFI_BIG_ENDIAN)
+#define cpu_to_cfi8(x) (x)
+#define cfi8_to_cpu(x) (x)
+#define cpu_to_cfi16(x) cpu_to_be16(x)
+#define cpu_to_cfi32(x) cpu_to_be32(x)
+#define cfi16_to_cpu(x) be16_to_cpu(x)
+#define cfi32_to_cpu(x) be32_to_cpu(x)
+#elif defined (CFI_HOST_ENDIAN)
+#define cpu_to_cfi8(x) (x)
+#define cfi8_to_cpu(x) (x)
+#define cpu_to_cfi16(x) (x)
+#define cpu_to_cfi32(x) (x)
+#define cfi16_to_cpu(x) (x)
+#define cfi32_to_cpu(x) (x)
+#elif defined (CFI_LART_ENDIAN)
+/* 
+   Fuck me backwards. The data line mapping on LART is as follows:
+
+	U2	CPU	|	U3	CPU
+	 0	20	|	0	12
+	 1	22	|	1	14
+	 2	19	|	2	11
+	 3	17	|	3	9
+	 4	24	|	4	0
+	 5	26	|	5	2
+	 6	31	|	6	7
+	 7	29	|	7	5
+	 8	21	|	8	13
+	 9	23	|	9	15
+	 10	18	|	10	10
+	 11	16	|	11	8
+	 12	25	|	12	1
+	 13	27	|	13	3
+	 14	30	|	14	6
+	 15	28	|	15	4
+
+   For historical reference: the reason why the LART has this strange
+   mapping is that the designer of the board wanted address lines to
+   be as short as possible. Why? Because in that way you don't need
+   drivers in the address lines so the memory access time can be held
+   short. -- Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
+*/
+/* cpu_to_cfi16() and cfi16_to_cpu() are not needed because the LART
+ * only has 32 bit wide Flash memory. -- Erik
+ */
+#define cpu_to_cfi16(x) (x)
+#define cfi16_to_cpu(x) (x)
+static inline __u32 cfi32_to_cpu(__u32 x)
+{
+	__u32 ret;
+
+	ret =  (x & 0x08009000) >> 11;
+	ret |= (x & 0x00002000) >> 10;
+	ret |= (x & 0x04004000) >> 8;
+	ret |= (x & 0x00000010) >> 4;
+	ret |= (x & 0x91000820) >> 3;
+	ret |= (x & 0x22080080) >> 2;
+	ret |= (x & 0x40000400);
+	ret |= (x & 0x00040040) << 1;
+	ret |= (x & 0x00110000) << 4;
+	ret |= (x & 0x00220100) << 5;
+	ret |= (x & 0x00800208) << 6;
+	ret |= (x & 0x00400004) << 9;
+	ret |= (x & 0x00000001) << 12;
+	ret |= (x & 0x00000002) << 13;
+
+	return ret;
+}
+static inline __u32 cpu_to_cfi32(__u32 x)
+{
+	__u32 ret;
+
+	ret =  (x & 0x00010012) << 11;
+	ret |= (x & 0x00000008) << 10;
+	ret |= (x & 0x00040040) << 8;
+	ret |= (x & 0x00000001) << 4;
+	ret |= (x & 0x12200104) << 3;
+	ret |= (x & 0x08820020) << 2;
+	ret |= (x & 0x40000400);
+	ret |= (x & 0x00080080) >> 1;
+	ret |= (x & 0x01100000) >> 4;
+	ret |= (x & 0x04402000) >> 5;
+	ret |= (x & 0x20008200) >> 6;
+	ret |= (x & 0x80000800) >> 9;
+	ret |= (x & 0x00001000) >> 12;
+	ret |= (x & 0x00004000) >> 13;
+
+	return ret;
+}
+#else
+#error No CFI endianness defined
+#endif
diff -u --recursive --new-file v2.4.5/linux/include/linux/mtd/doc2000.h linux/include/linux/mtd/doc2000.h
--- v2.4.5/linux/include/linux/mtd/doc2000.h	Mon Dec 11 14:57:58 2000
+++ linux/include/linux/mtd/doc2000.h	Tue Jun 12 10:30:27 2001
@@ -2,7 +2,7 @@
 /* Linux driver for Disk-On-Chip 2000       */
 /* (c) 1999 Machine Vision Holdings, Inc.   */
 /* Author: David Woodhouse <dwmw2@mvhi.com> */
-/* $Id: doc2000.h,v 1.12 2000/11/03 12:43:43 dwmw2 Exp $ */
+/* $Id: doc2000.h,v 1.13 2001/05/29 12:03:45 dwmw2 Exp $ */
 
 #ifndef __MTD_DOC2000_H__
 #define __MTD_DOC2000_H__
@@ -43,15 +43,19 @@
  * On PPC, it's mmap'd and 16-bit wide.
  * Others use readb/writeb 
  */
-#if defined(__arm__) 
-#define ReadDOC_(adr, reg)      ((unsigned char)(*(__u32 *)(((unsigned long)adr)+(reg<<2))))
-#define WriteDOC_(d, adr, reg)  do{ *(__u32 *)(((unsigned long)adr)+(reg<<2)) = (__u32)d} while(0)
+#if defined(__arm__)
+#define ReadDOC_(adr, reg)      ((unsigned char)(*(__u32 *)(((unsigned long)adr)+((reg)<<2))))
+#define WriteDOC_(d, adr, reg)  do{ *(__u32 *)(((unsigned long)adr)+((reg)<<2)) = (__u32)d; wmb();} while(0)
+#define DOC_IOREMAP_LEN 0x8000
 #elif defined(__ppc__)
-#define ReadDOC_(adr, reg)      ((unsigned char)(*(__u16 *)(((unsigned long)adr)+(reg<<1))))
-#define WriteDOC_(d, adr, reg)  do{ *(__u16 *)(((unsigned long)adr)+(reg<<1)) = (__u16)d} while(0)
+#define ReadDOC_(adr, reg)      ((unsigned char)(*(__u16 *)(((unsigned long)adr)+((reg)<<1))))
+#define WriteDOC_(d, adr, reg)  do{ *(__u16 *)(((unsigned long)adr)+((reg)<<1)) = (__u16)d; wmb();} while(0)
+#define DOC_IOREMAP_LEN 0x4000
 #else
-#define ReadDOC_(adr, reg)      readb(((unsigned long)adr) + reg)
-#define WriteDOC_(d, adr, reg)  writeb(d, ((unsigned long)adr) + reg)
+#define ReadDOC_(adr, reg)      readb(((unsigned long)adr) + (reg))
+#define WriteDOC_(d, adr, reg)  writeb(d, ((unsigned long)adr) + (reg))
+#define DOC_IOREMAP_LEN 0x2000
+
 #endif
 
 #if defined(__i386__)
diff -u --recursive --new-file v2.4.5/linux/include/linux/mtd/flashchip.h linux/include/linux/mtd/flashchip.h
--- v2.4.5/linux/include/linux/mtd/flashchip.h	Mon Dec 11 13:16:46 2000
+++ linux/include/linux/mtd/flashchip.h	Tue Jun 12 10:30:27 2001
@@ -6,7 +6,7 @@
  *
  * (C) 2000 Red Hat. GPLd.
  *
- * $Id: flashchip.h,v 1.4 2000/07/03 12:58:41 dwmw2 Exp $
+ * $Id: flashchip.h,v 1.7 2001/01/18 03:52:36 nico Exp $
  *
  */
 
@@ -25,12 +25,17 @@
 	FL_CFI_QUERY,
 	FL_JEDEC_QUERY,
 	FL_ERASING,
+	FL_ERASE_SUSPENDING,
 	FL_ERASE_SUSPENDED,
 	FL_WRITING,
+	FL_WRITING_TO_BUFFER,
+	FL_WRITE_SUSPENDING,
 	FL_WRITE_SUSPENDED,
 	FL_PM_SUSPENDED,
 	FL_SYNCING,
 	FL_UNLOADING,
+	FL_LOCKING,
+	FL_UNLOCKING,
 	FL_UNKNOWN
 } flstate_t;
 
diff -u --recursive --new-file v2.4.5/linux/include/linux/mtd/map.h linux/include/linux/mtd/map.h
--- v2.4.5/linux/include/linux/mtd/map.h	Fri Feb  9 11:29:44 2001
+++ linux/include/linux/mtd/map.h	Tue Jun 12 10:30:27 2001
@@ -1,6 +1,6 @@
 
 /* Overhauled routines for dealing with different mmap regions of flash */
-/* $Id: map.h,v 1.10.2.2 2001/01/09 00:44:51 dwmw2 Exp $ */
+/* $Id: map.h,v 1.24 2001/06/09 19:53:16 dwmw2 Exp $ */
 
 #ifndef __LINUX_MTD_MAP_H__
 #define __LINUX_MTD_MAP_H__
@@ -53,47 +53,23 @@
 	unsigned long map_priv_1;
 	unsigned long map_priv_2;
 	void *fldrv_priv;
-	void (*fldrv_destroy)(struct mtd_info *);
-	const char *im_name;
+	struct mtd_chip_driver *fldrv;
 };
 
-#ifdef CONFIG_MODULES
-/* 
- * Probe for the contents of a map device and make an MTD structure
- * if anything is recognised. Doesn't register it because the calling
- * map driver needs to set the 'module' field first.
- */
-static inline struct mtd_info *do_map_probe(struct map_info *map, const char *funcname, const char *modname)
-{
-	struct mtd_info *(*probe_p)(struct map_info *);
-	struct mtd_info *mtd = NULL;
 
-	if ((probe_p = inter_module_get_request(modname, funcname)))
-		mtd = (*probe_p)(map);	/* map->im_name is set by probe */
+struct mtd_chip_driver {
+	struct mtd_info *(*probe)(struct map_info *map);
+	void (*destroy)(struct mtd_info *);
+	struct module *module;
+	char *name;
+	struct list_head list;
+};
 
-	return mtd;
-}
+void register_mtd_chip_driver(struct mtd_chip_driver *);
+void unregister_mtd_chip_driver(struct mtd_chip_driver *);
 
+struct mtd_info *do_map_probe(char *name, struct map_info *map);
 
-/* 
- * Commonly-used probe functions for different types of chip.
- */
-#define do_cfi_probe(x) do_map_probe(x, "cfi_probe", "cfi_probe")
-#define do_jedec_probe(x) do_map_probe(x, "jedec_probe", "jedec_probe")
-#define do_ram_probe(x) do_map_probe(x, "map_ram_probe", "map_ram")
-#define do_rom_probe(x) do_map_probe(x, "map_rom_probe", "map_rom")
-#else
-	/* without module support, call probe function directly */
-extern struct mtd_info *cfi_probe(struct map_info *);
-extern struct mtd_info *jedec_probe(struct map_info *);
-extern struct mtd_info *map_ram_probe(struct map_info *);
-extern struct mtd_info *map_rom_probe(struct map_info *);
-
-#define do_cfi_probe(x) cfi_probe(x)
-#define do_jedec_probe(x) jedec_probe(x)
-#define do_ram_probe(x) map_ram_probe(x)
-#define do_rom_probe(x) map_rom_probe(x)
-#endif
 
 /*
  * Destroy an MTD device which was created for a map device.
@@ -103,8 +79,11 @@
 {
 	struct map_info *map = mtd->priv;
 
-	map->fldrv_destroy(mtd);
-	inter_module_put(map->im_name);
+	map->fldrv->destroy(mtd);
+#ifdef CONFIG_MODULES
+	if (map->fldrv->module)
+		__MOD_DEC_USE_COUNT(map->fldrv->module);
+#endif
 	kfree(mtd);
 }
 
diff -u --recursive --new-file v2.4.5/linux/include/linux/mtd/mapped.h linux/include/linux/mtd/mapped.h
--- v2.4.5/linux/include/linux/mtd/mapped.h	Tue Jul  4 10:12:33 2000
+++ linux/include/linux/mtd/mapped.h	Wed Dec 31 16:00:00 1969
@@ -1,92 +0,0 @@
-// -*- mode: cpp; mode: fold -*-
-// Description                                                          /*{{{*/
-// $Id: mapped.h,v 1.2 2000/03/14 17:13:12 dwmw2 Exp $
-/* ######################################################################
-
-   Memory Mapped  MTD Routines
-   
-   These routines are support routines for memory mapped chips, with
-   routines to support common sorts of flash. For devices that are based
-   on a memory mapped interface these routines provide everything necessary,
-   only a window changing function is required by the low level implementation.
-   
-   The entry point to setup and register a memory mapped MTD device, 
-   mtd_mapped_setup will perform a detection sequence that can determine
-   the type size and configuration of many sorts of chip setups. 
-
-   ROMs and RAMs are detected and passed off to very simple routines, Flash
-   writing and erasing is handled as well.
-   
-   ##################################################################### */
-									/*}}}*/
-#ifndef __MTD_FLASH_H__
-#define __MTD_FLASH_H__
-
-#include <linux/types.h>
-#include <linux/mtd/mtd.h>
-
-// MTD flags for ordinary flash
-struct JEDECTable
-{
-   u_short jedec;
-   char *name;
-   u_long size;
-   u_long sectorsize;
-   u_long capabilities;
-};
-
-// JEDEC being 0 is the end of the chip array
-struct flash_chip
-{
-   u_short jedec;
-   u_long size;
-   u_long sectorsize;
-   u_long base;
-   u_long capabilities;
-   
-   // These markers are filled in by the flash_chip_scan function
-   u_long start;
-   u_long length;
-};
-
-struct mapped_mtd_info
-{
-   struct mtd_info mtd;
-   u_long pagesize;        // Size of the memory window
-   u_long maxsize;         // Maximum MTD size in pages
-   u_char mfr,id;
-   char part[100];            // Part Catalogue number if available
-   int *lock;
-   // Multiple chip support, only used if this is type MTD_FLASH
-   u_char interleve;       // Address chip interleve (0 = concatination)
-   struct flash_chip chips[5];
-  
-   // Operations
-   unsigned long (*page)(struct mapped_mtd_info *map,unsigned long page);
-   int (*jedec_sense)(struct mapped_mtd_info *map);
-};
-
-extern struct JEDECTable mtd_JEDEC_table[];
-
-// Automatic configurators
-extern int mtd_mapped_setup(struct mapped_mtd_info *map);
-extern int mtd_mapped_remove(struct mapped_mtd_info *map);
-
-// Generic functions
-extern int flash_jedec(struct mapped_mtd_info *map);
-extern int flash_erase(struct mtd_info *map, struct erase_info *instr);
-extern int flash_write(struct mtd_info *map, loff_t start, size_t len,
-		       size_t *retlen, const u_char *buf);
-extern int rom_read(struct mtd_info *map, loff_t start, size_t len,
-		    size_t *retlen, u_char *buf);
-extern int ram_write(struct mtd_info *map, loff_t start, size_t len,
-		     size_t *retlen, const u_char *buf);
-
-// Helpers
-extern int page_jump(struct mapped_mtd_info *map,unsigned long start,
-		     unsigned long len,unsigned long *buffer,
-		     unsigned long *size);
-extern void flash_chip_scan(struct mapped_mtd_info *map,unsigned long start,
-			    unsigned long len);
-
-#endif /* __MTD_FLASH_H__ */
diff -u --recursive --new-file v2.4.5/linux/include/linux/mtd/mtd.h linux/include/linux/mtd/mtd.h
--- v2.4.5/linux/include/linux/mtd/mtd.h	Fri Dec 29 14:07:24 2000
+++ linux/include/linux/mtd/mtd.h	Tue Jun 12 10:30:27 2001
@@ -1,5 +1,5 @@
 
-/* $Id: mtd.h,v 1.26 2000/10/30 17:18:04 sjhill Exp $ */
+/* $Id: mtd.h,v 1.33 2001/06/09 00:08:59 dwmw2 Exp $ */
 
 #ifndef __MTD_MTD_H__
 #define __MTD_MTD_H__
@@ -16,13 +16,13 @@
 #endif /* __KERNEL__ */
 
 struct erase_info_user {
-	unsigned long start;
-	unsigned long length;
+	u_int32_t start;
+	u_int32_t length;
 };
 
 struct mtd_oob_buf {
-	loff_t start;
-	ssize_t length;
+	u_int32_t start;
+	u_int32_t length;
 	unsigned char *ptr;
 };
 
@@ -68,13 +68,21 @@
 
 struct mtd_info_user {
 	u_char type;
-	u_long flags;
-	u_long size;	 // Total size of the MTD
-	u_long erasesize;
-	u_long oobblock;  // Size of OOB blocks (e.g. 512)
-	u_long oobsize;   // Amount of OOB data per block (e.g. 16)
-        u_long ecctype;
-        u_long eccsize;
+	u_int32_t flags;
+	u_int32_t size;	 // Total size of the MTD
+	u_int32_t erasesize;
+	u_int32_t oobblock;  // Size of OOB blocks (e.g. 512)
+	u_int32_t oobsize;   // Amount of OOB data per block (e.g. 16)
+	u_int32_t ecctype;
+	u_int32_t eccsize;
+};
+
+struct region_info_user {
+	u_int32_t offset;		/* At which this region starts, 
+					 * from the beginning of the MTD */
+	u_int32_t erasesize;		/* For this region */
+	u_int32_t numblocks;		/* Number of blocks in this region */
+	u_int32_t regionindex;
 };
 
 #define MEMGETINFO              _IOR('M', 1, struct mtd_info_user)
@@ -83,11 +91,14 @@
 #define MEMREADOOB              _IOWR('M', 4, struct mtd_oob_buf)
 #define MEMLOCK                 _IOW('M', 5, struct erase_info_user)
 #define MEMUNLOCK               _IOW('M', 6, struct erase_info_user)
+#define MEMGETREGIONCOUNT	_IOR('M', 7, int)
+#define MEMGETREGIONINFO	_IOWR('M', 8, struct region_info_user)
 
 #ifndef __KERNEL__
 
 typedef struct mtd_info_user mtd_info_t;
 typedef struct erase_info_user erase_info_t;
+typedef struct region_info_user region_info_t;
 
 	/* User-space ioctl definitions */
 
@@ -103,8 +114,8 @@
 
 struct erase_info {
 	struct mtd_info *mtd;
-	u_long addr;
-	u_long len;
+	u_int32_t addr;
+	u_int32_t len;
 	u_long time;
 	u_long retries;
 	u_int dev;
@@ -115,22 +126,40 @@
 	struct erase_info *next;
 };
 
+struct mtd_erase_region_info {
+	u_int32_t offset;			/* At which this region starts, from the beginning of the MTD */
+	u_int32_t erasesize;		/* For this region */
+	u_int32_t numblocks;		/* Number of blocks of erasesize in this region */
+};
 
 struct mtd_info {
 	u_char type;
-	u_long flags;
-	u_long size;	 // Total size of the MTD
-	u_long erasesize;
-	u_long oobblock;  // Size of OOB blocks (e.g. 512)
-	u_long oobsize;   // Amount of OOB data per block (e.g. 16)
-        u_long ecctype;
-        u_long eccsize;
+	u_int32_t flags;
+	u_int32_t size;	 // Total size of the MTD
+
+	/* "Major" erase size for the device. Naďve users may take this
+	 * to be the only erase size available, or may use the more detailed
+	 * information below if they desire
+	 */
+	u_int32_t erasesize;
+
+	u_int32_t oobblock;  // Size of OOB blocks (e.g. 512)
+	u_int32_t oobsize;   // Amount of OOB data per block (e.g. 16)
+	u_int32_t ecctype;
+	u_int32_t eccsize;
 
 	// Kernel-only stuff starts here.
 	char *name;
 	int index;
 
-	u_long bank_size;
+	/* Data for variable erase regions. If numeraseregions is zero,
+	 * it means that the whole device has erasesize as given above. 
+	 */
+	int numeraseregions;
+	struct mtd_erase_region_info *eraseregions; 
+
+	/* This really shouldn't be here. It can go away in 2.5 */
+	u_int32_t bank_size;
 
 	struct module *module;
 	int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
diff -u --recursive --new-file v2.4.5/linux/include/linux/mtd/nand_ecc.h linux/include/linux/mtd/nand_ecc.h
--- v2.4.5/linux/include/linux/mtd/nand_ecc.h	Wed Dec 31 16:00:00 1969
+++ linux/include/linux/mtd/nand_ecc.h	Tue Jun 12 10:30:27 2001
@@ -0,0 +1,28 @@
+/*
+ *  drivers/mtd/nand_ecc.h
+ *
+ *  Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
+ *
+ * $Id: nand_ecc.h,v 1.1 2000/10/12 00:57:15 sjhill Exp $
+ *
+ * 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.
+ *
+ * This file is the header for the ECC algorithm.
+ */
+
+/*
+ * Creates non-inverted ECC code from line parity
+ */
+void nand_trans_result(u_char reg2, u_char reg3, u_char *ecc_code);
+
+/*
+ * Calculate 3 byte ECC code for 256 byte block
+ */
+void nand_calculate_ecc (const u_char *dat, u_char *ecc_code);
+
+/*
+ * Detect and correct a 1 bit error for 256 byte block
+ */
+int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc);
diff -u --recursive --new-file v2.4.5/linux/include/linux/mtd/nftl.h linux/include/linux/mtd/nftl.h
--- v2.4.5/linux/include/linux/mtd/nftl.h	Mon Dec 11 14:57:58 2000
+++ linux/include/linux/mtd/nftl.h	Tue Jun 12 10:30:27 2001
@@ -2,7 +2,7 @@
 /* Defines for NAND Flash Translation Layer  */
 /* (c) 1999 Machine Vision Holdings, Inc.    */
 /* Author: David Woodhouse <dwmw2@mvhi.com>  */
-/* $Id: nftl.h,v 1.9 2000/11/07 05:48:49 ollie Exp $ */
+/* $Id: nftl.h,v 1.10 2000/12/29 00:25:38 dwmw2 Exp $ */
 
 #ifndef __MTD_NFTL_H__
 #define __MTD_NFTL_H__
@@ -115,6 +115,7 @@
 
 #define MAX_NFTLS 16
 #define MAX_SECTORS_PER_UNIT 32
+#define NFTL_PARTN_BITS 4
 
 #endif /* __KERNEL__ */
 
diff -u --recursive --new-file v2.4.5/linux/include/linux/mtd/partitions.h linux/include/linux/mtd/partitions.h
--- v2.4.5/linux/include/linux/mtd/partitions.h	Mon Dec 11 14:57:58 2000
+++ linux/include/linux/mtd/partitions.h	Tue Jun 12 10:30:27 2001
@@ -5,7 +5,7 @@
  *
  * This code is GPL
  *
- * $Id: partitions.h,v 1.3 2000/11/10 23:35:12 nico Exp $
+ * $Id: partitions.h,v 1.6 2001/03/17 17:10:21 dwmw2 Exp $
  */
 
 #ifndef MTD_PARTITIONS_H
@@ -22,10 +22,11 @@
  *
  * For each partition, these fields are available:
  * name: string that will be used to label the partition's MTD device.
- * size: the partition size; if 0, the partition will extend to the end of the 
- * 	master MTD device.
- * offset: absolute starting position within the master MTD device; if 0,
- * 	partition will start where the previous one ended.
+ * size: the partition size; if defined as MTDPART_SIZ_FULL, the partition 
+ * 	will extend to the end of the master MTD device.
+ * offset: absolute starting position within the master MTD device; if 
+ * 	defined as MTDPART_OFS_APPEND, the partition will start where the 
+ * 	previous one ended.
  * mask_flags: contains flags that have to be masked (removed) from the 
  * 	master MTD flag set for the corresponding MTD partition.
  * 	For example, to force a read-only partition, simply adding 
@@ -37,10 +38,13 @@
 
 struct mtd_partition {
 	char *name;		/* identifier string */
-	u_long size;		/* partition size */
-	u_long offset;		/* offset within the master MTD space */
-	u_long mask_flags;	/* master MTD flags to mask out for this partition */
+	u_int32_t size;		/* partition size */
+	u_int32_t offset;		/* offset within the master MTD space */
+	u_int32_t mask_flags;	/* master MTD flags to mask out for this partition */
 };
+
+#define MTDPART_OFS_APPEND	(-1)
+#define MTDPART_SIZ_FULL	(0)
 
 
 int add_mtd_partitions(struct mtd_info *, struct mtd_partition *, int);
diff -u --recursive --new-file v2.4.5/linux/include/linux/netfilter_bridge.h linux/include/linux/netfilter_bridge.h
--- v2.4.5/linux/include/linux/netfilter_bridge.h	Wed Dec 31 16:00:00 1969
+++ linux/include/linux/netfilter_bridge.h	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,24 @@
+#ifndef __LINUX_BRIDGE_NETFILTER_H
+#define __LINUX_BRIDGE_NETFILTER_H
+
+/* bridge-specific defines for netfilter. 
+ */
+
+#include <linux/config.h>
+#include <linux/netfilter.h>
+
+/* Bridge Hooks */
+/* After promisc drops, checksum checks. */
+#define NF_BR_PRE_ROUTING	0
+/* If the packet is destined for this box. */
+#define NF_BR_LOCAL_IN		1
+/* If the packet is destined for another interface. */
+#define NF_BR_FORWARD		2
+/* Packets coming from a local process. */
+#define NF_BR_LOCAL_OUT		3
+/* Packets about to hit the wire. */
+#define NF_BR_POST_ROUTING	4
+#define NF_BR_NUMHOOKS		5
+
+
+#endif
diff -u --recursive --new-file v2.4.5/linux/include/linux/netfilter_ipv4/ip_tables.h linux/include/linux/netfilter_ipv4/ip_tables.h
--- v2.4.5/linux/include/linux/netfilter_ipv4/ip_tables.h	Mon Dec 11 13:31:24 2000
+++ linux/include/linux/netfilter_ipv4/ip_tables.h	Mon Jun 11 19:15:27 2001
@@ -300,14 +300,14 @@
 ({						\
 	unsigned int __i;			\
 	int __ret = 0;				\
-	struct ipt_entry_match *__m;		\
+	struct ipt_entry_match *__match;	\
 						\
 	for (__i = sizeof(struct ipt_entry);	\
 	     __i < (e)->target_offset;		\
-	     __i += __m->u.match_size) {	\
-		__m = (void *)(e) + __i;	\
+	     __i += __match->u.match_size) {	\
+		__match = (void *)(e) + __i;	\
 						\
-		__ret = fn(__m , ## args);	\
+		__ret = fn(__match , ## args);	\
 		if (__ret != 0)			\
 			break;			\
 	}					\
@@ -319,12 +319,12 @@
 ({								\
 	unsigned int __i;					\
 	int __ret = 0;						\
-	struct ipt_entry *__e;					\
+	struct ipt_entry *__entry;				\
 								\
-	for (__i = 0; __i < (size); __i += __e->next_offset) {	\
-		__e = (void *)(entries) + __i;			\
+	for (__i = 0; __i < (size); __i += __entry->next_offset) { \
+		__entry = (void *)(entries) + __i;		\
 								\
-		__ret = fn(__e , ## args);			\
+		__ret = fn(__entry , ## args);			\
 		if (__ret != 0)					\
 			break;					\
 	}							\
diff -u --recursive --new-file v2.4.5/linux/include/linux/parport_pc.h linux/include/linux/parport_pc.h
--- v2.4.5/linux/include/linux/parport_pc.h	Sat May 19 18:07:04 2001
+++ linux/include/linux/parport_pc.h	Mon Jun 11 19:15:27 2001
@@ -224,5 +224,6 @@
 					      unsigned long base_hi,
 					      int irq, int dma,
 					      struct pci_dev *dev);
+extern void parport_pc_unregister_port (struct parport *p);
 
 #endif
diff -u --recursive --new-file v2.4.5/linux/include/linux/pci.h linux/include/linux/pci.h
--- v2.4.5/linux/include/linux/pci.h	Fri May 25 18:02:11 2001
+++ linux/include/linux/pci.h	Wed Jun 27 16:01:49 2001
@@ -327,6 +327,9 @@
 #define pci_for_each_dev_reverse(dev) \
 	for(dev = pci_dev_g(pci_devices.prev); dev != pci_dev_g(&pci_devices); dev = pci_dev_g(dev->global_list.prev))
 
+#define pci_for_each_bus(bus) \
+for(bus = pci_bus_b(pci_root_buses.next); bus != pci_bus_b(&pci_root_buses); bus = pci_bus_b(bus->node.next))
+
 /*
  * The pci_dev structure is used to describe both PCI and ISAPnP devices.
  */
@@ -356,6 +359,10 @@
 					   this if your device has broken DMA
 					   or supports 64-bit transfers.  */
 
+	u32             current_state;  /* Current operating state. In ACPI-speak,
+					   this is D0-D3, D0 being fully functional,
+					   and D3 being off. */
+
 	/* device is compatible with these IDs */
 	unsigned short vendor_compatible[DEVICE_COUNT_COMPATIBLE];
 	unsigned short device_compatible[DEVICE_COUNT_COMPATIBLE];
@@ -469,10 +476,11 @@
 	struct list_head node;
 	char *name;
 	const struct pci_device_id *id_table;	/* NULL if wants all devices */
-	int (*probe)(struct pci_dev *dev, const struct pci_device_id *id);	/* New device inserted */
-	void (*remove)(struct pci_dev *dev);	/* Device removed (NULL if not a hot-plug capable driver) */
-	void (*suspend)(struct pci_dev *dev);	/* Device suspended */
-	void (*resume)(struct pci_dev *dev);	/* Device woken up */
+	int  (*probe)  (struct pci_dev *dev, const struct pci_device_id *id);	/* New device inserted */
+	void (*remove) (struct pci_dev *dev);	/* Device removed (NULL if not a hot-plug capable driver) */
+	int  (*suspend)(struct pci_dev *dev, u32 state);	/* Device suspended */
+	int  (*resume) (struct pci_dev *dev);	                /* Device woken up */
+	int  (*enable_wake) (struct pci_dev *dev, u32 state, int enable);   /* Enable wake event */
 };
 
 
@@ -547,13 +555,17 @@
 int pci_write_config_word(struct pci_dev *dev, int where, u16 val);
 int pci_write_config_dword(struct pci_dev *dev, int where, u32 val);
 
-#define HAVE_PCI_DISABLE_DEVICE
 int pci_enable_device(struct pci_dev *dev);
 void pci_disable_device(struct pci_dev *dev);
 void pci_set_master(struct pci_dev *dev);
 int pci_set_dma_mask(struct pci_dev *dev, dma_addr_t mask);
-int pci_set_power_state(struct pci_dev *dev, int state);
 int pci_assign_resource(struct pci_dev *dev, int i);
+
+/* Power management related routines */
+int pci_save_state(struct pci_dev *dev, u32 *buffer);
+int pci_restore_state(struct pci_dev *dev, u32 *buffer);
+int pci_set_power_state(struct pci_dev *dev, int state);
+int pci_enable_wake(struct pci_dev *dev, u32 state, int enable);
 
 /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */
 
diff -u --recursive --new-file v2.4.5/linux/include/linux/pci_ids.h linux/include/linux/pci_ids.h
--- v2.4.5/linux/include/linux/pci_ids.h	Wed May 16 10:25:39 2001
+++ linux/include/linux/pci_ids.h	Wed Jun 20 21:00:55 2001
@@ -160,20 +160,37 @@
 #define PCI_DEVICE_ID_NCR_YELLOWFIN	0x0701
 
 #define PCI_VENDOR_ID_ATI		0x1002
+/* Mach64 */
 #define PCI_DEVICE_ID_ATI_68800		0x4158
 #define PCI_DEVICE_ID_ATI_215CT222	0x4354
 #define PCI_DEVICE_ID_ATI_210888CX	0x4358
+#define PCI_DEVICE_ID_ATI_215ET222	0x4554
+/* Mach64 / Rage */
 #define PCI_DEVICE_ID_ATI_215GB		0x4742
 #define PCI_DEVICE_ID_ATI_215GD		0x4744
 #define PCI_DEVICE_ID_ATI_215GI		0x4749
 #define PCI_DEVICE_ID_ATI_215GP		0x4750
 #define PCI_DEVICE_ID_ATI_215GQ		0x4751
+#define PCI_DEVICE_ID_ATI_215XL		0x4752
 #define PCI_DEVICE_ID_ATI_215GT		0x4754
 #define PCI_DEVICE_ID_ATI_215GTB	0x4755
+#define PCI_DEVICE_ID_ATI_215_IV	0x4756
+#define PCI_DEVICE_ID_ATI_215_IW	0x4757
+#define PCI_DEVICE_ID_ATI_215_IZ	0x475A
 #define PCI_DEVICE_ID_ATI_210888GX	0x4758
-#define PCI_DEVICE_ID_ATI_215LG		0x4c47
-#define PCI_DEVICE_ID_ATI_264LT		0x4c54
+#define PCI_DEVICE_ID_ATI_215_LB	0x4c42
+#define PCI_DEVICE_ID_ATI_215_LD	0x4c44
+#define PCI_DEVICE_ID_ATI_215_LG	0x4c47
+#define PCI_DEVICE_ID_ATI_215_LI	0x4c49
+#define PCI_DEVICE_ID_ATI_215_LM	0x4c4D
+#define PCI_DEVICE_ID_ATI_215_LN	0x4c4E
+#define PCI_DEVICE_ID_ATI_215_LR	0x4c52
+#define PCI_DEVICE_ID_ATI_215_LS	0x4c53
+#define PCI_DEVICE_ID_ATI_264_LT	0x4c54
+/* Mach64 VT */
 #define PCI_DEVICE_ID_ATI_264VT		0x5654
+#define PCI_DEVICE_ID_ATI_264VU		0x5655
+#define PCI_DEVICE_ID_ATI_264VV		0x5656
 /* Rage128 Pro GL */
 #define PCI_DEVICE_ID_ATI_Rage128_PA	0x5041
 #define PCI_DEVICE_ID_ATI_Rage128_PB	0x5042
@@ -1135,6 +1152,7 @@
 #define PCI_DEVICE_ID_AVM_B1		0x0700
 #define PCI_DEVICE_ID_AVM_C4		0x0800
 #define PCI_DEVICE_ID_AVM_A1		0x0a00
+#define PCI_DEVICE_ID_AVM_C2		0x1100
 #define PCI_DEVICE_ID_AVM_T1		0x1200
 
 #define PCI_VENDOR_ID_DIPIX		0x1246
@@ -1366,6 +1384,9 @@
 #define PCI_VENDOR_ID_AFAVLAB		0x14db
 #define PCI_DEVICE_ID_AFAVLAB_TK9902	0x2120
 
+#define PCI_VENDOR_ID_BROADCOM		0x14e4
+#define PCI_DEVICE_ID_TIGON3		0x1644
+
 #define PCI_VENDOR_ID_SYBA		0x1592
 #define PCI_DEVICE_ID_SYBA_2P_EPP	0x0782
 #define PCI_DEVICE_ID_SYBA_1P_ECP	0x0783
@@ -1476,13 +1497,18 @@
 #define PCI_DEVICE_ID_INTEL_82801AB_5	0x2425
 #define PCI_DEVICE_ID_INTEL_82801AB_6	0x2426
 #define PCI_DEVICE_ID_INTEL_82801AB_8	0x2428
-#define PCI_DEVICE_ID_INTEL_82820FW_0	0x2440
-#define PCI_DEVICE_ID_INTEL_82820FW_1	0x2442
-#define PCI_DEVICE_ID_INTEL_82820FW_2	0x2443
-#define PCI_DEVICE_ID_INTEL_82820FW_3	0x2444
-#define PCI_DEVICE_ID_INTEL_82820FW_4	0x2449
-#define PCI_DEVICE_ID_INTEL_82820FW_5	0x244b
-#define PCI_DEVICE_ID_INTEL_82820FW_6	0x244e
+#define PCI_DEVICE_ID_INTEL_82801BA_0	0x2440
+#define PCI_DEVICE_ID_INTEL_82801BA_1	0x2442
+#define PCI_DEVICE_ID_INTEL_82801BA_2	0x2443
+#define PCI_DEVICE_ID_INTEL_82801BA_3	0x2444
+#define PCI_DEVICE_ID_INTEL_82801BA_4	0x2445
+#define PCI_DEVICE_ID_INTEL_82801BA_5	0x2446
+#define PCI_DEVICE_ID_INTEL_82801BA_6	0x2448
+#define PCI_DEVICE_ID_INTEL_82801BA_7	0x2449
+#define PCI_DEVICE_ID_INTEL_82801BA_8	0x244a
+#define PCI_DEVICE_ID_INTEL_82801BA_9	0x244b
+#define PCI_DEVICE_ID_INTEL_82801BA_10	0x244c
+#define PCI_DEVICE_ID_INTEL_82801BA_11	0x244e
 #define PCI_DEVICE_ID_INTEL_82810_MC1	0x7120
 #define PCI_DEVICE_ID_INTEL_82810_IG1	0x7121
 #define PCI_DEVICE_ID_INTEL_82810_MC3	0x7122
diff -u --recursive --new-file v2.4.5/linux/include/linux/quotaops.h linux/include/linux/quotaops.h
--- v2.4.5/linux/include/linux/quotaops.h	Fri May 25 18:01:57 2001
+++ linux/include/linux/quotaops.h	Wed Jun 27 16:01:40 2001
@@ -21,7 +21,6 @@
  */
 extern void dquot_initialize(struct inode *inode, short type);
 extern void dquot_drop(struct inode *inode);
-extern void invalidate_dquots(kdev_t dev, short type);
 extern int  quota_off(struct super_block *sb, short type);
 extern int  sync_dquots(kdev_t dev, short type);
 
diff -u --recursive --new-file v2.4.5/linux/include/linux/raid/raid5.h linux/include/linux/raid/raid5.h
--- v2.4.5/linux/include/linux/raid/raid5.h	Thu Feb  8 19:38:38 2001
+++ linux/include/linux/raid/raid5.h	Wed Jun 20 20:55:08 2001
@@ -132,6 +132,7 @@
 	struct buffer_head	*bh_read[MD_SB_DISKS];	/* read request buffers of the MD device */
 	struct buffer_head	*bh_write[MD_SB_DISKS];	/* write request buffers of the MD device */
 	struct buffer_head	*bh_written[MD_SB_DISKS]; /* write request buffers of the MD device that have been scheduled for write */
+	struct page		*bh_page[MD_SB_DISKS];	/* saved bh_cache[n]->b_page when reading around the cache */
 	unsigned long		sector;			/* sector of this row */
 	int			size;			/* buffers size */
 	int			pd_idx;			/* parity disk index */
@@ -157,6 +158,32 @@
 #define STRIPE_HANDLE		2
 #define	STRIPE_SYNCING		3
 #define	STRIPE_INSYNC		4
+#define	STRIPE_PREREAD_ACTIVE	5
+#define	STRIPE_DELAYED		6
+
+/*
+ * Plugging:
+ *
+ * To improve write throughput, we need to delay the handling of some
+ * stripes until there has been a chance that several write requests
+ * for the one stripe have all been collected.
+ * In particular, any write request that would require pre-reading
+ * is put on a "delayed" queue until there are no stripes currently
+ * in a pre-read phase.  Further, if the "delayed" queue is empty when
+ * a stripe is put on it then we "plug" the queue and do not process it
+ * until an unplg call is made. (the tq_disk list is run).
+ *
+ * When preread is initiated on a stripe, we set PREREAD_ACTIVE and add
+ * it to the count of prereading stripes.
+ * When write is initiated, or the stripe refcnt == 0 (just in case) we
+ * clear the PREREAD_ACTIVE flag and decrement the count
+ * Whenever the delayed queue is empty and the device is not plugged, we
+ * move any strips from delayed to handle and clear the DELAYED flag and set PREREAD_ACTIVE.
+ * In stripe_handle, if we find pre-reading is necessary, we do it if
+ * PREREAD_ACTIVE is set, else we set DELAYED which will send it to the delayed queue.
+ * HANDLE gets cleared if stripe_handle leave nothing locked.
+ */
+ 
 
 struct disk_info {
 	kdev_t	dev;
@@ -181,14 +208,21 @@
 	int			max_nr_stripes;
 
 	struct list_head	handle_list; /* stripes needing handling */
+	struct list_head	delayed_list; /* stripes that have plugged requests */
+	atomic_t		preread_active_stripes; /* stripes with scheduled io */
 	/*
 	 * Free stripes pool
 	 */
 	atomic_t		active_stripes;
 	struct list_head	inactive_list;
 	md_wait_queue_head_t	wait_for_stripe;
-
+	int			inactive_blocked;	/* release of inactive stripes blocked,
+							 * waiting for 25% to be free
+							 */        
 	md_spinlock_t		device_lock;
+
+	int			plugged;
+	struct tq_struct	plug_tq;
 };
 
 typedef struct raid5_private_data raid5_conf_t;
diff -u --recursive --new-file v2.4.5/linux/include/linux/reiserfs_fs.h linux/include/linux/reiserfs_fs.h
--- v2.4.5/linux/include/linux/reiserfs_fs.h	Fri Apr 27 14:18:08 2001
+++ linux/include/linux/reiserfs_fs.h	Tue Jun 12 11:12:47 2001
@@ -1806,6 +1806,10 @@
 extern int reiserfs_notify_change(struct dentry * dentry, struct iattr * attr);
 void reiserfs_write_inode (struct inode * inode, int) ;
 
+/* nfsd support functions */
+struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, __u32 *fh, int len, int fhtype, int parent);
+int reiserfs_dentry_to_fh(struct dentry *, __u32 *fh, int *lenp, int need_parent);
+
 /* we don't mark inodes dirty, we just log them */
 void reiserfs_dirty_inode (struct inode * inode) ;
 
diff -u --recursive --new-file v2.4.5/linux/include/linux/slab.h linux/include/linux/slab.h
--- v2.4.5/linux/include/linux/slab.h	Fri May 25 18:01:28 2001
+++ linux/include/linux/slab.h	Wed Jun 27 16:01:22 2001
@@ -22,7 +22,7 @@
 #define	SLAB_NFS		GFP_NFS
 #define	SLAB_DMA		GFP_DMA
 
-#define SLAB_LEVEL_MASK		(__GFP_WAIT|__GFP_HIGH|__GFP_IO)
+#define SLAB_LEVEL_MASK		(__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_BUFFER)
 #define	SLAB_NO_GROW		0x00001000UL	/* don't grow a cache */
 
 /* flags to pass to kmem_cache_create().
diff -u --recursive --new-file v2.4.5/linux/include/linux/smb_fs.h linux/include/linux/smb_fs.h
--- v2.4.5/linux/include/linux/smb_fs.h	Tue May 15 13:40:55 2001
+++ linux/include/linux/smb_fs.h	Wed Jun 20 16:07:57 2001
@@ -93,6 +93,11 @@
 
 #endif /* DEBUG_SMB_MALLOC */
 
+/*
+ * Flags for the in-memory inode
+ */
+#define SMB_F_LOCALWRITE	0x02	/* file modified locally */
+
 
 /* NT1 protocol capability bits */
 #define SMB_CAP_RAW_MODE         0x0001
diff -u --recursive --new-file v2.4.5/linux/include/linux/smb_fs_i.h linux/include/linux/smb_fs_i.h
--- v2.4.5/linux/include/linux/smb_fs_i.h	Fri May 25 18:01:26 2001
+++ linux/include/linux/smb_fs_i.h	Wed Jun 27 16:01:21 2001
@@ -26,6 +26,7 @@
 	__u16 attr;		/* Attribute fields, DOS value */
 
 	__u16 access;		/* Access mode */
+	__u16 flags;
 	unsigned long oldmtime;	/* last time refreshed */
 	unsigned long closed;	/* timestamp when closed */
 	unsigned openers;	/* number of fileid users */
diff -u --recursive --new-file v2.4.5/linux/include/linux/socket.h linux/include/linux/socket.h
--- v2.4.5/linux/include/linux/socket.h	Fri May 25 18:01:26 2001
+++ linux/include/linux/socket.h	Wed Jun 27 16:01:22 2001
@@ -156,6 +156,7 @@
 #define AF_IRDA		23	/* IRDA sockets			*/
 #define AF_PPPOX	24	/* PPPoX sockets		*/
 #define AF_WANPIPE	25	/* Wanpipe API Sockets */
+#define AF_BLUETOOTH	31	/* Bluetooth sockets 		*/
 #define AF_MAX		32	/* For now.. */
 
 /* Protocol families, same as address families. */
@@ -186,6 +187,7 @@
 #define PF_IRDA		AF_IRDA
 #define PF_PPPOX	AF_PPPOX
 #define PF_WANPIPE	AF_WANPIPE
+#define PF_BLUETOOTH	AF_BLUETOOTH
 #define PF_MAX		AF_MAX
 
 /* Maximum queue length specifiable by listen.  */
diff -u --recursive --new-file v2.4.5/linux/include/linux/sockios.h linux/include/linux/sockios.h
--- v2.4.5/linux/include/linux/sockios.h	Sat Nov 11 19:02:40 2000
+++ linux/include/linux/sockios.h	Wed Jun 27 14:15:30 2001
@@ -77,6 +77,10 @@
 
 #define SIOCETHTOOL	0x8946		/* Ethtool interface		*/
 
+#define SIOCGMIIPHY	0x8947		/* Get address of MII PHY in use. */
+#define SIOCGMIIREG	0x8948		/* Read MII PHY register.	*/
+#define SIOCSMIIREG	0x8949		/* Write MII PHY register.	*/
+
 /* ARP cache control calls. */
 		    /*  0x8950 - 0x8952  * obsolete calls, don't re-use */
 #define SIOCDARP	0x8953		/* delete ARP table entry	*/
diff -u --recursive --new-file v2.4.5/linux/include/linux/sunrpc/xprt.h linux/include/linux/sunrpc/xprt.h
--- v2.4.5/linux/include/linux/sunrpc/xprt.h	Fri May 25 18:01:27 2001
+++ linux/include/linux/sunrpc/xprt.h	Wed Jun 27 16:02:08 2001
@@ -138,7 +138,7 @@
 	struct rpc_wait_queue	reconn;		/* waiting for reconnect */
 	struct rpc_rqst *	free;		/* free slots */
 	struct rpc_rqst		slot[RPC_MAXREQS];
-	unsigned int		sockstate;	/* Socket state */
+	unsigned long		sockstate;	/* Socket state */
 	unsigned char		shutdown   : 1,	/* being shut down */
 				nocong	   : 1,	/* no congestion control */
 				stream     : 1,	/* TCP */
diff -u --recursive --new-file v2.4.5/linux/include/linux/swap.h linux/include/linux/swap.h
--- v2.4.5/linux/include/linux/swap.h	Fri May 25 18:01:27 2001
+++ linux/include/linux/swap.h	Wed Jun 27 16:01:22 2001
@@ -133,6 +133,7 @@
 extern void __delete_from_swap_cache(struct page *page);
 extern void delete_from_swap_cache(struct page *page);
 extern void delete_from_swap_cache_nolock(struct page *page);
+extern void free_page_and_swap_cache(struct page *page);
 
 /* linux/mm/swapfile.c */
 extern unsigned int nr_swapfiles;
@@ -200,6 +201,16 @@
 	ZERO_PAGE_BUG \
 	SetPageInactiveDirty(page); \
 	list_add(&(page)->lru, &inactive_dirty_list); \
+	nr_inactive_dirty_pages++; \
+	page->zone->inactive_dirty_pages++; \
+}
+
+/* Like the above, but add us after the bookmark. */
+#define add_page_to_inactive_dirty_list_marker(page) { \
+	DEBUG_ADD_PAGE \
+	ZERO_PAGE_BUG \
+	SetPageInactiveDirty(page); \
+	list_add(&(page)->lru, marker_lru); \
 	nr_inactive_dirty_pages++; \
 	page->zone->inactive_dirty_pages++; \
 }
diff -u --recursive --new-file v2.4.5/linux/include/linux/udf_167.h linux/include/linux/udf_167.h
--- v2.4.5/linux/include/linux/udf_167.h	Mon Dec 11 13:27:05 2000
+++ linux/include/linux/udf_167.h	Mon Jun 11 19:15:27 2001
@@ -31,7 +31,7 @@
  * CONTACTS
  *	E-mail regarding any portion of the Linux UDF file system should be
  *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hootie.lvld.hp.com
+ *		linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
diff -u --recursive --new-file v2.4.5/linux/include/linux/udf_fs.h linux/include/linux/udf_fs.h
--- v2.4.5/linux/include/linux/udf_fs.h	Mon Jan  1 09:57:08 2001
+++ linux/include/linux/udf_fs.h	Mon Jun 11 19:15:27 2001
@@ -16,7 +16,7 @@
  * CONTACTS
  *	E-mail regarding any portion of the Linux UDF file system should be
  *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hootie.lvld.hp.com
+ *		linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
@@ -35,10 +35,20 @@
 #define _LINUX_UDF_FS_H
 
 #define UDF_PREALLOCATE
-#define UDF_DEFAULT_PREALLOC_BLOCKS		8
+#define UDF_DEFAULT_PREALLOC_BLOCKS	8
 
-#define UDFFS_DATE		"2000/02/29"
-#define UDFFS_VERSION	"0.9.1"
+#define UDFFS_DATE			"2001/06/06"
+#define UDFFS_VERSION			"0.9.4"
+
+#if !defined(UDFFS_RW)
+
+#if defined(CONFIG_UDF_RW)
+#define UDFFS_RW			1
+#else /* !defined(CONFIG_UDF_RW) */
+#define UDFFS_RW			0
+#endif /* defined(CONFIG_UDF_RW) */
+
+#endif /* !defined(UDFFS_RW) */
 
 #define UDFFS_DEBUG
 
diff -u --recursive --new-file v2.4.5/linux/include/linux/udf_fs_i.h linux/include/linux/udf_fs_i.h
--- v2.4.5/linux/include/linux/udf_fs_i.h	Thu Mar  2 11:17:32 2000
+++ linux/include/linux/udf_fs_i.h	Mon Jun 11 19:15:27 2001
@@ -6,7 +6,7 @@
  * CONTACTS
  *	E-mail regarding any portion of the Linux UDF file system should be
  *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hootie.lvld.hp.com
+ *		linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
@@ -38,6 +38,7 @@
 	__u64 i_unique;
 	__u32 i_lenEAttr;
 	__u32 i_lenAlloc;
+	__u64 i_lenExtents;
 	__u32 i_next_alloc_block;
 	__u32 i_next_alloc_goal;
 	unsigned i_alloc_type : 3;
@@ -54,5 +55,6 @@
 #define UDF_GETEASIZE   _IOR('l', 0x40, int)
 #define UDF_GETEABLOCK  _IOR('l', 0x41, void *)
 #define UDF_GETVOLIDENT _IOR('l', 0x42, void *)
+#define UDF_RELOCATE_BLOCKS _IOWR('l', 0x43, long)
 
 #endif /* !defined(_LINUX_UDF_FS_I_H) */
diff -u --recursive --new-file v2.4.5/linux/include/linux/udf_fs_sb.h linux/include/linux/udf_fs_sb.h
--- v2.4.5/linux/include/linux/udf_fs_sb.h	Mon Mar 20 08:17:43 2000
+++ linux/include/linux/udf_fs_sb.h	Wed Jun 27 16:01:20 2001
@@ -6,7 +6,7 @@
  * CONTACTS
  *	E-mail regarding any portion of the Linux UDF file system should be
  *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hootie.lvld.hp.com
+ *		linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
@@ -18,6 +18,10 @@
 #if !defined(_LINUX_UDF_FS_SB_H)
 #define _LINUX_UDF_FS_SB_H
 
+#ifndef LINUX_VERSION_CODE
+#include <linux/version.h>
+#endif
+
 #pragma pack(1)
 
 #define UDF_MAX_BLOCK_LOADED	8
@@ -29,16 +33,8 @@
 
 struct udf_sparing_data
 {
-	__u32	s_spar_loc[4];
-	__u8	s_spar_pshift;
-	__u8	s_spar_indexsize;
-	__u32	*s_spar_map;
-	union
-	{
-		__u8	*s_spar_remap8;
-		__u16	*s_spar_remap16;
-		__u32	*s_spar_remap32;
-	} s_spar_remap;
+	__u16	s_packet_len;
+	struct buffer_head *s_spar_map[4];
 };
 
 struct udf_virtual_data
@@ -47,18 +43,26 @@
 	__u16	s_start_offset;
 };
 
+struct udf_bitmap
+{
+	__u32			s_extLength;
+	__u32			s_extPosition;
+	__u16			s_nr_groups;
+	struct buffer_head 	**s_block_bitmap;
+};
+
 struct udf_part_map
 {
 	union
 	{
-		__u32			bitmap;
-		struct inode	*table;
-	}		s_uspace;
+		struct udf_bitmap	*s_bitmap;
+		struct inode		*s_table;
+	} s_uspace;
 	union
 	{
-		__u32			bitmap;
-		struct inode	*table;
-	}		s_fspace;
+		struct udf_bitmap	*s_bitmap;
+		struct inode		*s_table;
+	} s_fspace;
 	__u32	s_partition_root;
 	__u32	s_partition_len;
 	__u16	s_partition_type;
@@ -77,43 +81,42 @@
 
 struct udf_sb_info
 {
-	struct udf_part_map *s_partmaps;
-	__u8  s_volident[32];
+	struct udf_part_map	*s_partmaps;
+	__u8			s_volident[32];
 
 	/* Overall info */
-	__u16 s_partitions;
-	__u16 s_partition;
+	__u16			s_partitions;
+	__u16			s_partition;
 
 	/* Sector headers */
-	__u32 s_session;
-	__u32 s_anchor[4];
-	__u32 s_lastblock;
-
-	struct buffer_head *s_lvidbh;
-
-	__u16 s_loaded_block_bitmaps;
-	__u32 s_block_bitmap_number[UDF_MAX_BLOCK_LOADED];
-	struct buffer_head *s_block_bitmap[UDF_MAX_BLOCK_LOADED];
+	__u32			s_session;
+	__u32			s_anchor[4];
+	__u32			s_lastblock;
+
+	struct buffer_head	*s_lvidbh;
 
 	/* Default permissions */
-	mode_t s_umask;
-	gid_t s_gid;
-	uid_t s_uid;
+	mode_t			s_umask;
+	gid_t			s_gid;
+	uid_t			s_uid;
 
 	/* Root Info */
-	time_t s_recordtime;
+	time_t			s_recordtime;
 
 	/* Fileset Info */
-	__u16 s_serialnum;
+	__u16			s_serialnum;
 
 	/* highest UDF revision we have recorded to this media */
-	__u16 s_udfrev;
+	__u16			s_udfrev;
 
 	/* Miscellaneous flags */
-	__u32 s_flags;
+	__u32			s_flags;
+
+	/* Encoding info */
+	struct nls_table	*s_nls_map;
 
 	/* VAT inode */
-	struct inode    *s_vat;
+	struct inode		*s_vat;
 };
 
 #endif /* !defined(_LINUX_UDF_FS_SB_H) */
diff -u --recursive --new-file v2.4.5/linux/include/linux/udf_udf.h linux/include/linux/udf_udf.h
--- v2.4.5/linux/include/linux/udf_udf.h	Mon Dec 11 13:27:05 2000
+++ linux/include/linux/udf_udf.h	Mon Jun 11 19:15:27 2001
@@ -10,7 +10,7 @@
  * CONTACTS
  *	E-mail regarding any portion of the Linux UDF file system should be
  *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hootie.lvld.hp.com
+ *		linux_udf@hpesjro.fc.hp.com
  *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
diff -u --recursive --new-file v2.4.5/linux/include/net/bluetooth/bluetooth.h linux/include/net/bluetooth/bluetooth.h
--- v2.4.5/linux/include/net/bluetooth/bluetooth.h	Wed Dec 31 16:00:00 1969
+++ linux/include/net/bluetooth/bluetooth.h	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,82 @@
+/* 
+   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: bluetooth.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ */
+
+#ifndef __IF_BLUETOOTH_H
+#define __IF_BLUETOOTH_H
+
+#include <asm/types.h>
+#include <asm/byteorder.h>
+
+#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 */
+	BT_OPEN,
+	BT_BOUND,
+	BT_LISTEN,
+	BT_CONNECT,
+	BT_CONFIG,
+	BT_DISCONN,
+	BT_CLOSED
+};
+
+/* Copy, swap, convert BD Address */
+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)
+{
+	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)
+
+int bterr(__u16 code);
+
+#endif /* __IF_BLUETOOTH_H */
diff -u --recursive --new-file v2.4.5/linux/include/net/bluetooth/bluez.h linux/include/net/bluetooth/bluez.h
--- v2.4.5/linux/include/net/bluetooth/bluez.h	Wed Dec 31 16:00:00 1969
+++ linux/include/net/bluetooth/bluez.h	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,176 @@
+/* 
+   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: bluez.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ */
+
+#ifndef __IF_BLUEZ_H
+#define __IF_BLUEZ_H
+
+#include <net/sock.h>
+
+#define BLUEZ_VER "1.0"
+
+#define BLUEZ_MAX_PROTO 	2
+
+/* Reserv for core and drivers use */
+#define BLUEZ_SKB_RESERVE	8
+
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+/* Debugging */
+#ifdef BLUEZ_DEBUG
+
+#define HCI_CORE_DEBUG		1
+#define HCI_SOCK_DEBUG		1
+#define HCI_UART_DEBUG		1
+#define HCI_USB_DEBUG		1
+//#define HCI_DATA_DUMP		1
+
+#define L2CAP_DEBUG			1
+
+#endif /* BLUEZ_DEBUG */
+
+extern void bluez_dump(char *pref, __u8 *buf, int count);
+
+#define INF(fmt, arg...) printk(KERN_INFO fmt "\n" , ## arg)
+#define DBG(fmt, arg...) printk(KERN_INFO __FUNCTION__ ": " fmt "\n" , ## arg)
+#define ERR(fmt, arg...) printk(KERN_ERR  __FUNCTION__ ": " fmt "\n" , ## arg)
+
+#ifdef HCI_DATA_DUMP
+#define DMP(buf, len)    bluez_dump(__FUNCTION__, buf, len)
+#else
+#define DMP(D...)
+#endif
+
+/* ----- Sockets ------ */
+struct bluez_sock_list {
+	struct sock *head;
+	rwlock_t     lock;
+};
+
+extern int  bluez_sock_register(int proto, struct net_proto_family *ops);
+extern int  bluez_sock_unregister(int proto);
+
+extern void bluez_sock_link(struct bluez_sock_list *l, struct sock *s);
+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;
+};
+#define bluez_cb(skb)	((struct bluez_skb_cb *)(skb->cb)) 
+
+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);
+	}
+	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, 
+						       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);
+	}
+
+	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)
+{
+	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;
+
+	while((skb = skb_dequeue(q)))
+		bluez_skb_free(skb);
+}
+
+extern int hci_core_init(void);
+extern int hci_core_cleanup(void);
+extern int hci_sock_init(void);
+extern int hci_sock_cleanup(void);
+
+#endif /* __IF_BLUEZ_H */
diff -u --recursive --new-file v2.4.5/linux/include/net/bluetooth/hci.h linux/include/net/bluetooth/hci.h
--- v2.4.5/linux/include/net/bluetooth/hci.h	Wed Dec 31 16:00:00 1969
+++ linux/include/net/bluetooth/hci.h	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,370 @@
+/* 
+   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.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ */
+
+#ifndef __IF_HCI_H
+#define __IF_HCI_H
+
+#include <asm/byteorder.h>
+
+/* HCI Packet types */
+#define HCI_COMMAND_PKT		0x01
+#define HCI_ACLDATA_PKT 	0x02
+#define HCI_SCODATA_PKT 	0x03
+#define HCI_EVENT_PKT		0x04
+#define HCI_UNKNOWN_PKT		0xff
+
+/* -----  HCI Commands ----- */
+/* OGF & OCF values */
+
+/* Informational Parameters */
+#define OGF_INFO_PARAM	0x04
+#define OCF_NOP			0x0000
+
+#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;
+
+#define OCF_READ_BD_ADDR		0x0009
+typedef struct {
+	__u8 status;
+	bdaddr_t bdaddr;
+} __attribute__ ((packed))		read_bd_addr_rp;
+
+/* Host Controller and Baseband */
+#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_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 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
+
+/* Filter types */
+#define FLT_CLEAR_ALL	0x00
+#define FLT_INQ_RESULT	0x01
+#define FLT_CONN_SETUP	0x02
+
+/* CONN_SETUP Condition types */
+#define CONN_SETUP_ALLOW_ALL	0x00
+#define CONN_SETUP_ALLOW_CLASS	0x01
+#define CONN_SETUP_ALLOW_BDADDR	0x02
+
+/* CONN_SETUP Conditions */
+#define CONN_SETUP_AUTO_OFF	0x01
+#define CONN_SETUP_AUTO_ON		0x02
+
+/* Link Control */
+#define OGF_LINK_CTL	0x01 
+#define OCF_CREATE_CONN	0x0005
+typedef struct {
+	bdaddr_t bdaddr;
+	__u16 	pkt_type;
+	__u8 	pscan_rep_mode;
+	__u8 	pscan_mode;
+	__u16 	clock_offset;
+	__u8 	role_switch;
+} __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
+
+#define OCF_DISCONNECT	0x0006
+typedef struct {
+	__u16 	handle;
+	__u8 	reason;
+} __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
+
+#define OGF_LINK_POLICY	 	0x02   /* Link Policy */
+
+/* --------- HCI Events --------- */
+#define EVT_INQUIRY_COMPLETE 	0x01
+
+#define EVT_INQUIRY_RESULT 	0x02
+typedef struct {
+	bdaddr_t	bdaddr;
+	__u8	pscan_rep_mode;
+	__u8	pscan_period_mode;
+	__u8	pscan_mode;
+	__u8	class[3];
+	__u16	clock_offset;
+} __attribute__ ((packed))		inquiry_info;
+#define INQUIRY_INFO_SIZE 	14
+
+#define EVT_CONN_COMPLETE 	0x03
+typedef struct {
+	__u8	status;
+	__u16	handle;
+	bdaddr_t	bdaddr;
+	__u8	link_type;
+	__u8	encr_mode;
+} __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
+
+#define EVT_DISCONN_COMPLETE	0x05
+typedef struct {
+	__u8 	status;
+	__u16 	handle;
+	__u8 	reason;
+} __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
+
+#define EVT_CMD_STATUS 		0x0f
+typedef struct {
+	__u8 	status;
+	__u8 	ncmd;
+	__u16 	opcode;
+} __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
+
+#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
+
+/* --------  HCI Packet structures  -------- */
+#define HCI_TYPE_LEN	1
+
+typedef struct {
+	__u16 	opcode;		/* OCF & OGF */
+	__u8 	plen;
+} __attribute__ ((packed))	hci_command_hdr;
+#define HCI_COMMAND_HDR_SIZE 	3
+
+typedef struct {
+	__u8 	evt;
+	__u8 	plen;
+} __attribute__ ((packed))	hci_event_hdr;
+#define HCI_EVENT_HDR_SIZE 	2
+
+typedef struct {
+	__u16 	handle;		/* Handle & Flags(PB, BC) */
+	__u16 	dlen;
+} __attribute__ ((packed))	hci_acl_hdr;
+#define HCI_ACL_HDR_SIZE 	4
+
+typedef struct {
+	__u16 	handle;
+	__u8 	dlen;
+} __attribute__ ((packed))	hci_sco_hdr;
+#define HCI_SCO_HDR_SIZE 	3
+
+/* Command opcode pack/unpack */
+#define cmd_opcode_pack(ocf, ogf)	(__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
+
+/* 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)
+
+/* HCI Socket options */
+#define HCI_DATA_DIR	0x0001
+#define HCI_FILTER	0x0002
+
+/* HCI CMSG types */
+#define HCI_CMSG_DIR	0x0001
+
+struct sockaddr_hci {
+	sa_family_t	    hci_family;
+	unsigned short  hci_dev;
+};
+#define HCI_DEV_NONE	0xffff
+
+struct hci_dev_req {
+	__u16 dev_id;
+	__u32 dev_opt;
+};
+
+struct hci_dev_list_req {
+	__u16  dev_num;
+	struct hci_dev_req dev_req[0];	/* hci_dev_req structures */
+};
+
+struct hci_inquiry_req {
+	__u16 dev_id;
+	__u16 flags;
+	__u8  lap[3];
+	__u8  length;
+	__u8  num_rsp;
+};
+#define IREQ_CACHE_FLUSH 0x0001
+
+struct hci_dev_stats {
+	__u32 err_rx;
+	__u32 err_tx;
+	__u32 cmd_tx;
+	__u32 evt_rx;
+	__u32 acl_tx;
+	__u32 acl_rx;
+	__u32 sco_tx;
+	__u32 sco_rx;
+	__u32 byte_rx;
+	__u32 byte_tx;
+};
+
+struct hci_dev_info {
+	__u16 dev_id;
+	char  name[8];
+
+	__u32 flags;
+	__u8  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
+
+/* HCI dev events */
+#define HCI_DEV_REG	1
+#define HCI_DEV_UNREG   2
+#define HCI_DEV_UP	3
+#define HCI_DEV_DOWN	4
+
+#endif /* __IF_HCI_H */
diff -u --recursive --new-file v2.4.5/linux/include/net/bluetooth/hci_core.h linux/include/net/bluetooth/hci_core.h
--- v2.4.5/linux/include/net/bluetooth/hci_core.h	Wed Dec 31 16:00:00 1969
+++ linux/include/net/bluetooth/hci_core.h	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,343 @@
+/* 
+   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_core.h,v 1.1 2001/06/01 08:12:11 davem Exp $ 
+ */
+
+#ifndef __IF_HCI_CORE_H
+#define __IF_HCI_CORE_H
+
+#include "hci.h"
+
+/* HCI upper protocols */
+#define HCI_MAX_PROTO 	1
+#define HCI_PROTO_L2CAP	0
+
+#define HCI_INIT_TIMEOUT (HZ * 10)
+
+/* ----- Inquiry cache ----- */
+#define INQUIRY_CACHE_AGE_MAX   (HZ*5)    // 5 seconds
+#define INQUIRY_ENTRY_AGE_MAX   (HZ*60)   // 60 seconds
+
+struct inquiry_entry {
+	struct inquiry_entry 	*next;
+	__u32			timestamp;
+	inquiry_info		info;
+};
+
+struct inquiry_cache {
+	spinlock_t 		lock;
+	__u32			timestamp;
+	struct inquiry_entry 	*list;
+};
+
+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)
+{
+	spin_lock(&cache->lock);
+}
+
+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)
+{
+	spin_lock_bh(&cache->lock);
+}
+
+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)
+{
+	return jiffies - cache->timestamp;
+}
+
+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
+
+/* 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];
+};
+
+static __inline__ void conn_hash_init(struct conn_hash *h)
+{
+	memset(h, 0, sizeof(struct conn_hash));
+	spin_lock_init(&h->lock);
+}
+
+static __inline__ void conn_hash_lock(struct conn_hash *h)
+{
+	spin_lock(&h->lock);
+}
+
+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)
+{
+	if (!h->conn[handle]) {
+		h->conn[handle] = conn;
+		h->num++;
+		return conn;
+	} else
+		return NULL;
+}
+
+static __inline__ void *conn_hash_add(struct conn_hash *h, __u16 handle, void *conn)
+{
+	if (handle >= HCI_MAX_CONN)
+		return NULL;
+
+	conn_hash_lock(h);
+	conn = __conn_hash_add(h, handle, conn);
+	conn_hash_unlock(h);
+
+	return conn;
+}
+
+static __inline__ void *__conn_hash_del(struct conn_hash *h, __u16 handle)
+{
+	void *conn = h->conn[handle];
+
+	if (conn) {
+		h->conn[handle] = NULL;
+		h->num--;
+		return conn;
+	} else
+		return NULL;
+}
+
+static __inline__ void *conn_hash_del(struct conn_hash *h, __u16 handle)
+{
+	void *conn;
+
+	if (handle >= HCI_MAX_CONN)
+		return NULL;
+	conn_hash_lock(h);
+	conn = __conn_hash_del(h, handle); 
+	conn_hash_unlock(h);
+
+	return conn;
+}
+
+static __inline__ void *__conn_hash_lookup(struct conn_hash *h, __u16 handle)
+{
+	return h->conn[handle];
+}
+
+static __inline__ void *conn_hash_lookup(struct conn_hash *h, __u16 handle)
+{
+	void *conn;
+
+	if (handle >= HCI_MAX_CONN)
+		return NULL;
+
+	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;
+
+	char		name[8];
+	__u32	 	flags;
+	__u16		id;
+	__u8	 	type;
+	bdaddr_t	bdaddr;
+
+	atomic_t 	cmd_cnt;
+	unsigned int 	acl_cnt;
+	unsigned int 	sco_cnt;
+
+	unsigned int	acl_mtu;
+	unsigned int 	sco_mtu;
+	unsigned int	acl_max;
+	unsigned int	sco_max;
+
+	void		*driver_data;
+	void		*l2cap_data;
+	void		*priv;
+
+	struct tasklet_struct 	cmd_task;
+	struct tasklet_struct	rx_task;
+	struct tasklet_struct 	tx_task;
+
+	struct sk_buff_head	rx_q;
+	struct sk_buff_head 	raw_q;
+	struct sk_buff_head 	cmd_q;
+	struct sk_buff     	*cmd_sent;
+
+	struct semaphore	req_lock;
+	wait_queue_head_t	req_wait_q;
+	__u32			req_status;
+	__u32			req_result;
+
+	struct inquiry_cache 	inq_cache;
+
+	struct conn_hash 	conn_hash;
+
+	struct hci_dev_stats 	stat;
+
+	int (*open)(struct hci_dev *hdev);
+	int (*close)(struct hci_dev *hdev);
+	int (*flush)(struct hci_dev *hdev);
+	int (*send)(struct sk_buff *skb);
+};
+
+static __inline__ void hci_dev_hold(struct hci_dev *hdev)
+{
+	atomic_inc(&hdev->refcnt);
+}
+
+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);
+extern int hci_dev_close(__u16 dev);
+extern int hci_dev_reset(__u16 dev);
+extern int hci_dev_reset_stat(__u16 dev);
+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_inquiry(unsigned long arg);
+
+extern __u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode);
+extern __u32 hci_dev_getmode(struct hci_dev *hdev);
+
+extern int hci_recv_frame(struct sk_buff *skb);
+
+/* ----- HCI tasks ----- */
+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)
+{
+	tasklet_schedule(&hdev->rx_task);
+}
+
+static __inline__ void hci_sched_tx(struct hci_dev *hdev)
+{
+	tasklet_schedule(&hdev->tx_task);
+}
+
+/* ----- HCI protocols ----- */
+struct hci_proto {
+	char 		*name;
+	__u32		id;
+	__u32		flags;
+
+	void		*priv;
+
+	int (*connect_ind) 	(struct hci_dev *hdev, bdaddr_t *bdaddr);
+	int (*connect_cfm)	(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 status, struct hci_conn *conn);
+	int (*disconn_ind)	(struct hci_conn *conn, __u8 reason);
+	int (*recv_acldata)	(struct hci_conn *conn, struct sk_buff *skb , __u16 flags);
+	int (*recv_scodata)	(struct hci_conn *conn, struct sk_buff *skb);
+};
+
+extern int hci_register_proto(struct hci_proto *hproto);
+extern int hci_unregister_proto(struct hci_proto *hproto);
+extern int hci_register_notifier(struct notifier_block *nb);
+extern int hci_unregister_notifier(struct notifier_block *nb);
+extern int hci_connect(struct hci_dev * hdev, bdaddr_t * bdaddr);
+extern int hci_disconnect(struct hci_conn *conn, __u8 reason);
+extern int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void * param);
+extern int hci_send_raw(struct sk_buff *skb);
+extern int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
+extern int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
+
+/* ----- HCI Sockets ----- */
+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;
+};
+
+/* ----- HCI requests ----- */
+#define HCI_REQ_DONE	  0
+#define HCI_REQ_PEND	  1
+#define HCI_REQ_CANCELED  2
+
+#endif /* __IF_HCI_CORE_H */
diff -u --recursive --new-file v2.4.5/linux/include/net/bluetooth/hci_emu.h linux/include/net/bluetooth/hci_emu.h
--- v2.4.5/linux/include/net/bluetooth/hci_emu.h	Wed Dec 31 16:00:00 1969
+++ linux/include/net/bluetooth/hci_emu.h	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,52 @@
+/* 
+   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 */
diff -u --recursive --new-file v2.4.5/linux/include/net/bluetooth/hci_uart.h linux/include/net/bluetooth/hci_uart.h
--- v2.4.5/linux/include/net/bluetooth/hci_uart.h	Wed Dec 31 16:00:00 1969
+++ linux/include/net/bluetooth/hci_uart.h	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,60 @@
+/* 
+   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_uart.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ */
+
+#define HCI_MAX_READ 2048
+
+#ifdef __KERNEL__
+
+#define tty2n_hci(tty)  ((struct n_hci *)((tty)->disc_data))
+#define n_hci2tty(n_hci) ((n_hci)->tty)
+
+struct n_hci {
+	struct tty_struct *tty;
+	struct hci_dev hdev;
+
+	struct sk_buff_head txq;
+	unsigned long tx_state;
+
+	spinlock_t rx_lock;
+	unsigned long rx_state;
+	unsigned long rx_count;
+	struct sk_buff *rx_skb;
+};
+
+/* Transmit states  */
+#define TRANS_SENDING		1
+#define TRANS_WAKEUP		2
+
+/* Receiver States */
+#define WAIT_PACKET_TYPE	0
+#define WAIT_EVENT_HDR	 	1
+#define WAIT_ACL_HDR		2
+#define WAIT_SCO_HDR		3
+#define WAIT_DATA	        4
+
+#endif /* __KERNEL__ */
diff -u --recursive --new-file v2.4.5/linux/include/net/bluetooth/hci_usb.h linux/include/net/bluetooth/hci_usb.h
--- v2.4.5/linux/include/net/bluetooth/hci_usb.h	Wed Dec 31 16:00:00 1969
+++ linux/include/net/bluetooth/hci_usb.h	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,70 @@
+/* 
+   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_usb.h,v 1.1 2001/06/01 08:12:11 davem 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 */
+#define HCI_DEV_PROTOCOL     0x01	/* Bluetooth programming protocol */
+
+#define HCI_CTRL_REQ	     0x20
+
+struct hci_usb {
+	struct usb_device 	*udev;
+
+	devrequest		dev_req;
+	struct urb 		*ctrl_urb;
+	struct urb		*intr_urb;
+	struct urb		*read_urb;
+	struct urb		*write_urb;
+
+	__u8			*read_buf;
+	__u8			*intr_buf;
+	struct sk_buff		*intr_skb;
+	int			intr_count;
+
+	__u8			bulk_out_ep_addr;
+	__u8			bulk_in_ep_addr;
+	__u8			intr_in_ep_addr;
+	__u8			intr_in_interval;
+
+	struct hci_dev		hdev;
+
+	unsigned long		tx_state;
+	struct sk_buff_head	tx_ctrl_q;
+	struct sk_buff_head	tx_write_q;
+};
+
+/* Transmit states  */
+#define HCI_TX_CTRL	1
+#define HCI_TX_WRITE	2
+
+#endif /* __KERNEL__ */
diff -u --recursive --new-file v2.4.5/linux/include/net/bluetooth/l2cap.h linux/include/net/bluetooth/l2cap.h
--- v2.4.5/linux/include/net/bluetooth/l2cap.h	Wed Dec 31 16:00:00 1969
+++ linux/include/net/bluetooth/l2cap.h	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,155 @@
+/* 
+   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: l2cap.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ */
+
+#ifndef __L2CAP_H
+#define __L2CAP_H
+
+#include <asm/types.h>
+#include <asm/byteorder.h>
+
+/* L2CAP socket address */
+struct sockaddr_l2 {
+	sa_family_t	l2_family;
+	unsigned short	l2_psm;
+	bdaddr_t	l2_bdaddr;
+};
+
+/* set/get sockopt defines */
+#define L2CAP_OPTIONS  0x01
+struct l2cap_options {
+	__u16 omtu;
+	__u16 imtu;
+	__u16 flush_to;
+	__u32 token_rate;
+	__u32 bucket_size;
+	__u32 pick_band;
+	__u32 latency;
+	__u32 delay_var;
+};
+
+/* L2CAP defaults */
+#define L2CAP_DEFAULT_MTU 	672
+#define L2CAP_DEFAULT_FLUSH_TO	0xFFFF
+
+#define L2CAP_CONN_TIMEOUT 	(HZ * 40)
+
+/* L2CAP command codes */
+#define L2CAP_COMMAND_REJ 0x01
+#define L2CAP_CONN_REQ    0x02
+#define L2CAP_CONN_RSP    0x03
+#define L2CAP_CONF_REQ    0x04
+#define L2CAP_CONF_RSP    0x05
+#define L2CAP_DISCONN_REQ 0x06
+#define L2CAP_DISCONN_RSP 0x07
+#define L2CAP_ECHO_REQ    0x08
+#define L2CAP_ECHO_RSP    0x09
+#define L2CAP_INFO_REQ    0x0a
+#define L2CAP_INFO_RSP    0x0b
+
+/* L2CAP structures */
+
+typedef struct {
+	__u16      len;
+	__u16      cid;
+} __attribute__ ((packed)) 	l2cap_hdr;
+#define L2CAP_HDR_SIZE		4
+
+typedef struct {
+	__u8       code;
+	__u8       ident;
+	__u16      len;
+} __attribute__ ((packed))	l2cap_cmd_hdr;
+#define L2CAP_CMD_HDR_SIZE	4
+
+typedef struct {
+	__u16      reason;
+} __attribute__ ((packed))	l2cap_cmd_rej;
+#define L2CAP_CMD_REJ_SIZE	2
+
+typedef struct {
+	__u16      psm;
+	__u16      scid;
+} __attribute__ ((packed))	l2cap_conn_req;
+#define L2CAP_CONN_REQ_SIZE	4
+
+typedef struct {
+	__u16      dcid;
+	__u16      scid;
+	__u16      result;
+	__u16      status;
+} __attribute__ ((packed))	l2cap_conn_rsp;
+#define L2CAP_CONN_RSP_SIZE	8
+
+#define L2CAP_CONN_SUCCESS    0x0000
+#define L2CAP_CONN_PEND       0x0001
+#define L2CAP_CONN_BAD_PSM    0x0002
+#define L2CAP_CONN_SEC_BLOCK  0x0003
+#define L2CAP_CONN_NO_MEM     0x0004
+
+typedef struct {
+	__u16      dcid;
+	__u16      flags;
+	__u8       data[0];
+} __attribute__ ((packed))	l2cap_conf_req;
+#define L2CAP_CONF_REQ_SIZE	4
+
+typedef struct {
+	__u16      scid;
+	__u16      flags;
+	__u16      result;
+	__u8       data[0];
+} __attribute__ ((packed))	l2cap_conf_rsp;
+#define L2CAP_CONF_RSP_SIZE   	6
+
+#define L2CAP_CONF_SUCCESS	0x00
+#define L2CAP_CONF_UNACCEPT	0x01
+
+typedef struct {
+	__u8       type;
+	__u8       len;
+	__u8       val[0];
+} __attribute__ ((packed))	l2cap_conf_opt;
+#define L2CAP_CONF_OPT_SIZE	2
+
+#define L2CAP_CONF_MTU		0x01
+#define L2CAP_CONF_FLUSH_TO	0x02
+#define L2CAP_CONF_QOS		0x03
+
+typedef struct {
+	__u16      dcid;
+	__u16      scid;
+} __attribute__ ((packed)) 	l2cap_disconn_req;
+#define L2CAP_DISCONN_REQ_SIZE	4
+
+typedef struct {
+	__u16      dcid;
+	__u16      scid;
+} __attribute__ ((packed)) 	l2cap_disconn_rsp;
+#define L2CAP_DISCONN_RSP_SIZE	4
+
+#endif /* __L2CAP_H */
diff -u --recursive --new-file v2.4.5/linux/include/net/bluetooth/l2cap_core.h linux/include/net/bluetooth/l2cap_core.h
--- v2.4.5/linux/include/net/bluetooth/l2cap_core.h	Wed Dec 31 16:00:00 1969
+++ linux/include/net/bluetooth/l2cap_core.h	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,142 @@
+/* 
+   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: l2cap_core.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ */
+
+#ifndef __L2CAP_CORE_H
+#define __L2CAP_CORE_H
+
+#ifdef __KERNEL__
+
+/* ----- L2CAP interface ----- */
+struct l2cap_iff {
+	struct list_head list;
+	struct hci_dev   *hdev;
+	bdaddr_t         *bdaddr;
+	__u16            mtu;
+	spinlock_t       lock;
+	struct list_head conn_list;
+};
+
+static __inline__ void l2cap_iff_lock(struct l2cap_iff *iff)
+{
+	spin_lock(&iff->lock);
+}
+
+static __inline__ void l2cap_iff_unlock(struct l2cap_iff *iff)
+{
+	spin_unlock(&iff->lock);
+}
+
+/* ----- L2CAP connections ----- */
+struct l2cap_chan_list {
+	struct sock	*head;
+	rwlock_t	lock;
+	long		num;
+};
+
+struct l2cap_conn {
+	struct l2cap_iff *iff;
+	struct list_head list;
+
+	struct hci_conn	 *hconn;
+
+	__u16		state;
+	__u8		out;
+	bdaddr_t	src;
+	bdaddr_t	dst;
+
+	spinlock_t	lock;
+	atomic_t	refcnt;
+
+	struct sk_buff *rx_skb;
+	__u32		rx_len;
+	__u8		rx_ident;
+	__u8		tx_ident;
+
+	struct l2cap_chan_list chan_list;
+};
+
+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)
+{
+	list_del(&c->list);
+}
+
+/* ----- L2CAP channel and socket info ----- */
+#define l2cap_pi(sk)   ((struct l2cap_pinfo *) &sk->protinfo)
+
+struct l2cap_accept_q {
+	struct sock 	*head;
+	struct sock 	*tail;
+};
+
+struct l2cap_pinfo {
+	bdaddr_t	src;
+	bdaddr_t	dst;
+	__u16		psm;
+	__u16		dcid;
+	__u16		scid;
+	__u32		flags;
+
+	__u16		imtu;
+	__u16		omtu;
+	__u16		flush_to;
+
+	__u8		conf_state;
+	__u16		conf_mtu;
+
+	__u8		ident;
+
+	struct l2cap_conn 	*conn;
+	struct sock 		*next_c;
+	struct sock 		*prev_c;
+
+	struct sock *parent;
+	struct sock *next_q;
+	struct sock *prev_q;
+
+	struct l2cap_accept_q accept_q;
+};
+
+#define CONF_INPUT  0x01
+#define CONF_OUTPUT 0x02
+#define CONF_DONE	(CONF_INPUT | CONF_OUTPUT)
+
+extern struct bluez_sock_list l2cap_sk_list;
+extern struct list_head  l2cap_iff_list;
+extern rwlock_t l2cap_rt_lock;
+
+extern void l2cap_register_proc(void);
+extern void l2cap_unregister_proc(void);
+
+#endif /* __KERNEL__ */
+
+#endif /* __L2CAP_CORE_H */
diff -u --recursive --new-file v2.4.5/linux/include/net/irda/irdacall.h linux/include/net/irda/irdacall.h
--- v2.4.5/linux/include/net/irda/irdacall.h	Thu Dec 17 09:01:03 1998
+++ linux/include/net/irda/irdacall.h	Wed Dec 31 16:00:00 1969
@@ -1,2 +0,0 @@
-/* Separate to keep compilation of protocols.c simpler */
-extern void irda_proto_init(struct net_proto *pro);
diff -u --recursive --new-file v2.4.5/linux/include/net/protocol.h linux/include/net/protocol.h
--- v2.4.5/linux/include/net/protocol.h	Fri May 25 18:01:27 2001
+++ linux/include/net/protocol.h	Wed Jun 27 16:01:22 2001
@@ -63,19 +63,46 @@
 
 #endif
 
+/* This is used to register socket interfaces for IP protocols.  */
+struct inet_protosw {
+	struct list_head list;
+
+        /* These two fields form the lookup key.  */
+	unsigned short	 type;	   /* This is the 2nd argument to socket(2). */
+	int		 protocol; /* This is the L4 protocol number.  */
+
+	struct proto	 *prot;
+	struct proto_ops *ops;
+  
+	int              capability; /* Which (if any) capability do
+				      * we need to use this socket
+				      * interface?
+                                      */
+	char             no_check;   /* checksum on rcv/xmit/none? */
+	unsigned char	 flags;      /* See INET_PROTOSW_* below.  */
+};
+#define INET_PROTOSW_REUSE 0x01	     /* Are ports automatically reusable? */
+#define INET_PROTOSW_PERMANENT 0x02  /* Permanent protocols are unremovable. */
+
 extern struct inet_protocol *inet_protocol_base;
 extern struct inet_protocol *inet_protos[MAX_INET_PROTOS];
+extern struct list_head inetsw[SOCK_MAX];
 
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
 extern struct inet6_protocol *inet6_protos[MAX_INET_PROTOS];
+extern struct list_head inetsw6[SOCK_MAX];
 #endif
 
 extern void	inet_add_protocol(struct inet_protocol *prot);
 extern int	inet_del_protocol(struct inet_protocol *prot);
+extern void	inet_register_protosw(struct inet_protosw *p);
+extern void	inet_unregister_protosw(struct inet_protosw *p);
 
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
 extern void	inet6_add_protocol(struct inet6_protocol *prot);
 extern int	inet6_del_protocol(struct inet6_protocol *prot);
+extern void	inet6_register_protosw(struct inet_protosw *p);
+extern void	inet6_unregister_protosw(struct inet_protosw *p);
 #endif
 
 #endif	/* _PROTOCOL_H */
diff -u --recursive --new-file v2.4.5/linux/include/net/snmp.h linux/include/net/snmp.h
--- v2.4.5/linux/include/net/snmp.h	Fri May 25 18:01:27 2001
+++ linux/include/net/snmp.h	Wed Jun 27 16:01:22 2001
@@ -14,7 +14,7 @@
  *		as published by the Free Software Foundation; either version
  *		2 of the License, or (at your option) any later version.
  *
- *		$Id: snmp.h,v 1.18 2001/05/16 16:45:35 davem Exp $
+ *		$Id: snmp.h,v 1.19 2001/06/14 13:40:46 davem Exp $
  *
  */
  
@@ -119,6 +119,7 @@
  	unsigned long	IcmpOutTimestampReps;
  	unsigned long	IcmpOutAddrMasks;
  	unsigned long	IcmpOutAddrMaskReps;
+	unsigned long	dummy;
 	unsigned long   __pad[0]; 
 } ____cacheline_aligned;
 
diff -u --recursive --new-file v2.4.5/linux/include/video/macmodes.h linux/include/video/macmodes.h
--- v2.4.5/linux/include/video/macmodes.h	Wed Feb  9 19:43:57 2000
+++ linux/include/video/macmodes.h	Wed Jun 27 17:10:55 2001
@@ -38,7 +38,9 @@
 #define VMODE_1152_870_75	18	/* 1152x870, 75Hz */
 #define VMODE_1280_960_75	19	/* 1280x960, 75Hz */
 #define VMODE_1280_1024_75	20	/* 1280x1024, 75Hz */
-#define VMODE_MAX		20
+#define VMODE_1152_768_60	21	/* 1152x768, 60Hz     Titanium PowerBook */
+#define VMODE_1600_1024_60	22	/* 1600x1024, 60Hz 22" Cinema Display */
+#define VMODE_MAX		22
 #define VMODE_CHOOSE		99
 
 #define CMODE_NVRAM		-1
diff -u --recursive --new-file v2.4.5/linux/init/main.c linux/init/main.c
--- v2.4.5/linux/init/main.c	Tue May 22 09:35:42 2001
+++ linux/init/main.c	Wed Jun 20 11:10:27 2001
@@ -62,7 +62,8 @@
 #endif
 
 #ifdef CONFIG_IRDA
-#include <net/irda/irda_device.h>
+extern int irda_proto_init(void);
+extern int irda_device_init(void);
 #endif
 
 #ifdef CONFIG_X86_IO_APIC
diff -u --recursive --new-file v2.4.5/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v2.4.5/linux/kernel/ksyms.c	Thu May 24 15:20:18 2001
+++ linux/kernel/ksyms.c	Mon Jun 11 19:15:27 2001
@@ -90,17 +90,13 @@
 EXPORT_SYMBOL(exit_sighand);
 
 /* internal kernel memory management */
+EXPORT_SYMBOL(_alloc_pages);
 EXPORT_SYMBOL(__alloc_pages);
 EXPORT_SYMBOL(alloc_pages_node);
 EXPORT_SYMBOL(__get_free_pages);
 EXPORT_SYMBOL(get_zeroed_page);
 EXPORT_SYMBOL(__free_pages);
 EXPORT_SYMBOL(free_pages);
-#ifndef CONFIG_DISCONTIGMEM
-EXPORT_SYMBOL(contig_page_data);
-#else
-EXPORT_SYMBOL(alloc_pages);
-#endif
 EXPORT_SYMBOL(num_physpages);
 EXPORT_SYMBOL(kmem_find_general_cachep);
 EXPORT_SYMBOL(kmem_cache_create);
@@ -144,6 +140,7 @@
 EXPORT_SYMBOL(force_delete);
 EXPORT_SYMBOL(follow_up);
 EXPORT_SYMBOL(follow_down);
+EXPORT_SYMBOL(lookup_mnt);
 EXPORT_SYMBOL(path_init);
 EXPORT_SYMBOL(path_walk);
 EXPORT_SYMBOL(path_release);
@@ -539,6 +536,9 @@
 EXPORT_SYMBOL(tasklet_init);
 EXPORT_SYMBOL(tasklet_kill);
 EXPORT_SYMBOL(__run_task_queue);
+EXPORT_SYMBOL(do_softirq);
+EXPORT_SYMBOL(tasklet_schedule);
+EXPORT_SYMBOL(tasklet_hi_schedule);
 
 /* init task, for moving kthread roots - ought to export a function ?? */
 
diff -u --recursive --new-file v2.4.5/linux/kernel/sched.c linux/kernel/sched.c
--- v2.4.5/linux/kernel/sched.c	Fri Apr 20 18:26:16 2001
+++ linux/kernel/sched.c	Wed Jun 27 14:12:04 2001
@@ -544,7 +544,7 @@
 	release_kernel_lock(prev, this_cpu);
 
 	/* Do "administrative" work here while we don't hold any locks */
-	if (softirq_active(this_cpu) & softirq_mask(this_cpu))
+	if (softirq_pending(this_cpu))
 		goto handle_softirq;
 handle_softirq_back:
 
@@ -1104,7 +1104,7 @@
 	int state;
 	static const char * stat_nam[] = { "R", "S", "D", "Z", "T", "W" };
 
-	printk("%-8s  ", p->comm);
+	printk("%-13.13s ", p->comm);
 	state = p->state ? ffz(~p->state) + 1 : 0;
 	if (((unsigned) state) < sizeof(stat_nam)/sizeof(char *))
 		printk(stat_nam[state]);
@@ -1132,21 +1132,21 @@
 		printk("%5d ", p->p_cptr->pid);
 	else
 		printk("      ");
-	if (!p->mm)
-		printk(" (L-TLB) ");
-	else
-		printk(" (NOTLB) ");
 	if (p->p_ysptr)
 		printk("%7d", p->p_ysptr->pid);
 	else
 		printk("       ");
 	if (p->p_osptr)
-		printk(" %5d\n", p->p_osptr->pid);
+		printk(" %5d", p->p_osptr->pid);
+	else
+		printk("      ");
+	if (!p->mm)
+		printk(" (L-TLB)\n");
 	else
-		printk("\n");
+		printk(" (NOTLB)\n");
 
-#if defined(CONFIG_X86) || defined(CONFIG_SPARC64)
-/* This is very useful, but only works on x86 and sparc64 right now */
+#if defined(CONFIG_X86) || defined(CONFIG_SPARC64) || defined(CONFIG_ARM)
+/* This is very useful, but only works on ARM, x86 and sparc64 right now */
 	{
 		extern void show_trace_task(struct task_struct *tsk);
 		show_trace_task(p);
diff -u --recursive --new-file v2.4.5/linux/kernel/softirq.c linux/kernel/softirq.c
--- v2.4.5/linux/kernel/softirq.c	Fri Dec 29 14:07:24 2000
+++ linux/kernel/softirq.c	Mon Jun 11 19:15:27 2001
@@ -50,70 +50,50 @@
 asmlinkage void do_softirq()
 {
 	int cpu = smp_processor_id();
-	__u32 active, mask;
+	__u32 pending;
 
 	if (in_interrupt())
 		return;
 
-	local_bh_disable();
-
 	local_irq_disable();
-	mask = softirq_mask(cpu);
-	active = softirq_active(cpu) & mask;
 
-	if (active) {
+	pending = softirq_pending(cpu);
+
+	if (pending) {
 		struct softirq_action *h;
 
+		local_bh_disable();
 restart:
-		/* Reset active bitmask before enabling irqs */
-		softirq_active(cpu) &= ~active;
+		/* Reset the pending bitmask before enabling irqs */
+		softirq_pending(cpu) = 0;
 
 		local_irq_enable();
 
 		h = softirq_vec;
-		mask &= ~active;
 
 		do {
-			if (active & 1)
+			if (pending & 1)
 				h->action(h);
 			h++;
-			active >>= 1;
-		} while (active);
+			pending >>= 1;
+		} while (pending);
 
 		local_irq_disable();
 
-		active = softirq_active(cpu);
-		if ((active &= mask) != 0)
-			goto retry;
+		pending = softirq_pending(cpu);
+		if (pending)
+			goto restart;
+		__local_bh_enable();
 	}
 
-	local_bh_enable();
-
-	/* Leave with locally disabled hard irqs. It is critical to close
-	 * window for infinite recursion, while we help local bh count,
-	 * it protected us. Now we are defenceless.
-	 */
-	return;
-
-retry:
-	goto restart;
+	local_irq_enable();
 }
 
 
-static spinlock_t softirq_mask_lock = SPIN_LOCK_UNLOCKED;
-
 void open_softirq(int nr, void (*action)(struct softirq_action*), void *data)
 {
-	unsigned long flags;
-	int i;
-
-	spin_lock_irqsave(&softirq_mask_lock, flags);
 	softirq_vec[nr].data = data;
 	softirq_vec[nr].action = action;
-
-	for (i=0; i<NR_CPUS; i++)
-		softirq_mask(i) |= (1<<nr);
-	spin_unlock_irqrestore(&softirq_mask_lock, flags);
 }
 
 
@@ -121,6 +101,45 @@
 
 struct tasklet_head tasklet_vec[NR_CPUS] __cacheline_aligned;
 
+void tasklet_schedule(struct tasklet_struct *t)
+{
+	unsigned long flags;
+	int cpu;
+
+	cpu = smp_processor_id();
+	local_irq_save(flags);
+	/*
+	 * If nobody is running it then add it to this CPU's
+	 * tasklet queue.
+	 */
+	if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state) &&
+						tasklet_trylock(t)) {
+		t->next = tasklet_vec[cpu].list;
+		tasklet_vec[cpu].list = t;
+		__cpu_raise_softirq(cpu, TASKLET_SOFTIRQ);
+		tasklet_unlock(t);
+	}
+	local_irq_restore(flags);
+}
+
+void tasklet_hi_schedule(struct tasklet_struct *t)
+{
+	unsigned long flags;
+	int cpu;
+
+	cpu = smp_processor_id();
+	local_irq_save(flags);
+
+	if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state) &&
+						tasklet_trylock(t)) {
+		t->next = tasklet_hi_vec[cpu].list;
+		tasklet_hi_vec[cpu].list = t;
+		__cpu_raise_softirq(cpu, HI_SOFTIRQ);
+		tasklet_unlock(t);
+	}
+	local_irq_restore(flags);
+}
+
 static void tasklet_action(struct softirq_action *a)
 {
 	int cpu = smp_processor_id();
@@ -129,37 +148,37 @@
 	local_irq_disable();
 	list = tasklet_vec[cpu].list;
 	tasklet_vec[cpu].list = NULL;
-	local_irq_enable();
 
-	while (list != NULL) {
+	while (list) {
 		struct tasklet_struct *t = list;
 
 		list = list->next;
 
-		if (tasklet_trylock(t)) {
-			if (atomic_read(&t->count) == 0) {
-				clear_bit(TASKLET_STATE_SCHED, &t->state);
-
-				t->func(t->data);
-				/*
-				 * talklet_trylock() uses test_and_set_bit that imply
-				 * an mb when it returns zero, thus we need the explicit
-				 * mb only here: while closing the critical section.
-				 */
-#ifdef CONFIG_SMP
-				smp_mb__before_clear_bit();
-#endif
-				tasklet_unlock(t);
-				continue;
-			}
-			tasklet_unlock(t);
+		/*
+		 * A tasklet is only added to the queue while it's
+		 * locked, so no other CPU can have this tasklet
+		 * pending:
+		 */
+		if (!tasklet_trylock(t))
+			BUG();
+repeat:
+		if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))
+			BUG();
+		if (!atomic_read(&t->count)) {
+			local_irq_enable();
+			t->func(t->data);
+			local_irq_disable();
+			/*
+			 * One more run if the tasklet got reactivated:
+			 */
+			if (test_bit(TASKLET_STATE_SCHED, &t->state))
+				goto repeat;
 		}
-		local_irq_disable();
-		t->next = tasklet_vec[cpu].list;
-		tasklet_vec[cpu].list = t;
-		__cpu_raise_softirq(cpu, TASKLET_SOFTIRQ);
-		local_irq_enable();
+		tasklet_unlock(t);
+		if (test_bit(TASKLET_STATE_SCHED, &t->state))
+			tasklet_schedule(t);
 	}
+	local_irq_enable();
 }
 
 
@@ -174,39 +193,40 @@
 	local_irq_disable();
 	list = tasklet_hi_vec[cpu].list;
 	tasklet_hi_vec[cpu].list = NULL;
-	local_irq_enable();
 
-	while (list != NULL) {
+	while (list) {
 		struct tasklet_struct *t = list;
 
 		list = list->next;
 
-		if (tasklet_trylock(t)) {
-			if (atomic_read(&t->count) == 0) {
-				clear_bit(TASKLET_STATE_SCHED, &t->state);
-
-				t->func(t->data);
-				tasklet_unlock(t);
-				continue;
-			}
-			tasklet_unlock(t);
+		if (!tasklet_trylock(t))
+			BUG();
+repeat:
+		if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))
+			BUG();
+		if (!atomic_read(&t->count)) {
+			local_irq_enable();
+			t->func(t->data);
+			local_irq_disable();
+			if (test_bit(TASKLET_STATE_SCHED, &t->state))
+				goto repeat;
 		}
-		local_irq_disable();
-		t->next = tasklet_hi_vec[cpu].list;
-		tasklet_hi_vec[cpu].list = t;
-		__cpu_raise_softirq(cpu, HI_SOFTIRQ);
-		local_irq_enable();
+		tasklet_unlock(t);
+		if (test_bit(TASKLET_STATE_SCHED, &t->state))
+			tasklet_hi_schedule(t);
 	}
+	local_irq_enable();
 }
 
 
 void tasklet_init(struct tasklet_struct *t,
 		  void (*func)(unsigned long), unsigned long data)
 {
-	t->func = func;
-	t->data = data;
+	t->next = NULL;
 	t->state = 0;
 	atomic_set(&t->count, 0);
+	t->func = func;
+	t->data = data;
 }
 
 void tasklet_kill(struct tasklet_struct *t)
diff -u --recursive --new-file v2.4.5/linux/kernel/timer.c linux/kernel/timer.c
--- v2.4.5/linux/kernel/timer.c	Sun Dec 10 09:53:19 2000
+++ linux/kernel/timer.c	Tue Jun 12 16:40:11 2001
@@ -32,7 +32,7 @@
 long tick = (1000000 + HZ/2) / HZ;	/* timer interrupt period */
 
 /* The current time */
-volatile struct timeval xtime __attribute__ ((aligned (16)));
+struct timeval xtime __attribute__ ((aligned (16)));
 
 /* Don't completely fail for HZ > 500.  */
 int tickadj = 500/HZ ? : 1;		/* microsecs */
diff -u --recursive --new-file v2.4.5/linux/lib/brlock.c linux/lib/brlock.c
--- v2.4.5/linux/lib/brlock.c	Mon Apr 24 13:59:56 2000
+++ linux/lib/brlock.c	Mon Jun 11 19:15:27 2001
@@ -25,7 +25,7 @@
 	int i;
 
 	for (i = 0; i < smp_num_cpus; i++)
-		write_lock(__brlock_array[idx] + cpu_logical_map(i));
+		write_lock(&__brlock_array[cpu_logical_map(i)][idx]);
 }
 
 void __br_write_unlock (enum brlock_indices idx)
@@ -33,7 +33,7 @@
 	int i;
 
 	for (i = 0; i < smp_num_cpus; i++)
-		write_unlock(__brlock_array[idx] + cpu_logical_map(i));
+		write_unlock(&__brlock_array[cpu_logical_map(i)][idx]);
 }
 
 #else /* ! __BRLOCK_USE_ATOMICS */
diff -u --recursive --new-file v2.4.5/linux/mm/filemap.c linux/mm/filemap.c
--- v2.4.5/linux/mm/filemap.c	Tue May 22 10:52:35 2001
+++ linux/mm/filemap.c	Tue Jun 12 11:16:41 2001
@@ -230,17 +230,17 @@
 		unsigned long offset;
 
 		page = list_entry(curr, struct page, list);
-		curr = curr->next;
 		offset = page->index;
 
 		/* Is one of the pages to truncate? */
 		if ((offset >= start) || (*partial && (offset + 1) == start)) {
+			list_del(head);
+			list_add(head, curr);
 			if (TryLockPage(page)) {
 				page_cache_get(page);
 				spin_unlock(&pagecache_lock);
 				wait_on_page(page);
-				page_cache_release(page);
-				return 1;
+				goto out_restart;
 			}
 			page_cache_get(page);
 			spin_unlock(&pagecache_lock);
@@ -252,11 +252,15 @@
 				truncate_complete_page(page);
 
 			UnlockPage(page);
-			page_cache_release(page);
-			return 1;
+			goto out_restart;
 		}
+		curr = curr->next;
 	}
 	return 0;
+out_restart:
+	page_cache_release(page);
+	spin_lock(&pagecache_lock);
+	return 1;
 }
 
 
@@ -273,15 +277,19 @@
 {
 	unsigned long start = (lstart + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 	unsigned partial = lstart & (PAGE_CACHE_SIZE - 1);
+	int complete;
 
-repeat:
 	spin_lock(&pagecache_lock);
-	if (truncate_list_pages(&mapping->clean_pages, start, &partial))
-		goto repeat;
-	if (truncate_list_pages(&mapping->dirty_pages, start, &partial))
-		goto repeat;
-	if (truncate_list_pages(&mapping->locked_pages, start, &partial))
-		goto repeat;
+	do {
+		complete = 1;
+		while (truncate_list_pages(&mapping->clean_pages, start, &partial))
+			complete = 0;
+		while (truncate_list_pages(&mapping->dirty_pages, start, &partial))
+			complete = 0;
+		while (truncate_list_pages(&mapping->locked_pages, start, &partial))
+			complete = 0;
+	} while (!complete);
+	/* Traversed all three lists without dropping the lock */
 	spin_unlock(&pagecache_lock);
 }
 
@@ -529,7 +537,7 @@
 	if (PageLocked(page))
 		BUG();
 
-	flags = page->flags & ~((1 << PG_uptodate) | (1 << PG_error) | (1 << PG_dirty) | (1 << PG_referenced) | (1 << PG_arch_1));
+	flags = page->flags & ~((1 << PG_uptodate) | (1 << PG_error) | (1 << PG_dirty) | (1 << PG_referenced) | (1 << PG_arch_1) | (1 << PG_checked));
 	page->flags = flags | (1 << PG_locked);
 	page_cache_get(page);
 	page->index = offset;
diff -u --recursive --new-file v2.4.5/linux/mm/memory.c linux/mm/memory.c
--- v2.4.5/linux/mm/memory.c	Fri Apr 27 14:23:25 2001
+++ linux/mm/memory.c	Mon Jun 11 19:15:27 2001
@@ -274,7 +274,7 @@
 		 */
 		if (pte_dirty(pte) && page->mapping)
 			set_page_dirty(page);
-		page_cache_release(page);
+		free_page_and_swap_cache(page);
 		return 1;
 	}
 	swap_free(pte_to_swp_entry(pte));
@@ -870,24 +870,6 @@
 	flush_cache_page(vma, address);
 	establish_pte(vma, address, page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
 }
-
-/*
- * Work out if there are any other processes sharing this
- * swap cache page. Never mind the buffers.
- */
-static inline int exclusive_swap_page(struct page *page)
-{
-	unsigned int count;
-
-	if (!PageLocked(page))
-		BUG();
-	if (!PageSwapCache(page))
-		return 0;
-	count = page_count(page) - !!page->buffers;	/*  2: us + swap cache */
-	count += swap_count(page);			/* +1: just swap cache */
-	return count == 3;				/* =3: total */
-}
-
 
 /*
  * This routine handles present pages, when users try to write
diff -u --recursive --new-file v2.4.5/linux/mm/numa.c linux/mm/numa.c
--- v2.4.5/linux/mm/numa.c	Mon Oct 16 15:25:45 2000
+++ linux/mm/numa.c	Mon Jun 11 19:15:27 2001
@@ -34,7 +34,7 @@
 struct page * alloc_pages_node(int nid, int gfp_mask, unsigned long order)
 {
 #ifdef CONFIG_NUMA
-	return __alloc_pages(NODE_DATA(nid)->node_zonelists + gfp_mask, order);
+	return __alloc_pages(gfp_mask, order, NODE_DATA(nid)->node_zonelists + (gfp_mask & GFP_ZONEMASK));
 #else
 	return alloc_pages(gfp_mask, order);
 #endif
@@ -85,14 +85,14 @@
 static struct page * alloc_pages_pgdat(pg_data_t *pgdat, int gfp_mask,
 	unsigned long order)
 {
-	return __alloc_pages(pgdat->node_zonelists + gfp_mask, order);
+	return __alloc_pages(gfp_mask, order, pgdat->node_zonelists + (gfp_mask & GFP_ZONEMASK));
 }
 
 /*
  * This can be refined. Currently, tries to do round robin, instead
  * should do concentratic circle search, starting from current node.
  */
-struct page * alloc_pages(int gfp_mask, unsigned long order)
+struct page * _alloc_pages(int gfp_mask, unsigned long order)
 {
 	struct page *ret = 0;
 	pg_data_t *start, *temp;
diff -u --recursive --new-file v2.4.5/linux/mm/page_alloc.c linux/mm/page_alloc.c
--- v2.4.5/linux/mm/page_alloc.c	Fri May 25 16:55:23 2001
+++ linux/mm/page_alloc.c	Wed Jun 27 14:14:07 2001
@@ -268,15 +268,21 @@
 	return NULL;
 }
 
+#ifndef CONFIG_DISCONTIGMEM
+struct page *_alloc_pages(unsigned int gfp_mask, unsigned long order)
+{
+	return __alloc_pages(gfp_mask, order,
+		contig_page_data.node_zonelists+(gfp_mask & GFP_ZONEMASK));
+}
+#endif
 
 /*
  * This is the 'heart' of the zoned buddy allocator:
  */
-struct page * __alloc_pages(zonelist_t *zonelist, unsigned long order)
+struct page * __alloc_pages(unsigned int gfp_mask, unsigned long order, zonelist_t *zonelist)
 {
 	zone_t **zone;
 	int direct_reclaim = 0;
-	unsigned int gfp_mask = zonelist->gfp_mask;
 	struct page * page;
 
 	/*
@@ -428,18 +434,30 @@
 		}
 		/*
 		 * When we arrive here, we are really tight on memory.
+		 * Since kswapd didn't succeed in freeing pages for us,
+		 * we try to help it.
 		 *
-		 * We try to free pages ourselves by:
-		 * 	- shrinking the i/d caches.
-		 * 	- reclaiming unused memory from the slab caches.
-		 * 	- swapping/syncing pages to disk (done by page_launder)
-		 * 	- moving clean pages from the inactive dirty list to
-		 * 	  the inactive clean list. (done by page_launder)
+		 * Single page allocs loop until the allocation succeeds.
+		 * Multi-page allocs can fail due to memory fragmentation;
+		 * in that case we bail out to prevent infinite loops and
+		 * hanging device drivers ...
+		 *
+		 * Another issue are GFP_BUFFER allocations; because they
+		 * do not have __GFP_IO set it's possible we cannot make
+		 * any progress freeing pages, in that case it's better
+		 * to give up than to deadlock the kernel looping here.
 		 */
 		if (gfp_mask & __GFP_WAIT) {
-			memory_pressure++;
-			try_to_free_pages(gfp_mask);
-			goto try_again;
+			if (!order || free_shortage()) {
+				int progress = try_to_free_pages(gfp_mask);
+				if (progress || (gfp_mask & __GFP_IO))
+					goto try_again;
+				/*
+				 * Fail in case no progress was made and the
+				 * allocation may not be able to block on IO.
+				 */
+				return NULL;
+			}
 		}
 	}
 
@@ -671,14 +689,13 @@
 {
 	int i, j, k;
 
-	for (i = 0; i < NR_GFPINDEX; i++) {
+	for (i = 0; i <= GFP_ZONEMASK; i++) {
 		zonelist_t *zonelist;
 		zone_t *zone;
 
 		zonelist = pgdat->node_zonelists + i;
 		memset(zonelist, 0, sizeof(*zonelist));
 
-		zonelist->gfp_mask = i;
 		j = 0;
 		k = ZONE_NORMAL;
 		if (i & __GFP_HIGHMEM)
diff -u --recursive --new-file v2.4.5/linux/mm/swap_state.c linux/mm/swap_state.c
--- v2.4.5/linux/mm/swap_state.c	Thu May 24 15:20:18 2001
+++ linux/mm/swap_state.c	Mon Jun 11 19:15:27 2001
@@ -145,6 +145,30 @@
 	UnlockPage(page);
 }
 
+/* 
+ * Perform a free_page(), also freeing any swap cache associated with
+ * this page if it is the last user of the page. Can not do a lock_page,
+ * as we are holding the page_table_lock spinlock.
+ */
+void free_page_and_swap_cache(struct page *page)
+{
+	/* 
+	 * If we are the only user, then try to free up the swap cache. 
+	 * 
+	 * Its ok to check for PageSwapCache without the page lock
+	 * here because we are going to recheck again inside 
+	 * exclusive_swap_page() _with_ the lock. 
+	 * 					- Marcelo
+	 */
+	if (PageSwapCache(page) && !TryLockPage(page)) {
+		if (exclusive_swap_page(page))
+			delete_from_swap_cache_nolock(page);
+		UnlockPage(page);
+	}
+	page_cache_release(page);
+}
+
+
 /*
  * Lookup a swap entry in the swap cache. A found page will be returned
  * unlocked and with its refcount incremented - we rely on the kernel
diff -u --recursive --new-file v2.4.5/linux/mm/swapfile.c linux/mm/swapfile.c
--- v2.4.5/linux/mm/swapfile.c	Sat May 19 17:16:18 2001
+++ linux/mm/swapfile.c	Mon Jun 11 19:15:27 2001
@@ -343,6 +343,16 @@
 
 	while (1) {
 		/*
+		 * The algorithm is inefficient but seldomly used
+		 * and probably not worth fixing.
+		 *
+		 * Make sure that we aren't completely killing
+		 * interactive performance.
+		 */
+		if (current->need_resched)
+			schedule();
+			
+		/*
 		 * Find a swap page in use and read it in.
 		 */
 		swap_device_lock(si);
diff -u --recursive --new-file v2.4.5/linux/mm/vmscan.c linux/mm/vmscan.c
--- v2.4.5/linux/mm/vmscan.c	Fri May 25 17:00:18 2001
+++ linux/mm/vmscan.c	Wed Jun 27 14:13:37 2001
@@ -265,12 +265,9 @@
 	return !count;
 }
 
-/*
- * N.B. This function returns only 0 or 1.  Return values != 1 from
- * the lower level routines result in continued processing.
- */
-#define SWAP_SHIFT 5
-#define SWAP_MIN 8
+#define SWAP_MM_SHIFT	4
+#define SWAP_SHIFT	5
+#define SWAP_MIN	8
 
 static inline int swap_amount(struct mm_struct *mm)
 {
@@ -283,7 +280,7 @@
 	return nr;
 }
 
-static int swap_out(unsigned int priority, int gfp_mask)
+static void swap_out(unsigned int priority, int gfp_mask)
 {
 	int counter;
 	int retval = 0;
@@ -294,7 +291,7 @@
 		retval = swap_out_mm(mm, swap_amount(mm));
 
 	/* Then, look at the other mm's */
-	counter = (mmlist_nr << SWAP_SHIFT) >> priority;
+	counter = (mmlist_nr << SWAP_MM_SHIFT) >> priority;
 	do {
 		struct list_head *p;
 
@@ -316,11 +313,10 @@
 		retval |= swap_out_mm(mm, swap_amount(mm));
 		mmput(mm);
 	} while (--counter >= 0);
-	return retval;
+	return;
 
 empty:
 	spin_unlock(&mmlist_lock);
-	return 0;
 }
 
 
@@ -395,6 +391,7 @@
 	goto out;
 
 found_page:
+	memory_pressure++;
 	del_page_from_inactive_clean_list(page);
 	UnlockPage(page);
 	page->age = PAGE_AGE_START;
@@ -404,14 +401,13 @@
 out:
 	spin_unlock(&pagemap_lru_lock);
 	spin_unlock(&pagecache_lock);
-	memory_pressure++;
 	return page;
 }
 
 /**
  * page_launder - clean dirty inactive pages, move to inactive_clean list
  * @gfp_mask: what operations we are allowed to do
- * @sync: should we wait synchronously for the cleaning of pages
+ * @sync: are we allowed to do synchronous IO in emergencies ?
  *
  * When this function is called, we are most likely low on free +
  * inactive_clean pages. Since we want to refill those pages as
@@ -428,18 +424,18 @@
  * go out to Matthew Dillon.
  */
 #define MAX_LAUNDER 		(4 * (1 << page_cluster))
+#define CAN_DO_IO		(gfp_mask & __GFP_IO)
+#define CAN_DO_BUFFERS		(gfp_mask & __GFP_BUFFER)
+#define marker_lru		(&marker_page_struct.lru)
 int page_launder(int gfp_mask, int sync)
 {
+	static int cannot_free_pages;
 	int launder_loop, maxscan, cleaned_pages, maxlaunder;
-	int can_get_io_locks;
 	struct list_head * page_lru;
 	struct page * page;
 
-	/*
-	 * We can only grab the IO locks (eg. for flushing dirty
-	 * buffers to disk) if __GFP_IO is set.
-	 */
-	can_get_io_locks = gfp_mask & __GFP_IO;
+	/* Our bookmark of where we are in the inactive_dirty list. */
+	struct page marker_page_struct = { zone: NULL };
 
 	launder_loop = 0;
 	maxlaunder = 0;
@@ -447,11 +443,44 @@
 
 dirty_page_rescan:
 	spin_lock(&pagemap_lru_lock);
-	maxscan = nr_inactive_dirty_pages;
-	while ((page_lru = inactive_dirty_list.prev) != &inactive_dirty_list &&
-				maxscan-- > 0) {
+	/*
+	 * By not scanning all inactive dirty pages we'll write out
+	 * really old dirty pages before evicting newer clean pages.
+	 * This should cause some LRU behaviour if we have a large
+	 * amount of inactive pages (due to eg. drop behind).
+	 *
+	 * It also makes us accumulate dirty pages until we have enough
+	 * to be worth writing to disk without causing excessive disk
+	 * seeks and eliminates the infinite penalty clean pages incurred
+	 * vs. dirty pages.
+	 */
+	maxscan = nr_inactive_dirty_pages / 4;
+	if (launder_loop)
+		maxscan *= 2;
+	list_add_tail(marker_lru, &inactive_dirty_list);
+	for (;;) {
+		page_lru = marker_lru->prev;
+		if (page_lru == &inactive_dirty_list)
+			break;
+		if (--maxscan < 0)
+			break;
+		if (!free_shortage())
+			break;
+
 		page = list_entry(page_lru, struct page, lru);
 
+		/* Move the bookmark backwards.. */
+		list_del(marker_lru);
+		list_add_tail(marker_lru, page_lru);
+
+		/* Don't waste CPU if chances are we cannot free anything. */
+		if (launder_loop && maxlaunder < 0 && cannot_free_pages)
+			break;
+
+		/* Skip other people's marker pages. */
+		if (!page->zone)
+			continue;
+
 		/* Wrong page on list?! (list corruption, should not happen) */
 		if (!PageInactiveDirty(page)) {
 			printk("VM: page_launder, wrong page on list.\n");
@@ -472,11 +501,9 @@
 
 		/*
 		 * The page is locked. IO in progress?
-		 * Move it to the back of the list.
+		 * Skip the page, we'll take a look when it unlocks.
 		 */
 		if (TryLockPage(page)) {
-			list_del(page_lru);
-			list_add(page_lru, &inactive_dirty_list);
 			continue;
 		}
 
@@ -490,10 +517,8 @@
 			if (!writepage)
 				goto page_active;
 
-			/* First time through? Move it to the back of the list */
-			if (!launder_loop) {
-				list_del(page_lru);
-				list_add(page_lru, &inactive_dirty_list);
+			/* First time through? Skip the page. */
+			if (!launder_loop || !CAN_DO_IO) {
 				UnlockPage(page);
 				continue;
 			}
@@ -506,6 +531,8 @@
 			writepage(page);
 			page_cache_release(page);
 
+			maxlaunder--;
+
 			/* And re-start the thing.. */
 			spin_lock(&pagemap_lru_lock);
 			continue;
@@ -533,9 +560,9 @@
 			spin_unlock(&pagemap_lru_lock);
 
 			/* Will we do (asynchronous) IO? */
-			if (launder_loop && maxlaunder == 0 && sync)
+			if (launder_loop && maxlaunder-- == 0 && sync)
 				wait = 2;	/* Synchrounous IO */
-			else if (launder_loop && maxlaunder-- > 0)
+			else if (launder_loop && maxlaunder > 0)
 				wait = 1;	/* Async IO */
 			else
 				wait = 0;	/* No IO */
@@ -552,7 +579,7 @@
 
 			/* The buffers were not freed. */
 			if (!clearedbuf) {
-				add_page_to_inactive_dirty_list(page);
+				add_page_to_inactive_dirty_list_marker(page);
 
 			/* The page was only in the buffer cache. */
 			} else if (!page->mapping) {
@@ -608,6 +635,8 @@
 			UnlockPage(page);
 		}
 	}
+	/* Remove our marker. */
+	list_del(marker_lru);
 	spin_unlock(&pagemap_lru_lock);
 
 	/*
@@ -621,18 +650,31 @@
 	 * loads, flush out the dirty pages before we have to wait on
 	 * IO.
 	 */
-	if (can_get_io_locks && !launder_loop && free_shortage()) {
+	if ((CAN_DO_IO || CAN_DO_BUFFERS) && !launder_loop && free_shortage()) {
 		launder_loop = 1;
-		/* If we cleaned pages, never do synchronous IO. */
-		if (cleaned_pages)
+		/*
+		 * If we, or the previous process running page_launder(),
+		 * managed to free any pages we never do synchronous IO.
+		 */
+		if (cleaned_pages || !cannot_free_pages)
 			sync = 0;
+		/* Else, do synchronous IO (if we are allowed to). */
+		else if (sync)
+			sync = 1;
 		/* We only do a few "out of order" flushes. */
 		maxlaunder = MAX_LAUNDER;
-		/* Kflushd takes care of the rest. */
+		/* Let bdflush take care of the rest. */
 		wakeup_bdflush(0);
 		goto dirty_page_rescan;
 	}
 
+	/*
+	 * If we failed to free pages (because all pages are dirty)
+	 * we remember this for the next time. This will prevent us
+	 * from wasting too much CPU here.
+	 */
+	cannot_free_pages = !cleaned_pages;
+
 	/* Return the number of pages moved to the inactive_clean list. */
 	return cleaned_pages;
 }
@@ -655,24 +697,10 @@
 
 	/*
 	 * When we are background aging, we try to increase the page aging
-	 * information in the system. When we have too many inactive pages
-	 * we don't do background aging since having all pages on the
-	 * inactive list decreases aging information.
-	 *
-	 * Since not all active pages have to be on the active list, we round
-	 * nr_active_pages up to num_physpages/2, if needed.
+	 * information in the system.
 	 */
-	if (!target) {
-		int inactive = nr_free_pages() + nr_inactive_clean_pages() +
-						nr_inactive_dirty_pages;
-		int active = MAX(nr_active_pages, num_physpages / 2);
-		if (active > 10 * inactive)
-			maxscan = nr_active_pages >> 4;
-		else if (active > 3 * inactive)
-			maxscan = nr_active_pages >> 8;
-		else
-			return 0;
-	}
+	if (!target)
+		maxscan = nr_active_pages >> 4;
 
 	/* Take the lock while messing with the list... */
 	spin_lock(&pagemap_lru_lock);
@@ -792,6 +820,8 @@
 			int zone_shortage;
 			zone_t *zone = pgdat->node_zones+ i;
 
+			if (!zone->size)
+				continue;
 			zone_shortage = zone->pages_high;
 			zone_shortage -= zone->inactive_dirty_pages;
 			zone_shortage -= zone->inactive_clean_pages;
@@ -843,13 +873,13 @@
 				return 1;
 		}
 
+		/* Walk the VM space for a bit.. */
+		swap_out(DEF_PRIORITY, gfp_mask);
+
 		count -= refill_inactive_scan(DEF_PRIORITY, count);
 		if (count <= 0)
 			goto done;
 
-		/* If refill_inactive_scan failed, try to page stuff out.. */
-		swap_out(DEF_PRIORITY, gfp_mask);
-
 		if (--maxtry <= 0)
 				return 0;
 		
@@ -872,7 +902,7 @@
 	 * list, so this is a relatively cheap operation.
 	 */
 	if (free_shortage()) {
-		ret += page_launder(gfp_mask, user);
+		ret += page_launder(gfp_mask, 1);
 		shrink_dcache_memory(DEF_PRIORITY, gfp_mask);
 		shrink_icache_memory(DEF_PRIORITY, gfp_mask);
 	}
diff -u --recursive --new-file v2.4.5/linux/net/802/hippi.c linux/net/802/hippi.c
--- v2.4.5/linux/net/802/hippi.c	Wed Aug 18 11:38:48 1999
+++ linux/net/802/hippi.c	Wed Jun 20 21:00:55 2001
@@ -98,7 +98,7 @@
 		memcpy(&skb->private.ifield, daddr + 2, 4);
 		return HIPPI_HLEN;
 	}
-	return -HIPPI_HLEN;
+	return -((int)HIPPI_HLEN);
 }
 
 
diff -u --recursive --new-file v2.4.5/linux/net/Makefile linux/net/Makefile
--- v2.4.5/linux/net/Makefile	Fri Dec 29 14:07:24 2000
+++ linux/net/Makefile	Mon Jun 11 19:15:27 2001
@@ -7,7 +7,7 @@
 
 O_TARGET :=	network.o
 
-mod-subdirs :=	ipv4/netfilter ipv6/netfilter ipx irda atm netlink sched
+mod-subdirs :=	ipv4/netfilter ipv6/netfilter ipx irda bluetooth atm netlink sched
 export-objs :=	netsyms.o
 
 subdir-y :=	core ethernet
@@ -40,6 +40,7 @@
 subdir-$(CONFIG_ROSE)		+= rose
 subdir-$(CONFIG_AX25)		+= ax25
 subdir-$(CONFIG_IRDA)		+= irda
+subdir-$(CONFIG_BLUEZ)		+= bluetooth
 subdir-$(CONFIG_SUNRPC)		+= sunrpc
 subdir-$(CONFIG_ATM)		+= atm
 subdir-$(CONFIG_DECNET)		+= decnet
diff -u --recursive --new-file v2.4.5/linux/net/README linux/net/README
--- v2.4.5/linux/net/README	Wed May 16 10:31:27 2001
+++ linux/net/README	Mon Jun 11 19:15:27 2001
@@ -22,5 +22,5 @@
 wanrouter		gene@compuserve.com, jaspreet@sangoma and dm@sangoma.com
 unix			alan@lxorguk.ukuu.org.uk
 x25			g4klx@g4klx.demon.co.uk
-
+bluetooth		maxk@qualcomm.com
 
diff -u --recursive --new-file v2.4.5/linux/net/atm/clip.c linux/net/atm/clip.c
--- v2.4.5/linux/net/atm/clip.c	Wed Apr 18 14:40:07 2001
+++ linux/net/atm/clip.c	Wed Jun 27 17:10:55 2001
@@ -685,8 +685,6 @@
 
 static void atmarpd_close(struct atm_vcc *vcc)
 {
-	struct sk_buff *skb;
-
 	DPRINTK("atmarpd_close\n");
 	atmarpd = NULL; /* assumed to be atomic */
 	barrier();
@@ -695,7 +693,7 @@
 	if (skb_peek(&vcc->recvq))
 		printk(KERN_ERR "atmarpd_close: closing with requests "
 		    "pending\n");
-	while ((skb = skb_dequeue(&vcc->recvq))) kfree_skb(skb);
+	skb_queue_purge(&vcc->recvq);
 	DPRINTK("(done)\n");
 }
 
diff -u --recursive --new-file v2.4.5/linux/net/atm/common.c linux/net/atm/common.c
--- v2.4.5/linux/net/atm/common.c	Fri Apr  6 10:51:19 2001
+++ linux/net/atm/common.c	Wed Jun 27 17:10:55 2001
@@ -544,7 +544,7 @@
 {
 	struct atm_dev *dev;
 	struct atm_vcc *vcc;
-	int *tmp_buf;
+	int *tmp_buf, *tmp_p;
 	void *buf;
 	int error,len,size,number, ret_val;
 
@@ -598,14 +598,13 @@
 				ret_val = -ENOMEM;
 				goto done;
 			}
+			tmp_p = tmp_buf;
 			for (dev = atm_devs; dev; dev = dev->next)
-				*tmp_buf++ = dev->number;
-			if (copy_to_user(buf,(char *) tmp_buf-size,size)) {
-				ret_val = -EFAULT;
-				goto done;
-			}
-		        ret_val = put_user(size,
-			    &((struct atm_iobuf *) arg)->length) ? -EFAULT : 0;
+				*tmp_p++ = dev->number;
+		        ret_val = ((copy_to_user(buf, tmp_buf, size)) ||
+			    put_user(size, &((struct atm_iobuf *) arg)->length)
+			    ) ? -EFAULT : 0;
+			kfree(tmp_buf);
 			goto done;
 		case SIOCGSTAMP: /* borrowed from IP */
 			if (!vcc->timestamp.tv_sec) {
diff -u --recursive --new-file v2.4.5/linux/net/atm/lec.c linux/net/atm/lec.c
--- v2.4.5/linux/net/atm/lec.c	Tue Mar  6 19:28:33 2001
+++ linux/net/atm/lec.c	Wed Jun 27 17:10:55 2001
@@ -281,6 +281,10 @@
                                dev->name,
                                skb->len,skb->truesize);
                         nb=(unsigned char*)kmalloc(64, GFP_ATOMIC);
+                        if (nb == NULL) {
+                                dev_kfree_skb(skb);
+                                return 0;
+                        }
                         memcpy(nb,skb->data,skb->len);
                         kfree(skb->head);
                         skb->head = skb->data = nb;
@@ -1796,6 +1800,10 @@
         entry = lec_arp_find(priv, mac_addr);
         if (!entry) {
                 entry = make_entry(priv, mac_addr);
+                if (!entry) {
+                        lec_arp_unlock(priv);
+                        return;
+                }
                 entry->status = ESI_UNKNOWN;
                 lec_arp_put(priv->lec_arp_tables, entry);
                 /* Temporary, changes before end of function */
@@ -1890,6 +1898,10 @@
                         ioc_data->atm_addr[16],ioc_data->atm_addr[17],
                         ioc_data->atm_addr[18],ioc_data->atm_addr[19]);
                 entry = make_entry(priv, bus_mac);
+                if (entry == NULL) {
+                        lec_arp_unlock(priv);
+                        return;
+                }
                 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
                 memset(entry->mac_addr, 0, ETH_ALEN);
                 entry->recv_vcc = vcc;
@@ -1967,6 +1979,10 @@
         /* Not found, snatch address from first data packet that arrives from
            this vcc */
         entry = make_entry(priv, bus_mac);
+        if (!entry) {
+                lec_arp_unlock(priv);
+                return;
+        }
         entry->vcc = vcc;
         entry->old_push = old_push;
         memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
diff -u --recursive --new-file v2.4.5/linux/net/atm/mpc.c linux/net/atm/mpc.c
--- v2.4.5/linux/net/atm/mpc.c	Wed Aug  9 13:51:09 2000
+++ linux/net/atm/mpc.c	Wed Jun 27 17:10:55 2001
@@ -772,6 +772,8 @@
 	if (mpc == NULL) {
 		dprintk("mpoa: mpoad_attach: allocating new mpc for itf %d\n", arg);
 		mpc = alloc_mpc();
+		if (mpc == NULL)
+			return -ENOMEM;
 		mpc->dev_num = arg;
 		mpc->dev = find_lec_by_itfnum(arg); /* NULL if there was no lec */
 	}
diff -u --recursive --new-file v2.4.5/linux/net/atm/signaling.c linux/net/atm/signaling.c
--- v2.4.5/linux/net/atm/signaling.c	Fri Dec 29 14:35:47 2000
+++ linux/net/atm/signaling.c	Wed Jun 27 17:10:55 2001
@@ -211,14 +211,13 @@
 
 static void sigd_close(struct atm_vcc *vcc)
 {
-	struct sk_buff *skb;
 	struct atm_dev *dev;
 
 	DPRINTK("sigd_close\n");
 	sigd = NULL;
 	if (skb_peek(&vcc->recvq))
 		printk(KERN_ERR "sigd_close: closing with requests pending\n");
-	while ((skb = skb_dequeue(&vcc->recvq))) kfree_skb(skb);
+	skb_queue_purge(&vcc->recvq);
 	purge_vccs(nodev_vccs);
 
 	spin_lock (&atm_dev_lock);
diff -u --recursive --new-file v2.4.5/linux/net/bluetooth/Config.in linux/net/bluetooth/Config.in
--- v2.4.5/linux/net/bluetooth/Config.in	Wed Dec 31 16:00:00 1969
+++ linux/net/bluetooth/Config.in	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,16 @@
+#
+# Bluetooth configuration
+#
+
+if [ "$CONFIG_NET" != "n" ]; then
+   mainmenu_option next_comment
+   comment 'Bluetooth support'
+   dep_tristate 'Bluetooth subsystem support' CONFIG_BLUEZ $CONFIG_NET
+
+   if [ "$CONFIG_BLUEZ" != "n" ]; then
+      dep_tristate 'L2CAP protocol support' CONFIG_BLUEZ_L2CAP $CONFIG_BLUEZ
+      source drivers/bluetooth/Config.in
+   fi
+   endmenu
+fi
+
diff -u --recursive --new-file v2.4.5/linux/net/bluetooth/Makefile linux/net/bluetooth/Makefile
--- v2.4.5/linux/net/bluetooth/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/net/bluetooth/Makefile	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,20 @@
+#
+# Makefile for the Bluetooth subsystem
+#
+O_TARGET	:= bluetooth.o
+
+list-multi	:= hci.o l2cap.o
+export-objs	:= syms.o
+hci-objs	:= af_bluetooth.o hci_core.o hci_sock.o lib.o syms.o
+l2cap-objs	:= l2cap_core.o l2cap_proc.o
+
+obj-$(CONFIG_BLUEZ) += hci.o
+obj-$(CONFIG_BLUEZ_L2CAP) += l2cap.o
+
+include $(TOPDIR)/Rules.make
+
+hci.o: $(hci-objs)
+	$(LD) -r -o $@ $(hci-objs)
+
+l2cap.o: $(l2cap-objs)
+	$(LD) -r -o $@ $(l2cap-objs)
diff -u --recursive --new-file v2.4.5/linux/net/bluetooth/af_bluetooth.c linux/net/bluetooth/af_bluetooth.c
--- v2.4.5/linux/net/bluetooth/af_bluetooth.c	Wed Dec 31 16:00:00 1969
+++ linux/net/bluetooth/af_bluetooth.c	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,164 @@
+/* 
+   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 Bluetooth address family and sockets.
+ *
+ * $Id: af_bluetooth.c,v 1.1 2001/06/01 08:12:11 davem Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/malloc.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <net/sock.h>
+
+#if defined(CONFIG_KMOD)
+#include <linux/kmod.h>
+#endif
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/bluez.h>
+
+/* Bluetooth sockets */
+static struct net_proto_family *bluez_sock[BLUEZ_MAX_PROTO];
+
+int bluez_sock_register(int proto, struct net_proto_family *ops)
+{
+	if (proto > BLUEZ_MAX_PROTO)
+		return -EINVAL;
+
+	if (bluez_sock[proto])
+		return -EEXIST;
+
+	bluez_sock[proto] = ops;
+	return 0;
+}
+
+int bluez_sock_unregister(int proto)
+{
+	if (proto > BLUEZ_MAX_PROTO)
+		return -EINVAL;
+
+	if (!bluez_sock[proto])
+		return -ENOENT;
+
+	bluez_sock[proto] = NULL;
+	return 0;
+}
+
+static int bluez_sock_create(struct socket *sock, int proto)
+{
+	if (proto > BLUEZ_MAX_PROTO)
+		return -EINVAL;
+
+#if defined(CONFIG_KMOD)
+	if (!bluez_sock[proto]) {
+		char module_name[30];
+		sprintf(module_name, "bt-proto-%d", proto);
+		request_module(module_name);
+	}
+#endif
+
+	if (!bluez_sock[proto])
+		return -ENOENT;
+
+	return bluez_sock[proto]->create(sock, proto);
+}
+
+void bluez_sock_link(struct bluez_sock_list *l, struct sock *sk)
+{
+	write_lock(&l->lock);
+
+	sk->next = l->head;
+	l->head = sk;
+	sock_hold(sk);
+
+	write_unlock(&l->lock);
+}
+
+void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *sk)
+{
+	struct sock **skp;
+
+	write_lock(&l->lock);
+	for (skp = &l->head; *skp; skp = &((*skp)->next)) {
+		if (*skp == sk) {
+			*skp = sk->next;
+			__sock_put(sk);
+			break;
+		}
+	}
+	write_unlock(&l->lock);
+}
+
+struct net_proto_family bluez_sock_family_ops =
+{
+	PF_BLUETOOTH, bluez_sock_create
+};
+
+int bluez_init(void)
+{
+	INF("BlueZ HCI Core ver %s Copyright (C) 2000,2001 Qualcomm Inc",
+		 BLUEZ_VER);
+	INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+
+	proc_mkdir("bluetooth", NULL);
+
+	sock_register(&bluez_sock_family_ops);
+
+	/* Init HCI Core */
+	hci_core_init();
+
+	/* Init sockets */
+	hci_sock_init();
+
+	return 0;
+}
+
+void bluez_cleanup(void)
+{
+	/* Release socket */
+	hci_sock_cleanup();
+
+	/* Release core */
+	hci_core_cleanup();
+
+	sock_unregister(PF_BLUETOOTH);
+
+	remove_proc_entry("bluetooth", NULL);
+}
+
+#ifdef MODULE
+module_init(bluez_init);
+module_exit(bluez_cleanup);
+#endif
diff -u --recursive --new-file v2.4.5/linux/net/bluetooth/hci_core.c linux/net/bluetooth/hci_core.c
--- v2.4.5/linux/net/bluetooth/hci_core.c	Wed Dec 31 16:00:00 1969
+++ linux/net/bluetooth/hci_core.c	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,1870 @@
+/* 
+   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 Core.
+ *
+ * $Id: hci_core.c,v 1.2 2001/06/01 16:57:03 davem Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/malloc.h>
+#include <linux/poll.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <linux/interrupt.h>
+#include <linux/notifier.h>
+#include <net/sock.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>
+
+#ifndef HCI_CORE_DEBUG
+#undef  DBG
+#define DBG( A... )
+#endif
+
+static void hci_cmd_task(unsigned long arg);
+static void hci_rx_task(unsigned long arg);
+static void hci_tx_task(unsigned long arg);
+static void hci_notify(struct hci_dev *hdev, int event);
+
+static rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
+
+/* HCI device list */
+struct hci_dev *hdev_list[HCI_MAX_DEV];
+spinlock_t hdev_list_lock;
+#define GET_HDEV(a) (hdev_list[a])
+
+/* HCI protocol list */
+struct hci_proto *hproto_list[HCI_MAX_PROTO];
+#define GET_HPROTO(a) (hproto_list[a])
+
+/* HCI notifiers list */
+struct notifier_block *hci_dev_notifier;
+
+/* HCI device notifications */
+int hci_register_notifier(struct notifier_block *nb)
+{
+	int err, i;
+	struct hci_dev *hdev;
+
+	if ((err = notifier_chain_register(&hci_dev_notifier, nb)))
+		return err;
+
+	/* Notify about already registered devices */
+	spin_lock(&hdev_list_lock);
+	for (i = 0; i < HCI_MAX_DEV; i++) {
+		if (!(hdev = GET_HDEV(i)))
+			continue;
+		if (hdev->flags & HCI_UP)
+			(*nb->notifier_call)(nb, HCI_DEV_UP, hdev);
+	}
+	spin_unlock(&hdev_list_lock);
+
+	return 0;
+}
+
+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)
+{
+	notifier_call_chain(&hci_dev_notifier, event, hdev);
+}
+
+/* Get HCI device by index (device is locked on return)*/
+struct hci_dev *hci_dev_get(int index)
+{
+	struct hci_dev *hdev;
+	DBG("%d", index);
+
+	if (index < 0 || index >= HCI_MAX_DEV)
+		return NULL;
+
+	spin_lock(&hdev_list_lock);
+	if ((hdev = GET_HDEV(index)))
+		hci_dev_hold(hdev);
+	spin_unlock(&hdev_list_lock);
+
+	return hdev;
+}
+
+/* Flush inquiry cache */
+void inquiry_cache_flush(struct inquiry_cache *cache)
+{
+	struct inquiry_entry *next = cache->list, *e;
+
+	DBG("cache %p", cache);
+
+	cache->list = NULL;
+	while ((e = next)) {
+		next = e->next;
+		kfree(e);
+	}
+}
+
+/* Lookup by bdaddr.
+ * Cache must be locked. */
+static struct inquiry_entry * __inquiry_cache_lookup(struct inquiry_cache *cache, bdaddr_t *bdaddr)
+{
+	struct inquiry_entry *e;
+
+	DBG("cache %p, %s", cache, batostr(bdaddr));
+
+	for (e = cache->list; e; e = e->next)
+		if (!bacmp(&e->info.bdaddr, bdaddr))
+			break;
+
+	return e;
+}
+
+static void inquiry_cache_update(struct inquiry_cache *cache, inquiry_info *info)
+{
+	struct inquiry_entry *e;
+
+	DBG("cache %p, %s", cache, batostr(&info->bdaddr));
+
+	inquiry_cache_lock(cache);
+
+	if (!(e = __inquiry_cache_lookup(cache, &info->bdaddr))) {
+		/* Entry not in the cache. Add new one. */
+		if (!(e = kmalloc(sizeof(struct inquiry_entry), GFP_ATOMIC)))
+			goto unlock;
+		memset(e, 0, sizeof(struct inquiry_entry));
+		e->next     = cache->list;
+		cache->list = e;
+	}
+
+	memcpy(&e->info, info, sizeof(inquiry_info));
+	e->timestamp = jiffies;
+	cache->timestamp = jiffies;
+unlock:
+	inquiry_cache_unlock(cache);
+}
+
+static int inquiry_cache_dump(struct inquiry_cache *cache, int num, __u8 *buf)
+{
+	inquiry_info *info = (inquiry_info *) buf;
+	struct inquiry_entry *e;
+	int copied = 0;
+
+	inquiry_cache_lock(cache);
+
+	for (e = cache->list; e && copied < num; e = e->next, copied++)
+		memcpy(info++, &e->info, sizeof(inquiry_info));
+
+	inquiry_cache_unlock(cache);
+
+	DBG("cache %p, copied %d", cache, copied);
+	return copied;
+}
+
+/* --------- BaseBand connections --------- */
+static struct hci_conn *hci_conn_add(struct hci_dev *hdev, __u16 handle, 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);
+		return NULL;
+	}
+
+	if (!(conn = kmalloc(sizeof(struct hci_conn), GFP_ATOMIC)))
+		return NULL;
+	memset(conn, 0, sizeof(struct hci_conn));
+
+	bacpy(&conn->dst, dst);
+	conn->handle = handle;
+	conn->hdev   = hdev;
+
+	skb_queue_head_init(&conn->acl_q);
+	skb_queue_head_init(&conn->sco_q);
+
+	if (conn_hash_add(&hdev->conn_hash, handle, conn)) {
+		hci_dev_hold(hdev);
+		return conn;
+	} else {
+		kfree(conn);
+		return NULL;
+	}
+}
+
+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);
+
+		/* Unacked frames */
+		hdev->acl_cnt += conn->acl_sent;
+	}
+
+	bluez_skb_queue_purge(&conn->acl_q);
+	bluez_skb_queue_purge(&conn->sco_q);
+
+	kfree(conn);
+	return 0;
+}
+
+/* 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;
+
+	DBG("hdev %s", hdev->name);
+
+	for (i = 0; i < HCI_MAX_CONN; i++) {
+		struct hci_conn *conn;
+
+		if (!(conn = conn_hash_lookup(h, i)))
+			continue;
+
+		if (hp && hp->disconn_ind)
+			hp->disconn_ind(conn, 0x16);
+		
+		hci_conn_del(hdev, conn);
+	}
+}
+
+int hci_connect(struct hci_dev *hdev, bdaddr_t *bdaddr)
+{
+	struct inquiry_cache *cache = &hdev->inq_cache;
+	struct inquiry_entry *e;
+	create_conn_cp cc;
+	__u16 clock_offset;
+
+	DBG("%s bdaddr %s", hdev->name, batostr(bdaddr));
+
+	if (!(hdev->flags & HCI_UP))
+		return -ENODEV;
+
+	inquiry_cache_lock_bh(cache);
+
+	if (!(e = __inquiry_cache_lookup(cache, bdaddr)) || inquiry_entry_age(e) > INQUIRY_ENTRY_AGE_MAX) {
+		cc.pscan_rep_mode = 0;
+		cc.pscan_mode     = 0;
+		clock_offset      = 0;
+	} else {
+		cc.pscan_rep_mode = e->info.pscan_rep_mode;
+		cc.pscan_mode     = e->info.pscan_mode;
+		clock_offset      = __le16_to_cpu(e->info.clock_offset) & 0x8000;
+	}
+
+	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.clock_offset	= __cpu_to_le16(clock_offset);
+	cc.role_switch	= 0;
+	hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, CREATE_CONN_CP_SIZE, &cc);
+
+	return 0;
+}
+
+int hci_disconnect(struct hci_conn *conn, __u8 reason)
+{
+	disconnect_cp dc;
+
+	DBG("conn %p handle %d", conn, conn->handle);
+
+	dc.handle = __cpu_to_le16(conn->handle);
+	dc.reason = reason;
+	hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_DISCONNECT, DISCONNECT_CP_SIZE, &dc);
+
+	return 0;
+}
+
+/* --------- HCI request handling ------------ */
+static __inline__ void hci_req_lock(struct hci_dev *hdev)
+{
+	down(&hdev->req_lock);
+}
+
+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)
+{
+	DBG("%s result 0x%2.2x", hdev->name, result);
+
+	if (hdev->req_status == HCI_REQ_PEND) {
+		hdev->req_result = result;
+		hdev->req_status = HCI_REQ_DONE;
+		wake_up_interruptible(&hdev->req_wait_q);
+	}
+}
+
+static __inline__ void hci_req_cancel(struct hci_dev *hdev, int err)
+{
+	DBG("%s err 0x%2.2x", hdev->name, err);
+
+	if (hdev->req_status == HCI_REQ_PEND) {
+		hdev->req_result = err;
+		hdev->req_status = HCI_REQ_CANCELED;
+		wake_up_interruptible(&hdev->req_wait_q);
+	}
+}
+
+/* Execute request and wait for completion. */
+static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
+                         unsigned long opt, __u32 timeout)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int err = 0;
+
+	DBG("%s start", hdev->name);
+
+	hdev->req_status = HCI_REQ_PEND;
+
+	add_wait_queue(&hdev->req_wait_q, &wait);
+	current->state = TASK_INTERRUPTIBLE;
+
+	req(hdev, opt);
+	schedule_timeout(timeout);
+
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&hdev->req_wait_q, &wait);
+
+	if (signal_pending(current))
+		return -EINTR;
+
+	switch (hdev->req_status) {
+	case HCI_REQ_DONE:
+		err = -bterr(hdev->req_result);
+		break;
+
+	case HCI_REQ_CANCELED:
+		err = -hdev->req_result;
+		break;
+
+	default:
+		err = -ETIMEDOUT;
+		break;
+	};
+
+	hdev->req_status = hdev->req_result = 0;
+
+	DBG("%s end: err %d", hdev->name, err);
+
+	return err;
+}
+
+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;
+
+	/* Serialize all requests */
+	hci_req_lock(hdev);
+	ret = __hci_request(hdev, req, opt, timeout);
+	hci_req_unlock(hdev);
+
+	return ret;
+}
+
+/* --------- HCI requests ---------- */
+static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
+{
+	DBG("%s %ld", hdev->name, opt);
+
+	/* Reset device */
+	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
+}
+
+static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
+{
+	set_event_flt_cp ec;
+	__u16 param;
+
+	DBG("%s %ld", hdev->name, opt);
+
+	/* Mandatory initialization */
+
+	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
+	hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BUFFER_SIZE, 0, NULL);
+
+	/* Read BD Address */
+	hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BD_ADDR, 0, NULL);
+
+	/* Optional initialization */
+
+	/* 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);
+
+	/* Page timeout ~ 20 secs */
+	param = __cpu_to_le16(0x8000);
+	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_PG_TIMEOUT, 2, &param);
+
+	/* Connection accept timeout ~20 secs */
+	param = __cpu_to_le16(0x7d00);
+	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_CA_TIMEOUT, 2, &param);
+}
+
+static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
+{
+	__u8 scan = opt;
+
+	DBG("%s %x", hdev->name, scan);
+
+	/* Inquiry and Page scans */
+	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 1, &scan);
+}
+
+static void hci_auth_req(struct hci_dev *hdev, unsigned long opt)
+{
+	__u8 auth = opt;
+
+	DBG("%s %x", hdev->name, auth);
+
+	/* Authentication */
+	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE, 1, &auth);
+}
+
+static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
+{
+	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
+	inquiry_cp ic;
+
+	DBG("%s", hdev->name);
+
+	/* Start Inquiry */
+	memcpy(&ic.lap, &ir->lap, 3);
+	ic.lenght  = ir->length;
+	ic.num_rsp = ir->num_rsp;
+	hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, INQUIRY_CP_SIZE, &ic);
+}
+
+/* Open HCI device */
+int hci_dev_open(__u16 dev)
+{
+	struct hci_dev *hdev;
+	int ret = 0;
+
+	if (!(hdev = hci_dev_get(dev)))
+		return -ENODEV;
+
+	DBG("%s %p", hdev->name, hdev);
+
+	hci_req_lock(hdev);
+
+	if (hdev->flags & HCI_UP) {
+		ret = -EALREADY;
+		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;
+
+	__hci_request(hdev, hci_reset_req, 0, HZ);
+
+	if (!(ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT))) {
+		hdev->flags |= HCI_UP;
+		hci_notify(hdev, HCI_DEV_UP);
+	}
+
+	hdev->flags &= ~HCI_INIT;
+
+done:
+	hci_req_unlock(hdev);
+	hci_dev_put(hdev);
+
+	return ret;
+}
+
+/* Close HCI device */
+int hci_dev_close(__u16 dev)
+{
+	struct hci_dev *hdev;
+
+	if (!(hdev = hci_dev_get(dev)))
+		return -ENODEV;
+
+	DBG("%s %p", hdev->name, hdev);
+
+	hci_req_cancel(hdev, ENODEV);
+	hci_req_lock(hdev);
+
+	if (!(hdev->flags & HCI_UP))
+		goto done;
+
+	/* Kill RX and TX tasks */
+	tasklet_kill(&hdev->rx_task);
+	tasklet_kill(&hdev->tx_task);
+
+	inquiry_cache_flush(&hdev->inq_cache);
+
+	hci_conn_hash_flush(hdev);
+
+	/* Clear flags */
+	hdev->flags &= (HCI_NORMAL | HCI_SOCK);
+
+	hci_notify(hdev, HCI_DEV_DOWN);
+
+	if (hdev->flush)
+		hdev->flush(hdev);
+
+	/* Reset device */
+	bluez_skb_queue_purge(&hdev->cmd_q);
+	atomic_set(&hdev->cmd_cnt, 1);
+	hdev->flags |= HCI_INIT;
+	__hci_request(hdev, hci_reset_req, 0, HZ);
+	hdev->flags &= ~HCI_INIT;
+
+	/* Kill cmd task */
+	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);
+
+	/* Drop last sent command */
+	if (hdev->cmd_sent) {
+		bluez_skb_free(hdev->cmd_sent);
+		hdev->cmd_sent = NULL;
+	}
+
+	/* After this point our queues are empty
+	 * and no tasks are scheduled.
+	 */
+	hdev->close(hdev);
+
+done:
+	hci_req_unlock(hdev);
+	hci_dev_put(hdev);
+
+	return 0;
+}
+
+/* Interface to HCI drivers */
+
+/* Register HCI device */
+int hci_register_dev(struct hci_dev *hdev)
+{
+	int i;
+
+	DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
+
+	/* Find free slot */
+	spin_lock_bh(&hdev_list_lock);
+	for (i = 0; i < HCI_MAX_DEV; i++) {
+		if (!hdev_list[i]) {
+			hdev_list[i] = hdev;
+
+			sprintf(hdev->name, "hci%d", i);
+			atomic_set(&hdev->refcnt, 0);
+			hdev->id    = i;
+			hdev->flags = HCI_NORMAL;
+
+			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);
+
+			skb_queue_head_init(&hdev->rx_q);
+			skb_queue_head_init(&hdev->cmd_q);
+			skb_queue_head_init(&hdev->raw_q);
+
+			init_waitqueue_head(&hdev->req_wait_q);
+			init_MUTEX(&hdev->req_lock);
+
+			inquiry_cache_init(&hdev->inq_cache);
+
+			conn_hash_init(&hdev->conn_hash);
+
+			memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
+
+			hci_notify(hdev, HCI_DEV_REG);
+
+			MOD_INC_USE_COUNT;
+			break;
+		}
+	}
+	spin_unlock_bh(&hdev_list_lock);
+
+	return (i == HCI_MAX_DEV) ? -1 : i;
+}
+
+/* Unregister HCI device */
+int hci_unregister_dev(struct hci_dev *hdev)
+{
+	int i;
+
+	DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
+
+	if (hdev->flags & HCI_UP)
+		hci_dev_close(hdev->id);
+
+	/* Find device slot */
+	spin_lock(&hdev_list_lock);
+	for (i = 0; i < HCI_MAX_DEV; i++) {
+		if (hdev_list[i] == hdev) {
+			hdev_list[i] = NULL;
+			MOD_DEC_USE_COUNT;
+			break;
+		}
+	}
+	spin_unlock(&hdev_list_lock);
+
+	hci_notify(hdev, HCI_DEV_UNREG);
+
+	/* Sleep while device is in use */
+	while (atomic_read(&hdev->refcnt)) {
+		int sleep_cnt = 100;
+
+		DBG("%s sleeping on lock %d", hdev->name, atomic_read(&hdev->refcnt));
+
+		sleep_on_timeout(&hdev->req_wait_q, HZ*10);
+		if (!(--sleep_cnt))
+			break;
+	}
+
+	return 0;
+}
+
+/* Interface to upper protocols */
+
+/* Register/Unregister protocols.
+ * hci_task_lock is used to ensure that no tasks are running.
+ */
+int hci_register_proto(struct hci_proto *hproto)
+{
+	int err = 0;
+
+	DBG("%p name %s", hproto, hproto->name);
+
+	if (hproto->id >= HCI_MAX_PROTO)
+		return -EINVAL;
+
+	write_lock_bh(&hci_task_lock);
+
+	if (!hproto_list[hproto->id])
+		hproto_list[hproto->id] = hproto;
+	else
+		err = -1;
+
+	write_unlock_bh(&hci_task_lock);
+
+	return err;
+}
+
+int hci_unregister_proto(struct hci_proto *hproto)
+{
+	int err = 0;
+
+	DBG("%p name %s", hproto, hproto->name);
+
+	if (hproto->id > HCI_MAX_PROTO)
+		return -EINVAL;
+
+	write_lock_bh(&hci_task_lock);
+
+	if (hproto_list[hproto->id])
+		hproto_list[hproto->id] = NULL;
+	else
+		err = -ENOENT;
+
+	write_unlock_bh(&hci_task_lock);
+
+	return err;
+}
+
+static int hci_send_frame(struct sk_buff *skb)
+{
+	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+
+	if (!hdev) {
+		bluez_skb_free(skb);
+		return -ENODEV;
+	}
+
+	DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
+
+	if (hdev->flags & HCI_SOCK)
+		hci_send_to_sock(hdev, skb);
+
+	/* Get rid of skb owner, prior to sending to the driver. */
+	skb_orphan(skb);
+
+	return hdev->send(skb);
+}
+
+/* ACL scheduler */
+static __inline__ struct hci_conn *hci_low_acl_sent(struct hci_dev *hdev, int *quote)
+{
+	struct conn_hash *h = &hdev->conn_hash;
+	struct hci_conn *conn = NULL;
+	int i, num = 0, min = 0xffff;
+
+	conn_hash_lock(h);
+	for (i = 0; i < HCI_MAX_CONN; i++) {
+		struct hci_conn *c;
+
+		if (!(c = __conn_hash_lookup(h,i)) || !skb_queue_len(&c->acl_q))
+			continue;
+		num++;
+
+		if (c->acl_sent < min) {
+			min  = c->acl_sent;
+			conn = c;
+		}
+	}
+	conn_hash_unlock(h);
+
+	if (conn) {
+		int q = hdev->acl_cnt / num;
+		*quote = q ? q : 1;
+	} else
+		*quote = 0;
+
+	DBG("conn %p quote %d", conn, *quote);
+
+	return conn;
+}
+
+static __inline__ void hci_sched_acl(struct hci_dev *hdev)
+{
+	struct hci_conn *conn;
+	struct sk_buff *skb, *frag;
+	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);
+
+				hci_send_frame(frag);
+
+				conn->acl_sent++;
+				hdev->acl_cnt--;
+				quote--;
+			} while ((frag = bluez_skb_get_frag(skb)));
+			kfree_skb(skb);
+		}
+	}
+done:
+	return;
+}
+
+/* Schedule SCO */
+static __inline__ void hci_sched_sco(struct hci_dev *hdev)
+{
+	struct conn_hash *h = &hdev->conn_hash;
+	struct sk_buff *skb;
+	int i;
+
+	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))) {
+			hci_send_frame(skb);
+			conn->sco_sent++;
+			hdev->sco_cnt--;
+		}
+	}
+	conn_hash_unlock(h);
+}
+
+/* Send raw HCI frame */
+int hci_send_raw(struct sk_buff *skb)
+{
+	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+
+	if (!hdev) {
+		bluez_skb_free(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);
+
+		return 0;
+	};
+
+	return 0;
+}
+
+/* Send HCI command */
+int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param)
+{
+	int len = HCI_COMMAND_HDR_SIZE + plen;
+	hci_command_hdr *hc;
+	struct sk_buff *skb;
+
+	DBG("%s ogf 0x%x ocf 0x%x plen %d", hdev->name, ogf, ocf, plen);
+
+	if (!(skb = bluez_skb_alloc(len, GFP_ATOMIC))) {
+		ERR("%s Can't allocate memory for HCI command", hdev->name);
+		return -ENOMEM;
+	}
+	
+	hc = (hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
+	hc->opcode = __cpu_to_le16(cmd_opcode_pack(ocf, ogf));
+	hc->plen   = plen;
+
+	if (plen)
+		memcpy(skb_put(skb, plen), param, plen);
+
+	DBG("skb len %d", skb->len);
+
+	skb->pkt_type = HCI_COMMAND_PKT;
+	skb->dev = (void *) hdev;
+	skb_queue_tail(&hdev->cmd_q, skb);
+	hci_sched_cmd(hdev);
+
+	return 0;
+}
+
+/* Send ACL data */
+
+static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
+{
+	int len = skb->len;	
+	hci_acl_hdr *ah;
+
+	ah = (hci_acl_hdr *) skb_push(skb, HCI_ACL_HDR_SIZE);
+	ah->handle = __cpu_to_le16(acl_handle_pack(handle, flags));
+	ah->dlen   = __cpu_to_le16(len);
+
+	skb->h.raw = (void *) ah;
+}
+
+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;
+
+	DBG("%s conn %p len %d flags 0x%x", hdev->name, conn, skb->len, flags);
+	DBG("frags %d", bluez_skb_frags(skb));
+
+	/* Add ACL header to all fragments */
+	flags |= ACL_START;
+	frag = skb;
+	do {
+		DBG("frag %p len %d", frag, frag->len);
+		sent += frag->len;
+
+		hci_add_acl_hdr(frag, conn->handle, flags);
+		frag->pkt_type = HCI_ACLDATA_PKT;
+		frag->dev = (void *) hdev;
+
+		flags = ACL_CONT;
+	} while ((frag = bluez_skb_next_frag(frag)));
+
+	skb_queue_tail(&conn->acl_q, skb);
+	hci_sched_tx(hdev);
+
+	return sent;
+}
+
+/* Send SCO data */
+int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
+{
+	struct hci_dev *hdev = conn->hdev;
+	hci_sco_hdr hs;
+
+	DBG("%s len %d", hdev->name, skb->len);
+
+	if (skb->len > hdev->sco_mtu) {
+		bluez_skb_free(skb);
+		return -EINVAL;
+	}
+
+	hs.handle = __cpu_to_le16(conn->handle);
+	hs.dlen   = skb->len;
+
+	skb->h.raw = skb_push(skb, HCI_SCO_HDR_SIZE);
+	memcpy(skb->h.raw, &hs, HCI_SCO_HDR_SIZE);
+
+	skb->dev = (void *) hdev;
+	skb->pkt_type = HCI_SCODATA_PKT;
+	skb_queue_tail(&conn->sco_q, skb);
+	hci_sched_tx(hdev);
+
+	return 0;
+}
+
+/* Handle HCI Event packets */
+
+/* Command Complete OGF LINK_CTL  */
+static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+{
+	DBG("%s ocf 0x%x", hdev->name, ocf);
+
+	switch (ocf) {
+	default:
+		DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
+		break;
+	};
+}
+
+/* Command Complete OGF LINK_POLICY  */
+static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+{
+	DBG("%s ocf 0x%x", hdev->name, ocf);
+
+	switch (ocf) {
+	default:
+		DBG("%s: Command complete: ogf LINK_POLICY ocf %x", hdev->name, ocf);
+		break;
+	};
+}
+
+/* Command Complete OGF HOST_CTL  */
+static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+{
+	__u8 status, param;
+
+	DBG("%s ocf 0x%x", hdev->name, ocf);
+
+	switch (ocf) {
+	case OCF_RESET:
+		status = *((__u8 *) skb->data);
+
+		hci_req_complete(hdev, status);
+		break;
+
+	case OCF_SET_EVENT_FLT:
+		status = *((__u8 *) skb->data);
+
+		if (status) {
+			DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
+		} else {
+			DBG("%s SET_EVENT_FLT succeseful", hdev->name);
+		}
+		break;
+
+	case OCF_WRITE_AUTH_ENABLE:
+		status = *((__u8 *) skb->data);
+		param  = *(SENT_CMD_PARAM(hdev));
+
+		if (!status) {
+			if (param == AUTH_ENABLED)
+				hdev->flags |= HCI_AUTH;
+			else
+				hdev->flags &= ~HCI_AUTH;
+		}
+		hci_req_complete(hdev, status);
+		break;
+
+	case OCF_WRITE_CA_TIMEOUT:
+		status = *((__u8 *) skb->data);
+
+		if (status) {
+			DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
+		} else {
+			DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
+		}
+		break;
+
+	case OCF_WRITE_PG_TIMEOUT:
+		status = *((__u8 *) skb->data);
+
+		if (status) {
+			DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
+		} else {
+			DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
+		}
+		break;
+
+	case OCF_WRITE_SCAN_ENABLE:
+		status = *((__u8 *) skb->data);
+		param  = *(SENT_CMD_PARAM(hdev));
+
+		if (!status) {
+			switch (param) {
+			case IS_ENA_PS_ENA:
+				hdev->flags |=  HCI_PSCAN | HCI_ISCAN;
+				break;
+
+			case IS_ENA_PS_DIS:
+				hdev->flags &= ~HCI_PSCAN;
+				hdev->flags |=  HCI_ISCAN;
+				break;
+
+			case IS_DIS_PS_ENA:
+				hdev->flags &= ~HCI_ISCAN;
+				hdev->flags |=  HCI_PSCAN;
+				break;
+
+			default:
+				hdev->flags &= ~(HCI_ISCAN | HCI_PSCAN);
+				break;
+			};
+		}
+		hci_req_complete(hdev, status);
+		break;
+
+	default:
+		DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
+		break;
+	};
+}
+
+/* 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;
+
+	DBG("%s ocf 0x%x", hdev->name, ocf);
+
+	switch (ocf) {
+	case OCF_READ_BUFFER_SIZE:
+		rsp = (read_buffer_size_rp *) skb->data;
+
+		if (rsp->status) {
+			DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, rsp->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);
+
+		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);
+
+		break;
+
+	case OCF_READ_BD_ADDR:
+		rap = (read_bd_addr_rp *) skb->data;
+
+		if (!rap->status) {
+			bacpy(&hdev->bdaddr, &rap->bdaddr);
+		} else {
+			DBG("%s: READ_BD_ADDR failed %d", hdev->name, rap->status);
+		}
+
+		hci_req_complete(hdev, rap->status);
+		break;
+
+	default:
+		DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
+		break;
+	};
+}
+
+/* Command Status OGF LINK_CTL  */
+static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
+{
+	struct hci_proto * hp;
+
+	DBG("%s ocf 0x%x", hdev->name, ocf);
+
+	switch (ocf) {
+	case OCF_CREATE_CONN:
+		if (status) {
+			create_conn_cp *cc = (void *) SENT_CMD_PARAM(hdev);
+			DBG("%s Create connection error: status 0x%x %s", hdev->name,
+			    status, batostr(&cc->bdaddr));
+
+			/* Notify upper protocols */
+			if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_cfm) {
+				tasklet_disable(&hdev->tx_task);
+				hp->connect_cfm(hdev, &cc->bdaddr, status, NULL);
+				tasklet_enable(&hdev->tx_task);
+			}
+		}
+		break;
+
+	case OCF_INQUIRY:
+		if (status) {
+			DBG("%s Inquiry error: status 0x%x", hdev->name, status);
+			hci_req_complete(hdev, status);
+		}
+		break;
+
+	default:
+		DBG("%s Command status: ogf LINK_CTL ocf %x", hdev->name, ocf);
+		break;
+	};
+}
+
+/* Command Status OGF LINK_POLICY */
+static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
+{
+	DBG("%s ocf 0x%x", hdev->name, ocf);
+
+	switch (ocf) {
+	default:
+		DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf);
+		break;
+	};
+}
+
+/* Command Status OGF HOST_CTL */
+static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
+{
+	DBG("%s ocf 0x%x", hdev->name, ocf);
+
+	switch (ocf) {
+	default:
+		DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
+		break;
+	};
+}
+
+/* Command Status OGF INFO_PARAM  */
+static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
+{
+	DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
+
+	switch (ocf) {
+	default:
+		DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
+		break;
+	};
+}
+
+/* Inquiry Complete */
+static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	__u8 status = *((__u8 *) skb->data);
+
+	DBG("%s status %d", hdev->name, status);
+
+	hci_req_complete(hdev, status);
+}
+
+/* Inquiry Result */
+static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	inquiry_info *info = (inquiry_info *) (skb->data + 1);
+	int num_rsp = *((__u8 *) skb->data);
+
+	DBG("%s num_rsp %d", hdev->name, num_rsp);
+
+	for (; num_rsp; num_rsp--)
+		inquiry_cache_update(&hdev->inq_cache, info++);
+}
+
+/* Connect Request */
+static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	evt_conn_request *cr = (evt_conn_request *) skb->data;
+	struct hci_proto *hp;
+	accept_conn_req_cp ac;
+	int accept = 0;
+
+	DBG("%s Connection request: %s type 0x%x", hdev->name, batostr(&cr->bdaddr), cr->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 (accept) {
+		/* Connection accepted by upper layer */
+		bacpy(&ac.bdaddr, &cr->bdaddr);
+		ac.role = 0x01; /* Remain slave */
+		hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, ACCEPT_CONN_REQ_CP_SIZE, &ac);
+	} else {
+		/* Connection rejected by upper layer */
+		/* FIXME: 
+		 * Should we use HCI reject here ?
+		 */
+		return;
+	}
+}
+
+/* Connect Complete */
+static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	evt_conn_complete *cc = (evt_conn_complete *) skb->data;
+	struct hci_conn *conn = NULL;
+	struct hci_proto *hp;
+
+	DBG("%s", hdev->name);
+
+	tasklet_disable(&hdev->tx_task);
+
+	if (!cc->status)
+ 		conn = hci_conn_add(hdev, __le16_to_cpu(cc->handle), &cc->bdaddr);
+
+	/* Notify upper protocols */
+	if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_cfm)
+		hp->connect_cfm(hdev, &cc->bdaddr, cc->status, conn);
+
+	tasklet_enable(&hdev->tx_task);
+}
+
+/* Disconnect Complete */
+static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	evt_disconn_complete *dc = (evt_disconn_complete *) skb->data;
+	struct hci_conn *conn = NULL;
+	struct hci_proto *hp;
+	__u16 handle = __le16_to_cpu(dc->handle);
+
+	DBG("%s", hdev->name);
+
+	if (!dc->status && (conn = conn_hash_lookup(&hdev->conn_hash, handle))) {
+		tasklet_disable(&hdev->tx_task);
+
+		/* Notify upper protocols */
+		if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
+			hp->disconn_ind(conn, dc->reason);
+
+		hci_conn_del(hdev, conn);
+
+		tasklet_enable(&hdev->tx_task);
+	}
+}
+
+/* Number of completed packets */
+static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	evt_num_comp_pkts *nc = (evt_num_comp_pkts *) skb->data;
+	__u16 *ptr;
+	int i;
+
+	skb_pull(skb, EVT_NUM_COMP_PKTS_SIZE);
+
+	DBG("%s num_hndl %d", hdev->name, nc->num_hndl);
+
+	if (skb->len < nc->num_hndl * 4) {
+		DBG("%s bad parameters", hdev->name);
+		return;
+	}
+
+	tasklet_disable(&hdev->tx_task);
+
+	for (i = 0, ptr = (__u16 *) skb->data; i < nc->num_hndl; i++) {
+		struct hci_conn *conn;
+		__u16 handle, count;
+
+		handle = __le16_to_cpu(*ptr++);
+		count  = __le16_to_cpu(*ptr++);
+
+		hdev->acl_cnt += count;
+
+		if ((conn = conn_hash_lookup(&hdev->conn_hash, handle)))
+			conn->acl_sent -= count;
+	}
+
+	tasklet_enable(&hdev->tx_task);
+	
+	hci_sched_tx(hdev);
+}
+
+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;
+	evt_cmd_complete *ec;
+	__u16 opcode, ocf, ogf;
+
+	skb_pull(skb, HCI_EVENT_HDR_SIZE);
+
+	DBG("%s evt 0x%x", hdev->name, he->evt);
+
+	switch (he->evt) {
+	case EVT_NUM_COMP_PKTS:
+		hci_num_comp_pkts_evt(hdev, skb);
+		break;
+
+	case EVT_INQUIRY_COMPLETE:
+		hci_inquiry_complete_evt(hdev, skb);
+		break;
+
+	case EVT_INQUIRY_RESULT:
+		hci_inquiry_result_evt(hdev, skb);
+		break;
+
+	case EVT_CONN_REQUEST:
+		hci_conn_request_evt(hdev, skb);
+		break;
+
+	case EVT_CONN_COMPLETE:
+		hci_conn_complete_evt(hdev, skb);
+		break;
+
+	case EVT_DISCONN_COMPLETE:
+		hci_disconn_complete_evt(hdev, skb);
+		break;
+
+	case EVT_CMD_STATUS:
+		cs = (evt_cmd_status *) skb->data;
+		skb_pull(skb, EVT_CMD_STATUS_SIZE);
+				
+		opcode = __le16_to_cpu(cs->opcode);
+		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);
+			break;
+
+		case OGF_HOST_CTL:
+			hci_cs_host_ctl(hdev, ocf, cs->status);
+			break;
+
+		case OGF_LINK_CTL:
+			hci_cs_link_ctl(hdev, ocf, cs->status);
+			break;
+
+		case OGF_LINK_POLICY:
+			hci_cs_link_policy(hdev, ocf, cs->status);
+			break;
+
+		default:
+			DBG("%s Command Status OGF %x", hdev->name, ogf);
+			break;
+		};
+
+		break;
+
+	case EVT_CMD_COMPLETE:
+		ec = (evt_cmd_complete *) skb->data;
+		skb_pull(skb, EVT_CMD_COMPLETE_SIZE);
+
+		opcode = __le16_to_cpu(ec->opcode);
+		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);
+			break;
+
+		case OGF_HOST_CTL:
+			hci_cc_host_ctl(hdev, ocf, skb);
+			break;
+
+		case OGF_LINK_CTL:
+			hci_cc_link_ctl(hdev, ocf, skb);
+			break;
+
+		case OGF_LINK_POLICY:
+			hci_cc_link_policy(hdev, ocf, skb);
+			break;
+
+		default:
+			DBG("%s Command Completed OGF %x", hdev->name, ogf);
+			break;
+		};
+
+		break;
+	};
+
+	bluez_skb_free(skb);
+	hdev->stat.evt_rx++;
+}
+
+/* ACL data packet */
+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;
+	__u16 handle, flags;
+
+	skb_pull(skb, HCI_ACL_HDR_SIZE);
+
+	handle = __le16_to_cpu(ah->handle);
+	flags  = acl_flags(handle);
+	handle = acl_handle(handle);
+
+	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;
+
+		/* Send to upper protocol */
+		if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->recv_acldata)
+			hp->recv_acldata(conn, skb, flags);
+		else
+			bluez_skb_free(skb);
+	}
+
+	hdev->stat.acl_rx++;
+}
+
+/* SCO data packet */
+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);
+	}
+
+	hdev->stat.sco_rx++;
+}
+
+/* ----- HCI tasks ----- */
+void hci_rx_task(unsigned long arg)
+{
+	struct hci_dev *hdev = (struct hci_dev *) arg;
+	struct sk_buff *skb;
+
+	DBG("%s", hdev->name);
+
+	read_lock(&hci_task_lock);
+
+	while ((skb = skb_dequeue(&hdev->rx_q))) {
+		if (hdev->flags & HCI_SOCK) {
+			/* Send copy to the sockets */
+			hci_send_to_sock(hdev, skb);
+		}
+
+		if (hdev->flags & HCI_INIT) {
+			/* Don't process data packets in this states. */
+			switch (skb->pkt_type) {
+			case HCI_ACLDATA_PKT:
+			case HCI_SCODATA_PKT:
+				bluez_skb_free(skb);
+				continue;
+			};
+		}
+
+		if (hdev->flags & HCI_NORMAL) {
+			/* Handle frame */
+			switch (skb->pkt_type) {
+			case HCI_EVENT_PKT:
+				hci_event_packet(hdev, skb);
+				break;
+
+			case HCI_ACLDATA_PKT:
+				DBG("%s ACL data packet", hdev->name);
+				hci_acldata_packet(hdev, skb);
+				break;
+
+			case HCI_SCODATA_PKT:
+				DBG("%s SCO data packet", hdev->name);
+				hci_scodata_packet(hdev, skb);
+				break;
+
+			default:
+				bluez_skb_free(skb);
+				break;
+			};
+		} else {
+			bluez_skb_free(skb);
+		}
+	}
+
+	read_unlock(&hci_task_lock);
+}
+
+static void hci_tx_task(unsigned long arg)
+{
+	struct hci_dev *hdev = (struct hci_dev *) arg;
+	struct sk_buff *skb;
+
+	read_lock(&hci_task_lock);
+
+	DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt);
+
+	/* Schedule queues and send stuff to HCI driver */
+
+	hci_sched_acl(hdev);
+
+	hci_sched_sco(hdev);
+
+	/* Send next queued raw(unknown type) packet */
+	while ((skb = skb_dequeue(&hdev->raw_q)))
+		hci_send_frame(skb);
+
+	read_unlock(&hci_task_lock);
+}
+
+static void hci_cmd_task(unsigned long arg)
+{
+	struct hci_dev *hdev = (struct hci_dev *) arg;
+	struct sk_buff *skb;
+
+	DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
+
+	/* 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->cmd_sent = bluez_skb_clone(skb, GFP_ATOMIC))) {
+			atomic_dec(&hdev->cmd_cnt);
+			hci_send_frame(skb);
+		} else {
+			skb_queue_head(&hdev->cmd_q, skb);
+			hci_sched_cmd(hdev);
+		}
+	}
+}
+
+/* Receive frame from HCI drivers */
+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);
+		return -1;
+	}
+
+	DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
+
+	/* Incomming skb */
+	bluez_cb(skb)->incomming = 1;
+
+	/* Queue frame for rx task */
+	skb_queue_tail(&hdev->rx_q, skb);
+	hci_sched_rx(hdev);
+
+	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 */
+	spin_lock_init(&hdev_list_lock);
+
+	return 0;
+}
+
+int hci_core_cleanup(void)
+{
+	return 0;
+}
diff -u --recursive --new-file v2.4.5/linux/net/bluetooth/hci_sock.c linux/net/bluetooth/hci_sock.c
--- v2.4.5/linux/net/bluetooth/hci_sock.c	Wed Dec 31 16:00:00 1969
+++ linux/net/bluetooth/hci_sock.c	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,511 @@
+/* 
+   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 socket layer.
+ *
+ * $Id: hci_sock.c,v 1.1 2001/06/01 08:12:11 davem Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/malloc.h>
+#include <linux/poll.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <linux/tqueue.h>
+#include <linux/interrupt.h>
+#include <linux/socket.h>
+#include <linux/ioctl.h>
+#include <net/sock.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>
+
+#ifndef HCI_SOCK_DEBUG
+#undef  DBG
+#define DBG( A... )
+#endif
+
+/* HCI socket interface */
+
+static struct bluez_sock_list hci_sk_list = {
+	lock: RW_LOCK_UNLOCKED
+};
+
+static struct sock *hci_sock_lookup(struct hci_dev *hdev)
+{
+	struct sock *sk;
+
+	read_lock(&hci_sk_list.lock);
+	for (sk = hci_sk_list.head; sk; sk = sk->next) {
+		if (hci_pi(sk)->hdev == hdev)
+			break;
+	}
+	read_unlock(&hci_sk_list.lock);
+	return sk;
+}
+
+/* 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) {
+		if (sk->state != BT_BOUND || hci_pi(sk)->hdev != hdev)
+			continue;
+
+		/* Don't send frame to the socket it came from */
+		if (skb->sk == sk)
+			continue;
+
+		if (!(nskb = bluez_skb_clone(skb, GFP_ATOMIC)))
+			continue;
+
+		/* Put type byte before the data */
+		memcpy(skb_push(nskb, 1), &nskb->pkt_type, 1);
+
+		skb_queue_tail(&sk->receive_queue, nskb);
+		sk->data_ready(sk, nskb->len);
+	}
+	read_unlock(&hci_sk_list.lock);
+}
+
+static int hci_sock_release(struct socket *sock)
+{
+	struct sock *sk = sock->sk;
+	struct hci_dev *hdev = hci_pi(sk)->hdev;
+
+	DBG("sock %p sk %p", sock, sk);
+
+	if (!sk)
+		return 0;
+
+	bluez_sock_unlink(&hci_sk_list, sk);
+
+	if (hdev) {
+		if (!hci_sock_lookup(hdev))
+			hdev->flags &= ~HCI_SOCK;
+
+		hci_dev_put(hdev);
+	}
+
+	sock_orphan(sk);
+
+	bluez_skb_queue_purge(&sk->receive_queue);
+	bluez_skb_queue_purge(&sk->write_queue);
+
+	sock_put(sk);
+
+	MOD_DEC_USE_COUNT;
+
+	return 0;
+}
+
+static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+{
+	struct sock *sk = sock->sk;
+	struct hci_dev *hdev = hci_pi(sk)->hdev;
+	__u32 mode;
+
+	DBG("cmd %x", cmd);
+
+	switch (cmd) {
+	case HCIGETINFO:
+		return hci_dev_info(arg);
+
+	case HCIGETDEVLIST:
+		return hci_dev_list(arg);
+
+	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:
+		if (!capable(CAP_NET_ADMIN))
+			return -EACCES;
+
+		if (!hdev)
+			return -EBADFD;
+
+		if (arg)
+			mode = HCI_RAW;
+		else
+			mode = HCI_NORMAL;
+
+		return hci_dev_setmode(hdev, mode);
+
+	case HCIINQUIRY:
+		return hci_inquiry(arg);
+
+	default:
+		return -EINVAL;
+	};
+}
+
+static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
+{
+	struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
+	struct sock *sk = sock->sk;
+	struct hci_dev *hdev = NULL;
+
+	DBG("sock %p sk %p", sock, sk);
+
+	if (!haddr || haddr->hci_family != AF_BLUETOOTH)
+		return -EINVAL;
+
+	if (hci_pi(sk)->hdev) {
+		/* Already bound */
+		return 0;
+	}
+
+	if (haddr->hci_dev != HCI_DEV_NONE) {
+		if (!(hdev = hci_dev_get(haddr->hci_dev)))
+			return -ENODEV;
+
+		hdev->flags |= HCI_SOCK;
+	}
+
+	hci_pi(sk)->hdev = hdev;
+	sk->state = BT_BOUND;
+
+	return 0;
+}
+
+static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int *addr_len, int peer)
+{
+	struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
+	struct sock *sk = sock->sk;
+
+	DBG("sock %p sk %p", sock, sk);
+
+	*addr_len = sizeof(*haddr);
+	haddr->hci_family = AF_BLUETOOTH;
+	haddr->hci_dev    = hci_pi(sk)->hdev->id;
+
+	return 0;
+}
+
+static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
+                            struct scm_cookie *scm)
+{
+	struct sock *sk = sock->sk;
+	struct hci_dev *hdev = hci_pi(sk)->hdev;
+	struct sk_buff *skb;
+	int err;
+
+	DBG("sock %p sk %p", sock, sk);
+
+	if (msg->msg_flags & MSG_OOB)
+		return -EOPNOTSUPP;
+
+	if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
+		return -EINVAL;
+
+	if (!hdev)
+		return -EBADFD;
+
+	if (!(skb = bluez_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
+		return err;
+
+	if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
+		kfree_skb(skb);
+		return -EFAULT;
+	}
+
+	skb->dev = (void *) hdev;
+	skb->pkt_type = *((unsigned char *) skb->data);
+	skb_pull(skb, 1);
+
+	/* Send frame to HCI core */
+	hci_send_raw(skb);
+
+	return len;
+}
+
+static __inline__ void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
+{
+	__u32 flags = hci_pi(sk)->cmsg_flags;
+
+	if (flags & HCI_CMSG_DIR)
+        	put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(int), &bluez_cb(skb)->incomming);
+}
+ 
+static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len,
+                            int flags, struct scm_cookie *scm)
+{
+	int noblock = flags & MSG_DONTWAIT;
+	struct sock *sk = sock->sk;
+	struct sk_buff *skb;
+	int copied, err;
+
+	DBG("sock %p sk %p", sock, sk);
+
+	if (flags & (MSG_OOB | MSG_PEEK))
+		return -EOPNOTSUPP;
+
+	if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
+		return err;
+
+	msg->msg_namelen = 0;
+
+	copied = skb->len;
+	if (len < copied) {
+		msg->msg_flags |= MSG_TRUNC;
+		copied = len;
+	}
+
+	skb->h.raw = skb->data;
+	err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+
+	if (hci_pi(sk)->cmsg_flags)
+		hci_sock_cmsg(sk, msg, skb);
+
+	skb_free_datagram(sk, skb);
+
+	return err ? : copied;
+}
+
+int hci_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
+{
+	struct sock *sk = sock->sk;
+	int err = 0, opt;
+
+	if (get_user(opt, (int *)optval))
+		return -EFAULT;
+
+	DBG("sk %p, opt %d", sk, opt);
+
+	lock_sock(sk);
+
+	switch (optname) {
+	case HCI_DATA_DIR:
+		if (opt)
+			hci_pi(sk)->cmsg_flags |= HCI_CMSG_DIR;
+		else
+			hci_pi(sk)->cmsg_flags &= ~HCI_CMSG_DIR;
+		break;
+
+	default:
+		err = -ENOPROTOOPT;
+		break;
+	};
+
+	release_sock(sk);
+	return err;
+}
+
+int hci_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
+{
+	struct sock *sk = sock->sk;
+	int len, opt; 
+
+	if (get_user(len, optlen))
+		return -EFAULT;
+
+	switch (optname) {
+	case HCI_DATA_DIR:
+		if (hci_pi(sk)->cmsg_flags & HCI_CMSG_DIR)
+			opt = 1;
+		else 
+			opt = 0;
+
+		if (put_user(opt, optval))
+			return -EFAULT;
+		break;
+
+	default:
+		return -ENOPROTOOPT;
+		break;
+	};
+
+	return 0;
+}
+
+struct proto_ops hci_sock_ops = {
+	family:		PF_BLUETOOTH,
+	release:	hci_sock_release,
+	bind:		hci_sock_bind,
+	getname:	hci_sock_getname,
+	sendmsg:	hci_sock_sendmsg,
+	recvmsg:	hci_sock_recvmsg,
+	ioctl:		hci_sock_ioctl,
+	poll:		datagram_poll,
+	listen:		sock_no_listen,
+	shutdown:	sock_no_shutdown,
+	setsockopt:	hci_sock_setsockopt,
+	getsockopt:	hci_sock_getsockopt,
+	connect:	sock_no_connect,
+	socketpair:	sock_no_socketpair,
+	accept:		sock_no_accept,
+	mmap:		sock_no_mmap
+};
+
+static int hci_sock_create(struct socket *sock, int protocol)
+{
+	struct sock *sk;
+
+	DBG("sock %p", sock);
+
+	if (sock->type != SOCK_RAW)
+		return -ESOCKTNOSUPPORT;
+
+	sock->ops = &hci_sock_ops;
+
+	if (!(sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, 1)))
+		return -ENOMEM;
+
+	sock->state = SS_UNCONNECTED;
+	sock_init_data(sock, sk);
+
+	memset(&sk->protinfo, 0, sizeof(struct hci_pinfo));
+	sk->destruct = NULL;
+	sk->protocol = protocol;
+	sk->state    = BT_OPEN;
+
+	bluez_sock_link(&hci_sk_list, sk);
+
+	MOD_INC_USE_COUNT;
+
+	return 0;
+}
+
+static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+	struct hci_dev *hdev = (struct hci_dev *) ptr;
+	struct sk_buff *skb;
+
+	DBG("hdev %s event %ld", hdev->name, event);
+
+	/* Send event to sockets */
+	if ((skb = bluez_skb_alloc(HCI_EVENT_HDR_SIZE + EVT_HCI_DEV_EVENT_SIZE, GFP_ATOMIC))) {
+		hci_event_hdr eh = { EVT_HCI_DEV_EVENT, EVT_HCI_DEV_EVENT_SIZE };
+		evt_hci_dev_event he = { event, hdev->id };
+
+		skb->pkt_type = HCI_EVENT_PKT;
+		memcpy(skb_put(skb, HCI_EVENT_HDR_SIZE), &eh, HCI_EVENT_HDR_SIZE);
+		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);
+	}
+
+	if (event == HCI_DEV_UNREG) {
+		struct sock *sk;
+
+		/* Detach sockets from device */
+		read_lock(&hci_sk_list.lock);
+		for (sk = hci_sk_list.head; sk; sk = sk->next) {
+			if (hci_pi(sk)->hdev == hdev) {
+				hci_pi(sk)->hdev = NULL;
+				sk->err = EPIPE;
+				sk->state = BT_OPEN;
+				sk->state_change(sk);
+
+				hci_dev_put(hdev);
+			}
+		}
+		read_unlock(&hci_sk_list.lock);
+	}
+
+	return NOTIFY_DONE;
+}
+
+struct net_proto_family hci_sock_family_ops = {
+	family: PF_BLUETOOTH,
+	create: hci_sock_create
+};
+
+struct notifier_block hci_sock_nblock = {
+	notifier_call: hci_sock_dev_event
+};
+
+int hci_sock_init(void)
+{
+	if (bluez_sock_register(BTPROTO_HCI, &hci_sock_family_ops)) {
+		ERR("Can't register HCI socket");
+		return -EPROTO;
+	}
+
+	hci_register_notifier(&hci_sock_nblock);
+
+	return 0;
+}
+
+int hci_sock_cleanup(void)
+{
+	if (bluez_sock_unregister(BTPROTO_HCI))
+		ERR("Can't unregister HCI socket");
+
+	hci_unregister_notifier(&hci_sock_nblock);
+
+	return 0;
+}
diff -u --recursive --new-file v2.4.5/linux/net/bluetooth/l2cap_core.c linux/net/bluetooth/l2cap_core.c
--- v2.4.5/linux/net/bluetooth/l2cap_core.c	Wed Dec 31 16:00:00 1969
+++ linux/net/bluetooth/l2cap_core.c	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,2202 @@
+/* 
+   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 L2CAP core and sockets.
+ *
+ * $Id: l2cap_core.c,v 1.1 2001/06/01 08:12:11 davem Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/malloc.h>
+#include <linux/poll.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <linux/interrupt.h>
+#include <linux/socket.h>
+#include <linux/skbuff.h>
+#include <linux/proc_fs.h>
+#include <linux/list.h>
+#include <net/sock.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/l2cap.h>
+#include <net/bluetooth/l2cap_core.h>
+
+#ifndef L2CAP_DEBUG
+#undef  DBG
+#define DBG( A... )
+#endif
+
+struct proto_ops l2cap_sock_ops;
+
+struct bluez_sock_list l2cap_sk_list = {
+	lock: RW_LOCK_UNLOCKED
+};
+
+struct list_head l2cap_iff_list = LIST_HEAD_INIT(l2cap_iff_list);
+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 void l2cap_chan_del(struct sock *sk, int err);
+static int  l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len);
+
+static void l2cap_sock_close(struct sock *sk);
+static void l2cap_sock_kill(struct sock *sk);
+
+static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data);
+static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data);
+
+/* -------- L2CAP interfaces & routing --------- */
+/* Add/delete L2CAP interface.
+ * Must be called with locked rt_lock
+ */ 
+
+static void l2cap_iff_add(struct hci_dev *hdev)
+{
+	struct l2cap_iff *iff;
+
+	DBG("%s", hdev->name);
+
+	DBG("iff_list %p next %p prev %p", &l2cap_iff_list, l2cap_iff_list.next, l2cap_iff_list.prev);
+
+	/* Allocate new interface and lock HCI device */
+	if (!(iff = kmalloc(sizeof(struct l2cap_iff), GFP_KERNEL))) {
+		ERR("Can't allocate new interface %s", hdev->name);
+		return;
+	}
+	memset(iff, 0, sizeof(struct l2cap_iff));
+
+	hci_dev_hold(hdev);
+	hdev->l2cap_data = iff;
+	iff->hdev   = hdev;
+	iff->mtu    = hdev->acl_mtu - HCI_ACL_HDR_SIZE;
+	iff->bdaddr = &hdev->bdaddr;
+
+	spin_lock_init(&iff->lock);
+	INIT_LIST_HEAD(&iff->conn_list);
+
+	list_add(&iff->list, &l2cap_iff_list);
+}
+
+static void l2cap_iff_del(struct hci_dev *hdev)
+{
+	struct l2cap_iff *iff;
+
+	if (!(iff = hdev->l2cap_data))
+		return;
+
+	DBG("%s iff %p", hdev->name, iff);
+
+	list_del(&iff->list);
+
+	l2cap_iff_lock(iff);
+
+	/* Drop connections */
+	while (!list_empty(&iff->conn_list)) {
+		struct l2cap_conn *c;
+
+		c = list_entry(iff->conn_list.next, struct l2cap_conn, list);
+		l2cap_conn_del(c, ENODEV);
+	}
+
+	l2cap_iff_unlock(iff);
+
+	/* Unlock HCI device */
+	hdev->l2cap_data = NULL;
+	hci_dev_put(hdev);
+
+	kfree(iff);
+}
+
+/* Get route. Returns L2CAP interface.
+ * Must be called with locked rt_lock
+ */
+static struct l2cap_iff *l2cap_get_route(bdaddr_t *src, bdaddr_t *dst)
+{
+	struct list_head *p;
+	int use_src;
+
+	DBG("%s -> %s", batostr(src), batostr(dst));
+
+	use_src = bacmp(src, BDADDR_ANY) ? 0 : 1;
+	
+	/* Simple routing: 
+	 * 	No source address - find interface with bdaddr != dst 
+	 *	Source address 	  - find interface with bdaddr == src 
+	 */
+
+	list_for_each(p, &l2cap_iff_list) {
+		struct l2cap_iff *iff;
+
+		iff = list_entry(p, struct l2cap_iff, list);
+
+		if (use_src && !bacmp(iff->bdaddr, src))
+			return iff;
+		else if (bacmp(iff->bdaddr, dst))
+			return iff;
+	}
+	return NULL;
+}
+
+/* ----- L2CAP timers ------ */
+static void l2cap_timeout(unsigned long arg)
+{
+	struct sock *sk = (struct sock *) arg;
+
+	DBG("sock %p state %d", sk, sk->state);
+
+	bh_lock_sock(sk);
+	switch (sk->state) {
+	case BT_DISCONN:
+		l2cap_chan_del(sk, ETIMEDOUT);
+		break;
+
+	default:
+		sk->err = ETIMEDOUT;
+		sk->state_change(sk);
+		break;
+	};
+	bh_unlock_sock(sk);
+
+	l2cap_sock_kill(sk);
+	sock_put(sk);
+}
+
+static void l2cap_set_timer(struct sock *sk, long timeout)
+{
+	DBG("sock %p state %d timeout %ld", sk, sk->state, timeout);
+
+	if (!mod_timer(&sk->timer, jiffies + timeout))
+		sock_hold(sk);
+}
+
+static void l2cap_clear_timer(struct sock *sk)
+{
+	DBG("sock %p state %d", sk, sk->state);
+
+	if (timer_pending(&sk->timer) && del_timer(&sk->timer))
+		__sock_put(sk);
+}
+
+static void l2cap_init_timer(struct sock *sk)
+{
+	init_timer(&sk->timer);
+	sk->timer.function = l2cap_timeout;
+	sk->timer.data = (unsigned long)sk;
+}
+
+/* -------- L2CAP connections --------- */
+/* Add new connection to the interface.
+ * Interface must be locked
+ */
+static struct l2cap_conn *l2cap_conn_add(struct l2cap_iff *iff, bdaddr_t *dst)
+{
+	struct l2cap_conn *conn;
+	bdaddr_t *src = iff->bdaddr;
+
+	if (!(conn = kmalloc(sizeof(struct l2cap_conn), GFP_KERNEL)))
+		return NULL;
+
+	memset(conn, 0, sizeof(struct l2cap_conn));
+
+	conn->state = BT_OPEN;
+	conn->iff   = iff;
+	bacpy(&conn->src, src);
+	bacpy(&conn->dst, dst);
+
+	spin_lock_init(&conn->lock);
+	conn->chan_list.lock = RW_LOCK_UNLOCKED;
+
+	__l2cap_conn_link(iff, conn);
+
+	DBG("%s -> %s, %p", batostr(src), batostr(dst), conn);
+
+	MOD_INC_USE_COUNT;
+
+	return conn;
+}
+
+/* Delete connection on the interface.
+ * Interface must be locked
+ */
+static int l2cap_conn_del(struct l2cap_conn *conn, int err)
+{
+	struct sock *sk;
+
+	DBG("conn %p, state %d, err %d", conn, conn->state, err);
+
+	__l2cap_conn_unlink(conn->iff, conn);
+
+	conn->state = BT_CLOSED;
+
+	if (conn->rx_skb)
+		bluez_skb_free(conn->rx_skb);
+
+	/* Kill channels */
+	while ((sk = conn->chan_list.head)) {
+		bh_lock_sock(sk);
+		l2cap_clear_timer(sk);
+		l2cap_chan_del(sk, err);
+		bh_unlock_sock(sk);
+
+		l2cap_sock_kill(sk);
+	}
+
+	kfree(conn);
+
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+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){
+		struct l2cap_conn *c;
+
+		c = list_entry(p, struct l2cap_conn, list);
+		if (!bacmp(&c->dst, dst))
+			return c;
+	}
+	return NULL;
+}
+
+int l2cap_connect(struct sock *sk)
+{
+	bdaddr_t *src = &l2cap_pi(sk)->src;
+	bdaddr_t *dst = &l2cap_pi(sk)->dst;
+	struct l2cap_conn *conn;
+	struct l2cap_iff *iff;
+	int err = 0;
+
+	DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
+
+	read_lock_bh(&l2cap_rt_lock);
+
+	/* Get route to remote BD address */
+	if (!(iff = l2cap_get_route(src, dst))) {
+		err = -EHOSTUNREACH;
+		goto done;
+	}
+
+	/* Update source addr of the socket */
+	bacpy(src, iff->bdaddr);
+
+	l2cap_iff_lock(iff);
+
+	if (!(conn = l2cap_get_conn_by_addr(iff, dst))) {
+		/* Connection doesn't exist */
+		if (!(conn = l2cap_conn_add(iff, dst))) {
+			l2cap_iff_unlock(iff);
+			err = -ENOMEM;
+			goto done;
+		}
+		conn->out = 1;
+	}
+
+	l2cap_iff_unlock(iff);
+
+	l2cap_chan_add(conn, sk, NULL);
+
+	sk->state = BT_CONNECT;
+	l2cap_set_timer(sk, sk->sndtimeo);
+
+	switch (conn->state) {
+	case BT_CONNECTED:
+		if (sk->type == SOCK_SEQPACKET) {
+			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);
+		} else {
+			sk->state = BT_CONNECTED;
+			l2cap_clear_timer(sk);
+		}
+		break;
+
+	case BT_CONNECT:
+		break;
+
+	default:
+		/* Create ACL connection */
+		conn->state = BT_CONNECT;
+		hci_connect(iff->hdev, dst);
+		break;
+	};
+
+done:
+	read_unlock_bh(&l2cap_rt_lock);
+
+	return err;
+}
+
+/* ------ Channel queues for listening sockets ------ */
+void l2cap_accept_queue(struct sock *parent, struct sock *sk)
+{
+	struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
+
+	DBG("parent %p, sk %p", parent, sk);
+
+	sock_hold(sk);
+	l2cap_pi(sk)->parent = parent;
+	l2cap_pi(sk)->next_q = NULL;
+
+	if (!q->head) {
+		q->head = q->tail = sk;
+	} else {
+		struct sock *tail = q->tail;
+
+		l2cap_pi(sk)->prev_q = tail;
+		l2cap_pi(tail)->next_q = sk;
+		q->tail = sk;
+	}
+
+	parent->ack_backlog++;
+}
+
+void l2cap_accept_unlink(struct sock *sk)
+{
+	struct sock *parent = l2cap_pi(sk)->parent;
+	struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
+	struct sock *next, *prev;
+
+	DBG("sk %p", sk);
+
+	next = l2cap_pi(sk)->next_q;
+	prev = l2cap_pi(sk)->prev_q;
+
+	if (sk == q->head)
+		q->head = next;
+	if (sk == q->tail)
+		q->tail = prev;
+
+	if (next)
+		l2cap_pi(next)->prev_q = prev;
+	if (prev)
+		l2cap_pi(prev)->next_q = next;
+
+	l2cap_pi(sk)->parent = NULL;
+
+	parent->ack_backlog--;
+	__sock_put(sk);
+}
+
+/* Get next connected channel in queue. */
+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){
+		if (!state || sk->state == state) {
+			l2cap_accept_unlink(sk);
+			break;
+		}
+	}
+
+	DBG("parent %p, sk %p", parent, sk);
+
+	return sk;
+}
+
+/* -------- Socket interface ---------- */
+static struct sock *__l2cap_get_sock_by_addr(struct sockaddr_l2 *addr)
+{
+	bdaddr_t *src = &addr->l2_bdaddr;
+	__u16 psm = addr->l2_psm;
+	struct sock *sk;
+
+	for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
+		if (l2cap_pi(sk)->psm == psm &&
+		    !bacmp(&l2cap_pi(sk)->src, src))
+			break;
+	}
+
+	return sk;
+}
+
+/* Find socket listening on psm and source bdaddr.
+ * Returns closest match.
+ */
+static struct sock *l2cap_get_sock_listen(bdaddr_t *src, __u16 psm)
+{
+	struct sock *sk, *sk1 = NULL;
+
+	read_lock(&l2cap_sk_list.lock);
+
+	for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
+		struct l2cap_pinfo *pi;
+
+		if (sk->state != BT_LISTEN)
+			continue;
+
+		pi = l2cap_pi(sk);
+
+		if (pi->psm == psm) {
+			/* Exact match. */
+			if (!bacmp(&pi->src, src))
+				break;
+
+			/* Closest match */
+			if (!bacmp(&pi->src, BDADDR_ANY))
+				sk1 = sk;
+		}
+	}
+
+	read_unlock(&l2cap_sk_list.lock);
+
+	return sk ? sk : sk1;
+}
+
+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);
+
+	MOD_DEC_USE_COUNT;
+}
+
+static void l2cap_sock_cleanup_listen(struct sock *parent)
+{
+	struct sock *sk;
+
+	DBG("parent %p", parent);
+
+	/* Close not yet accepted channels */
+	while ((sk = l2cap_accept_dequeue(parent, 0)))
+		l2cap_sock_close(sk);
+
+	parent->state  = BT_CLOSED;
+	parent->zapped = 1;
+}
+
+/* Kill socket (only if zapped and orphan)
+ * Must be called on unlocked socket.
+ */
+static void l2cap_sock_kill(struct sock *sk)
+{
+	if (!sk->zapped || sk->socket)
+		return;
+
+	DBG("sk %p state %d", sk, sk->state);
+
+	/* Kill poor orphan */
+	bluez_sock_unlink(&l2cap_sk_list, sk);
+	sk->dead = 1;
+	sock_put(sk);
+}
+
+/* Close socket.
+ * Must be called on unlocked socket.
+ */
+static void l2cap_sock_close(struct sock *sk)
+{
+	struct l2cap_conn *conn;
+
+	lock_sock(sk);
+
+	conn = l2cap_pi(sk)->conn;
+
+	DBG("sk %p state %d conn %p socket %p", sk, sk->state, conn, sk->socket);
+
+	switch (sk->state) {
+	case BT_LISTEN:
+		l2cap_sock_cleanup_listen(sk);
+		break;
+
+	case BT_CONNECTED:
+	case BT_CONFIG:
+		if (sk->type == SOCK_SEQPACKET) {
+			l2cap_disconn_req req;
+
+			sk->state = BT_DISCONN;
+
+			req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
+			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);
+		} else {
+			l2cap_chan_del(sk, ECONNRESET);
+		}
+		break;
+
+	case BT_CONNECT:
+	case BT_DISCONN:
+		l2cap_chan_del(sk, ECONNRESET);
+		break;
+
+	default:
+		sk->zapped = 1;
+		break;
+	};
+
+	release_sock(sk);
+
+	l2cap_sock_kill(sk);
+}
+
+static void l2cap_sock_init(struct sock *sk, struct sock *parent)
+{
+	struct l2cap_pinfo *pi = l2cap_pi(sk);
+
+	DBG("sk %p", sk);
+
+	if (parent) {
+		sk->type = parent->type;
+
+		pi->imtu = l2cap_pi(parent)->imtu;
+		pi->omtu = l2cap_pi(parent)->omtu;
+	} else {
+		pi->imtu = L2CAP_DEFAULT_MTU;
+		pi->omtu = 0;
+	}
+
+	/* Default config options */
+	pi->conf_mtu = L2CAP_DEFAULT_MTU;
+	pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
+}
+
+static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio)
+{
+	struct sock *sk;
+
+	if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
+		return NULL;
+
+	sock_init_data(sock, sk);
+
+	sk->zapped   = 0;
+
+	sk->destruct = l2cap_sock_destruct;
+	sk->sndtimeo = L2CAP_CONN_TIMEOUT;
+
+	sk->protocol = proto;
+	sk->state    = BT_OPEN;
+
+	l2cap_init_timer(sk);
+
+	bluez_sock_link(&l2cap_sk_list, sk);
+
+	MOD_INC_USE_COUNT;
+
+	return sk;
+}
+
+static int l2cap_sock_create(struct socket *sock, int protocol)
+{
+	struct sock *sk;
+
+	DBG("sock %p", sock);
+
+	sock->state = SS_UNCONNECTED;
+
+	if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_RAW)
+		return -ESOCKTNOSUPPORT;
+
+	sock->ops = &l2cap_sock_ops;
+
+	if (!(sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL)))
+		return -ENOMEM;
+
+	l2cap_sock_init(sk, NULL);
+
+	return 0;
+}
+
+static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
+{
+	struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
+	struct sock *sk = sock->sk;
+	int err = 0;
+
+	DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm);
+
+	if (!addr || addr->sa_family != AF_BLUETOOTH)
+		return -EINVAL;
+
+	lock_sock(sk);
+
+	if (sk->state != BT_OPEN) {
+		err = -EBADFD;
+		goto done;
+	}
+
+	write_lock(&l2cap_sk_list.lock);
+
+	if (la->l2_psm && __l2cap_get_sock_by_addr(la)) {
+		err = -EADDRINUSE;
+		goto unlock;
+	}
+
+	/* Save source address */
+	bacpy(&l2cap_pi(sk)->src, &la->l2_bdaddr);
+	l2cap_pi(sk)->psm = la->l2_psm;
+	sk->state = BT_BOUND;
+
+unlock:
+	write_unlock(&l2cap_sk_list.lock);
+
+done:
+	release_sock(sk);
+
+	return err;
+}
+
+static int l2cap_sock_w4_connect(struct sock *sk, int flags)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	long timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
+	int err = 0;
+
+	add_wait_queue(sk->sleep, &wait);
+	current->state = TASK_INTERRUPTIBLE;
+
+	while (sk->state != BT_CONNECTED) {
+		if (!timeo) {
+			err = -EAGAIN;
+			break;
+		}
+
+		release_sock(sk);
+		timeo = schedule_timeout(timeo);
+		lock_sock(sk);
+
+		err = 0;
+		if (sk->state == BT_CONNECTED)
+			break;
+
+		if (sk->err) {
+			err = sock_error(sk);
+			break;
+		}
+
+		if (signal_pending(current)) {
+			err = sock_intr_errno(timeo);
+			break;
+		}
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(sk->sleep, &wait);
+
+	return err;
+}
+
+static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
+{
+	struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
+	struct sock *sk = sock->sk;
+	int err = 0;
+
+	lock_sock(sk);
+
+	DBG("sk %p", sk);
+
+	if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_l2)) {
+		err = -EINVAL;
+		goto done;
+	}
+
+	if (sk->state != BT_OPEN && sk->state != BT_BOUND) {
+		err = -EBADFD;
+		goto done;
+	}
+
+	if (sk->type == SOCK_SEQPACKET && !la->l2_psm) {
+		err = -EINVAL;
+		goto done;
+	}
+
+	/* Set destination address and psm */
+	bacpy(&l2cap_pi(sk)->dst, &la->l2_bdaddr);
+	l2cap_pi(sk)->psm = la->l2_psm;
+
+	if ((err = l2cap_connect(sk)))
+		goto done;
+
+	err = l2cap_sock_w4_connect(sk, flags);
+
+done:
+	release_sock(sk);
+	return err;
+}
+
+int l2cap_sock_listen(struct socket *sock, int backlog)
+{
+	struct sock *sk = sock->sk;
+	int err = 0;
+
+	DBG("sk %p backlog %d", sk, backlog);
+
+	lock_sock(sk);
+
+	if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
+		err = -EBADFD;
+		goto done;
+	}
+
+	if (!l2cap_pi(sk)->psm) {
+		err = -EINVAL;
+		goto done;
+	}
+
+	sk->max_ack_backlog = backlog;
+	sk->ack_backlog = 0;
+	sk->state = BT_LISTEN;
+
+done:
+	release_sock(sk);
+	return err;
+}
+
+int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	struct sock *sk = sock->sk, *ch;
+	long timeo;
+	int err = 0;
+
+	lock_sock(sk);
+
+	if (sk->state != BT_LISTEN) {
+		err = -EBADFD;
+		goto done;
+	}
+
+	timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
+
+	DBG("sk %p timeo %ld", sk, timeo);
+
+	/* Wait for an incoming connection. (wake-one). */
+	add_wait_queue_exclusive(sk->sleep, &wait);
+	current->state = TASK_INTERRUPTIBLE;
+	while (!(ch = l2cap_accept_dequeue(sk, BT_CONNECTED))) {
+		if (!timeo) {
+			err = -EAGAIN;
+			break;
+		}
+
+		release_sock(sk);
+		timeo = schedule_timeout(timeo);
+		lock_sock(sk);
+
+		if (sk->state != BT_LISTEN) {
+			err = -EBADFD;
+			break;
+		}
+
+		if (signal_pending(current)) {
+			err = sock_intr_errno(timeo);
+			break;
+		}
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(sk->sleep, &wait);
+
+	if (err)
+		goto done;
+
+	sock_graft(ch, newsock);
+	newsock->state = SS_CONNECTED;
+
+	DBG("new socket %p", ch);
+
+done:
+	release_sock(sk);
+
+	return err;
+}
+
+static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
+{
+	struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
+	struct sock *sk = sock->sk;
+
+	DBG("sock %p, sk %p", sock, sk);
+
+	addr->sa_family = AF_BLUETOOTH;
+	*len = sizeof(struct sockaddr_l2);
+
+	if (peer)
+		bacpy(&la->l2_bdaddr, &l2cap_pi(sk)->dst);
+	else
+		bacpy(&la->l2_bdaddr, &l2cap_pi(sk)->src);
+
+	la->l2_psm = l2cap_pi(sk)->psm;
+
+	return 0;
+}
+
+static int l2cap_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
+{
+	struct sock *sk = sock->sk;
+	int err = 0;
+
+	DBG("sock %p, sk %p", sock, sk);
+
+	if (sk->err)
+		return sock_error(sk);
+
+	if (msg->msg_flags & MSG_OOB)
+		return -EOPNOTSUPP;
+
+	lock_sock(sk);
+
+	if (sk->state == BT_CONNECTED)
+		err = l2cap_chan_send(sk, msg, len);
+	else
+		err = -ENOTCONN;
+
+	release_sock(sk);
+	return err;
+}
+
+static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
+{
+	struct sock *sk = sock->sk;
+	int noblock = flags & MSG_DONTWAIT;
+	int copied, err;
+	struct sk_buff *skb;
+
+	DBG("sock %p, sk %p", sock, sk);
+
+	if (flags & (MSG_OOB))
+		return -EOPNOTSUPP;
+
+	if (sk->state == BT_CLOSED)
+		return 0;
+
+	if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
+		return err;
+
+	msg->msg_namelen = 0;
+
+	copied = skb->len;
+	if (len < copied) {
+		msg->msg_flags |= MSG_TRUNC;
+		copied = len;
+	}
+
+	skb->h.raw = skb->data;
+	err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+
+	skb_free_datagram(sk, skb);
+
+	return err ? : copied;
+}
+
+int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
+{
+	struct sock *sk = sock->sk;
+	struct l2cap_options opts;
+	int err = 0;
+
+	DBG("sk %p", sk);
+
+	lock_sock(sk);
+
+	switch (optname) {
+	case L2CAP_OPTIONS:
+		if (copy_from_user((char *)&opts, optval, optlen)) {
+			err = -EFAULT;
+			break;
+		}
+		l2cap_pi(sk)->imtu = opts.imtu;
+		l2cap_pi(sk)->omtu = opts.omtu;
+		break;
+
+	default:
+		err = -ENOPROTOOPT;
+		break;
+	};
+
+	release_sock(sk);
+
+	return err;
+}
+
+int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
+{
+	struct sock *sk = sock->sk;
+	struct l2cap_options opts;
+	int len; 
+
+	if (get_user(len, optlen))
+		return -EFAULT;
+
+	switch (optname) {
+	case L2CAP_OPTIONS:
+		opts.imtu     = l2cap_pi(sk)->imtu;
+		opts.omtu     = l2cap_pi(sk)->omtu;
+		opts.flush_to = l2cap_pi(sk)->flush_to;
+
+		len = MIN(len, sizeof(opts));
+		if (copy_to_user(optval, (char *)&opts, len))
+			return -EFAULT;
+
+		break;
+
+	default:
+		return -ENOPROTOOPT;
+		break;
+	};
+
+	return 0;
+}
+
+static int l2cap_sock_release(struct socket *sock)
+{
+	struct sock *sk = sock->sk;
+
+	DBG("sock %p, sk %p", sock, sk);
+
+	if (!sk)
+		return 0;
+
+	sock_orphan(sk);
+
+	l2cap_sock_close(sk);
+
+	return 0;
+}
+
+/* --------- L2CAP channels --------- */
+static struct sock * __l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
+{
+	struct sock *s;
+
+	for (s = l->head; s; s = l2cap_pi(s)->next_c) {
+		if (l2cap_pi(s)->dcid == cid)
+			break;
+	}
+
+	return s;
+}
+
+static __inline__ struct sock *l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
+{
+	struct sock *s;
+
+	read_lock(&l->lock);
+	s = __l2cap_get_chan_by_dcid(l, cid);
+	read_unlock(&l->lock);
+
+	return s;
+}
+
+static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
+{
+	struct sock *s;
+
+	for (s = l->head; s; s = l2cap_pi(s)->next_c) {
+		if (l2cap_pi(s)->scid == cid)
+			break;
+	}
+
+	return s;
+}
+static __inline__ struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
+{
+	struct sock *s;
+
+	read_lock(&l->lock);
+	s = __l2cap_get_chan_by_scid(l, cid);
+	read_unlock(&l->lock);
+
+	return s;
+}
+
+static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 ident)
+{
+	struct sock *s;
+
+	for (s = l->head; s; s = l2cap_pi(s)->next_c) {
+		if (l2cap_pi(s)->ident == ident)
+			break;
+	}
+
+	return s;
+}
+
+static __inline__ struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 ident)
+{
+	struct sock *s;
+
+	read_lock(&l->lock);
+	s = __l2cap_get_chan_by_ident(l, ident);
+	read_unlock(&l->lock);
+
+	return s;
+}
+
+static __u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
+{
+	__u16 cid = 0x0040;
+
+	for (; cid < 0xffff; cid++) {
+		if(!__l2cap_get_chan_by_scid(l, cid))
+			return cid;
+	}
+
+	return 0;
+}
+
+static __inline__ void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
+{
+	sock_hold(sk);
+
+	if (l->head)
+		l2cap_pi(l->head)->prev_c = sk;
+
+	l2cap_pi(sk)->next_c = l->head;
+	l2cap_pi(sk)->prev_c = NULL;
+	l->head = 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;
+
+	write_lock(&l->lock);
+	if (sk == l->head)
+		l->head = next;
+
+	if (next)
+		l2cap_pi(next)->prev_c = prev;
+	if (prev)
+		l2cap_pi(prev)->next_c = next;
+	write_unlock(&l->lock);
+
+	__sock_put(sk);
+}
+
+static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
+{
+	struct l2cap_chan_list *l = &conn->chan_list;
+
+	DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
+
+	atomic_inc(&conn->refcnt);
+	l2cap_pi(sk)->conn = conn;
+
+	if (sk->type == SOCK_SEQPACKET) {
+		/* Alloc CID for normal socket */
+		l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
+	} else {
+		/* Raw socket can send only signalling messages */
+		l2cap_pi(sk)->scid = 0x0001;
+		l2cap_pi(sk)->dcid = 0x0001;
+		l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
+	}
+
+	__l2cap_chan_link(l, sk);
+
+	if (parent)
+		l2cap_accept_queue(parent, sk);
+}
+
+static __inline__ void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
+{
+	struct l2cap_chan_list *l = &conn->chan_list;
+
+	write_lock(&l->lock);
+	__l2cap_chan_add(conn, sk, parent);
+	write_unlock(&l->lock);
+}
+
+/* Delete channel. Must be called on the locked socket. */
+static void l2cap_chan_del(struct sock *sk, int err)
+{
+	struct l2cap_conn *conn;
+	struct sock *parent;
+
+	conn = l2cap_pi(sk)->conn;
+	parent = l2cap_pi(sk)->parent;
+
+	DBG("sk %p, conn %p, err %d", sk, conn, err);
+
+	if (parent) {
+		/* Unlink from parent accept queue */
+		bh_lock_sock(parent);
+		l2cap_accept_unlink(sk);
+		bh_unlock_sock(parent);
+	}
+
+	if (conn) {
+		/* 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);
+		}
+	}
+
+	sk->state  = BT_CLOSED;
+	sk->err    = err;
+	sk->state_change(sk);
+
+	sk->zapped = 1;
+}
+
+static void l2cap_conn_ready(struct l2cap_conn *conn)
+{
+	struct l2cap_chan_list *l = &conn->chan_list;
+	struct sock *sk;
+
+	DBG("conn %p", conn);
+
+	read_lock(&l->lock);
+
+	for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
+		bh_lock_sock(sk);
+
+		if (sk->type != SOCK_SEQPACKET) {
+			sk->state = BT_CONNECTED;
+			sk->state_change(sk);
+			l2cap_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);
+		}
+
+		bh_unlock_sock(sk);
+	}
+
+	read_unlock(&l->lock);
+}
+
+static void l2cap_chan_ready(struct sock *sk)
+{
+	struct sock *parent = l2cap_pi(sk)->parent;
+
+	DBG("sk %p, parent %p", sk, parent);
+
+	l2cap_pi(sk)->conf_state = 0;
+	l2cap_clear_timer(sk);
+
+	if (!parent) {
+		/* Outgoing channel.
+		 * Wake up socket sleeping on connect.
+		 */
+		sk->state = BT_CONNECTED;
+		sk->state_change(sk);
+	} else {
+		/* Incomming channel.
+		 * Wake up socket sleeping on accept.
+		 */
+		parent->state_change(parent);
+	}
+}
+
+/* Copy frame to all raw sockets on that connection */
+void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+	struct l2cap_chan_list *l = &conn->chan_list;
+	struct sk_buff *nskb;
+	struct sock * sk;
+
+	DBG("conn %p", conn);
+
+	read_lock(&l->lock);
+	for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
+		if (sk->type != SOCK_RAW)
+			continue;
+
+		/* Don't send frame to the socket it came from */
+		if (skb->sk == sk)
+			continue;
+
+		if (!(nskb = bluez_skb_clone(skb, GFP_ATOMIC)))
+			continue;
+
+		skb_queue_tail(&sk->receive_queue, nskb);
+		sk->data_ready(sk, nskb->len);
+	}
+	read_unlock(&l->lock);
+}
+
+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;
+	int err, size, count, sent=0;
+	l2cap_hdr * lh;
+
+	/* Check outgoing MTU */
+	if (len > l2cap_pi(sk)->omtu)
+		return -EINVAL;
+
+	/* First fragment (with L2CAP header) */
+	count = MIN(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;
+
+	/* Create L2CAP header */
+	lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
+	lh->len = __cpu_to_le16(len);
+	lh->cid = __cpu_to_le16(l2cap_pi(sk)->dcid);
+
+	if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
+		err = -EFAULT;
+		goto fail;
+	}
+
+	sent += count;
+	len  -= count;
+
+	/* Continuation fragments (no L2CAP header) */
+	while (len) {
+		count = MIN(iff->mtu, len);
+
+		if (!(frag = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err)))
+			goto fail;
+
+		bluez_skb_add_frag(skb, frag);
+	
+		if (memcpy_fromiovec(skb_put(frag, count), msg->msg_iov, count)) {
+			err = -EFAULT;
+			goto fail;
+		}
+
+		sent += count;
+		len  -= count;
+	}
+
+	if ((err = hci_send_acl(conn->hconn, skb, 0)) < 0)
+		goto fail;
+
+	return sent;
+
+fail:
+	bluez_skb_free(skb);
+
+	return err;
+}
+/* --------- L2CAP signalling commands --------- */
+static __inline__ __u8 l2cap_get_ident(struct l2cap_conn *conn)
+{
+	__u8 id;
+
+	/* Get next available identificator.
+	 *    1 - 199 are used by kernel.
+	 *  200 - 254 are used by utilities like l2ping, etc 
+	 */
+
+	spin_lock(&conn->lock);
+
+	if (++conn->tx_ident > 199)
+		conn->tx_ident = 1;
+
+	id = conn->tx_ident;
+
+	spin_unlock(&conn->lock);
+
+	return id;
+}
+
+static __inline__ struct sk_buff *l2cap_build_cmd(__u8 code, __u8 ident, __u16 len, void *data)
+{
+	struct sk_buff *skb;
+	l2cap_cmd_hdr *cmd;
+	l2cap_hdr *lh;
+	int size;
+
+	DBG("code 0x%2.2x, ident 0x%2.2x, len %d", code, ident, len);
+
+	size = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + len;
+	if (!(skb = bluez_skb_alloc(size, GFP_ATOMIC)))
+		return NULL;
+
+	lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
+	lh->len = __cpu_to_le16(L2CAP_CMD_HDR_SIZE + len);
+	lh->cid = __cpu_to_le16(0x0001);
+
+	cmd = (l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
+	cmd->code  = code;
+	cmd->ident = ident;
+	cmd->len   = __cpu_to_le16(len);
+
+	if (len)
+		memcpy(skb_put(skb, len), data, len);
+
+	return skb;
+}
+
+static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data)
+{
+	struct sk_buff *skb;
+	__u8 ident;
+
+	DBG("code 0x%2.2x", code);
+
+	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);
+}
+
+static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data)
+{
+	struct sk_buff *skb;
+
+	DBG("code 0x%2.2x", code);
+
+	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)
+{
+	l2cap_conf_opt *opt = (l2cap_conf_opt *) (*ptr);
+	int len;
+
+	*type = opt->type;
+	switch (opt->len) {
+	case 1:
+		*val = *((__u8 *) opt->val);
+		break;
+
+	case 2:
+		*val = __le16_to_cpu(*((__u16 *)opt->val));
+		break;
+
+	case 4:
+		*val = __le32_to_cpu(*((__u32 *)opt->val));
+		break;
+
+	default:
+		*val = 0L;
+		break;
+	};
+
+	DBG("type 0x%2.2x len %d val 0x%8.8x", *type, opt->len, *val);
+
+	len = L2CAP_CONF_OPT_SIZE + opt->len;
+
+	*ptr += len;
+
+	return len;
+}
+
+static __inline__ void l2cap_parse_conf_req(struct sock *sk, char *data, int len)
+{
+	__u8 type; __u32 val;
+	__u8 *ptr = data;
+
+	DBG("sk %p len %d", sk, len);
+
+	while (len >= L2CAP_CONF_OPT_SIZE) {
+		len -= l2cap_get_conf_opt(&ptr, &type, &val);
+
+		switch (type) {
+		case L2CAP_CONF_MTU:
+			l2cap_pi(sk)->conf_mtu = val;
+			break;
+
+		case L2CAP_CONF_FLUSH_TO:
+			l2cap_pi(sk)->flush_to = val;
+			break;
+
+		case L2CAP_CONF_QOS:
+			break;
+		};
+	}
+}
+
+static __inline__ void l2cap_add_conf_opt(__u8 **ptr, __u8 type, __u8 len, __u32 val)
+{
+	register l2cap_conf_opt *opt = (l2cap_conf_opt *) (*ptr);
+
+	DBG("type 0x%2.2x len %d val 0x%8.8x", type, len, val);
+
+	opt->type = type;
+	opt->len  = len;
+	switch (len) {
+	case 1:
+		*((__u8 *) opt->val)  = val;
+		break;
+
+	case 2:
+		*((__u16 *) opt->val) = __cpu_to_le16(val);
+		break;
+
+	case 4:
+		*((__u32 *) opt->val) = __cpu_to_le32(val);
+		break;
+	};
+
+	*ptr += L2CAP_CONF_OPT_SIZE + len;
+}
+
+static int l2cap_build_conf_req(struct sock *sk, __u8 *data)
+{
+	struct l2cap_pinfo *pi = l2cap_pi(sk);
+	l2cap_conf_req *req = (l2cap_conf_req *) data;
+	__u8 *ptr = req->data;
+
+	DBG("sk %p", sk);
+
+	if (pi->imtu != L2CAP_DEFAULT_MTU)
+		l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
+
+	/* FIXME. Need actual value of the flush timeout */
+	//if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
+	//   l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
+
+	req->dcid  = __cpu_to_le16(pi->dcid);
+	req->flags = __cpu_to_le16(0);
+
+	return ptr - data;
+}
+
+static int l2cap_conf_output(struct sock *sk, __u8 **ptr)
+{
+	struct l2cap_pinfo *pi = l2cap_pi(sk);
+	int result = 0;
+
+	/* Configure output options and let other side know
+	 * which ones we don't like.
+	 */
+	if (pi->conf_mtu < pi->omtu) {
+		l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, l2cap_pi(sk)->omtu);
+		result = L2CAP_CONF_UNACCEPT;
+	} else {
+		pi->omtu = pi->conf_mtu;
+	}
+
+	DBG("sk %p result %d", sk, result);
+	return result;
+}
+
+static int l2cap_build_conf_rsp(struct sock *sk, __u8 *data, int *result)
+{
+	l2cap_conf_rsp *rsp = (l2cap_conf_rsp *) data;
+	__u8 *ptr = rsp->data;
+
+	DBG("sk %p complete %d", sk, result ? 1 : 0);
+
+	if (result)
+		*result = l2cap_conf_output(sk, &ptr);
+
+	rsp->scid   = __cpu_to_le16(l2cap_pi(sk)->dcid);
+	rsp->result = __cpu_to_le16(result ? *result : 0);
+	rsp->flags  = __cpu_to_le16(0);
+
+	return ptr - 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;
+	l2cap_conn_rsp rsp;
+	struct sock *sk, *parent;
+
+	__u16 scid = __le16_to_cpu(req->scid);
+	__u16 psm  = req->psm;
+
+	DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
+
+	/* Check if we have socket listening on psm */
+	if (!(parent = l2cap_get_sock_listen(&conn->src, psm)))
+		goto reject;
+
+	bh_lock_sock(parent);
+	write_lock(&list->lock);
+
+	/* Check if we already have channel with that dcid */
+	if (__l2cap_get_chan_by_dcid(list, scid))
+		goto unlock;
+
+	/* Check for backlog size */
+	if (parent->ack_backlog > parent->max_ack_backlog)
+		goto unlock;
+
+	if (!(sk = l2cap_sock_alloc(NULL, BTPROTO_L2CAP, GFP_ATOMIC)))
+		goto unlock;
+
+	l2cap_sock_init(sk, parent);
+
+	bacpy(&l2cap_pi(sk)->src, &conn->src);
+	bacpy(&l2cap_pi(sk)->dst, &conn->dst);
+	l2cap_pi(sk)->psm  = psm;
+	l2cap_pi(sk)->dcid = scid;
+
+	__l2cap_chan_add(conn, sk, parent);
+	sk->state = BT_CONFIG;
+
+	write_unlock(&list->lock);
+	bh_unlock_sock(parent);
+
+	rsp.dcid   = __cpu_to_le16(l2cap_pi(sk)->scid);
+	rsp.scid   = __cpu_to_le16(l2cap_pi(sk)->dcid);
+	rsp.result = __cpu_to_le16(0);
+	rsp.status = __cpu_to_le16(0);
+	l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
+
+	return 0;
+
+unlock:
+	write_unlock(&list->lock);
+	bh_unlock_sock(parent);
+
+reject:
+	rsp.scid   = __cpu_to_le16(scid);
+	rsp.dcid   = __cpu_to_le16(0);
+	rsp.status = __cpu_to_le16(0);
+	rsp.result = __cpu_to_le16(L2CAP_CONN_NO_MEM);
+	l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
+
+	return 0;
+}
+
+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;
+	struct sock *sk;
+
+	scid   = __le16_to_cpu(rsp->scid);
+	dcid   = __le16_to_cpu(rsp->dcid);
+	result = __le16_to_cpu(rsp->result);
+	status = __le16_to_cpu(rsp->status);
+
+	DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
+
+	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
+		return -ENOENT;
+
+	bh_lock_sock(sk);
+
+	if (!result) {
+		char req[64];
+
+		l2cap_pi(sk)->dcid = dcid;
+		sk->state = BT_CONFIG;
+
+		l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
+	} else {
+		l2cap_chan_del(sk, ECONNREFUSED);
+	}
+
+	bh_unlock_sock(sk);
+	return 0;
+}
+
+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;
+	__u8 rsp[64];
+	struct sock *sk;
+	int result;
+
+	dcid  = __le16_to_cpu(req->dcid);
+	flags = __le16_to_cpu(req->flags);
+
+	DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
+
+	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
+		return -ENOENT;
+
+	bh_lock_sock(sk);
+
+	l2cap_parse_conf_req(sk, req->data, cmd->len - L2CAP_CONF_REQ_SIZE);
+
+	if (flags & 0x01) {
+		/* Incomplete config. Send empty response. */
+		l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, NULL), rsp);
+		goto unlock;
+	}
+
+	/* Complete config. */
+	l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, &result), rsp);
+
+	if (result)
+		goto unlock;
+
+	/* Output config done */
+	l2cap_pi(sk)->conf_state |= CONF_OUTPUT;
+
+	if (l2cap_pi(sk)->conf_state == CONF_DONE) {
+		sk->state = BT_CONNECTED;
+		l2cap_chan_ready(sk);
+	} else {
+		char req[64];
+		l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
+	}
+
+unlock:
+	bh_unlock_sock(sk);
+
+	return 0;
+}
+
+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;
+	struct sock *sk;
+	int err = 0;
+
+	scid   = __le16_to_cpu(rsp->scid);
+	flags  = __le16_to_cpu(rsp->flags);
+	result = __le16_to_cpu(rsp->result);
+
+	DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result);
+
+	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
+		return -ENOENT;
+
+	bh_lock_sock(sk);
+
+	if (sk->state != BT_CONFIG) {
+		err = -EINVAL;
+		goto done;
+	}
+
+	if (result) {
+		l2cap_disconn_req req;
+
+		/* They didn't like our options. Well... we do not negotiate.
+		 * Close channel.
+		 */
+		sk->state = BT_DISCONN;
+
+		req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
+		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);
+		goto done;
+	}
+
+	if (flags & 0x01)
+		goto done;
+
+	/* Input config done */
+	l2cap_pi(sk)->conf_state |= CONF_INPUT;
+
+	if (l2cap_pi(sk)->conf_state == CONF_DONE) {
+		sk->state = BT_CONNECTED;
+		l2cap_chan_ready(sk);
+	}
+
+done:
+	bh_unlock_sock(sk);
+
+	return err;
+}
+
+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;
+	__u16 dcid, scid;
+	struct sock *sk;
+
+	scid = __le16_to_cpu(req->scid);
+	dcid = __le16_to_cpu(req->dcid);
+
+	DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
+
+	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
+		return 0;
+
+	bh_lock_sock(sk);
+
+	rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
+	rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
+	l2cap_send_rsp(conn, cmd->ident, L2CAP_DISCONN_RSP, L2CAP_DISCONN_RSP_SIZE, &rsp);
+
+	l2cap_chan_del(sk, ECONNRESET);
+
+	bh_unlock_sock(sk);
+
+	l2cap_sock_kill(sk);
+
+	return 0;
+}
+
+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;
+	struct sock *sk;
+
+	scid = __le16_to_cpu(rsp->scid);
+	dcid = __le16_to_cpu(rsp->dcid);
+
+	DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
+
+	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
+		return -ENOENT;
+
+	bh_lock_sock(sk);
+	l2cap_clear_timer(sk);
+	l2cap_chan_del(sk, ECONNABORTED);
+	bh_unlock_sock(sk);
+
+	l2cap_sock_kill(sk);
+
+	return 0;
+}
+
+static __inline__ void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+	__u8 *data = skb->data;
+	int len = skb->len;
+	l2cap_cmd_hdr cmd;
+	int err = 0;
+
+	while (len >= L2CAP_CMD_HDR_SIZE) {
+		memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
+		data += L2CAP_CMD_HDR_SIZE;
+		len  -= L2CAP_CMD_HDR_SIZE;
+
+		cmd.len = le16_to_cpu(cmd.len);
+
+		DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
+
+		if (cmd.len > len || !cmd.ident) {
+			DBG("corrupted command");
+			break;
+		}
+
+		switch (cmd.code) {
+		case L2CAP_CONN_REQ:
+			err = l2cap_connect_req(conn, &cmd, data);
+			break;
+
+		case L2CAP_CONN_RSP:
+			err = l2cap_connect_rsp(conn, &cmd, data);
+			break;
+
+		case L2CAP_CONF_REQ:
+			err = l2cap_config_req(conn, &cmd, data);
+			break;
+
+		case L2CAP_CONF_RSP:
+			err = l2cap_config_rsp(conn, &cmd, data);
+			break;
+
+		case L2CAP_DISCONN_REQ:
+			err = l2cap_disconnect_req(conn, &cmd, data);
+			break;
+
+		case L2CAP_DISCONN_RSP:
+			err = l2cap_disconnect_rsp(conn, &cmd, data);
+			break;
+
+		case L2CAP_COMMAND_REJ:
+			/* FIXME: We should process this */
+			l2cap_raw_recv(conn, skb);
+			break;
+
+		case L2CAP_ECHO_REQ:
+			l2cap_send_rsp(conn, cmd.ident, L2CAP_ECHO_RSP, cmd.len, data);
+			break;
+
+		case L2CAP_ECHO_RSP:
+		case L2CAP_INFO_REQ:
+		case L2CAP_INFO_RSP:
+			l2cap_raw_recv(conn, skb);
+			break;
+
+		default:
+			ERR("Uknown signaling command 0x%2.2x", cmd.code);
+			err = -EINVAL;
+			break;
+		};
+
+		if (err) {
+			l2cap_cmd_rej rej;
+			DBG("error %d", err);
+
+			/* FIXME: Map err to a valid reason. */
+			rej.reason = cpu_to_le16(0);
+			l2cap_send_rsp(conn, cmd.ident, L2CAP_COMMAND_REJ, L2CAP_CMD_REJ_SIZE, &rej);
+		}
+
+		data += cmd.len;
+		len  -= cmd.len;
+	}
+
+	bluez_skb_free(skb);
+}
+
+static __inline__ int l2cap_data_channel(struct l2cap_conn *conn, __u16 cid, struct sk_buff *skb)
+{
+	struct sock *sk;
+
+	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, cid))) {
+		DBG("unknown cid 0x%4.4x", cid);
+		goto drop;
+	}
+
+	DBG("sk %p, len %d", sk, skb->len);
+
+	if (sk->state != BT_CONNECTED)
+		goto drop;
+
+	if (l2cap_pi(sk)->imtu < skb->len)
+		goto drop;
+
+	skb_queue_tail(&sk->receive_queue, skb);
+	sk->data_ready(sk, skb->len);
+
+	return 0;
+
+drop:
+	bluez_skb_free(skb);
+
+	return 0;
+}
+
+static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+	l2cap_hdr *lh = (l2cap_hdr *) skb->data;
+	__u16 cid, len;
+
+	skb_pull(skb, L2CAP_HDR_SIZE);
+	cid = le16_to_cpu(lh->cid);
+	len = le16_to_cpu(lh->len);
+
+	DBG("len %d, cid 0x%4.4x", len, cid);
+
+	if (cid == 0x0001)
+		l2cap_sig_channel(conn, skb);
+	else	
+		l2cap_data_channel(conn, cid, skb);
+}
+
+/* ------------ L2CAP interface with lower layer (HCI) ------------- */
+static int l2cap_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+	struct hci_dev *hdev = (struct hci_dev *) ptr;
+
+	DBG("hdev %s, event %ld", hdev->name, event);
+
+	write_lock(&l2cap_rt_lock);
+
+	switch (event) {
+	case HCI_DEV_UP:
+		l2cap_iff_add(hdev);
+		break;
+
+	case HCI_DEV_DOWN:
+		l2cap_iff_del(hdev);
+		break;
+	};
+
+	write_unlock(&l2cap_rt_lock);
+
+	return NOTIFY_DONE;
+}
+
+int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
+{
+	struct l2cap_iff *iff;
+
+	DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
+
+	if (!(iff = hdev->l2cap_data)) {
+		ERR("unknown interface");
+		return 0;
+	}
+
+	/* Always accept connection */
+	return 1;
+}
+
+int l2cap_connect_cfm(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 status, struct hci_conn *hconn)
+{
+	struct l2cap_conn *conn;
+	struct l2cap_iff *iff;
+	int err = 0;
+
+	DBG("hdev %s bdaddr %s hconn %p", hdev->name, batostr(bdaddr), hconn);
+
+	if (!(iff = hdev->l2cap_data)) {
+		ERR("unknown interface");
+		return 0;
+	}
+
+	l2cap_iff_lock(iff);
+
+	conn = l2cap_get_conn_by_addr(iff, bdaddr);
+
+	if (conn) {
+		/* Outgoing connection */
+		DBG("Outgoing connection: %s -> %s, %p, %2.2x", batostr(iff->bdaddr), batostr(bdaddr), conn, status);
+
+		if (!status && hconn) {
+			conn->state = BT_CONNECTED;
+			conn->hconn = hconn;
+
+			hconn->l2cap_data = (void *)conn;
+
+			/* Establish channels */
+			l2cap_conn_ready(conn);
+		} else {
+			l2cap_conn_del(conn, bterr(status));
+		}
+	} else {
+		/* Incomming connection */
+		DBG("Incomming connection: %s -> %s, %2.2x", batostr(iff->bdaddr), batostr(bdaddr), status);
+	
+		if (status || !hconn)
+			goto done;
+
+		if (!(conn = l2cap_conn_add(iff, bdaddr))) {
+			err = -ENOMEM;
+			goto done;
+		}
+
+		conn->state = BT_CONNECTED;
+		conn->hconn = hconn;
+
+		hconn->l2cap_data = (void *)conn;
+	}
+
+done:
+	l2cap_iff_unlock(iff);
+
+	return err;
+}
+
+int l2cap_disconn_ind(struct hci_conn *hconn, __u8 reason)
+{
+	struct l2cap_conn *conn = hconn->l2cap_data;
+
+	DBG("hconn %p reason %d", hconn, reason);
+
+	if (!conn) {
+		ERR("unknown connection");
+		return 0;
+	}
+	conn->hconn = NULL;
+
+	l2cap_iff_lock(conn->iff);
+	l2cap_conn_del(conn, bterr(reason));
+	l2cap_iff_unlock(conn->iff);
+
+	return 0;
+}
+
+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");
+		goto drop;
+	}
+
+	DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
+
+	if (flags & ACL_START) {
+		int flen, tlen, size;
+		l2cap_hdr *lh;
+
+		if (skb->len < L2CAP_HDR_SIZE) {
+			DBG("Corrupted L2CAP frame %d", skb->len);
+			goto drop;
+		}
+
+		lh = (l2cap_hdr *)skb->data;
+		tlen = __le16_to_cpu(lh->len);
+		flen = skb->len - L2CAP_HDR_SIZE;
+
+		DBG("Start: total len %d, frag len %d", tlen, flen);
+
+		if (flen == tlen) {
+			/* Complete frame received */
+			l2cap_recv_frame(conn, skb);
+			return 0;
+		}
+
+		/* Allocate skb for the complete frame (with header) */
+		size = L2CAP_HDR_SIZE + tlen;
+		if (!(conn->rx_skb = bluez_skb_alloc(size, GFP_ATOMIC)))
+			goto drop;
+
+		memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
+
+		conn->rx_len = tlen - flen;
+	} else {
+		DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
+
+		/* Check length */
+		if (skb->len > conn->rx_len) {
+			if (conn->rx_skb) {
+				bluez_skb_free(conn->rx_skb);
+				conn->rx_skb = NULL;
+			}
+			goto drop;
+		}
+
+		memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
+		conn->rx_len -= skb->len;
+
+		if (!conn->rx_len) {
+			/* Complete frame received */
+			l2cap_recv_frame(conn, conn->rx_skb);
+			conn->rx_skb = NULL;
+			conn->rx_len = 0;
+		}
+	}
+
+drop:
+	bluez_skb_free(skb);
+
+	return 0;
+}
+
+struct proto_ops l2cap_sock_ops = {
+	family:		PF_BLUETOOTH,
+	release:	l2cap_sock_release,
+	bind:		l2cap_sock_bind,
+	connect:	l2cap_sock_connect,
+	listen:		l2cap_sock_listen,
+	accept:		l2cap_sock_accept,
+	getname:	l2cap_sock_getname,
+	sendmsg:	l2cap_sock_sendmsg,
+	recvmsg:	l2cap_sock_recvmsg,
+	poll:		datagram_poll,
+	socketpair:	sock_no_socketpair,
+	ioctl:		sock_no_ioctl,
+	shutdown:	sock_no_shutdown,
+	setsockopt:	l2cap_sock_setsockopt,
+	getsockopt:	l2cap_sock_getsockopt,
+	mmap:		sock_no_mmap
+};
+
+struct net_proto_family l2cap_sock_family_ops = {
+	family:		PF_BLUETOOTH,
+	create:		l2cap_sock_create
+};
+
+struct hci_proto l2cap_hci_proto = {
+	name:		"L2CAP",
+	id:		HCI_PROTO_L2CAP,
+	connect_ind:	l2cap_connect_ind,
+	connect_cfm:	l2cap_connect_cfm,
+	disconn_ind:	l2cap_disconn_ind,
+	recv_acldata:	l2cap_recv_acldata,
+};
+
+struct notifier_block l2cap_nblock = {
+	notifier_call: l2cap_dev_event
+};
+
+int __init l2cap_init(void)
+{
+	INF("BlueZ L2CAP ver %s Copyright (C) 2000,2001 Qualcomm Inc",
+		BLUEZ_VER);
+	INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+
+	if (bluez_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops)) {
+		ERR("Can't register L2CAP socket");
+		return -EPROTO;
+	}
+
+	if (hci_register_proto(&l2cap_hci_proto) < 0) {
+		ERR("Can't register L2CAP protocol");
+		return -EPROTO;
+	}
+
+	hci_register_notifier(&l2cap_nblock);
+
+	l2cap_register_proc();
+
+	return 0;
+}
+
+void l2cap_cleanup(void)
+{
+	l2cap_unregister_proc();
+
+	/* Unregister socket, protocol and notifier */
+	if (bluez_sock_unregister(BTPROTO_L2CAP))
+		ERR("Can't unregister L2CAP socket");
+
+	if (hci_unregister_proto(&l2cap_hci_proto) < 0)
+		ERR("Can't unregister L2CAP protocol");
+
+	hci_unregister_notifier(&l2cap_nblock);
+
+	/* We _must_ not have any sockets and/or connections
+	 * at this stage.
+	 */
+
+	/* Free interface list and unlock HCI devices */
+	{
+		struct list_head *list = &l2cap_iff_list;
+
+		while (!list_empty(list)) {
+			struct l2cap_iff *iff;
+
+			iff = list_entry(list->next, struct l2cap_iff, list);
+			l2cap_iff_del(iff->hdev);
+		}
+	}
+}
+
+module_init(l2cap_init);
+module_exit(l2cap_cleanup);
diff -u --recursive --new-file v2.4.5/linux/net/bluetooth/l2cap_proc.c linux/net/bluetooth/l2cap_proc.c
--- v2.4.5/linux/net/bluetooth/l2cap_proc.c	Wed Dec 31 16:00:00 1969
+++ linux/net/bluetooth/l2cap_proc.c	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,165 @@
+/* 
+   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 L2CAP proc fs support.
+ *
+ * $Id: l2cap_proc.c,v 1.1 2001/06/01 08:12:11 davem Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/malloc.h>
+#include <linux/poll.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <linux/interrupt.h>
+#include <linux/socket.h>
+#include <linux/skbuff.h>
+#include <linux/proc_fs.h>
+#include <linux/list.h>
+#include <net/sock.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include <net/bluetooth/bluez.h>
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/l2cap_core.h>
+
+#ifndef L2CAP_DEBUG
+#undef  DBG
+#define DBG( A... )
+#endif
+
+/* ----- PROC fs support ----- */
+static int l2cap_conn_dump(char *buf, struct l2cap_iff *iff)
+{
+	struct list_head *p;
+	char *ptr = buf;
+
+	list_for_each(p, &iff->conn_list) {
+		struct l2cap_conn *c;
+
+		c = list_entry(p, struct l2cap_conn, list);
+		ptr += sprintf(ptr, "    %p %d %p %p %s %s\n", 
+				c, c->state, c->iff, c->hconn, batostr(&c->src), batostr(&c->dst));
+	}
+
+	return ptr - buf;
+}
+
+static int l2cap_iff_dump(char *buf)
+{
+	struct list_head *p;
+	char *ptr = buf;
+
+	ptr += sprintf(ptr, "Interfaces:\n");
+
+	write_lock(&l2cap_rt_lock);
+
+	list_for_each(p, &l2cap_iff_list) {
+		struct l2cap_iff *iff;
+
+		iff = list_entry(p, struct l2cap_iff, list);
+
+		ptr += sprintf(ptr, "  %s %p %p\n", iff->hdev->name, iff, iff->hdev);
+		
+		l2cap_iff_lock(iff);
+		ptr += l2cap_conn_dump(ptr, iff);
+		l2cap_iff_unlock(iff);
+	}
+
+	write_unlock(&l2cap_rt_lock);
+
+	ptr += sprintf(ptr, "\n");
+
+	return ptr - buf;
+}
+
+static int l2cap_sock_dump(char *buf, struct bluez_sock_list *list)
+{
+	struct l2cap_pinfo *pi;
+	struct sock *sk;
+	char *ptr = buf;
+
+	ptr += sprintf(ptr, "Sockets:\n");
+
+	write_lock(&list->lock);
+
+	for (sk = list->head; sk; sk = sk->next) {
+		pi = l2cap_pi(sk);
+		ptr += sprintf(ptr, "  %p %d %p %d %s %s 0x%4.4x 0x%4.4x %d %d\n", sk, sk->state, pi->conn, pi->psm,
+		               batostr(&pi->src), batostr(&pi->dst), pi->scid, pi->dcid, pi->imtu, pi->omtu );
+	}
+
+	write_unlock(&list->lock);
+
+	ptr += sprintf(ptr, "\n");
+
+	return ptr - buf;
+}
+
+static int l2cap_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
+{
+	char *ptr = buf;
+	int len;
+
+	DBG("count %d, offset %ld", count, offset);
+
+	ptr += l2cap_iff_dump(ptr);
+	ptr += l2cap_sock_dump(ptr, &l2cap_sk_list);
+	len  = ptr - buf;
+
+	if (len <= count + offset)
+		*eof = 1;
+
+	*start = buf + offset;
+	len -= offset;
+
+	if (len > count)
+		len = count;
+	if (len < 0)
+		len = 0;
+
+	return len;
+}
+
+void l2cap_register_proc(void)
+{
+	create_proc_read_entry("bluetooth/l2cap", 0, 0, l2cap_read_proc, NULL);
+}
+
+void l2cap_unregister_proc(void)
+{
+	remove_proc_entry("bluetooth/l2cap", NULL);
+}
diff -u --recursive --new-file v2.4.5/linux/net/bluetooth/lib.c linux/net/bluetooth/lib.c
--- v2.4.5/linux/net/bluetooth/lib.c	Wed Dec 31 16:00:00 1969
+++ linux/net/bluetooth/lib.c	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,174 @@
+/* 
+   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 kernel library.
+ *
+ * $Id: lib.c,v 1.1 2001/06/01 08:12:11 davem Exp $
+ */
+
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <asm/errno.h>
+
+#include <net/bluetooth/bluetooth.h>
+
+void bluez_dump(char *pref, __u8 *buf, int count)
+{
+	char *ptr;
+	char line[100];
+	int i;
+
+	printk(KERN_INFO "%s: dump, len %d\n", pref, count);
+
+	ptr = line;
+	*ptr = 0;
+	for (i = 0; i<count; i++) {
+		ptr += sprintf(ptr, " %2.2X", buf[i]);
+
+		if (i && !((i + 1) % 20)) {
+			printk(KERN_INFO "%s:%s\n", pref, line);
+			ptr = line;
+			*ptr = 0;
+		}
+	}
+
+	if (line[0])
+		printk(KERN_INFO "%s:%s\n", pref, line);
+}
+
+void baswap(bdaddr_t *dst, bdaddr_t *src)
+{
+	unsigned char *d = (unsigned char *) dst;
+	unsigned char *s = (unsigned char *) src;
+	int i;
+
+	for (i = 0; i < 6; i++)
+		d[i] = s[5 - i];
+}
+
+char *batostr(bdaddr_t *ba)
+{
+	static char str[2][18];
+	static int i = 1;
+
+	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);
+
+	return str[i];
+}
+
+/* Bluetooth error codes to Unix errno mapping */
+int bterr(__u16 code)
+{
+	switch (code) {
+	case 0:
+		return 0;
+
+	case 0x01:
+		return EBADRQC;
+
+	case 0x02:
+		return ENOTCONN;
+
+	case 0x03:
+		return EIO;
+
+	case 0x04:
+		return EHOSTDOWN;
+
+	case 0x05:
+		return EACCES;
+
+	case 0x06:
+		return EINVAL;
+
+	case 0x07:
+		return ENOMEM;
+
+	case 0x08:
+		return ETIMEDOUT;
+
+	case 0x09:
+		return EMLINK;
+
+	case 0x0a:
+		return EMLINK;
+
+	case 0x0b:
+		return EALREADY;
+
+	case 0x0c:
+		return EBUSY;
+
+	case 0x0d:
+	case 0x0e:
+	case 0x0f:
+		return ECONNREFUSED;
+
+	case 0x10:
+		return ETIMEDOUT;
+
+	case 0x11:
+	case 0x27:
+	case 0x29:
+	case 0x20:
+		return EOPNOTSUPP;
+
+	case 0x12:
+		return EINVAL;
+
+	case 0x13:
+	case 0x14:
+	case 0x15:
+		return ECONNRESET;
+
+	case 0x16:
+		return ECONNABORTED;
+
+	case 0x17:
+		return ELOOP;
+
+	case 0x18:
+		return EACCES;
+
+	case 0x1a:
+		return EPROTONOSUPPORT;
+
+	case 0x1b:
+		return ECONNREFUSED;
+
+	case 0x19:
+	case 0x1e:
+	case 0x23:
+	case 0x24:
+	case 0x25:
+		return EPROTO;
+
+	default:
+		return ENOSYS;
+	};
+}
diff -u --recursive --new-file v2.4.5/linux/net/bluetooth/syms.c linux/net/bluetooth/syms.c
--- v2.4.5/linux/net/bluetooth/syms.c	Wed Dec 31 16:00:00 1969
+++ linux/net/bluetooth/syms.c	Mon Jun 11 19:15:27 2001
@@ -0,0 +1,72 @@
+/* 
+   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 symbols.
+ *
+ * $Id: syms.c,v 1.1 2001/06/01 08:12:11 davem Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <linux/socket.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/bluez.h>
+#include <net/bluetooth/hci_core.h>
+
+/* HCI Core */
+EXPORT_SYMBOL(hci_register_dev);
+EXPORT_SYMBOL(hci_unregister_dev);
+EXPORT_SYMBOL(hci_register_proto);
+EXPORT_SYMBOL(hci_unregister_proto);
+EXPORT_SYMBOL(hci_register_notifier);
+EXPORT_SYMBOL(hci_unregister_notifier);
+
+EXPORT_SYMBOL(hci_connect);
+EXPORT_SYMBOL(hci_disconnect);
+EXPORT_SYMBOL(hci_dev_get);
+
+EXPORT_SYMBOL(hci_recv_frame);
+EXPORT_SYMBOL(hci_send_acl);
+EXPORT_SYMBOL(hci_send_sco);
+EXPORT_SYMBOL(hci_send_raw);
+
+/* BlueZ lib */
+EXPORT_SYMBOL(bluez_dump);
+EXPORT_SYMBOL(baswap);
+EXPORT_SYMBOL(batostr);
+EXPORT_SYMBOL(bterr);
+
+/* BlueZ sockets */
+EXPORT_SYMBOL(bluez_sock_register);
+EXPORT_SYMBOL(bluez_sock_unregister);
+EXPORT_SYMBOL(bluez_sock_link);
+EXPORT_SYMBOL(bluez_sock_unlink);
diff -u --recursive --new-file v2.4.5/linux/net/bridge/br_device.c linux/net/bridge/br_device.c
--- v2.4.5/linux/net/bridge/br_device.c	Thu Mar  2 11:41:11 2000
+++ linux/net/bridge/br_device.c	Mon Jun 11 19:15:27 2001
@@ -5,7 +5,7 @@
  *	Authors:
  *	Lennert Buytenhek		<buytenh@gnu.org>
  *
- *	$Id: br_device.c,v 1.3 2000/03/01 02:58:09 davem Exp $
+ *	$Id: br_device.c,v 1.4 2001/06/01 09:28:28 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
@@ -56,17 +56,17 @@
 	dest = skb->data;
 
 	if (dest[0] & 1) {
-		br_flood(br, skb, 0);
+		br_flood_deliver(br, skb, 0);
 		return 0;
 	}
 
 	if ((dst = br_fdb_get(br, dest)) != NULL) {
-		br_forward(dst->dst, skb);
+		br_deliver(dst->dst, skb);
 		br_fdb_put(dst);
 		return 0;
 	}
 
-	br_flood(br, skb, 0);
+	br_flood_deliver(br, skb, 0);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.5/linux/net/bridge/br_forward.c linux/net/bridge/br_forward.c
--- v2.4.5/linux/net/bridge/br_forward.c	Mon Feb 21 17:35:06 2000
+++ linux/net/bridge/br_forward.c	Mon Jun 11 19:15:27 2001
@@ -5,7 +5,7 @@
  *	Authors:
  *	Lennert Buytenhek		<buytenh@gnu.org>
  *
- *	$Id: br_forward.c,v 1.2 2000/02/21 15:51:33 davem Exp $
+ *	$Id: br_forward.c,v 1.3 2001/06/01 09:28:28 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
@@ -18,9 +18,10 @@
 #include <linux/inetdevice.h>
 #include <linux/skbuff.h>
 #include <linux/if_bridge.h>
+#include <linux/netfilter_bridge.h>
 #include "br_private.h"
 
-static inline int should_forward(struct net_bridge_port *p, struct sk_buff *skb)
+static inline int should_deliver(struct net_bridge_port *p, struct sk_buff *skb)
 {
 	if (skb->dev == p->dev ||
 	    p->state != BR_STATE_FORWARDING)
@@ -29,16 +30,51 @@
 	return 1;
 }
 
+static int __br_forward_finish(struct sk_buff *skb)
+{
+	NF_HOOK(PF_BRIDGE, NF_BR_POST_ROUTING, skb, NULL, skb->dev,
+			dev_queue_xmit);
+
+	return 0;
+}
+
+static void __br_deliver(struct net_bridge_port *to, struct sk_buff *skb)
+{
+	struct net_device *indev;
+
+	indev = skb->dev;
+	skb->dev = to->dev;
+
+	NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, indev, skb->dev,
+			__br_forward_finish);
+}
+
 static void __br_forward(struct net_bridge_port *to, struct sk_buff *skb)
 {
+	struct net_device *indev;
+
+	indev = skb->dev;
 	skb->dev = to->dev;
-	dev_queue_xmit(skb);
+
+	NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev,
+			__br_forward_finish);
+}
+
+/* called under bridge lock */
+void br_deliver(struct net_bridge_port *to, struct sk_buff *skb)
+{
+	if (should_deliver(to, skb)) {
+		__br_deliver(to, skb);
+		return;
+	}
+
+	kfree_skb(skb);
 }
 
 /* called under bridge lock */
 void br_forward(struct net_bridge_port *to, struct sk_buff *skb)
 {
-	if (should_forward(to, skb)) {
+	if (should_deliver(to, skb)) {
 		__br_forward(to, skb);
 		return;
 	}
@@ -47,7 +83,8 @@
 }
 
 /* called under bridge lock */
-void br_flood(struct net_bridge *br, struct sk_buff *skb, int clone)
+static void br_flood(struct net_bridge *br, struct sk_buff *skb, int clone,
+	void (*__packet_hook)(struct net_bridge_port *p, struct sk_buff *skb))
 {
 	struct net_bridge_port *p;
 	struct net_bridge_port *prev;
@@ -67,7 +104,7 @@
 
 	p = br->port_list;
 	while (p != NULL) {
-		if (should_forward(p, skb)) {
+		if (should_deliver(p, skb)) {
 			if (prev != NULL) {
 				struct sk_buff *skb2;
 
@@ -77,7 +114,7 @@
 					return;
 				}
 
-				__br_forward(prev, skb2);
+				__packet_hook(prev, skb2);
 			}
 
 			prev = p;
@@ -87,9 +124,21 @@
 	}
 
 	if (prev != NULL) {
-		__br_forward(prev, skb);
+		__packet_hook(prev, skb);
 		return;
 	}
 
 	kfree_skb(skb);
+}
+
+/* called under bridge lock */
+void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb, int clone)
+{
+	br_flood(br, skb, clone, __br_deliver);
+}
+
+/* called under bridge lock */
+void br_flood_forward(struct net_bridge *br, struct sk_buff *skb, int clone)
+{
+	br_flood(br, skb, clone, __br_forward);
 }
diff -u --recursive --new-file v2.4.5/linux/net/bridge/br_input.c linux/net/bridge/br_input.c
--- v2.4.5/linux/net/bridge/br_input.c	Fri Dec 29 14:07:24 2000
+++ linux/net/bridge/br_input.c	Mon Jun 11 19:15:27 2001
@@ -5,7 +5,7 @@
  *	Authors:
  *	Lennert Buytenhek		<buytenh@gnu.org>
  *
- *	$Id: br_input.c,v 1.7 2000/12/13 16:44:14 davem Exp $
+ *	$Id: br_input.c,v 1.8 2001/06/01 09:28:28 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
@@ -17,20 +17,33 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/if_bridge.h>
+#include <linux/netfilter_bridge.h>
 #include "br_private.h"
 
 unsigned char bridge_ula[6] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
 
+static int br_pass_frame_up_finish(struct sk_buff *skb)
+{
+	netif_rx(skb);
+
+	return 0;
+}
+
 static void br_pass_frame_up(struct net_bridge *br, struct sk_buff *skb)
 {
+	struct net_device *indev;
+
 	br->statistics.rx_packets++;
 	br->statistics.rx_bytes += skb->len;
 
+	indev = skb->dev;
 	skb->dev = &br->dev;
 	skb->pkt_type = PACKET_HOST;
 	skb_pull(skb, skb->mac.raw - skb->data);
 	skb->protocol = eth_type_trans(skb, &br->dev);
-	netif_rx(skb);
+
+	NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL,
+			br_pass_frame_up_finish);
 }
 
 static void __br_handle_frame(struct sk_buff *skb)
@@ -91,7 +104,7 @@
 		goto freeandout;
 
 	if (dest[0] & 1) {
-		br_flood(br, skb, 1);
+		br_flood_forward(br, skb, 1);
 		if (!passedup)
 			br_pass_frame_up(br, skb);
 		else
@@ -116,7 +129,7 @@
 		return;
 	}
 
-	br_flood(br, skb, 0);
+	br_flood_forward(br, skb, 0);
 	return;
 
  handle_special_frame:
@@ -129,7 +142,7 @@
 	kfree_skb(skb);
 }
 
-void br_handle_frame(struct sk_buff *skb)
+static int br_handle_frame_finish(struct sk_buff *skb)
 {
 	struct net_bridge *br;
 
@@ -137,4 +150,12 @@
 	read_lock(&br->lock);
 	__br_handle_frame(skb);
 	read_unlock(&br->lock);
+
+	return 0;
+}
+
+void br_handle_frame(struct sk_buff *skb)
+{
+	NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
+			br_handle_frame_finish);
 }
diff -u --recursive --new-file v2.4.5/linux/net/bridge/br_private.h linux/net/bridge/br_private.h
--- v2.4.5/linux/net/bridge/br_private.h	Fri Feb  9 11:34:13 2001
+++ linux/net/bridge/br_private.h	Mon Jun 11 19:15:27 2001
@@ -4,7 +4,7 @@
  *	Authors:
  *	Lennert Buytenhek		<buytenh@gnu.org>
  *
- *	$Id: br_private.h,v 1.5 2001/02/05 06:03:47 davem Exp $
+ *	$Id: br_private.h,v 1.6 2001/06/01 09:28:28 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
@@ -141,11 +141,16 @@
 		   int is_local);
 
 /* br_forward.c */
+extern void br_deliver(struct net_bridge_port *to,
+		struct sk_buff *skb);
 extern void br_forward(struct net_bridge_port *to,
 		struct sk_buff *skb);
-extern void br_flood(struct net_bridge *br,
-	      struct sk_buff *skb,
-	      int clone);
+extern void br_flood_deliver(struct net_bridge *br,
+		      struct sk_buff *skb,
+		      int clone);
+extern void br_flood_forward(struct net_bridge *br,
+		      struct sk_buff *skb,
+		      int clone);
 
 /* br_if.c */
 extern int br_add_bridge(char *name);
diff -u --recursive --new-file v2.4.5/linux/net/core/dev.c linux/net/core/dev.c
--- v2.4.5/linux/net/core/dev.c	Sat May 19 18:11:49 2001
+++ linux/net/core/dev.c	Wed Jun 20 21:00:55 2001
@@ -20,6 +20,10 @@
  *              Pekka Riikonen <priikone@poesidon.pspt.fi>
  *
  *	Changes:
+ *              D.J. Barrow     :       Fixed bug where dev->refcnt gets set to 2
+ *                                      if register_netdev gets called before
+ *                                      net_dev_init & also removed a few lines
+ *                                      of code in the process.
  *		Alan Cox	:	device private ioctl copies fields back.
  *		Alan Cox	:	Transmit queue code does relevant stunts to
  *					keep the queue safe.
@@ -1278,7 +1282,7 @@
 
 	ret = pt->func(skb, skb->dev, pt);
 
-	tasklet_enable(bh_task_vec+TIMER_BH);
+	tasklet_hi_enable(bh_task_vec+TIMER_BH);
 	spin_unlock(&net_bh_lock);
 	return ret;
 }
@@ -2382,6 +2386,8 @@
  *	will not get the same name.
  */
 
+int net_dev_init(void);
+
 int register_netdevice(struct net_device *dev)
 {
 	struct net_device *d, **dp;
@@ -2396,47 +2402,8 @@
 	dev->fastpath_lock=RW_LOCK_UNLOCKED;
 #endif
 
-	if (dev_boot_phase) {
-#ifdef CONFIG_NET_DIVERT
-		ret = alloc_divert_blk(dev);
-		if (ret)
-			return ret;
-#endif /* CONFIG_NET_DIVERT */
-		
-		/* This is NOT bug, but I am not sure, that all the
-		   devices, initialized before netdev module is started
-		   are sane. 
-
-		   Now they are chained to device boot list
-		   and probed later. If a module is initialized
-		   before netdev, but assumes that dev->init
-		   is really called by register_netdev(), it will fail.
-
-		   So that this message should be printed for a while.
-		 */
-		printk(KERN_INFO "early initialization of device %s is deferred\n", dev->name);
-
-		/* Check for existence, and append to tail of chain */
-		for (dp=&dev_base; (d=*dp) != NULL; dp=&d->next) {
-			if (d == dev || strcmp(d->name, dev->name) == 0) {
-				return -EEXIST;
-			}
-		}
-		dev->next = NULL;
-		write_lock_bh(&dev_base_lock);
-		*dp = dev;
-		dev_hold(dev);
-		write_unlock_bh(&dev_base_lock);
-
-		/*
-		 *	Default initial state at registry is that the
-		 *	device is present.
-		 */
-
-		set_bit(__LINK_STATE_PRESENT, &dev->state);
-
-		return 0;
-	}
+	if (dev_boot_phase)
+		net_dev_init();
 
 #ifdef CONFIG_NET_DIVERT
 	ret = alloc_divert_blk(dev);
@@ -2679,6 +2646,9 @@
 {
 	struct net_device *dev, **dp;
 	int i;
+
+	if (!dev_boot_phase)
+		return 0;
 
 #ifdef CONFIG_NET_SCHED
 	pktsched_init();
diff -u --recursive --new-file v2.4.5/linux/net/core/neighbour.c linux/net/core/neighbour.c
--- v2.4.5/linux/net/core/neighbour.c	Tue Nov 28 21:53:45 2000
+++ linux/net/core/neighbour.c	Mon Jun 11 19:15:27 2001
@@ -308,7 +308,7 @@
 	}
 
 	/* Device specific setup. */
-	if (n->parms && n->parms->neigh_setup &&
+	if (n->parms->neigh_setup &&
 	    (error = n->parms->neigh_setup(n)) < 0) {
 		neigh_release(n);
 		return ERR_PTR(error);
diff -u --recursive --new-file v2.4.5/linux/net/decnet/af_decnet.c linux/net/decnet/af_decnet.c
--- v2.4.5/linux/net/decnet/af_decnet.c	Tue May  1 16:05:00 2001
+++ linux/net/decnet/af_decnet.c	Wed Jun 27 17:10:55 2001
@@ -1488,7 +1488,11 @@
 		default:
 #ifdef CONFIG_NETFILTER
 		{
-			int val, len = *optlen;
+			int val, len;
+			
+			if(get_user(len, optlen))
+				return -EFAULT;
+			
 			val = nf_getsockopt(sk, PF_DECnet, optname, 
 							optval, &len);
 			if (val >= 0)
diff -u --recursive --new-file v2.4.5/linux/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c
--- v2.4.5/linux/net/ipv4/af_inet.c	Tue May  1 20:59:24 2001
+++ linux/net/ipv4/af_inet.c	Wed Jun 20 21:00:55 2001
@@ -5,7 +5,7 @@
  *
  *		PF_INET protocol family socket handler.
  *
- * Version:	$Id: af_inet.c,v 1.130 2001/04/29 08:21:32 davem Exp $
+ * Version:	$Id: af_inet.c,v 1.131 2001/06/13 16:25:03 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -14,6 +14,8 @@
  *
  * Changes (see also sock.c)
  *
+ *		piggy,
+ *		Karl Knutson	:	Socket protocol table
  *		A.N.Kuznetsov	:	Socket death error in accept().
  *		John Richardson :	Fix non blocking error in connect()
  *					so sockets that fail to connect
@@ -88,6 +90,7 @@
 #include <linux/smp_lock.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
+#include <linux/brlock.h>
 #include <net/ip.h>
 #include <net/protocol.h>
 #include <net/arp.h>
@@ -142,6 +145,11 @@
 int (*br_ioctl_hook)(unsigned long);
 #endif
 
+/* The inetsw table contains everything that inet_create needs to
+ * build a new socket.
+ */
+struct list_head inetsw[SOCK_MAX];
+
 /* New destruction routine */
 
 void inet_sock_destruct(struct sock *sk)
@@ -309,45 +317,54 @@
 static int inet_create(struct socket *sock, int protocol)
 {
 	struct sock *sk;
-	struct proto *prot;
+        struct list_head *p;
+        struct inet_protosw *answer;
 
 	sock->state = SS_UNCONNECTED;
 	sk = sk_alloc(PF_INET, GFP_KERNEL, 1);
 	if (sk == NULL) 
 		goto do_oom;
+  
+	/* Look for the requested type/protocol pair. */
+	answer = NULL;
+	br_read_lock_bh(BR_NETPROTO_LOCK);
+	list_for_each(p, &inetsw[sock->type]) {
+		answer = list_entry(p, struct inet_protosw, list);
+
+		/* Check the non-wild match. */
+		if (protocol == answer->protocol) {
+			if (protocol != IPPROTO_IP)
+				break;
+		} else {
+			/* Check for the two wild cases. */
+			if (IPPROTO_IP == protocol) {
+				protocol = answer->protocol;
+				break;
+			}
+			if (IPPROTO_IP == answer->protocol)
+				break;
+		}
+		answer = NULL;
+	}
+	br_read_unlock_bh(BR_NETPROTO_LOCK);
 
-	switch (sock->type) {
-	case SOCK_STREAM:
-		if (protocol && protocol != IPPROTO_TCP)
-			goto free_and_noproto;
-		protocol = IPPROTO_TCP;
-		prot = &tcp_prot;
-		sock->ops = &inet_stream_ops;
-		break;
-	case SOCK_SEQPACKET:
+	if (!answer)
 		goto free_and_badtype;
-	case SOCK_DGRAM:
-		if (protocol && protocol != IPPROTO_UDP)
-			goto free_and_noproto;
-		protocol = IPPROTO_UDP;
-		sk->no_check = UDP_CSUM_DEFAULT;
-		prot=&udp_prot;
-		sock->ops = &inet_dgram_ops;
-		break;
-	case SOCK_RAW:
-		if (!capable(CAP_NET_RAW))
-			goto free_and_badperm;
-		if (!protocol)
-			goto free_and_noproto;
-		prot = &raw_prot;
+	if (answer->capability > 0 && !capable(answer->capability))
+		goto free_and_badperm;
+	if (!protocol)
+		goto free_and_noproto;
+
+	sock->ops = answer->ops;
+	sk->prot = answer->prot;
+	sk->no_check = answer->no_check;
+	if (INET_PROTOSW_REUSE & answer->flags)
 		sk->reuse = 1;
+
+	if (SOCK_RAW == sock->type) {
 		sk->num = protocol;
-		sock->ops = &inet_dgram_ops;
-		if (protocol == IPPROTO_RAW)
+		if (IPPROTO_RAW == protocol)
 			sk->protinfo.af_inet.hdrincl = 1;
-		break;
-	default:
-		goto free_and_badtype;
 	}
 
 	if (ipv4_config.no_pmtu_disc)
@@ -365,8 +382,7 @@
 	sk->family	= PF_INET;
 	sk->protocol	= protocol;
 
-	sk->prot	= prot;
-	sk->backlog_rcv = prot->backlog_rcv;
+	sk->backlog_rcv = sk->prot->backlog_rcv;
 
 	sk->protinfo.af_inet.ttl	= sysctl_ip_default_ttl;
 
@@ -395,10 +411,10 @@
 		int err = sk->prot->init(sk);
 		if (err != 0) {
 			inet_sock_release(sk);
-			return(err);
+			return err;
 		}
 	}
-	return(0);
+	return 0;
 
 free_and_badtype:
 	sk_free(sk);
@@ -969,6 +985,107 @@
 extern void tcp_init(void);
 extern void tcp_v4_init(struct net_proto_family *);
 
+/* Upon startup we insert all the elements in inetsw_array[] into
+ * the linked list inetsw.
+ */
+static struct inet_protosw inetsw_array[] =
+{
+        {
+                type:        SOCK_STREAM,
+                protocol:    IPPROTO_TCP,
+                prot:        &tcp_prot,
+                ops:         &inet_stream_ops,
+                capability:  -1,
+                no_check:    0,
+                flags:       INET_PROTOSW_PERMANENT,
+        },
+
+        {
+                type:        SOCK_DGRAM,
+                protocol:    IPPROTO_UDP,
+                prot:        &udp_prot,
+                ops:         &inet_dgram_ops,
+                capability:  -1,
+                no_check:    UDP_CSUM_DEFAULT,
+                flags:       INET_PROTOSW_PERMANENT,
+       },
+        
+
+       {
+               type:        SOCK_RAW,
+               protocol:    IPPROTO_IP,	/* wild card */
+               prot:        &raw_prot,
+               ops:         &inet_dgram_ops,
+               capability:  CAP_NET_RAW,
+               no_check:    UDP_CSUM_DEFAULT,
+               flags:       INET_PROTOSW_REUSE,
+       }
+};
+
+#define INETSW_ARRAY_LEN (sizeof(inetsw_array) / sizeof(struct inet_protosw))
+
+void
+inet_register_protosw(struct inet_protosw *p)
+{
+	struct list_head *lh;
+	struct inet_protosw *answer;
+	int protocol = p->protocol;
+
+	br_write_lock_bh(BR_NETPROTO_LOCK);
+
+	if (p->type > SOCK_MAX)
+		goto out_illegal;
+
+	/* If we are trying to override a permanent protocol, bail. */
+	answer = NULL;
+	list_for_each(lh, &inetsw[p->type]) {
+		answer = list_entry(lh, struct inet_protosw, list);
+
+		/* Check only the non-wild match. */
+		if (protocol == answer->protocol &&
+		    (INET_PROTOSW_PERMANENT & answer->flags))
+			break;
+
+		answer = NULL;
+	}
+	if (answer)
+		goto out_permanent;
+
+	/* Add to the BEGINNING so that we override any existing
+	 * entry.  This means that when we remove this entry, the
+	 * system automatically returns to the old behavior.
+	 */
+	list_add(&p->list, &inetsw[p->type]);
+out:
+	br_write_unlock_bh(BR_NETPROTO_LOCK);
+	return;
+
+out_permanent:
+	printk(KERN_ERR "Attempt to override permanent protocol %d.\n",
+	       protocol);
+	goto out;
+
+out_illegal:
+	printk(KERN_ERR
+	       "Ignoring attempt to register illegal socket type %d.\n",
+	       p->type);
+	goto out;
+}
+
+void
+inet_unregister_protosw(struct inet_protosw *p)
+{
+	if (INET_PROTOSW_PERMANENT & p->flags) {
+		printk(KERN_ERR
+		       "Attempt to unregister permanent protocol %d.\n",
+		       p->protocol);
+	} else {
+		br_write_lock_bh(BR_NETPROTO_LOCK);
+		list_del(&p->list);
+		br_write_unlock_bh(BR_NETPROTO_LOCK);
+	}
+}
+
 
 /*
  *	Called by socket.c on kernel startup.  
@@ -978,6 +1095,8 @@
 {
 	struct sk_buff *dummy_skb;
 	struct inet_protocol *p;
+	struct inet_protosw *q;
+	struct list_head *r;
 
 	printk(KERN_INFO "NET4: Linux TCP/IP 1.0 for NET4.0\n");
 
@@ -1003,6 +1122,13 @@
 		printk("%s%s",p->name,tmp?", ":"\n");
 		p = tmp;
 	}
+
+	/* Register the socket-side information for inet_create. */
+	for(r = &inetsw[0]; r < &inetsw[SOCK_MAX]; ++r)
+		INIT_LIST_HEAD(r);
+
+	for(q = inetsw_array; q < &inetsw_array[INETSW_ARRAY_LEN]; ++q)
+		inet_register_protosw(q);
 
 	/*
 	 *	Set the ARP module up
diff -u --recursive --new-file v2.4.5/linux/net/ipv4/fib_frontend.c linux/net/ipv4/fib_frontend.c
--- v2.4.5/linux/net/ipv4/fib_frontend.c	Wed May 16 10:31:23 2001
+++ linux/net/ipv4/fib_frontend.c	Mon Jun 11 19:15:27 2001
@@ -5,7 +5,7 @@
  *
  *		IPv4 Forwarding Information Base: FIB frontend.
  *
- * Version:	$Id: fib_frontend.c,v 1.24 2001/05/13 18:14:46 davem Exp $
+ * Version:	$Id: fib_frontend.c,v 1.25 2001/05/29 22:16:25 davem Exp $
  *
  * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
  *
@@ -236,8 +236,7 @@
 	if (res.type != RTN_UNICAST)
 		goto e_inval_res;
 	*spec_dst = FIB_RES_PREFSRC(res);
-	if (itag)
-		fib_combine_itag(itag, &res);
+	fib_combine_itag(itag, &res);
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
 	if (FIB_RES_DEV(res) == dev || res.fi->fib_nhs > 1)
 #else
diff -u --recursive --new-file v2.4.5/linux/net/ipv4/icmp.c linux/net/ipv4/icmp.c
--- v2.4.5/linux/net/ipv4/icmp.c	Wed May 16 10:31:26 2001
+++ linux/net/ipv4/icmp.c	Wed Jun 20 21:00:55 2001
@@ -3,7 +3,7 @@
  *	
  *		Alan Cox, <alan@redhat.com>
  *
- *	Version: $Id: icmp.c,v 1.76 2001/05/10 01:20:58 davem Exp $
+ *	Version: $Id: icmp.c,v 1.77 2001/06/14 13:40:46 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
@@ -928,11 +928,6 @@
 	goto drop;
 }
 
-/*
- *	A spare long used to speed up statistics updating
- */
- 
-static unsigned long dummy;
 
 /* 
  * 	Configurable rate limits.
@@ -954,20 +949,20 @@
 static struct icmp_control icmp_pointers[NR_ICMP_TYPES+1] = {
 /* ECHO REPLY (0) */
  { &icmp_statistics[0].IcmpOutEchoReps, &icmp_statistics[0].IcmpInEchoReps, icmp_discard, 0, &sysctl_icmp_echoreply_time},
- { &dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1, },
- { &dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1, },
+ { &icmp_statistics[0].dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1, },
+ { &icmp_statistics[0].dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1, },
 /* DEST UNREACH (3) */
  { &icmp_statistics[0].IcmpOutDestUnreachs, &icmp_statistics[0].IcmpInDestUnreachs, icmp_unreach, 1, &sysctl_icmp_destunreach_time },
 /* SOURCE QUENCH (4) */
  { &icmp_statistics[0].IcmpOutSrcQuenchs, &icmp_statistics[0].IcmpInSrcQuenchs, icmp_unreach, 1, },
 /* REDIRECT (5) */
  { &icmp_statistics[0].IcmpOutRedirects, &icmp_statistics[0].IcmpInRedirects, icmp_redirect, 1, },
- { &dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1, },
- { &dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1, },
+ { &icmp_statistics[0].dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1, },
+ { &icmp_statistics[0].dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1, },
 /* ECHO (8) */
  { &icmp_statistics[0].IcmpOutEchos, &icmp_statistics[0].IcmpInEchos, icmp_echo, 0, },
- { &dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1, },
- { &dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1, },
+ { &icmp_statistics[0].dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1, },
+ { &icmp_statistics[0].dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1, },
 /* TIME EXCEEDED (11) */
  { &icmp_statistics[0].IcmpOutTimeExcds, &icmp_statistics[0].IcmpInTimeExcds, icmp_unreach, 1, &sysctl_icmp_timeexceed_time },
 /* PARAMETER PROBLEM (12) */
@@ -977,9 +972,9 @@
 /* TIMESTAMP REPLY (14) */
  { &icmp_statistics[0].IcmpOutTimestampReps, &icmp_statistics[0].IcmpInTimestampReps, icmp_discard, 0, },
 /* INFO (15) */
- { &dummy, &dummy, icmp_discard, 0, },
+ { &icmp_statistics[0].dummy, &icmp_statistics[0].dummy, icmp_discard, 0, },
 /* INFO REPLY (16) */
- { &dummy, &dummy, icmp_discard, 0, },
+ { &icmp_statistics[0].dummy, &icmp_statistics[0].dummy, icmp_discard, 0, },
 /* ADDR MASK (17) */
  { &icmp_statistics[0].IcmpOutAddrMasks, &icmp_statistics[0].IcmpInAddrMasks, icmp_address, 0,  },
 /* ADDR MASK REPLY (18) */
diff -u --recursive --new-file v2.4.5/linux/net/ipv4/ip_output.c linux/net/ipv4/ip_output.c
--- v2.4.5/linux/net/ipv4/ip_output.c	Thu Apr 12 12:11:39 2001
+++ linux/net/ipv4/ip_output.c	Mon Jun 11 19:15:27 2001
@@ -5,7 +5,7 @@
  *
  *		The Internet Protocol (IP) output module.
  *
- * Version:	$Id: ip_output.c,v 1.91 2001/03/29 06:25:55 davem Exp $
+ * Version:	$Id: ip_output.c,v 1.93 2001/06/01 14:59:31 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -499,7 +499,7 @@
 	 *	Begin outputting the bytes.
 	 */
 
-	id = (sk ? sk->protinfo.af_inet.id++ : 0);
+	id = sk->protinfo.af_inet.id++;
 
 	do {
 		char *data;
@@ -848,6 +848,7 @@
 		offset += len;
 
 #ifdef CONFIG_NETFILTER
+		skb2->nfmark = skb->nfmark;
 		/* Connection association is same as pre-frag packet */
 		skb2->nfct = skb->nfct;
 		nf_conntrack_get(skb2->nfct);
diff -u --recursive --new-file v2.4.5/linux/net/ipv4/netfilter/ipfwadm_core.c linux/net/ipv4/netfilter/ipfwadm_core.c
--- v2.4.5/linux/net/ipv4/netfilter/ipfwadm_core.c	Fri Aug  4 18:18:49 2000
+++ linux/net/ipv4/netfilter/ipfwadm_core.c	Mon Jun 11 19:15:27 2001
@@ -20,7 +20,7 @@
  *	license in recognition of the original copyright.
  *				-- Alan Cox.
  *
- *	$Id: ipfwadm_core.c,v 1.4 2000/07/26 01:04:21 davem Exp $
+ *	$Id: ipfwadm_core.c,v 1.5 2001/06/01 14:56:53 davem Exp $
  *
  *	Ported from BSD to Linux,
  *		Alan Cox 22/Nov/1994.
@@ -515,7 +515,7 @@
 			}
 			continue;	/* Mismatch */
 
-		ifa_ok:
+		ifa_ok:;
 		}
 
 		/*
diff -u --recursive --new-file v2.4.5/linux/net/ipv4/netfilter/ipt_REJECT.c linux/net/ipv4/netfilter/ipt_REJECT.c
--- v2.4.5/linux/net/ipv4/netfilter/ipt_REJECT.c	Fri Apr 27 14:15:01 2001
+++ linux/net/ipv4/netfilter/ipt_REJECT.c	Mon Jun 11 19:15:27 2001
@@ -309,9 +309,9 @@
     		break;
 	case IPT_TCP_RESET:
 		send_reset(*pskb, hooknum == NF_IP_LOCAL_IN);
-		break;
 	case IPT_ICMP_ECHOREPLY:
 		/* Doesn't happen. */
+		break;
 	}
 
 	return NF_DROP;
diff -u --recursive --new-file v2.4.5/linux/net/ipv4/netfilter/ipt_unclean.c linux/net/ipv4/netfilter/ipt_unclean.c
--- v2.4.5/linux/net/ipv4/netfilter/ipt_unclean.c	Thu Apr 27 15:43:15 2000
+++ linux/net/ipv4/netfilter/ipt_unclean.c	Wed Jun 20 16:05:21 2001
@@ -76,7 +76,7 @@
 		    = { 12, 12, ICMP_NOT_ERROR, 0, 0 } };
 
 	/* Can't do anything if it's a fragment. */
-	if (!offset)
+	if (offset)
 		return 1;
 
 	/* Must cover type and code. */
@@ -87,7 +87,7 @@
 
 	/* If not embedded. */
 	if (!embedded) {
-		/* Bad checksum?  Don't print, just drop. */
+		/* Bad checksum?  Don't print, just ignore. */
 		if (!more_frags
 		    && ip_compute_csum((unsigned char *) icmph, datalen) != 0)
 			return 0;
@@ -108,6 +108,8 @@
 			   length of iph + 8 bytes. */
 			struct iphdr *inner = (void *)icmph + 8;
 
+			/* datalen > 8 since all ICMP_IS_ERROR types
+                           have min length > 8 */
 			if (datalen - 8 < sizeof(struct iphdr)) {
 				limpk("ICMP error internal way too short\n");
 				return 0;
@@ -155,6 +157,8 @@
 		u_int32_t arg = ntohl(icmph->un.gateway);
 
 		if (icmph->code == 0) {
+			/* Code 0 means that upper 8 bits is pointer
+                           to problem. */
 			if ((arg >> 24) >= iph->ihl*4) {
 				limpk("ICMP PARAMETERPROB ptr = %u\n",
 				      ntohl(icmph->un.gateway) >> 24);
@@ -196,7 +200,7 @@
 	  int embedded)
 {
 	/* Can't do anything if it's a fragment. */
-	if (!offset)
+	if (offset)
 		return 1;
 
 	/* CHECK: Must cover UDP header. */
@@ -205,7 +209,7 @@
 		return 0;
 	}
 
-	/* Bad checksum?  Don't print, just drop. */
+	/* Bad checksum?  Don't print, just say it's unclean. */
 	/* FIXME: SRC ROUTE packets won't match checksum --RR */
 	if (!more_frags && !embedded
 	    && csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_UDP,
@@ -263,7 +267,7 @@
 	  int more_frags,
 	  int embedded)
 {
-	u_int8_t *opt = (u_int8_t *)(tcph + 1);
+	u_int8_t *opt = (u_int8_t *)tcph;
 	u_int8_t tcpflags;
 	int end_of_options = 0;
 	size_t i;
@@ -272,7 +276,7 @@
 	/* In fact, this is caught below (offset < 516). */
 
 	/* Can't do anything if it's a fragment. */
-	if (!offset)
+	if (offset)
 		return 1;
 
 	/* CHECK: Smaller than minimal TCP hdr. */
@@ -281,7 +285,8 @@
 			limpk("Packet length %u < TCP header.\n", datalen);
 			return 0;
 		}
-		/* Must have ports available (datalen >= 8). */
+		/* Must have ports available (datalen >= 8), from
+                   check_icmp which set embedded = 1 */
 		/* CHECK: TCP ports inside ICMP error */
 		if (!tcph->source || !tcph->dest) {
 			limpk("Zero TCP ports %u/%u.\n",
@@ -301,7 +306,7 @@
 			return 1;
 	}
 
-	/* Bad checksum?  Don't print, just drop. */
+	/* Bad checksum?  Don't print, just say it's unclean. */
 	/* FIXME: SRC ROUTE packets won't match checksum --RR */
 	if (!more_frags && !embedded
 	    && csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_TCP,
@@ -373,6 +378,8 @@
 				      (unsigned int) opt[i], i);
 				return 0;
 			}
+			/* Move to next option */
+			i += opt[i+1];
 		}
 	}
 
@@ -384,7 +391,7 @@
 static int
 check_ip(struct iphdr *iph, size_t length, int embedded)
 {
-	u_int8_t *opt = (u_int8_t *)(iph + 1);
+	u_int8_t *opt = (u_int8_t *)iph;
 	int end_of_options = 0;
 	void *protoh;
 	size_t datalen;
@@ -430,18 +437,20 @@
 				      opt[i]);
 				return 0;
 			}
-			/* CHECK: zero-length options. */
-			else if (opt[i+1] == 0) {
-				limpk("IP option %u 0 len\n",
-				      opt[i]);
+			/* CHECK: zero-length or one-length options. */
+			else if (opt[i+1] < 2) {
+				limpk("IP option %u %u len\n",
+				      opt[i], opt[i+1]);
 				return 0;
 			}
 			/* CHECK: oversize options. */
-			else if (opt[i+1] + i >= iph->ihl * 4) {
+			else if (opt[i+1] + i > iph->ihl * 4) {
 				limpk("IP option %u at %u too long\n",
 				      opt[i], i);
 				return 0;
 			}
+			/* Move to next option */
+			i += opt[i+1];
 		}
 	}
 
@@ -495,10 +504,10 @@
 		return 0;
 	}
 
-	/* CHECK: Min offset of frag = 128 - 60 (max IP hdr len). */
-	if (offset && offset * 8 < MIN_LIKELY_MTU - 60) {
+	/* CHECK: Min offset of frag = 128 - IP hdr len. */
+	if (offset && offset * 8 < MIN_LIKELY_MTU - iph->ihl * 4) {
 		limpk("Fragment starts at %u < %u\n", offset * 8,
-		      MIN_LIKELY_MTU-60);
+		      MIN_LIKELY_MTU - iph->ihl * 4);
 		return 0;
 	}
 
diff -u --recursive --new-file v2.4.5/linux/net/ipv4/raw.c linux/net/ipv4/raw.c
--- v2.4.5/linux/net/ipv4/raw.c	Wed May 16 10:31:27 2001
+++ linux/net/ipv4/raw.c	Thu Jun 14 14:16:58 2001
@@ -5,7 +5,7 @@
  *
  *		RAW - implementation of IP "raw" sockets.
  *
- * Version:	$Id: raw.c,v 1.61 2001/05/03 20:56:04 davem Exp $
+ * Version:	$Id: raw.c,v 1.62 2001/06/05 10:52:15 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -121,8 +121,11 @@
 	int type;
 
 	type = skb->h.icmph->type;
-	if (type < 32)
-		return test_bit(type, &sk->tp_pinfo.tp_raw4.filter);
+	if (type < 32) {
+		__u32 data = sk->tp_pinfo.tp_raw4.filter.data;
+
+		return ((1 << type) & data) != 0;
+	}
 
 	/* Do not block unknown ICMP types */
 	return 0;
diff -u --recursive --new-file v2.4.5/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c
--- v2.4.5/linux/net/ipv4/tcp_input.c	Thu May 24 15:00:59 2001
+++ linux/net/ipv4/tcp_input.c	Mon Jun 11 19:15:27 2001
@@ -5,7 +5,7 @@
  *
  *		Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:	$Id: tcp_input.c,v 1.231 2001/05/22 05:15:16 davem Exp $
+ * Version:	$Id: tcp_input.c,v 1.232 2001/05/24 22:32:49 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -2611,10 +2611,10 @@
 	if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) {
 		/* A retransmit, 2nd most common case.  Force an immediate ack. */
 		NET_INC_STATS_BH(DelayedACKLost);
-		tcp_enter_quickack_mode(tp);
 		tcp_dsack_set(tp, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq);
 
 out_of_window:
+		tcp_enter_quickack_mode(tp);
 		tcp_schedule_ack(tp);
 drop:
 		__kfree_skb(skb);
diff -u --recursive --new-file v2.4.5/linux/net/ipv6/addrconf.c linux/net/ipv6/addrconf.c
--- v2.4.5/linux/net/ipv6/addrconf.c	Wed May 16 10:31:27 2001
+++ linux/net/ipv6/addrconf.c	Wed Jun 20 21:00:55 2001
@@ -6,7 +6,7 @@
  *	Pedro Roque		<roque@di.fc.ul.pt>	
  *	Alexey Kuznetsov	<kuznet@ms2.inr.ac.ru>
  *
- *	$Id: addrconf.c,v 1.65 2001/05/03 07:02:47 davem Exp $
+ *	$Id: addrconf.c,v 1.66 2001/06/11 00:39:29 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -1389,7 +1389,10 @@
 	if (ifp->probes++ < ifp->idev->cnf.rtr_solicits) {
 		struct in6_addr all_routers;
 
+		/* The wait after the last probe can be shorter */
 		addrconf_mod_timer(ifp, AC_RS,
+				   (ifp->probes == ifp->idev->cnf.rtr_solicits) ?
+				   ifp->idev->cnf.rtr_solicit_delay :
 				   ifp->idev->cnf.rtr_solicit_interval);
 		spin_unlock(&ifp->lock);
 
diff -u --recursive --new-file v2.4.5/linux/net/ipv6/af_inet6.c linux/net/ipv6/af_inet6.c
--- v2.4.5/linux/net/ipv6/af_inet6.c	Thu Apr 12 12:11:39 2001
+++ linux/net/ipv6/af_inet6.c	Wed Jun 20 21:00:55 2001
@@ -7,9 +7,10 @@
  *
  *	Adapted from linux/net/ipv4/af_inet.c
  *
- *	$Id: af_inet6.c,v 1.63 2001/03/02 03:13:05 davem Exp $
+ *	$Id: af_inet6.c,v 1.64 2001/06/13 16:25:03 davem Exp $
  *
  * 	Fixes:
+ *	piggy, Karl Knutson	:	Socket protocol table
  * 	Hideaki YOSHIFUJI	:	sin6_scope_id support
  * 	Arnaldo Melo		: 	check proc_net_create return, cleanups
  *
@@ -44,6 +45,7 @@
 #include <linux/inet.h>
 #include <linux/netdevice.h>
 #include <linux/icmpv6.h>
+#include <linux/brlock.h>
 #include <linux/smp_lock.h>
 
 #include <net/ip.h>
@@ -71,9 +73,6 @@
 MODULE_PARM(unloadable, "i");
 #endif
 
-extern struct proto_ops inet6_stream_ops;
-extern struct proto_ops inet6_dgram_ops;
-
 /* IPv6 procfs goodies... */
 
 #ifdef CONFIG_PROC_FS
@@ -93,6 +92,11 @@
 atomic_t inet6_sock_nr;
 #endif
 
+/* The inetsw table contains everything that inet_create needs to
+ * build a new socket.
+ */
+struct list_head inetsw6[SOCK_MAX];
+
 static void inet6_sock_destruct(struct sock *sk)
 {
 	inet_sock_destruct(sk);
@@ -106,47 +110,63 @@
 static int inet6_create(struct socket *sock, int protocol)
 {
 	struct sock *sk;
-	struct proto *prot;
+	struct list_head *p;
+	struct inet_protosw *answer;
 
 	sk = sk_alloc(PF_INET6, GFP_KERNEL, 1);
 	if (sk == NULL) 
 		goto do_oom;
 
-	if(sock->type == SOCK_STREAM || sock->type == SOCK_SEQPACKET) {
-		if (protocol && protocol != IPPROTO_TCP) 
-			goto free_and_noproto;
-		protocol = IPPROTO_TCP;
-		prot = &tcpv6_prot;
-		sock->ops = &inet6_stream_ops;
-	} else if(sock->type == SOCK_DGRAM) {
-		if (protocol && protocol != IPPROTO_UDP) 
-			goto free_and_noproto;
-		protocol = IPPROTO_UDP;
-		sk->no_check = UDP_CSUM_DEFAULT;
-		prot=&udpv6_prot;
-		sock->ops = &inet6_dgram_ops;
-	} else if(sock->type == SOCK_RAW) {
-		if (!capable(CAP_NET_RAW))
-			goto free_and_badperm;
-		if (!protocol) 
-			goto free_and_noproto;
-		prot = &rawv6_prot;
-		sock->ops = &inet6_dgram_ops;
+	/* Look for the requested type/protocol pair. */
+	answer = NULL;
+	br_read_lock_bh(BR_NETPROTO_LOCK);
+	list_for_each(p, &inetsw6[sock->type]) {
+		answer = list_entry(p, struct inet_protosw, list);
+
+		/* Check the non-wild match. */
+		if (protocol == answer->protocol) {
+			if (protocol != IPPROTO_IP)
+				break;
+		} else {
+			/* Check for the two wild cases. */
+			if (IPPROTO_IP == protocol) {
+				protocol = answer->protocol;
+				break;
+			}
+			if (IPPROTO_IP == answer->protocol)
+				break;
+		}
+		answer = NULL;
+	}
+	br_read_unlock_bh(BR_NETPROTO_LOCK);
+
+	if (!answer)
+		goto free_and_badtype;
+	if (answer->capability > 0 && !capable(answer->capability))
+		goto free_and_badperm;
+	if (!protocol)
+		goto free_and_noproto;
+
+	sock->ops = answer->ops;
+	sock_init_data(sock, sk);
+
+	sk->prot = answer->prot;
+	sk->no_check = answer->no_check;
+	if (INET_PROTOSW_REUSE & answer->flags)
 		sk->reuse = 1;
+
+	if (SOCK_RAW == sock->type) {
 		sk->num = protocol;
-	} else {
-		goto free_and_badtype;
+		if (IPPROTO_RAW == protocol)
+			sk->protinfo.af_inet.hdrincl = 1;
 	}
-	
-	sock_init_data(sock, sk);
 
 	sk->destruct            = inet6_sock_destruct;
 	sk->zapped		= 0;
 	sk->family		= PF_INET6;
 	sk->protocol		= protocol;
 
-	sk->prot		= prot;
-	sk->backlog_rcv		= prot->backlog_rcv;
+	sk->backlog_rcv		= answer->prot->backlog_rcv;
 
 	sk->net_pinfo.af_inet6.hop_limit  = -1;
 	sk->net_pinfo.af_inet6.mcast_hops = -1;
@@ -175,9 +195,6 @@
 #endif
 	MOD_INC_USE_COUNT;
 
-	if (sk->type==SOCK_RAW && protocol==IPPROTO_RAW)
-		sk->protinfo.af_inet.hdrincl=1;
-
 	if (sk->num) {
 		/* It assumes that any protocol which allows
 		 * the user to assign a number at socket
@@ -186,16 +203,15 @@
 		sk->sport = ntohs(sk->num);
 		sk->prot->hash(sk);
 	}
-
 	if (sk->prot->init) {
 		int err = sk->prot->init(sk);
 		if (err != 0) {
 			MOD_DEC_USE_COUNT;
 			inet_sock_release(sk);
-			return(err);
+			return err;
 		}
 	}
-	return(0);
+	return 0;
 
 free_and_badtype:
 	sk_free(sk);
@@ -504,9 +520,76 @@
 extern void ipv6_sysctl_unregister(void);
 #endif
 
+static struct inet_protosw rawv6_protosw = {
+	type:        SOCK_RAW,
+	protocol:    IPPROTO_IP,	/* wild card */
+	prot:        &rawv6_prot,
+	ops:         &inet6_dgram_ops,
+	capability:  CAP_NET_RAW,
+	no_check:    UDP_CSUM_DEFAULT,
+	flags:       INET_PROTOSW_REUSE,
+};
+
+#define INETSW6_ARRAY_LEN (sizeof(inetsw6_array) / sizeof(struct inet_protosw))
+
+void
+inet6_register_protosw(struct inet_protosw *p)
+{
+	struct list_head *lh;
+	struct inet_protosw *answer;
+	int protocol = p->protocol;
+
+	br_write_lock_bh(BR_NETPROTO_LOCK);
+
+	if (p->type > SOCK_MAX)
+		goto out_illegal;
+
+	/* If we are trying to override a permanent protocol, bail. */
+	answer = NULL;
+	list_for_each(lh, &inetsw6[p->type]) {
+		answer = list_entry(lh, struct inet_protosw, list);
+
+		/* Check only the non-wild match. */
+		if (protocol == answer->protocol &&
+		    (INET_PROTOSW_PERMANENT & answer->flags))
+			break;
+
+		answer = NULL;
+	}
+	if (answer)
+		goto out_permanent;
+
+	/* Add to the BEGINNING so that we override any existing
+	 * entry.  This means that when we remove this entry, the
+	 * system automatically returns to the old behavior.
+	 */
+	list_add(&p->list, &inetsw6[p->type]);
+out:
+	br_write_unlock_bh(BR_NETPROTO_LOCK);
+	return;
+
+out_permanent:
+	printk(KERN_ERR "Attempt to override permanent protocol %d.\n",
+	       protocol);
+	goto out;
+
+out_illegal:
+	printk(KERN_ERR
+	       "Ignoring attempt to register illegal socket type %d.\n",
+	       p->type);
+	goto out;
+}
+
+void
+inet6_unregister_protosw(struct inet_protosw *p)
+{
+	inet_unregister_protosw(p);
+}
+
 static int __init inet6_init(void)
 {
 	struct sk_buff *dummy_skb;
+        struct list_head *r;
 	int err;
 
 #ifdef MODULE
@@ -523,6 +606,15 @@
 		printk(KERN_CRIT "inet6_proto_init: size fault\n");
 		return -EINVAL;
 	}
+
+	/* Register the socket-side information for inet6_create.  */
+	for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r)
+		INIT_LIST_HEAD(r);
+
+	/* We MUST register RAW sockets before we create the ICMP6,
+	 * IGMP6, or NDISC control sockets.
+	 */
+	inet6_register_protosw(&rawv6_protosw);
 
 	/*
 	 *	ipngwg API draft makes clear that the correct semantics
diff -u --recursive --new-file v2.4.5/linux/net/ipv6/exthdrs.c linux/net/ipv6/exthdrs.c
--- v2.4.5/linux/net/ipv6/exthdrs.c	Thu Apr 12 12:11:39 2001
+++ linux/net/ipv6/exthdrs.c	Wed Jun 20 21:00:55 2001
@@ -7,7 +7,7 @@
  *	Andi Kleen		<ak@muc.de>
  *	Alexey Kuznetsov	<kuznet@ms2.inr.ac.ru>
  *
- *	$Id: exthdrs.c,v 1.12 2001/01/22 02:36:37 davem Exp $
+ *	$Id: exthdrs.c,v 1.13 2001/06/19 15:58:56 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -112,6 +112,7 @@
 	if ((skb->h.raw + len) - skb->data > skb_headlen(skb))
 		goto bad;
 
+	off += 2;
 	len -= 2;
 
 	while (len > 0) {
diff -u --recursive --new-file v2.4.5/linux/net/ipv6/icmp.c linux/net/ipv6/icmp.c
--- v2.4.5/linux/net/ipv6/icmp.c	Thu Apr 12 12:11:39 2001
+++ linux/net/ipv6/icmp.c	Wed Jun 20 21:00:55 2001
@@ -5,7 +5,7 @@
  *	Authors:
  *	Pedro Roque		<roque@di.fc.ul.pt>
  *
- *	$Id: icmp.c,v 1.31 2001/01/22 02:36:37 davem Exp $
+ *	$Id: icmp.c,v 1.32 2001/06/10 09:20:07 davem Exp $
  *
  *	Based on net/ipv4/icmp.c
  *
@@ -564,7 +564,7 @@
 		 */
 		if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
 			goto discard_it;
-		hdr = (struct icmp6hdr *) skb->data;
+		hdr = (struct icmp6hdr *) skb->h.raw;
 		orig_hdr = (struct ipv6hdr *) (hdr + 1);
 		rt6_pmtu_discovery(&orig_hdr->daddr, &orig_hdr->saddr, dev,
 				   ntohl(hdr->icmp6_mtu));
diff -u --recursive --new-file v2.4.5/linux/net/ipv6/ip6_fib.c linux/net/ipv6/ip6_fib.c
--- v2.4.5/linux/net/ipv6/ip6_fib.c	Sun Mar 25 18:14:25 2001
+++ linux/net/ipv6/ip6_fib.c	Thu Jun 14 14:16:58 2001
@@ -5,7 +5,7 @@
  *	Authors:
  *	Pedro Roque		<roque@di.fc.ul.pt>	
  *
- *	$Id: ip6_fib.c,v 1.23 2001/03/19 20:31:17 davem Exp $
+ *	$Id: ip6_fib.c,v 1.24 2001/06/05 11:36:55 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -174,7 +174,7 @@
 
 			xb = ntohl(xb);
 
-			while (test_bit(j, &xb) == 0)
+			while ((xb & (1 << j)) == 0)
 				j--;
 
 			return (i * 32 + 31 - j);
diff -u --recursive --new-file v2.4.5/linux/net/ipv6/raw.c linux/net/ipv6/raw.c
--- v2.4.5/linux/net/ipv6/raw.c	Thu Apr 12 12:11:39 2001
+++ linux/net/ipv6/raw.c	Thu Jun 14 14:16:58 2001
@@ -7,7 +7,7 @@
  *
  *	Adapted from linux/net/ipv4/raw.c
  *
- *	$Id: raw.c,v 1.45 2001/02/18 09:10:42 davem Exp $
+ *	$Id: raw.c,v 1.46 2001/06/05 11:36:55 davem Exp $
  *
  *	Fixes:
  *	Hideaki YOSHIFUJI	:	sin6_scope_id support
@@ -117,8 +117,13 @@
 
 	opt = &sk->tp_pinfo.tp_raw;
 	if (pskb_may_pull(skb, sizeof(struct icmp6hdr))) {
+		__u32 *data = &opt->filter.data[0];
+		int bit_nr;
+
 		icmph = (struct icmp6hdr *) skb->data;
-		return test_bit(icmph->icmp6_type, &opt->filter);
+		bit_nr = icmph->icmp6_type;
+
+		return (data[bit_nr >> 5] & (1 << (bit_nr & 31))) != 0;
 	}
 	return 0;
 }
diff -u --recursive --new-file v2.4.5/linux/net/ipv6/tcp_ipv6.c linux/net/ipv6/tcp_ipv6.c
--- v2.4.5/linux/net/ipv6/tcp_ipv6.c	Wed Apr 25 14:57:39 2001
+++ linux/net/ipv6/tcp_ipv6.c	Wed Jun 20 21:00:55 2001
@@ -5,7 +5,7 @@
  *	Authors:
  *	Pedro Roque		<roque@di.fc.ul.pt>	
  *
- *	$Id: tcp_ipv6.c,v 1.136 2001/04/20 20:46:19 davem Exp $
+ *	$Id: tcp_ipv6.c,v 1.137 2001/06/13 16:25:03 davem Exp $
  *
  *	Based on: 
  *	linux/net/ipv4/tcp.c
@@ -2125,8 +2125,21 @@
 	"TCPv6"			/* name			*/
 };
 
+extern struct proto_ops inet6_stream_ops;
+
+static struct inet_protosw tcpv6_protosw = {
+	type:        SOCK_STREAM,
+	protocol:    IPPROTO_TCP,
+	prot:        &tcpv6_prot,
+	ops:         &inet6_stream_ops,
+	capability:  -1,
+	no_check:    0,
+	flags:       INET_PROTOSW_PERMANENT,
+};
+
 void __init tcpv6_init(void)
 {
 	/* register inet6 protocol */
 	inet6_add_protocol(&tcpv6_protocol);
+	inet6_register_protosw(&tcpv6_protosw);
 }
diff -u --recursive --new-file v2.4.5/linux/net/ipv6/udp.c linux/net/ipv6/udp.c
--- v2.4.5/linux/net/ipv6/udp.c	Thu Apr 12 12:11:39 2001
+++ linux/net/ipv6/udp.c	Wed Jun 20 21:00:55 2001
@@ -7,7 +7,7 @@
  *
  *	Based on linux/ipv4/udp.c
  *
- *	$Id: udp.c,v 1.62 2001/03/06 21:15:11 davem Exp $
+ *	$Id: udp.c,v 1.63 2001/06/13 16:25:03 davem Exp $
  *
  *	Fixes:
  *	Hideaki YOSHIFUJI	:	sin6_scope_id support
@@ -992,7 +992,21 @@
 	get_port:	udp_v6_get_port,
 };
 
+extern struct proto_ops inet6_dgram_ops;
+
+static struct inet_protosw udpv6_protosw = {
+	type:        SOCK_DGRAM,
+	protocol:    IPPROTO_UDP,
+	prot:        &udpv6_prot,
+	ops:         &inet6_dgram_ops,
+	capability:  -1,
+	no_check:    UDP_CSUM_DEFAULT,
+	flags:       INET_PROTOSW_PERMANENT,
+};
+
+
 void __init udpv6_init(void)
 {
 	inet6_add_protocol(&udpv6_protocol);
+	inet6_register_protosw(&udpv6_protosw);
 }
diff -u --recursive --new-file v2.4.5/linux/net/irda/irnet/irnet.h linux/net/irda/irnet/irnet.h
--- v2.4.5/linux/net/irda/irnet/irnet.h	Tue May  1 16:05:00 2001
+++ linux/net/irda/irnet/irnet.h	Mon Jun 11 19:15:27 2001
@@ -168,6 +168,23 @@
  *		(but PPP doesn't read the MTU value :-()
  *	o Declare hashbin HB_NOLOCK instead of HB_LOCAL to avoid
  *		disabling and enabling irq twice
+ *
+ * v6 - 31/05/01 - Jean II
+ *	o Print source address in Found, Discovery, Expiry & Request events
+ *	o Print requested source address in /proc/net/irnet
+ *	o Change control channel input. Allow multiple commands in one line.
+ *	o Add saddr command to change ap->rsaddr (and use that in IrDA)
+ *	---
+ *	o Make the IrDA connection procedure totally asynchronous.
+ *	  Heavy rewrite of the IAS query code and the whole connection
+ *	  procedure. Now, irnet_connect() no longer need to be called from
+ *	  a process context...
+ *	o Enable IrDA connect retries in ppp_irnet_send(). The good thing
+ *	  is that IrDA connect retries are directly driven by PPP LCP
+ *	  retries (we retry for each LCP packet), so that everything
+ *	  is transparently controlled from pppd lcp-max-configure.
+ *	o Add ttp_connect flag to prevent rentry on the connect procedure
+ *	o Test and fixups to eliminate side effects of retries
  */
 
 /***************************** INCLUDES *****************************/
@@ -181,6 +198,8 @@
 #include <linux/devfs_fs_kernel.h>
 #include <linux/netdevice.h>
 #include <linux/poll.h>
+#include <linux/config.h>
+#include <linux/ctype.h>	/* isspace() */
 #include <asm/uaccess.h>
 
 #include <linux/ppp_defs.h>
@@ -214,7 +233,7 @@
 
 /* PPP side of the business */
 #define BLOCK_WHEN_CONNECT	/* Block packets when connecting */
-#undef CONNECT_IN_SEND		/* Will crash hard your box... */
+#define CONNECT_IN_SEND		/* Retry IrDA connection procedure */
 #undef FLUSH_TO_PPP		/* Not sure about this one, let's play safe */
 #undef SECURE_DEVIRNET		/* Bah... */
 
@@ -249,9 +268,11 @@
 #define DEBUG_IRDA_SERV_INFO	0	/* various info */
 #define DEBUG_IRDA_SERV_ERROR	1	/* problems */
 #define DEBUG_IRDA_TCB_TRACE	0	/* IRDA IrTTP callbacks */
-#define DEBUG_IRDA_OCB_TRACE	0	/* IRDA other callbacks */
 #define DEBUG_IRDA_CB_INFO	0	/* various info */
 #define DEBUG_IRDA_CB_ERROR	1	/* problems */
+#define DEBUG_IRDA_OCB_TRACE	0	/* IRDA other callbacks */
+#define DEBUG_IRDA_OCB_INFO	0	/* various info */
+#define DEBUG_IRDA_OCB_ERROR	1	/* problems */
 
 #define DEBUG_ASSERT		0	/* Verify all assertions */
 
@@ -351,13 +372,15 @@
   /* ------------------------ IrTTP part ------------------------ */
   /* We create a pseudo "socket" over the IrDA tranport */
   int			ttp_open;	/* Set when IrTTP is ready */
+  int			ttp_connect;	/* Set when IrTTP is connecting */
   struct tsap_cb *	tsap;		/* IrTTP instance (the connection) */
 
   char			rname[NICKNAME_MAX_LEN + 1];
 					/* IrDA nickname of destination */
-  __u32			raddr;		/* Requested peer IrDA address */
-  __u32			saddr;		/* my local IrDA address */
+  __u32			rdaddr;		/* Requested peer IrDA address */
+  __u32			rsaddr;		/* Requested local IrDA address */
   __u32			daddr;		/* actual peer IrDA address */
+  __u32			saddr;		/* my local IrDA address */
   __u8			dtsap_sel;	/* Remote TSAP selector */
   __u8			stsap_sel;	/* Local TSAP selector */
 
@@ -374,17 +397,14 @@
   int			nslots;		/* Number of slots for discovery */
 
   struct iriap_cb *	iriap;		/* Used to query remote IAS */
-  wait_queue_head_t	query_wait;	/* Wait for the answer to a query */
-  struct ias_value *	ias_result;	/* Result of remote IAS query */
   int			errno;		/* status of the IAS query */
 
-  /* ---------------------- Optional parts ---------------------- */
-#ifdef INITIAL_DISCOVERY
-  /* Stuff used to dump discovery log */
+  /* -------------------- Discovery log part -------------------- */
+  /* Used by initial discovery on the control channel
+   * and by irnet_discover_daddr_and_lsap_sel() */
   struct irda_device_info *discoveries;	/* Copy of the discovery log */
   int			disco_index;	/* Last read in the discovery log */
   int			disco_number;	/* Size of the discovery log */
-#endif /* INITIAL_DISCOVERY */
 
 } irnet_socket;
 
@@ -411,8 +431,9 @@
 {
   irnet_event	event;
   int		unit;
-  __u32		addr;
-  char		name[NICKNAME_MAX_LEN + 1];
+  __u32		saddr;
+  __u32		daddr;
+  char		name[NICKNAME_MAX_LEN + 1];	/* 21 + 1 */
 } irnet_log;
 
 /*
diff -u --recursive --new-file v2.4.5/linux/net/irda/irnet/irnet_irda.c linux/net/irda/irnet/irnet_irda.c
--- v2.4.5/linux/net/irda/irnet/irnet_irda.c	Sat May 19 17:47:55 2001
+++ linux/net/irda/irnet/irnet_irda.c	Mon Jun 11 19:15:27 2001
@@ -8,7 +8,6 @@
  * and exchange frames with IrTTP.
  */
 
-#include <linux/config.h>
 #include "irnet_irda.h"		/* Private header */
 
 /************************* CONTROL CHANNEL *************************/
@@ -27,14 +26,15 @@
 static void
 irnet_post_event(irnet_socket *	ap,
 		 irnet_event	event,
-		 __u32		addr,
+		 __u32		saddr,
+		 __u32		daddr,
 		 char *		name)
 {
   unsigned long		flags;		/* For spinlock */
   int			index;		/* In the log */
 
-  DENTER(CTRL_TRACE, "(ap=0x%X, event=%d, addr=%08x, name=``%s'')\n",
-	 (unsigned int) ap, event, addr, name);
+  DENTER(CTRL_TRACE, "(ap=0x%X, event=%d, daddr=%08x, name=``%s'')\n",
+	 (unsigned int) ap, event, daddr, name);
 
   /* Protect this section via spinlock.
    * Note : as we are the only event producer, we only need to exclude
@@ -45,7 +45,8 @@
   /* Copy the event in the log */
   index = irnet_events.index;
   irnet_events.log[index].event = event;
-  irnet_events.log[index].addr = addr;
+  irnet_events.log[index].daddr = daddr;
+  irnet_events.log[index].saddr = saddr;
   /* Try to copy IrDA nickname */
   if(name)
     strcpy(irnet_events.log[index].name, name);
@@ -129,6 +130,92 @@
 
 /*------------------------------------------------------------------*/
 /*
+ * Function irnet_ias_to_tsap (self, result, value)
+ *
+ *    Examine an IAS object and extract TSAP
+ *
+ * We do an IAP query to find the TSAP associated with the IrNET service.
+ * When IrIAP pass us the result of the query, this function look at
+ * the return values to check for failures and extract the TSAP if
+ * possible.
+ * Also deallocate value
+ * The failure is in self->errno
+ * Return TSAP or -1
+ */
+static inline __u8
+irnet_ias_to_tsap(irnet_socket *	self,
+		  int			result,
+		  struct ias_value *	value)
+{
+  __u8	dtsap_sel = 0;		/* TSAP we are looking for */
+
+  DENTER(IRDA_SR_TRACE, "(self=0x%X)\n", (unsigned int) self);
+
+  /* By default, no error */
+  self->errno = 0;
+
+  /* Check if request succeeded */
+  switch(result)
+    {
+      /* Standard errors : service not available */
+    case IAS_CLASS_UNKNOWN:
+    case IAS_ATTRIB_UNKNOWN:
+      DEBUG(IRDA_SR_INFO, "IAS object doesn't exist ! (%d)\n", result);
+      self->errno = -EADDRNOTAVAIL;
+      break;
+
+      /* Other errors, most likely IrDA stack failure */
+    default :
+      DEBUG(IRDA_SR_INFO, "IAS query failed ! (%d)\n", result);
+      self->errno = -EHOSTUNREACH;
+      break;
+
+      /* Success : we got what we wanted */
+    case IAS_SUCCESS:
+      break;
+    }
+
+  /* Check what was returned to us */
+  if(value != NULL)
+    {
+      /* What type of argument have we got ? */
+      switch(value->type)
+	{
+	case IAS_INTEGER:
+	  DEBUG(IRDA_SR_INFO, "result=%d\n", value->t.integer);
+	  if(value->t.integer != -1)
+	    /* Get the remote TSAP selector */
+	    dtsap_sel = value->t.integer;
+	  else 
+	    self->errno = -EADDRNOTAVAIL;
+	  break;
+	default:
+	  self->errno = -EADDRNOTAVAIL;
+	  DERROR(IRDA_SR_ERROR, "bad type ! (0x%X)\n", value->type);
+	  break;
+	}
+
+      /* Cleanup */
+      irias_delete_value(value);
+    }
+  else	/* value == NULL */
+    {
+      /* Nothing returned to us - usually result != SUCCESS */
+      if(!(self->errno))
+	{
+	  DERROR(IRDA_SR_ERROR,
+		 "IrDA bug : result == SUCCESS && value == NULL\n");
+	  self->errno = -EHOSTUNREACH;
+	}
+    }
+  DEXIT(IRDA_SR_TRACE, "\n");
+
+  /* Return the TSAP */
+  return(dtsap_sel);
+}
+
+/*------------------------------------------------------------------*/
+/*
  * Function irnet_find_lsap_sel (self)
  *
  *    Try to lookup LSAP selector in remote LM-IAS
@@ -139,7 +226,7 @@
  * Note that in some case, the query fail even before we go to sleep,
  * creating some races...
  */
-static int
+static inline int
 irnet_find_lsap_sel(irnet_socket *	self)
 {
   DENTER(IRDA_SR_TRACE, "(self=0x%X)\n", (unsigned int) self);
@@ -155,48 +242,101 @@
   self->errno = -EHOSTUNREACH;
 
   /* Query remote LM-IAS */
-  iriap_getvaluebyclass_request(self->iriap, self->saddr, self->daddr,
+  iriap_getvaluebyclass_request(self->iriap, self->rsaddr, self->daddr,
 				IRNET_SERVICE_NAME, IRNET_IAS_VALUE);
-  /* Wait for answer (if not already failed) */
-  if(self->iriap != NULL)
-    interruptible_sleep_on(&self->query_wait);
 
-  /* Check what happened */
-  if(self->errno)
+  /* The above request is non-blocking.
+   * After a while, IrDA will call us back in irnet_getvalue_confirm()
+   * We will then call irnet_ias_to_tsap() and finish the
+   * connection procedure */
+
+  DEXIT(IRDA_SR_TRACE, "\n");
+  return 0;
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Function irnet_connect_tsap (self)
+ *
+ *    Initialise the TTP socket and initiate TTP connection
+ *
+ */
+static inline int
+irnet_connect_tsap(irnet_socket *	self)
+{
+  int		err;
+
+  DENTER(IRDA_SR_TRACE, "(self=0x%X)\n", (unsigned int) self);
+
+  /* Open a local TSAP (an IrTTP instance) */
+  err = irnet_open_tsap(self);
+  if(err != 0)
     {
-      DEBUG(IRDA_SR_INFO, "IAS query failed! (%d)\n", self->errno);
-      /* Requested object/attribute doesn't exist */
-      if((self->errno == IAS_CLASS_UNKNOWN) ||
-	 (self->errno == IAS_ATTRIB_UNKNOWN))
-	return (-EADDRNOTAVAIL);
-      else
-	return (-EHOSTUNREACH);
+      self->ttp_connect = 0;
+      DERROR(IRDA_SR_ERROR, "connect aborted!\n");
+      return(err);
     }
 
-  /* Get the remote TSAP selector */
-  switch(self->ias_result->type)
+  /* Connect to remote device */
+  err = irttp_connect_request(self->tsap, self->dtsap_sel, 
+			      self->rsaddr, self->daddr, NULL, 
+			      self->max_sdu_size_rx, NULL);
+  if(err != 0)
     {
-    case IAS_INTEGER:
-      DEBUG(IRDA_SR_INFO, "result=%d\n", self->ias_result->t.integer);
-      if(self->ias_result->t.integer != -1)
-	self->dtsap_sel = self->ias_result->t.integer;
-      else 
-	self->dtsap_sel = 0;
-      break;
-    default:
-      self->dtsap_sel = 0;
-      DERROR(IRDA_SR_ERROR, "bad type ! (0x%X)\n", self->ias_result->type);
-      break;
+      self->ttp_connect = 0;
+      DERROR(IRDA_SR_ERROR, "connect aborted!\n");
+      return(err);
     }
-  /* Cleanup */
-  if(self->ias_result)
-    irias_delete_value(self->ias_result);
+
+  /* The above call is non-blocking.
+   * After a while, the IrDA stack will either call us back in
+   * irnet_connect_confirm() or irnet_disconnect_indication()
+   * See you there ;-) */
 
   DEXIT(IRDA_SR_TRACE, "\n");
-  if(self->dtsap_sel)
-    return 0;
+  return(err);
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Function irnet_discover_next_daddr (self)
+ *
+ *    Query the IrNET TSAP of the next device in the log.
+ *
+ * Used in the TSAP discovery procedure.
+ */
+static inline int
+irnet_discover_next_daddr(irnet_socket *	self)
+{
+  /* Close the last instance of IrIAP, and open a new one.
+   * We can't reuse the IrIAP instance in the IrIAP callback */
+  if(self->iriap)
+    {
+      iriap_close(self->iriap);
+      self->iriap = NULL;
+    }
+  /* Create a new IAP instance */
+  self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
+			   irnet_discovervalue_confirm);
 
-  return -EADDRNOTAVAIL;
+  /* Next discovery - before the call to avoid races */
+  self->disco_index++;
+
+  /* Check if we have one more address to try */
+  if(self->disco_index < self->disco_number)
+    {
+      /* Query remote LM-IAS */
+      iriap_getvaluebyclass_request(self->iriap,
+				    self->discoveries[self->disco_index].saddr,
+				    self->discoveries[self->disco_index].daddr,
+				    IRNET_SERVICE_NAME, IRNET_IAS_VALUE);
+      /* The above request is non-blocking.
+       * After a while, IrDA will call us back in irnet_discovervalue_confirm()
+       * We will then call irnet_ias_to_tsap() and come back here again... */
+      return(0);
+    }
+  else
+    return(1);
 }
 
 /*------------------------------------------------------------------*/
@@ -205,100 +345,67 @@
  *
  *    This try to find a device with the requested service.
  *
+ * Initiate a TSAP discovery procedure.
  * It basically look into the discovery log. For each address in the list,
  * it queries the LM-IAS of the device to find if this device offer
  * the requested service.
  * If there is more than one node supporting the service, we complain
  * to the user (it should move devices around).
- * The, we set both the destination address and the lsap selector to point
- * on the service on the unique device we have found.
+ * If we find one node which have the requested TSAP, we connect to it.
  *
- * Note : this function fails if there is more than one device in range,
- * because IrLMP doesn't disconnect the LAP when the last LSAP is closed.
- * Moreover, we would need to wait the LAP disconnection...
+ * This function just start the whole procedure. It request the discovery
+ * log and submit the first IAS query.
+ * The bulk of the job is handled in irnet_discovervalue_confirm()
+ *
+ * Note : this procedure fails if there is more than one device in range
+ * on the same dongle, because IrLMP doesn't disconnect the LAP when the
+ * last LSAP is closed. Moreover, we would need to wait the LAP
+ * disconnection...
  */
 static inline int
 irnet_discover_daddr_and_lsap_sel(irnet_socket *	self)
 {
-  struct irda_device_info *discoveries;	/* Copy of the discovery log */
-  int	number;			/* Number of nodes in the log */
-  int	i;
-  int	err = -ENETUNREACH;
-  __u32	daddr = DEV_ADDR_ANY;	/* Address we found the service on */
-  __u8	dtsap_sel = 0x0;	/* TSAP associated with it */
+  int	ret;
 
   DENTER(IRDA_SR_TRACE, "(self=0x%X)\n", (unsigned int) self);
 
-  /* Ask lmp for the current discovery log
-   * Note : we have to use irlmp_get_discoveries(), as opposed
-   * to play with the cachelog directly, because while we are
-   * making our ias query, le log might change... */
-  discoveries = irlmp_get_discoveries(&number, self->mask);
-  /* Check if the we got some results */
-  if (discoveries == NULL)
-    DRETURN(-ENETUNREACH, IRDA_SR_INFO, "Cachelog empty...\n");
+  /* Ask lmp for the current discovery log */
+  self->discoveries = irlmp_get_discoveries(&self->disco_number, self->mask);
 
-  /* 
-   * Now, check all discovered devices (if any), and connect
-   * client only about the services that the client is
-   * interested in...
-   */
-  for(i = 0; i < number; i++)
+  /* Check if the we got some results */
+  if(self->discoveries == NULL)
     {
-      /* Try the address in the log */
-      self->daddr = discoveries[i].daddr;
-      self->saddr = 0x0;
-      DEBUG(IRDA_SR_INFO, "trying daddr = %08x\n", self->daddr);
-
-      /* Query remote LM-IAS for this service */
-      err = irnet_find_lsap_sel(self);
-      switch(err)
-	{
-	case 0:
-	  /* We found the requested service */
-	  if(daddr != DEV_ADDR_ANY)
-	    {
-	      DEBUG(IRDA_SR_INFO, "More than one device in range supports IrNET...\n");
-	    }
-	  else
-	    {
-	      /* First time we found that one, save it ! */
-	      daddr = self->daddr;
-	      dtsap_sel = self->dtsap_sel;
-	    }
-	  break;
-	case -EADDRNOTAVAIL:
-	  /* Requested service simply doesn't exist on this node */
-	  break;
-	default:
-	  /* Something bad did happen :-( */
-	  DERROR(IRDA_SR_ERROR, "unexpected IAS query failure\n");
-	  self->daddr = DEV_ADDR_ANY;
-	  kfree(discoveries);
-	  return(-EHOSTUNREACH);
-	  break;
-	}
+      self->disco_number = -1;
+      self->ttp_connect = 0;
+      DRETURN(-ENETUNREACH, IRDA_SR_INFO, "No Cachelog...\n");
     }
-  /* Cleanup our copy of the discovery log */
-  kfree(discoveries);
+  DEBUG(IRDA_SR_INFO, "Got the log (0x%X), size is %d\n",
+	(unsigned int) self->discoveries, self->disco_number);
 
-  /* Check out what we found */
-  if(daddr == DEV_ADDR_ANY)
+  /* Start with the first discovery */
+  self->disco_index = -1;
+  self->daddr = DEV_ADDR_ANY;
+
+  /* This will fail if the log is empty - this is non-blocking */
+  ret = irnet_discover_next_daddr(self);
+  if(ret)
     {
-      self->daddr = DEV_ADDR_ANY;
-      DEXIT(IRDA_SR_INFO, "cannot discover IrNET in any device !!!\n");
-      return(-EADDRNOTAVAIL);
+      /* Close IAP */
+      iriap_close(self->iriap);
+      self->iriap = NULL;
+
+      /* Cleanup our copy of the discovery log */
+      kfree(self->discoveries);
+      self->discoveries = NULL;
+
+      self->ttp_connect = 0;
+      DRETURN(-ENETUNREACH, IRDA_SR_INFO, "Cachelog empty...\n");
     }
 
-  /* Revert back to discovered device & service */
-  self->daddr = daddr;
-  self->saddr = 0x0;
-  self->dtsap_sel = dtsap_sel;
+  /* Follow me in irnet_discovervalue_confirm() */
 
-  DEBUG(IRDA_SR_INFO, "discovered IrNET at address %08x\n", self->daddr);
   DEXIT(IRDA_SR_TRACE, "\n");
-
-  return 0;
+  return(0);
 }
 
 /*------------------------------------------------------------------*/
@@ -367,13 +474,13 @@
 
   self->magic = IRNET_MAGIC;	/* Paranoia */
 
-  init_waitqueue_head(&self->query_wait);
-
   self->ttp_open = 0;		/* Prevent higher layer from accessing IrTTP */
+  self->ttp_connect = 0;	/* Not connecting yet */
   self->rname[0] = '\0';	/* May be set via control channel */
-  self->raddr = DEV_ADDR_ANY;	/* May be set via control channel */
+  self->rdaddr = DEV_ADDR_ANY;	/* May be set via control channel */
+  self->rsaddr = 0x0;		/* May be set via control channel */
   self->daddr = DEV_ADDR_ANY;	/* Until we get connected */
-  self->saddr = 0x0;		/* so IrLMP assign us any link */
+  self->saddr = 0x0;		/* Until we get connected */
   self->max_sdu_size_rx = TTP_SAR_UNBOUND;
 
   /* Register as a client with IrLMP */
@@ -395,6 +502,12 @@
  *	o convert device name to an address
  *	o find the socket number (dlsap)
  *	o Establish the connection
+ *
+ * Note : We no longer mimic af_irda. The IAS query for finding the TSAP
+ * is done asynchronously, like the TTP connection. This allow us to
+ * call this function from any context (not only process).
+ * The downside is that following what's happening in there is tricky
+ * because it involve various functions all over the place...
  */
 int
 irda_irnet_connect(irnet_socket *	self)
@@ -406,8 +519,11 @@
   /* Check if we have opened a local TSAP :
    * If we have already opened a TSAP, it means that either we are already
    * connected or in the process of doing so... */
-  if(self->tsap != NULL)
+  if(self->ttp_connect)
     DRETURN(-EBUSY, IRDA_SOCK_INFO, "Already connecting...\n");
+  self->ttp_connect = 1;
+  if((self->iriap != NULL) || (self->tsap != NULL))
+    DERROR(IRDA_SOCK_ERROR, "Socket not cleaned up...\n");
 
   /* Insert ourselves in the hashbin so that the IrNET server can find us.
    * Notes : 4th arg is string of 32 char max and must be null terminated
@@ -423,41 +539,34 @@
     }
 
   /* If we don't have anything (no address, no name) */
-  if((self->raddr == DEV_ADDR_ANY) && (self->rname[0] == '\0'))
+  if((self->rdaddr == DEV_ADDR_ANY) && (self->rname[0] == '\0'))
     {
       /* Try to find a suitable address */
-      if((err = irnet_discover_daddr_and_lsap_sel(self)) != 0) 
+      if((err = irnet_discover_daddr_and_lsap_sel(self)) != 0)
 	DRETURN(err, IRDA_SOCK_INFO, "auto-connect failed!\n");
+      /* In most cases, the call above is non-blocking */
     }
   else
     {
       /* If we have only the name (no address), try to get an address */
-      if(self->raddr == DEV_ADDR_ANY)
+      if(self->rdaddr == DEV_ADDR_ANY)
 	{
 	  if((err = irnet_dname_to_daddr(self)) != 0)
-	    DRETURN(err, IRDA_SOCK_INFO, "name-connect failed!\n");
+	    DRETURN(err, IRDA_SOCK_INFO, "name connect failed!\n");
 	}
       else
 	/* Use the requested destination address */
-	self->daddr = self->raddr;
+	self->daddr = self->rdaddr;
 
       /* Query remote LM-IAS to find LSAP selector */
-      if((err = irnet_find_lsap_sel(self)) != 0)
-	DRETURN(err, IRDA_SOCK_INFO, "connect failed!\n");
+      irnet_find_lsap_sel(self);
+      /* The above call is non blocking */
     }
-  DEBUG(IRDA_SOCK_INFO, "daddr = %08x, lsap = %d, starting IrTTP connection\n",
-	self->daddr, self->dtsap_sel);
-
-  /* Open a local TSAP (an IrTTP instance) */
-  err = irnet_open_tsap(self);
-  DABORT(err != 0, err, IRDA_SOCK_ERROR, "connect aborted!\n");
-
-  /* Connect to remote device */
-  err = irttp_connect_request(self->tsap, self->dtsap_sel, 
-			      self->saddr, self->daddr, NULL, 
-			      self->max_sdu_size_rx, NULL);
-  DABORT(err != 0, err, IRDA_SOCK_ERROR, "connect aborted!\n");
 
+  /* At this point, we are waiting for the IrDA stack to call us back,
+   * or we have already failed.
+   * We will finish the connection procedure in irnet_connect_tsap().
+   */
   DEXIT(IRDA_SOCK_TRACE, "\n");
   return(0);
 }
@@ -494,8 +603,21 @@
   irlmp_unregister_client(self->ckey);
 
   /* Unregister with LM-IAS */
-  if(self->iriap) 
-    iriap_close(self->iriap);
+  if(self->iriap)
+    { 
+      iriap_close(self->iriap);
+      self->iriap = NULL;
+    }
+
+  /* If we were connected, post a message */
+  if(self->ttp_open)
+    {
+      /* Note : as the disconnect comes from ppp_generic, the unit number
+       * doesn't exist anymore when we post the event, so we need to pass
+       * NULL as the first arg... */
+      irnet_post_event(NULL, IRNET_DISCONNECT_TO,
+		       self->saddr, self->daddr, self->rname);
+    }
 
   /* Prevent higher layer from accessing IrTTP */
   self->ttp_open = 0;
@@ -507,10 +629,6 @@
       irttp_disconnect_request(self->tsap, NULL, P_NORMAL);
       irttp_close_tsap(self->tsap);
       self->tsap = NULL;
-      /* Note : as the disconnect comes from ppp_generic, the unit number
-       * doesn't exist anymore when we post the event, so we need to pass
-       * NULL as the first arg... */
-      irnet_post_event(NULL, IRNET_DISCONNECT_TO, self->daddr, self->rname);
     }
   self->stsap_sel = 0;
 
@@ -591,8 +709,9 @@
 
   DENTER(IRDA_SERV_TRACE, "(self=0x%X)\n", (unsigned int) self);
 
-  /* Get the address of the requester */
+  /* Get the addresses of the requester */
   self->daddr = irttp_get_daddr(self->tsap);
+  self->saddr = irttp_get_saddr(self->tsap);
 
   /* Try to get the IrDA nickname of the requester */
   err = irnet_daddr_to_dname(self);
@@ -621,7 +740,7 @@
       while(new !=(irnet_socket *) NULL)
 	{
 	  /* Does it have the same address ? */
-	  if((new->raddr == self->daddr) || (new->daddr == self->daddr))
+	  if((new->rdaddr == self->daddr) || (new->daddr == self->daddr))
 	    {
 	      /* Yes !!! Get it.. */
 	      DEBUG(IRDA_SERV_INFO, "Socket 0x%X matches daddr %#08x.\n",
@@ -639,7 +758,7 @@
       while(new !=(irnet_socket *) NULL)
 	{
 	  /* Is it available ? */
-	  if(!(new->ttp_open) && (new->raddr == DEV_ADDR_ANY) &&
+	  if(!(new->ttp_open) && (new->rdaddr == DEV_ADDR_ANY) &&
 	     (new->rname[0] == '\0') && (new->ppp_open))
 	    {
 	      /* Yes !!! Get it.. */
@@ -703,6 +822,7 @@
 
   /* Allow PPP to send its junk over the new socket... */
   new->ttp_open = 1;
+  new->ttp_connect = 0;
 #ifdef CONNECT_INDIC_KICK
   /* As currently we don't packets in ppp_irnet_send(), this is not needed...
    * Also, not doing it give IrDA a chance to finish the setup properly
@@ -711,7 +831,8 @@
 #endif /* CONNECT_INDIC_KICK */
 
   /* Notify the control channel */
-  irnet_post_event(new, IRNET_CONNECT_FROM, new->daddr, self->rname);
+  irnet_post_event(new, IRNET_CONNECT_FROM,
+		   new->saddr, new->daddr, self->rname);
 
   DEXIT(IRDA_SERV_TRACE, "\n");
   return 0;
@@ -740,13 +861,14 @@
   irttp_disconnect_request(self->tsap, NULL, P_NORMAL);
 #endif /* FAIL_SEND_DISCONNECT */
 
+  /* Notify the control channel (see irnet_find_socket()) */
+  irnet_post_event(NULL, IRNET_REQUEST_FROM,
+		   self->saddr, self->daddr, self->rname);
+
   /* Clean up the server to keep it in listen state */
   self->tsap->dtsap_sel = self->tsap->lsap->dlsap_sel = LSAP_ANY;
   self->tsap->lsap->lsap_state = LSAP_DISCONNECTED;
 
-  /* Notify the control channel */
-  irnet_post_event(NULL, IRNET_REQUEST_FROM, self->daddr, self->rname);
-
   DEXIT(IRDA_SERV_TRACE, "\n");
   return;
 }
@@ -934,14 +1056,17 @@
 
   /* If we were active, notify the control channel */
   if(self->ttp_open)
-    irnet_post_event(self, IRNET_DISCONNECT_FROM, self->daddr, self->rname);
+    irnet_post_event(self, IRNET_DISCONNECT_FROM,
+		     self->saddr, self->daddr, self->rname);
   else
     /* If we were trying to connect, notify the control channel */
     if((self->tsap) && (self != &irnet_server.s))
-      irnet_post_event(self, IRNET_NOANSWER_FROM, self->daddr, self->rname);
+      irnet_post_event(self, IRNET_NOANSWER_FROM,
+		       self->saddr, self->daddr, self->rname);
 
   /* Prevent higher layer from accessing IrTTP */
   self->ttp_open = 0;
+  self->ttp_connect = 0;
 
   /* Close our IrTTP connection */
   if((self->tsap) && (self != &irnet_server.s))
@@ -1001,6 +1126,7 @@
   self->saddr = irttp_get_saddr(self->tsap);
 
   /* Allow higher layer to access IrTTP */
+  self->ttp_connect = 0;
   self->ttp_open = 1;
   /* Give a kick in the ass of ppp_generic so that he sends us some data */
   ppp_output_wakeup(&self->chan);
@@ -1021,7 +1147,8 @@
     kfree_skb(skb);
 
   /* Notify the control channel */
-  irnet_post_event(self, IRNET_CONNECT_TO, self->daddr, self->rname);
+  irnet_post_event(self, IRNET_CONNECT_TO,
+		   self->saddr, self->daddr, self->rname);
 
   DEXIT(IRDA_TCB_TRACE, "\n");
 }
@@ -1081,7 +1208,6 @@
 			LOCK_STATUS lock)
 {
   irnet_socket *	self = (irnet_socket *) instance;
-  LOCAL_FLOW		oldflow = self->tx_flow;
 
   DENTER(IRDA_TCB_TRACE, "(self=0x%X)\n", (unsigned int) self);
   DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!\n");
@@ -1090,7 +1216,8 @@
   switch(link)
     {
     case STATUS_NO_ACTIVITY:
-      irnet_post_event(self, IRNET_BLOCKED_LINK, self->daddr, self->rname);
+      irnet_post_event(self, IRNET_BLOCKED_LINK,
+		       self->saddr, self->daddr, self->rname);
       break;
     default:
       DEBUG(IRDA_CB_INFO, "Unknown status...\n");
@@ -1199,10 +1326,14 @@
 
 /*------------------------------------------------------------------*/
 /*
- * Function irnet_getvalue_confirm (obj_id, value, priv)
+ * Function irnet_getvalue_confirm (result, obj_id, value, priv)
  *
- *    Got answer from remote LM-IAS, just pass object to requester...
+ *    Got answer from remote LM-IAS, just connect
  *
+ * This is the reply to a IAS query we were doing to find the TSAP of
+ * the device we want to connect to.
+ * If we have found a valid TSAP, just initiate the TTP connection
+ * on this TSAP.
  */
 static void
 irnet_getvalue_confirm(int	result,
@@ -1213,27 +1344,146 @@
   irnet_socket *	self = (irnet_socket *) priv;
 
   DENTER(IRDA_OCB_TRACE, "(self=0x%X)\n", (unsigned int) self);
-  DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!\n");
+  DASSERT(self != NULL, , IRDA_OCB_ERROR, "Self is NULL !!!\n");
 
   /* We probably don't need to make any more queries */
   iriap_close(self->iriap);
   self->iriap = NULL;
 
-  /* Check if request succeeded */
-  if(result != IAS_SUCCESS)
+  /* Check if already connected (via irnet_connect_socket()) */
+  if(self->ttp_open)
     {
-      DEBUG(IRDA_CB_INFO, "IAS query failed! (%d)\n", result);
-      self->errno = result;	/* We really need it later */
+      DERROR(IRDA_OCB_ERROR, "Socket already connected. Ouch !\n");
+      return;
     }
-  else
+
+  /* Post process the IAS reply */
+  self->dtsap_sel = irnet_ias_to_tsap(self, result, value);
+
+  /* If error, just go out */
+  if(self->errno)
+    {
+      self->ttp_connect = 0;
+      DERROR(IRDA_OCB_ERROR, "IAS connect failed ! (0x%X)\n", self->errno);
+      return;
+    }
+
+  DEBUG(IRDA_OCB_INFO, "daddr = %08x, lsap = %d, starting IrTTP connection\n",
+	self->daddr, self->dtsap_sel);
+
+  /* Start up TTP - non blocking */
+  irnet_connect_tsap(self);
+
+  DEXIT(IRDA_OCB_TRACE, "\n");
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Function irnet_discovervalue_confirm (result, obj_id, value, priv)
+ *
+ *    Handle the TSAP discovery procedure state machine.
+ *    Got answer from remote LM-IAS, try next device
+ *
+ * We are doing a  TSAP discovery procedure, and we got an answer to
+ * a IAS query we were doing to find the TSAP on one of the address
+ * in the discovery log.
+ *
+ * If we have found a valid TSAP for the first time, save it. If it's
+ * not the first time we found one, complain.
+ *
+ * If we have more addresses in the log, just initiate a new query.
+ * Note that those query may fail (see irnet_discover_daddr_and_lsap_sel())
+ *
+ * Otherwise, wrap up the procedure (cleanup), check if we have found
+ * any device and connect to it.
+ */
+static void
+irnet_discovervalue_confirm(int		result,
+			    __u16	obj_id, 
+			    struct ias_value *value,
+			    void *	priv)
+{
+  irnet_socket *	self = (irnet_socket *) priv;
+  __u8			dtsap_sel;		/* TSAP we are looking for */
+
+  DENTER(IRDA_OCB_TRACE, "(self=0x%X)\n", (unsigned int) self);
+  DASSERT(self != NULL, , IRDA_OCB_ERROR, "Self is NULL !!!\n");
+
+  /* Post process the IAS reply */
+  dtsap_sel = irnet_ias_to_tsap(self, result, value);
+
+  /* Have we got something ? */
+  if(self->errno == 0)
+    {
+      /* We found the requested service */
+      if(self->daddr != DEV_ADDR_ANY)
+	{
+	  DERROR(IRDA_OCB_ERROR, "More than one device in range supports IrNET...\n");
+	}
+      else
+	{
+	  /* First time we found that one, save it ! */
+	  self->daddr = self->discoveries[self->disco_index].daddr;
+	  self->dtsap_sel = dtsap_sel;
+	}
+    }
+
+  /* If no failure */
+  if((self->errno == -EADDRNOTAVAIL) || (self->errno == 0))
+    {
+      int	ret;
+
+      /* Search the next node */
+      ret = irnet_discover_next_daddr(self);
+      if(!ret)
+	{
+	  /* In this case, the above request was non-blocking.
+	   * We will return here after a while... */
+	  return;
+	}
+      /* In this case, we have processed the last discovery item */
+    }
+
+  /* No more queries to be done (failure or last one) */
+
+  /* We probably don't need to make any more queries */
+  iriap_close(self->iriap);
+  self->iriap = NULL;
+
+  /* No more items : remove the log and signal termination */
+  DEBUG(IRDA_OCB_INFO, "Cleaning up log (0x%X)\n",
+	(unsigned int) self->discoveries);
+  if(self->discoveries != NULL)
+    {
+      /* Cleanup our copy of the discovery log */
+      kfree(self->discoveries);
+      self->discoveries = NULL;
+    }
+  self->disco_number = -1;
+
+  /* Check out what we found */
+  if(self->daddr == DEV_ADDR_ANY)
     {
-      /* Pass the object to the caller (so the caller must delete it) */
-      self->ias_result = value;
-      self->errno = 0;
+      self->daddr = DEV_ADDR_ANY;
+      self->ttp_connect = 0;
+      DEXIT(IRDA_OCB_TRACE, ": cannot discover IrNET in any device !!!\n");
+      return;
     }
 
-  /* Wake up any processes waiting for result */
-  wake_up_interruptible(&self->query_wait);
+  /* Check if already connected (via irnet_connect_socket()) */
+  if(self->ttp_open)
+    {
+      DERROR(IRDA_OCB_ERROR, "Socket already connected. Ouch !\n");
+      return;
+    }
+
+  /* We have a valid address - just connect */
+
+  DEBUG(IRDA_OCB_INFO, "daddr = %08x, lsap = %d, starting IrTTP connection\n",
+	self->daddr, self->dtsap_sel);
+
+  /* Start up TTP - non blocking */
+  irnet_connect_tsap(self);
 
   DEXIT(IRDA_OCB_TRACE, "\n");
 }
@@ -1268,7 +1518,7 @@
   irnet_socket *	self = &irnet_server.s;
 	
   DENTER(IRDA_OCB_TRACE, "(self=0x%X)\n", (unsigned int) self);
-  DASSERT(priv == &irnet_server, , IRDA_CB_ERROR,
+  DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
 	  "Invalid instance (0x%X) !!!\n", (unsigned int) priv);
 
   /* Check if node is discovered is a new one or an old one.
@@ -1280,12 +1530,12 @@
       return;		/* Too old, not interesting -> goodbye */
     }
 
-  DEBUG(IRDA_CB_INFO, "Discovered new IrNET/IrLAN node %s...\n",
+  DEBUG(IRDA_OCB_INFO, "Discovered new IrNET/IrLAN node %s...\n",
 	discovery->nickname);
 
   /* Notify the control channel */
-  irnet_post_event(NULL, IRNET_DISCOVER, discovery->daddr,
-		   discovery->nickname);
+  irnet_post_event(NULL, IRNET_DISCOVER,
+		   discovery->saddr, discovery->daddr, discovery->nickname);
 
   DEXIT(IRDA_OCB_TRACE, "\n");
 }
@@ -1306,15 +1556,15 @@
   irnet_socket *	self = &irnet_server.s;
 	
   DENTER(IRDA_OCB_TRACE, "(self=0x%X)\n", (unsigned int) self);
-  DASSERT(priv == &irnet_server, , IRDA_CB_ERROR,
+  DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
 	  "Invalid instance (0x%X) !!!\n", (unsigned int) priv);
 
-  DEBUG(IRDA_CB_INFO, "IrNET/IrLAN node %s expired...\n",
+  DEBUG(IRDA_OCB_INFO, "IrNET/IrLAN node %s expired...\n",
 	expiry->nickname);
 
   /* Notify the control channel */
-  irnet_post_event(NULL, IRNET_EXPIRE, expiry->daddr,
-		   expiry->nickname);
+  irnet_post_event(NULL, IRNET_EXPIRE,
+		   expiry->saddr, expiry->daddr, expiry->nickname);
 
   DEXIT(IRDA_OCB_TRACE, "\n");
 }
@@ -1370,7 +1620,8 @@
 
       /* First, get the requested configuration */
       len += sprintf(buf+len, "Requested IrDA name: \"%s\", ", self->rname);
-      len += sprintf(buf+len, "addr: %08x\n", self->raddr);
+      len += sprintf(buf+len, "daddr: %08x, ", self->rdaddr);
+      len += sprintf(buf+len, "saddr: %08x\n", self->rsaddr);
 
       /* Second, get all the PPP info */
       len += sprintf(buf+len, "	PPP state: %s",
@@ -1393,7 +1644,13 @@
 	if(self->tsap != NULL)
 	  state = "connecting";
 	else
-	  state = "idle";
+	  if(self->iriap != NULL)
+	    state = "searching";
+	  else
+	    if(self->ttp_connect)
+	      state = "weird";
+	    else
+	      state = "idle";
       len += sprintf(buf+len, "\n	IrDA state: %s, ", state);
       len += sprintf(buf+len, "daddr: %08x, ", self->daddr);
       len += sprintf(buf+len, "stsap_sel: %02x, ", self->stsap_sel);
diff -u --recursive --new-file v2.4.5/linux/net/irda/irnet/irnet_irda.h linux/net/irda/irnet/irnet_irda.h
--- v2.4.5/linux/net/irda/irnet/irnet_irda.h	Tue May  1 16:05:00 2001
+++ linux/net/irda/irnet/irnet_irda.h	Mon Jun 11 19:15:27 2001
@@ -13,7 +13,6 @@
 #define IRNET_IRDA_H
 
 /***************************** INCLUDES *****************************/
-#include <linux/config.h>
 /* Please add other headers in irnet.h */
 
 #include "irnet.h"		/* Module global include */
@@ -69,13 +68,22 @@
 	irnet_post_event(irnet_socket *,
 			 irnet_event,
 			 __u32,
+			 __u32,
 			 char *);
 /* ----------------------- IRDA SUBROUTINES ----------------------- */
 static inline int
 	irnet_open_tsap(irnet_socket *);
-static int
+static inline __u8
+	irnet_ias_to_tsap(irnet_socket *,
+			  int,
+			  struct ias_value *);
+static inline int
 	irnet_find_lsap_sel(irnet_socket *);
 static inline int
+	irnet_connect_tsap(irnet_socket *);
+static inline int
+	irnet_discover_next_daddr(irnet_socket *);
+static inline int
 	irnet_discover_daddr_and_lsap_sel(irnet_socket *);
 static inline int
 	irnet_dname_to_daddr(irnet_socket *);
@@ -135,6 +143,11 @@
 			       __u16,
 			       struct ias_value *,
 			       void *);
+static void
+	irnet_discovervalue_confirm(int,
+				    __u16, 
+				    struct ias_value *,
+				    void *);
 #ifdef DISCOVERY_EVENTS
 static void
 	irnet_discovery_indication(discovery_t *,
diff -u --recursive --new-file v2.4.5/linux/net/irda/irnet/irnet_ppp.c linux/net/irda/irnet/irnet_ppp.c
--- v2.4.5/linux/net/irda/irnet/irnet_ppp.c	Tue May  1 16:05:00 2001
+++ linux/net/irda/irnet/irnet_ppp.c	Mon Jun 11 19:15:27 2001
@@ -37,13 +37,15 @@
 		 const char *	buf,
 		 size_t		count)
 {
-  char		command[5 + NICKNAME_MAX_LEN + 2];
-  int		length = count;
+  char		command[IRNET_MAX_COMMAND];
+  char *	start;		/* Current command beeing processed */
+  char *	next;		/* Next command to process */
+  int		length;		/* Length of current command */
 
   DENTER(CTRL_TRACE, "(ap=0x%X, count=%d)\n", (unsigned int) ap, count);
 
   /* Check for overflow... */
-  DABORT(count > (5 + NICKNAME_MAX_LEN + 1), -ENOMEM,
+  DABORT(count >= IRNET_MAX_COMMAND, -ENOMEM,
 	 CTRL_ERROR, "Too much data !!!\n");
 
   /* Get the data in the driver */
@@ -53,58 +55,110 @@
       return -EFAULT;
     }
 
-  /* Strip out '\n' if needed, and safe terminate the string */
-  if(command[length - 1] == '\0')
-    length--;
-  if(command[length - 1] == '\n')
-    length--;
-  command[length] = '\0';
-  DEBUG(CTRL_INFO, "Command received is ``%s'' (%d-%d).\n",
-	command, length, count);
-
-  /* Check if we recognised the command */
-  /* First command : name */
-  if(!strncmp(command, "name", 4))
-    {
-      /* Copy the name only if is included and not "any" */
-      if((length > 5) && (strcmp(command + 5, "any")))
+  /* Safe terminate the string */
+  command[count] = '\0';
+  DEBUG(CTRL_INFO, "Command line received is ``%s'' (%d).\n",
+	command, count);
+
+  /* Check every commands in the command line */
+  next = command;
+  while(next != NULL)
+    {
+      /* Look at the next command */
+      start = next;
+
+      /* Scrap whitespaces before the command */
+      while(isspace(*start))
+	start++;
+
+      /* ',' is our command separator */
+      next = strchr(start, ',');
+      if(next)
 	{
-	  /* Copy the name for later reuse (including the '/0') */
-	  memcpy(ap->rname, command + 5, length - 5 + 1);
+	  *next = '\0';			/* Terminate command */
+	  length = next - start;	/* Length */
+	  next++;			/* Skip the '\0' */
 	}
       else
-	ap->rname[0] = '\0';
-      DEXIT(CTRL_TRACE, " - rname = ``%s''\n", ap->rname);
-      return(count);
-    }
+	length = strlen(start);
 
-  /* Second command : addr */
-  if(!strncmp(command, "addr", 4))
-    {
-      /* Copy the address only if is included and not "any" */
-      if((length > 5) && (strcmp(command + 5, "any")))
+      DEBUG(CTRL_INFO, "Found command ``%s'' (%d).\n", start, length);
+
+      /* Check if we recognised one of the known command
+       * We can't use "switch" with strings, so hack with "continue" */
+      
+      /* First command : name -> Requested IrDA nickname */
+      if(!strncmp(start, "name", 4))
 	{
-	  char *	endp;
-	  __u32		daddr;
+	  /* Copy the name only if is included and not "any" */
+	  if((length > 5) && (strcmp(start + 5, "any")))
+	    {
+	      /* Strip out trailing whitespaces */
+	      while(isspace(start[length - 1]))
+		length--;
+
+	      /* Copy the name for later reuse */
+	      memcpy(ap->rname, start + 5, length - 5);
+	      ap->rname[length - 5] = '\0';
+	    }
+	  else
+	    ap->rname[0] = '\0';
+	  DEBUG(CTRL_INFO, "Got rname = ``%s''\n", ap->rname);
 
-	  /* Convert argument to a number (last arg is the base) */
-	  daddr = simple_strtoul(command + 5, &endp, 16);
-	  /* Has it worked  ? (endp should be command + count) */
-	  DABORT(endp <= (command + 5), -EINVAL,
-		 CTRL_ERROR, "Invalid address.\n");
-	  /* Save it */
-	  ap->raddr = daddr;
+	  /* Restart the loop */
+	  continue;
+	}
+
+      /* Second command : addr, daddr -> Requested IrDA destination address
+       * Also process : saddr -> Requested IrDA source address */
+      if((!strncmp(start, "addr", 4)) ||
+	 (!strncmp(start, "daddr", 5)) ||
+	 (!strncmp(start, "saddr", 5)))
+	{
+	  __u32		addr = DEV_ADDR_ANY;
+
+	  /* Copy the address only if is included and not "any" */
+	  if((length > 5) && (strcmp(start + 5, "any")))
+	    {
+	      char *	begp = start + 5;
+	      char *	endp;
+
+	      /* Scrap whitespaces before the command */
+	      while(isspace(*begp))
+		begp++;
+
+	      /* Convert argument to a number (last arg is the base) */
+	      addr = simple_strtoul(begp, &endp, 16);
+	      /* Has it worked  ? (endp should be start + length) */
+	      DABORT(endp <= (start + 5), -EINVAL,
+		     CTRL_ERROR, "Invalid address.\n");
+	    }
+	  /* Which type of address ? */
+	  if(start[0] == 's')
+	    {
+	      /* Save it */
+	      ap->rsaddr = addr;
+	      DEBUG(CTRL_INFO, "Got rsaddr = %08x\n", ap->rsaddr);
+	    }
+	  else
+	    {
+	      /* Save it */
+	      ap->rdaddr = addr;
+	      DEBUG(CTRL_INFO, "Got rdaddr = %08x\n", ap->rdaddr);
+	    }
+
+	  /* Restart the loop */
+	  continue;
 	}
-      else
-	ap->raddr = DEV_ADDR_ANY;
-      DEXIT(CTRL_TRACE, " - raddr = %08x\n", ap->raddr);
-      return(count);
-    }
 
-  /* Other possible command : connect N (number of retries) */
+      /* Other possible command : connect N (number of retries) */
 
-  /* Failed... */
-  DABORT(1, -EINVAL, CTRL_ERROR, "Not a recognised IrNET command.\n");
+      /* No command matched -> Failed... */
+      DABORT(1, -EINVAL, CTRL_ERROR, "Not a recognised IrNET command.\n");
+    }
+
+  /* Success : we have parsed all commands successfully */
+  return(count);
 }
 
 #ifdef INITIAL_DISCOVERY
@@ -157,9 +211,10 @@
   if(ap->disco_index < ap->disco_number)
     {
       /* Write an event */
-      sprintf(event, "Found %08x (%s)\n",
+      sprintf(event, "Found %08x (%s) behind %08x\n",
 	      ap->discoveries[ap->disco_index].daddr,
-	      ap->discoveries[ap->disco_index].info);
+	      ap->discoveries[ap->disco_index].info,
+	      ap->discoveries[ap->disco_index].saddr);
       DEBUG(CTRL_INFO, "Writing discovery %d : %s\n",
 	    ap->disco_index, ap->discoveries[ap->disco_index].info);
 
@@ -256,53 +311,56 @@
   switch(irnet_events.log[ap->event_index].event)
     {
     case IRNET_DISCOVER:
-      sprintf(event, "Discovered %08x (%s)\n",
-	      irnet_events.log[ap->event_index].addr,
-	      irnet_events.log[ap->event_index].name);
+      sprintf(event, "Discovered %08x (%s) behind %08x\n",
+	      irnet_events.log[ap->event_index].daddr,
+	      irnet_events.log[ap->event_index].name,
+	      irnet_events.log[ap->event_index].saddr);
       break;
     case IRNET_EXPIRE:
-      sprintf(event, "Expired %08x (%s)\n",
-	      irnet_events.log[ap->event_index].addr,
-	      irnet_events.log[ap->event_index].name);
+      sprintf(event, "Expired %08x (%s) behind %08x\n",
+	      irnet_events.log[ap->event_index].daddr,
+	      irnet_events.log[ap->event_index].name,
+	      irnet_events.log[ap->event_index].saddr);
       break;
     case IRNET_CONNECT_TO:
       sprintf(event, "Connected to %08x (%s) on ppp%d\n",
-	      irnet_events.log[ap->event_index].addr,
+	      irnet_events.log[ap->event_index].daddr,
 	      irnet_events.log[ap->event_index].name,
 	      irnet_events.log[ap->event_index].unit);
       break;
     case IRNET_CONNECT_FROM:
       sprintf(event, "Connection from %08x (%s) on ppp%d\n",
-	      irnet_events.log[ap->event_index].addr,
+	      irnet_events.log[ap->event_index].daddr,
 	      irnet_events.log[ap->event_index].name,
 	      irnet_events.log[ap->event_index].unit);
       break;
     case IRNET_REQUEST_FROM:
-      sprintf(event, "Request from %08x (%s)\n",
-	      irnet_events.log[ap->event_index].addr,
-	      irnet_events.log[ap->event_index].name);
+      sprintf(event, "Request from %08x (%s) behind %08x\n",
+	      irnet_events.log[ap->event_index].daddr,
+	      irnet_events.log[ap->event_index].name,
+	      irnet_events.log[ap->event_index].saddr);
       break;
     case IRNET_NOANSWER_FROM:
       sprintf(event, "No-answer from %08x (%s) on ppp%d\n",
-	      irnet_events.log[ap->event_index].addr,
+	      irnet_events.log[ap->event_index].daddr,
 	      irnet_events.log[ap->event_index].name,
 	      irnet_events.log[ap->event_index].unit);
       break;
     case IRNET_BLOCKED_LINK:
       sprintf(event, "Blocked link with %08x (%s) on ppp%d\n",
-	      irnet_events.log[ap->event_index].addr,
+	      irnet_events.log[ap->event_index].daddr,
 	      irnet_events.log[ap->event_index].name,
 	      irnet_events.log[ap->event_index].unit);
       break;
     case IRNET_DISCONNECT_FROM:
       sprintf(event, "Disconnection from %08x (%s) on ppp%d\n",
-	      irnet_events.log[ap->event_index].addr,
+	      irnet_events.log[ap->event_index].daddr,
 	      irnet_events.log[ap->event_index].name,
 	      irnet_events.log[ap->event_index].unit);
       break;
     case IRNET_DISCONNECT_TO:
       sprintf(event, "Disconnected to %08x (%s)\n",
-	      irnet_events.log[ap->event_index].addr,
+	      irnet_events.log[ap->event_index].daddr,
 	      irnet_events.log[ap->event_index].name);
       break;
     default:
@@ -794,11 +852,9 @@
     {
 #ifdef CONNECT_IN_SEND
       /* Let's try to connect one more time... */
-      /* Note : we won't connect fully yet, but we should be ready for
-       * next packet... */
-      /* Note : we can't do that, we need to have a process context to
-       * go through interruptible_sleep_on() in irnet_find_lsap_sel()
-       * We need to find another way... */
+      /* Note : we won't be connected after this call, but we should be
+       * ready for next packet... */
+      /* If we are already connecting, this will fail */
       irda_irnet_connect(self);
 #endif /* CONNECT_IN_SEND */
 
diff -u --recursive --new-file v2.4.5/linux/net/irda/irnet/irnet_ppp.h linux/net/irda/irnet/irnet_ppp.h
--- v2.4.5/linux/net/irda/irnet/irnet_ppp.h	Mon Apr 30 16:26:09 2001
+++ linux/net/irda/irnet/irnet_ppp.h	Mon Jun 11 19:15:27 2001
@@ -22,13 +22,8 @@
 #define IRNET_MAJOR	10	/* Misc range */
 #define IRNET_MINOR	187	/* Official allocation */
 
-#ifdef LINKNAME_IOCTL
-/* Compatibility with old ppp drivers
- * Should be defined in <linux/if_ppp.h> */
-#ifndef PPPIOCSLINKNAME
-#define PPPIOCSLINKNAME	_IOW('t', 74, struct ppp_option_data)
-#endif /* PPPIOCSLINKNAME */
-#endif /* LINKNAME_IOCTL */
+/* IrNET control channel stuff */
+#define IRNET_MAX_COMMAND	256	/* Max length of a command line */
 
 /* PPP hardcore stuff */
 
diff -u --recursive --new-file v2.4.5/linux/net/khttpd/security.h linux/net/khttpd/security.h
--- v2.4.5/linux/net/khttpd/security.h	Wed Aug 18 09:45:10 1999
+++ linux/net/khttpd/security.h	Tue Jun 12 11:06:54 2001
@@ -9,4 +9,4 @@
 	char value[32-sizeof(void*)];  /* fill 1 cache-line */
 };
 
-#endif
\ No newline at end of file
+#endif
diff -u --recursive --new-file v2.4.5/linux/net/netlink/af_netlink.c linux/net/netlink/af_netlink.c
--- v2.4.5/linux/net/netlink/af_netlink.c	Thu Apr 12 12:11:39 2001
+++ linux/net/netlink/af_netlink.c	Wed Jun 27 13:54:26 2001
@@ -9,6 +9,9 @@
  *		as published by the Free Software Foundation; either version
  *		2 of the License, or (at your option) any later version.
  * 
+ * Tue Jun 26 14:36:48 MEST 2001 Herbert "herp" Rosmanith
+ *                               added netlink_proto_exit
+ *
  */
 
 #include <linux/config.h>
@@ -985,4 +988,11 @@
 	return 0;
 }
 
+static void __exit netlink_proto_exit(void)
+{
+	sock_unregister(PF_NETLINK);
+	remove_proc_entry("net/netlink", NULL);
+}
+
 module_init(netlink_proto_init);
+module_exit(netlink_proto_exit);
diff -u --recursive --new-file v2.4.5/linux/net/netrom/nr_dev.c linux/net/netrom/nr_dev.c
--- v2.4.5/linux/net/netrom/nr_dev.c	Wed Apr 18 14:40:07 2001
+++ linux/net/netrom/nr_dev.c	Wed Jun 27 17:10:55 2001
@@ -89,6 +89,7 @@
 	struct net_device_stats *stats = (struct net_device_stats *)dev->priv;
 	struct sk_buff *skbn;
 	unsigned char *bp = skb->data;
+	int len;
 
 	if (arp_find(bp + 7, skb)) {
 		return 1;
@@ -113,13 +114,15 @@
 
 	kfree_skb(skb);
 
+	len = skbn->len;
+	
 	if (!nr_route_frame(skbn, NULL)) {
 		kfree_skb(skbn);
 		stats->tx_errors++;
 	}
 
 	stats->tx_packets++;
-	stats->tx_bytes += skbn->len;
+	stats->tx_bytes += len;
 
 	return 1;
 }
diff -u --recursive --new-file v2.4.5/linux/net/netrom/nr_loopback.c linux/net/netrom/nr_loopback.c
--- v2.4.5/linux/net/netrom/nr_loopback.c	Fri Dec 29 14:44:46 2000
+++ linux/net/netrom/nr_loopback.c	Wed Jun 27 17:10:55 2001
@@ -92,10 +92,6 @@
 
 void __exit nr_loopback_clear(void)
 {
-	struct sk_buff *skb;
-
 	del_timer(&loopback_timer);
-
-	while ((skb = skb_dequeue(&loopback_queue)) != NULL)
-		kfree_skb(skb);
+	skb_queue_purge(&loopback_queue);
 }
diff -u --recursive --new-file v2.4.5/linux/net/netrom/nr_subr.c linux/net/netrom/nr_subr.c
--- v2.4.5/linux/net/netrom/nr_subr.c	Fri Dec 29 14:44:46 2000
+++ linux/net/netrom/nr_subr.c	Wed Jun 27 17:10:55 2001
@@ -42,19 +42,10 @@
  */
 void nr_clear_queues(struct sock *sk)
 {
-	struct sk_buff *skb;
-
-	while ((skb = skb_dequeue(&sk->write_queue)) != NULL)
-		kfree_skb(skb);
-
-	while ((skb = skb_dequeue(&sk->protinfo.nr->ack_queue)) != NULL)
-		kfree_skb(skb);
-
-	while ((skb = skb_dequeue(&sk->protinfo.nr->reseq_queue)) != NULL)
-		kfree_skb(skb);
-
-	while ((skb = skb_dequeue(&sk->protinfo.nr->frag_queue)) != NULL)
-		kfree_skb(skb);
+	skb_queue_purge(&sk->write_queue);
+	skb_queue_purge(&sk->protinfo.nr->ack_queue);
+	skb_queue_purge(&sk->protinfo.nr->reseq_queue);
+	skb_queue_purge(&sk->protinfo.nr->frag_queue);
 }
 
 /*
diff -u --recursive --new-file v2.4.5/linux/net/netsyms.c linux/net/netsyms.c
--- v2.4.5/linux/net/netsyms.c	Fri Apr 27 14:15:01 2001
+++ linux/net/netsyms.c	Wed Jun 20 21:00:55 2001
@@ -234,6 +234,8 @@
 EXPORT_SYMBOL(inetdev_lock);
 EXPORT_SYMBOL(inet_add_protocol);
 EXPORT_SYMBOL(inet_del_protocol);
+EXPORT_SYMBOL(inet_register_protosw);
+EXPORT_SYMBOL(inet_unregister_protosw);
 EXPORT_SYMBOL(ip_route_output_key);
 EXPORT_SYMBOL(ip_route_input);
 EXPORT_SYMBOL(icmp_send);
diff -u --recursive --new-file v2.4.5/linux/net/rose/rose_dev.c linux/net/rose/rose_dev.c
--- v2.4.5/linux/net/rose/rose_dev.c	Wed Apr 18 14:40:08 2001
+++ linux/net/rose/rose_dev.c	Wed Jun 27 17:10:55 2001
@@ -121,6 +121,7 @@
 	if (!rose_route_frame(skbn, NULL)) {
 		kfree_skb(skbn);
 		stats->tx_errors++;
+		return 1;
 	}
 
 	stats->tx_packets++;
diff -u --recursive --new-file v2.4.5/linux/net/sched/sch_cbq.c linux/net/sched/sch_cbq.c
--- v2.4.5/linux/net/sched/sch_cbq.c	Sun Mar 25 18:14:25 2001
+++ linux/net/sched/sch_cbq.c	Mon Jun 11 19:15:27 2001
@@ -282,6 +282,7 @@
 		case TC_POLICE_SHOT:
 			return NULL;
 		default:
+			break;
 		}
 #endif
 		if (cl->level == 0)
diff -u --recursive --new-file v2.4.5/linux/net/socket.c linux/net/socket.c
--- v2.4.5/linux/net/socket.c	Wed Apr 25 16:13:50 2001
+++ linux/net/socket.c	Mon Jun 11 19:15:27 2001
@@ -1668,6 +1668,10 @@
 extern void wanrouter_init(void);
 #endif
 
+#ifdef CONFIG_BLUEZ
+extern void bluez_init(void);
+#endif
+
 void __init sock_init(void)
 {
 	int i;
@@ -1726,6 +1730,10 @@
 #endif
 #ifdef CONFIG_NETFILTER
 	netfilter_init();
+#endif
+
+#ifdef CONFIG_BLUEZ
+	bluez_init();
 #endif
 }
 
diff -u --recursive --new-file v2.4.5/linux/net/sunrpc/svc.c linux/net/sunrpc/svc.c
--- v2.4.5/linux/net/sunrpc/svc.c	Wed Jun 21 12:43:37 2000
+++ linux/net/sunrpc/svc.c	Wed Jun 20 17:42:19 2001
@@ -368,7 +368,9 @@
 
 err_bad_prog:
 #ifdef RPC_PARANOIA
-	printk("svc: unknown program %d (me %d)\n", prog, progp->pg_prog);
+	if (prog != 100227 || progp->pg_prog != 100003)
+		printk("svc: unknown program %d (me %d)\n", prog, progp->pg_prog);
+	/* else it is just a Solaris client seeing if ACLs are supported */
 #endif
 	serv->sv_stats->rpcbadfmt++;
 	svc_putlong(resp, rpc_prog_unavail);
diff -u --recursive --new-file v2.4.5/linux/net/wanrouter/wanmain.c linux/net/wanrouter/wanmain.c
--- v2.4.5/linux/net/wanrouter/wanmain.c	Thu Apr 12 12:11:39 2001
+++ linux/net/wanrouter/wanmain.c	Wed Jun 27 17:10:55 2001
@@ -611,10 +611,10 @@
 
 	if (conf->data_size && conf->data){
 		if(conf->data_size > 128000 || conf->data_size < 0) {
-			kfree(conf);
 			printk(KERN_INFO 
 			    "%s: ERROR, Invalid firmware data size %i !\n",
 					wandev->name, conf->data_size);
+			kfree(conf);
 		        return -EINVAL;;
 		}
 
@@ -764,23 +764,23 @@
 {
 	wanif_conf_t conf;
 	netdevice_t *dev=NULL;
-      #ifdef CONFIG_WANPIPE_MULTPPP
+#ifdef CONFIG_WANPIPE_MULTPPP
 	struct ppp_device *pppdev=NULL;
-      #endif
+#endif
 	int err;
 
 	if ((wandev->state == WAN_UNCONFIGURED) || (wandev->new_if == NULL))
 		return -ENODEV;
 	
-      #if defined (LINUX_2_1) || defined (LINUX_2_4)	
+#if defined (LINUX_2_1) || defined (LINUX_2_4)	
 	if(copy_from_user(&conf, u_conf, sizeof(wanif_conf_t)))
 		return -EFAULT;
-      #else
+#else
         err = verify_area(VERIFY_READ, u_conf, sizeof(wanif_conf_t));
         if (err)
                 return err;
         memcpy_fromfs((void*)&conf, (void*)u_conf, sizeof(wanif_conf_t));
-      #endif
+#endif
 		
 	if (conf.magic != ROUTER_MAGIC)
 		return -EINVAL;
@@ -797,13 +797,14 @@
 		}
 		memset(pppdev, 0, sizeof(struct ppp_device));
 
-	      #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,16)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,16)
 		pppdev->dev = kmalloc(sizeof(netdevice_t), GFP_KERNEL);
 		if (pppdev->dev == NULL){
+			kfree(pppdev);
 			return -ENOBUFS;
 		}
 		memset(pppdev->dev, 0, sizeof(netdevice_t));
-	      #endif
+#endif
 		
 		err = wandev->new_if(wandev, (netdevice_t *)pppdev, &conf);
 		
diff -u --recursive --new-file v2.4.5/linux/net/wanrouter/wanproc.c linux/net/wanrouter/wanproc.c
--- v2.4.5/linux/net/wanrouter/wanproc.c	Thu May 24 15:01:02 2001
+++ linux/net/wanrouter/wanproc.c	Wed Jun 27 17:10:55 2001
@@ -813,8 +813,10 @@
 		offs = file->f_pos;
 		if (offs < pos) {
 			len = min(pos - offs, count);
-			if(copy_to_user(buf, (page + offs), len))
+			if (copy_to_user(buf, (page + offs), len)) {
+				kfree(page);
 				return -EFAULT;
+			}
 			file->f_pos += len;
 		}
 		else
diff -u --recursive --new-file v2.4.5/linux/scripts/docgen linux/scripts/docgen
--- v2.4.5/linux/scripts/docgen	Tue Mar 14 17:54:42 2000
+++ linux/scripts/docgen	Wed Jun 20 20:56:24 2001
@@ -1,3 +1,10 @@
 #!/bin/sh
-X=`$TOPDIR/scripts/gen-all-syms "$*"`
-$TOPDIR/scripts/docproc $X
+set -e
+if [ -z "$scripts_objtree" ]
+then
+	X=`$TOPDIR/scripts/gen-all-syms "$*"`
+	$TOPDIR/scripts/docproc $X
+else
+	X=`${scripts_objtree}gen-all-syms "$*"`
+	TOPDIR=. ${scripts_objtree}docproc $X
+fi
diff -u --recursive --new-file v2.4.5/linux/scripts/docproc.c linux/scripts/docproc.c
--- v2.4.5/linux/scripts/docproc.c	Wed Apr 12 09:47:30 2000
+++ linux/scripts/docproc.c	Wed Jun 20 20:56:24 2001
@@ -18,6 +18,7 @@
 	char type[64];
 	int i;
 	int vp=2;
+	int ret=0;
 	pid_t pid;
 
 
@@ -96,8 +97,8 @@
 			perror("exec scripts/kernel-doc");
 			exit(1);
 		default:
-			waitpid(pid, NULL,0);
+			waitpid(pid, &ret ,0);
 		}
 	}
-	exit(0);
+	exit(ret);
 }
diff -u --recursive --new-file v2.4.5/linux/scripts/kernel-doc linux/scripts/kernel-doc
--- v2.4.5/linux/scripts/kernel-doc	Wed Apr 25 16:31:16 2001
+++ linux/scripts/kernel-doc	Wed Jun 20 20:56:24 2001
@@ -22,6 +22,10 @@
 # 	- add perldoc documentation
 # 	- Look more closely at some of the scarier bits :)
 
+# 26/05/2001 - 	Support for separate source and object trees.
+#		Return error code.
+# 		Keith Owens <kaos@ocs.com.au>
+
 #
 # This will read a 'c' file and scan for embedded comments in the
 # style of gnome comments (+minor extensions - see below).
@@ -97,6 +101,8 @@
 # '@parameter' - name of a parameter
 # '%CONST' - name of a constant.
 
+my $errors = 0;
+
 # match expressions used to find embedded type information
 my $type_constant = '\%([-_\w]+)';
 my $type_func = '(\w+)\(\)';
@@ -198,6 +204,7 @@
 my @parameterlist = ();
 my %sections = ();
 my @sectionlist = ();
+my %source_map = ();
 
 my $contents = "";
 my $section_default = "Description";	# default section
@@ -776,6 +783,7 @@
             if (defined $type && $type && !defined $parameters{$param}) {
 	        $parameters{$param} = "-- undescribed --";
 	        print STDERR "Warning($file:$.): Function parameter '$param' not described in '$function_name'\n";
+		++$errors;
 	    }
 
 	    push @parameterlist, $param;
@@ -784,6 +792,7 @@
 	}
     } else {
 	print STDERR "Error($.): cannot understand prototype: '$prototype'\n";
+	++$errors;
 	return;
     }
 
@@ -837,6 +846,19 @@
 
 sub process_file($);
 
+# Read the file that maps relative names to absolute names for
+# separate source and object directories and for shadow trees.
+if (open(SOURCE_MAP, "<.tmp_filelist.txt")) {
+	my ($relname, $absname);
+	while(<SOURCE_MAP>) {
+		chop();
+		($relname, $absname) = (split())[0..1];
+		$relname =~ s:^/+::;
+		$source_map{$relname} = $absname;
+	}
+	close(SOURCE_MAP);
+}
+
 if ($filelist) {
 	open(FLIST,"<$filelist") or die "Can't open file list $filelist";
 	while(<FLIST>) {
@@ -850,11 +872,17 @@
     process_file($_);
 }
 
+exit($errors);
+
 sub process_file($) {
     my ($file) = @_;
+    if (defined($source_map{$file})) {
+	$file = $source_map{$file};
+    }
 
     if (!open(IN,"<$file")) {
 	print STDERR "Error: Cannot open file $file\n";
+	++$errors;
 	return;
     }
 
@@ -887,6 +915,7 @@
 	    } else {
 		print STDERR "WARN($.): Cannot understand $_ on line $.",
 		" - I thought it was a doc line\n";
+		++$errors;
 		$state = 0;
 	    }
 	} elsif ($state == 2) {	# look for head: lines, and include content
@@ -937,6 +966,7 @@
 	    } else {
 		# i dont know - bad line?  ignore.
 		print STDERR "WARNING($.): bad line: $_"; 
+		++$errors;
 	    }
 	} elsif ($state == 3) {	# scanning for function { (end of prototype)
 	    if (m#\s*/\*\s+MACDOC\s*#io) {
