Initial revision
authorMarc Fiuczynski <mef@cs.princeton.edu>
Tue, 13 Jul 2004 17:49:45 +0000 (17:49 +0000)
committerMarc Fiuczynski <mef@cs.princeton.edu>
Tue, 13 Jul 2004 17:49:45 +0000 (17:49 +0000)
41 files changed:
Documentation/arm/Sharp-LH/SDRAM [new file with mode: 0644]
Documentation/arm/VFP/release-notes.txt [new file with mode: 0644]
Documentation/device-mapper/dm-io.txt [new file with mode: 0644]
Documentation/device-mapper/kcopyd.txt [new file with mode: 0644]
Documentation/device-mapper/linear.txt [new file with mode: 0644]
Documentation/device-mapper/striped.txt [new file with mode: 0644]
Documentation/device-mapper/zero.txt [new file with mode: 0644]
Documentation/hpet.txt [new file with mode: 0644]
arch/arm/mach-integrator/clock.c [new file with mode: 0644]
arch/arm/mach-integrator/clock.h [new file with mode: 0644]
arch/arm/mach-versatile/clock.c [new file with mode: 0644]
arch/arm/mach-versatile/clock.h [new file with mode: 0644]
arch/i386/lib/bitops.c [new file with mode: 0644]
arch/ppc/kernel/head_e500.S [new file with mode: 0644]
arch/ppc/platforms/85xx/Kconfig [new file with mode: 0644]
arch/ppc/platforms/85xx/Makefile [new file with mode: 0644]
arch/ppc/platforms/85xx/mpc8540_ads.c [new file with mode: 0644]
arch/ppc/platforms/85xx/mpc8540_ads.h [new file with mode: 0644]
arch/ppc/syslib/ppc85xx_setup.c [new file with mode: 0644]
arch/ppc/syslib/ppc85xx_setup.h [new file with mode: 0644]
configs/kernel-2.6.7-i586-smp.config [new file with mode: 0644]
configs/kernel-2.6.7-i586.config [new file with mode: 0644]
configs/kernel-2.6.7-i686-smp.config [new file with mode: 0644]
configs/kernel-2.6.7-i686.config [new file with mode: 0644]
drivers/char/hpet.c [new file with mode: 0644]
drivers/md/dm-io.h [new file with mode: 0644]
drivers/md/dm-raid1.c [new file with mode: 0644]
drivers/md/kcopyd.c [new file with mode: 0644]
drivers/md/kcopyd.h [new file with mode: 0644]
drivers/net/arm/smc91x.c [new file with mode: 0644]
drivers/net/arm/smc91x.h [new file with mode: 0644]
drivers/net/via-velocity.c [new file with mode: 0644]
drivers/scsi/3w-9xxx.c [new file with mode: 0644]
drivers/usb/class/cdc-acm.h [new file with mode: 0644]
fs/isofs/export.c [new file with mode: 0644]
include/asm-arm/hardware/clock.h [new file with mode: 0644]
include/asm-arm/vfp.h [new file with mode: 0644]
include/asm-ppc/immap_85xx.h [new file with mode: 0644]
include/asm-ppc/mpc85xx.h [new file with mode: 0644]
include/linux/hpet.h [new file with mode: 0644]
net/core/stream.c [new file with mode: 0644]

diff --git a/Documentation/arm/Sharp-LH/SDRAM b/Documentation/arm/Sharp-LH/SDRAM
new file mode 100644 (file)
index 0000000..93ddc23
--- /dev/null
@@ -0,0 +1,51 @@
+README on the SDRAM Controller for the LH7a40X
+==============================================
+
+The standard configuration for the SDRAM controller generates a sparse
+memory array.  The precise layout is determined by the SDRAM chips.  A
+default kernel configuration assembles the discontiguous memory
+regions into separate memory nodes via the NUMA (Non-Uniform Memory
+Architecture) facilities.  In this default configuration, the kernel
+is forgiving about the precise layout.  As long as it is given an
+accurate picture of available memory by the bootloader the kernel will
+execute correctly.
+
+The SDRC supports a mode where some of the chip select lines are
+swapped in order to make SDRAM look like a synchronous ROM.  Setting
+this bit means that the RAM will present as a contiguous array.  Some
+programmers prefer this to the discontiguous layout.  Be aware that
+may be a penalty for this feature where some some configurations of
+memory are significantly reduced; i.e. 64MiB of RAM appears as only 32
+MiB.
+
+There are a couple of configuration options to override the default
+behavior.  When the SROMLL bit is set and memory appears as a
+contiguous array, there is no reason to support NUMA.
+CONFIG_LH7A40X_CONTIGMEM disables NUMA support.  When physical memory
+is discontiguous, the memory tables are organized such that there are
+two banks per nodes with a small gap between them.  This layout wastes
+some kernel memory for page tables representing non-existent memory.
+CONFIG_LH7A40X_ONE_BANK_PER_NODE optimizes the node tables such that
+there are no gaps.  These options control the low level organization
+of the memory management tables in ways that may prevent the kernel
+from booting or may cause the kernel to allocated excessively large
+page tables.  Be warned.  Only change these options if you know what
+you are doing.  The default behavior is a reasonable compromise that
+will suit all users.
+
+--
+
+A typical 32MiB system with the default configuration options will
+find physical memory managed as follows.
+
+   node 0: 0xc0000000 4MiB
+           0xc1000000 4MiB
+   node 1: 0xc4000000 4MiB
+           0xc5000000 4MiB
+   node 2: 0xc8000000 4MiB
+           0xc9000000 4MiB
+   node 3: 0xcc000000 4MiB
+           0xcd000000 4MiB
+
+Setting CONFIG_LH7A40X_ONE_BANK_PER_NODE will put each bank into a
+separate node.
diff --git a/Documentation/arm/VFP/release-notes.txt b/Documentation/arm/VFP/release-notes.txt
new file mode 100644 (file)
index 0000000..f28e022
--- /dev/null
@@ -0,0 +1,55 @@
+Release notes for Linux Kernel VFP support code
+-----------------------------------------------
+
+Date:  20 May 2004
+Author:        Russell King
+
+This is the first release of the Linux Kernel VFP support code.  It
+provides support for the exceptions bounced from VFP hardware found
+on ARM926EJ-S.
+
+This release has been validated against the SoftFloat-2b library by
+John R. Hauser using the TestFloat-2a test suite.  Details of this
+library and test suite can be found at:
+
+   http://www.cs.berkeley.edu/~jhauser/arithmetic/SoftFloat.html
+
+The operations which have been tested with this package are:
+
+ - fdiv
+ - fsub
+ - fadd
+ - fmul
+ - fcmp
+ - fcmpe
+ - fcvtd
+ - fcvts
+ - fsito
+ - ftosi
+ - fsqrt
+
+All the above pass softfloat tests with the following exceptions:
+
+- fadd/fsub shows some differences in the handling of +0 / -0 results
+  when input operands differ in signs.
+- the handling of underflow exceptions is slightly different.  If a
+  result underflows before rounding, but becomes a normalised number
+  after rounding, we do not signal an underflow exception.
+
+Other operations which have been tested by basic assembly-only tests
+are:
+
+ - fcpy
+ - fabs
+ - fneg
+ - ftoui
+ - ftosiz
+ - ftouiz
+
+The combination operations have not been tested:
+
+ - fmac
+ - fnmac
+ - fmsc
+ - fnmsc
+ - fnmul
diff --git a/Documentation/device-mapper/dm-io.txt b/Documentation/device-mapper/dm-io.txt
new file mode 100644 (file)
index 0000000..3b5d9a5
--- /dev/null
@@ -0,0 +1,75 @@
+dm-io
+=====
+
+Dm-io provides synchronous and asynchronous I/O services. There are three
+types of I/O services available, and each type has a sync and an async
+version.
+
+The user must set up an io_region structure to describe the desired location
+of the I/O. Each io_region indicates a block-device along with the starting
+sector and size of the region.
+
+   struct io_region {
+      struct block_device *bdev;
+      sector_t sector;
+      sector_t count;
+   };
+
+Dm-io can read from one io_region or write to one or more io_regions. Writes
+to multiple regions are specified by an array of io_region structures.
+
+The first I/O service type takes a list of memory pages as the data buffer for
+the I/O, along with an offset into the first page.
+
+   struct page_list {
+      struct page_list *next;
+      struct page *page;
+   };
+
+   int dm_io_sync(unsigned int num_regions, struct io_region *where, int rw,
+                  struct page_list *pl, unsigned int offset,
+                  unsigned long *error_bits);
+   int dm_io_async(unsigned int num_regions, struct io_region *where, int rw,
+                   struct page_list *pl, unsigned int offset,
+                   io_notify_fn fn, void *context);
+
+The second I/O service type takes an array of bio vectors as the data buffer
+for the I/O. This service can be handy if the caller has a pre-assembled bio,
+but wants to direct different portions of the bio to different devices.
+
+   int dm_io_sync_bvec(unsigned int num_regions, struct io_region *where,
+                       int rw, struct bio_vec *bvec,
+                       unsigned long *error_bits);
+   int dm_io_async_bvec(unsigned int num_regions, struct io_region *where,
+                        int rw, struct bio_vec *bvec,
+                        io_notify_fn fn, void *context);
+
+The third I/O service type takes a pointer to a vmalloc'd memory buffer as the
+data buffer for the I/O. This service can be handy if the caller needs to do
+I/O to a large region but doesn't want to allocate a large number of individual
+memory pages.
+
+   int dm_io_sync_vm(unsigned int num_regions, struct io_region *where, int rw,
+                     void *data, unsigned long *error_bits);
+   int dm_io_async_vm(unsigned int num_regions, struct io_region *where, int rw,
+                      void *data, io_notify_fn fn, void *context);
+
+Callers of the asynchronous I/O services must include the name of a completion
+callback routine and a pointer to some context data for the I/O.
+
+   typedef void (*io_notify_fn)(unsigned long error, void *context);
+
+The "error" parameter in this callback, as well as the "*error" parameter in
+all of the synchronous versions, is a bitset (instead of a simple error value).
+In the case of an write-I/O to multiple regions, this bitset allows dm-io to
+indicate success or failure on each individual region.
+
+Before using any of the dm-io services, the user should call dm_io_get()
+and specify the number of pages they expect to perform I/O on concurrently.
+Dm-io will attempt to resize its mempool to make sure enough pages are
+always available in order to avoid unnecessary waiting while performing I/O.
+
+When the user is finished using the dm-io services, they should call
+dm_io_put() and specify the same number of pages that were given on the
+dm_io_get() call.
+
diff --git a/Documentation/device-mapper/kcopyd.txt b/Documentation/device-mapper/kcopyd.txt
new file mode 100644 (file)
index 0000000..820382c
--- /dev/null
@@ -0,0 +1,47 @@
+kcopyd
+======
+
+Kcopyd provides the ability to copy a range of sectors from one block-device
+to one or more other block-devices, with an asynchronous completion
+notification. It is used by dm-snapshot and dm-mirror.
+
+Users of kcopyd must first create a client and indicate how many memory pages
+to set aside for their copy jobs. This is done with a call to
+kcopyd_client_create().
+
+   int kcopyd_client_create(unsigned int num_pages,
+                            struct kcopyd_client **result);
+
+To start a copy job, the user must set up io_region structures to describe
+the source and destinations of the copy. Each io_region indicates a
+block-device along with the starting sector and size of the region. The source
+of the copy is given as one io_region structure, and the destinations of the
+copy are given as an array of io_region structures.
+
+   struct io_region {
+      struct block_device *bdev;
+      sector_t sector;
+      sector_t count;
+   };
+
+To start the copy, the user calls kcopyd_copy(), passing in the client
+pointer, pointers to the source and destination io_regions, the name of a
+completion callback routine, and a pointer to some context data for the copy.
+
+   int kcopyd_copy(struct kcopyd_client *kc, struct io_region *from,
+                   unsigned int num_dests, struct io_region *dests,
+                   unsigned int flags, kcopyd_notify_fn fn, void *context);
+
+   typedef void (*kcopyd_notify_fn)(int read_err, unsigned int write_err,
+                                   void *context);
+
+When the copy completes, kcopyd will call the user's completion routine,
+passing back the user's context pointer. It will also indicate if a read or
+write error occurred during the copy.
+
+When a user is done with all their copy jobs, they should call
+kcopyd_client_destroy() to delete the kcopyd client, which will release the
+associated memory pages.
+
+   void kcopyd_client_destroy(struct kcopyd_client *kc);
+
diff --git a/Documentation/device-mapper/linear.txt b/Documentation/device-mapper/linear.txt
new file mode 100644 (file)
index 0000000..d5307d3
--- /dev/null
@@ -0,0 +1,61 @@
+dm-linear
+=========
+
+Device-Mapper's "linear" target maps a linear range of the Device-Mapper
+device onto a linear range of another device.  This is the basic building
+block of logical volume managers.
+
+Parameters: <dev path> <offset>
+    <dev path>: Full pathname to the underlying block-device, or a
+                "major:minor" device-number.
+    <offset>: Starting sector within the device.
+
+
+Example scripts
+===============
+[[
+#!/bin/sh
+# Create an identity mapping for a device
+echo "0 `blockdev --getsize $1` linear $1 0" | dmsetup create identity
+]]
+
+
+[[
+#!/bin/sh
+# Join 2 devices together
+size1=`blockdev --getsize $1`
+size2=`blockdev --getsize $2`
+echo "0 $size1 linear $1 0
+$size1 $size2 linear $2 0" | dmsetup create joined
+]]
+
+
+[[
+#!/usr/bin/perl -w
+# Split a device into 4M chunks and then join them together in reverse order.
+
+my $name = "reverse";
+my $extent_size = 4 * 1024 * 2;
+my $dev = $ARGV[0];
+my $table = "";
+my $count = 0;
+
+if (!defined($dev)) {
+        die("Please specify a device.\n");
+}
+
+my $dev_size = `blockdev --getsize $dev`;
+my $extents = int($dev_size / $extent_size) -
+              (($dev_size % $extent_size) ? 1 : 0);
+
+while ($extents > 0) {
+        my $this_start = $count * $extent_size;
+        $extents--;
+        $count++;
+        my $this_offset = $extents * $extent_size;
+
+        $table .= "$this_start $extent_size linear $dev $this_offset\n";
+}
+
+`echo \"$table\" | dmsetup create $name`;
+]]
diff --git a/Documentation/device-mapper/striped.txt b/Documentation/device-mapper/striped.txt
new file mode 100644 (file)
index 0000000..f34d323
--- /dev/null
@@ -0,0 +1,58 @@
+dm-stripe
+=========
+
+Device-Mapper's "striped" target is used to create a striped (i.e. RAID-0)
+device across one or more underlying devices. Data is written in "chunks",
+with consecutive chunks rotating among the underlying devices. This can
+potentially provide improved I/O throughput by utilizing several physical
+devices in parallel.
+
+Parameters: <num devs> <chunk size> [<dev path> <offset>]+
+    <num devs>: Number of underlying devices.
+    <chunk size>: Size of each chunk of data. Must be a power-of-2 and at
+                  least as large as the system's PAGE_SIZE.
+    <dev path>: Full pathname to the underlying block-device, or a
+                "major:minor" device-number.
+    <offset>: Starting sector within the device.
+
+One or more underlying devices can be specified. The striped device size must
+be a multiple of the chunk size and a multiple of the number of underlying
+devices.
+
+
+Example scripts
+===============
+
+[[
+#!/usr/bin/perl -w
+# Create a striped device across any number of underlying devices. The device
+# will be called "stripe_dev" and have a chunk-size of 128k.
+
+my $chunk_size = 128 * 2;
+my $dev_name = "stripe_dev";
+my $num_devs = @ARGV;
+my @devs = @ARGV;
+my ($min_dev_size, $stripe_dev_size, $i);
+
+if (!$num_devs) {
+        die("Specify at least one device\n");
+}
+
+$min_dev_size = `blockdev --getsize $devs[0]`;
+for ($i = 1; $i < $num_devs; $i++) {
+        my $this_size = `blockdev --getsize $devs[$i]`;
+        $min_dev_size = ($min_dev_size < $this_size) ?
+                        $min_dev_size : $this_size;
+}
+
+$stripe_dev_size = $min_dev_size * $num_devs;
+$stripe_dev_size -= $stripe_dev_size % ($chunk_size * $num_devs);
+
+$table = "0 $stripe_dev_size striped $num_devs $chunk_size";
+for ($i = 0; $i < $num_devs; $i++) {
+        $table .= " $devs[$i] 0";
+}
+
+`echo $table | dmsetup create $dev_name`;
+]]
+
diff --git a/Documentation/device-mapper/zero.txt b/Documentation/device-mapper/zero.txt
new file mode 100644 (file)
index 0000000..20fb38e
--- /dev/null
@@ -0,0 +1,37 @@
+dm-zero
+=======
+
+Device-Mapper's "zero" target provides a block-device that always returns
+zero'd data on reads and silently drops writes. This is similar behavior to
+/dev/zero, but as a block-device instead of a character-device.
+
+Dm-zero has no target-specific parameters.
+
+One very interesting use of dm-zero is for creating "sparse" devices in
+conjunction with dm-snapshot. A sparse device reports a device-size larger
+than the amount of actual storage space available for that device. A user can
+write data anywhere within the sparse device and read it back like a normal
+device. Reads to previously unwritten areas will return a zero'd buffer. When
+enough data has been written to fill up the actual storage space, the sparse
+device is deactivated. This can be very useful for testing device and
+filesystem limitations.
+
+To create a sparse device, start by creating a dm-zero device that's the
+desired size of the sparse device. For this example, we'll assume a 10TB
+sparse device.
+
+TEN_TERABYTES=`expr 10 \* 1024 \* 1024 \* 1024 \* 2`   # 10 TB in sectors
+echo "0 $TEN_TERABYTES zero" | dmsetup create zero1
+
+Then create a snapshot of the zero device, using any available block-device as
+the COW device. The size of the COW device will determine the amount of real
+space available to the sparse device. For this example, we'll assume /dev/sdb1
+is an available 10GB partition.
+
+echo "0 $TEN_TERABYTES snapshot /dev/mapper/zero1 /dev/sdb1 p 128" | \
+   dmsetup create sparse1
+
+This will create a 10TB sparse device called /dev/mapper/sparse1 that has
+10GB of actual storage space available. If more than 10GB of data is written
+to this device, it will start returning I/O errors.
+
diff --git a/Documentation/hpet.txt b/Documentation/hpet.txt
new file mode 100644 (file)
index 0000000..584ebc2
--- /dev/null
@@ -0,0 +1,298 @@
+               High Precision Event Timer Driver for Linux
+
+The High Precision Event Timer (HPET) hardware is the future replacement for the 8254 and Real
+Time Clock (RTC) periodic timer functionality.  Each HPET can have up two 32 timers.  It is possible
+to configure the first two timers as legacy replacements for 8254 and RTC periodic.  A specification
+done by INTEL and Microsoft can be found at http://www.intel.com/labs/platcomp/hpet/hpetspec.htm.
+
+The driver supports detection of HPET driver allocation and initialization of the HPET before the
+driver module_init routine is called.  This enables platform code which uses timer 0 or 1 as the
+main timer to intercept HPET initialization.  An example of this initialization can be found in
+arch/i386/kernel/time_hpet.c.
+
+The driver provides two APIs which are very similar to the API found in the rtc.c driver.
+There is a user space API and a kernel space API.  An example user space program is provided
+below.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <memory.h>
+#include <malloc.h>
+#include <time.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <linux/hpet.h>
+
+
+extern void hpet_open_close(int, const char **);
+extern void hpet_info(int, const char **);
+extern void hpet_poll(int, const char **);
+extern void hpet_fasync(int, const char **);
+extern void hpet_read(int, const char **);
+
+#include <sys/poll.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+
+struct hpet_command {
+       char            *command;
+       void            (*func)(int argc, const char ** argv);
+} hpet_command[] = {
+       {
+               "open-close",
+               hpet_open_close
+       },
+       {
+               "info",
+               hpet_info
+       },
+       {
+               "poll",
+               hpet_poll
+       },
+       {
+               "fasync",
+               hpet_fasync
+       },
+};
+
+int
+main(int argc, const char ** argv)
+{
+       int     i;
+
+       argc--;
+       argv++;
+
+       if (!argc) {
+               fprintf(stderr, "-hpet: requires command\n");
+               return -1;
+       }
+
+
+       for (i = 0; i < (sizeof (hpet_command) / sizeof (hpet_command[0])); i++)
+               if (!strcmp(argv[0], hpet_command[i].command)) {
+                       argc--;
+                       argv++;
+                       fprintf(stderr, "-hpet: executing %s\n",
+                               hpet_command[i].command);
+                       hpet_command[i].func(argc, argv);
+                       return 0;
+               }
+
+       fprintf(stderr, "do_hpet: command %s not implemented\n", argv[0]);
+
+       return -1;
+}
+
+void
+hpet_open_close(int argc, const char **argv)
+{
+       int     fd;
+
+       if (argc != 1) {
+               fprintf(stderr, "hpet_open_close: device-name\n");
+               return;
+       }
+
+       fd = open(argv[0], O_RDWR);
+       if (fd < 0)
+               fprintf(stderr, "hpet_open_close: open failed\n");
+       else
+               close(fd);
+
+       return;
+}
+
+void
+hpet_info(int argc, const char **argv)
+{
+}
+
+void
+hpet_poll(int argc, const char **argv)
+{
+       unsigned long           freq;
+       int                     iterations, i, fd;
+       struct pollfd           pfd;
+       struct hpet_info        info;
+       struct timeval          stv, etv;
+       struct timezone         tz;
+       long                    usec;
+
+       if (argc != 3) {
+               fprintf(stderr, "hpet_poll: device-name freq iterations\n");
+               return;
+       }
+
+       freq = atoi(argv[1]);
+       iterations = atoi(argv[2]);
+
+       fd = open(argv[0], O_RDWR);
+
+       if (fd < 0) {
+               fprintf(stderr, "hpet_poll: open of %s failed\n", argv[0]);
+               return;
+       }
+
+       if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
+               fprintf(stderr, "hpet_poll: HPET_IRQFREQ failed\n");
+               goto out;
+       }
+
+       if (ioctl(fd, HPET_INFO, &info) < 0) {
+               fprintf(stderr, "hpet_poll: failed to get info\n");
+               goto out;
+       }
+
+       fprintf(stderr, "hpet_poll: info.hi_flags 0x%lx\n", info.hi_flags);
+
+       if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
+               fprintf(stderr, "hpet_poll: HPET_EPI failed\n");
+               goto out;
+       }
+
+       if (ioctl(fd, HPET_IE_ON, 0) < 0) {
+               fprintf(stderr, "hpet_poll, HPET_IE_ON failed\n");
+               goto out;
+       }
+
+       pfd.fd = fd;
+       pfd.events = POLLIN;
+
+       for (i = 0; i < iterations; i++) {
+               pfd.revents = 0;
+               gettimeofday(&stv, &tz);
+               if (poll(&pfd, 1, -1) < 0)
+                       fprintf(stderr, "hpet_poll: poll failed\n");
+               else {
+                       long    data;
+
+                       gettimeofday(&etv, &tz);
+                       usec = stv.tv_sec * 1000000 + stv.tv_usec;
+                       usec = (etv.tv_sec * 1000000 + etv.tv_usec) - usec;
+
+                       fprintf(stderr,
+                               "hpet_poll: expired time = 0x%lx\n", usec);
+
+                       fprintf(stderr, "hpet_poll: revents = 0x%x\n",
+                               pfd.revents);
+
+                       if (read(fd, &data, sizeof(data)) != sizeof(data)) {
+                               fprintf(stderr, "hpet_poll: read failed\n");
+                       }
+                       else
+                               fprintf(stderr, "hpet_poll: data 0x%lx\n",
+                                       data);
+               }
+       }
+
+out:
+       close(fd);
+       return;
+}
+
+static int hpet_sigio_count;
+
+static void
+hpet_sigio(int val)
+{
+       fprintf(stderr, "hpet_sigio: called\n");
+       hpet_sigio_count++;
+}
+
+void
+hpet_fasync(int argc, const char **argv)
+{
+       unsigned long           freq;
+       int                     iterations, i, fd, value;
+       sig_t                   oldsig;
+       struct hpet_info        info;
+
+       hpet_sigio_count = 0;
+       fd = -1;
+
+       if ((oldsig = signal(SIGIO, hpet_sigio)) == SIG_ERR) {
+               fprintf(stderr, "hpet_fasync: failed to set signal handler\n");
+               return;
+       }
+
+       if (argc != 3) {
+               fprintf(stderr, "hpet_fasync: device-name freq iterations\n");
+               goto out;
+       }
+
+       fd = open(argv[0], O_RDWR);
+
+       if (fd < 0) {
+               fprintf(stderr, "hpet_fasync: failed to open %s\n", argv[0]);
+               return;
+       }
+
+
+       if ((fcntl(fd, F_SETOWN, getpid()) == 1) ||
+               ((value = fcntl(fd, F_GETFL)) == 1) ||
+               (fcntl(fd, F_SETFL, value | O_ASYNC) == 1)) {
+               fprintf(stderr, "hpet_fasync: fcntl failed\n");
+               goto out;
+       }
+
+       freq = atoi(argv[1]);
+       iterations = atoi(argv[2]);
+
+       if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
+               fprintf(stderr, "hpet_fasync: HPET_IRQFREQ failed\n");
+               goto out;
+       }
+
+       if (ioctl(fd, HPET_INFO, &info) < 0) {
+               fprintf(stderr, "hpet_fasync: failed to get info\n");
+               goto out;
+       }
+
+       fprintf(stderr, "hpet_fasync: info.hi_flags 0x%lx\n", info.hi_flags);
+
+       if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
+               fprintf(stderr, "hpet_fasync: HPET_EPI failed\n");
+               goto out;
+       }
+
+       if (ioctl(fd, HPET_IE_ON, 0) < 0) {
+               fprintf(stderr, "hpet_fasync, HPET_IE_ON failed\n");
+               goto out;
+       }
+
+       for (i = 0; i < iterations; i++) {
+               (void) pause();
+               fprintf(stderr, "hpet_fasync: count = %d\n", hpet_sigio_count);
+       }
+
+out:
+       signal(SIGIO, oldsig);
+
+       if (fd >= 0)
+               close(fd);
+
+       return;
+}
+
+The kernel API has three interfaces exported from the driver:
+
+       hpet_register(struct hpet_task *tp, int periodic)
+       hpet_unregister(struct hpet_task *tp)
+       hpet_control(struct hpet_task *tp, unsigned int cmd, unsigned long arg)
+
+The kernel module using this interface fills in the ht_func and ht_data members of the
+hpet_task structure before calling hpet_register.  hpet_control simply vectors to the hpet_ioctl
+routine and has the same commands and respective arguments as the user API.  hpet_unregister
+is used to terminate usage of the HPET timer reserved by hpet_register.
+
+
diff --git a/arch/arm/mach-integrator/clock.c b/arch/arm/mach-integrator/clock.c
new file mode 100644 (file)
index 0000000..6af3715
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ *  linux/arch/arm/mach-integrator/clock.c
+ *
+ *  Copyright (C) 2004 ARM Limited.
+ *  Written by Deep Blue Solutions Limited.
+ *
+ * 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/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+
+#include <asm/semaphore.h>
+#include <asm/hardware/clock.h>
+#include <asm/hardware/icst525.h>
+
+#include "clock.h"
+
+static LIST_HEAD(clocks);
+static DECLARE_MUTEX(clocks_sem);
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+       struct clk *p, *clk = ERR_PTR(-ENOENT);
+
+       down(&clocks_sem);
+       list_for_each_entry(p, &clocks, node) {
+               if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
+                       clk = p;
+                       break;
+               }
+       }
+       up(&clocks_sem);
+
+       return clk;
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+       module_put(clk->owner);
+}
+EXPORT_SYMBOL(clk_put);
+
+int clk_enable(struct clk *clk)
+{
+       return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+int clk_use(struct clk *clk)
+{
+       return 0;
+}
+EXPORT_SYMBOL(clk_use);
+
+void clk_unuse(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_unuse);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+       return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+       return rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+       int ret = -EIO;
+       if (clk->setvco) {
+               struct icst525_vco vco;
+
+               vco = icst525_khz_to_vco(clk->params, rate);
+               clk->rate = icst525_khz(clk->params, vco);
+
+               printk("Clock %s: setting VCO reg params: S=%d R=%d V=%d\n",
+                       clk->name, vco.s, vco.r, vco.v);
+
+               clk->setvco(clk, vco);
+               ret = 0;
+       }
+       return 0;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+/*
+ * These are fixed clocks.
+ */
+static struct clk kmi_clk = {
+       .name   = "KMIREFCLK",
+       .rate   = 24000000,
+};
+
+static struct clk uart_clk = {
+       .name   = "UARTCLK",
+       .rate   = 14745600,
+};
+
+int clk_register(struct clk *clk)
+{
+       down(&clocks_sem);
+       list_add(&clk->node, &clocks);
+       up(&clocks_sem);
+       return 0;
+}
+EXPORT_SYMBOL(clk_register);
+
+void clk_unregister(struct clk *clk)
+{
+       down(&clocks_sem);
+       list_del(&clk->node);
+       up(&clocks_sem);
+}
+EXPORT_SYMBOL(clk_unregister);
+
+static int __init clk_init(void)
+{
+       clk_register(&kmi_clk);
+       clk_register(&uart_clk);
+       return 0;
+}
+arch_initcall(clk_init);
diff --git a/arch/arm/mach-integrator/clock.h b/arch/arm/mach-integrator/clock.h
new file mode 100644 (file)
index 0000000..09e6328
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ *  linux/arch/arm/mach-integrator/clock.h
+ *
+ *  Copyright (C) 2004 ARM Limited.
+ *  Written by Deep Blue Solutions Limited.
+ *
+ * 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.
+ */
+struct module;
+struct icst525_params;
+
+struct clk {
+       struct list_head        node;
+       unsigned long           rate;
+       struct module           *owner;
+       const char              *name;
+       const struct icst525_params *params;
+       void                    *data;
+       void                    (*setvco)(struct clk *, struct icst525_vco vco);
+};
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
diff --git a/arch/arm/mach-versatile/clock.c b/arch/arm/mach-versatile/clock.c
new file mode 100644 (file)
index 0000000..c1f91fa
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ *  linux/arch/arm/mach-versatile/clock.c
+ *
+ *  Copyright (C) 2004 ARM Limited.
+ *  Written by Deep Blue Solutions Limited.
+ *
+ * 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/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+
+#include <asm/semaphore.h>
+#include <asm/hardware/clock.h>
+#include <asm/hardware/icst525.h>
+
+#include "clock.h"
+
+static LIST_HEAD(clocks);
+static DECLARE_MUTEX(clocks_sem);
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+       struct clk *p, *clk = ERR_PTR(-ENOENT);
+
+       down(&clocks_sem);
+       list_for_each_entry(p, &clocks, node) {
+               if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
+                       clk = p;
+                       break;
+               }
+       }
+       up(&clocks_sem);
+
+       return clk;
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+       module_put(clk->owner);
+}
+EXPORT_SYMBOL(clk_put);
+
+int clk_enable(struct clk *clk)
+{
+       return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+int clk_use(struct clk *clk)
+{
+       return 0;
+}
+EXPORT_SYMBOL(clk_use);
+
+void clk_unuse(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_unuse);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+       return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+       return rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+       int ret = -EIO;
+#if 0 // Not yet
+       if (clk->setvco) {
+               struct icst525_vco vco;
+
+               vco = icst525_khz_to_vco(clk->params, rate);
+               clk->rate = icst525_khz(clk->params, vco);
+
+               printk("Clock %s: setting VCO reg params: S=%d R=%d V=%d\n",
+                       clk->name, vco.s, vco.r, vco.v);
+
+               clk->setvco(clk, vco);
+               ret = 0;
+       }
+#endif
+       return 0;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+/*
+ * These are fixed clocks.
+ */
+static struct clk kmi_clk = {
+       .name   = "KMIREFCLK",
+       .rate   = 24000000,
+};
+
+static struct clk uart_clk = {
+       .name   = "UARTCLK",
+       .rate   = 24000000,
+};
+
+static struct clk mmci_clk = {
+       .name   = "MCLK",
+       .rate   = 33000000,
+};
+
+int clk_register(struct clk *clk)
+{
+       down(&clocks_sem);
+       list_add(&clk->node, &clocks);
+       up(&clocks_sem);
+       return 0;
+}
+EXPORT_SYMBOL(clk_register);
+
+void clk_unregister(struct clk *clk)
+{
+       down(&clocks_sem);
+       list_del(&clk->node);
+       up(&clocks_sem);
+}
+EXPORT_SYMBOL(clk_unregister);
+
+static int __init clk_init(void)
+{
+       clk_register(&kmi_clk);
+       clk_register(&uart_clk);
+       clk_register(&mmci_clk);
+       return 0;
+}
+arch_initcall(clk_init);
diff --git a/arch/arm/mach-versatile/clock.h b/arch/arm/mach-versatile/clock.h
new file mode 100644 (file)
index 0000000..12e68ec
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ *  linux/arch/arm/mach-versatile/clock.h
+ *
+ *  Copyright (C) 2004 ARM Limited.
+ *  Written by Deep Blue Solutions Limited.
+ *
+ * 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.
+ */
+struct module;
+struct icst525_params;
+
+struct clk {
+       struct list_head        node;
+       unsigned long           rate;
+       struct module           *owner;
+       const char              *name;
+       const struct icst525_params *params;
+       void                    *data;
+       void                    (*setvco)(struct clk *, struct icst525_vco vco);
+};
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
diff --git a/arch/i386/lib/bitops.c b/arch/i386/lib/bitops.c
new file mode 100644 (file)
index 0000000..97db385
--- /dev/null
@@ -0,0 +1,70 @@
+#include <linux/bitops.h>
+#include <linux/module.h>
+
+/**
+ * find_next_bit - find the first set bit in a memory region
+ * @addr: The address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The maximum size to search
+ */
+int find_next_bit(const unsigned long *addr, int size, int offset)
+{
+       const unsigned long *p = addr + (offset >> 5);
+       int set = 0, bit = offset & 31, res;
+
+       if (bit) {
+               /*
+                * Look for nonzero in the first 32 bits:
+                */
+               __asm__("bsfl %1,%0\n\t"
+                       "jne 1f\n\t"
+                       "movl $32, %0\n"
+                       "1:"
+                       : "=r" (set)
+                       : "r" (*p >> bit));
+               if (set < (32 - bit))
+                       return set + offset;
+               set = 32 - bit;
+               p++;
+       }
+       /*
+        * No set bit yet, search remaining full words for a bit
+        */
+       res = find_first_bit (p, size - 32 * (p - addr));
+       return (offset + set + res);
+}
+EXPORT_SYMBOL(find_next_bit);
+
+/**
+ * find_next_zero_bit - find the first zero bit in a memory region
+ * @addr: The address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The maximum size to search
+ */
+int find_next_zero_bit(const unsigned long *addr, int size, int offset)
+{
+       unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
+       int set = 0, bit = offset & 31, res;
+
+       if (bit) {
+               /*
+                * Look for zero in the first 32 bits.
+                */
+               __asm__("bsfl %1,%0\n\t"
+                       "jne 1f\n\t"
+                       "movl $32, %0\n"
+                       "1:"
+                       : "=r" (set)
+                       : "r" (~(*p >> bit)));
+               if (set < (32 - bit))
+                       return set + offset;
+               set = 32 - bit;
+               p++;
+       }
+       /*
+        * No zero yet, search remaining full bytes for a zero
+        */
+       res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
+       return (offset + set + res);
+}
+EXPORT_SYMBOL(find_next_zero_bit);
diff --git a/arch/ppc/kernel/head_e500.S b/arch/ppc/kernel/head_e500.S
new file mode 100644 (file)
index 0000000..8f0c590
--- /dev/null
@@ -0,0 +1,1329 @@
+/*
+ * arch/ppc/kernel/head_e500.S
+ *
+ * Kernel execution entry point code.
+ *
+ *    Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
+ *      Initial PowerPC version.
+ *    Copyright (c) 1996 Cort Dougan <cort@cs.nmt.edu>
+ *      Rewritten for PReP
+ *    Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
+ *      Low-level exception handers, MMU support, and rewrite.
+ *    Copyright (c) 1997 Dan Malek <dmalek@jlc.net>
+ *      PowerPC 8xx modifications.
+ *    Copyright (c) 1998-1999 TiVo, Inc.
+ *      PowerPC 403GCX modifications.
+ *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *      PowerPC 403GCX/405GP modifications.
+ *    Copyright 2000 MontaVista Software Inc.
+ *     PPC405 modifications
+ *      PowerPC 403GCX/405GP modifications.
+ *     Author: MontaVista Software, Inc.
+ *             frank_rowand@mvista.com or source@mvista.com
+ *             debbie_chu@mvista.com
+ *    Copyright 2002-2004 MontaVista Software, Inc.
+ *      PowerPC 44x support, Matt Porter <mporter@kernel.crashing.org>
+ *    Copyright 2004 Freescale Semiconductor, Inc
+ *      PowerPC e500 modifications, Kumar Gala <kumar.gala@freescale.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/config.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/offsets.h>
+
+/*
+ * Macros
+ */
+
+#define SET_IVOR(vector_number, vector_label)          \
+               li      r26,vector_label@l;             \
+               mtspr   SPRN_IVOR##vector_number,r26;   \
+               sync
+
+/* As with the other PowerPC ports, it is expected that when code
+ * execution begins here, the following registers contain valid, yet
+ * optional, information:
+ *
+ *   r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
+ *   r4 - Starting address of the init RAM disk
+ *   r5 - Ending address of the init RAM disk
+ *   r6 - Start of kernel command line string (e.g. "mem=128")
+ *   r7 - End of kernel command line string
+ *
+ */
+       .text
+_GLOBAL(_stext)
+_GLOBAL(_start)
+       /*
+        * Reserve a word at a fixed location to store the address
+        * of abatron_pteptrs
+        */
+       nop
+/*
+ * Save parameters we are passed
+ */
+       mr      r31,r3
+       mr      r30,r4
+       mr      r29,r5
+       mr      r28,r6
+       mr      r27,r7
+       li      r24,0           /* CPU number */
+
+/* We try to not make any assumptions about how the boot loader
+ * setup or used the TLBs.  We invalidate all mappings from the
+ * boot loader and load a single entry in TLB1[0] to map the
+ * first 16M of kernel memory.  Any boot info passed from the
+ * bootloader needs to live in this first 16M.
+ *
+ * Requirement on bootloader:
+ *  - The page we're executing in needs to reside in TLB1 and
+ *    have IPROT=1.  If not an invalidate broadcast could
+ *    evict the entry we're currently executing in.
+ *
+ *  r3 = Index of TLB1 were executing in
+ *  r4 = Current MSR[IS]
+ *  r5 = Index of TLB1 temp mapping
+ *
+ * Later in mapin_ram we will correctly map lowmem, and resize TLB1[0]
+ * if needed
+ */
+
+/* 1. Find the index of the entry we're executing in */
+       bl      invstr                          /* Find our address */
+invstr:        mflr    r6                              /* Make it accessible */
+       mfmsr   r7
+       rlwinm  r4,r7,27,31,31                  /* extract MSR[IS] */
+       mfspr   r7, SPRN_PID0
+       slwi    r7,r7,16
+       or      r7,r7,r4
+       mtspr   SPRN_MAS6,r7
+       tlbsx   0,r6                            /* search MSR[IS], SPID=PID0 */
+       mfspr   r7,SPRN_MAS1
+       andis.  r7,r7,MAS1_VALID@h
+       bne     match_TLB
+       mfspr   r7,SPRN_PID1
+       slwi    r7,r7,16
+       or      r7,r7,r4
+       mtspr   SPRN_MAS6,r7
+       tlbsx   0,r6                            /* search MSR[IS], SPID=PID1 */
+       mfspr   r7,SPRN_MAS1
+       andis.  r7,r7,MAS1_VALID@h
+       bne     match_TLB
+       mfspr   r7, SPRN_PID2
+       slwi    r7,r7,16
+       or      r7,r7,r4
+       mtspr   SPRN_MAS6,r7
+       tlbsx   0,r6                            /* Fall through, we had to match */
+match_TLB:
+       mfspr   r7,SPRN_MAS0
+       rlwinm  r3,r7,16,28,31                  /* Extract MAS0(Entry) */
+
+       mfspr   r7,SPRN_MAS1                    /* Insure IPROT set */
+       oris    r7,r7,MAS1_IPROT@h
+       mtspr   SPRN_MAS1,r7
+       tlbwe
+
+/* 2. Invalidate all entries except the entry we're executing in */
+       mfspr   r9,SPRN_TLB1CFG
+       andi.   r9,r9,0xfff
+       li      r6,0                            /* Set Entry counter to 0 */
+1:     lis     r7,0x1000                       /* Set MAS0(TLBSEL) = 1 */
+       rlwimi  r7,r6,16,12,15                  /* Setup MAS0 = TLBSEL | ESEL(r6) */
+       mtspr   SPRN_MAS0,r7
+       tlbre
+       mfspr   r7,SPRN_MAS1
+       rlwinm  r7,r7,0,2,31                    /* Clear MAS1 Valid and IPROT */
+       cmpw    r3,r6
+       beq     skpinv                          /* Dont update the current execution TLB */
+       mtspr   SPRN_MAS1,r7
+       tlbwe
+       isync
+skpinv:        addi    r6,r6,1                         /* Increment */
+       cmpw    r6,r9                           /* Are we done? */
+       bne     1b                              /* If not, repeat */
+
+       /* Invalidate TLB0 */
+       li      r6,0x04
+       tlbivax 0,r6
+#ifdef CONFIG_SMP
+       tlbsync
+#endif
+       /* Invalidate TLB1 */
+       li      r6,0x0c
+       tlbivax 0,r6
+#ifdef CONFIG_SMP
+       tlbsync
+#endif
+       msync
+
+/* 3. Setup a temp mapping and jump to it */
+       andi.   r5, r3, 0x1     /* Find an entry not used and is non-zero */
+       addi    r5, r5, 0x1
+       lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
+       rlwimi  r7,r3,16,12,15  /* Setup MAS0 = TLBSEL | ESEL(r3) */
+       mtspr   SPRN_MAS0,r7
+       tlbre
+
+       /* Just modify the entry ID and EPN for the temp mapping */
+       lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
+       rlwimi  r7,r5,16,12,15  /* Setup MAS0 = TLBSEL | ESEL(r5) */
+       mtspr   SPRN_MAS0,r7
+       xori    r6,r4,1         /* Setup TMP mapping in the other Address space */
+       slwi    r6,r6,12
+       oris    r6,r6,(MAS1_VALID|MAS1_IPROT)@h
+       ori     r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_4K))@l
+       mtspr   SPRN_MAS1,r6
+       mfspr   r6,SPRN_MAS2
+       li      r7,0            /* temp EPN = 0 */
+       rlwimi  r7,r6,0,20,31
+       mtspr   SPRN_MAS2,r7
+       tlbwe
+
+       xori    r6,r4,1
+       slwi    r6,r6,5         /* setup new context with other address space */
+       bl      1f              /* Find our address */
+1:     mflr    r9
+       rlwimi  r7,r9,0,20,31
+       addi    r7,r7,24
+       mtspr   SRR0,r7
+       mtspr   SRR1,r6
+       rfi
+
+/* 4. Clear out PIDs & Search info */
+       li      r6,0
+       mtspr   SPRN_PID0,r6
+       mtspr   SPRN_PID1,r6
+       mtspr   SPRN_PID2,r6
+       mtspr   SPRN_MAS6,r6
+
+/* 5. Invalidate mapping we started in */
+       lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
+       rlwimi  r7,r3,16,12,15  /* Setup MAS0 = TLBSEL | ESEL(r3) */
+       mtspr   SPRN_MAS0,r7
+       tlbre
+       li      r6,0
+       mtspr   SPRN_MAS1,r6
+       tlbwe
+       /* Invalidate TLB1 */
+       li      r9,0x0c
+       tlbivax 0,r9
+#ifdef CONFIG_SMP
+       tlbsync
+#endif
+       msync
+
+/* 6. Setup KERNELBASE mapping in TLB1[0] */
+       lis     r6,0x1000               /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
+       mtspr   SPRN_MAS0,r6
+       lis     r6,(MAS1_VALID|MAS1_IPROT)@h
+       ori     r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_16M))@l
+       mtspr   SPRN_MAS1,r6
+       li      r7,0
+       lis     r6,KERNELBASE@h
+       ori     r6,r6,KERNELBASE@l
+       rlwimi  r6,r7,0,20,31
+       mtspr   SPRN_MAS2,r6
+       li      r7,(MAS3_SX|MAS3_SW|MAS3_SR)
+       mtspr   SPRN_MAS3,r7
+       tlbwe
+
+/* 7. Jump to KERNELBASE mapping */
+       li      r7,0
+       bl      1f                      /* Find our address */
+1:     mflr    r9
+       rlwimi  r6,r9,0,20,31
+       addi    r6,r6,24
+       mtspr   SRR0,r6
+       mtspr   SRR1,r7
+       rfi                             /* start execution out of TLB1[0] entry */
+
+/* 8. Clear out the temp mapping */
+       lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
+       rlwimi  r7,r5,16,12,15  /* Setup MAS0 = TLBSEL | ESEL(r5) */
+       mtspr   SPRN_MAS0,r7
+       tlbre
+       mtspr   SPRN_MAS1,r8
+       tlbwe
+       /* Invalidate TLB1 */
+       li      r9,0x0c
+       tlbivax 0,r9
+#ifdef CONFIG_SMP
+       tlbsync
+#endif
+       msync
+
+       /* Establish the interrupt vector offsets */
+       SET_IVOR(0,  CriticalInput);
+       SET_IVOR(1,  MachineCheck);
+       SET_IVOR(2,  DataStorage);
+       SET_IVOR(3,  InstructionStorage);
+       SET_IVOR(4,  ExternalInput);
+       SET_IVOR(5,  Alignment);
+       SET_IVOR(6,  Program);
+       SET_IVOR(7,  FloatingPointUnavailable);
+       SET_IVOR(8,  SystemCall);
+       SET_IVOR(9,  AuxillaryProcessorUnavailable);
+       SET_IVOR(10, Decrementer);
+       SET_IVOR(11, FixedIntervalTimer);
+       SET_IVOR(12, WatchdogTimer);
+       SET_IVOR(13, DataTLBError);
+       SET_IVOR(14, InstructionTLBError);
+       SET_IVOR(15, Debug);
+       SET_IVOR(32, SPEUnavailable);
+       SET_IVOR(33, SPEFloatingPointData);
+       SET_IVOR(34, SPEFloatingPointRound);
+       SET_IVOR(35, PerformanceMonitor);
+
+       /* Establish the interrupt vector base */
+       lis     r4,interrupt_base@h     /* IVPR only uses the high 16-bits */
+       mtspr   SPRN_IVPR,r4
+
+       /* Setup the defaults for TLB entries */
+       li      r2,MAS4_TSIZED(BOOKE_PAGESZ_4K)
+       mtspr   SPRN_MAS4, r2
+
+#if 0
+       /* Enable DOZE */
+       mfspr   r2,SPRN_HID0
+       oris    r2,r2,HID0_DOZE@h
+       mtspr   SPRN_HID0, r2
+#endif
+
+       /*
+        * This is where the main kernel code starts.
+        */
+
+       /* ptr to current */
+       lis     r2,init_task@h
+       ori     r2,r2,init_task@l
+
+       /* ptr to current thread */
+       addi    r4,r2,THREAD    /* init task's THREAD */
+       mtspr   SPRG3,r4
+
+       /* stack */
+       lis     r1,init_thread_union@h
+       ori     r1,r1,init_thread_union@l
+       li      r0,0
+       stwu    r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
+
+       bl      early_init
+
+       mfspr   r3,SPRN_TLB1CFG
+       andi.   r3,r3,0xfff
+       lis     r4,num_tlbcam_entries@ha
+       stw     r3,num_tlbcam_entries@l(r4)
+/*
+ * Decide what sort of machine this is and initialize the MMU.
+ */
+       mr      r3,r31
+       mr      r4,r30
+       mr      r5,r29
+       mr      r6,r28
+       mr      r7,r27
+       bl      machine_init
+       bl      MMU_init
+
+       /* Setup PTE pointers for the Abatron bdiGDB */
+       lis     r6, swapper_pg_dir@h
+       ori     r6, r6, swapper_pg_dir@l
+       lis     r5, abatron_pteptrs@h
+       ori     r5, r5, abatron_pteptrs@l
+       lis     r4, KERNELBASE@h
+       ori     r4, r4, KERNELBASE@l
+       stw     r5, 0(r4)       /* Save abatron_pteptrs at a fixed location */
+       stw     r6, 0(r5)
+
+       /* Let's move on */
+       lis     r4,start_kernel@h
+       ori     r4,r4,start_kernel@l
+       lis     r3,MSR_KERNEL@h
+       ori     r3,r3,MSR_KERNEL@l
+       mtspr   SRR0,r4
+       mtspr   SRR1,r3
+       rfi                     /* change context and jump to start_kernel */
+
+/*
+ * Interrupt vector entry code
+ *
+ * The Book E MMUs are always on so we don't need to handle
+ * interrupts in real mode as with previous PPC processors. In
+ * this case we handle interrupts in the kernel virtual address
+ * space.
+ *
+ * Interrupt vectors are dynamically placed relative to the
+ * interrupt prefix as determined by the address of interrupt_base.
+ * The interrupt vectors offsets are programmed using the labels
+ * for each interrupt vector entry.
+ *
+ * Interrupt vectors must be aligned on a 16 byte boundary.
+ * We align on a 32 byte cache line boundary for good measure.
+ */
+
+#define NORMAL_EXCEPTION_PROLOG                                                     \
+       mtspr   SPRN_SPRG0,r10;         /* save two registers to work with */\
+       mtspr   SPRN_SPRG1,r11;                                              \
+       mtspr   SPRN_SPRG4W,r1;                                              \
+       mfcr    r10;                    /* save CR in r10 for now          */\
+       mfspr   r11,SPRN_SRR1;          /* check whether user or kernel    */\
+       andi.   r11,r11,MSR_PR;                                              \
+       beq     1f;                                                          \
+       mfspr   r1,SPRG3;               /* if from user, start at top of   */\
+       lwz     r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack   */\
+       addi    r1,r1,THREAD_SIZE;                                           \
+1:     subi    r1,r1,INT_FRAME_SIZE;   /* Allocate an exception frame     */\
+       tophys(r11,r1);                                                      \
+       stw     r10,_CCR(r11);          /* save various registers          */\
+       stw     r12,GPR12(r11);                                              \
+       stw     r9,GPR9(r11);                                                \
+       mfspr   r10,SPRG0;                                                   \
+       stw     r10,GPR10(r11);                                              \
+       mfspr   r12,SPRG1;                                                   \
+       stw     r12,GPR11(r11);                                              \
+       mflr    r10;                                                         \
+       stw     r10,_LINK(r11);                                              \
+       mfspr   r10,SPRG4R;                                                  \
+       mfspr   r12,SRR0;                                                    \
+       stw     r10,GPR1(r11);                                               \
+       mfspr   r9,SRR1;                                                     \
+       stw     r10,0(r11);                                                  \
+       rlwinm  r9,r9,0,14,12;          /* clear MSR_WE (necessary?)       */\
+       stw     r0,GPR0(r11);                                                \
+       SAVE_4GPRS(3, r11);                                                  \
+       SAVE_2GPRS(7, r11)
+
+/*
+ * Exception prolog for critical exceptions.  This is a little different
+ * from the normal exception prolog above since a critical exception
+ * can potentially occur at any point during normal exception processing.
+ * Thus we cannot use the same SPRG registers as the normal prolog above.
+ * Instead we use a couple of words of memory at low physical addresses.
+ * This is OK since we don't support SMP on these processors. For Book E
+ * processors, we also have a reserved register (SPRG2) that is only used
+ * in critical exceptions so we can free up a GPR to use as the base for
+ * indirect access to the critical exception save area.  This is necessary
+ * since the MMU is always on and the save area is offset from KERNELBASE.
+ */
+#define CRITICAL_EXCEPTION_PROLOG                                           \
+       mtspr   SPRG2,r8;               /* SPRG2 only used in criticals */   \
+       lis     r8,crit_save@ha;                                             \
+       stw     r10,crit_r10@l(r8);                                          \
+       stw     r11,crit_r11@l(r8);                                          \
+       mfspr   r10,SPRG0;                                                   \
+       stw     r10,crit_sprg0@l(r8);                                        \
+       mfspr   r10,SPRG1;                                                   \
+       stw     r10,crit_sprg1@l(r8);                                        \
+       mfspr   r10,SPRG4R;                                                  \
+       stw     r10,crit_sprg4@l(r8);                                        \
+       mfspr   r10,SPRG5R;                                                  \
+       stw     r10,crit_sprg5@l(r8);                                        \
+       mfspr   r10,SPRG7R;                                                  \
+       stw     r10,crit_sprg7@l(r8);                                        \
+       mfspr   r10,SPRN_PID;                                                \
+       stw     r10,crit_pid@l(r8);                                          \
+       mfspr   r10,SRR0;                                                    \
+       stw     r10,crit_srr0@l(r8);                                         \
+       mfspr   r10,SRR1;                                                    \
+       stw     r10,crit_srr1@l(r8);                                         \
+       mfspr   r8,SPRG2;               /* SPRG2 only used in criticals */   \
+       mfcr    r10;                    /* save CR in r10 for now          */\
+       mfspr   r11,SPRN_CSRR1;         /* check whether user or kernel    */\
+       andi.   r11,r11,MSR_PR;                                              \
+       lis     r11,critical_stack_top@h;                                    \
+       ori     r11,r11,critical_stack_top@l;                                \
+       beq     1f;                                                          \
+       /* COMING FROM USER MODE */                                          \
+       mfspr   r11,SPRG3;              /* if from user, start at top of   */\
+       lwz     r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
+       addi    r11,r11,THREAD_SIZE;                                         \
+1:     subi    r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame     */\
+       stw     r10,_CCR(r11);          /* save various registers          */\
+       stw     r12,GPR12(r11);                                              \
+       stw     r9,GPR9(r11);                                                \
+       mflr    r10;                                                         \
+       stw     r10,_LINK(r11);                                              \
+       mfspr   r12,SPRN_DEAR;          /* save DEAR and ESR in the frame  */\
+       stw     r12,_DEAR(r11);         /* since they may have had stuff   */\
+       mfspr   r9,SPRN_ESR;            /* in them at the point where the  */\
+       stw     r9,_ESR(r11);           /* exception was taken             */\
+       mfspr   r12,CSRR0;                                                   \
+       stw     r1,GPR1(r11);                                                \
+       mfspr   r9,CSRR1;                                                    \
+       stw     r1,0(r11);                                                   \
+       tovirt(r1,r11);                                                      \
+       rlwinm  r9,r9,0,14,12;          /* clear MSR_WE (necessary?)       */\
+       stw     r0,GPR0(r11);                                                \
+       SAVE_4GPRS(3, r11);                                                  \
+       SAVE_2GPRS(7, r11)
+
+/*
+ * Exception prolog for machine check exceptions.  This is similar to
+ * the critical exception prolog, except that machine check exceptions
+ * have their own save area.  For Book E processors, we also have a
+ * reserved register (SPRG6) that is only used in machine check exceptions
+ * so we can free up a GPR to use as the base for indirect access to the
+ * machine check exception save area.  This is necessary since the MMU
+ * is always on and the save area is offset from KERNELBASE.
+ */
+#define MCHECK_EXCEPTION_PROLOG                                             \
+       mtspr   SPRG6W,r8;              /* SPRG6 used in machine checks */   \
+       lis     r8,mcheck_save@ha;                                           \
+       stw     r10,mcheck_r10@l(r8);                                        \
+       stw     r11,mcheck_r11@l(r8);                                        \
+       mfspr   r10,SPRG0;                                                   \
+       stw     r10,mcheck_sprg0@l(r8);                                      \
+       mfspr   r10,SPRG1;                                                   \
+       stw     r10,mcheck_sprg1@l(r8);                                      \
+       mfspr   r10,SPRG4R;                                                  \
+       stw     r10,mcheck_sprg4@l(r8);                                      \
+       mfspr   r10,SPRG5R;                                                  \
+       stw     r10,mcheck_sprg5@l(r8);                                      \
+       mfspr   r10,SPRG7R;                                                  \
+       stw     r10,mcheck_sprg7@l(r8);                                      \
+       mfspr   r10,SPRN_PID;                                                \
+       stw     r10,mcheck_pid@l(r8);                                        \
+       mfspr   r10,SRR0;                                                    \
+       stw     r10,mcheck_srr0@l(r8);                                       \
+       mfspr   r10,SRR1;                                                    \
+       stw     r10,mcheck_srr1@l(r8);                                       \
+       mfspr   r10,CSRR0;                                                   \
+       stw     r10,mcheck_csrr0@l(r8);                                      \
+       mfspr   r10,CSRR1;                                                   \
+       stw     r10,mcheck_csrr1@l(r8);                                      \
+       mfspr   r8,SPRG6R;              /* SPRG6 used in machine checks */   \
+       mfcr    r10;                    /* save CR in r10 for now          */\
+       mfspr   r11,SPRN_MCSRR1;        /* check whether user or kernel    */\
+       andi.   r11,r11,MSR_PR;                                              \
+       lis     r11,mcheck_stack_top@h;                                      \
+       ori     r11,r11,mcheck_stack_top@l;                                  \
+       beq     1f;                                                          \
+       /* COMING FROM USER MODE */                                          \
+       mfspr   r11,SPRG3;              /* if from user, start at top of   */\
+       lwz     r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
+       addi    r11,r11,THREAD_SIZE;                                         \
+1:     subi    r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame     */\
+       stw     r10,_CCR(r11);          /* save various registers          */\
+       stw     r12,GPR12(r11);                                              \
+       stw     r9,GPR9(r11);                                                \
+       mflr    r10;                                                         \
+       stw     r10,_LINK(r11);                                              \
+       mfspr   r12,SPRN_DEAR;          /* save DEAR and ESR in the frame  */\
+       stw     r12,_DEAR(r11);         /* since they may have had stuff   */\
+       mfspr   r9,SPRN_ESR;            /* in them at the point where the  */\
+       stw     r9,_ESR(r11);           /* exception was taken             */\
+       mfspr   r12,MCSRR0;                                                  \
+       stw     r1,GPR1(r11);                                                \
+       mfspr   r9,MCSRR1;                                                   \
+       stw     r1,0(r11);                                                   \
+       tovirt(r1,r11);                                                      \
+       rlwinm  r9,r9,0,14,12;          /* clear MSR_WE (necessary?)       */\
+       stw     r0,GPR0(r11);                                                \
+       SAVE_4GPRS(3, r11);                                                  \
+       SAVE_2GPRS(7, r11)
+
+/*
+ * Exception vectors.
+ */
+#define        START_EXCEPTION(label)                                               \
+        .align 5;                                                                   \
+label:
+
+#define FINISH_EXCEPTION(func)                                 \
+       bl      transfer_to_handler_full;                       \
+       .long   func;                                           \
+       .long   ret_from_except_full
+
+#define EXCEPTION(n, label, hdlr, xfer)                                \
+       START_EXCEPTION(label);                                 \
+       NORMAL_EXCEPTION_PROLOG;                                \
+       addi    r3,r1,STACK_FRAME_OVERHEAD;                     \
+       xfer(n, hdlr)
+
+#define CRITICAL_EXCEPTION(n, label, hdlr)                     \
+       START_EXCEPTION(label);                                 \
+       CRITICAL_EXCEPTION_PROLOG;                              \
+       addi    r3,r1,STACK_FRAME_OVERHEAD;                     \
+       EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
+                         NOCOPY, transfer_to_handler_full, \
+                         ret_from_except_full)
+
+#define MCHECK_EXCEPTION(n, label, hdlr)                       \
+       START_EXCEPTION(label);                                 \
+       MCHECK_EXCEPTION_PROLOG;                                \
+       mfspr   r5,SPRN_ESR;                                    \
+       stw     r5,_ESR(r11);                                   \
+       addi    r3,r1,STACK_FRAME_OVERHEAD;                     \
+       EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
+                         NOCOPY, mcheck_transfer_to_handler,   \
+                         ret_from_mcheck_exc)
+
+#define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret)  \
+       li      r10,trap;                                       \
+       stw     r10,TRAP(r11);                                  \
+       lis     r10,msr@h;                                      \
+       ori     r10,r10,msr@l;                                  \
+       copyee(r10, r9);                                        \
+       bl      tfer;                                           \
+       .long   hdlr;                                           \
+       .long   ret
+
+#define COPY_EE(d, s)          rlwimi d,s,0,16,16
+#define NOCOPY(d, s)
+
+#define EXC_XFER_STD(n, hdlr)          \
+       EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, NOCOPY, transfer_to_handler_full, \
+                         ret_from_except_full)
+
+#define EXC_XFER_LITE(n, hdlr)         \
+       EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \
+                         ret_from_except)
+
+#define EXC_XFER_EE(n, hdlr)           \
+       EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, COPY_EE, transfer_to_handler_full, \
+                         ret_from_except_full)
+
+#define EXC_XFER_EE_LITE(n, hdlr)      \
+       EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \
+                         ret_from_except)
+
+interrupt_base:
+       /* Critical Input Interrupt */
+       CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException)
+
+       /* Machine Check Interrupt */
+       MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
+
+       /* Data Storage Interrupt */
+       START_EXCEPTION(DataStorage)
+       mtspr   SPRG0, r10              /* Save some working registers */
+       mtspr   SPRG1, r11
+       mtspr   SPRG4W, r12
+       mtspr   SPRG5W, r13
+       mfcr    r11
+       mtspr   SPRG7W, r11
+
+       /*
+        * Check if it was a store fault, if not then bail
+        * because a user tried to access a kernel or
+        * read-protected page.  Otherwise, get the
+        * offending address and handle it.
+        */
+       mfspr   r10, SPRN_ESR
+       andis.  r10, r10, ESR_ST@h
+       beq     2f
+
+       mfspr   r10, SPRN_DEAR          /* Get faulting address */
+
+       /* If we are faulting a kernel address, we have to use the
+        * kernel page tables.
+        */
+       lis     r11, TASK_SIZE@h
+       ori     r11, r11, TASK_SIZE@l
+       cmplw   0, r10, r11
+       bge     2f
+
+       /* Get the PGD for the current thread */
+3:
+       mfspr   r11,SPRG3
+       lwz     r11,PGDIR(r11)
+4:
+       rlwimi  r11, r10, 12, 20, 29    /* Create L1 (pgdir/pmd) address */
+       lwz     r11, 0(r11)             /* Get L1 entry */
+       rlwinm. r12, r11, 0, 0, 19      /* Extract L2 (pte) base address */
+       beq     2f                      /* Bail if no table */
+
+       rlwimi  r12, r10, 22, 20, 29    /* Compute PTE address */
+       lwz     r11, 0(r12)             /* Get Linux PTE */
+
+       /* Are _PAGE_USER & _PAGE_RW set & _PAGE_HWWRITE not? */
+       andi.   r13, r11, _PAGE_RW|_PAGE_USER|_PAGE_HWWRITE
+       cmpwi   0, r13, _PAGE_RW|_PAGE_USER
+       bne     2f                      /* Bail if not */
+
+       /* Update 'changed'. */
+       ori     r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
+       stw     r11, 0(r12)             /* Update Linux page table */
+
+       /* MAS2 not updated as the entry does exist in the tlb, this
+          fault taken to detect state transition (eg: COW -> DIRTY)
+        */
+       lis     r12, MAS3_RPN@h
+       ori     r12, r12, _PAGE_HWEXEC | MAS3_RPN@l
+       and     r11, r11, r12
+       rlwimi  r11, r11, 31, 27, 27    /* SX <- _PAGE_HWEXEC */
+       ori     r11, r11, (MAS3_UW|MAS3_SW|MAS3_UR|MAS3_SR)@l /* set static perms */
+
+       /* update search PID in MAS6, AS = 0 */
+       mfspr   r12, SPRN_PID0
+       slwi    r12, r12, 16
+       mtspr   SPRN_MAS6, r12
+
+       /* find the TLB index that caused the fault.  It has to be here. */
+       tlbsx   0, r10
+
+       mtspr   SPRN_MAS3,r11
+       tlbwe
+
+       /* Done...restore registers and get out of here.  */
+       mfspr   r11, SPRG7R
+       mtcr    r11
+       mfspr   r13, SPRG5R
+       mfspr   r12, SPRG4R
+       mfspr   r11, SPRG1
+       mfspr   r10, SPRG0
+       rfi                     /* Force context change */
+
+2:
+       /*
+        * The bailout.  Restore registers to pre-exception conditions
+        * and call the heavyweights to help us out.
+        */
+       mfspr   r11, SPRG7R
+       mtcr    r11
+       mfspr   r13, SPRG5R
+       mfspr   r12, SPRG4R
+       mfspr   r11, SPRG1
+       mfspr   r10, SPRG0
+       b       data_access
+
+       /* Instruction Storage Interrupt */
+       START_EXCEPTION(InstructionStorage)
+       NORMAL_EXCEPTION_PROLOG
+       mfspr   r5,SPRN_ESR             /* Grab the ESR and save it */
+       stw     r5,_ESR(r11)
+       mr      r4,r12                  /* Pass SRR0 as arg2 */
+       li      r5,0                    /* Pass zero as arg3 */
+       EXC_XFER_EE_LITE(0x0400, handle_page_fault)
+
+       /* External Input Interrupt */
+       EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE)
+
+       /* Alignment Interrupt */
+       START_EXCEPTION(Alignment)
+       NORMAL_EXCEPTION_PROLOG
+       mfspr   r4,SPRN_DEAR            /* Grab the DEAR and save it */
+       stw     r4,_DEAR(r11)
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       EXC_XFER_EE(0x0600, AlignmentException)
+
+       /* Program Interrupt */
+       START_EXCEPTION(Program)
+       NORMAL_EXCEPTION_PROLOG
+       mfspr   r4,SPRN_ESR             /* Grab the ESR and save it */
+       stw     r4,_ESR(r11)
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       EXC_XFER_STD(0x0700, ProgramCheckException)
+
+       /* Floating Point Unavailable Interrupt */
+       EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE)
+
+       /* System Call Interrupt */
+       START_EXCEPTION(SystemCall)
+       NORMAL_EXCEPTION_PROLOG
+       EXC_XFER_EE_LITE(0x0c00, DoSyscall)
+
+       /* Auxillary Processor Unavailable Interrupt */
+       EXCEPTION(0x2900, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE)
+
+       /* Decrementer Interrupt */
+       START_EXCEPTION(Decrementer)
+       NORMAL_EXCEPTION_PROLOG
+       lis     r0,TSR_DIS@h            /* Setup the DEC interrupt mask */
+       mtspr   SPRN_TSR,r0             /* Clear the DEC interrupt */
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       EXC_XFER_LITE(0x0900, timer_interrupt)
+
+       /* Fixed Internal Timer Interrupt */
+       /* TODO: Add FIT support */
+       EXCEPTION(0x3100, FixedIntervalTimer, UnknownException, EXC_XFER_EE)
+
+       /* Watchdog Timer Interrupt */
+       /* TODO: Add watchdog support */
+       CRITICAL_EXCEPTION(0x3200, WatchdogTimer, UnknownException)
+
+       /* Data TLB Error Interrupt */
+       START_EXCEPTION(DataTLBError)
+       mtspr   SPRG0, r10              /* Save some working registers */
+       mtspr   SPRG1, r11
+       mtspr   SPRG4W, r12
+       mtspr   SPRG5W, r13
+       mfcr    r11
+       mtspr   SPRG7W, r11
+       mfspr   r10, SPRN_DEAR          /* Get faulting address */
+
+       /* If we are faulting a kernel address, we have to use the
+        * kernel page tables.
+        */
+       lis     r11, TASK_SIZE@h
+       ori     r11, r11, TASK_SIZE@l
+       cmplw   5, r10, r11
+       blt     5, 3f
+       lis     r11, swapper_pg_dir@h
+       ori     r11, r11, swapper_pg_dir@l
+
+       mfspr   r12,SPRN_MAS1           /* Set TID to 0 */
+       li      r13,MAS1_TID@l
+       andc    r12,r12,r13
+       mtspr   SPRN_MAS1,r12
+
+       b       4f
+
+       /* Get the PGD for the current thread */
+3:
+       mfspr   r11,SPRG3
+       lwz     r11,PGDIR(r11)
+
+4:
+       rlwimi  r11, r10, 12, 20, 29    /* Create L1 (pgdir/pmd) address */
+       lwz     r11, 0(r11)             /* Get L1 entry */
+       rlwinm. r12, r11, 0, 0, 19      /* Extract L2 (pte) base address */
+       beq     2f                      /* Bail if no table */
+
+       rlwimi  r12, r10, 22, 20, 29    /* Compute PTE address */
+       lwz     r11, 0(r12)             /* Get Linux PTE */
+       andi.   r13, r11, _PAGE_PRESENT
+       beq     2f
+
+       ori     r11, r11, _PAGE_ACCESSED
+       stw     r11, 0(r12)
+
+        /* Jump to common tlb load */
+       b       finish_tlb_load
+2:
+       /* The bailout.  Restore registers to pre-exception conditions
+        * and call the heavyweights to help us out.
+        */
+       mfspr   r11, SPRG7R
+       mtcr    r11
+       mfspr   r13, SPRG5R
+       mfspr   r12, SPRG4R
+       mfspr   r11, SPRG1
+       mfspr   r10, SPRG0
+       b       data_access
+
+       /* Instruction TLB Error Interrupt */
+       /*
+        * Nearly the same as above, except we get our
+        * information from different registers and bailout
+        * to a different point.
+        */
+       START_EXCEPTION(InstructionTLBError)
+       mtspr   SPRG0, r10              /* Save some working registers */
+       mtspr   SPRG1, r11
+       mtspr   SPRG4W, r12
+       mtspr   SPRG5W, r13
+       mfcr    r11
+       mtspr   SPRG7W, r11
+       mfspr   r10, SRR0               /* Get faulting address */
+
+       /* If we are faulting a kernel address, we have to use the
+        * kernel page tables.
+        */
+       lis     r11, TASK_SIZE@h
+       ori     r11, r11, TASK_SIZE@l
+       cmplw   5, r10, r11
+       blt     5, 3f
+       lis     r11, swapper_pg_dir@h
+       ori     r11, r11, swapper_pg_dir@l
+
+       mfspr   r12,SPRN_MAS1           /* Set TID to 0 */
+       li      r13,MAS1_TID@l
+       andc    r12,r12,r13
+       mtspr   SPRN_MAS1,r12
+
+       b       4f
+
+       /* Get the PGD for the current thread */
+3:
+       mfspr   r11,SPRG3
+       lwz     r11,PGDIR(r11)
+
+4:
+       rlwimi  r11, r10, 12, 20, 29    /* Create L1 (pgdir/pmd) address */
+       lwz     r11, 0(r11)             /* Get L1 entry */
+       rlwinm. r12, r11, 0, 0, 19      /* Extract L2 (pte) base address */
+       beq     2f                      /* Bail if no table */
+
+       rlwimi  r12, r10, 22, 20, 29    /* Compute PTE address */
+       lwz     r11, 0(r12)             /* Get Linux PTE */
+       andi.   r13, r11, _PAGE_PRESENT
+       beq     2f
+
+       ori     r11, r11, _PAGE_ACCESSED
+       stw     r11, 0(r12)
+
+       /* Jump to common TLB load point */
+       b       finish_tlb_load
+
+2:
+       /* The bailout.  Restore registers to pre-exception conditions
+        * and call the heavyweights to help us out.
+        */
+       mfspr   r11, SPRG7R
+       mtcr    r11
+       mfspr   r13, SPRG5R
+       mfspr   r12, SPRG4R
+       mfspr   r11, SPRG1
+       mfspr   r10, SPRG0
+       b       InstructionStorage
+
+#ifdef CONFIG_SPE
+       /* SPE Unavailable */
+       START_EXCEPTION(SPEUnavailable)
+       NORMAL_EXCEPTION_PROLOG
+       bne     load_up_spe
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       EXC_XFER_EE_LITE(0x2010, KernelSPE)
+#else
+       EXCEPTION(0x2020, SPEUnavailable, UnknownException, EXC_XFER_EE)
+#endif /* CONFIG_SPE */
+
+       /* SPE Floating Point Data */
+#ifdef CONFIG_SPE
+       EXCEPTION(0x2030, SPEFloatingPointData, SPEFloatingPointException, EXC_XFER_EE);
+#else
+       EXCEPTION(0x2040, SPEFloatingPointData, UnknownException, EXC_XFER_EE)
+#endif /* CONFIG_SPE */
+
+       /* SPE Floating Point Round */
+       EXCEPTION(0x2050, SPEFloatingPointRound, UnknownException, EXC_XFER_EE)
+
+       /* Performance Monitor */
+       EXCEPTION(0x2060, PerformanceMonitor, UnknownException, EXC_XFER_EE)
+
+/* Check for a single step debug exception while in an exception
+ * handler before state has been saved.  This is to catch the case
+ * where an instruction that we are trying to single step causes
+ * an exception (eg ITLB/DTLB miss) and thus the first instruction of
+ * the exception handler generates a single step debug exception.
+ *
+ * If we get a debug trap on the first instruction of an exception handler,
+ * we reset the MSR_DE in the _exception handler's_ MSR (the debug trap is
+ * a critical exception, so we are using SPRN_CSRR1 to manipulate the MSR).
+ * The exception handler was handling a non-critical interrupt, so it will
+ * save (and later restore) the MSR via SPRN_SRR1, which will still have
+ * the MSR_DE bit set.
+ */
+       /* Debug Interrupt */
+       START_EXCEPTION(Debug)
+       CRITICAL_EXCEPTION_PROLOG
+
+       /*
+        * If this is a single step or branch-taken exception in an
+        * exception entry sequence, it was probably meant to apply to
+        * the code where the exception occurred (since exception entry
+        * doesn't turn off DE automatically).  We simulate the effect
+        * of turning off DE on entry to an exception handler by turning
+        * off DE in the CSRR1 value and clearing the debug status.
+        */
+       mfspr   r10,SPRN_DBSR           /* check single-step/branch taken */
+       andis.  r10,r10,(DBSR_IC|DBSR_BT)@h
+       beq+    1f
+       andi.   r0,r9,MSR_PR            /* check supervisor */
+       beq     2f                      /* branch if we need to fix it up... */
+
+       /* continue normal handling for a critical exception... */
+1:     mfspr   r4,SPRN_DBSR
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       EXC_XFER_TEMPLATE(DebugException, 0x2002, \
+               (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
+               NOCOPY, crit_transfer_to_handler, ret_from_crit_exc)
+
+       /* here it looks like we got an inappropriate debug exception. */
+2:     rlwinm  r9,r9,0,~MSR_DE         /* clear DE in the CSRR1 value */
+       mtspr   SPRN_DBSR,r10           /* clear the IC/BT debug intr status */
+       /* restore state and get out */
+       lwz     r10,_CCR(r11)
+       lwz     r0,GPR0(r11)
+       lwz     r1,GPR1(r11)
+       mtcrf   0x80,r10
+       mtspr   CSRR0,r12
+       mtspr   CSRR1,r9
+       lwz     r9,GPR9(r11)
+
+       mtspr   SPRG2,r8;               /* SPRG2 only used in criticals */
+       lis     r8,crit_save@ha;
+       lwz     r10,crit_r10@l(r8)
+       lwz     r11,crit_r11@l(r8)
+       mfspr   r8,SPRG2
+
+       rfci
+       b       .
+
+/*
+ * Local functions
+ */
+       /*
+        * Data TLB exceptions will bail out to this point
+        * if they can't resolve the lightweight TLB fault.
+        */
+data_access:
+       NORMAL_EXCEPTION_PROLOG
+       mfspr   r5,SPRN_ESR             /* Grab the ESR, save it, pass arg3 */
+       stw     r5,_ESR(r11)
+       mfspr   r4,SPRN_DEAR            /* Grab the DEAR, save it, pass arg2 */
+       andis.  r10,r5,(ESR_ILK|ESR_DLK)@h
+       bne     1f
+       EXC_XFER_EE_LITE(0x0300, handle_page_fault)
+1:
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       EXC_XFER_EE_LITE(0x0300, CacheLockingException)
+
+/*
+
+ * Both the instruction and data TLB miss get to this
+ * point to load the TLB.
+ *     r10 - EA of fault
+ *     r11 - TLB (info from Linux PTE)
+ *     r12, r13 - available to use
+ *     CR5 - results of addr < TASK_SIZE
+ *     MAS0, MAS1 - loaded with proper value when we get here
+ *     MAS2, MAS3 - will need additional info from Linux PTE
+ *     Upon exit, we reload everything and RFI.
+ */
+finish_tlb_load:
+       /*
+        * We set execute, because we don't have the granularity to
+        * properly set this at the page level (Linux problem).
+        * Many of these bits are software only.  Bits we don't set
+        * here we (properly should) assume have the appropriate value.
+        */
+
+       mfspr   r12, SPRN_MAS2
+       rlwimi  r12, r11, 26, 27, 31    /* extract WIMGE from pte */
+       mtspr   SPRN_MAS2, r12
+
+       bge     5, 1f
+
+       /* addr > TASK_SIZE */
+       li      r10, (MAS3_UX | MAS3_UW | MAS3_UR)
+       andi.   r13, r11, (_PAGE_USER | _PAGE_HWWRITE | _PAGE_HWEXEC)
+       andi.   r12, r11, _PAGE_USER    /* Test for _PAGE_USER */
+       iseleq  r12, 0, r10
+       and     r10, r12, r13
+       srwi    r12, r10, 1
+       or      r12, r12, r10   /* Copy user perms into supervisor */
+       b       2f
+
+       /* addr <= TASK_SIZE */
+1:     rlwinm  r12, r11, 31, 29, 29    /* Extract _PAGE_HWWRITE into SW */
+       ori     r12, r12, (MAS3_SX | MAS3_SR)
+
+2:     rlwimi  r11, r12, 0, 20, 31     /* Extract RPN from PTE and merge with perms */
+       mtspr   SPRN_MAS3, r11
+       tlbwe
+
+       /* Done...restore registers and get out of here.  */
+       mfspr   r11, SPRG7R
+       mtcr    r11
+       mfspr   r13, SPRG5R
+       mfspr   r12, SPRG4R
+       mfspr   r11, SPRG1
+       mfspr   r10, SPRG0
+       rfi                                     /* Force context change */
+
+#ifdef CONFIG_SPE
+/* Note that the SPE support is closely modeled after the AltiVec
+ * support.  Changes to one are likely to be applicable to the
+ * other!  */
+load_up_spe:
+/*
+ * Disable SPE for the task which had SPE previously,
+ * and save its SPE registers in its thread_struct.
+ * Enables SPE for use in the kernel on return.
+ * On SMP we know the SPE units are free, since we give it up every
+ * switch.  -- Kumar
+ */
+       mfmsr   r5
+       oris    r5,r5,MSR_SPE@h
+       mtmsr   r5                      /* enable use of SPE now */
+       isync
+/*
+ * For SMP, we don't do lazy SPE switching because it just gets too
+ * horrendously complex, especially when a task switches from one CPU
+ * to another.  Instead we call giveup_spe in switch_to.
+ */
+#ifndef CONFIG_SMP
+       lis     r3,last_task_used_spe@ha
+       lwz     r4,last_task_used_spe@l(r3)
+       cmpi    0,r4,0
+       beq     1f
+       addi    r4,r4,THREAD    /* want THREAD of last_task_used_spe */
+       SAVE_32EVR(0,r10,r4)
+       evxor   evr10, evr10, evr10     /* clear out evr10 */
+       evmwumiaa evr10, evr10, evr10   /* evr10 <- ACC = 0 * 0 + ACC */
+       li      r5,THREAD_ACC
+       evstddx evr10, r4, r5           /* save off accumulator */
+       lwz     r5,PT_REGS(r4)
+       lwz     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+       lis     r10,MSR_SPE@h
+       andc    r4,r4,r10       /* disable SPE for previous task */
+       stw     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#endif /* CONFIG_SMP */
+       /* enable use of SPE after return */
+       oris    r9,r9,MSR_SPE@h
+       mfspr   r5,SPRG3                /* current task's THREAD (phys) */
+       li      r4,1
+       li      r10,THREAD_ACC
+       stw     r4,THREAD_USED_SPE(r5)
+       evlddx  evr4,r10,r5
+       evmra   evr4,evr4
+       REST_32EVR(0,r10,r5)
+#ifndef CONFIG_SMP
+       subi    r4,r5,THREAD
+       stw     r4,last_task_used_spe@l(r3)
+#endif /* CONFIG_SMP */
+       /* restore registers and return */
+2:     REST_4GPRS(3, r11)
+       lwz     r10,_CCR(r11)
+       REST_GPR(1, r11)
+       mtcr    r10
+       lwz     r10,_LINK(r11)
+       mtlr    r10
+       REST_GPR(10, r11)
+       mtspr   SRR1,r9
+       mtspr   SRR0,r12
+       REST_GPR(9, r11)
+       REST_GPR(12, r11)
+       lwz     r11,GPR11(r11)
+       SYNC
+       rfi
+
+
+
+/*
+ * SPE unavailable trap from kernel - print a message, but let
+ * the task use SPE in the kernel until it returns to user mode.
+ */
+KernelSPE:
+       lwz     r3,_MSR(r1)
+       oris    r3,r3,MSR_SPE@h
+       stw     r3,_MSR(r1)     /* enable use of SPE after return */
+       lis     r3,87f@h
+       ori     r3,r3,87f@l
+       mr      r4,r2           /* current */
+       lwz     r5,_NIP(r1)
+       bl      printk
+       b       ret_from_except
+87:    .string "SPE used in kernel  (task=%p, pc=%x)  \n"
+       .align  4,0
+
+#endif /* CONFIG_SPE */
+
+/*
+ * Global functions
+ */
+
+/*
+ * extern void loadcam_entry(unsigned int index)
+ *
+ * Load TLBCAM[index] entry in to the L2 CAM MMU
+ */
+_GLOBAL(loadcam_entry)
+       lis     r4,TLBCAM@ha
+       addi    r4,r4,TLBCAM@l
+       mulli   r5,r3,20
+       add     r3,r5,r4
+       lwz     r4,0(r3)
+       mtspr   SPRN_MAS0,r4
+       lwz     r4,4(r3)
+       mtspr   SPRN_MAS1,r4
+       lwz     r4,8(r3)
+       mtspr   SPRN_MAS2,r4
+       lwz     r4,12(r3)
+       mtspr   SPRN_MAS3,r4
+       tlbwe
+       isync
+       blr
+
+/*
+ * extern void giveup_altivec(struct task_struct *prev)
+ *
+ * The e500 core does not have an AltiVec unit.
+ */
+_GLOBAL(giveup_altivec)
+       blr
+
+#ifdef CONFIG_SPE
+/*
+ * extern void giveup_spe(struct task_struct *prev)
+ *
+ */
+_GLOBAL(giveup_spe)
+       mfmsr   r5
+       oris    r5,r5,MSR_SPE@h
+       SYNC
+       mtmsr   r5                      /* enable use of SPE now */
+       isync
+       cmpi    0,r3,0
+       beqlr-                          /* if no previous owner, done */
+       addi    r3,r3,THREAD            /* want THREAD of task */
+       lwz     r5,PT_REGS(r3)
+       cmpi    0,r5,0
+       SAVE_32EVR(0, r4, r3)
+       evxor   evr6, evr6, evr6        /* clear out evr6 */
+       evmwumiaa evr6, evr6, evr6      /* evr6 <- ACC = 0 * 0 + ACC */
+       li      r4,THREAD_ACC
+       evstddx evr6, r4, r3            /* save off accumulator */
+       beq     1f
+       lwz     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+       lis     r3,MSR_SPE@h
+       andc    r4,r4,r3                /* disable SPE for previous task */
+       stw     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#ifndef CONFIG_SMP
+       li      r5,0
+       lis     r4,last_task_used_spe@ha
+       stw     r5,last_task_used_spe@l(r4)
+#endif /* CONFIG_SMP */
+       blr
+#endif /* CONFIG_SPE */
+
+/*
+ * extern void giveup_fpu(struct task_struct *prev)
+ *
+ * The e500 core does not have an FPU.
+ */
+_GLOBAL(giveup_fpu)
+       blr
+
+/*
+ * extern void abort(void)
+ *
+ * At present, this routine just applies a system reset.
+ */
+_GLOBAL(abort)
+       li      r13,0
+        mtspr   SPRN_DBCR0,r13         /* disable all debug events */
+       mfmsr   r13
+       ori     r13,r13,MSR_DE@l        /* Enable Debug Events */
+       mtmsr   r13
+        mfspr   r13,SPRN_DBCR0
+        lis    r13,(DBCR0_IDM|DBCR0_RST_CHIP)@h
+        mtspr   SPRN_DBCR0,r13
+
+_GLOBAL(set_context)
+
+#ifdef CONFIG_BDI_SWITCH
+       /* Context switch the PTE pointer for the Abatron BDI2000.
+        * The PGDIR is the second parameter.
+        */
+       lis     r5, abatron_pteptrs@h
+       ori     r5, r5, abatron_pteptrs@l
+       stw     r4, 0x4(r5)
+#endif
+       mtspr   SPRN_PID,r3
+       isync                   /* Force context change */
+       blr
+
+/*
+ * We put a few things here that have to be page-aligned. This stuff
+ * goes at the beginning of the data segment, which is page-aligned.
+ */
+       .data
+_GLOBAL(sdata)
+_GLOBAL(empty_zero_page)
+       .space  4096
+_GLOBAL(swapper_pg_dir)
+       .space  4096
+
+       .section .bss
+/* Stack for handling critical exceptions from kernel mode */
+critical_stack_bottom:
+       .space 4096
+critical_stack_top:
+       .previous
+
+/* Stack for handling machine check exceptions from kernel mode */
+mcheck_stack_bottom:
+       .space 4096
+mcheck_stack_top:
+       .previous
+
+/*
+ * This area is used for temporarily saving registers during the
+ * critical and machine check exception prologs. It must always
+ * follow the page aligned allocations, so it starts on a page
+ * boundary, ensuring that all crit_save areas are in a single
+ * page.
+ */
+
+/* crit_save */
+_GLOBAL(crit_save)
+       .space  4
+_GLOBAL(crit_r10)
+       .space  4
+_GLOBAL(crit_r11)
+       .space  4
+_GLOBAL(crit_sprg0)
+       .space  4
+_GLOBAL(crit_sprg1)
+       .space  4
+_GLOBAL(crit_sprg4)
+       .space  4
+_GLOBAL(crit_sprg5)
+       .space  4
+_GLOBAL(crit_sprg7)
+       .space  4
+_GLOBAL(crit_pid)
+       .space  4
+_GLOBAL(crit_srr0)
+       .space  4
+_GLOBAL(crit_srr1)
+       .space  4
+
+/* mcheck_save */
+_GLOBAL(mcheck_save)
+       .space  4
+_GLOBAL(mcheck_r10)
+       .space  4
+_GLOBAL(mcheck_r11)
+       .space  4
+_GLOBAL(mcheck_sprg0)
+       .space  4
+_GLOBAL(mcheck_sprg1)
+       .space  4
+_GLOBAL(mcheck_sprg4)
+       .space  4
+_GLOBAL(mcheck_sprg5)
+       .space  4
+_GLOBAL(mcheck_sprg7)
+       .space  4
+_GLOBAL(mcheck_pid)
+       .space  4
+_GLOBAL(mcheck_srr0)
+       .space  4
+_GLOBAL(mcheck_srr1)
+       .space  4
+_GLOBAL(mcheck_csrr0)
+       .space  4
+_GLOBAL(mcheck_csrr1)
+       .space  4
+
+/*
+ * This space gets a copy of optional info passed to us by the bootstrap
+ * which is used to pass parameters into the kernel like root=/dev/sda1, etc.
+ */
+_GLOBAL(cmd_line)
+       .space  512
+
+/*
+ * Room for two PTE pointers, usually the kernel and current user pointers
+ * to their respective root page table.
+ */
+abatron_pteptrs:
+       .space  8
+
+
diff --git a/arch/ppc/platforms/85xx/Kconfig b/arch/ppc/platforms/85xx/Kconfig
new file mode 100644 (file)
index 0000000..cfe29eb
--- /dev/null
@@ -0,0 +1,44 @@
+config 85xx
+       bool
+       depends on E500
+       default y
+
+config PPC_INDIRECT_PCI_BE
+       bool
+       depends on 85xx
+       default y
+
+menu "Freescale 85xx options"
+       depends on E500
+
+choice
+       prompt "Machine Type"
+       depends on 85xx
+       default MPC8540_ADS
+
+config MPC8540_ADS
+       bool "MPC8540ADS"
+       help
+         This option enables support for the MPC 8540 ADS evaluation board.
+
+endchoice
+
+# It's often necessary to know the specific 85xx processor type.
+# Fortunately, it is implied (so far) from the board type, so we
+# don't need to ask more redundant questions.
+config MPC8540
+       bool
+       depends on MPC8540_ADS
+       default y
+
+config FSL_OCP
+       bool
+       depends on 85xx
+       default y
+
+config PPC_GEN550
+       bool
+       depends on MPC8540
+       default y
+
+endmenu
diff --git a/arch/ppc/platforms/85xx/Makefile b/arch/ppc/platforms/85xx/Makefile
new file mode 100644 (file)
index 0000000..92a8823
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Makefile for the PowerPC 85xx linux kernel.
+#
+
+obj-$(CONFIG_MPC8540_ADS)      += mpc85xx_ads_common.o mpc8540_ads.o
+
+obj-$(CONFIG_MPC8540)          += mpc8540.o
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c
new file mode 100644 (file)
index 0000000..aada593
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * arch/ppc/platforms/85xx/mpc8540_ads.c
+ *
+ * MPC8540ADS board specific routines
+ *
+ * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ *
+ * Copyright 2004 Freescale Semiconductor 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.
+ */
+
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/serial.h>
+#include <linux/tty.h> /* for linux/serial_core.h */
+#include <linux/serial_core.h>
+#include <linux/module.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/atomic.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/open_pic.h>
+#include <asm/bootinfo.h>
+#include <asm/pci-bridge.h>
+#include <asm/mpc85xx.h>
+#include <asm/irq.h>
+#include <asm/immap_85xx.h>
+#include <asm/kgdb.h>
+#include <asm/ocp.h>
+#include <mm/mmu_decl.h>
+
+#include <syslib/ppc85xx_common.h>
+#include <syslib/ppc85xx_setup.h>
+
+struct ocp_gfar_data mpc85xx_tsec1_def = {
+       .interruptTransmit = MPC85xx_IRQ_TSEC1_TX,
+       .interruptError = MPC85xx_IRQ_TSEC1_ERROR,
+       .interruptReceive = MPC85xx_IRQ_TSEC1_RX,
+       .interruptPHY = MPC85xx_IRQ_EXT5,
+       .flags = (GFAR_HAS_GIGABIT | GFAR_HAS_MULTI_INTR
+                       | GFAR_HAS_RMON
+                       | GFAR_HAS_PHY_INTR | GFAR_HAS_COALESCE),
+       .phyid = 0,
+       .phyregidx = 0,
+};
+
+struct ocp_gfar_data mpc85xx_tsec2_def = {
+       .interruptTransmit = MPC85xx_IRQ_TSEC2_TX,
+       .interruptError = MPC85xx_IRQ_TSEC2_ERROR,
+       .interruptReceive = MPC85xx_IRQ_TSEC2_RX,
+       .interruptPHY = MPC85xx_IRQ_EXT5,
+       .flags = (GFAR_HAS_GIGABIT | GFAR_HAS_MULTI_INTR
+                       | GFAR_HAS_RMON
+                       | GFAR_HAS_PHY_INTR | GFAR_HAS_COALESCE),
+       .phyid = 1,
+       .phyregidx = 0,
+};
+
+struct ocp_gfar_data mpc85xx_fec_def = {
+       .interruptTransmit = MPC85xx_IRQ_FEC,
+       .interruptError = MPC85xx_IRQ_FEC,
+       .interruptReceive = MPC85xx_IRQ_FEC,
+       .interruptPHY = MPC85xx_IRQ_EXT5,
+       .flags = 0,
+       .phyid = 3,
+       .phyregidx = 0,
+};
+
+struct ocp_fs_i2c_data mpc85xx_i2c1_def = {
+       .flags = FS_I2C_SEPARATE_DFSRR,
+};
+
+/* ************************************************************************
+ *
+ * Setup the architecture
+ *
+ */
+static void __init
+mpc8540ads_setup_arch(void)
+{
+       struct ocp_def *def;
+       struct ocp_gfar_data *einfo;
+       bd_t *binfo = (bd_t *) __res;
+       unsigned int freq;
+
+       /* get the core frequency */
+       freq = binfo->bi_intfreq;
+
+       if (ppc_md.progress)
+               ppc_md.progress("mpc8540ads_setup_arch()", 0);
+
+       /* Set loops_per_jiffy to a half-way reasonable value,
+          for use until calibrate_delay gets called. */
+       loops_per_jiffy = freq / HZ;
+
+#ifdef CONFIG_PCI
+       /* setup PCI host bridges */
+       mpc85xx_setup_hose();
+#endif
+
+#ifdef CONFIG_DUMMY_CONSOLE
+       conswitchp = &dummy_con;
+#endif
+
+#ifdef CONFIG_SERIAL_8250
+       mpc85xx_early_serial_map();
+#endif
+
+#ifdef CONFIG_SERIAL_TEXT_DEBUG
+       /* Invalidate the entry we stole earlier the serial ports
+        * should be properly mapped */
+       invalidate_tlbcam_entry(NUM_TLBCAMS - 1);
+#endif
+
+       def = ocp_get_one_device(OCP_VENDOR_FREESCALE, OCP_FUNC_GFAR, 0);
+       if (def) {
+               einfo = (struct ocp_gfar_data *) def->additions;
+               memcpy(einfo->mac_addr, binfo->bi_enetaddr, 6);
+       }
+
+       def = ocp_get_one_device(OCP_VENDOR_FREESCALE, OCP_FUNC_GFAR, 1);
+       if (def) {
+               einfo = (struct ocp_gfar_data *) def->additions;
+               memcpy(einfo->mac_addr, binfo->bi_enet1addr, 6);
+       }
+
+       def = ocp_get_one_device(OCP_VENDOR_FREESCALE, OCP_FUNC_GFAR, 2);
+       if (def) {
+               einfo = (struct ocp_gfar_data *) def->additions;
+               memcpy(einfo->mac_addr, binfo->bi_enet2addr, 6);
+       }
+
+#ifdef CONFIG_BLK_DEV_INITRD
+       if (initrd_start)
+               ROOT_DEV = Root_RAM0;
+       else
+#endif
+#ifdef  CONFIG_ROOT_NFS
+               ROOT_DEV = Root_NFS;
+#else
+               ROOT_DEV = Root_HDA1;
+#endif
+
+       ocp_for_each_device(mpc85xx_update_paddr_ocp, &(binfo->bi_immr_base));
+}
+
+/* ************************************************************************ */
+void __init
+platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+             unsigned long r6, unsigned long r7)
+{
+       /* parse_bootinfo must always be called first */
+       parse_bootinfo(find_bootinfo());
+
+       /*
+        * If we were passed in a board information, copy it into the
+        * residual data area.
+        */
+       if (r3) {
+               memcpy((void *) __res, (void *) (r3 + KERNELBASE),
+                      sizeof (bd_t));
+       }
+#ifdef CONFIG_SERIAL_TEXT_DEBUG
+       {
+               bd_t *binfo = (bd_t *) __res;
+
+               /* Use the last TLB entry to map CCSRBAR to allow access to DUART regs */
+               settlbcam(NUM_TLBCAMS - 1, binfo->bi_immr_base,
+                         binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0);
+       }
+#endif
+
+#if defined(CONFIG_BLK_DEV_INITRD)
+       /*
+        * If the init RAM disk has been configured in, and there's a valid
+        * starting address for it, set it up.
+        */
+       if (r4) {
+               initrd_start = r4 + KERNELBASE;
+               initrd_end = r5 + KERNELBASE;
+       }
+#endif                         /* CONFIG_BLK_DEV_INITRD */
+
+       /* Copy the kernel command line arguments to a safe place. */
+
+       if (r6) {
+               *(char *) (r7 + KERNELBASE) = 0;
+               strcpy(cmd_line, (char *) (r6 + KERNELBASE));
+       }
+
+       /* setup the PowerPC module struct */
+       ppc_md.setup_arch = mpc8540ads_setup_arch;
+       ppc_md.show_cpuinfo = mpc85xx_ads_show_cpuinfo;
+
+       ppc_md.init_IRQ = mpc85xx_ads_init_IRQ;
+       ppc_md.get_irq = openpic_get_irq;
+
+       ppc_md.restart = mpc85xx_restart;
+       ppc_md.power_off = mpc85xx_power_off;
+       ppc_md.halt = mpc85xx_halt;
+
+       ppc_md.find_end_of_memory = mpc85xx_find_end_of_memory;
+
+       ppc_md.time_init = NULL;
+       ppc_md.set_rtc_time = NULL;
+       ppc_md.get_rtc_time = NULL;
+       ppc_md.calibrate_decr = mpc85xx_calibrate_decr;
+
+#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
+       ppc_md.progress = gen550_progress;
+#endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
+
+       if (ppc_md.progress)
+               ppc_md.progress("mpc8540ads_init(): exit", 0);
+
+       return;
+}
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.h b/arch/ppc/platforms/85xx/mpc8540_ads.h
new file mode 100644 (file)
index 0000000..9056361
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * arch/ppc/platforms/85xx/mpc8540_ads.h
+ *
+ * MPC8540ADS board definitions
+ *
+ * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ *
+ * Copyright 2004 Freescale Semiconductor 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.
+ *
+ */
+
+#ifndef __MACH_MPC8540ADS_H__
+#define __MACH_MPC8540ADS_H__
+
+#include <linux/config.h>
+#include <linux/serial.h>
+#include <linux/initrd.h>
+#include <syslib/ppc85xx_setup.h>
+#include <platforms/85xx/mpc85xx_ads_common.h>
+
+#define SERIAL_PORT_DFNS       \
+       STD_UART_OP(0)          \
+       STD_UART_OP(1)
+
+#endif /* __MACH_MPC8540ADS_H__ */
diff --git a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c
new file mode 100644 (file)
index 0000000..33aa1dc
--- /dev/null
@@ -0,0 +1,341 @@
+/*
+ * arch/ppc/syslib/ppc85xx_setup.c
+ *
+ * MPC85XX common board code
+ *
+ * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ *
+ * Copyright 2004 Freescale Semiconductor 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.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/serial.h>
+#include <linux/tty.h> /* for linux/serial_core.h */
+#include <linux/serial_core.h>
+
+#include <asm/prom.h>
+#include <asm/time.h>
+#include <asm/mpc85xx.h>
+#include <asm/immap_85xx.h>
+#include <asm/mmu.h>
+#include <asm/ocp.h>
+#include <asm/kgdb.h>
+
+/* Return the amount of memory */
+unsigned long __init
+mpc85xx_find_end_of_memory(void)
+{
+        bd_t *binfo;
+
+        binfo = (bd_t *) __res;
+
+        return binfo->bi_memsize;
+}
+
+/* The decrementer counts at the system (internal) clock freq divided by 8 */
+void __init
+mpc85xx_calibrate_decr(void)
+{
+        bd_t *binfo = (bd_t *) __res;
+        unsigned int freq, divisor;
+
+        /* get the core frequency */
+        freq = binfo->bi_busfreq;
+
+        /* The timebase is updated every 8 bus clocks, HID0[SEL_TBCLK] = 0 */
+        divisor = 8;
+        tb_ticks_per_jiffy = freq / divisor / HZ;
+        tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000);
+
+       /* Set the time base to zero */
+       mtspr(SPRN_TBWL, 0);
+       mtspr(SPRN_TBWU, 0);
+
+       /* Clear any pending timer interrupts */
+       mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
+
+       /* Enable decrementer interrupt */
+       mtspr(SPRN_TCR, TCR_DIE);
+}
+
+#ifdef CONFIG_SERIAL_8250
+void __init
+mpc85xx_early_serial_map(void)
+{
+       struct uart_port serial_req;
+       bd_t *binfo = (bd_t *) __res;
+       phys_addr_t duart_paddr = binfo->bi_immr_base + MPC85xx_UART0_OFFSET;
+
+       /* Setup serial port access */
+       memset(&serial_req, 0, sizeof (serial_req));
+       serial_req.uartclk = binfo->bi_busfreq;
+       serial_req.line = 0;
+       serial_req.irq = MPC85xx_IRQ_DUART;
+       serial_req.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+       serial_req.iotype = SERIAL_IO_MEM;
+       serial_req.membase = ioremap(duart_paddr, MPC85xx_UART0_SIZE);
+       serial_req.mapbase = duart_paddr;
+       serial_req.regshift = 0;
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+       gen550_init(0, &serial_req);
+#endif
+
+       if (early_serial_setup(&serial_req) != 0)
+               printk("Early serial init of port 0 failed\n");
+
+       /* Assume early_serial_setup() doesn't modify serial_req */
+       duart_paddr = binfo->bi_immr_base + MPC85xx_UART1_OFFSET;
+       serial_req.line = 1;
+       serial_req.mapbase = duart_paddr;
+       serial_req.membase = ioremap(duart_paddr, MPC85xx_UART1_SIZE);
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+       gen550_init(1, &serial_req);
+#endif
+
+       if (early_serial_setup(&serial_req) != 0)
+               printk("Early serial init of port 1 failed\n");
+}
+#endif
+
+void
+mpc85xx_restart(char *cmd)
+{
+       local_irq_disable();
+       abort();
+}
+
+void
+mpc85xx_power_off(void)
+{
+       local_irq_disable();
+       for(;;);
+}
+
+void
+mpc85xx_halt(void)
+{
+       local_irq_disable();
+       for(;;);
+}
+
+#ifdef CONFIG_PCI
+static void __init
+mpc85xx_setup_pci1(struct pci_controller *hose)
+{
+       volatile struct ccsr_pci *pci;
+       volatile struct ccsr_guts *guts;
+       unsigned short temps;
+       bd_t *binfo = (bd_t *) __res;
+
+       pci = ioremap(binfo->bi_immr_base + MPC85xx_PCI1_OFFSET,
+                   MPC85xx_PCI1_SIZE);
+
+       guts = ioremap(binfo->bi_immr_base + MPC85xx_GUTS_OFFSET,
+                   MPC85xx_GUTS_SIZE);
+
+       early_read_config_word(hose, 0, 0, PCI_COMMAND, &temps);
+       temps |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+       early_write_config_word(hose, 0, 0, PCI_COMMAND, temps);
+
+#define PORDEVSR_PCI   (0x00800000)    /* PCI Mode */
+       if (guts->pordevsr & PORDEVSR_PCI) {
+               early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80);
+       } else {
+               /* PCI-X init */
+               temps = PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ
+                       | PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E;
+               early_write_config_word(hose, 0, 0, PCIX_COMMAND, temps);
+       }
+
+       /* Disable all windows (except powar0 since its ignored) */
+       pci->powar1 = 0;
+       pci->powar2 = 0;
+       pci->powar3 = 0;
+       pci->powar4 = 0;
+       pci->piwar1 = 0;
+       pci->piwar2 = 0;
+       pci->piwar3 = 0;
+
+       /* Setup 512M Phys:PCI 1:1 outbound mem window @ 0x80000000 */
+       pci->potar1 = (MPC85XX_PCI1_LOWER_MEM >> 12) & 0x000fffff;
+       pci->potear1 = 0x00000000;
+       pci->powbar1 = (MPC85XX_PCI1_LOWER_MEM >> 12) & 0x000fffff;
+       pci->powar1 = 0x8004401c;       /* Enable, Mem R/W, 512M */
+
+       /* Setup 16M outboud IO windows @ 0xe2000000 */
+       pci->potar2 = 0x00000000;
+       pci->potear2 = 0x00000000;
+       pci->powbar2 = (MPC85XX_PCI1_IO_BASE >> 12) & 0x000fffff;
+       pci->powar2 = 0x80088017;       /* Enable, IO R/W, 16M */
+
+       /* Setup 2G inbound Memory Window @ 0 */
+       pci->pitar1 = 0x00000000;
+       pci->piwbar1 = 0x00000000;
+       pci->piwar1 = 0xa0f5501e;       /* Enable, Prefetch, Local
+                                          Mem, Snoop R/W, 2G */
+}
+
+
+extern int mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin);
+extern int mpc85xx_exclude_device(u_char bus, u_char devfn);
+
+#if CONFIG_85xx_PCI2
+static void __init
+mpc85xx_setup_pci2(struct pci_controller *hose)
+{
+       volatile struct ccsr_pci *pci;
+       unsigned short temps;
+       bd_t *binfo = (bd_t *) __res;
+
+       pci = ioremap(binfo->bi_immr_base + MPC85xx_PCI2_OFFSET,
+                   MPC85xx_PCI2_SIZE);
+
+       early_read_config_word(hose, 0, 0, PCI_COMMAND, &temps);
+       temps |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+       early_write_config_word(hose, 0, 0, PCI_COMMAND, temps);
+       early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80);
+
+       /* Disable all windows (except powar0 since its ignored) */
+       pci->powar1 = 0;
+       pci->powar2 = 0;
+       pci->powar3 = 0;
+       pci->powar4 = 0;
+       pci->piwar1 = 0;
+       pci->piwar2 = 0;
+       pci->piwar3 = 0;
+
+       /* Setup 512M Phys:PCI 1:1 outbound mem window @ 0xa0000000 */
+       pci->potar1 = (MPC85XX_PCI2_LOWER_MEM >> 12) & 0x000fffff;
+       pci->potear1 = 0x00000000;
+       pci->powbar1 = (MPC85XX_PCI2_LOWER_MEM >> 12) & 0x000fffff;
+       pci->powar1 = 0x8004401c;       /* Enable, Mem R/W, 512M */
+
+       /* Setup 16M outboud IO windows @ 0xe3000000 */
+       pci->potar2 = 0x00000000;
+       pci->potear2 = 0x00000000;
+       pci->powbar2 = (MPC85XX_PCI2_IO_BASE >> 12) & 0x000fffff;
+       pci->powar2 = 0x80088017;       /* Enable, IO R/W, 16M */
+
+       /* Setup 2G inbound Memory Window @ 0 */
+       pci->pitar1 = 0x00000000;
+       pci->piwbar1 = 0x00000000;
+       pci->piwar1 = 0xa0f5501e;       /* Enable, Prefetch, Local
+                                          Mem, Snoop R/W, 2G */
+}
+#endif /* CONFIG_85xx_PCI2 */
+
+void __init
+mpc85xx_setup_hose(void)
+{
+       struct pci_controller *hose_a;
+#ifdef CONFIG_85xx_PCI2
+       struct pci_controller *hose_b;
+#endif
+       bd_t *binfo = (bd_t *) __res;
+
+       hose_a = pcibios_alloc_controller();
+
+       if (!hose_a)
+               return;
+
+       ppc_md.pci_swizzle = common_swizzle;
+       ppc_md.pci_map_irq = mpc85xx_map_irq;
+
+       hose_a->first_busno = 0;
+       hose_a->bus_offset = 0;
+       hose_a->last_busno = 0xff;
+
+       setup_indirect_pci(hose_a, binfo->bi_immr_base + PCI1_CFG_ADDR_OFFSET,
+                          binfo->bi_immr_base + PCI1_CFG_DATA_OFFSET);
+       hose_a->set_cfg_type = 1;
+
+       mpc85xx_setup_pci1(hose_a);
+
+       hose_a->pci_mem_offset = MPC85XX_PCI1_MEM_OFFSET;
+       hose_a->mem_space.start = MPC85XX_PCI1_LOWER_MEM;
+       hose_a->mem_space.end = MPC85XX_PCI1_UPPER_MEM;
+
+       hose_a->io_space.start = MPC85XX_PCI1_LOWER_IO;
+       hose_a->io_space.end = MPC85XX_PCI1_UPPER_IO;
+       hose_a->io_base_phys = MPC85XX_PCI1_IO_BASE;
+#if CONFIG_85xx_PCI2
+       isa_io_base =
+               (unsigned long) ioremap(MPC85XX_PCI1_IO_BASE,
+                                       MPC85XX_PCI1_IO_SIZE +
+                                       MPC85XX_PCI2_IO_SIZE);
+#else
+       isa_io_base =
+               (unsigned long) ioremap(MPC85XX_PCI1_IO_BASE,
+                                       MPC85XX_PCI1_IO_SIZE);
+#endif
+       hose_a->io_base_virt = (void *) isa_io_base;
+
+       /* setup resources */
+       pci_init_resource(&hose_a->mem_resources[0],
+                       MPC85XX_PCI1_LOWER_MEM,
+                       MPC85XX_PCI1_UPPER_MEM,
+                       IORESOURCE_MEM, "PCI1 host bridge");
+
+       pci_init_resource(&hose_a->io_resource,
+                       MPC85XX_PCI1_LOWER_IO,
+                       MPC85XX_PCI1_UPPER_IO,
+                       IORESOURCE_IO, "PCI1 host bridge");
+
+       ppc_md.pci_exclude_device = mpc85xx_exclude_device;
+
+       hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno);
+
+#if CONFIG_85xx_PCI2
+       hose_b = pcibios_alloc_controller();
+
+       if (!hose_b)
+               return;
+
+       hose_b->bus_offset = hose_a->last_busno + 1;
+       hose_b->first_busno = hose_a->last_busno + 1;
+       hose_b->last_busno = 0xff;
+
+       setup_indirect_pci(hose_b, binfo->bi_immr_base + PCI2_CFG_ADDR_OFFSET,
+                          binfo->bi_immr_base + PCI2_CFG_DATA_OFFSET);
+       hose_b->set_cfg_type = 1;
+
+       mpc85xx_setup_pci2(hose_b);
+
+       hose_b->pci_mem_offset = MPC85XX_PCI2_MEM_OFFSET;
+       hose_b->mem_space.start = MPC85XX_PCI2_LOWER_MEM;
+       hose_b->mem_space.end = MPC85XX_PCI2_UPPER_MEM;
+
+       hose_b->io_space.start = MPC85XX_PCI2_LOWER_IO;
+       hose_b->io_space.end = MPC85XX_PCI2_UPPER_IO;
+       hose_b->io_base_phys = MPC85XX_PCI2_IO_BASE;
+       hose_b->io_base_virt = (void *) isa_io_base + MPC85XX_PCI1_IO_SIZE;
+
+       /* setup resources */
+       pci_init_resource(&hose_b->mem_resources[0],
+                       MPC85XX_PCI2_LOWER_MEM,
+                       MPC85XX_PCI2_UPPER_MEM,
+                       IORESOURCE_MEM, "PCI2 host bridge");
+
+       pci_init_resource(&hose_b->io_resource,
+                       MPC85XX_PCI2_LOWER_IO,
+                       MPC85XX_PCI2_UPPER_IO,
+                       IORESOURCE_IO, "PCI2 host bridge");
+
+       hose_b->last_busno = pciauto_bus_scan(hose_b, hose_b->first_busno);
+#endif
+       return;
+}
+#endif /* CONFIG_PCI */
+
+
diff --git a/arch/ppc/syslib/ppc85xx_setup.h b/arch/ppc/syslib/ppc85xx_setup.h
new file mode 100644 (file)
index 0000000..311b8a4
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * arch/ppc/syslib/ppc85xx_setup.h
+ *
+ * MPC85XX common board definitions
+ *
+ * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ *
+ * Copyright 2004 Freescale Semiconductor 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.
+ *
+ */
+
+#ifndef __PPC_SYSLIB_PPC85XX_SETUP_H
+#define __PPC_SYSLIB_PPC85XX_SETUP_H
+
+#include <linux/config.h>
+#include <linux/serial.h>
+#include <linux/init.h>
+#include <asm/ppcboot.h>
+
+extern unsigned long mpc85xx_find_end_of_memory(void) __init;
+extern void mpc85xx_calibrate_decr(void) __init;
+extern void mpc85xx_early_serial_map(void) __init;
+extern void mpc85xx_restart(char *cmd);
+extern void mpc85xx_power_off(void);
+extern void mpc85xx_halt(void);
+extern void mpc85xx_setup_hose(void) __init;
+
+/* PCI config */
+#define PCI1_CFG_ADDR_OFFSET   (0x8000)
+#define PCI1_CFG_DATA_OFFSET   (0x8004)
+
+#define PCI2_CFG_ADDR_OFFSET   (0x9000)
+#define PCI2_CFG_DATA_OFFSET   (0x9004)
+
+/* Additional register for PCI-X configuration */
+#define PCIX_NEXT_CAP  0x60
+#define PCIX_CAP_ID    0x61
+#define PCIX_COMMAND   0x62
+#define PCIX_STATUS    0x64
+
+/* Serial Config */
+#define MPC85XX_0_SERIAL                (CCSRBAR + 0x4500)
+#define MPC85XX_1_SERIAL                (CCSRBAR + 0x4600)
+
+#ifdef CONFIG_SERIAL_MANY_PORTS
+#define RS_TABLE_SIZE  64
+#else
+#define RS_TABLE_SIZE  2
+#endif
+
+#define BASE_BAUD 0
+
+#define STD_UART_OP(num)                                       \
+       { 0, BASE_BAUD, num, MPC85xx_IRQ_DUART,                 \
+               (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST),        \
+               iomem_base: (u8 *)MPC85XX_##num##_SERIAL,       \
+               io_type: SERIAL_IO_MEM},
+
+/* Offset of CPM register space */
+#define CPM_MAP_ADDR   (CCSRBAR + MPC85xx_CPM_OFFSET)
+
+#endif /* __PPC_SYSLIB_PPC85XX_SETUP_H */
diff --git a/configs/kernel-2.6.7-i586-smp.config b/configs/kernel-2.6.7-i586-smp.config
new file mode 100644 (file)
index 0000000..c1d4cfa
--- /dev/null
@@ -0,0 +1,2399 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_X86=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_GENERIC_ISA_DMA=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_STANDALONE=y
+
+#
+# General setup
+#
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_HOTPLUG=y
+# CONFIG_IKCONFIG is not set
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Processor type and features
+#
+CONFIG_X86_PC=y
+# CONFIG_X86_ELAN is not set
+# CONFIG_X86_VOYAGER is not set
+# CONFIG_X86_NUMAQ is not set
+# CONFIG_X86_SUMMIT is not set
+# CONFIG_X86_BIGSMP is not set
+# CONFIG_X86_VISWS is not set
+# CONFIG_X86_GENERICARCH is not set
+# CONFIG_X86_ES7000 is not set
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+CONFIG_M586=y
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+# CONFIG_M686 is not set
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+CONFIG_X86_GENERIC=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_XADD=y
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_X86_PPRO_FENCE=y
+CONFIG_X86_F00F_BUG=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_ALIGNMENT_16=y
+CONFIG_X86_INTEL_USERCOPY=y
+# CONFIG_X86_4G is not set
+# CONFIG_X86_SWITCH_PAGETABLES is not set
+# CONFIG_X86_4G_VM_LAYOUT is not set
+# CONFIG_X86_UACCESS_INDIRECT is not set
+# CONFIG_X86_HIGH_ENTRY is not set
+CONFIG_HPET_TIMER=y
+CONFIG_HPET_EMULATE_RTC=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=8
+CONFIG_SCHED_SMT=y
+# CONFIG_PREEMPT is not set
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_X86_IO_APIC=y
+CONFIG_X86_MCE=y
+# CONFIG_X86_MCE_NONFATAL is not set
+CONFIG_X86_MCE_P4THERMAL=y
+CONFIG_TOSHIBA=m
+CONFIG_I8K=m
+# CONFIG_MICROCODE is not set
+CONFIG_X86_MSR=m
+CONFIG_X86_CPUID=m
+
+#
+# Firmware Drivers
+#
+CONFIG_EDD=m
+# CONFIG_NOHIGHMEM is not set
+CONFIG_HIGHMEM4G=y
+# CONFIG_HIGHMEM64G is not set
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+# CONFIG_MATH_EMULATION is not set
+CONFIG_MTRR=y
+# CONFIG_EFI is not set
+# CONFIG_IRQBALANCE is not set
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_REGPARM=y
+
+#
+# Power management options (ACPI, APM)
+#
+CONFIG_PM=y
+# CONFIG_SOFTWARE_SUSPEND is not set
+# CONFIG_PM_DISK is not set
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_BOOT=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_SLEEP=y
+CONFIG_ACPI_SLEEP_PROC_FS=y
+CONFIG_ACPI_AC=m
+CONFIG_ACPI_BATTERY=m
+CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_ASUS=m
+CONFIG_ACPI_TOSHIBA=m
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_BUS=y
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_PCI=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_X86_PM_TIMER=y
+
+#
+# APM (Advanced Power Management) BIOS Support
+#
+CONFIG_APM=y
+# CONFIG_APM_IGNORE_USER_SUSPEND is not set
+# CONFIG_APM_DO_ENABLE is not set
+CONFIG_APM_CPU_IDLE=y
+# CONFIG_APM_DISPLAY_BLANK is not set
+CONFIG_APM_RTC_IS_GMT=y
+# CONFIG_APM_ALLOW_INTS is not set
+# CONFIG_APM_REAL_MODE_POWER_OFF is not set
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+# CONFIG_CPU_FREQ_PROC_INTF is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_24_API is not set
+CONFIG_CPU_FREQ_TABLE=y
+
+#
+# CPUFreq processor drivers
+#
+CONFIG_X86_ACPI_CPUFREQ=m
+# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
+CONFIG_X86_POWERNOW_K6=m
+CONFIG_X86_POWERNOW_K7=y
+CONFIG_X86_POWERNOW_K8=m
+# CONFIG_X86_GX_SUSPMOD is not set
+CONFIG_X86_SPEEDSTEP_CENTRINO=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI=y
+CONFIG_X86_SPEEDSTEP_ICH=y
+CONFIG_X86_SPEEDSTEP_SMI=m
+CONFIG_X86_P4_CLOCKMOD=m
+CONFIG_X86_SPEEDSTEP_LIB=y
+# CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK is not set
+CONFIG_X86_LONGRUN=y
+# CONFIG_X86_LONGHAUL is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GOMMCONFIG is not set
+# CONFIG_PCI_GODIRECT is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+CONFIG_PCI_USE_VECTOR=y
+CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_NAMES is not set
+CONFIG_ISA=y
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SCx200 is not set
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_YENTA=m
+CONFIG_CARDBUS=y
+CONFIG_I82092=m
+CONFIG_I82365=m
+CONFIG_TCIC=m
+CONFIG_PCMCIA_PROBE=y
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+# CONFIG_HOTPLUG_PCI_FAKE is not set
+CONFIG_HOTPLUG_PCI_COMPAQ=m
+# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+CONFIG_HOTPLUG_PCI_IBM=m
+# CONFIG_HOTPLUG_PCI_ACPI is not set
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+CONFIG_HOTPLUG_PCI_PCIE=m
+CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE=y
+CONFIG_HOTPLUG_PCI_SHPC=m
+CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE=y
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=m
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_CMDLINE_PARTS=m
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PNC2000 is not set
+CONFIG_MTD_SC520CDP=m
+CONFIG_MTD_NETSC520=m
+CONFIG_MTD_SBC_GXX=m
+CONFIG_MTD_ELAN_104NC=m
+CONFIG_MTD_SCx200_DOCFLASH=m
+CONFIG_MTD_AMD76XROM=m
+CONFIG_MTD_ICH2ROM=m
+CONFIG_MTD_SCB2_FLASH=m
+# CONFIG_MTD_NETtel is not set
+# CONFIG_MTD_DILNETPC is not set
+CONFIG_MTD_L440GX=m
+CONFIG_MTD_PCI=m
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+# CONFIG_MTD_SLRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+CONFIG_MTD_DOC2000=m
+# CONFIG_MTD_DOC2001 is not set
+CONFIG_MTD_DOC2001PLUS=m
+CONFIG_MTD_DOCPROBE=m
+# CONFIG_MTD_DOCPROBE_ADVANCED is not set
+CONFIG_MTD_DOCPROBE_ADDRESS=0
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_IDS=m
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_PC_CML1=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+# CONFIG_PARPORT_OTHER is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_ISAPNP=y
+# CONFIG_PNPBIOS is not set
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_CARMEL=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_LBD=y
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDETAPE=m
+CONFIG_BLK_DEV_IDEFLOPPY=y
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+# CONFIG_IDE_TASKFILE_IO is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_CMD640 is not set
+CONFIG_BLK_DEV_IDEPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_RZ1000=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_ADMA=y
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_ATIIXP=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+CONFIG_BLK_DEV_CY82C693=y
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_PDC202XX_FORCE=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+CONFIG_BLK_DEV_SLC90E66=y
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+# CONFIG_SCSI_7000FASST is not set
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AHA152X=m
+CONFIG_SCSI_AHA1542=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_BUILD_FIRMWARE is not set
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_DPT_I2O is not set
+CONFIG_SCSI_ADVANSYS=m
+CONFIG_SCSI_IN2000=m
+CONFIG_SCSI_MEGARAID=m
+CONFIG_SCSI_SATA=y
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+CONFIG_SCSI_FUTURE_DOMAIN=m
+CONFIG_SCSI_GDTH=m
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+# CONFIG_SCSI_NCR53C406A is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PSI240I is not set
+CONFIG_SCSI_QLOGIC_FAS=m
+CONFIG_SCSI_QLOGIC_ISP=m
+# CONFIG_SCSI_QLOGIC_FC is not set
+CONFIG_SCSI_QLOGIC_1280=m
+CONFIG_SCSI_QLA2XXX=m
+CONFIG_SCSI_QLA21XX=m
+CONFIG_SCSI_QLA22XX=m
+CONFIG_SCSI_QLA2300=m
+CONFIG_SCSI_QLA2322=m
+CONFIG_SCSI_QLA6312=m
+CONFIG_SCSI_QLA6322=m
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC395x is not set
+CONFIG_SCSI_DC390T=m
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+CONFIG_PCMCIA_AHA152X=m
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_NINJA_SCSI=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID5=m
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=m
+CONFIG_FUSION_MAX_SGE=40
+# CONFIG_FUSION_ISENSE is not set
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set
+
+#
+# Device Drivers
+#
+# CONFIG_IEEE1394_PCILYNX is not set
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
+# CONFIG_IEEE1394_ETH1394 is not set
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+CONFIG_IEEE1394_CMP=m
+CONFIG_IEEE1394_AMDTP=m
+
+#
+# I2O device support
+#
+CONFIG_I2O=m
+CONFIG_I2O_CONFIG=m
+CONFIG_I2O_BLOCK=m
+CONFIG_I2O_SCSI=m
+CONFIG_I2O_PROC=m
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_FWMARK=y
+CONFIG_IP_ROUTE_NAT=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_TOS=y
+CONFIG_IP_ROUTE_VERBOSE=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_PHYSDEV=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_LOCAL=y
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_RAW=m
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_IP6_NF_QUEUE is not set
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_LIMIT=m
+CONFIG_IP6_NF_MATCH_MAC=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_MARK=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AHESP=m
+CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_RAW=m
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_ATM is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=y
+CONFIG_LTPC=m
+CONFIG_COPS=m
+CONFIG_COPS_DAYNA=y
+CONFIG_COPS_TANGENT=y
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+CONFIG_NET_DIVERT=y
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=m
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_CSZ=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_DELAY=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+# CONFIG_WINBOND_FIR is not set
+# CONFIG_TOSHIBA_FIR is not set
+# CONFIG_SMC_IRCC_FIR is not set
+# CONFIG_ALI_FIR is not set
+# CONFIG_VLSI_FIR is not set
+# CONFIG_VIA_FIR is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_BCSP_TXCRC=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+# CONFIG_TUX_EXTENDED_LOG is not set
+# CONFIG_TUX_DEBUG is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_ETHERTAP=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_EL1=m
+CONFIG_EL2=m
+CONFIG_ELPLUS=m
+CONFIG_EL16=m
+CONFIG_EL3=m
+CONFIG_3C515=m
+CONFIG_VORTEX=m
+# CONFIG_TYPHOON is not set
+CONFIG_LANCE=m
+CONFIG_NET_VENDOR_SMC=y
+CONFIG_WD80x3=m
+CONFIG_ULTRA=m
+CONFIG_SMC9194=m
+CONFIG_NET_VENDOR_RACAL=y
+CONFIG_NI52=m
+CONFIG_NI65=m
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_AT1700 is not set
+CONFIG_DEPCA=m
+CONFIG_HP100=m
+# CONFIG_NET_ISA is not set
+CONFIG_NE2000=m
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+CONFIG_AC3200=m
+CONFIG_APRICOT=m
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+CONFIG_CS89x0=m
+CONFIG_DGRS=m
+CONFIG_EEPRO100=m
+# CONFIG_EEPRO100_PIO is not set
+CONFIG_E100=m
+CONFIG_E100_NAPI=y
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+CONFIG_8139TOO_PIO=y
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_TLAN=m
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_VELOCITY=m
+CONFIG_NET_POCKET=y
+CONFIG_ATP=m
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_SK98LIN=m
+CONFIG_TIGON3=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_ARLAN is not set
+CONFIG_WAVELAN=m
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+CONFIG_HISAX_16_0=y
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_TELESPCI=y
+CONFIG_HISAX_S0BOX=y
+CONFIG_HISAX_AVM_A1=y
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+CONFIG_HISAX_IX1MICROR2=y
+CONFIG_HISAX_DIEHLDIVA=y
+CONFIG_HISAX_ASUSCOM=y
+CONFIG_HISAX_TELEINT=y
+CONFIG_HISAX_HFCS=y
+CONFIG_HISAX_SEDLBAUER=y
+CONFIG_HISAX_SPORTSTER=y
+CONFIG_HISAX_MIC=y
+CONFIG_HISAX_NETJET=y
+CONFIG_HISAX_NETJET_U=y
+CONFIG_HISAX_NICCY=y
+CONFIG_HISAX_ISURF=y
+CONFIG_HISAX_HSTSAPHIR=y
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_HFC_PCI=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+CONFIG_HISAX_ENTERNOW_PCI=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+CONFIG_HISAX_HFCUSB=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+CONFIG_ISDN_DRV_ICN=m
+CONFIG_ISDN_DRV_PCBIT=m
+CONFIG_ISDN_DRV_SC=m
+CONFIG_ISDN_DRV_ACT2000=m
+CONFIG_ISDN_DRV_TPAM=m
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+
+#
+# Active Eicon DIVA Server cards
+#
+CONFIG_CAPI_EICON=y
+CONFIG_ISDN_DIVAS=m
+CONFIG_ISDN_DIVAS_BRIPCI=y
+CONFIG_ISDN_DIVAS_PRIPCI=y
+CONFIG_ISDN_DIVAS_DIVACAPI=m
+CONFIG_ISDN_DIVAS_USERIDI=m
+CONFIG_ISDN_DIVAS_MAINT=m
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_JOYDEV=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+CONFIG_GAMEPORT=m
+CONFIG_SOUND_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_VORTEX=m
+CONFIG_GAMEPORT_FM801=m
+CONFIG_GAMEPORT_CS461x=m
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_INPORT=m
+CONFIG_MOUSE_ATIXL=y
+CONFIG_MOUSE_LOGIBM=m
+CONFIG_MOUSE_PC110PAD=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDDLER=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+# CONFIG_INPUT_JOYDUMP is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+# CONFIG_INPUT_UINPUT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_SERIAL_NONSTANDARD=y
+CONFIG_ROCKETPORT=m
+# CONFIG_CYCLADES is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_N_HDLC=m
+CONFIG_STALDRV=y
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_CS=m
+# CONFIG_SERIAL_8250_ACPI is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_MULTIPORT=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_CRASH=m
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+# CONFIG_QIC02_TAPE is not set
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_ACQUIRE_WDT=m
+CONFIG_ADVANTECH_WDT=m
+CONFIG_ALIM1535_WDT=m
+CONFIG_ALIM7101_WDT=m
+CONFIG_SC520_WDT=m
+CONFIG_EUROTECH_WDT=m
+CONFIG_IB700_WDT=m
+CONFIG_WAFER_WDT=m
+CONFIG_I8XX_TCO=m
+CONFIG_SC1200_WDT=m
+# CONFIG_SCx200_WDT is not set
+# CONFIG_60XX_WDT is not set
+CONFIG_CPU5_WDT=m
+CONFIG_W83627HF_WDT=m
+CONFIG_W83877F_WDT=m
+CONFIG_MACHZ_WDT=m
+
+#
+# ISA-based Watchdog Cards
+#
+CONFIG_PCWATCHDOG=m
+# CONFIG_MIXCOMWD is not set
+CONFIG_WDT=m
+# CONFIG_WDT_501 is not set
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_HW_RANDOM=m
+CONFIG_NVRAM=m
+CONFIG_RTC=y
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+CONFIG_SONYPI=m
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_AGP=y
+CONFIG_AGP_ALI=y
+CONFIG_AGP_ATI=y
+CONFIG_AGP_AMD=y
+CONFIG_AGP_AMD64=y
+CONFIG_AGP_INTEL=y
+CONFIG_AGP_INTEL_MCH=y
+CONFIG_AGP_NVIDIA=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_SWORKS=y
+CONFIG_AGP_VIA=y
+CONFIG_AGP_EFFICEON=y
+CONFIG_DRM=y
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_GAMMA=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_I810=m
+CONFIG_DRM_I830=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+
+#
+# PCMCIA character devices
+#
+CONFIG_SYNCLINK_CS=m
+CONFIG_MWAVE=m
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HPET is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_ALI1535=m
+CONFIG_I2C_ALI1563=m
+CONFIG_I2C_ALI15X3=m
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD8111=m
+CONFIG_I2C_I801=m
+CONFIG_I2C_I810=m
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_PARPORT is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_SCx200_ACB is not set
+CONFIG_I2C_SIS5595=m
+CONFIG_I2C_SIS630=m
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_VOODOO3=m
+
+#
+# Hardware Sensors Chip support
+#
+CONFIG_I2C_SENSOR=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+
+#
+# Other I2C Chip support
+#
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_RTC8564=m
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+CONFIG_IBM_ASM=m
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+
+#
+# Video For Linux
+#
+
+#
+# Video Adapters
+#
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_PMS=m
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_MEYE=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88=m
+
+#
+# Radio Adapters
+#
+CONFIG_RADIO_CADET=m
+CONFIG_RADIO_RTRACK=m
+CONFIG_RADIO_RTRACK2=m
+CONFIG_RADIO_AZTECH=m
+CONFIG_RADIO_GEMTEK=m
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+CONFIG_RADIO_SF16FMI=m
+CONFIG_RADIO_SF16FMR2=m
+CONFIG_RADIO_TERRATEC=m
+CONFIG_RADIO_TRUST=m
+CONFIG_RADIO_TYPHOON=m
+CONFIG_RADIO_TYPHOON_PROC_FS=y
+CONFIG_RADIO_ZOLTRIX=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported Frontend Modules
+#
+CONFIG_DVB_TWINHAN_DST=m
+CONFIG_DVB_STV0299=m
+# CONFIG_DVB_SP887X is not set
+# CONFIG_DVB_ALPS_TDLB7 is not set
+CONFIG_DVB_ALPS_TDMB7=m
+CONFIG_DVB_ATMEL_AT76C651=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_GRUNDIG_29504_491=m
+CONFIG_DVB_GRUNDIG_29504_401=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_VES1X93=m
+# CONFIG_DVB_TDA1004X is not set
+CONFIG_DVB_NXT6000=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_SKYSTAR=m
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_VGA16=m
+CONFIG_FB_VESA=y
+CONFIG_VIDEO_SELECT=y
+CONFIG_FB_HGA=m
+CONFIG_FB_HGA_ACCEL=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+CONFIG_FB_I810=m
+CONFIG_FB_I810_GTF=y
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G450=y
+CONFIG_FB_MATROX_G100=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+# CONFIG_FB_RADEON_OLD is not set
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GX=y
+# CONFIG_FB_ATY_XL_INIT is not set
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_MDA_CONSOLE=m
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_PCI_CONSOLE=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_RTCTIMER=m
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_OPL4_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# ISA devices
+#
+CONFIG_SND_AD1816A=m
+CONFIG_SND_AD1848=m
+CONFIG_SND_CS4231=m
+CONFIG_SND_CS4232=m
+CONFIG_SND_CS4236=m
+CONFIG_SND_ES968=m
+CONFIG_SND_ES1688=m
+CONFIG_SND_ES18XX=m
+CONFIG_SND_GUSCLASSIC=m
+CONFIG_SND_GUSEXTREME=m
+CONFIG_SND_GUSMAX=m
+CONFIG_SND_INTERWAVE=m
+CONFIG_SND_INTERWAVE_STB=m
+CONFIG_SND_OPTI92X_AD1848=m
+CONFIG_SND_OPTI92X_CS4231=m
+CONFIG_SND_OPTI93X=m
+CONFIG_SND_SB8=m
+CONFIG_SND_SB16=m
+CONFIG_SND_SBAWE=m
+CONFIG_SND_SB16_CSP=y
+# CONFIG_SND_WAVEFRONT is not set
+CONFIG_SND_ALS100=m
+CONFIG_SND_AZT2320=m
+CONFIG_SND_CMI8330=m
+CONFIG_SND_DT019X=m
+CONFIG_SND_OPL3SA2=m
+CONFIG_SND_SGALAXY=m
+CONFIG_SND_SSCAPE=m
+
+#
+# PCI devices
+#
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_CS4281=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_YMFPCI=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VX222=m
+
+#
+# ALSA USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_VXP440 is not set
+CONFIG_SND_PDAUDIOCF=m
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_UHCI_HCD=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_AUDIO=m
+
+#
+# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
+#
+CONFIG_USB_MIDI=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_RW_DETECT=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_HP8200e=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_MTOUCH=m
+CONFIG_USB_EGALAX=m
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_HPUSBSCSI=m
+
+#
+# USB Multimedia devices
+#
+CONFIG_USB_DABUSB=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_DSBR=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_STV680=m
+CONFIG_USB_W9968CF=m
+
+#
+# USB Network adaptors
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+
+#
+# USB Host-to-Host Cables
+#
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_GENESYS=y
+CONFIG_USB_NET1080=y
+CONFIG_USB_PL2301=y
+
+#
+# Intelligent USB Devices/Gadgets
+#
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_ZAURUS=y
+CONFIG_USB_CDCETHER=y
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_AX8817X=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_SAFE=m
+CONFIG_USB_SERIAL_SAFE_PADDED=y
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+# CONFIG_USB_EMI26 is not set
+CONFIG_USB_TIGL=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_TEST=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_NAND=y
+CONFIG_CRAMFS=m
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+# CONFIG_QNX4FS_RW is not set
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_FRAME_POINTER is not set
+CONFIG_X86_FIND_SMP_CONFIG=y
+CONFIG_X86_MPPARSE=y
+
+#
+# Security options
+#
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+# CONFIG_SECURITY_SELINUX_MLS is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Library routines
+#
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_X86_SMP=y
+CONFIG_X86_HT=y
+CONFIG_X86_BIOS_REBOOT=y
+CONFIG_X86_TRAMPOLINE=y
+CONFIG_PC=y
diff --git a/configs/kernel-2.6.7-i586.config b/configs/kernel-2.6.7-i586.config
new file mode 100644 (file)
index 0000000..9c0db66
--- /dev/null
@@ -0,0 +1,2416 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_X86=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_GENERIC_ISA_DMA=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_STANDALONE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_HOTPLUG=y
+# CONFIG_IKCONFIG is not set
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Processor type and features
+#
+CONFIG_X86_PC=y
+# CONFIG_X86_ELAN is not set
+# CONFIG_X86_VOYAGER is not set
+# CONFIG_X86_NUMAQ is not set
+# CONFIG_X86_SUMMIT is not set
+# CONFIG_X86_BIGSMP is not set
+# CONFIG_X86_VISWS is not set
+# CONFIG_X86_GENERICARCH is not set
+# CONFIG_X86_ES7000 is not set
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+CONFIG_M586=y
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+# CONFIG_M686 is not set
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+CONFIG_X86_GENERIC=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_XADD=y
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_X86_PPRO_FENCE=y
+CONFIG_X86_F00F_BUG=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_ALIGNMENT_16=y
+CONFIG_X86_INTEL_USERCOPY=y
+# CONFIG_X86_4G is not set
+# CONFIG_X86_SWITCH_PAGETABLES is not set
+# CONFIG_X86_4G_VM_LAYOUT is not set
+# CONFIG_X86_UACCESS_INDIRECT is not set
+# CONFIG_X86_HIGH_ENTRY is not set
+CONFIG_HPET_TIMER=y
+CONFIG_HPET_EMULATE_RTC=y
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_X86_UP_APIC is not set
+CONFIG_X86_MCE=y
+# CONFIG_X86_MCE_NONFATAL is not set
+CONFIG_TOSHIBA=m
+CONFIG_I8K=m
+# CONFIG_MICROCODE is not set
+CONFIG_X86_MSR=m
+CONFIG_X86_CPUID=m
+
+#
+# Firmware Drivers
+#
+CONFIG_EDD=m
+# CONFIG_NOHIGHMEM is not set
+CONFIG_HIGHMEM4G=y
+# CONFIG_HIGHMEM64G is not set
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+# CONFIG_MATH_EMULATION is not set
+CONFIG_MTRR=y
+# CONFIG_EFI is not set
+CONFIG_REGPARM=y
+
+#
+# Power management options (ACPI, APM)
+#
+CONFIG_PM=y
+# CONFIG_SOFTWARE_SUSPEND is not set
+# CONFIG_PM_DISK is not set
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_BOOT=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_SLEEP=y
+CONFIG_ACPI_SLEEP_PROC_FS=y
+CONFIG_ACPI_AC=m
+CONFIG_ACPI_BATTERY=m
+CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_ASUS=m
+CONFIG_ACPI_TOSHIBA=m
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_BUS=y
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_PCI=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_X86_PM_TIMER=y
+
+#
+# APM (Advanced Power Management) BIOS Support
+#
+CONFIG_APM=y
+# CONFIG_APM_IGNORE_USER_SUSPEND is not set
+# CONFIG_APM_DO_ENABLE is not set
+CONFIG_APM_CPU_IDLE=y
+# CONFIG_APM_DISPLAY_BLANK is not set
+CONFIG_APM_RTC_IS_GMT=y
+# CONFIG_APM_ALLOW_INTS is not set
+# CONFIG_APM_REAL_MODE_POWER_OFF is not set
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+# CONFIG_CPU_FREQ_PROC_INTF is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_24_API is not set
+CONFIG_CPU_FREQ_TABLE=y
+
+#
+# CPUFreq processor drivers
+#
+CONFIG_X86_ACPI_CPUFREQ=m
+# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
+CONFIG_X86_POWERNOW_K6=m
+CONFIG_X86_POWERNOW_K7=y
+CONFIG_X86_POWERNOW_K8=m
+# CONFIG_X86_GX_SUSPMOD is not set
+CONFIG_X86_SPEEDSTEP_CENTRINO=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI=y
+CONFIG_X86_SPEEDSTEP_ICH=y
+CONFIG_X86_SPEEDSTEP_SMI=m
+CONFIG_X86_P4_CLOCKMOD=m
+CONFIG_X86_SPEEDSTEP_LIB=y
+# CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK is not set
+CONFIG_X86_LONGRUN=y
+# CONFIG_X86_LONGHAUL is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GOMMCONFIG is not set
+# CONFIG_PCI_GODIRECT is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_NAMES is not set
+CONFIG_ISA=y
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SCx200 is not set
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_YENTA=m
+CONFIG_CARDBUS=y
+CONFIG_I82092=m
+CONFIG_I82365=m
+CONFIG_TCIC=m
+CONFIG_PCMCIA_PROBE=y
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+# CONFIG_HOTPLUG_PCI_FAKE is not set
+CONFIG_HOTPLUG_PCI_COMPAQ=m
+# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_ACPI is not set
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+CONFIG_HOTPLUG_PCI_PCIE=m
+CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE=y
+CONFIG_HOTPLUG_PCI_SHPC=m
+CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE=y
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=m
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_CMDLINE_PARTS=m
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PNC2000 is not set
+CONFIG_MTD_SC520CDP=m
+CONFIG_MTD_NETSC520=m
+CONFIG_MTD_SBC_GXX=m
+CONFIG_MTD_ELAN_104NC=m
+CONFIG_MTD_SCx200_DOCFLASH=m
+CONFIG_MTD_AMD76XROM=m
+CONFIG_MTD_ICH2ROM=m
+CONFIG_MTD_SCB2_FLASH=m
+# CONFIG_MTD_NETtel is not set
+# CONFIG_MTD_DILNETPC is not set
+CONFIG_MTD_L440GX=m
+CONFIG_MTD_PCI=m
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+# CONFIG_MTD_SLRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+CONFIG_MTD_DOC2000=m
+# CONFIG_MTD_DOC2001 is not set
+CONFIG_MTD_DOC2001PLUS=m
+CONFIG_MTD_DOCPROBE=m
+# CONFIG_MTD_DOCPROBE_ADVANCED is not set
+CONFIG_MTD_DOCPROBE_ADDRESS=0
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_IDS=m
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_PC_CML1=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+# CONFIG_PARPORT_OTHER is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_ISAPNP=y
+# CONFIG_PNPBIOS is not set
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_CARMEL=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_LBD=y
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDETAPE=m
+CONFIG_BLK_DEV_IDEFLOPPY=y
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+# CONFIG_IDE_TASKFILE_IO is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_CMD640 is not set
+CONFIG_BLK_DEV_IDEPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_RZ1000=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_ADMA=y
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_ATIIXP=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+CONFIG_BLK_DEV_CY82C693=y
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_PDC202XX_FORCE=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+CONFIG_BLK_DEV_SLC90E66=y
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+# CONFIG_SCSI_7000FASST is not set
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AHA152X=m
+CONFIG_SCSI_AHA1542=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_BUILD_FIRMWARE is not set
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_DPT_I2O is not set
+CONFIG_SCSI_ADVANSYS=m
+CONFIG_SCSI_IN2000=m
+CONFIG_SCSI_MEGARAID=m
+CONFIG_SCSI_SATA=y
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+CONFIG_SCSI_FUTURE_DOMAIN=m
+CONFIG_SCSI_GDTH=m
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+# CONFIG_SCSI_NCR53C406A is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PSI240I is not set
+CONFIG_SCSI_QLOGIC_FAS=m
+CONFIG_SCSI_QLOGIC_ISP=m
+# CONFIG_SCSI_QLOGIC_FC is not set
+CONFIG_SCSI_QLOGIC_1280=m
+CONFIG_SCSI_QLA2XXX=m
+CONFIG_SCSI_QLA21XX=m
+CONFIG_SCSI_QLA22XX=m
+CONFIG_SCSI_QLA2300=m
+CONFIG_SCSI_QLA2322=m
+CONFIG_SCSI_QLA6312=m
+CONFIG_SCSI_QLA6322=m
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC395x is not set
+CONFIG_SCSI_DC390T=m
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+CONFIG_PCMCIA_AHA152X=m
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_NINJA_SCSI=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID5=m
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=m
+CONFIG_FUSION_MAX_SGE=40
+# CONFIG_FUSION_ISENSE is not set
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set
+
+#
+# Device Drivers
+#
+# CONFIG_IEEE1394_PCILYNX is not set
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
+# CONFIG_IEEE1394_ETH1394 is not set
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+CONFIG_IEEE1394_CMP=m
+CONFIG_IEEE1394_AMDTP=m
+
+#
+# I2O device support
+#
+CONFIG_I2O=m
+CONFIG_I2O_CONFIG=m
+CONFIG_I2O_BLOCK=m
+CONFIG_I2O_SCSI=m
+CONFIG_I2O_PROC=m
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_FWMARK=y
+CONFIG_IP_ROUTE_NAT=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_TOS=y
+CONFIG_IP_ROUTE_VERBOSE=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_PHYSDEV=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_LOCAL=y
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_RAW=m
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_IP6_NF_QUEUE is not set
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_LIMIT=m
+CONFIG_IP6_NF_MATCH_MAC=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_MARK=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AHESP=m
+CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_RAW=m
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_ATM is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=y
+CONFIG_LTPC=m
+CONFIG_COPS=m
+CONFIG_COPS_DAYNA=y
+CONFIG_COPS_TANGENT=y
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+CONFIG_NET_DIVERT=y
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=m
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_CSZ=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_DELAY=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+CONFIG_IRPORT_SIR=m
+
+#
+# Old Serial dongle support
+#
+# CONFIG_DONGLE_OLD is not set
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+# CONFIG_WINBOND_FIR is not set
+# CONFIG_TOSHIBA_FIR is not set
+# CONFIG_SMC_IRCC_FIR is not set
+# CONFIG_ALI_FIR is not set
+# CONFIG_VLSI_FIR is not set
+# CONFIG_VIA_FIR is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_BCSP_TXCRC=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+# CONFIG_TUX_EXTENDED_LOG is not set
+# CONFIG_TUX_DEBUG is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_ETHERTAP=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_EL1=m
+CONFIG_EL2=m
+CONFIG_ELPLUS=m
+CONFIG_EL16=m
+CONFIG_EL3=m
+CONFIG_3C515=m
+CONFIG_VORTEX=m
+# CONFIG_TYPHOON is not set
+CONFIG_LANCE=m
+CONFIG_NET_VENDOR_SMC=y
+CONFIG_WD80x3=m
+CONFIG_ULTRA=m
+CONFIG_SMC9194=m
+CONFIG_NET_VENDOR_RACAL=y
+# CONFIG_NI5010 is not set
+CONFIG_NI52=m
+CONFIG_NI65=m
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_PCMCIA_XIRTULIP is not set
+# CONFIG_AT1700 is not set
+CONFIG_DEPCA=m
+CONFIG_HP100=m
+# CONFIG_NET_ISA is not set
+CONFIG_NE2000=m
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+CONFIG_AC3200=m
+CONFIG_APRICOT=m
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+CONFIG_CS89x0=m
+CONFIG_DGRS=m
+CONFIG_EEPRO100=m
+# CONFIG_EEPRO100_PIO is not set
+CONFIG_E100=m
+CONFIG_E100_NAPI=y
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+CONFIG_8139TOO_PIO=y
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_TLAN=m
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_VELOCITY=m
+CONFIG_NET_POCKET=y
+CONFIG_ATP=m
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_SK98LIN=m
+CONFIG_TIGON3=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_ARLAN is not set
+CONFIG_WAVELAN=m
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DRV_LOOP=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+CONFIG_HISAX_16_0=y
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_TELESPCI=y
+CONFIG_HISAX_S0BOX=y
+CONFIG_HISAX_AVM_A1=y
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+CONFIG_HISAX_IX1MICROR2=y
+CONFIG_HISAX_DIEHLDIVA=y
+CONFIG_HISAX_ASUSCOM=y
+CONFIG_HISAX_TELEINT=y
+CONFIG_HISAX_HFCS=y
+CONFIG_HISAX_SEDLBAUER=y
+CONFIG_HISAX_SPORTSTER=y
+CONFIG_HISAX_MIC=y
+CONFIG_HISAX_NETJET=y
+CONFIG_HISAX_NETJET_U=y
+CONFIG_HISAX_NICCY=y
+CONFIG_HISAX_ISURF=y
+CONFIG_HISAX_HSTSAPHIR=y
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_HFC_PCI=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+CONFIG_HISAX_ENTERNOW_PCI=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+CONFIG_HISAX_HFCUSB=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+CONFIG_ISDN_DRV_ICN=m
+CONFIG_ISDN_DRV_PCBIT=m
+CONFIG_ISDN_DRV_SC=m
+CONFIG_ISDN_DRV_ACT2000=m
+CONFIG_ISDN_DRV_TPAM=m
+CONFIG_HYSDN=m
+CONFIG_HYSDN_CAPI=y
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+CONFIG_ISDN_DRV_AVMB1_B1ISA=m
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+CONFIG_ISDN_DRV_AVMB1_T1ISA=m
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+CONFIG_CAPI_EICON=y
+CONFIG_ISDN_DIVAS=m
+CONFIG_ISDN_DIVAS_BRIPCI=y
+CONFIG_ISDN_DIVAS_PRIPCI=y
+CONFIG_ISDN_DIVAS_DIVACAPI=m
+CONFIG_ISDN_DIVAS_USERIDI=m
+CONFIG_ISDN_DIVAS_MAINT=m
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_JOYDEV=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+CONFIG_GAMEPORT=m
+CONFIG_SOUND_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_VORTEX=m
+CONFIG_GAMEPORT_FM801=m
+CONFIG_GAMEPORT_CS461x=m
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_INPORT=m
+CONFIG_MOUSE_ATIXL=y
+CONFIG_MOUSE_LOGIBM=m
+CONFIG_MOUSE_PC110PAD=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDDLER=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+# CONFIG_INPUT_JOYDUMP is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+# CONFIG_INPUT_UINPUT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+CONFIG_ROCKETPORT=m
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_N_HDLC=m
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+CONFIG_STALDRV=y
+# CONFIG_STALLION is not set
+# CONFIG_ISTALLION is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_CS=m
+# CONFIG_SERIAL_8250_ACPI is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_MULTIPORT=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_CRASH=m
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+# CONFIG_QIC02_TAPE is not set
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_ACQUIRE_WDT=m
+CONFIG_ADVANTECH_WDT=m
+CONFIG_ALIM1535_WDT=m
+CONFIG_ALIM7101_WDT=m
+CONFIG_SC520_WDT=m
+CONFIG_EUROTECH_WDT=m
+CONFIG_IB700_WDT=m
+CONFIG_WAFER_WDT=m
+CONFIG_I8XX_TCO=m
+CONFIG_SC1200_WDT=m
+# CONFIG_SCx200_WDT is not set
+# CONFIG_60XX_WDT is not set
+CONFIG_CPU5_WDT=m
+CONFIG_W83627HF_WDT=m
+CONFIG_W83877F_WDT=m
+CONFIG_MACHZ_WDT=m
+
+#
+# ISA-based Watchdog Cards
+#
+CONFIG_PCWATCHDOG=m
+# CONFIG_MIXCOMWD is not set
+CONFIG_WDT=m
+# CONFIG_WDT_501 is not set
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_HW_RANDOM=m
+CONFIG_NVRAM=m
+CONFIG_RTC=y
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+CONFIG_SONYPI=m
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+CONFIG_AGP=y
+CONFIG_AGP_ALI=y
+CONFIG_AGP_ATI=y
+CONFIG_AGP_AMD=y
+CONFIG_AGP_AMD64=y
+CONFIG_AGP_INTEL=y
+CONFIG_AGP_INTEL_MCH=y
+CONFIG_AGP_NVIDIA=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_SWORKS=y
+CONFIG_AGP_VIA=y
+CONFIG_AGP_EFFICEON=y
+CONFIG_DRM=y
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_GAMMA=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_I810=m
+CONFIG_DRM_I830=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+
+#
+# PCMCIA character devices
+#
+CONFIG_SYNCLINK_CS=m
+CONFIG_MWAVE=m
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HPET is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_ALI1535=m
+CONFIG_I2C_ALI1563=m
+CONFIG_I2C_ALI15X3=m
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD8111=m
+# CONFIG_I2C_ELEKTOR is not set
+CONFIG_I2C_I801=m
+CONFIG_I2C_I810=m
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_PARPORT is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_SCx200_ACB is not set
+CONFIG_I2C_SIS5595=m
+CONFIG_I2C_SIS630=m
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_VOODOO3=m
+
+#
+# Hardware Sensors Chip support
+#
+CONFIG_I2C_SENSOR=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+
+#
+# Other I2C Chip support
+#
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_RTC8564=m
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+CONFIG_IBM_ASM=m
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+
+#
+# Video For Linux
+#
+
+#
+# Video Adapters
+#
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_PMS=m
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_MEYE=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88=m
+
+#
+# Radio Adapters
+#
+CONFIG_RADIO_CADET=m
+CONFIG_RADIO_RTRACK=m
+CONFIG_RADIO_RTRACK2=m
+CONFIG_RADIO_AZTECH=m
+CONFIG_RADIO_GEMTEK=m
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+CONFIG_RADIO_SF16FMI=m
+CONFIG_RADIO_SF16FMR2=m
+CONFIG_RADIO_TERRATEC=m
+CONFIG_RADIO_TRUST=m
+CONFIG_RADIO_TYPHOON=m
+CONFIG_RADIO_TYPHOON_PROC_FS=y
+CONFIG_RADIO_ZOLTRIX=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported Frontend Modules
+#
+CONFIG_DVB_TWINHAN_DST=m
+CONFIG_DVB_STV0299=m
+# CONFIG_DVB_SP887X is not set
+# CONFIG_DVB_ALPS_TDLB7 is not set
+CONFIG_DVB_ALPS_TDMB7=m
+CONFIG_DVB_ATMEL_AT76C651=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_GRUNDIG_29504_491=m
+CONFIG_DVB_GRUNDIG_29504_401=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_VES1X93=m
+# CONFIG_DVB_TDA1004X is not set
+CONFIG_DVB_NXT6000=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_SKYSTAR=m
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_VGA16=m
+CONFIG_FB_VESA=y
+CONFIG_VIDEO_SELECT=y
+CONFIG_FB_HGA=m
+CONFIG_FB_HGA_ACCEL=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+CONFIG_FB_I810=m
+CONFIG_FB_I810_GTF=y
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G450=y
+CONFIG_FB_MATROX_G100=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+# CONFIG_FB_RADEON_OLD is not set
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GX=y
+# CONFIG_FB_ATY_XL_INIT is not set
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_MDA_CONSOLE=m
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_PCI_CONSOLE=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_RTCTIMER=m
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_OPL4_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# ISA devices
+#
+CONFIG_SND_AD1816A=m
+CONFIG_SND_AD1848=m
+CONFIG_SND_CS4231=m
+CONFIG_SND_CS4232=m
+CONFIG_SND_CS4236=m
+CONFIG_SND_ES968=m
+CONFIG_SND_ES1688=m
+CONFIG_SND_ES18XX=m
+CONFIG_SND_GUSCLASSIC=m
+CONFIG_SND_GUSEXTREME=m
+CONFIG_SND_GUSMAX=m
+CONFIG_SND_INTERWAVE=m
+CONFIG_SND_INTERWAVE_STB=m
+CONFIG_SND_OPTI92X_AD1848=m
+CONFIG_SND_OPTI92X_CS4231=m
+CONFIG_SND_OPTI93X=m
+CONFIG_SND_SB8=m
+CONFIG_SND_SB16=m
+CONFIG_SND_SBAWE=m
+CONFIG_SND_SB16_CSP=y
+# CONFIG_SND_WAVEFRONT is not set
+CONFIG_SND_ALS100=m
+CONFIG_SND_AZT2320=m
+CONFIG_SND_CMI8330=m
+CONFIG_SND_DT019X=m
+CONFIG_SND_OPL3SA2=m
+CONFIG_SND_SGALAXY=m
+CONFIG_SND_SSCAPE=m
+
+#
+# PCI devices
+#
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_CS4281=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_YMFPCI=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VX222=m
+
+#
+# ALSA USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_VXP440 is not set
+CONFIG_SND_PDAUDIOCF=m
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_UHCI_HCD=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_AUDIO=m
+
+#
+# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
+#
+CONFIG_USB_MIDI=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_RW_DETECT=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_HP8200e=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_MTOUCH=m
+CONFIG_USB_EGALAX=m
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_HPUSBSCSI=m
+
+#
+# USB Multimedia devices
+#
+CONFIG_USB_DABUSB=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_DSBR=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_STV680=m
+CONFIG_USB_W9968CF=m
+
+#
+# USB Network adaptors
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+
+#
+# USB Host-to-Host Cables
+#
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_GENESYS=y
+CONFIG_USB_NET1080=y
+CONFIG_USB_PL2301=y
+
+#
+# Intelligent USB Devices/Gadgets
+#
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_ZAURUS=y
+CONFIG_USB_CDCETHER=y
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_AX8817X=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_SAFE=m
+CONFIG_USB_SERIAL_SAFE_PADDED=y
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+# CONFIG_USB_EMI26 is not set
+CONFIG_USB_TIGL=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_TEST=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_NAND=y
+CONFIG_CRAMFS=m
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+# CONFIG_QNX4FS_RW is not set
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_FRAME_POINTER is not set
+
+#
+# Security options
+#
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+# CONFIG_SECURITY_SELINUX_MLS is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Library routines
+#
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_X86_BIOS_REBOOT=y
+CONFIG_PC=y
diff --git a/configs/kernel-2.6.7-i686-smp.config b/configs/kernel-2.6.7-i686-smp.config
new file mode 100644 (file)
index 0000000..9cf67ea
--- /dev/null
@@ -0,0 +1,2402 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_X86=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_GENERIC_ISA_DMA=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_STANDALONE=y
+
+#
+# General setup
+#
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_HOTPLUG=y
+# CONFIG_IKCONFIG is not set
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Processor type and features
+#
+# CONFIG_X86_PC is not set
+# CONFIG_X86_ELAN is not set
+# CONFIG_X86_VOYAGER is not set
+# CONFIG_X86_NUMAQ is not set
+# CONFIG_X86_SUMMIT is not set
+# CONFIG_X86_BIGSMP is not set
+# CONFIG_X86_VISWS is not set
+CONFIG_X86_GENERICARCH=y
+# CONFIG_X86_ES7000 is not set
+CONFIG_X86_CYCLONE_TIMER=y
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+# CONFIG_M586 is not set
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+CONFIG_M686=y
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+CONFIG_X86_GENERIC=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_XADD=y
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_X86_PPRO_FENCE=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_GOOD_APIC=y
+CONFIG_X86_INTEL_USERCOPY=y
+CONFIG_X86_USE_PPRO_CHECKSUM=y
+CONFIG_X86_4G=y
+CONFIG_X86_SWITCH_PAGETABLES=y
+CONFIG_X86_4G_VM_LAYOUT=y
+CONFIG_X86_UACCESS_INDIRECT=y
+CONFIG_X86_HIGH_ENTRY=y
+CONFIG_HPET_TIMER=y
+CONFIG_HPET_EMULATE_RTC=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=32
+CONFIG_SCHED_SMT=y
+# CONFIG_PREEMPT is not set
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_X86_IO_APIC=y
+CONFIG_X86_TSC=y
+CONFIG_X86_MCE=y
+# CONFIG_X86_MCE_NONFATAL is not set
+CONFIG_X86_MCE_P4THERMAL=y
+CONFIG_TOSHIBA=m
+CONFIG_I8K=m
+CONFIG_MICROCODE=m
+CONFIG_X86_MSR=m
+CONFIG_X86_CPUID=m
+
+#
+# Firmware Drivers
+#
+CONFIG_EDD=m
+# CONFIG_NOHIGHMEM is not set
+# CONFIG_HIGHMEM4G is not set
+CONFIG_HIGHMEM64G=y
+CONFIG_HIGHMEM=y
+CONFIG_X86_PAE=y
+# CONFIG_NUMA is not set
+CONFIG_HIGHPTE=y
+# CONFIG_MATH_EMULATION is not set
+CONFIG_MTRR=y
+# CONFIG_EFI is not set
+# CONFIG_IRQBALANCE is not set
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_REGPARM=y
+
+#
+# Power management options (ACPI, APM)
+#
+CONFIG_PM=y
+# CONFIG_SOFTWARE_SUSPEND is not set
+# CONFIG_PM_DISK is not set
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_BOOT=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_SLEEP=y
+CONFIG_ACPI_SLEEP_PROC_FS=y
+CONFIG_ACPI_AC=m
+CONFIG_ACPI_BATTERY=m
+CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_ASUS=m
+CONFIG_ACPI_TOSHIBA=m
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_BUS=y
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_PCI=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_X86_PM_TIMER=y
+
+#
+# APM (Advanced Power Management) BIOS Support
+#
+CONFIG_APM=y
+# CONFIG_APM_IGNORE_USER_SUSPEND is not set
+# CONFIG_APM_DO_ENABLE is not set
+CONFIG_APM_CPU_IDLE=y
+# CONFIG_APM_DISPLAY_BLANK is not set
+CONFIG_APM_RTC_IS_GMT=y
+# CONFIG_APM_ALLOW_INTS is not set
+# CONFIG_APM_REAL_MODE_POWER_OFF is not set
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+# CONFIG_CPU_FREQ_PROC_INTF is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_24_API is not set
+CONFIG_CPU_FREQ_TABLE=y
+
+#
+# CPUFreq processor drivers
+#
+CONFIG_X86_ACPI_CPUFREQ=m
+# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
+CONFIG_X86_POWERNOW_K6=m
+CONFIG_X86_POWERNOW_K7=y
+CONFIG_X86_POWERNOW_K8=m
+# CONFIG_X86_GX_SUSPMOD is not set
+CONFIG_X86_SPEEDSTEP_CENTRINO=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI=y
+CONFIG_X86_SPEEDSTEP_ICH=y
+CONFIG_X86_SPEEDSTEP_SMI=m
+CONFIG_X86_P4_CLOCKMOD=m
+CONFIG_X86_SPEEDSTEP_LIB=y
+# CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK is not set
+CONFIG_X86_LONGRUN=y
+# CONFIG_X86_LONGHAUL is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GOMMCONFIG is not set
+# CONFIG_PCI_GODIRECT is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+CONFIG_PCI_USE_VECTOR=y
+CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_NAMES is not set
+CONFIG_ISA=y
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SCx200 is not set
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_YENTA=m
+CONFIG_CARDBUS=y
+CONFIG_I82092=m
+CONFIG_I82365=m
+CONFIG_TCIC=m
+CONFIG_PCMCIA_PROBE=y
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+# CONFIG_HOTPLUG_PCI_FAKE is not set
+CONFIG_HOTPLUG_PCI_COMPAQ=m
+# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+CONFIG_HOTPLUG_PCI_IBM=m
+# CONFIG_HOTPLUG_PCI_ACPI is not set
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+CONFIG_HOTPLUG_PCI_PCIE=m
+CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE=y
+CONFIG_HOTPLUG_PCI_SHPC=m
+CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE=y
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=m
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_CMDLINE_PARTS=m
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PNC2000 is not set
+CONFIG_MTD_SC520CDP=m
+CONFIG_MTD_NETSC520=m
+CONFIG_MTD_SBC_GXX=m
+CONFIG_MTD_ELAN_104NC=m
+CONFIG_MTD_SCx200_DOCFLASH=m
+CONFIG_MTD_AMD76XROM=m
+CONFIG_MTD_ICH2ROM=m
+CONFIG_MTD_SCB2_FLASH=m
+# CONFIG_MTD_NETtel is not set
+# CONFIG_MTD_DILNETPC is not set
+CONFIG_MTD_L440GX=m
+CONFIG_MTD_PCI=m
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+# CONFIG_MTD_SLRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+CONFIG_MTD_DOC2000=m
+# CONFIG_MTD_DOC2001 is not set
+CONFIG_MTD_DOC2001PLUS=m
+CONFIG_MTD_DOCPROBE=m
+# CONFIG_MTD_DOCPROBE_ADVANCED is not set
+CONFIG_MTD_DOCPROBE_ADDRESS=0
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_IDS=m
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_PC_CML1=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+# CONFIG_PARPORT_OTHER is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_ISAPNP=y
+# CONFIG_PNPBIOS is not set
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_CARMEL=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_LBD=y
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDETAPE=m
+CONFIG_BLK_DEV_IDEFLOPPY=y
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+# CONFIG_IDE_TASKFILE_IO is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_CMD640 is not set
+CONFIG_BLK_DEV_IDEPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_RZ1000=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_ADMA=y
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_ATIIXP=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+CONFIG_BLK_DEV_CY82C693=y
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_PDC202XX_FORCE=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+CONFIG_BLK_DEV_SLC90E66=y
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+# CONFIG_SCSI_7000FASST is not set
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AHA152X=m
+CONFIG_SCSI_AHA1542=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_BUILD_FIRMWARE is not set
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_DPT_I2O is not set
+CONFIG_SCSI_ADVANSYS=m
+CONFIG_SCSI_IN2000=m
+CONFIG_SCSI_MEGARAID=m
+CONFIG_SCSI_SATA=y
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+CONFIG_SCSI_FUTURE_DOMAIN=m
+CONFIG_SCSI_GDTH=m
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+# CONFIG_SCSI_NCR53C406A is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PSI240I is not set
+CONFIG_SCSI_QLOGIC_FAS=m
+CONFIG_SCSI_QLOGIC_ISP=m
+# CONFIG_SCSI_QLOGIC_FC is not set
+CONFIG_SCSI_QLOGIC_1280=m
+CONFIG_SCSI_QLA2XXX=m
+CONFIG_SCSI_QLA21XX=m
+CONFIG_SCSI_QLA22XX=m
+CONFIG_SCSI_QLA2300=m
+CONFIG_SCSI_QLA2322=m
+CONFIG_SCSI_QLA6312=m
+CONFIG_SCSI_QLA6322=m
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC395x is not set
+CONFIG_SCSI_DC390T=m
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+CONFIG_PCMCIA_AHA152X=m
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_NINJA_SCSI=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID5=m
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=m
+CONFIG_FUSION_MAX_SGE=40
+# CONFIG_FUSION_ISENSE is not set
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set
+
+#
+# Device Drivers
+#
+# CONFIG_IEEE1394_PCILYNX is not set
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
+# CONFIG_IEEE1394_ETH1394 is not set
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+CONFIG_IEEE1394_CMP=m
+CONFIG_IEEE1394_AMDTP=m
+
+#
+# I2O device support
+#
+CONFIG_I2O=m
+CONFIG_I2O_CONFIG=m
+CONFIG_I2O_BLOCK=m
+CONFIG_I2O_SCSI=m
+CONFIG_I2O_PROC=m
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_FWMARK=y
+CONFIG_IP_ROUTE_NAT=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_TOS=y
+CONFIG_IP_ROUTE_VERBOSE=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_PHYSDEV=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_LOCAL=y
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_RAW=m
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_IP6_NF_QUEUE is not set
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_LIMIT=m
+CONFIG_IP6_NF_MATCH_MAC=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_MARK=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AHESP=m
+CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_RAW=m
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_ATM is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=y
+CONFIG_LTPC=m
+CONFIG_COPS=m
+CONFIG_COPS_DAYNA=y
+CONFIG_COPS_TANGENT=y
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+CONFIG_NET_DIVERT=y
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=m
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_CSZ=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_DELAY=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+# CONFIG_WINBOND_FIR is not set
+# CONFIG_TOSHIBA_FIR is not set
+# CONFIG_SMC_IRCC_FIR is not set
+# CONFIG_ALI_FIR is not set
+# CONFIG_VLSI_FIR is not set
+# CONFIG_VIA_FIR is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_BCSP_TXCRC=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+# CONFIG_TUX_EXTENDED_LOG is not set
+# CONFIG_TUX_DEBUG is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_ETHERTAP=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_EL1=m
+CONFIG_EL2=m
+CONFIG_ELPLUS=m
+CONFIG_EL16=m
+CONFIG_EL3=m
+CONFIG_3C515=m
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+CONFIG_LANCE=m
+CONFIG_NET_VENDOR_SMC=y
+CONFIG_WD80x3=m
+CONFIG_ULTRA=m
+CONFIG_SMC9194=m
+CONFIG_NET_VENDOR_RACAL=y
+CONFIG_NI52=m
+CONFIG_NI65=m
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_AT1700 is not set
+CONFIG_DEPCA=m
+CONFIG_HP100=m
+# CONFIG_NET_ISA is not set
+CONFIG_NE2000=m
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+CONFIG_AC3200=m
+CONFIG_APRICOT=m
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+CONFIG_CS89x0=m
+CONFIG_DGRS=m
+CONFIG_EEPRO100=m
+# CONFIG_EEPRO100_PIO is not set
+CONFIG_E100=m
+CONFIG_E100_NAPI=y
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+CONFIG_8139TOO_PIO=y
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_TLAN=m
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_VELOCITY=m
+CONFIG_NET_POCKET=y
+CONFIG_ATP=m
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_SK98LIN=m
+CONFIG_TIGON3=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_ARLAN is not set
+CONFIG_WAVELAN=m
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+CONFIG_HISAX_16_0=y
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_TELESPCI=y
+CONFIG_HISAX_S0BOX=y
+CONFIG_HISAX_AVM_A1=y
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+CONFIG_HISAX_IX1MICROR2=y
+CONFIG_HISAX_DIEHLDIVA=y
+CONFIG_HISAX_ASUSCOM=y
+CONFIG_HISAX_TELEINT=y
+CONFIG_HISAX_HFCS=y
+CONFIG_HISAX_SEDLBAUER=y
+CONFIG_HISAX_SPORTSTER=y
+CONFIG_HISAX_MIC=y
+CONFIG_HISAX_NETJET=y
+CONFIG_HISAX_NETJET_U=y
+CONFIG_HISAX_NICCY=y
+CONFIG_HISAX_ISURF=y
+CONFIG_HISAX_HSTSAPHIR=y
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_HFC_PCI=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+CONFIG_HISAX_ENTERNOW_PCI=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+CONFIG_HISAX_HFCUSB=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+CONFIG_ISDN_DRV_ICN=m
+CONFIG_ISDN_DRV_PCBIT=m
+CONFIG_ISDN_DRV_SC=m
+CONFIG_ISDN_DRV_ACT2000=m
+CONFIG_ISDN_DRV_TPAM=m
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+
+#
+# Active Eicon DIVA Server cards
+#
+CONFIG_CAPI_EICON=y
+CONFIG_ISDN_DIVAS=m
+CONFIG_ISDN_DIVAS_BRIPCI=y
+CONFIG_ISDN_DIVAS_PRIPCI=y
+CONFIG_ISDN_DIVAS_DIVACAPI=m
+CONFIG_ISDN_DIVAS_USERIDI=m
+CONFIG_ISDN_DIVAS_MAINT=m
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_JOYDEV=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+CONFIG_GAMEPORT=m
+CONFIG_SOUND_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_VORTEX=m
+CONFIG_GAMEPORT_FM801=m
+CONFIG_GAMEPORT_CS461x=m
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_INPORT=m
+CONFIG_MOUSE_ATIXL=y
+CONFIG_MOUSE_LOGIBM=m
+CONFIG_MOUSE_PC110PAD=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDDLER=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+# CONFIG_INPUT_JOYDUMP is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+# CONFIG_INPUT_UINPUT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_SERIAL_NONSTANDARD=y
+CONFIG_ROCKETPORT=m
+# CONFIG_CYCLADES is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_N_HDLC=m
+CONFIG_STALDRV=y
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_CS=m
+# CONFIG_SERIAL_8250_ACPI is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_MULTIPORT=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_CRASH=m
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+# CONFIG_QIC02_TAPE is not set
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_ACQUIRE_WDT=m
+CONFIG_ADVANTECH_WDT=m
+CONFIG_ALIM1535_WDT=m
+CONFIG_ALIM7101_WDT=m
+CONFIG_SC520_WDT=m
+CONFIG_EUROTECH_WDT=m
+CONFIG_IB700_WDT=m
+CONFIG_WAFER_WDT=m
+CONFIG_I8XX_TCO=m
+CONFIG_SC1200_WDT=m
+# CONFIG_SCx200_WDT is not set
+# CONFIG_60XX_WDT is not set
+CONFIG_CPU5_WDT=m
+CONFIG_W83627HF_WDT=m
+CONFIG_W83877F_WDT=m
+CONFIG_MACHZ_WDT=m
+
+#
+# ISA-based Watchdog Cards
+#
+CONFIG_PCWATCHDOG=m
+# CONFIG_MIXCOMWD is not set
+CONFIG_WDT=m
+# CONFIG_WDT_501 is not set
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_HW_RANDOM=m
+CONFIG_NVRAM=m
+CONFIG_RTC=y
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+CONFIG_SONYPI=m
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_AGP=y
+CONFIG_AGP_ALI=y
+CONFIG_AGP_ATI=y
+CONFIG_AGP_AMD=y
+CONFIG_AGP_AMD64=y
+CONFIG_AGP_INTEL=y
+CONFIG_AGP_INTEL_MCH=y
+CONFIG_AGP_NVIDIA=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_SWORKS=y
+CONFIG_AGP_VIA=y
+CONFIG_AGP_EFFICEON=y
+CONFIG_DRM=y
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_GAMMA=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_I810=m
+CONFIG_DRM_I830=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+
+#
+# PCMCIA character devices
+#
+CONFIG_SYNCLINK_CS=m
+CONFIG_MWAVE=m
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HPET is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_ALI1535=m
+CONFIG_I2C_ALI1563=m
+CONFIG_I2C_ALI15X3=m
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD8111=m
+CONFIG_I2C_I801=m
+CONFIG_I2C_I810=m
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_PARPORT is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_SCx200_ACB is not set
+CONFIG_I2C_SIS5595=m
+CONFIG_I2C_SIS630=m
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_VOODOO3=m
+
+#
+# Hardware Sensors Chip support
+#
+CONFIG_I2C_SENSOR=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+
+#
+# Other I2C Chip support
+#
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_RTC8564=m
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+CONFIG_IBM_ASM=m
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+
+#
+# Video For Linux
+#
+
+#
+# Video Adapters
+#
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_PMS=m
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88=m
+
+#
+# Radio Adapters
+#
+CONFIG_RADIO_CADET=m
+CONFIG_RADIO_RTRACK=m
+CONFIG_RADIO_RTRACK2=m
+CONFIG_RADIO_AZTECH=m
+CONFIG_RADIO_GEMTEK=m
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+CONFIG_RADIO_SF16FMI=m
+CONFIG_RADIO_SF16FMR2=m
+CONFIG_RADIO_TERRATEC=m
+CONFIG_RADIO_TRUST=m
+CONFIG_RADIO_TYPHOON=m
+CONFIG_RADIO_TYPHOON_PROC_FS=y
+CONFIG_RADIO_ZOLTRIX=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported Frontend Modules
+#
+CONFIG_DVB_TWINHAN_DST=m
+CONFIG_DVB_STV0299=m
+# CONFIG_DVB_SP887X is not set
+# CONFIG_DVB_ALPS_TDLB7 is not set
+CONFIG_DVB_ALPS_TDMB7=m
+CONFIG_DVB_ATMEL_AT76C651=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_GRUNDIG_29504_491=m
+CONFIG_DVB_GRUNDIG_29504_401=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_VES1X93=m
+# CONFIG_DVB_TDA1004X is not set
+CONFIG_DVB_NXT6000=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_SKYSTAR=m
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_VGA16=m
+CONFIG_FB_VESA=y
+CONFIG_VIDEO_SELECT=y
+CONFIG_FB_HGA=m
+CONFIG_FB_HGA_ACCEL=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+CONFIG_FB_I810=m
+CONFIG_FB_I810_GTF=y
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G450=y
+CONFIG_FB_MATROX_G100=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+# CONFIG_FB_RADEON_OLD is not set
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GX=y
+# CONFIG_FB_ATY_XL_INIT is not set
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_MDA_CONSOLE=m
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_PCI_CONSOLE=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_RTCTIMER=m
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_OPL4_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# ISA devices
+#
+CONFIG_SND_AD1816A=m
+CONFIG_SND_AD1848=m
+CONFIG_SND_CS4231=m
+CONFIG_SND_CS4232=m
+CONFIG_SND_CS4236=m
+CONFIG_SND_ES968=m
+CONFIG_SND_ES1688=m
+CONFIG_SND_ES18XX=m
+CONFIG_SND_GUSCLASSIC=m
+CONFIG_SND_GUSEXTREME=m
+CONFIG_SND_GUSMAX=m
+CONFIG_SND_INTERWAVE=m
+CONFIG_SND_INTERWAVE_STB=m
+CONFIG_SND_OPTI92X_AD1848=m
+CONFIG_SND_OPTI92X_CS4231=m
+CONFIG_SND_OPTI93X=m
+CONFIG_SND_SB8=m
+CONFIG_SND_SB16=m
+CONFIG_SND_SBAWE=m
+CONFIG_SND_SB16_CSP=y
+# CONFIG_SND_WAVEFRONT is not set
+CONFIG_SND_ALS100=m
+CONFIG_SND_AZT2320=m
+CONFIG_SND_CMI8330=m
+CONFIG_SND_DT019X=m
+CONFIG_SND_OPL3SA2=m
+CONFIG_SND_SGALAXY=m
+CONFIG_SND_SSCAPE=m
+
+#
+# PCI devices
+#
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_CS4281=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_YMFPCI=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VX222=m
+
+#
+# ALSA USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_VXP440 is not set
+CONFIG_SND_PDAUDIOCF=m
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_UHCI_HCD=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_AUDIO=m
+
+#
+# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
+#
+CONFIG_USB_MIDI=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_RW_DETECT=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_HP8200e=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_MTOUCH=m
+CONFIG_USB_EGALAX=m
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_HPUSBSCSI=m
+
+#
+# USB Multimedia devices
+#
+CONFIG_USB_DABUSB=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_DSBR=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_STV680=m
+CONFIG_USB_W9968CF=m
+
+#
+# USB Network adaptors
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+
+#
+# USB Host-to-Host Cables
+#
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_GENESYS=y
+CONFIG_USB_NET1080=y
+CONFIG_USB_PL2301=y
+
+#
+# Intelligent USB Devices/Gadgets
+#
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_ZAURUS=y
+CONFIG_USB_CDCETHER=y
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_AX8817X=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_SAFE=m
+CONFIG_USB_SERIAL_SAFE_PADDED=y
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+# CONFIG_USB_EMI26 is not set
+CONFIG_USB_TIGL=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_TEST=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_NAND=y
+CONFIG_CRAMFS=m
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+# CONFIG_QNX4FS_RW is not set
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_FRAME_POINTER is not set
+CONFIG_X86_FIND_SMP_CONFIG=y
+CONFIG_X86_MPPARSE=y
+
+#
+# Security options
+#
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+# CONFIG_SECURITY_SELINUX_MLS is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Library routines
+#
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_X86_SMP=y
+CONFIG_X86_HT=y
+CONFIG_X86_BIOS_REBOOT=y
+CONFIG_X86_TRAMPOLINE=y
+CONFIG_PC=y
diff --git a/configs/kernel-2.6.7-i686.config b/configs/kernel-2.6.7-i686.config
new file mode 100644 (file)
index 0000000..7445bef
--- /dev/null
@@ -0,0 +1,2417 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_X86=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_GENERIC_ISA_DMA=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_STANDALONE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_HOTPLUG=y
+# CONFIG_IKCONFIG is not set
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Processor type and features
+#
+CONFIG_X86_PC=y
+# CONFIG_X86_ELAN is not set
+# CONFIG_X86_VOYAGER is not set
+# CONFIG_X86_NUMAQ is not set
+# CONFIG_X86_SUMMIT is not set
+# CONFIG_X86_BIGSMP is not set
+# CONFIG_X86_VISWS is not set
+# CONFIG_X86_GENERICARCH is not set
+# CONFIG_X86_ES7000 is not set
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+# CONFIG_M586 is not set
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+CONFIG_M686=y
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+CONFIG_X86_GENERIC=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_XADD=y
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_X86_PPRO_FENCE=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_GOOD_APIC=y
+CONFIG_X86_INTEL_USERCOPY=y
+CONFIG_X86_USE_PPRO_CHECKSUM=y
+CONFIG_X86_4G=y
+CONFIG_X86_SWITCH_PAGETABLES=y
+CONFIG_X86_4G_VM_LAYOUT=y
+CONFIG_X86_UACCESS_INDIRECT=y
+CONFIG_X86_HIGH_ENTRY=y
+CONFIG_HPET_TIMER=y
+CONFIG_HPET_EMULATE_RTC=y
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_X86_UP_APIC is not set
+CONFIG_X86_TSC=y
+CONFIG_X86_MCE=y
+# CONFIG_X86_MCE_NONFATAL is not set
+CONFIG_TOSHIBA=m
+CONFIG_I8K=m
+CONFIG_MICROCODE=m
+CONFIG_X86_MSR=m
+CONFIG_X86_CPUID=m
+
+#
+# Firmware Drivers
+#
+CONFIG_EDD=m
+# CONFIG_NOHIGHMEM is not set
+CONFIG_HIGHMEM4G=y
+# CONFIG_HIGHMEM64G is not set
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+# CONFIG_MATH_EMULATION is not set
+CONFIG_MTRR=y
+# CONFIG_EFI is not set
+CONFIG_REGPARM=y
+
+#
+# Power management options (ACPI, APM)
+#
+CONFIG_PM=y
+# CONFIG_SOFTWARE_SUSPEND is not set
+# CONFIG_PM_DISK is not set
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_BOOT=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_SLEEP=y
+CONFIG_ACPI_SLEEP_PROC_FS=y
+CONFIG_ACPI_AC=m
+CONFIG_ACPI_BATTERY=m
+CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_ASUS=m
+CONFIG_ACPI_TOSHIBA=m
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_BUS=y
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_PCI=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_X86_PM_TIMER=y
+
+#
+# APM (Advanced Power Management) BIOS Support
+#
+CONFIG_APM=y
+# CONFIG_APM_IGNORE_USER_SUSPEND is not set
+# CONFIG_APM_DO_ENABLE is not set
+CONFIG_APM_CPU_IDLE=y
+# CONFIG_APM_DISPLAY_BLANK is not set
+CONFIG_APM_RTC_IS_GMT=y
+# CONFIG_APM_ALLOW_INTS is not set
+# CONFIG_APM_REAL_MODE_POWER_OFF is not set
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+# CONFIG_CPU_FREQ_PROC_INTF is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_24_API is not set
+CONFIG_CPU_FREQ_TABLE=y
+
+#
+# CPUFreq processor drivers
+#
+CONFIG_X86_ACPI_CPUFREQ=m
+# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
+CONFIG_X86_POWERNOW_K6=m
+CONFIG_X86_POWERNOW_K7=y
+CONFIG_X86_POWERNOW_K8=m
+# CONFIG_X86_GX_SUSPMOD is not set
+CONFIG_X86_SPEEDSTEP_CENTRINO=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI=y
+CONFIG_X86_SPEEDSTEP_ICH=y
+CONFIG_X86_SPEEDSTEP_SMI=m
+CONFIG_X86_P4_CLOCKMOD=m
+CONFIG_X86_SPEEDSTEP_LIB=y
+# CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK is not set
+CONFIG_X86_LONGRUN=y
+# CONFIG_X86_LONGHAUL is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GOMMCONFIG is not set
+# CONFIG_PCI_GODIRECT is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_NAMES is not set
+CONFIG_ISA=y
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SCx200 is not set
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_YENTA=m
+CONFIG_CARDBUS=y
+CONFIG_I82092=m
+CONFIG_I82365=m
+CONFIG_TCIC=m
+CONFIG_PCMCIA_PROBE=y
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+# CONFIG_HOTPLUG_PCI_FAKE is not set
+CONFIG_HOTPLUG_PCI_COMPAQ=m
+# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_ACPI is not set
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+CONFIG_HOTPLUG_PCI_PCIE=m
+CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE=y
+CONFIG_HOTPLUG_PCI_SHPC=m
+CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE=y
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=m
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_CMDLINE_PARTS=m
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PNC2000 is not set
+CONFIG_MTD_SC520CDP=m
+CONFIG_MTD_NETSC520=m
+CONFIG_MTD_SBC_GXX=m
+CONFIG_MTD_ELAN_104NC=m
+CONFIG_MTD_SCx200_DOCFLASH=m
+CONFIG_MTD_AMD76XROM=m
+CONFIG_MTD_ICH2ROM=m
+CONFIG_MTD_SCB2_FLASH=m
+# CONFIG_MTD_NETtel is not set
+# CONFIG_MTD_DILNETPC is not set
+CONFIG_MTD_L440GX=m
+CONFIG_MTD_PCI=m
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+# CONFIG_MTD_SLRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+CONFIG_MTD_DOC2000=m
+# CONFIG_MTD_DOC2001 is not set
+CONFIG_MTD_DOC2001PLUS=m
+CONFIG_MTD_DOCPROBE=m
+# CONFIG_MTD_DOCPROBE_ADVANCED is not set
+CONFIG_MTD_DOCPROBE_ADDRESS=0
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_IDS=m
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_PC_CML1=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+# CONFIG_PARPORT_OTHER is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_ISAPNP=y
+# CONFIG_PNPBIOS is not set
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_CARMEL=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_LBD=y
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDETAPE=m
+CONFIG_BLK_DEV_IDEFLOPPY=y
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+# CONFIG_IDE_TASKFILE_IO is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_CMD640 is not set
+CONFIG_BLK_DEV_IDEPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_RZ1000=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_ADMA=y
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_ATIIXP=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+CONFIG_BLK_DEV_CY82C693=y
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_PDC202XX_FORCE=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+CONFIG_BLK_DEV_SLC90E66=y
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+# CONFIG_SCSI_7000FASST is not set
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AHA152X=m
+CONFIG_SCSI_AHA1542=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_BUILD_FIRMWARE is not set
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_DPT_I2O is not set
+CONFIG_SCSI_ADVANSYS=m
+CONFIG_SCSI_IN2000=m
+CONFIG_SCSI_MEGARAID=m
+CONFIG_SCSI_SATA=y
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+CONFIG_SCSI_FUTURE_DOMAIN=m
+CONFIG_SCSI_GDTH=m
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+# CONFIG_SCSI_NCR53C406A is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PSI240I is not set
+CONFIG_SCSI_QLOGIC_FAS=m
+CONFIG_SCSI_QLOGIC_ISP=m
+# CONFIG_SCSI_QLOGIC_FC is not set
+CONFIG_SCSI_QLOGIC_1280=m
+CONFIG_SCSI_QLA2XXX=m
+CONFIG_SCSI_QLA21XX=m
+CONFIG_SCSI_QLA22XX=m
+CONFIG_SCSI_QLA2300=m
+CONFIG_SCSI_QLA2322=m
+CONFIG_SCSI_QLA6312=m
+CONFIG_SCSI_QLA6322=m
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC395x is not set
+CONFIG_SCSI_DC390T=m
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+CONFIG_PCMCIA_AHA152X=m
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_NINJA_SCSI=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID5=m
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=m
+CONFIG_FUSION_MAX_SGE=40
+# CONFIG_FUSION_ISENSE is not set
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set
+
+#
+# Device Drivers
+#
+# CONFIG_IEEE1394_PCILYNX is not set
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
+# CONFIG_IEEE1394_ETH1394 is not set
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+CONFIG_IEEE1394_CMP=m
+CONFIG_IEEE1394_AMDTP=m
+
+#
+# I2O device support
+#
+CONFIG_I2O=m
+CONFIG_I2O_CONFIG=m
+CONFIG_I2O_BLOCK=m
+CONFIG_I2O_SCSI=m
+CONFIG_I2O_PROC=m
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_FWMARK=y
+CONFIG_IP_ROUTE_NAT=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_TOS=y
+CONFIG_IP_ROUTE_VERBOSE=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_PHYSDEV=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_LOCAL=y
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_RAW=m
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_IP6_NF_QUEUE is not set
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_LIMIT=m
+CONFIG_IP6_NF_MATCH_MAC=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_MARK=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AHESP=m
+CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_RAW=m
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_ATM is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=y
+CONFIG_LTPC=m
+CONFIG_COPS=m
+CONFIG_COPS_DAYNA=y
+CONFIG_COPS_TANGENT=y
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+CONFIG_NET_DIVERT=y
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=m
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_CSZ=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_DELAY=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+CONFIG_IRPORT_SIR=m
+
+#
+# Old Serial dongle support
+#
+# CONFIG_DONGLE_OLD is not set
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+# CONFIG_WINBOND_FIR is not set
+# CONFIG_TOSHIBA_FIR is not set
+# CONFIG_SMC_IRCC_FIR is not set
+# CONFIG_ALI_FIR is not set
+# CONFIG_VLSI_FIR is not set
+# CONFIG_VIA_FIR is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_BCSP_TXCRC=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+# CONFIG_TUX_EXTENDED_LOG is not set
+# CONFIG_TUX_DEBUG is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_ETHERTAP=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_EL1=m
+CONFIG_EL2=m
+CONFIG_ELPLUS=m
+CONFIG_EL16=m
+CONFIG_EL3=m
+CONFIG_3C515=m
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+CONFIG_LANCE=m
+CONFIG_NET_VENDOR_SMC=y
+CONFIG_WD80x3=m
+CONFIG_ULTRA=m
+CONFIG_SMC9194=m
+CONFIG_NET_VENDOR_RACAL=y
+# CONFIG_NI5010 is not set
+CONFIG_NI52=m
+CONFIG_NI65=m
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_PCMCIA_XIRTULIP is not set
+# CONFIG_AT1700 is not set
+CONFIG_DEPCA=m
+CONFIG_HP100=m
+# CONFIG_NET_ISA is not set
+CONFIG_NE2000=m
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+CONFIG_AC3200=m
+CONFIG_APRICOT=m
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+CONFIG_CS89x0=m
+CONFIG_DGRS=m
+CONFIG_EEPRO100=m
+# CONFIG_EEPRO100_PIO is not set
+CONFIG_E100=m
+CONFIG_E100_NAPI=y
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+CONFIG_8139TOO_PIO=y
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_TLAN=m
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_VELOCITY=m
+CONFIG_NET_POCKET=y
+CONFIG_ATP=m
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_SK98LIN=m
+CONFIG_TIGON3=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_ARLAN is not set
+CONFIG_WAVELAN=m
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DRV_LOOP=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+CONFIG_HISAX_16_0=y
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_TELESPCI=y
+CONFIG_HISAX_S0BOX=y
+CONFIG_HISAX_AVM_A1=y
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+CONFIG_HISAX_IX1MICROR2=y
+CONFIG_HISAX_DIEHLDIVA=y
+CONFIG_HISAX_ASUSCOM=y
+CONFIG_HISAX_TELEINT=y
+CONFIG_HISAX_HFCS=y
+CONFIG_HISAX_SEDLBAUER=y
+CONFIG_HISAX_SPORTSTER=y
+CONFIG_HISAX_MIC=y
+CONFIG_HISAX_NETJET=y
+CONFIG_HISAX_NETJET_U=y
+CONFIG_HISAX_NICCY=y
+CONFIG_HISAX_ISURF=y
+CONFIG_HISAX_HSTSAPHIR=y
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_HFC_PCI=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+CONFIG_HISAX_ENTERNOW_PCI=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+CONFIG_HISAX_HFCUSB=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+CONFIG_ISDN_DRV_ICN=m
+CONFIG_ISDN_DRV_PCBIT=m
+CONFIG_ISDN_DRV_SC=m
+CONFIG_ISDN_DRV_ACT2000=m
+CONFIG_ISDN_DRV_TPAM=m
+CONFIG_HYSDN=m
+CONFIG_HYSDN_CAPI=y
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+CONFIG_ISDN_DRV_AVMB1_B1ISA=m
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+CONFIG_ISDN_DRV_AVMB1_T1ISA=m
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+CONFIG_CAPI_EICON=y
+CONFIG_ISDN_DIVAS=m
+CONFIG_ISDN_DIVAS_BRIPCI=y
+CONFIG_ISDN_DIVAS_PRIPCI=y
+CONFIG_ISDN_DIVAS_DIVACAPI=m
+CONFIG_ISDN_DIVAS_USERIDI=m
+CONFIG_ISDN_DIVAS_MAINT=m
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_JOYDEV=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+CONFIG_GAMEPORT=m
+CONFIG_SOUND_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_VORTEX=m
+CONFIG_GAMEPORT_FM801=m
+CONFIG_GAMEPORT_CS461x=m
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_INPORT=m
+CONFIG_MOUSE_ATIXL=y
+CONFIG_MOUSE_LOGIBM=m
+CONFIG_MOUSE_PC110PAD=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDDLER=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+# CONFIG_INPUT_JOYDUMP is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+# CONFIG_INPUT_UINPUT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+CONFIG_ROCKETPORT=m
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_N_HDLC=m
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+CONFIG_STALDRV=y
+# CONFIG_STALLION is not set
+# CONFIG_ISTALLION is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_CS=m
+# CONFIG_SERIAL_8250_ACPI is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_MULTIPORT=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_CRASH=m
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+# CONFIG_QIC02_TAPE is not set
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_ACQUIRE_WDT=m
+CONFIG_ADVANTECH_WDT=m
+CONFIG_ALIM1535_WDT=m
+CONFIG_ALIM7101_WDT=m
+CONFIG_SC520_WDT=m
+CONFIG_EUROTECH_WDT=m
+CONFIG_IB700_WDT=m
+CONFIG_WAFER_WDT=m
+CONFIG_I8XX_TCO=m
+CONFIG_SC1200_WDT=m
+# CONFIG_SCx200_WDT is not set
+# CONFIG_60XX_WDT is not set
+CONFIG_CPU5_WDT=m
+CONFIG_W83627HF_WDT=m
+CONFIG_W83877F_WDT=m
+CONFIG_MACHZ_WDT=m
+
+#
+# ISA-based Watchdog Cards
+#
+CONFIG_PCWATCHDOG=m
+# CONFIG_MIXCOMWD is not set
+CONFIG_WDT=m
+# CONFIG_WDT_501 is not set
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_HW_RANDOM=m
+CONFIG_NVRAM=m
+CONFIG_RTC=y
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+CONFIG_SONYPI=m
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+CONFIG_AGP=y
+CONFIG_AGP_ALI=y
+CONFIG_AGP_ATI=y
+CONFIG_AGP_AMD=y
+CONFIG_AGP_AMD64=y
+CONFIG_AGP_INTEL=y
+CONFIG_AGP_INTEL_MCH=y
+CONFIG_AGP_NVIDIA=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_SWORKS=y
+CONFIG_AGP_VIA=y
+CONFIG_AGP_EFFICEON=y
+CONFIG_DRM=y
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_GAMMA=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_I810=m
+CONFIG_DRM_I830=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+
+#
+# PCMCIA character devices
+#
+CONFIG_SYNCLINK_CS=m
+CONFIG_MWAVE=m
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HPET is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_ALI1535=m
+CONFIG_I2C_ALI1563=m
+CONFIG_I2C_ALI15X3=m
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD8111=m
+# CONFIG_I2C_ELEKTOR is not set
+CONFIG_I2C_I801=m
+CONFIG_I2C_I810=m
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_PARPORT is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_SCx200_ACB is not set
+CONFIG_I2C_SIS5595=m
+CONFIG_I2C_SIS630=m
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_VOODOO3=m
+
+#
+# Hardware Sensors Chip support
+#
+CONFIG_I2C_SENSOR=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+
+#
+# Other I2C Chip support
+#
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_RTC8564=m
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+CONFIG_IBM_ASM=m
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+
+#
+# Video For Linux
+#
+
+#
+# Video Adapters
+#
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_PMS=m
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_MEYE=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88=m
+
+#
+# Radio Adapters
+#
+CONFIG_RADIO_CADET=m
+CONFIG_RADIO_RTRACK=m
+CONFIG_RADIO_RTRACK2=m
+CONFIG_RADIO_AZTECH=m
+CONFIG_RADIO_GEMTEK=m
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+CONFIG_RADIO_SF16FMI=m
+CONFIG_RADIO_SF16FMR2=m
+CONFIG_RADIO_TERRATEC=m
+CONFIG_RADIO_TRUST=m
+CONFIG_RADIO_TYPHOON=m
+CONFIG_RADIO_TYPHOON_PROC_FS=y
+CONFIG_RADIO_ZOLTRIX=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported Frontend Modules
+#
+CONFIG_DVB_TWINHAN_DST=m
+CONFIG_DVB_STV0299=m
+# CONFIG_DVB_SP887X is not set
+# CONFIG_DVB_ALPS_TDLB7 is not set
+CONFIG_DVB_ALPS_TDMB7=m
+CONFIG_DVB_ATMEL_AT76C651=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_GRUNDIG_29504_491=m
+CONFIG_DVB_GRUNDIG_29504_401=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_VES1X93=m
+# CONFIG_DVB_TDA1004X is not set
+CONFIG_DVB_NXT6000=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_SKYSTAR=m
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_VGA16=m
+CONFIG_FB_VESA=y
+CONFIG_VIDEO_SELECT=y
+CONFIG_FB_HGA=m
+CONFIG_FB_HGA_ACCEL=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+CONFIG_FB_I810=m
+CONFIG_FB_I810_GTF=y
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G450=y
+CONFIG_FB_MATROX_G100=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+# CONFIG_FB_RADEON_OLD is not set
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GX=y
+# CONFIG_FB_ATY_XL_INIT is not set
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_MDA_CONSOLE=m
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_PCI_CONSOLE=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_RTCTIMER=m
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_OPL4_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# ISA devices
+#
+CONFIG_SND_AD1816A=m
+CONFIG_SND_AD1848=m
+CONFIG_SND_CS4231=m
+CONFIG_SND_CS4232=m
+CONFIG_SND_CS4236=m
+CONFIG_SND_ES968=m
+CONFIG_SND_ES1688=m
+CONFIG_SND_ES18XX=m
+CONFIG_SND_GUSCLASSIC=m
+CONFIG_SND_GUSEXTREME=m
+CONFIG_SND_GUSMAX=m
+CONFIG_SND_INTERWAVE=m
+CONFIG_SND_INTERWAVE_STB=m
+CONFIG_SND_OPTI92X_AD1848=m
+CONFIG_SND_OPTI92X_CS4231=m
+CONFIG_SND_OPTI93X=m
+CONFIG_SND_SB8=m
+CONFIG_SND_SB16=m
+CONFIG_SND_SBAWE=m
+CONFIG_SND_SB16_CSP=y
+# CONFIG_SND_WAVEFRONT is not set
+CONFIG_SND_ALS100=m
+CONFIG_SND_AZT2320=m
+CONFIG_SND_CMI8330=m
+CONFIG_SND_DT019X=m
+CONFIG_SND_OPL3SA2=m
+CONFIG_SND_SGALAXY=m
+CONFIG_SND_SSCAPE=m
+
+#
+# PCI devices
+#
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_CS4281=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_YMFPCI=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VX222=m
+
+#
+# ALSA USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_VXP440 is not set
+CONFIG_SND_PDAUDIOCF=m
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_UHCI_HCD=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_AUDIO=m
+
+#
+# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
+#
+CONFIG_USB_MIDI=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_RW_DETECT=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_HP8200e=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_MTOUCH=m
+CONFIG_USB_EGALAX=m
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_HPUSBSCSI=m
+
+#
+# USB Multimedia devices
+#
+CONFIG_USB_DABUSB=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_DSBR=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_STV680=m
+CONFIG_USB_W9968CF=m
+
+#
+# USB Network adaptors
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+
+#
+# USB Host-to-Host Cables
+#
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_GENESYS=y
+CONFIG_USB_NET1080=y
+CONFIG_USB_PL2301=y
+
+#
+# Intelligent USB Devices/Gadgets
+#
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_ZAURUS=y
+CONFIG_USB_CDCETHER=y
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_AX8817X=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_SAFE=m
+CONFIG_USB_SERIAL_SAFE_PADDED=y
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+# CONFIG_USB_EMI26 is not set
+CONFIG_USB_TIGL=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_TEST=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_NAND=y
+CONFIG_CRAMFS=m
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+# CONFIG_QNX4FS_RW is not set
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_FRAME_POINTER is not set
+
+#
+# Security options
+#
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+# CONFIG_SECURITY_SELINUX_MLS is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Library routines
+#
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_X86_BIOS_REBOOT=y
+CONFIG_PC=y
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
new file mode 100644 (file)
index 0000000..cef6032
--- /dev/null
@@ -0,0 +1,1076 @@
+/*
+ * Intel & MS High Precision Event Timer Implementation.
+ * Contributors:
+ *     Venki Pallipadi
+ *     Bob Picco
+ */
+
+#include <linux/config.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/major.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <linux/sysctl.h>
+#include <linux/wait.h>
+#include <linux/bcd.h>
+#include <linux/seq_file.h>
+
+#include <asm/current.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/div64.h>
+
+#include <linux/acpi.h>
+#include <acpi/acpi_bus.h>
+#include <linux/hpet.h>
+
+/*
+ * The High Precision Event Timer driver.
+ * This driver is closely modelled after the rtc.c driver.
+ * http://www.intel.com/labs/platcomp/hpet/hpetspec.htm
+ */
+#define        HPET_USER_FREQ  (64)
+#define        HPET_DRIFT      (500)
+
+static u32 hpet_ntimer, hpet_nhpet, hpet_max_freq = HPET_USER_FREQ;
+
+/* A lock for concurrent access by app and isr hpet activity. */
+static spinlock_t hpet_lock = SPIN_LOCK_UNLOCKED;
+/* A lock for concurrent intermodule access to hpet and isr hpet activity. */
+static spinlock_t hpet_task_lock = SPIN_LOCK_UNLOCKED;
+
+struct hpet_dev {
+       struct hpets *hd_hpets;
+       struct hpet *hd_hpet;
+       struct hpet_timer *hd_timer;
+       unsigned long hd_ireqfreq;
+       unsigned long hd_irqdata;
+       wait_queue_head_t hd_waitqueue;
+       struct fasync_struct *hd_async_queue;
+       struct hpet_task *hd_task;
+       unsigned int hd_flags;
+       unsigned int hd_irq;
+       unsigned int hd_hdwirq;
+};
+
+struct hpets {
+       struct hpets *hp_next;
+       struct hpet *hp_hpet;
+       unsigned long hp_period;
+       unsigned long hp_delta;
+       unsigned int hp_ntimer;
+       unsigned int hp_which;
+       struct hpet_dev hp_dev[1];
+};
+
+static struct hpets *hpets;
+
+#define        HPET_OPEN               0x0001
+#define        HPET_IE                 0x0002  /* interrupt enabled */
+#define        HPET_PERIODIC           0x0004
+
+#if BITS_PER_LONG == 64
+#define        write_counter(V, MC)    writeq(V, MC)
+#define        read_counter(MC)        readq(MC)
+#else
+#define        write_counter(V, MC)    writel(V, MC)
+#define        read_counter(MC)        readl(MC)
+#endif
+
+#ifndef readq
+static unsigned long long __inline readq(void *addr)
+{
+       return readl(addr) | (((unsigned long long)readl(addr + 4)) << 32LL);
+}
+#endif
+
+#ifndef writeq
+static void __inline writeq(unsigned long long v, void *addr)
+{
+       writel(v & 0xffffffff, addr);
+       writel(v >> 32, addr + 4);
+}
+#endif
+
+static irqreturn_t hpet_interrupt(int irq, void *data, struct pt_regs *regs)
+{
+       struct hpet_dev *devp;
+       unsigned long isr;
+
+       devp = data;
+
+       spin_lock(&hpet_lock);
+       devp->hd_irqdata++;
+
+       /*
+        * For non-periodic timers, increment the accumulator.
+        * This has the effect of treating non-periodic like periodic.
+        */
+       if ((devp->hd_flags & (HPET_IE | HPET_PERIODIC)) == HPET_IE) {
+               unsigned long m, t;
+
+               t = devp->hd_ireqfreq;
+               m = read_counter(&devp->hd_hpet->hpet_mc);
+               write_counter(t + m + devp->hd_hpets->hp_delta,
+                             &devp->hd_timer->hpet_compare);
+       }
+
+       isr = (1 << (devp - devp->hd_hpets->hp_dev));
+       writeq(isr, &devp->hd_hpet->hpet_isr);
+       spin_unlock(&hpet_lock);
+
+       spin_lock(&hpet_task_lock);
+       if (devp->hd_task)
+               devp->hd_task->ht_func(devp->hd_task->ht_data);
+       spin_unlock(&hpet_task_lock);
+
+       wake_up_interruptible(&devp->hd_waitqueue);
+
+       kill_fasync(&devp->hd_async_queue, SIGIO, POLL_IN);
+
+       return IRQ_HANDLED;
+}
+
+static int hpet_open(struct inode *inode, struct file *file)
+{
+       struct hpet_dev *devp;
+       struct hpets *hpetp;
+       int i;
+
+       spin_lock_irq(&hpet_lock);
+
+       for (devp = NULL, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next)
+               for (i = 0; i < hpetp->hp_ntimer; i++)
+                       if (hpetp->hp_dev[i].hd_flags & HPET_OPEN
+                           || hpetp->hp_dev[i].hd_task)
+                               continue;
+                       else {
+                               devp = &hpetp->hp_dev[i];
+                               break;
+                       }
+
+       if (!devp) {
+               spin_unlock_irq(&hpet_lock);
+               return -EBUSY;
+       }
+
+       file->private_data = devp;
+       devp->hd_irqdata = 0;
+       devp->hd_flags |= HPET_OPEN;
+       spin_unlock_irq(&hpet_lock);
+
+       return 0;
+}
+
+static ssize_t
+hpet_read(struct file *file, char *buf, size_t count, loff_t * ppos)
+{
+       DECLARE_WAITQUEUE(wait, current);
+       unsigned long data;
+       ssize_t retval;
+       struct hpet_dev *devp;
+
+       devp = file->private_data;
+       if (!devp->hd_ireqfreq)
+               return -EIO;
+
+       if (count < sizeof(unsigned long))
+               return -EINVAL;
+
+       add_wait_queue(&devp->hd_waitqueue, &wait);
+
+       do {
+               __set_current_state(TASK_INTERRUPTIBLE);
+
+               spin_lock_irq(&hpet_lock);
+               data = devp->hd_irqdata;
+               devp->hd_irqdata = 0;
+               spin_unlock_irq(&hpet_lock);
+
+               if (data)
+                       break;
+               else if (file->f_flags & O_NONBLOCK) {
+                       retval = -EAGAIN;
+                       goto out;
+               } else if (signal_pending(current)) {
+                       retval = -ERESTARTSYS;
+                       goto out;
+               }
+
+               schedule();
+
+       } while (1);
+
+       retval = put_user(data, (unsigned long *)buf);
+       if (!retval)
+               retval = sizeof(unsigned long);
+      out:
+       current->state = TASK_RUNNING;
+       remove_wait_queue(&devp->hd_waitqueue, &wait);
+
+       return retval;
+}
+
+static unsigned int hpet_poll(struct file *file, poll_table * wait)
+{
+       unsigned long v;
+       struct hpet_dev *devp;
+
+       devp = file->private_data;
+
+       if (!devp->hd_ireqfreq)
+               return 0;
+
+       poll_wait(file, &devp->hd_waitqueue, wait);
+
+       spin_lock_irq(&hpet_lock);
+       v = devp->hd_irqdata;
+       spin_unlock_irq(&hpet_lock);
+
+       if (v != 0)
+               return POLLIN | POLLRDNORM;
+
+       return 0;
+}
+
+static int hpet_mmap(struct file *file, struct vm_area_struct *vma)
+{
+#ifdef CONFIG_HPET_NOMMAP
+       return -ENOSYS;
+#else
+       struct hpet_dev *devp;
+       unsigned long addr;
+
+       if (((vma->vm_end - vma->vm_start) != PAGE_SIZE) || vma->vm_pgoff)
+               return -EINVAL;
+
+       if (vma->vm_flags & VM_WRITE)
+               return -EPERM;
+
+       devp = file->private_data;
+       addr = (unsigned long)devp->hd_hpet;
+
+       if (addr & (PAGE_SIZE - 1))
+               return -ENOSYS;
+
+       vma->vm_flags |= VM_IO;
+       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+       addr = __pa(addr);
+
+       if (remap_page_range
+           (vma, vma->vm_start, addr, PAGE_SIZE, vma->vm_page_prot)) {
+               printk(KERN_ERR "remap_page_range failed in hpet.c\n");
+               return -EAGAIN;
+       }
+
+       return 0;
+#endif
+}
+
+static int hpet_fasync(int fd, struct file *file, int on)
+{
+       struct hpet_dev *devp;
+
+       devp = file->private_data;
+
+       if (fasync_helper(fd, file, on, &devp->hd_async_queue) >= 0)
+               return 0;
+       else
+               return -EIO;
+}
+
+static int hpet_release(struct inode *inode, struct file *file)
+{
+       struct hpet_dev *devp;
+       struct hpet_timer *timer;
+       int irq = 0;
+
+       devp = file->private_data;
+       timer = devp->hd_timer;
+
+       spin_lock_irq(&hpet_lock);
+
+       writeq((readq(&timer->hpet_config) & ~Tn_INT_ENB_CNF_MASK),
+              &timer->hpet_config);
+
+       irq = devp->hd_irq;
+       devp->hd_irq = 0;
+
+       devp->hd_ireqfreq = 0;
+
+       if (devp->hd_flags & HPET_PERIODIC
+           && readq(&timer->hpet_config) & Tn_TYPE_CNF_MASK) {
+               unsigned long v;
+
+               v = readq(&timer->hpet_config);
+               v ^= Tn_TYPE_CNF_MASK;
+               writeq(v, &timer->hpet_config);
+       }
+
+       devp->hd_flags &= ~(HPET_OPEN | HPET_IE | HPET_PERIODIC);
+       spin_unlock_irq(&hpet_lock);
+
+       if (irq)
+               free_irq(irq, devp);
+
+       if (file->f_flags & FASYNC)
+               hpet_fasync(-1, file, 0);
+
+       file->private_data = 0;
+       return 0;
+}
+
+static int hpet_ioctl_common(struct hpet_dev *, int, unsigned long, int);
+
+static int
+hpet_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+          unsigned long arg)
+{
+       struct hpet_dev *devp;
+
+       devp = file->private_data;
+       return hpet_ioctl_common(devp, cmd, arg, 0);
+}
+
+static int hpet_ioctl_ieon(struct hpet_dev *devp)
+{
+       struct hpet_timer *timer;
+       struct hpet *hpet;
+       struct hpets *hpetp;
+       int irq;
+       unsigned long g, v, t, m;
+       unsigned long flags, isr;
+
+       timer = devp->hd_timer;
+       hpet = devp->hd_hpet;
+       hpetp = devp->hd_hpets;
+
+       v = readq(&timer->hpet_config);
+       spin_lock_irq(&hpet_lock);
+
+       if (devp->hd_flags & HPET_IE) {
+               spin_unlock_irq(&hpet_lock);
+               return -EBUSY;
+       }
+
+       devp->hd_flags |= HPET_IE;
+       spin_unlock_irq(&hpet_lock);
+
+       t = readq(&timer->hpet_config);
+       irq = devp->hd_hdwirq;
+
+       if (irq) {
+               char name[7];
+
+               sprintf(name, "hpet%d", (int)(devp - hpetp->hp_dev));
+
+               if (request_irq
+                   (irq, hpet_interrupt, SA_INTERRUPT, name, (void *)devp)) {
+                       printk(KERN_ERR "hpet: IRQ %d is not free\n", irq);
+                       irq = 0;
+               }
+       }
+
+       if (irq == 0) {
+               spin_lock_irq(&hpet_lock);
+               devp->hd_flags ^= HPET_IE;
+               spin_unlock_irq(&hpet_lock);
+               return -EIO;
+       }
+
+       devp->hd_irq = irq;
+       t = devp->hd_ireqfreq;
+       v = readq(&timer->hpet_config);
+       g = v | Tn_INT_ENB_CNF_MASK;
+
+       if (devp->hd_flags & HPET_PERIODIC) {
+               write_counter(t, &timer->hpet_compare);
+               g |= Tn_TYPE_CNF_MASK;
+               v |= Tn_TYPE_CNF_MASK;
+               writeq(v, &timer->hpet_config);
+               v |= Tn_VAL_SET_CNF_MASK;
+               writeq(v, &timer->hpet_config);
+               local_irq_save(flags);
+               m = read_counter(&hpet->hpet_mc);
+               write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare);
+       } else {
+               local_irq_save(flags);
+               m = read_counter(&hpet->hpet_mc);
+               write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare);
+       }
+
+       isr = (1 << (devp - hpets->hp_dev));
+       writeq(isr, &hpet->hpet_isr);
+       writeq(g, &timer->hpet_config);
+       local_irq_restore(flags);
+
+       return 0;
+}
+
+static inline unsigned long hpet_time_div(unsigned long dis)
+{
+       unsigned long long m = 1000000000000000ULL;
+
+       do_div(m, dis);
+
+       return (unsigned long)m;
+}
+
+static int
+hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel)
+{
+       struct hpet_timer *timer;
+       struct hpet *hpet;
+       struct hpets *hpetp;
+       int err;
+       unsigned long v;
+
+       switch (cmd) {
+       case HPET_IE_OFF:
+       case HPET_INFO:
+       case HPET_EPI:
+       case HPET_DPI:
+       case HPET_IRQFREQ:
+               timer = devp->hd_timer;
+               hpet = devp->hd_hpet;
+               hpetp = devp->hd_hpets;
+               break;
+       case HPET_IE_ON:
+               return hpet_ioctl_ieon(devp);
+       default:
+               return -EINVAL;
+       }
+
+       err = 0;
+
+       switch (cmd) {
+       case HPET_IE_OFF:
+               if ((devp->hd_flags & HPET_IE) == 0)
+                       break;
+               v = readq(&timer->hpet_config);
+               v &= ~Tn_INT_ENB_CNF_MASK;
+               writeq(v, &timer->hpet_config);
+               if (devp->hd_irq) {
+                       free_irq(devp->hd_irq, devp);
+                       devp->hd_irq = 0;
+               }
+               devp->hd_flags ^= HPET_IE;
+               break;
+       case HPET_INFO:
+               {
+                       struct hpet_info info;
+
+                       info.hi_ireqfreq = hpet_time_div(hpetp->hp_period *
+                                                        devp->hd_ireqfreq);
+                       info.hi_flags =
+                           readq(&timer->hpet_config) & Tn_PER_INT_CAP_MASK;
+                       info.hi_hpet = devp->hd_hpets->hp_which;
+                       info.hi_timer = devp - devp->hd_hpets->hp_dev;
+                       if (copy_to_user((void *)arg, &info, sizeof(info)))
+                               err = -EFAULT;
+                       break;
+               }
+       case HPET_EPI:
+               v = readq(&timer->hpet_config);
+               if ((v & Tn_PER_INT_CAP_MASK) == 0) {
+                       err = -ENXIO;
+                       break;
+               }
+               devp->hd_flags |= HPET_PERIODIC;
+               break;
+       case HPET_DPI:
+               v = readq(&timer->hpet_config);
+               if ((v & Tn_PER_INT_CAP_MASK) == 0) {
+                       err = -ENXIO;
+                       break;
+               }
+               if (devp->hd_flags & HPET_PERIODIC &&
+                   readq(&timer->hpet_config) & Tn_TYPE_CNF_MASK) {
+                       v = readq(&timer->hpet_config);
+                       v ^= Tn_TYPE_CNF_MASK;
+                       writeq(v, &timer->hpet_config);
+               }
+               devp->hd_flags &= ~HPET_PERIODIC;
+               break;
+       case HPET_IRQFREQ:
+               if (!kernel && (arg > hpet_max_freq) &&
+                   !capable(CAP_SYS_RESOURCE)) {
+                       err = -EACCES;
+                       break;
+               }
+
+               if (arg & (arg - 1)) {
+                       err = -EINVAL;
+                       break;
+               }
+
+               devp->hd_ireqfreq = hpet_time_div(hpetp->hp_period * arg);
+       }
+
+       return err;
+}
+
+static struct file_operations hpet_fops = {
+       .owner = THIS_MODULE,
+       .llseek = no_llseek,
+       .read = hpet_read,
+       .poll = hpet_poll,
+       .ioctl = hpet_ioctl,
+       .open = hpet_open,
+       .release = hpet_release,
+       .fasync = hpet_fasync,
+       .mmap = hpet_mmap,
+};
+
+EXPORT_SYMBOL(hpet_alloc);
+EXPORT_SYMBOL(hpet_register);
+EXPORT_SYMBOL(hpet_unregister);
+EXPORT_SYMBOL(hpet_control);
+
+int hpet_register(struct hpet_task *tp, int periodic)
+{
+       unsigned int i;
+       u64 mask;
+       struct hpet_timer *timer;
+       struct hpet_dev *devp;
+       struct hpets *hpetp;
+
+       switch (periodic) {
+       case 1:
+               mask = Tn_PER_INT_CAP_MASK;
+               break;
+       case 0:
+               mask = 0;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       spin_lock_irq(&hpet_task_lock);
+       spin_lock(&hpet_lock);
+
+       for (devp = 0, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next)
+               for (timer = hpetp->hp_hpet->hpet_timers, i = 0;
+                    i < hpetp->hp_ntimer; i++, timer++) {
+                       if ((readq(&timer->hpet_config) & Tn_PER_INT_CAP_MASK)
+                           != mask)
+                               continue;
+
+                       devp = &hpetp->hp_dev[i];
+
+                       if (devp->hd_flags & HPET_OPEN || devp->hd_task) {
+                               devp = 0;
+                               continue;
+                       }
+
+                       tp->ht_opaque = devp;
+                       devp->hd_task = tp;
+                       break;
+               }
+
+       spin_unlock(&hpet_lock);
+       spin_unlock_irq(&hpet_task_lock);
+
+       if (tp->ht_opaque)
+               return 0;
+       else
+               return -EBUSY;
+}
+
+static inline int hpet_tpcheck(struct hpet_task *tp)
+{
+       struct hpet_dev *devp;
+       struct hpets *hpetp;
+
+       devp = tp->ht_opaque;
+
+       if (!devp)
+               return -ENXIO;
+
+       for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
+               if (devp >= hpetp->hp_dev
+                   && devp < (hpetp->hp_dev + hpetp->hp_ntimer)
+                   && devp->hd_hpet == hpetp->hp_hpet)
+                       return 0;
+
+       return -ENXIO;
+}
+
+int hpet_unregister(struct hpet_task *tp)
+{
+       struct hpet_dev *devp;
+       struct hpet_timer *timer;
+       int err;
+
+       if ((err = hpet_tpcheck(tp)))
+               return err;
+
+       spin_lock_irq(&hpet_task_lock);
+       spin_lock(&hpet_lock);
+
+       devp = tp->ht_opaque;
+       if (devp->hd_task != tp) {
+               spin_unlock(&hpet_lock);
+               spin_unlock_irq(&hpet_task_lock);
+               return -ENXIO;
+       }
+
+       timer = devp->hd_timer;
+       writeq((readq(&timer->hpet_config) & ~Tn_INT_ENB_CNF_MASK),
+              &timer->hpet_config);
+       devp->hd_flags &= ~(HPET_IE | HPET_PERIODIC);
+       devp->hd_task = 0;
+       spin_unlock(&hpet_lock);
+       spin_unlock_irq(&hpet_task_lock);
+
+       return 0;
+}
+
+int hpet_control(struct hpet_task *tp, unsigned int cmd, unsigned long arg)
+{
+       struct hpet_dev *devp;
+       int err;
+
+       if ((err = hpet_tpcheck(tp)))
+               return err;
+
+       spin_lock_irq(&hpet_lock);
+       devp = tp->ht_opaque;
+       if (devp->hd_task != tp) {
+               spin_unlock_irq(&hpet_lock);
+               return -ENXIO;
+       }
+       spin_unlock_irq(&hpet_lock);
+       return hpet_ioctl_common(devp, cmd, arg, 1);
+}
+
+#ifdef CONFIG_TIME_INTERPOLATION
+
+static unsigned long hpet_offset, last_wall_hpet;
+static long hpet_nsecs_per_cycle, hpet_cycles_per_sec;
+
+static unsigned long hpet_getoffset(void)
+{
+       return hpet_offset + (read_counter(&hpets->hp_hpet->hpet_mc) -
+                             last_wall_hpet) * hpet_nsecs_per_cycle;
+}
+
+static void hpet_update(long delta)
+{
+       unsigned long mc;
+       unsigned long offset;
+
+       mc = read_counter(&hpets->hp_hpet->hpet_mc);
+       offset = hpet_offset + (mc - last_wall_hpet) * hpet_nsecs_per_cycle;
+
+       if (delta < 0 || (unsigned long)delta < offset)
+               hpet_offset = offset - delta;
+       else
+               hpet_offset = 0;
+       last_wall_hpet = mc;
+}
+
+static void hpet_reset(void)
+{
+       hpet_offset = 0;
+       last_wall_hpet = read_counter(&hpets->hp_hpet->hpet_mc);
+}
+
+static struct time_interpolator hpet_interpolator = {
+       .get_offset = hpet_getoffset,
+       .update = hpet_update,
+       .reset = hpet_reset
+};
+
+#endif
+
+static ctl_table hpet_table[] = {
+       {
+        .ctl_name = 1,
+        .procname = "max-user-freq",
+        .data = &hpet_max_freq,
+        .maxlen = sizeof(int),
+        .mode = 0644,
+        .proc_handler = &proc_dointvec,
+        },
+       {.ctl_name = 0}
+};
+
+static ctl_table hpet_root[] = {
+       {
+        .ctl_name = 1,
+        .procname = "hpet",
+        .maxlen = 0,
+        .mode = 0555,
+        .child = hpet_table,
+        },
+       {.ctl_name = 0}
+};
+
+static ctl_table dev_root[] = {
+       {
+        .ctl_name = CTL_DEV,
+        .procname = "dev",
+        .maxlen = 0,
+        .mode = 0555,
+        .child = hpet_root,
+        },
+       {.ctl_name = 0}
+};
+
+static struct ctl_table_header *sysctl_header;
+
+static void *hpet_start(struct seq_file *s, loff_t * pos)
+{
+       struct hpets *hpetp;
+       loff_t n;
+
+       for (n = *pos, hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
+               if (!n--)
+                       return hpetp;
+
+       return 0;
+}
+
+static void *hpet_next(struct seq_file *s, void *v, loff_t * pos)
+{
+       struct hpets *hpetp;
+
+       hpetp = v;
+       ++*pos;
+       return hpetp->hp_next;
+}
+
+static void hpet_stop(struct seq_file *s, void *v)
+{
+       return;
+}
+
+static int hpet_show(struct seq_file *s, void *v)
+{
+       struct hpets *hpetp;
+       struct hpet *hpet;
+       u64 cap, vendor, period;
+
+       hpetp = v;
+       hpet = hpetp->hp_hpet;
+
+       cap = readq(&hpet->hpet_cap);
+       period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >>
+           HPET_COUNTER_CLK_PERIOD_SHIFT;
+       vendor = (cap & HPET_VENDOR_ID_MASK) >> HPET_VENDOR_ID_SHIFT;
+
+       seq_printf(s,
+                  "HPET%d period = %d 10**-15  vendor = 0x%x number timer = %d\n",
+                  hpetp->hp_which, (u32) period, (u32) vendor,
+                  hpetp->hp_ntimer);
+
+       return 0;
+}
+
+static struct seq_operations hpet_seq_ops = {
+       .start = hpet_start,
+       .next = hpet_next,
+       .stop = hpet_stop,
+       .show = hpet_show
+};
+
+static int hpet_proc_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &hpet_seq_ops);
+}
+
+static struct file_operations hpet_proc_fops = {
+       .open = hpet_proc_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release
+};
+
+/*
+ * Adjustment for when arming the timer with
+ * initial conditions.  That is, main counter
+ * ticks expired before interrupts are enabled.
+ */
+#define        TICK_CALIBRATE  (1000UL)
+
+static unsigned long __init hpet_calibrate(struct hpets *hpetp)
+{
+       struct hpet_timer *timer;
+       unsigned long t, m, count, i, flags, start;
+       struct hpet_dev *devp;
+       int j;
+       struct hpet *hpet;
+
+       for (timer = 0, j = 0, devp = hpetp->hp_dev; j < hpetp->hp_ntimer;
+            j++, devp++)
+               if ((devp->hd_flags & HPET_OPEN) == 0) {
+                       timer = devp->hd_timer;
+                       break;
+               }
+
+       if (!timer)
+               return 0;
+
+       hpet = hpets->hp_hpet;
+       t = read_counter(&timer->hpet_compare);
+
+       i = 0;
+       count = hpet_time_div(hpetp->hp_period * TICK_CALIBRATE);
+
+       local_irq_save(flags);
+
+       start = read_counter(&hpet->hpet_mc);
+
+       do {
+               m = read_counter(&hpet->hpet_mc);
+               write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare);
+       } while (i++, (m - start) < count);
+
+       local_irq_restore(flags);
+
+       return (m - start) / i;
+}
+
+int __init hpet_alloc(struct hpet_data *hdp)
+{
+       u64 cap, mcfg;
+       struct hpet_dev *devp;
+       u32 i, ntimer;
+       struct hpets *hpetp;
+       size_t siz;
+       struct hpet *hpet;
+       static struct hpets *last __initdata = (struct hpets *)0;
+
+       /*
+        * hpet_alloc can be called by platform dependent code.
+        * if platform dependent code has allocated the hpet
+        * ACPI also reports hpet, then we catch it here.
+        */
+       for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
+               if (hpetp->hp_hpet == (struct hpet *)(hdp->hd_address))
+                       return 0;
+
+       siz = sizeof(struct hpets) + ((hdp->hd_nirqs - 1) *
+                                     sizeof(struct hpet_dev));
+
+       hpetp = kmalloc(siz, GFP_KERNEL);
+
+       if (!hpetp)
+               return -ENOMEM;
+
+       memset(hpetp, 0, siz);
+
+       hpetp->hp_which = hpet_nhpet++;
+       hpetp->hp_hpet = (struct hpet *)hdp->hd_address;
+
+       hpetp->hp_ntimer = hdp->hd_nirqs;
+
+       for (i = 0; i < hdp->hd_nirqs; i++)
+               hpetp->hp_dev[i].hd_hdwirq = hdp->hd_irq[i];
+
+       hpet = hpetp->hp_hpet;
+
+       cap = readq(&hpet->hpet_cap);
+
+       ntimer = ((cap & HPET_NUM_TIM_CAP_MASK) >> HPET_NUM_TIM_CAP_SHIFT) + 1;
+
+       if (hpetp->hp_ntimer != ntimer) {
+               printk(KERN_WARNING "hpet: number irqs doesn't agree"
+                      " with number of timers\n");
+               kfree(hpetp);
+               return -ENODEV;
+       }
+
+       if (last)
+               last->hp_next = hpetp;
+       else
+               hpets = hpetp;
+
+       last = hpetp;
+
+       hpetp->hp_period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >>
+           HPET_COUNTER_CLK_PERIOD_SHIFT;
+
+       mcfg = readq(&hpet->hpet_config);
+       if ((mcfg & HPET_ENABLE_CNF_MASK) == 0) {
+               write_counter(0L, &hpet->hpet_mc);
+               mcfg |= HPET_ENABLE_CNF_MASK;
+               writeq(mcfg, &hpet->hpet_config);
+       }
+
+       for (i = 0, devp = hpetp->hp_dev; i < hpetp->hp_ntimer;
+            i++, hpet_ntimer++, devp++) {
+               unsigned long v;
+               struct hpet_timer *timer;
+
+               timer = &hpet->hpet_timers[devp - hpetp->hp_dev];
+               v = readq(&timer->hpet_config);
+
+               devp->hd_hpets = hpetp;
+               devp->hd_hpet = hpet;
+               devp->hd_timer = timer;
+
+               /*
+                * If the timer was reserved by platform code,
+                * then make timer unavailable for opens.
+                */
+               if (hdp->hd_state & (1 << i)) {
+                       devp->hd_flags = HPET_OPEN;
+                       continue;
+               }
+
+               init_waitqueue_head(&devp->hd_waitqueue);
+       }
+
+       hpetp->hp_delta = hpet_calibrate(hpetp);
+
+       return 0;
+}
+
+static acpi_status __init hpet_resources(struct acpi_resource *res, void *data)
+{
+       struct hpet_data *hdp;
+       acpi_status status;
+       struct acpi_resource_address64 addr;
+       struct hpets *hpetp;
+
+       hdp = data;
+
+       status = acpi_resource_to_address64(res, &addr);
+
+       if (ACPI_SUCCESS(status)) {
+               unsigned long size;
+
+               size = addr.max_address_range - addr.min_address_range + 1;
+               hdp->hd_address =
+                   (unsigned long)ioremap(addr.min_address_range, size);
+
+               for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
+                       if (hpetp->hp_hpet == (struct hpet *)(hdp->hd_address))
+                               return -EBUSY;
+       } else if (res->id == ACPI_RSTYPE_EXT_IRQ) {
+               struct acpi_resource_ext_irq *irqp;
+               int i;
+
+               irqp = &res->data.extended_irq;
+
+               if (irqp->number_of_interrupts > 0) {
+                       hdp->hd_nirqs = irqp->number_of_interrupts;
+
+                       for (i = 0; i < hdp->hd_nirqs; i++)
+#ifdef CONFIG_IA64
+                               hdp->hd_irq[i] =
+                                   acpi_register_gsi(irqp->interrupts[i],
+                                                     irqp->edge_level,
+                                                     irqp->active_high_low);
+#else
+                               hdp->hd_irq[i] = irqp->interrupts[i];
+#endif
+               }
+       }
+
+       return AE_OK;
+}
+
+static int __init hpet_acpi_add(struct acpi_device *device)
+{
+       acpi_status result;
+       struct hpet_data data;
+
+       memset(&data, 0, sizeof(data));
+
+       result =
+           acpi_walk_resources(device->handle, METHOD_NAME__CRS,
+                               hpet_resources, &data);
+
+       if (ACPI_FAILURE(result))
+               return -ENODEV;
+
+       if (!data.hd_address || !data.hd_nirqs) {
+               printk("%s: no address or irqs in _CRS\n", __FUNCTION__);
+               return -ENODEV;
+       }
+
+       return hpet_alloc(&data);
+}
+
+static int __init hpet_acpi_remove(struct acpi_device *device, int type)
+{
+       return 0;
+}
+
+static struct acpi_driver hpet_acpi_driver __initdata = {
+       .name = "hpet",
+       .class = "",
+       .ids = "PNP0103",
+       .ops = {
+               .add = hpet_acpi_add,
+               .remove = hpet_acpi_remove,
+               },
+};
+
+static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
+
+static int __init hpet_init(void)
+{
+       struct proc_dir_entry *entry;
+
+       (void)acpi_bus_register_driver(&hpet_acpi_driver);
+
+       if (hpets) {
+               if (misc_register(&hpet_misc))
+                       return -ENODEV;
+
+               entry = create_proc_entry("driver/hpet", 0, 0);
+
+               if (entry)
+                       entry->proc_fops = &hpet_proc_fops;
+
+               sysctl_header = register_sysctl_table(dev_root, 0);
+
+#ifdef CONFIG_TIME_INTERPOLATION
+               {
+                       struct hpet *hpet;
+
+                       hpet = hpets->hp_hpet;
+                       hpet_cycles_per_sec = hpet_time_div(hpets->hp_period);
+                       hpet_interpolator.frequency = hpet_cycles_per_sec;
+                       hpet_interpolator.drift = hpet_cycles_per_sec *
+                           HPET_DRIFT / 1000000;
+                       hpet_nsecs_per_cycle = 1000000000 / hpet_cycles_per_sec;
+                       register_time_interpolator(&hpet_interpolator);
+               }
+#endif
+               return 0;
+       } else
+               return -ENODEV;
+}
+
+static void __exit hpet_exit(void)
+{
+       acpi_bus_unregister_driver(&hpet_acpi_driver);
+
+       if (hpets) {
+               unregister_sysctl_table(sysctl_header);
+               remove_proc_entry("driver/hpet", NULL);
+       }
+
+       return;
+}
+
+module_init(hpet_init);
+module_exit(hpet_exit);
+MODULE_AUTHOR("Bob Picco <Robert.Picco@hp.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/md/dm-io.h b/drivers/md/dm-io.h
new file mode 100644 (file)
index 0000000..1a77f32
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2003 Sistina Software
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef _DM_IO_H
+#define _DM_IO_H
+
+#include "dm.h"
+
+/* FIXME make this configurable */
+#define DM_MAX_IO_REGIONS 8
+
+struct io_region {
+       struct block_device *bdev;
+       sector_t sector;
+       sector_t count;
+};
+
+struct page_list {
+       struct page_list *next;
+       struct page *page;
+};
+
+
+/*
+ * 'error' is a bitset, with each bit indicating whether an error
+ * occurred doing io to the corresponding region.
+ */
+typedef void (*io_notify_fn)(unsigned long error, void *context);
+
+
+/*
+ * Before anyone uses the IO interface they should call
+ * dm_io_get(), specifying roughly how many pages they are
+ * expecting to perform io on concurrently.
+ *
+ * This function may block.
+ */
+int dm_io_get(unsigned int num_pages);
+void dm_io_put(unsigned int num_pages);
+
+/*
+ * Synchronous IO.
+ *
+ * Please ensure that the rw flag in the next two functions is
+ * either READ or WRITE, ie. we don't take READA.  Any
+ * regions with a zero count field will be ignored.
+ */
+int dm_io_sync(unsigned int num_regions, struct io_region *where, int rw,
+              struct page_list *pl, unsigned int offset,
+              unsigned long *error_bits);
+
+int dm_io_sync_bvec(unsigned int num_regions, struct io_region *where, int rw,
+                   struct bio_vec *bvec, unsigned long *error_bits);
+
+int dm_io_sync_vm(unsigned int num_regions, struct io_region *where, int rw,
+                 void *data, unsigned long *error_bits);
+
+/*
+ * Aynchronous IO.
+ *
+ * The 'where' array may be safely allocated on the stack since
+ * the function takes a copy.
+ */
+int dm_io_async(unsigned int num_regions, struct io_region *where, int rw,
+               struct page_list *pl, unsigned int offset,
+               io_notify_fn fn, void *context);
+
+int dm_io_async_bvec(unsigned int num_regions, struct io_region *where, int rw,
+                    struct bio_vec *bvec, io_notify_fn fn, void *context);
+
+int dm_io_async_vm(unsigned int num_regions, struct io_region *where, int rw,
+                  void *data, io_notify_fn fn, void *context);
+
+#endif
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
new file mode 100644 (file)
index 0000000..843e9b8
--- /dev/null
@@ -0,0 +1,1278 @@
+/*
+ * Copyright (C) 2003 Sistina Software Limited.
+ *
+ * This file is released under the GPL.
+ */
+
+#include "dm.h"
+#include "dm-bio-list.h"
+#include "dm-io.h"
+#include "dm-log.h"
+#include "kcopyd.h"
+
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include <linux/mempool.h>
+#include <linux/module.h>
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/vmalloc.h>
+#include <linux/workqueue.h>
+
+static struct workqueue_struct *_kmirrord_wq;
+static struct work_struct _kmirrord_work;
+
+static inline void wake(void)
+{
+       queue_work(_kmirrord_wq, &_kmirrord_work);
+}
+
+/*-----------------------------------------------------------------
+ * Region hash
+ *
+ * The mirror splits itself up into discrete regions.  Each
+ * region can be in one of three states: clean, dirty,
+ * nosync.  There is no need to put clean regions in the hash.
+ *
+ * In addition to being present in the hash table a region _may_
+ * be present on one of three lists.
+ *
+ *   clean_regions: Regions on this list have no io pending to
+ *   them, they are in sync, we are no longer interested in them,
+ *   they are dull.  rh_update_states() will remove them from the
+ *   hash table.
+ *
+ *   quiesced_regions: These regions have been spun down, ready
+ *   for recovery.  rh_recovery_start() will remove regions from
+ *   this list and hand them to kmirrord, which will schedule the
+ *   recovery io with kcopyd.
+ *
+ *   recovered_regions: Regions that kcopyd has successfully
+ *   recovered.  rh_update_states() will now schedule any delayed
+ *   io, up the recovery_count, and remove the region from the
+ *   hash.
+ *
+ * There are 2 locks:
+ *   A rw spin lock 'hash_lock' protects just the hash table,
+ *   this is never held in write mode from interrupt context,
+ *   which I believe means that we only have to disable irqs when
+ *   doing a write lock.
+ *
+ *   An ordinary spin lock 'region_lock' that protects the three
+ *   lists in the region_hash, with the 'state', 'list' and
+ *   'bhs_delayed' fields of the regions.  This is used from irq
+ *   context, so all other uses will have to suspend local irqs.
+ *---------------------------------------------------------------*/
+struct mirror_set;
+struct region_hash {
+       struct mirror_set *ms;
+       sector_t region_size;
+       unsigned region_shift;
+
+       /* holds persistent region state */
+       struct dirty_log *log;
+
+       /* hash table */
+       rwlock_t hash_lock;
+       mempool_t *region_pool;
+       unsigned int mask;
+       unsigned int nr_buckets;
+       struct list_head *buckets;
+
+       spinlock_t region_lock;
+       struct semaphore recovery_count;
+       struct list_head clean_regions;
+       struct list_head quiesced_regions;
+       struct list_head recovered_regions;
+};
+
+enum {
+       RH_CLEAN,
+       RH_DIRTY,
+       RH_NOSYNC,
+       RH_RECOVERING
+};
+
+struct region {
+       struct region_hash *rh; /* FIXME: can we get rid of this ? */
+       region_t key;
+       int state;
+
+       struct list_head hash_list;
+       struct list_head list;
+
+       atomic_t pending;
+       struct bio_list delayed_bios;
+};
+
+/*
+ * Conversion fns
+ */
+static inline region_t bio_to_region(struct region_hash *rh, struct bio *bio)
+{
+       return bio->bi_sector >> rh->region_shift;
+}
+
+static inline sector_t region_to_sector(struct region_hash *rh, region_t region)
+{
+       return region << rh->region_shift;
+}
+
+/* FIXME move this */
+static void queue_bio(struct mirror_set *ms, struct bio *bio, int rw);
+
+static void *region_alloc(int gfp_mask, void *pool_data)
+{
+       return kmalloc(sizeof(struct region), gfp_mask);
+}
+
+static void region_free(void *element, void *pool_data)
+{
+       kfree(element);
+}
+
+#define MIN_REGIONS 64
+#define MAX_RECOVERY 1
+static int rh_init(struct region_hash *rh, struct mirror_set *ms,
+                  struct dirty_log *log, sector_t region_size,
+                  region_t nr_regions)
+{
+       unsigned int nr_buckets, max_buckets;
+       size_t i;
+
+       /*
+        * Calculate a suitable number of buckets for our hash
+        * table.
+        */
+       max_buckets = nr_regions >> 6;
+       for (nr_buckets = 128u; nr_buckets < max_buckets; nr_buckets <<= 1)
+               ;
+       nr_buckets >>= 1;
+
+       rh->ms = ms;
+       rh->log = log;
+       rh->region_size = region_size;
+       rh->region_shift = ffs(region_size) - 1;
+       rwlock_init(&rh->hash_lock);
+       rh->mask = nr_buckets - 1;
+       rh->nr_buckets = nr_buckets;
+
+       rh->buckets = vmalloc(nr_buckets * sizeof(*rh->buckets));
+       if (!rh->buckets) {
+               DMERR("unable to allocate region hash memory");
+               return -ENOMEM;
+       }
+
+       for (i = 0; i < nr_buckets; i++)
+               INIT_LIST_HEAD(rh->buckets + i);
+
+       spin_lock_init(&rh->region_lock);
+       sema_init(&rh->recovery_count, 0);
+       INIT_LIST_HEAD(&rh->clean_regions);
+       INIT_LIST_HEAD(&rh->quiesced_regions);
+       INIT_LIST_HEAD(&rh->recovered_regions);
+
+       rh->region_pool = mempool_create(MIN_REGIONS, region_alloc,
+                                        region_free, NULL);
+       if (!rh->region_pool) {
+               vfree(rh->buckets);
+               rh->buckets = NULL;
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+static void rh_exit(struct region_hash *rh)
+{
+       unsigned int h;
+       struct region *reg, *nreg;
+
+       BUG_ON(!list_empty(&rh->quiesced_regions));
+       for (h = 0; h < rh->nr_buckets; h++) {
+               list_for_each_entry_safe(reg, nreg, rh->buckets + h, hash_list) {
+                       BUG_ON(atomic_read(&reg->pending));
+                       mempool_free(reg, rh->region_pool);
+               }
+       }
+
+       if (rh->log)
+               dm_destroy_dirty_log(rh->log);
+       if (rh->region_pool)
+               mempool_destroy(rh->region_pool);
+       vfree(rh->buckets);
+}
+
+#define RH_HASH_MULT 2654435387U
+
+static inline unsigned int rh_hash(struct region_hash *rh, region_t region)
+{
+       return (unsigned int) ((region * RH_HASH_MULT) >> 12) & rh->mask;
+}
+
+static struct region *__rh_lookup(struct region_hash *rh, region_t region)
+{
+       struct region *reg;
+
+       list_for_each_entry (reg, rh->buckets + rh_hash(rh, region), hash_list)
+               if (reg->key == region)
+                       return reg;
+
+       return NULL;
+}
+
+static void __rh_insert(struct region_hash *rh, struct region *reg)
+{
+       unsigned int h = rh_hash(rh, reg->key);
+       list_add(&reg->hash_list, rh->buckets + h);
+}
+
+static struct region *__rh_alloc(struct region_hash *rh, region_t region)
+{
+       struct region *reg, *nreg;
+
+       read_unlock(&rh->hash_lock);
+       nreg = mempool_alloc(rh->region_pool, GFP_NOIO);
+       nreg->state = rh->log->type->in_sync(rh->log, region, 1) ?
+               RH_CLEAN : RH_NOSYNC;
+       nreg->rh = rh;
+       nreg->key = region;
+
+       INIT_LIST_HEAD(&nreg->list);
+
+       atomic_set(&nreg->pending, 0);
+       bio_list_init(&nreg->delayed_bios);
+       write_lock_irq(&rh->hash_lock);
+
+       reg = __rh_lookup(rh, region);
+       if (reg)
+               /* we lost the race */
+               mempool_free(nreg, rh->region_pool);
+
+       else {
+               __rh_insert(rh, nreg);
+               if (nreg->state == RH_CLEAN) {
+                       spin_lock_irq(&rh->region_lock);
+                       list_add(&nreg->list, &rh->clean_regions);
+                       spin_unlock_irq(&rh->region_lock);
+               }
+               reg = nreg;
+       }
+       write_unlock_irq(&rh->hash_lock);
+       read_lock(&rh->hash_lock);
+
+       return reg;
+}
+
+static inline struct region *__rh_find(struct region_hash *rh, region_t region)
+{
+       struct region *reg;
+
+       reg = __rh_lookup(rh, region);
+       if (!reg)
+               reg = __rh_alloc(rh, region);
+
+       return reg;
+}
+
+static int rh_state(struct region_hash *rh, region_t region, int may_block)
+{
+       int r;
+       struct region *reg;
+
+       read_lock(&rh->hash_lock);
+       reg = __rh_lookup(rh, region);
+       read_unlock(&rh->hash_lock);
+
+       if (reg)
+               return reg->state;
+
+       /*
+        * The region wasn't in the hash, so we fall back to the
+        * dirty log.
+        */
+       r = rh->log->type->in_sync(rh->log, region, may_block);
+
+       /*
+        * Any error from the dirty log (eg. -EWOULDBLOCK) gets
+        * taken as a RH_NOSYNC
+        */
+       return r == 1 ? RH_CLEAN : RH_NOSYNC;
+}
+
+static inline int rh_in_sync(struct region_hash *rh,
+                            region_t region, int may_block)
+{
+       int state = rh_state(rh, region, may_block);
+       return state == RH_CLEAN || state == RH_DIRTY;
+}
+
+static void dispatch_bios(struct mirror_set *ms, struct bio_list *bio_list)
+{
+       struct bio *bio;
+
+       while ((bio = bio_list_pop(bio_list))) {
+               queue_bio(ms, bio, WRITE);
+       }
+}
+
+static void rh_update_states(struct region_hash *rh)
+{
+       struct region *reg, *next;
+
+       LIST_HEAD(clean);
+       LIST_HEAD(recovered);
+
+       /*
+        * Quickly grab the lists.
+        */
+       write_lock_irq(&rh->hash_lock);
+       spin_lock(&rh->region_lock);
+       if (!list_empty(&rh->clean_regions)) {
+               list_splice(&rh->clean_regions, &clean);
+               INIT_LIST_HEAD(&rh->clean_regions);
+
+               list_for_each_entry (reg, &clean, list) {
+                       rh->log->type->clear_region(rh->log, reg->key);
+                       list_del(&reg->hash_list);
+               }
+       }
+
+       if (!list_empty(&rh->recovered_regions)) {
+               list_splice(&rh->recovered_regions, &recovered);
+               INIT_LIST_HEAD(&rh->recovered_regions);
+
+               list_for_each_entry (reg, &recovered, list)
+                       list_del(&reg->hash_list);
+       }
+       spin_unlock(&rh->region_lock);
+       write_unlock_irq(&rh->hash_lock);
+
+       /*
+        * All the regions on the recovered and clean lists have
+        * now been pulled out of the system, so no need to do
+        * any more locking.
+        */
+       list_for_each_entry_safe (reg, next, &recovered, list) {
+               rh->log->type->clear_region(rh->log, reg->key);
+               rh->log->type->complete_resync_work(rh->log, reg->key, 1);
+               dispatch_bios(rh->ms, &reg->delayed_bios);
+               up(&rh->recovery_count);
+               mempool_free(reg, rh->region_pool);
+       }
+
+       if (!list_empty(&recovered))
+               rh->log->type->flush(rh->log);
+
+       list_for_each_entry_safe (reg, next, &clean, list)
+               mempool_free(reg, rh->region_pool);
+}
+
+static void rh_inc(struct region_hash *rh, region_t region)
+{
+       struct region *reg;
+
+       read_lock(&rh->hash_lock);
+       reg = __rh_find(rh, region);
+       if (reg->state == RH_CLEAN) {
+               rh->log->type->mark_region(rh->log, reg->key);
+
+               spin_lock_irq(&rh->region_lock);
+               reg->state = RH_DIRTY;
+               list_del_init(&reg->list);      /* take off the clean list */
+               spin_unlock_irq(&rh->region_lock);
+       }
+
+       atomic_inc(&reg->pending);
+       read_unlock(&rh->hash_lock);
+}
+
+static void rh_inc_pending(struct region_hash *rh, struct bio_list *bios)
+{
+       struct bio *bio;
+
+       for (bio = bios->head; bio; bio = bio->bi_next)
+               rh_inc(rh, bio_to_region(rh, bio));
+}
+
+static void rh_dec(struct region_hash *rh, region_t region)
+{
+       unsigned long flags;
+       struct region *reg;
+       int should_wake = 0;
+
+       read_lock(&rh->hash_lock);
+       reg = __rh_lookup(rh, region);
+       read_unlock(&rh->hash_lock);
+
+       if (atomic_dec_and_test(&reg->pending)) {
+               spin_lock_irqsave(&rh->region_lock, flags);
+               if (reg->state == RH_RECOVERING) {
+                       list_add_tail(&reg->list, &rh->quiesced_regions);
+               } else {
+                       reg->state = RH_CLEAN;
+                       list_add(&reg->list, &rh->clean_regions);
+               }
+               spin_unlock_irqrestore(&rh->region_lock, flags);
+               should_wake = 1;
+       }
+
+       if (should_wake)
+               wake();
+}
+
+/*
+ * Starts quiescing a region in preparation for recovery.
+ */
+static int __rh_recovery_prepare(struct region_hash *rh)
+{
+       int r;
+       struct region *reg;
+       region_t region;
+
+       /*
+        * Ask the dirty log what's next.
+        */
+       r = rh->log->type->get_resync_work(rh->log, &region);
+       if (r <= 0)
+               return r;
+
+       /*
+        * Get this region, and start it quiescing by setting the
+        * recovering flag.
+        */
+       read_lock(&rh->hash_lock);
+       reg = __rh_find(rh, region);
+       read_unlock(&rh->hash_lock);
+
+       spin_lock_irq(&rh->region_lock);
+       reg->state = RH_RECOVERING;
+
+       /* Already quiesced ? */
+       if (atomic_read(&reg->pending))
+               list_del_init(&reg->list);
+
+       else {
+               list_del_init(&reg->list);
+               list_add(&reg->list, &rh->quiesced_regions);
+       }
+       spin_unlock_irq(&rh->region_lock);
+
+       return 1;
+}
+
+static void rh_recovery_prepare(struct region_hash *rh)
+{
+       while (!down_trylock(&rh->recovery_count))
+               if (__rh_recovery_prepare(rh) <= 0) {
+                       up(&rh->recovery_count);
+                       break;
+               }
+}
+
+/*
+ * Returns any quiesced regions.
+ */
+static struct region *rh_recovery_start(struct region_hash *rh)
+{
+       struct region *reg = NULL;
+
+       spin_lock_irq(&rh->region_lock);
+       if (!list_empty(&rh->quiesced_regions)) {
+               reg = list_entry(rh->quiesced_regions.next,
+                                struct region, list);
+               list_del_init(&reg->list);      /* remove from the quiesced list */
+       }
+       spin_unlock_irq(&rh->region_lock);
+
+       return reg;
+}
+
+/* FIXME: success ignored for now */
+static void rh_recovery_end(struct region *reg, int success)
+{
+       struct region_hash *rh = reg->rh;
+
+       spin_lock_irq(&rh->region_lock);
+       list_add(&reg->list, &reg->rh->recovered_regions);
+       spin_unlock_irq(&rh->region_lock);
+
+       wake();
+}
+
+static void rh_flush(struct region_hash *rh)
+{
+       rh->log->type->flush(rh->log);
+}
+
+static void rh_delay(struct region_hash *rh, struct bio *bio)
+{
+       struct region *reg;
+
+       read_lock(&rh->hash_lock);
+       reg = __rh_find(rh, bio_to_region(rh, bio));
+       bio_list_add(&reg->delayed_bios, bio);
+       read_unlock(&rh->hash_lock);
+}
+
+static void rh_stop_recovery(struct region_hash *rh)
+{
+       int i;
+
+       /* wait for any recovering regions */
+       for (i = 0; i < MAX_RECOVERY; i++)
+               down(&rh->recovery_count);
+}
+
+static void rh_start_recovery(struct region_hash *rh)
+{
+       int i;
+
+       for (i = 0; i < MAX_RECOVERY; i++)
+               up(&rh->recovery_count);
+
+       wake();
+}
+
+/*-----------------------------------------------------------------
+ * Mirror set structures.
+ *---------------------------------------------------------------*/
+struct mirror {
+       atomic_t error_count;
+       struct dm_dev *dev;
+       sector_t offset;
+};
+
+struct mirror_set {
+       struct dm_target *ti;
+       struct list_head list;
+       struct region_hash rh;
+       struct kcopyd_client *kcopyd_client;
+
+       spinlock_t lock;        /* protects the next two lists */
+       struct bio_list reads;
+       struct bio_list writes;
+
+       /* recovery */
+       region_t nr_regions;
+       int in_sync;
+
+       unsigned int nr_mirrors;
+       struct mirror mirror[0];
+};
+
+/*
+ * Every mirror should look like this one.
+ */
+#define DEFAULT_MIRROR 0
+
+/*
+ * This is yucky.  We squirrel the mirror_set struct away inside
+ * bi_next for write buffers.  This is safe since the bh
+ * doesn't get submitted to the lower levels of block layer.
+ */
+static struct mirror_set *bio_get_ms(struct bio *bio)
+{
+       return (struct mirror_set *) bio->bi_next;
+}
+
+static void bio_set_ms(struct bio *bio, struct mirror_set *ms)
+{
+       bio->bi_next = (struct bio *) ms;
+}
+
+/*-----------------------------------------------------------------
+ * Recovery.
+ *
+ * When a mirror is first activated we may find that some regions
+ * are in the no-sync state.  We have to recover these by
+ * recopying from the default mirror to all the others.
+ *---------------------------------------------------------------*/
+static void recovery_complete(int read_err, unsigned int write_err,
+                             void *context)
+{
+       struct region *reg = (struct region *) context;
+
+       /* FIXME: better error handling */
+       rh_recovery_end(reg, read_err || write_err);
+}
+
+static int recover(struct mirror_set *ms, struct region *reg)
+{
+       int r;
+       unsigned int i;
+       struct io_region from, to[ms->nr_mirrors - 1], *dest;
+       struct mirror *m;
+       unsigned long flags = 0;
+
+       /* fill in the source */
+       m = ms->mirror + DEFAULT_MIRROR;
+       from.bdev = m->dev->bdev;
+       from.sector = m->offset + region_to_sector(reg->rh, reg->key);
+       if (reg->key == (ms->nr_regions - 1)) {
+               /*
+                * The final region may be smaller than
+                * region_size.
+                */
+               from.count = ms->ti->len & (reg->rh->region_size - 1);
+               if (!from.count)
+                       from.count = reg->rh->region_size;
+       } else
+               from.count = reg->rh->region_size;
+
+       /* fill in the destinations */
+       for (i = 0, dest = to; i < ms->nr_mirrors; i++) {
+               if (i == DEFAULT_MIRROR)
+                       continue;
+
+               m = ms->mirror + i;
+               dest->bdev = m->dev->bdev;
+               dest->sector = m->offset + region_to_sector(reg->rh, reg->key);
+               dest->count = from.count;
+               dest++;
+       }
+
+       /* hand to kcopyd */
+       set_bit(KCOPYD_IGNORE_ERROR, &flags);
+       r = kcopyd_copy(ms->kcopyd_client, &from, ms->nr_mirrors - 1, to, flags,
+                       recovery_complete, reg);
+
+       return r;
+}
+
+static void do_recovery(struct mirror_set *ms)
+{
+       int r;
+       struct region *reg;
+       struct dirty_log *log = ms->rh.log;
+
+       /*
+        * Start quiescing some regions.
+        */
+       rh_recovery_prepare(&ms->rh);
+
+       /*
+        * Copy any already quiesced regions.
+        */
+       while ((reg = rh_recovery_start(&ms->rh))) {
+               r = recover(ms, reg);
+               if (r)
+                       rh_recovery_end(reg, 0);
+       }
+
+       /*
+        * Update the in sync flag.
+        */
+       if (!ms->in_sync &&
+           (log->type->get_sync_count(log) == ms->nr_regions)) {
+               /* the sync is complete */
+               dm_table_event(ms->ti->table);
+               ms->in_sync = 1;
+       }
+}
+
+/*-----------------------------------------------------------------
+ * Reads
+ *---------------------------------------------------------------*/
+static struct mirror *choose_mirror(struct mirror_set *ms, sector_t sector)
+{
+       /* FIXME: add read balancing */
+       return ms->mirror + DEFAULT_MIRROR;
+}
+
+/*
+ * remap a buffer to a particular mirror.
+ */
+static void map_bio(struct mirror_set *ms, struct mirror *m, struct bio *bio)
+{
+       bio->bi_bdev = m->dev->bdev;
+       bio->bi_sector = m->offset + (bio->bi_sector - ms->ti->begin);
+}
+
+static void do_reads(struct mirror_set *ms, struct bio_list *reads)
+{
+       region_t region;
+       struct bio *bio;
+       struct mirror *m;
+
+       while ((bio = bio_list_pop(reads))) {
+               region = bio_to_region(&ms->rh, bio);
+
+               /*
+                * We can only read balance if the region is in sync.
+                */
+               if (rh_in_sync(&ms->rh, region, 0))
+                       m = choose_mirror(ms, bio->bi_sector);
+               else
+                       m = ms->mirror + DEFAULT_MIRROR;
+
+               map_bio(ms, m, bio);
+               generic_make_request(bio);
+       }
+}
+
+/*-----------------------------------------------------------------
+ * Writes.
+ *
+ * We do different things with the write io depending on the
+ * state of the region that it's in:
+ *
+ * SYNC:       increment pending, use kcopyd to write to *all* mirrors
+ * RECOVERING: delay the io until recovery completes
+ * NOSYNC:     increment pending, just write to the default mirror
+ *---------------------------------------------------------------*/
+static void write_callback(unsigned long error, void *context)
+{
+       unsigned int i;
+       int uptodate = 1;
+       struct bio *bio = (struct bio *) context;
+       struct mirror_set *ms;
+
+       ms = bio_get_ms(bio);
+       bio_set_ms(bio, NULL);
+
+       /*
+        * NOTE: We don't decrement the pending count here,
+        * instead it is done by the targets endio function.
+        * This way we handle both writes to SYNC and NOSYNC
+        * regions with the same code.
+        */
+
+       if (error) {
+               /*
+                * only error the io if all mirrors failed.
+                * FIXME: bogus
+                */
+               uptodate = 0;
+               for (i = 0; i < ms->nr_mirrors; i++)
+                       if (!test_bit(i, &error)) {
+                               uptodate = 1;
+                               break;
+                       }
+       }
+       bio_endio(bio, bio->bi_size, 0);
+}
+
+static void do_write(struct mirror_set *ms, struct bio *bio)
+{
+       unsigned int i;
+       struct io_region io[ms->nr_mirrors];
+       struct mirror *m;
+
+       for (i = 0; i < ms->nr_mirrors; i++) {
+               m = ms->mirror + i;
+
+               io[i].bdev = m->dev->bdev;
+               io[i].sector = m->offset + (bio->bi_sector - ms->ti->begin);
+               io[i].count = bio->bi_size >> 9;
+       }
+
+       bio_set_ms(bio, ms);
+       dm_io_async_bvec(ms->nr_mirrors, io, WRITE,
+                        bio->bi_io_vec + bio->bi_idx,
+                        write_callback, bio);
+}
+
+static void do_writes(struct mirror_set *ms, struct bio_list *writes)
+{
+       int state;
+       struct bio *bio;
+       struct bio_list sync, nosync, recover, *this_list = NULL;
+
+       if (!writes->head)
+               return;
+
+       /*
+        * Classify each write.
+        */
+       bio_list_init(&sync);
+       bio_list_init(&nosync);
+       bio_list_init(&recover);
+
+       while ((bio = bio_list_pop(writes))) {
+               state = rh_state(&ms->rh, bio_to_region(&ms->rh, bio), 1);
+               switch (state) {
+               case RH_CLEAN:
+               case RH_DIRTY:
+                       this_list = &sync;
+                       break;
+
+               case RH_NOSYNC:
+                       this_list = &nosync;
+                       break;
+
+               case RH_RECOVERING:
+                       this_list = &recover;
+                       break;
+               }
+
+               bio_list_add(this_list, bio);
+       }
+
+       /*
+        * Increment the pending counts for any regions that will
+        * be written to (writes to recover regions are going to
+        * be delayed).
+        */
+       rh_inc_pending(&ms->rh, &sync);
+       rh_inc_pending(&ms->rh, &nosync);
+       rh_flush(&ms->rh);
+
+       /*
+        * Dispatch io.
+        */
+       while ((bio = bio_list_pop(&sync)))
+               do_write(ms, bio);
+
+       while ((bio = bio_list_pop(&recover)))
+               rh_delay(&ms->rh, bio);
+
+       while ((bio = bio_list_pop(&nosync))) {
+               map_bio(ms, ms->mirror + DEFAULT_MIRROR, bio);
+               generic_make_request(bio);
+       }
+}
+
+/*-----------------------------------------------------------------
+ * kmirrord
+ *---------------------------------------------------------------*/
+static LIST_HEAD(_mirror_sets);
+static DECLARE_RWSEM(_mirror_sets_lock);
+
+static void do_mirror(struct mirror_set *ms)
+{
+       struct bio_list reads, writes;
+
+       spin_lock(&ms->lock);
+       reads = ms->reads;
+       writes = ms->writes;
+       bio_list_init(&ms->reads);
+       bio_list_init(&ms->writes);
+       spin_unlock(&ms->lock);
+
+       rh_update_states(&ms->rh);
+       do_recovery(ms);
+       do_reads(ms, &reads);
+       do_writes(ms, &writes);
+}
+
+static void do_work(void *ignored)
+{
+       struct mirror_set *ms;
+
+       down_read(&_mirror_sets_lock);
+       list_for_each_entry (ms, &_mirror_sets, list)
+               do_mirror(ms);
+       up_read(&_mirror_sets_lock);
+}
+
+/*-----------------------------------------------------------------
+ * Target functions
+ *---------------------------------------------------------------*/
+static struct mirror_set *alloc_context(unsigned int nr_mirrors,
+                                       sector_t region_size,
+                                       struct dm_target *ti,
+                                       struct dirty_log *dl)
+{
+       size_t len;
+       struct mirror_set *ms = NULL;
+
+       if (array_too_big(sizeof(*ms), sizeof(ms->mirror[0]), nr_mirrors))
+               return NULL;
+
+       len = sizeof(*ms) + (sizeof(ms->mirror[0]) * nr_mirrors);
+
+       ms = kmalloc(len, GFP_KERNEL);
+       if (!ms) {
+               ti->error = "dm-mirror: Cannot allocate mirror context";
+               return NULL;
+       }
+
+       memset(ms, 0, len);
+       spin_lock_init(&ms->lock);
+
+       ms->ti = ti;
+       ms->nr_mirrors = nr_mirrors;
+       ms->nr_regions = dm_div_up(ti->len, region_size);
+       ms->in_sync = 0;
+
+       if (rh_init(&ms->rh, ms, dl, region_size, ms->nr_regions)) {
+               ti->error = "dm-mirror: Error creating dirty region hash";
+               kfree(ms);
+               return NULL;
+       }
+
+       return ms;
+}
+
+static void free_context(struct mirror_set *ms, struct dm_target *ti,
+                        unsigned int m)
+{
+       while (m--)
+               dm_put_device(ti, ms->mirror[m].dev);
+
+       rh_exit(&ms->rh);
+       kfree(ms);
+}
+
+static inline int _check_region_size(struct dm_target *ti, sector_t size)
+{
+       return !(size % (PAGE_SIZE >> 9) || (size & (size - 1)) ||
+                size > ti->len);
+}
+
+static int get_mirror(struct mirror_set *ms, struct dm_target *ti,
+                     unsigned int mirror, char **argv)
+{
+       sector_t offset;
+
+       if (sscanf(argv[1], SECTOR_FORMAT, &offset) != 1) {
+               ti->error = "dm-mirror: Invalid offset";
+               return -EINVAL;
+       }
+
+       if (dm_get_device(ti, argv[0], offset, ti->len,
+                         dm_table_get_mode(ti->table),
+                         &ms->mirror[mirror].dev)) {
+               ti->error = "dm-mirror: Device lookup failure";
+               return -ENXIO;
+       }
+
+       ms->mirror[mirror].offset = offset;
+
+       return 0;
+}
+
+static int add_mirror_set(struct mirror_set *ms)
+{
+       down_write(&_mirror_sets_lock);
+       list_add_tail(&ms->list, &_mirror_sets);
+       up_write(&_mirror_sets_lock);
+       wake();
+
+       return 0;
+}
+
+static void del_mirror_set(struct mirror_set *ms)
+{
+       down_write(&_mirror_sets_lock);
+       list_del(&ms->list);
+       up_write(&_mirror_sets_lock);
+}
+
+/*
+ * Create dirty log: log_type #log_params <log_params>
+ */
+static struct dirty_log *create_dirty_log(struct dm_target *ti,
+                                         unsigned int argc, char **argv,
+                                         unsigned int *args_used)
+{
+       unsigned int param_count;
+       struct dirty_log *dl;
+
+       if (argc < 2) {
+               ti->error = "dm-mirror: Insufficient mirror log arguments";
+               return NULL;
+       }
+
+       if (sscanf(argv[1], "%u", &param_count) != 1) {
+               ti->error = "dm-mirror: Invalid mirror log argument count";
+               return NULL;
+       }
+
+       *args_used = 2 + param_count;
+
+       if (argc < *args_used) {
+               ti->error = "dm-mirror: Insufficient mirror log arguments";
+               return NULL;
+       }
+
+       dl = dm_create_dirty_log(argv[0], ti, param_count, argv + 2);
+       if (!dl) {
+               ti->error = "dm-mirror: Error creating mirror dirty log";
+               return NULL;
+       }
+
+       if (!_check_region_size(ti, dl->type->get_region_size(dl))) {
+               ti->error = "dm-mirror: Invalid region size";
+               dm_destroy_dirty_log(dl);
+               return NULL;
+       }
+
+       return dl;
+}
+
+/*
+ * Construct a mirror mapping:
+ *
+ * log_type #log_params <log_params>
+ * #mirrors [mirror_path offset]{2,}
+ *
+ * For now, #log_params = 1, log_type = "core"
+ *
+ */
+#define DM_IO_PAGES 64
+static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+{
+       int r;
+       unsigned int nr_mirrors, m, args_used;
+       struct mirror_set *ms;
+       struct dirty_log *dl;
+
+       dl = create_dirty_log(ti, argc, argv, &args_used);
+       if (!dl)
+               return -EINVAL;
+
+       argv += args_used;
+       argc -= args_used;
+
+       if (!argc || sscanf(argv[0], "%u", &nr_mirrors) != 1 ||
+           nr_mirrors < 2) {
+               ti->error = "dm-mirror: Invalid number of mirrors";
+               dm_destroy_dirty_log(dl);
+               return -EINVAL;
+       }
+
+       argv++, argc--;
+
+       if (argc != nr_mirrors * 2) {
+               ti->error = "dm-mirror: Wrong number of mirror arguments";
+               dm_destroy_dirty_log(dl);
+               return -EINVAL;
+       }
+
+       ms = alloc_context(nr_mirrors, dl->type->get_region_size(dl), ti, dl);
+       if (!ms) {
+               dm_destroy_dirty_log(dl);
+               return -ENOMEM;
+       }
+
+       /* Get the mirror parameter sets */
+       for (m = 0; m < nr_mirrors; m++) {
+               r = get_mirror(ms, ti, m, argv);
+               if (r) {
+                       free_context(ms, ti, m);
+                       return r;
+               }
+               argv += 2;
+               argc -= 2;
+       }
+
+       ti->private = ms;
+
+       r = kcopyd_client_create(DM_IO_PAGES, &ms->kcopyd_client);
+       if (r) {
+               free_context(ms, ti, ms->nr_mirrors);
+               return r;
+       }
+
+       add_mirror_set(ms);
+       return 0;
+}
+
+static void mirror_dtr(struct dm_target *ti)
+{
+       struct mirror_set *ms = (struct mirror_set *) ti->private;
+
+       del_mirror_set(ms);
+       kcopyd_client_destroy(ms->kcopyd_client);
+       free_context(ms, ti, ms->nr_mirrors);
+}
+
+static void queue_bio(struct mirror_set *ms, struct bio *bio, int rw)
+{
+       int should_wake = 0;
+       struct bio_list *bl;
+
+       bl = (rw == WRITE) ? &ms->writes : &ms->reads;
+       spin_lock(&ms->lock);
+       should_wake = !(bl->head);
+       bio_list_add(bl, bio);
+       spin_unlock(&ms->lock);
+
+       if (should_wake)
+               wake();
+}
+
+/*
+ * Mirror mapping function
+ */
+static int mirror_map(struct dm_target *ti, struct bio *bio,
+                     union map_info *map_context)
+{
+       int r, rw = bio_rw(bio);
+       struct mirror *m;
+       struct mirror_set *ms = ti->private;
+
+       map_context->ll = bio->bi_sector >> ms->rh.region_shift;
+
+       if (rw == WRITE) {
+               queue_bio(ms, bio, rw);
+               return 0;
+       }
+
+       r = ms->rh.log->type->in_sync(ms->rh.log,
+                                     bio_to_region(&ms->rh, bio), 0);
+       if (r < 0 && r != -EWOULDBLOCK)
+               return r;
+
+       if (r == -EWOULDBLOCK)  /* FIXME: ugly */
+               r = 0;
+
+       /*
+        * We don't want to fast track a recovery just for a read
+        * ahead.  So we just let it silently fail.
+        * FIXME: get rid of this.
+        */
+       if (!r && rw == READA)
+               return -EIO;
+
+       if (!r) {
+               /* Pass this io over to the daemon */
+               queue_bio(ms, bio, rw);
+               return 0;
+       }
+
+       m = choose_mirror(ms, bio->bi_sector);
+       if (!m)
+               return -EIO;
+
+       map_bio(ms, m, bio);
+       return 1;
+}
+
+static int mirror_end_io(struct dm_target *ti, struct bio *bio,
+                        int error, union map_info *map_context)
+{
+       int rw = bio_rw(bio);
+       struct mirror_set *ms = (struct mirror_set *) ti->private;
+       region_t region = map_context->ll;
+
+       /*
+        * We need to dec pending if this was a write.
+        */
+       if (rw == WRITE)
+               rh_dec(&ms->rh, region);
+
+       return 0;
+}
+
+static void mirror_suspend(struct dm_target *ti)
+{
+       struct mirror_set *ms = (struct mirror_set *) ti->private;
+       struct dirty_log *log = ms->rh.log;
+       rh_stop_recovery(&ms->rh);
+       if (log->type->suspend && log->type->suspend(log))
+               /* FIXME: need better error handling */
+               DMWARN("log suspend failed");
+}
+
+static void mirror_resume(struct dm_target *ti)
+{
+       struct mirror_set *ms = (struct mirror_set *) ti->private;
+       struct dirty_log *log = ms->rh.log;
+       if (log->type->resume && log->type->resume(log))
+               /* FIXME: need better error handling */
+               DMWARN("log resume failed");
+       rh_start_recovery(&ms->rh);
+}
+
+static int mirror_status(struct dm_target *ti, status_type_t type,
+                        char *result, unsigned int maxlen)
+{
+       char buffer[32];
+       unsigned int m, sz = 0;
+       struct mirror_set *ms = (struct mirror_set *) ti->private;
+
+#define EMIT(x...) sz += ((sz >= maxlen) ? \
+                         0 : scnprintf(result + sz, maxlen - sz, x))
+
+       switch (type) {
+       case STATUSTYPE_INFO:
+               EMIT("%d ", ms->nr_mirrors);
+
+               for (m = 0; m < ms->nr_mirrors; m++) {
+                       format_dev_t(buffer, ms->mirror[m].dev->bdev->bd_dev);
+                       EMIT("%s ", buffer);
+               }
+
+               EMIT(SECTOR_FORMAT "/" SECTOR_FORMAT,
+                    ms->rh.log->type->get_sync_count(ms->rh.log),
+                    ms->nr_regions);
+               break;
+
+       case STATUSTYPE_TABLE:
+               EMIT("%s 1 " SECTOR_FORMAT " %d ",
+                    ms->rh.log->type->name, ms->rh.region_size,
+                    ms->nr_mirrors);
+
+               for (m = 0; m < ms->nr_mirrors; m++) {
+                       format_dev_t(buffer, ms->mirror[m].dev->bdev->bd_dev);
+                       EMIT("%s " SECTOR_FORMAT " ",
+                            buffer, ms->mirror[m].offset);
+               }
+       }
+
+       return 0;
+}
+
+static struct target_type mirror_target = {
+       .name    = "mirror",
+       .version = {1, 0, 1},
+       .module  = THIS_MODULE,
+       .ctr     = mirror_ctr,
+       .dtr     = mirror_dtr,
+       .map     = mirror_map,
+       .end_io  = mirror_end_io,
+       .suspend = mirror_suspend,
+       .resume  = mirror_resume,
+       .status  = mirror_status,
+};
+
+static int __init dm_mirror_init(void)
+{
+       int r;
+
+       r = dm_dirty_log_init();
+       if (r)
+               return r;
+
+       _kmirrord_wq = create_workqueue("kmirrord");
+       if (!_kmirrord_wq) {
+               DMERR("couldn't start kmirrord");
+               dm_dirty_log_exit();
+               return r;
+       }
+       INIT_WORK(&_kmirrord_work, do_work, NULL);
+
+       r = dm_register_target(&mirror_target);
+       if (r < 0) {
+               DMERR("%s: Failed to register mirror target",
+                     mirror_target.name);
+               dm_dirty_log_exit();
+               destroy_workqueue(_kmirrord_wq);
+       }
+
+       return r;
+}
+
+static void __exit dm_mirror_exit(void)
+{
+       int r;
+
+       r = dm_unregister_target(&mirror_target);
+       if (r < 0)
+               DMERR("%s: unregister failed %d", mirror_target.name, r);
+
+       destroy_workqueue(_kmirrord_wq);
+       dm_dirty_log_exit();
+}
+
+/* Module hooks */
+module_init(dm_mirror_init);
+module_exit(dm_mirror_exit);
+
+MODULE_DESCRIPTION(DM_NAME " mirror target");
+MODULE_AUTHOR("Joe Thornber");
+MODULE_LICENSE("GPL");
diff --git a/drivers/md/kcopyd.c b/drivers/md/kcopyd.c
new file mode 100644 (file)
index 0000000..40e4694
--- /dev/null
@@ -0,0 +1,699 @@
+/*
+ * Copyright (C) 2002 Sistina Software (UK) Limited.
+ *
+ * This file is released under the GPL.
+ *
+ * Kcopyd provides a simple interface for copying an area of one
+ * block-device to one or more other block-devices, with an asynchronous
+ * completion notification.
+ */
+
+#include <asm/atomic.h>
+
+#include <linux/blkdev.h>
+#include <linux/config.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/mempool.h>
+#include <linux/module.h>
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/workqueue.h>
+
+#include "kcopyd.h"
+
+/* FIXME: this is only needed for the DMERR macros */
+#include "dm.h"
+
+static struct workqueue_struct *_kcopyd_wq;
+static struct work_struct _kcopyd_work;
+
+static inline void wake(void)
+{
+       queue_work(_kcopyd_wq, &_kcopyd_work);
+}
+
+/*-----------------------------------------------------------------
+ * Each kcopyd client has its own little pool of preallocated
+ * pages for kcopyd io.
+ *---------------------------------------------------------------*/
+struct kcopyd_client {
+       struct list_head list;
+
+       spinlock_t lock;
+       struct page_list *pages;
+       unsigned int nr_pages;
+       unsigned int nr_free_pages;
+};
+
+static struct page_list *alloc_pl(void)
+{
+       struct page_list *pl;
+
+       pl = kmalloc(sizeof(*pl), GFP_KERNEL);
+       if (!pl)
+               return NULL;
+
+       pl->page = alloc_page(GFP_KERNEL);
+       if (!pl->page) {
+               kfree(pl);
+               return NULL;
+       }
+
+       return pl;
+}
+
+static void free_pl(struct page_list *pl)
+{
+       __free_page(pl->page);
+       kfree(pl);
+}
+
+static int kcopyd_get_pages(struct kcopyd_client *kc,
+                           unsigned int nr, struct page_list **pages)
+{
+       struct page_list *pl;
+
+       spin_lock(&kc->lock);
+       if (kc->nr_free_pages < nr) {
+               spin_unlock(&kc->lock);
+               return -ENOMEM;
+       }
+
+       kc->nr_free_pages -= nr;
+       for (*pages = pl = kc->pages; --nr; pl = pl->next)
+               ;
+
+       kc->pages = pl->next;
+       pl->next = 0;
+
+       spin_unlock(&kc->lock);
+
+       return 0;
+}
+
+static void kcopyd_put_pages(struct kcopyd_client *kc, struct page_list *pl)
+{
+       struct page_list *cursor;
+
+       spin_lock(&kc->lock);
+       for (cursor = pl; cursor->next; cursor = cursor->next)
+               kc->nr_free_pages++;
+
+       kc->nr_free_pages++;
+       cursor->next = kc->pages;
+       kc->pages = pl;
+       spin_unlock(&kc->lock);
+}
+
+/*
+ * These three functions resize the page pool.
+ */
+static void drop_pages(struct page_list *pl)
+{
+       struct page_list *next;
+
+       while (pl) {
+               next = pl->next;
+               free_pl(pl);
+               pl = next;
+       }
+}
+
+static int client_alloc_pages(struct kcopyd_client *kc, unsigned int nr)
+{
+       unsigned int i;
+       struct page_list *pl = NULL, *next;
+
+       for (i = 0; i < nr; i++) {
+               next = alloc_pl();
+               if (!next) {
+                       if (pl)
+                               drop_pages(pl);
+                       return -ENOMEM;
+               }
+               next->next = pl;
+               pl = next;
+       }
+
+       kcopyd_put_pages(kc, pl);
+       kc->nr_pages += nr;
+       return 0;
+}
+
+static void client_free_pages(struct kcopyd_client *kc)
+{
+       BUG_ON(kc->nr_free_pages != kc->nr_pages);
+       drop_pages(kc->pages);
+       kc->pages = NULL;
+       kc->nr_free_pages = kc->nr_pages = 0;
+}
+
+/*-----------------------------------------------------------------
+ * kcopyd_jobs need to be allocated by the *clients* of kcopyd,
+ * for this reason we use a mempool to prevent the client from
+ * ever having to do io (which could cause a deadlock).
+ *---------------------------------------------------------------*/
+struct kcopyd_job {
+       struct kcopyd_client *kc;
+       struct list_head list;
+       unsigned long flags;
+
+       /*
+        * Error state of the job.
+        */
+       int read_err;
+       unsigned int write_err;
+
+       /*
+        * Either READ or WRITE
+        */
+       int rw;
+       struct io_region source;
+
+       /*
+        * The destinations for the transfer.
+        */
+       unsigned int num_dests;
+       struct io_region dests[KCOPYD_MAX_REGIONS];
+
+       sector_t offset;
+       unsigned int nr_pages;
+       struct page_list *pages;
+
+       /*
+        * Set this to ensure you are notified when the job has
+        * completed.  'context' is for callback to use.
+        */
+       kcopyd_notify_fn fn;
+       void *context;
+
+       /*
+        * These fields are only used if the job has been split
+        * into more manageable parts.
+        */
+       struct semaphore lock;
+       atomic_t sub_jobs;
+       sector_t progress;
+};
+
+/* FIXME: this should scale with the number of pages */
+#define MIN_JOBS 512
+
+static kmem_cache_t *_job_cache;
+static mempool_t *_job_pool;
+
+/*
+ * We maintain three lists of jobs:
+ *
+ * i)   jobs waiting for pages
+ * ii)  jobs that have pages, and are waiting for the io to be issued.
+ * iii) jobs that have completed.
+ *
+ * All three of these are protected by job_lock.
+ */
+static spinlock_t _job_lock = SPIN_LOCK_UNLOCKED;
+
+static LIST_HEAD(_complete_jobs);
+static LIST_HEAD(_io_jobs);
+static LIST_HEAD(_pages_jobs);
+
+static int jobs_init(void)
+{
+       _job_cache = kmem_cache_create("kcopyd-jobs",
+                                      sizeof(struct kcopyd_job),
+                                      __alignof__(struct kcopyd_job),
+                                      0, NULL, NULL);
+       if (!_job_cache)
+               return -ENOMEM;
+
+       _job_pool = mempool_create(MIN_JOBS, mempool_alloc_slab,
+                                  mempool_free_slab, _job_cache);
+       if (!_job_pool) {
+               kmem_cache_destroy(_job_cache);
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+static void jobs_exit(void)
+{
+       BUG_ON(!list_empty(&_complete_jobs));
+       BUG_ON(!list_empty(&_io_jobs));
+       BUG_ON(!list_empty(&_pages_jobs));
+
+       mempool_destroy(_job_pool);
+       kmem_cache_destroy(_job_cache);
+       _job_pool = NULL;
+       _job_cache = NULL;
+}
+
+/*
+ * Functions to push and pop a job onto the head of a given job
+ * list.
+ */
+static inline struct kcopyd_job *pop(struct list_head *jobs)
+{
+       struct kcopyd_job *job = NULL;
+       unsigned long flags;
+
+       spin_lock_irqsave(&_job_lock, flags);
+
+       if (!list_empty(jobs)) {
+               job = list_entry(jobs->next, struct kcopyd_job, list);
+               list_del(&job->list);
+       }
+       spin_unlock_irqrestore(&_job_lock, flags);
+
+       return job;
+}
+
+static inline void push(struct list_head *jobs, struct kcopyd_job *job)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&_job_lock, flags);
+       list_add_tail(&job->list, jobs);
+       spin_unlock_irqrestore(&_job_lock, flags);
+}
+
+/*
+ * These three functions process 1 item from the corresponding
+ * job list.
+ *
+ * They return:
+ * < 0: error
+ *   0: success
+ * > 0: can't process yet.
+ */
+static int run_complete_job(struct kcopyd_job *job)
+{
+       void *context = job->context;
+       int read_err = job->read_err;
+       unsigned int write_err = job->write_err;
+       kcopyd_notify_fn fn = job->fn;
+
+       kcopyd_put_pages(job->kc, job->pages);
+       mempool_free(job, _job_pool);
+       fn(read_err, write_err, context);
+       return 0;
+}
+
+static void complete_io(unsigned long error, void *context)
+{
+       struct kcopyd_job *job = (struct kcopyd_job *) context;
+
+       if (error) {
+               if (job->rw == WRITE)
+                       job->write_err &= error;
+               else
+                       job->read_err = 1;
+
+               if (!test_bit(KCOPYD_IGNORE_ERROR, &job->flags)) {
+                       push(&_complete_jobs, job);
+                       wake();
+                       return;
+               }
+       }
+
+       if (job->rw == WRITE)
+               push(&_complete_jobs, job);
+
+       else {
+               job->rw = WRITE;
+               push(&_io_jobs, job);
+       }
+
+       wake();
+}
+
+/*
+ * Request io on as many buffer heads as we can currently get for
+ * a particular job.
+ */
+static int run_io_job(struct kcopyd_job *job)
+{
+       int r;
+
+       if (job->rw == READ)
+               r = dm_io_async(1, &job->source, job->rw,
+                               job->pages,
+                               job->offset, complete_io, job);
+
+       else
+               r = dm_io_async(job->num_dests, job->dests, job->rw,
+                               job->pages,
+                               job->offset, complete_io, job);
+
+       return r;
+}
+
+static int run_pages_job(struct kcopyd_job *job)
+{
+       int r;
+
+       job->nr_pages = dm_div_up(job->dests[0].count + job->offset,
+                                 PAGE_SIZE >> 9);
+       r = kcopyd_get_pages(job->kc, job->nr_pages, &job->pages);
+       if (!r) {
+               /* this job is ready for io */
+               push(&_io_jobs, job);
+               return 0;
+       }
+
+       if (r == -ENOMEM)
+               /* can't complete now */
+               return 1;
+
+       return r;
+}
+
+/*
+ * Run through a list for as long as possible.  Returns the count
+ * of successful jobs.
+ */
+static int process_jobs(struct list_head *jobs, int (*fn) (struct kcopyd_job *))
+{
+       struct kcopyd_job *job;
+       int r, count = 0;
+
+       while ((job = pop(jobs))) {
+
+               r = fn(job);
+
+               if (r < 0) {
+                       /* error this rogue job */
+                       if (job->rw == WRITE)
+                               job->write_err = (unsigned int) -1;
+                       else
+                               job->read_err = 1;
+                       push(&_complete_jobs, job);
+                       break;
+               }
+
+               if (r > 0) {
+                       /*
+                        * We couldn't service this job ATM, so
+                        * push this job back onto the list.
+                        */
+                       push(jobs, job);
+                       break;
+               }
+
+               count++;
+       }
+
+       return count;
+}
+
+/*
+ * kcopyd does this every time it's woken up.
+ */
+static void do_work(void *ignored)
+{
+       /*
+        * The order that these are called is *very* important.
+        * complete jobs can free some pages for pages jobs.
+        * Pages jobs when successful will jump onto the io jobs
+        * list.  io jobs call wake when they complete and it all
+        * starts again.
+        */
+       process_jobs(&_complete_jobs, run_complete_job);
+       process_jobs(&_pages_jobs, run_pages_job);
+       process_jobs(&_io_jobs, run_io_job);
+}
+
+/*
+ * If we are copying a small region we just dispatch a single job
+ * to do the copy, otherwise the io has to be split up into many
+ * jobs.
+ */
+static void dispatch_job(struct kcopyd_job *job)
+{
+       push(&_pages_jobs, job);
+       wake();
+}
+
+#define SUB_JOB_SIZE 128
+static void segment_complete(int read_err,
+                            unsigned int write_err, void *context)
+{
+       /* FIXME: tidy this function */
+       sector_t progress = 0;
+       sector_t count = 0;
+       struct kcopyd_job *job = (struct kcopyd_job *) context;
+
+       down(&job->lock);
+
+       /* update the error */
+       if (read_err)
+               job->read_err = 1;
+
+       if (write_err)
+               job->write_err &= write_err;
+
+       /*
+        * Only dispatch more work if there hasn't been an error.
+        */
+       if ((!job->read_err && !job->write_err) ||
+           test_bit(KCOPYD_IGNORE_ERROR, &job->flags)) {
+               /* get the next chunk of work */
+               progress = job->progress;
+               count = job->source.count - progress;
+               if (count) {
+                       if (count > SUB_JOB_SIZE)
+                               count = SUB_JOB_SIZE;
+
+                       job->progress += count;
+               }
+       }
+       up(&job->lock);
+
+       if (count) {
+               int i;
+               struct kcopyd_job *sub_job = mempool_alloc(_job_pool, GFP_NOIO);
+
+               *sub_job = *job;
+               sub_job->source.sector += progress;
+               sub_job->source.count = count;
+
+               for (i = 0; i < job->num_dests; i++) {
+                       sub_job->dests[i].sector += progress;
+                       sub_job->dests[i].count = count;
+               }
+
+               sub_job->fn = segment_complete;
+               sub_job->context = job;
+               dispatch_job(sub_job);
+
+       } else if (atomic_dec_and_test(&job->sub_jobs)) {
+
+               /*
+                * To avoid a race we must keep the job around
+                * until after the notify function has completed.
+                * Otherwise the client may try and stop the job
+                * after we've completed.
+                */
+               job->fn(read_err, write_err, job->context);
+               mempool_free(job, _job_pool);
+       }
+}
+
+/*
+ * Create some little jobs that will do the move between
+ * them.
+ */
+#define SPLIT_COUNT 8
+static void split_job(struct kcopyd_job *job)
+{
+       int i;
+
+       atomic_set(&job->sub_jobs, SPLIT_COUNT);
+       for (i = 0; i < SPLIT_COUNT; i++)
+               segment_complete(0, 0u, job);
+}
+
+int kcopyd_copy(struct kcopyd_client *kc, struct io_region *from,
+               unsigned int num_dests, struct io_region *dests,
+               unsigned int flags, kcopyd_notify_fn fn, void *context)
+{
+       struct kcopyd_job *job;
+
+       /*
+        * Allocate a new job.
+        */
+       job = mempool_alloc(_job_pool, GFP_NOIO);
+
+       /*
+        * set up for the read.
+        */
+       job->kc = kc;
+       job->flags = flags;
+       job->read_err = 0;
+       job->write_err = 0;
+       job->rw = READ;
+
+       job->source = *from;
+
+       job->num_dests = num_dests;
+       memcpy(&job->dests, dests, sizeof(*dests) * num_dests);
+
+       job->offset = 0;
+       job->nr_pages = 0;
+       job->pages = NULL;
+
+       job->fn = fn;
+       job->context = context;
+
+       if (job->source.count < SUB_JOB_SIZE)
+               dispatch_job(job);
+
+       else {
+               init_MUTEX(&job->lock);
+               job->progress = 0;
+               split_job(job);
+       }
+
+       return 0;
+}
+
+/*
+ * Cancels a kcopyd job, eg. someone might be deactivating a
+ * mirror.
+ */
+int kcopyd_cancel(struct kcopyd_job *job, int block)
+{
+       /* FIXME: finish */
+       return -1;
+}
+
+/*-----------------------------------------------------------------
+ * Unit setup
+ *---------------------------------------------------------------*/
+static DECLARE_MUTEX(_client_lock);
+static LIST_HEAD(_clients);
+
+static int client_add(struct kcopyd_client *kc)
+{
+       down(&_client_lock);
+       list_add(&kc->list, &_clients);
+       up(&_client_lock);
+       return 0;
+}
+
+static void client_del(struct kcopyd_client *kc)
+{
+       down(&_client_lock);
+       list_del(&kc->list);
+       up(&_client_lock);
+}
+
+static DECLARE_MUTEX(kcopyd_init_lock);
+static int kcopyd_clients = 0;
+
+static int kcopyd_init(void)
+{
+       int r;
+
+       down(&kcopyd_init_lock);
+
+       if (kcopyd_clients) {
+               /* Already initialized. */
+               kcopyd_clients++;
+               up(&kcopyd_init_lock);
+               return 0;
+       }
+
+       r = jobs_init();
+       if (r) {
+               up(&kcopyd_init_lock);
+               return r;
+       }
+
+       _kcopyd_wq = create_singlethread_workqueue("kcopyd");
+       if (!_kcopyd_wq) {
+               jobs_exit();
+               up(&kcopyd_init_lock);
+               return -ENOMEM;
+       }
+
+       kcopyd_clients++;
+       INIT_WORK(&_kcopyd_work, do_work, NULL);
+       up(&kcopyd_init_lock);
+       return 0;
+}
+
+static void kcopyd_exit(void)
+{
+       down(&kcopyd_init_lock);
+       kcopyd_clients--;
+       if (!kcopyd_clients) {
+               jobs_exit();
+               destroy_workqueue(_kcopyd_wq);
+               _kcopyd_wq = NULL;
+       }
+       up(&kcopyd_init_lock);
+}
+
+int kcopyd_client_create(unsigned int nr_pages, struct kcopyd_client **result)
+{
+       int r = 0;
+       struct kcopyd_client *kc;
+
+       r = kcopyd_init();
+       if (r)
+               return r;
+
+       kc = kmalloc(sizeof(*kc), GFP_KERNEL);
+       if (!kc) {
+               kcopyd_exit();
+               return -ENOMEM;
+       }
+
+       kc->lock = SPIN_LOCK_UNLOCKED;
+       kc->pages = NULL;
+       kc->nr_pages = kc->nr_free_pages = 0;
+       r = client_alloc_pages(kc, nr_pages);
+       if (r) {
+               kfree(kc);
+               kcopyd_exit();
+               return r;
+       }
+
+       r = dm_io_get(nr_pages);
+       if (r) {
+               client_free_pages(kc);
+               kfree(kc);
+               kcopyd_exit();
+               return r;
+       }
+
+       r = client_add(kc);
+       if (r) {
+               dm_io_put(nr_pages);
+               client_free_pages(kc);
+               kfree(kc);
+               kcopyd_exit();
+               return r;
+       }
+
+       *result = kc;
+       return 0;
+}
+
+void kcopyd_client_destroy(struct kcopyd_client *kc)
+{
+       dm_io_put(kc->nr_pages);
+       client_free_pages(kc);
+       client_del(kc);
+       kfree(kc);
+       kcopyd_exit();
+}
+
+EXPORT_SYMBOL(kcopyd_client_create);
+EXPORT_SYMBOL(kcopyd_client_destroy);
+EXPORT_SYMBOL(kcopyd_copy);
+EXPORT_SYMBOL(kcopyd_cancel);
diff --git a/drivers/md/kcopyd.h b/drivers/md/kcopyd.h
new file mode 100644 (file)
index 0000000..4621ea0
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2001 Sistina Software
+ *
+ * This file is released under the GPL.
+ *
+ * Kcopyd provides a simple interface for copying an area of one
+ * block-device to one or more other block-devices, with an asynchronous
+ * completion notification.
+ */
+
+#ifndef DM_KCOPYD_H
+#define DM_KCOPYD_H
+
+#include "dm-io.h"
+
+/* FIXME: make this configurable */
+#define KCOPYD_MAX_REGIONS 8
+
+#define KCOPYD_IGNORE_ERROR 1
+
+/*
+ * To use kcopyd you must first create a kcopyd client object.
+ */
+struct kcopyd_client;
+int kcopyd_client_create(unsigned int num_pages, struct kcopyd_client **result);
+void kcopyd_client_destroy(struct kcopyd_client *kc);
+
+/*
+ * Submit a copy job to kcopyd.  This is built on top of the
+ * previous three fns.
+ *
+ * read_err is a boolean,
+ * write_err is a bitset, with 1 bit for each destination region
+ */
+typedef void (*kcopyd_notify_fn)(int read_err,
+                                unsigned int write_err, void *context);
+
+int kcopyd_copy(struct kcopyd_client *kc, struct io_region *from,
+               unsigned int num_dests, struct io_region *dests,
+               unsigned int flags, kcopyd_notify_fn fn, void *context);
+
+#endif
diff --git a/drivers/net/arm/smc91x.c b/drivers/net/arm/smc91x.c
new file mode 100644 (file)
index 0000000..3968a1c
--- /dev/null
@@ -0,0 +1,2171 @@
+/*
+ * smc91x.c
+ * This is a driver for SMSC's 91C9x/91C1xx single-chip Ethernet devices.
+ *
+ * Copyright (C) 1996 by Erik Stahlman
+ * Copyright (C) 2001 Standard Microsystems Corporation
+ *     Developed by Simple Network Magic Corporation
+ * Copyright (C) 2003 Monta Vista Software, Inc.
+ *     Unified SMC91x driver by Nicolas Pitre
+ *
+ * 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
+ *
+ * Arguments:
+ *     io      = for the base address
+ *     irq     = for the IRQ
+ *     nowait  = 0 for normal wait states, 1 eliminates additional wait states
+ *
+ * original author:
+ *     Erik Stahlman <erik@vt.edu>
+ *
+ * hardware multicast code:
+ *    Peter Cammaert <pc@denkart.be>
+ *
+ * contributors:
+ *     Daris A Nevil <dnevil@snmc.com>
+ *      Nicolas Pitre <nico@cam.org>
+ *     Russell King <rmk@arm.linux.org.uk>
+ *
+ * History:
+ *   08/20/00  Arnaldo Melo       fix kfree(skb) in smc_hardware_send_packet
+ *   12/15/00  Christian Jullien  fix "Warning: kfree_skb on hard IRQ"
+ *   03/16/01  Daris A Nevil      modified smc9194.c for use with LAN91C111
+ *   08/22/01  Scott Anderson     merge changes from smc9194 to smc91111
+ *   08/21/01  Pramod B Bhardwaj  added support for RevB of LAN91C111
+ *   12/20/01  Jeff Sutherland    initial port to Xscale PXA with DMA support
+ *   04/07/03  Nicolas Pitre      unified SMC91x driver, killed irq races,
+ *                                more bus abstraction, big cleanup, etc.
+ *   29/09/03  Russell King       - add driver model support
+ *                                - ethtool support
+ *                                - convert to use generic MII interface
+ *                                - add link up/down notification
+ *                                - don't try to handle full negotiation in
+ *                                  smc_phy_configure
+ *                                - clean up (and fix stack overrun) in PHY
+ *                                  MII read/write functions
+ */
+static const char version[] =
+       "smc91x.c: v1.0, mar 07 2003 by Nicolas Pitre <nico@cam.org>\n";
+
+/* Debugging level */
+#ifndef SMC_DEBUG
+#define SMC_DEBUG              0
+#endif
+
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/crc32.h>
+#include <linux/device.h>
+#include <linux/spinlock.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+#include "smc91x.h"
+
+#ifdef CONFIG_ISA
+/*
+ * the LAN91C111 can be at any of the following port addresses.  To change,
+ * for a slightly different card, you can add it to the array.  Keep in
+ * mind that the array must end in zero.
+ */
+static unsigned int smc_portlist[] __initdata = {
+       0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0,
+       0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0, 0
+};
+
+#ifndef SMC_IOADDR
+# define SMC_IOADDR            -1
+#endif
+static unsigned long io = SMC_IOADDR;
+module_param(io, ulong, 0400);
+MODULE_PARM_DESC(io, "I/O base address");
+
+#ifndef SMC_IRQ
+# define SMC_IRQ               -1
+#endif
+static int irq = SMC_IRQ;
+module_param(irq, int, 0400);
+MODULE_PARM_DESC(irq, "IRQ number");
+
+#endif  /* CONFIG_ISA */
+
+#ifndef SMC_NOWAIT
+# define SMC_NOWAIT            0
+#endif
+static int nowait = SMC_NOWAIT;
+module_param(nowait, int, 0400);
+MODULE_PARM_DESC(nowait, "set to 1 for no wait state");
+
+/*
+ * Transmit timeout, default 5 seconds.
+ */
+static int watchdog = 5000;
+module_param(watchdog, int, 0400);
+MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
+
+MODULE_LICENSE("GPL");
+
+/*
+ * The internal workings of the driver.  If you are changing anything
+ * here with the SMC stuff, you should have the datasheet and know
+ * what you are doing.
+ */
+#define CARDNAME "smc91x"
+
+/*
+ * Use power-down feature of the chip
+ */
+#define POWER_DOWN             1
+
+/*
+ * Wait time for memory to be free.  This probably shouldn't be
+ * tuned that much, as waiting for this means nothing else happens
+ * in the system
+ */
+#define MEMORY_WAIT_TIME       16
+
+/*
+ * This selects whether TX packets are sent one by one to the SMC91x internal
+ * memory and throttled until transmission completes.  This may prevent
+ * RX overruns a litle by keeping much of the memory free for RX packets
+ * but to the expense of reduced TX throughput and increased IRQ overhead.
+ * Note this is not a cure for a too slow data bus or too high IRQ latency.
+ */
+#define THROTTLE_TX_PKTS       0
+
+/*
+ * The MII clock high/low times.  2x this number gives the MII clock period
+ * in microseconds. (was 50, but this gives 6.4ms for each MII transaction!)
+ */
+#define MII_DELAY              1
+
+/* store this information for the driver.. */
+struct smc_local {
+       /*
+        * If I have to wait until memory is available to send a
+        * packet, I will store the skbuff here, until I get the
+        * desired memory.  Then, I'll send it out and free it.
+        */
+       struct sk_buff *saved_skb;
+
+       /*
+        * these are things that the kernel wants me to keep, so users
+        * can find out semi-useless statistics of how well the card is
+        * performing
+        */
+       struct net_device_stats stats;
+
+       /* version/revision of the SMC91x chip */
+       int     version;
+
+       /* Contains the current active transmission mode */
+       int     tcr_cur_mode;
+
+       /* Contains the current active receive mode */
+       int     rcr_cur_mode;
+
+       /* Contains the current active receive/phy mode */
+       int     rpc_cur_mode;
+       int     ctl_rfduplx;
+       int     ctl_rspeed;
+
+       u32     msg_enable;
+       u32     phy_type;
+       struct mii_if_info mii;
+       spinlock_t lock;
+
+#ifdef SMC_USE_PXA_DMA
+       /* DMA needs the physical address of the chip */
+       u_long physaddr;
+#endif
+};
+
+#if SMC_DEBUG > 0
+#define DBG(n, args...)                                        \
+       do {                                            \
+               if (SMC_DEBUG >= (n))                   \
+                       printk(KERN_DEBUG args);        \
+       } while (0)
+
+#define PRINTK(args...)   printk(args)
+#else
+#define DBG(n, args...)   do { } while(0)
+#define PRINTK(args...)   printk(KERN_DEBUG args)
+#endif
+
+#if SMC_DEBUG > 3
+static void PRINT_PKT(u_char *buf, int length)
+{
+       int i;
+       int remainder;
+       int lines;
+
+       lines = length / 16;
+       remainder = length % 16;
+
+       for (i = 0; i < lines ; i ++) {
+               int cur;
+               for (cur = 0; cur < 8; cur++) {
+                       u_char a, b;
+                       a = *buf++;
+                       b = *buf++;
+                       printk("%02x%02x ", a, b);
+               }
+               printk("\n");
+       }
+       for (i = 0; i < remainder/2 ; i++) {
+               u_char a, b;
+               a = *buf++;
+               b = *buf++;
+               printk("%02x%02x ", a, b);
+       }
+       printk("\n");
+}
+#else
+#define PRINT_PKT(x...)  do { } while(0)
+#endif
+
+
+/* this enables an interrupt in the interrupt mask register */
+#define SMC_ENABLE_INT(x) do {                                         \
+       unsigned long flags;                                            \
+       unsigned char mask;                                             \
+       spin_lock_irqsave(&lp->lock, flags);                            \
+       mask = SMC_GET_INT_MASK();                                      \
+       mask |= (x);                                                    \
+       SMC_SET_INT_MASK(mask);                                         \
+       spin_unlock_irqrestore(&lp->lock, flags);                       \
+} while (0)
+
+/* this disables an interrupt from the interrupt mask register */
+#define SMC_DISABLE_INT(x) do {                                                \
+       unsigned long flags;                                            \
+       unsigned char mask;                                             \
+       spin_lock_irqsave(&lp->lock, flags);                            \
+       mask = SMC_GET_INT_MASK();                                      \
+       mask &= ~(x);                                                   \
+       SMC_SET_INT_MASK(mask);                                         \
+       spin_unlock_irqrestore(&lp->lock, flags);                       \
+} while (0)
+
+/*
+ * Wait while MMU is busy.  This is usually in the order of a few nanosecs
+ * if at all, but let's avoid deadlocking the system if the hardware
+ * decides to go south.
+ */
+#define SMC_WAIT_MMU_BUSY() do {                                       \
+       if (unlikely(SMC_GET_MMU_CMD() & MC_BUSY)) {                    \
+               unsigned long timeout = jiffies + 2;                    \
+               while (SMC_GET_MMU_CMD() & MC_BUSY) {                   \
+                       if (time_after(jiffies, timeout)) {             \
+                               printk("%s: timeout %s line %d\n",      \
+                                       dev->name, __FILE__, __LINE__); \
+                               break;                                  \
+                       }                                               \
+                       cpu_relax();                                    \
+               }                                                       \
+       }                                                               \
+} while (0)
+
+
+/*
+ * this does a soft reset on the device
+ */
+static void smc_reset(struct net_device *dev)
+{
+       unsigned long ioaddr = dev->base_addr;
+       unsigned int ctl, cfg;
+
+       DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+
+       /*
+        * This resets the registers mostly to defaults, but doesn't
+        * affect EEPROM.  That seems unnecessary
+        */
+       SMC_SELECT_BANK(0);
+       SMC_SET_RCR(RCR_SOFTRST);
+
+       /*
+        * Setup the Configuration Register
+        * This is necessary because the CONFIG_REG is not affected
+        * by a soft reset
+        */
+       SMC_SELECT_BANK(1);
+
+       cfg = CONFIG_DEFAULT;
+
+       /*
+        * Setup for fast accesses if requested.  If the card/system
+        * can't handle it then there will be no recovery except for
+        * a hard reset or power cycle
+        */
+       if (nowait)
+               cfg |= CONFIG_NO_WAIT;
+
+       /*
+        * Release from possible power-down state
+        * Configuration register is not affected by Soft Reset
+        */
+       cfg |= CONFIG_EPH_POWER_EN;
+
+       SMC_SET_CONFIG(cfg);
+
+       /* this should pause enough for the chip to be happy */
+       /*
+        * elaborate?  What does the chip _need_? --jgarzik
+        *
+        * This seems to be undocumented, but something the original
+        * driver(s) have always done.  Suspect undocumented timing
+        * info/determined empirically. --rmk
+        */
+       udelay(1);
+
+       /* Disable transmit and receive functionality */
+       SMC_SELECT_BANK(0);
+       SMC_SET_RCR(RCR_CLEAR);
+       SMC_SET_TCR(TCR_CLEAR);
+
+       SMC_SELECT_BANK(1);
+       ctl = SMC_GET_CTL() | CTL_LE_ENABLE;
+
+       /*
+        * Set the control register to automatically release successfully
+        * transmitted packets, to make the best use out of our limited
+        * memory
+        */
+#if ! THROTTLE_TX_PKTS
+       ctl |= CTL_AUTO_RELEASE;
+#else
+       ctl &= ~CTL_AUTO_RELEASE;
+#endif
+       SMC_SET_CTL(ctl);
+
+       /* Disable all interrupts */
+       SMC_SELECT_BANK(2);
+       SMC_SET_INT_MASK(0);
+
+       /* Reset the MMU */
+       SMC_SET_MMU_CMD(MC_RESET);
+       SMC_WAIT_MMU_BUSY();
+}
+
+/*
+ * Enable Interrupts, Receive, and Transmit
+ */
+static void smc_enable(struct net_device *dev)
+{
+       unsigned long ioaddr = dev->base_addr;
+       struct smc_local *lp = netdev_priv(dev);
+       int mask;
+
+       DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+
+       /* see the header file for options in TCR/RCR DEFAULT */
+       SMC_SELECT_BANK(0);
+       SMC_SET_TCR(lp->tcr_cur_mode);
+       SMC_SET_RCR(lp->rcr_cur_mode);
+
+       /* now, enable interrupts */
+       mask = IM_EPH_INT|IM_RX_OVRN_INT|IM_RCV_INT;
+       if (lp->version >= (CHIP_91100 << 4))
+               mask |= IM_MDINT;
+       SMC_SELECT_BANK(2);
+       SMC_SET_INT_MASK(mask);
+}
+
+/*
+ * this puts the device in an inactive state
+ */
+static void smc_shutdown(unsigned long ioaddr)
+{
+       DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
+
+       /* no more interrupts for me */
+       SMC_SELECT_BANK(2);
+       SMC_SET_INT_MASK(0);
+
+       /* and tell the card to stay away from that nasty outside world */
+       SMC_SELECT_BANK(0);
+       SMC_SET_RCR(RCR_CLEAR);
+       SMC_SET_TCR(TCR_CLEAR);
+
+#ifdef POWER_DOWN
+       /* finally, shut the chip down */
+       SMC_SELECT_BANK(1);
+       SMC_SET_CONFIG(SMC_GET_CONFIG() & ~CONFIG_EPH_POWER_EN);
+#endif
+}
+
+/*
+ * This is the procedure to handle the receipt of a packet.
+ */
+static inline void  smc_rcv(struct net_device *dev)
+{
+       struct smc_local *lp = netdev_priv(dev);
+       unsigned long ioaddr = dev->base_addr;
+       unsigned int packet_number, status, packet_len;
+
+       DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+
+       packet_number = SMC_GET_RXFIFO();
+       if (unlikely(packet_number & RXFIFO_REMPTY)) {
+               PRINTK("%s: smc_rcv with nothing on FIFO.\n", dev->name);
+               return;
+       }
+
+       /* read from start of packet */
+       SMC_SET_PTR(PTR_READ | PTR_RCV | PTR_AUTOINC);
+
+       /* First two words are status and packet length */
+       SMC_GET_PKT_HDR(status, packet_len);
+       packet_len &= 0x07ff;  /* mask off top bits */
+       DBG(2, "%s: RX PNR 0x%x STATUS 0x%04x LENGTH 0x%04x (%d)\n",
+               dev->name, packet_number, status,
+               packet_len, packet_len);
+
+       if (unlikely(status & RS_ERRORS)) {
+               lp->stats.rx_errors++;
+               if (status & RS_ALGNERR)
+                       lp->stats.rx_frame_errors++;
+               if (status & (RS_TOOSHORT | RS_TOOLONG))
+                       lp->stats.rx_length_errors++;
+               if (status & RS_BADCRC)
+                       lp->stats.rx_crc_errors++;
+       } else {
+               struct sk_buff *skb;
+               unsigned char *data;
+               unsigned int data_len;
+
+               /* set multicast stats */
+               if (status & RS_MULTICAST)
+                       lp->stats.multicast++;
+
+               /*
+                * Actual payload is packet_len - 4 (or 3 if odd byte).
+                * We want skb_reserve(2) and the final ctrl word
+                * (2 bytes, possibly containing the payload odd byte).
+                * Ence packet_len - 4 + 2 + 2.
+                */
+               skb = dev_alloc_skb(packet_len);
+               if (unlikely(skb == NULL)) {
+                       printk(KERN_NOTICE "%s: Low memory, packet dropped.\n",
+                               dev->name);
+                       lp->stats.rx_dropped++;
+                       goto done;
+               }
+
+               /* Align IP header to 32 bits */
+               skb_reserve(skb, 2);
+
+               /* BUG: the LAN91C111 rev A never sets this bit. Force it. */
+               if (lp->version == 0x90)
+                       status |= RS_ODDFRAME;
+
+               /*
+                * If odd length: packet_len - 3,
+                * otherwise packet_len - 4.
+                */
+               data_len = packet_len - ((status & RS_ODDFRAME) ? 3 : 4);
+               data = skb_put(skb, data_len);
+               SMC_PULL_DATA(data, packet_len - 2);
+
+               PRINT_PKT(data, packet_len - 2);
+
+               dev->last_rx = jiffies;
+               skb->dev = dev;
+               skb->protocol = eth_type_trans(skb, dev);
+               netif_rx(skb);
+               lp->stats.rx_packets++;
+               lp->stats.rx_bytes += data_len;
+       }
+
+done:
+       SMC_WAIT_MMU_BUSY();
+       SMC_SET_MMU_CMD(MC_RELEASE);
+}
+
+/*
+ * This is called to actually send a packet to the chip.
+ * Returns non-zero when successful.
+ */
+static void smc_hardware_send_packet(struct net_device *dev)
+{
+       struct smc_local *lp = netdev_priv(dev);
+       unsigned long ioaddr = dev->base_addr;
+       struct sk_buff *skb = lp->saved_skb;
+       unsigned int packet_no, len;
+       unsigned char *buf;
+
+       DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+
+       packet_no = SMC_GET_AR();
+       if (unlikely(packet_no & AR_FAILED)) {
+               printk("%s: Memory allocation failed.\n", dev->name);
+               lp->saved_skb = NULL;
+               lp->stats.tx_errors++;
+               lp->stats.tx_fifo_errors++;
+               dev_kfree_skb_any(skb);
+               return;
+       }
+
+       /* point to the beginning of the packet */
+       SMC_SET_PN(packet_no);
+       SMC_SET_PTR(PTR_AUTOINC);
+
+       buf = skb->data;
+       len = skb->len;
+       DBG(2, "%s: TX PNR 0x%x LENGTH 0x%04x (%d) BUF 0x%p\n",
+               dev->name, packet_no, len, len, buf);
+       PRINT_PKT(buf, len);
+
+       /*
+        * Send the packet length (+6 for status words, length, and ctl.
+        * The card will pad to 64 bytes with zeroes if packet is too small.
+        */
+       SMC_PUT_PKT_HDR(0, len + 6);
+
+       /* send the actual data */
+       SMC_PUSH_DATA(buf, len & ~1);
+
+       /* Send final ctl word with the last byte if there is one */
+       SMC_outw(((len & 1) ? (0x2000 | buf[len-1]) : 0), ioaddr, DATA_REG);
+
+       /* and let the chipset deal with it */
+       SMC_SET_MMU_CMD(MC_ENQUEUE);
+       SMC_ACK_INT(IM_TX_EMPTY_INT);
+
+       dev->trans_start = jiffies;
+       dev_kfree_skb_any(skb);
+       lp->saved_skb = NULL;
+       lp->stats.tx_packets++;
+       lp->stats.tx_bytes += len;
+}
+
+/*
+ * Since I am not sure if I will have enough room in the chip's ram
+ * to store the packet, I call this routine which either sends it
+ * now, or set the card to generates an interrupt when ready
+ * for the packet.
+ */
+static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct smc_local *lp = netdev_priv(dev);
+       unsigned long ioaddr = dev->base_addr;
+       unsigned int numPages, poll_count, status, saved_bank;
+
+       DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+
+       BUG_ON(lp->saved_skb != NULL);
+       lp->saved_skb = skb;
+
+       /*
+        * The MMU wants the number of pages to be the number of 256 bytes
+        * 'pages', minus 1 (since a packet can't ever have 0 pages :))
+        *
+        * The 91C111 ignores the size bits, but earlier models don't.
+        *
+        * Pkt size for allocating is data length +6 (for additional status
+        * words, length and ctl)
+        *
+        * If odd size then last byte is included in ctl word.
+        */
+       numPages = ((skb->len & ~1) + (6 - 1)) >> 8;
+       if (unlikely(numPages > 7)) {
+               printk("%s: Far too big packet error.\n", dev->name);
+               lp->saved_skb = NULL;
+               lp->stats.tx_errors++;
+               lp->stats.tx_dropped++;
+               dev_kfree_skb(skb);
+               return 0;
+       }
+
+       /* now, try to allocate the memory */
+       saved_bank = SMC_CURRENT_BANK();
+       SMC_SELECT_BANK(2);
+       SMC_SET_MMU_CMD(MC_ALLOC | numPages);
+
+       /*
+        * Poll the chip for a short amount of time in case the
+        * allocation succeeds quickly.
+        */
+       poll_count = MEMORY_WAIT_TIME;
+       do {
+               status = SMC_GET_INT();
+               if (status & IM_ALLOC_INT) {
+                       SMC_ACK_INT(IM_ALLOC_INT);
+                       break;
+               }
+       } while (--poll_count);
+
+       if (!poll_count) {
+               /* oh well, wait until the chip finds memory later */
+               netif_stop_queue(dev);
+               DBG(2, "%s: TX memory allocation deferred.\n", dev->name);
+               SMC_ENABLE_INT(IM_ALLOC_INT);
+       } else {
+               /*
+                * Allocation succeeded: push packet to the chip's own memory
+                * immediately.
+                *
+                * If THROTTLE_TX_PKTS is selected that means we don't want
+                * more than a single TX packet taking up space in the chip's
+                * internal memory at all time, in which case we stop the
+                * queue right here until we're notified of TX completion.
+                *
+                * Otherwise we're quite happy to feed more TX packets right
+                * away for better TX throughput, in which case the queue is
+                * left active.
+                */  
+#if THROTTLE_TX_PKTS
+               netif_stop_queue(dev);
+#endif
+               smc_hardware_send_packet(dev);
+               SMC_ENABLE_INT(IM_TX_INT | IM_TX_EMPTY_INT);
+       }
+
+       SMC_SELECT_BANK(saved_bank);
+       return 0;
+}
+
+/*
+ * This handles a TX interrupt, which is only called when:
+ * - a TX error occurred, or
+ * - CTL_AUTO_RELEASE is not set and TX of a packet completed.
+ */
+static void smc_tx(struct net_device *dev)
+{
+       unsigned long ioaddr = dev->base_addr;
+       struct smc_local *lp = netdev_priv(dev);
+       unsigned int saved_packet, packet_no, tx_status, pkt_len;
+
+       DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+
+       /* If the TX FIFO is empty then nothing to do */
+       packet_no = SMC_GET_TXFIFO();
+       if (unlikely(packet_no & TXFIFO_TEMPTY)) {
+               PRINTK("%s: smc_tx with nothing on FIFO.\n", dev->name);
+               return;
+       }
+
+       /* select packet to read from */
+       saved_packet = SMC_GET_PN();
+       SMC_SET_PN(packet_no);
+
+       /* read the first word (status word) from this packet */
+       SMC_SET_PTR(PTR_AUTOINC | PTR_READ);
+       SMC_GET_PKT_HDR(tx_status, pkt_len);
+       DBG(2, "%s: TX STATUS 0x%04x PNR 0x%02x\n",
+               dev->name, tx_status, packet_no);
+
+       if (!(tx_status & TS_SUCCESS))
+               lp->stats.tx_errors++;
+       if (tx_status & TS_LOSTCAR)
+               lp->stats.tx_carrier_errors++;
+
+       SMC_WAIT_MMU_BUSY();
+
+       if (tx_status & TS_LATCOL) {
+               PRINTK("%s: late collision occurred on last xmit\n", dev->name);
+               lp->stats.tx_window_errors++;
+               /* It's really cheap to requeue the pkt here */
+               SMC_SET_MMU_CMD( MC_ENQUEUE );
+       } else {
+               /* kill the packet */
+               SMC_SET_MMU_CMD(MC_FREEPKT);
+       }
+
+       /* Don't restore Packet Number Reg until busy bit is cleared */
+       SMC_WAIT_MMU_BUSY();
+       SMC_SET_PN(saved_packet);
+
+       /* re-enable transmit */
+       SMC_SELECT_BANK(0);
+       SMC_SET_TCR(lp->tcr_cur_mode);
+       SMC_SELECT_BANK(2);
+}
+
+
+/*---PHY CONTROL AND CONFIGURATION-----------------------------------------*/
+
+static void smc_mii_out(struct net_device *dev, unsigned int val, int bits)
+{
+       unsigned long ioaddr = dev->base_addr;
+       unsigned int mii_reg, mask;
+
+       mii_reg = SMC_GET_MII() & ~(MII_MCLK | MII_MDOE | MII_MDO);
+       mii_reg |= MII_MDOE;
+
+       for (mask = 1 << (bits - 1); mask; mask >>= 1) {
+               if (val & mask)
+                       mii_reg |= MII_MDO;
+               else
+                       mii_reg &= ~MII_MDO;
+
+               SMC_SET_MII(mii_reg);
+               udelay(MII_DELAY);
+               SMC_SET_MII(mii_reg | MII_MCLK);
+               udelay(MII_DELAY);
+       }
+}
+
+static unsigned int smc_mii_in(struct net_device *dev, int bits)
+{
+       unsigned long ioaddr = dev->base_addr;
+       unsigned int mii_reg, mask, val;
+
+       mii_reg = SMC_GET_MII() & ~(MII_MCLK | MII_MDOE | MII_MDO);
+       SMC_SET_MII(mii_reg);
+
+       for (mask = 1 << (bits - 1), val = 0; mask; mask >>= 1) {
+               if (SMC_GET_MII() & MII_MDI)
+                       val |= mask;
+
+               SMC_SET_MII(mii_reg);
+               udelay(MII_DELAY);
+               SMC_SET_MII(mii_reg | MII_MCLK);
+               udelay(MII_DELAY);
+       }
+
+       return val;
+}
+
+/*
+ * Reads a register from the MII Management serial interface
+ */
+static int smc_phy_read(struct net_device *dev, int phyaddr, int phyreg)
+{
+       unsigned long ioaddr = dev->base_addr;
+       unsigned int phydata, old_bank;
+
+       /* Save the current bank, and select bank 3 */
+       old_bank = SMC_CURRENT_BANK();
+       SMC_SELECT_BANK(3);
+
+       /* Idle - 32 ones */
+       smc_mii_out(dev, 0xffffffff, 32);
+
+       /* Start code (01) + read (10) + phyaddr + phyreg */
+       smc_mii_out(dev, 6 << 10 | phyaddr << 5 | phyreg, 14);
+
+       /* Turnaround (2bits) + phydata */
+       phydata = smc_mii_in(dev, 18);
+
+       /* Return to idle state */
+       SMC_SET_MII(SMC_GET_MII() & ~(MII_MCLK|MII_MDOE|MII_MDO));
+
+       /* And select original bank */
+       SMC_SELECT_BANK(old_bank);
+
+       DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
+               __FUNCTION__, phyaddr, phyreg, phydata);
+
+       return phydata;
+}
+
+/*
+ * Writes a register to the MII Management serial interface
+ */
+static void smc_phy_write(struct net_device *dev, int phyaddr, int phyreg,
+                         int phydata)
+{
+       unsigned long ioaddr = dev->base_addr;
+       unsigned int old_bank;
+
+       /* Save the current bank, and select bank 3 */
+       old_bank = SMC_CURRENT_BANK();
+       SMC_SELECT_BANK(3);
+
+       /* Idle - 32 ones */
+       smc_mii_out(dev, 0xffffffff, 32);
+
+       /* Start code (01) + write (01) + phyaddr + phyreg + turnaround + phydata */
+       smc_mii_out(dev, 5 << 28 | phyaddr << 23 | phyreg << 18 | 2 << 16 | phydata, 32);
+
+       /* Return to idle state */
+       SMC_SET_MII(SMC_GET_MII() & ~(MII_MCLK|MII_MDOE|MII_MDO));
+
+       /* And select original bank */
+       SMC_SELECT_BANK(old_bank);
+
+       DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
+               __FUNCTION__, phyaddr, phyreg, phydata);
+}
+
+/*
+ * Finds and reports the PHY address
+ */
+static void smc_detect_phy(struct net_device *dev)
+{
+       struct smc_local *lp = netdev_priv(dev);
+       int phyaddr;
+
+       DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+
+       lp->phy_type = 0;
+
+       /*
+        * Scan all 32 PHY addresses if necessary, starting at
+        * PHY#1 to PHY#31, and then PHY#0 last.
+        */
+       for (phyaddr = 1; phyaddr < 33; ++phyaddr) {
+               unsigned int id1, id2;
+
+               /* Read the PHY identifiers */
+               id1 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID1);
+               id2 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID2);
+
+               DBG(3, "%s: phy_id1=0x%x, phy_id2=0x%x\n",
+                       dev->name, id1, id2);
+
+               /* Make sure it is a valid identifier */
+               if (id1 != 0x0000 && id1 != 0xffff && id1 != 0x8000 &&
+                   id2 != 0x0000 && id2 != 0xffff && id2 != 0x8000) {
+                       /* Save the PHY's address */
+                       lp->mii.phy_id = phyaddr & 31;
+                       lp->phy_type = id1 << 16 | id2;
+                       break;
+               }
+       }
+}
+
+/*
+ * Sets the PHY to a configuration as determined by the user
+ */
+static int smc_phy_fixed(struct net_device *dev)
+{
+       struct smc_local *lp = netdev_priv(dev);
+       unsigned long ioaddr = dev->base_addr;
+       int phyaddr = lp->mii.phy_id;
+       int bmcr, cfg1;
+
+       DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+
+       /* Enter Link Disable state */
+       cfg1 = smc_phy_read(dev, phyaddr, PHY_CFG1_REG);
+       cfg1 |= PHY_CFG1_LNKDIS;
+       smc_phy_write(dev, phyaddr, PHY_CFG1_REG, cfg1);
+
+       /*
+        * Set our fixed capabilities
+        * Disable auto-negotiation
+        */
+       bmcr = 0;
+
+       if (lp->ctl_rfduplx)
+               bmcr |= BMCR_FULLDPLX;
+
+       if (lp->ctl_rspeed == 100)
+               bmcr |= BMCR_SPEED100;
+
+       /* Write our capabilities to the phy control register */
+       smc_phy_write(dev, phyaddr, MII_BMCR, bmcr);
+
+       /* Re-Configure the Receive/Phy Control register */
+       SMC_SET_RPC(lp->rpc_cur_mode);
+
+       return 1;
+}
+
+/*
+ * smc_phy_reset - reset the phy
+ * @dev: net device
+ * @phy: phy address
+ *
+ * Issue a software reset for the specified PHY and
+ * wait up to 100ms for the reset to complete.  We should
+ * not access the PHY for 50ms after issuing the reset.
+ *
+ * The time to wait appears to be dependent on the PHY.
+ *
+ * Must be called with lp->lock locked.
+ */
+static int smc_phy_reset(struct net_device *dev, int phy)
+{
+       struct smc_local *lp = netdev_priv(dev);
+       unsigned int bmcr;
+       int timeout;
+
+       smc_phy_write(dev, phy, MII_BMCR, BMCR_RESET);
+
+       for (timeout = 2; timeout; timeout--) {
+               spin_unlock_irq(&lp->lock);
+               msleep(50);
+               spin_lock_irq(&lp->lock);
+
+               bmcr = smc_phy_read(dev, phy, MII_BMCR);
+               if (!(bmcr & BMCR_RESET))
+                       break;
+       }
+
+       return bmcr & BMCR_RESET;
+}
+
+/*
+ * smc_phy_powerdown - powerdown phy
+ * @dev: net device
+ * @phy: phy address
+ *
+ * Power down the specified PHY
+ */
+static void smc_phy_powerdown(struct net_device *dev, int phy)
+{
+       struct smc_local *lp = netdev_priv(dev);
+       unsigned int bmcr;
+
+       spin_lock_irq(&lp->lock);
+       bmcr = smc_phy_read(dev, phy, MII_BMCR);
+       smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN);
+       spin_unlock_irq(&lp->lock);
+}
+
+/*
+ * smc_phy_check_media - check the media status and adjust TCR
+ * @dev: net device
+ * @init: set true for initialisation
+ *
+ * Select duplex mode depending on negotiation state.  This
+ * also updates our carrier state.
+ */
+static void smc_phy_check_media(struct net_device *dev, int init)
+{
+       struct smc_local *lp = netdev_priv(dev);
+       unsigned long ioaddr = dev->base_addr;
+
+       if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) {
+               unsigned int old_bank;
+
+               /* duplex state has changed */
+               if (lp->mii.full_duplex) {
+                       lp->tcr_cur_mode |= TCR_SWFDUP;
+               } else {
+                       lp->tcr_cur_mode &= ~TCR_SWFDUP;
+               }
+
+               old_bank = SMC_CURRENT_BANK();
+               SMC_SELECT_BANK(0);
+               SMC_SET_TCR(lp->tcr_cur_mode);
+               SMC_SELECT_BANK(old_bank);
+       }
+}
+
+/*
+ * Configures the specified PHY through the MII management interface
+ * using Autonegotiation.
+ * Calls smc_phy_fixed() if the user has requested a certain config.
+ * If RPC ANEG bit is set, the media selection is dependent purely on
+ * the selection by the MII (either in the MII BMCR reg or the result
+ * of autonegotiation.)  If the RPC ANEG bit is cleared, the selection
+ * is controlled by the RPC SPEED and RPC DPLX bits.
+ */
+static void smc_phy_configure(struct net_device *dev)
+{
+       struct smc_local *lp = netdev_priv(dev);
+       unsigned long ioaddr = dev->base_addr;
+       int phyaddr = lp->mii.phy_id;
+       int my_phy_caps; /* My PHY capabilities */
+       int my_ad_caps; /* My Advertised capabilities */
+       int status;
+
+       DBG(3, "%s:smc_program_phy()\n", dev->name);
+
+       spin_lock_irq(&lp->lock);
+
+       /*
+        * We should not be called if phy_type is zero.
+        */
+       if (lp->phy_type == 0)
+               goto smc_phy_configure_exit;
+
+       if (smc_phy_reset(dev, phyaddr)) {
+               printk("%s: PHY reset timed out\n", dev->name);
+               goto smc_phy_configure_exit;
+       }
+
+       /*
+        * Enable PHY Interrupts (for register 18)
+        * Interrupts listed here are disabled
+        */
+       smc_phy_write(dev, phyaddr, PHY_MASK_REG,
+               PHY_INT_LOSSSYNC | PHY_INT_CWRD | PHY_INT_SSD |
+               PHY_INT_ESD | PHY_INT_RPOL | PHY_INT_JAB |
+               PHY_INT_SPDDET | PHY_INT_DPLXDET);
+
+       /* Configure the Receive/Phy Control register */
+       SMC_SELECT_BANK(0);
+       SMC_SET_RPC(lp->rpc_cur_mode);
+
+       /* If the user requested no auto neg, then go set his request */
+       if (lp->mii.force_media) {
+               smc_phy_fixed(dev);
+               goto smc_phy_configure_exit;
+       }
+
+       /* Copy our capabilities from MII_BMSR to MII_ADVERTISE */
+       my_phy_caps = smc_phy_read(dev, phyaddr, MII_BMSR);
+
+       if (!(my_phy_caps & BMSR_ANEGCAPABLE)) {
+               printk(KERN_INFO "Auto negotiation NOT supported\n");
+               smc_phy_fixed(dev);
+               goto smc_phy_configure_exit;
+       }
+
+       my_ad_caps = ADVERTISE_CSMA; /* I am CSMA capable */
+
+       if (my_phy_caps & BMSR_100BASE4)
+               my_ad_caps |= ADVERTISE_100BASE4;
+       if (my_phy_caps & BMSR_100FULL)
+               my_ad_caps |= ADVERTISE_100FULL;
+       if (my_phy_caps & BMSR_100HALF)
+               my_ad_caps |= ADVERTISE_100HALF;
+       if (my_phy_caps & BMSR_10FULL)
+               my_ad_caps |= ADVERTISE_10FULL;
+       if (my_phy_caps & BMSR_10HALF)
+               my_ad_caps |= ADVERTISE_10HALF;
+
+       /* Disable capabilities not selected by our user */
+       if (lp->ctl_rspeed != 100)
+               my_ad_caps &= ~(ADVERTISE_100BASE4|ADVERTISE_100FULL|ADVERTISE_100HALF);
+
+       if (!lp->ctl_rfduplx)
+               my_ad_caps &= ~(ADVERTISE_100FULL|ADVERTISE_10FULL);
+
+       /* Update our Auto-Neg Advertisement Register */
+       smc_phy_write(dev, phyaddr, MII_ADVERTISE, my_ad_caps);
+       lp->mii.advertising = my_ad_caps;
+
+       /*
+        * Read the register back.  Without this, it appears that when
+        * auto-negotiation is restarted, sometimes it isn't ready and
+        * the link does not come up.
+        */
+       status = smc_phy_read(dev, phyaddr, MII_ADVERTISE);
+
+       DBG(2, "%s: phy caps=%x\n", dev->name, my_phy_caps);
+       DBG(2, "%s: phy advertised caps=%x\n", dev->name, my_ad_caps);
+
+       /* Restart auto-negotiation process in order to advertise my caps */
+       smc_phy_write(dev, phyaddr, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
+
+       smc_phy_check_media(dev, 1);
+
+smc_phy_configure_exit:
+       spin_unlock_irq(&lp->lock);
+}
+
+/*
+ * smc_phy_interrupt
+ *
+ * Purpose:  Handle interrupts relating to PHY register 18. This is
+ *  called from the "hard" interrupt handler under our private spinlock.
+ */
+static void smc_phy_interrupt(struct net_device *dev)
+{
+       struct smc_local *lp = netdev_priv(dev);
+       int phyaddr = lp->mii.phy_id;
+       int phy18;
+
+       DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+
+       if (lp->phy_type == 0)
+               return;
+
+       for(;;) {
+               smc_phy_check_media(dev, 0);
+
+               /* Read PHY Register 18, Status Output */
+               phy18 = smc_phy_read(dev, phyaddr, PHY_INT_REG);
+               if ((phy18 & PHY_INT_INT) == 0)
+                       break;
+       }
+}
+
+/*--- END PHY CONTROL AND CONFIGURATION-------------------------------------*/
+
+static void smc_10bt_check_media(struct net_device *dev, int init)
+{
+       struct smc_local *lp = netdev_priv(dev);
+       unsigned long ioaddr = dev->base_addr;
+       unsigned int old_carrier, new_carrier, old_bank;
+
+       old_bank = SMC_CURRENT_BANK();
+       SMC_SELECT_BANK(0);
+       old_carrier = netif_carrier_ok(dev) ? 1 : 0;
+       new_carrier = SMC_inw(ioaddr, EPH_STATUS_REG) & ES_LINK_OK ? 1 : 0;
+
+       if (init || (old_carrier != new_carrier)) {
+               if (!new_carrier) {
+                       netif_carrier_off(dev);
+               } else {
+                       netif_carrier_on(dev);
+               }
+               if (netif_msg_link(lp))
+                       printk(KERN_INFO "%s: link %s\n", dev->name,
+                              new_carrier ? "up" : "down");
+       }
+       SMC_SELECT_BANK(old_bank);
+}
+
+static void smc_eph_interrupt(struct net_device *dev)
+{
+       unsigned long ioaddr = dev->base_addr;
+       unsigned int old_bank, ctl;
+
+       smc_10bt_check_media(dev, 0);
+
+       old_bank = SMC_CURRENT_BANK();
+       SMC_SELECT_BANK(1);
+
+       ctl = SMC_GET_CTL();
+       SMC_SET_CTL(ctl & ~CTL_LE_ENABLE);
+       SMC_SET_CTL(ctl);
+
+       SMC_SELECT_BANK(old_bank);
+}
+
+/*
+ * This is the main routine of the driver, to handle the device when
+ * it needs some attention.
+ */
+static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+       struct net_device *dev = dev_id;
+       unsigned long ioaddr = dev->base_addr;
+       struct smc_local *lp = netdev_priv(dev);
+       int status, mask, timeout, card_stats;
+       int saved_bank, saved_pointer;
+
+       DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+
+       saved_bank = SMC_CURRENT_BANK();
+       SMC_SELECT_BANK(2);
+       saved_pointer = SMC_GET_PTR();
+       mask = SMC_GET_INT_MASK();
+       SMC_SET_INT_MASK(0);
+
+       /* set a timeout value, so I don't stay here forever */
+       timeout = 8;
+
+       do {
+               status = SMC_GET_INT();
+
+               DBG(2, "%s: IRQ 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n",
+                       dev->name, status, mask,
+                       ({ int meminfo; SMC_SELECT_BANK(0);
+                          meminfo = SMC_GET_MIR();
+                          SMC_SELECT_BANK(2); meminfo; }),
+                       SMC_GET_FIFO());
+
+               status &= mask;
+               if (!status)
+                       break;
+
+               spin_lock(&lp->lock);
+
+               if (status & IM_RCV_INT) {
+                       DBG(3, "%s: RX irq\n", dev->name);
+                       smc_rcv(dev);
+               } else if (status & IM_TX_INT) {
+                       DBG(3, "%s: TX int\n", dev->name);
+                       smc_tx(dev);
+                       SMC_ACK_INT(IM_TX_INT);
+#if THROTTLE_TX_PKTS
+                       netif_wake_queue(dev);
+#endif
+               } else if (status & IM_ALLOC_INT) {
+                       DBG(3, "%s: Allocation irq\n", dev->name);
+                       smc_hardware_send_packet(dev);
+                       mask |= (IM_TX_INT | IM_TX_EMPTY_INT);
+                       mask &= ~IM_ALLOC_INT;
+#if ! THROTTLE_TX_PKTS
+                       netif_wake_queue(dev);
+#endif
+               } else if (status & IM_TX_EMPTY_INT) {
+                       DBG(3, "%s: TX empty\n", dev->name);
+                       mask &= ~IM_TX_EMPTY_INT;
+
+                       /* update stats */
+                       SMC_SELECT_BANK(0);
+                       card_stats = SMC_GET_COUNTER();
+                       SMC_SELECT_BANK(2);
+
+                       /* single collisions */
+                       lp->stats.collisions += card_stats & 0xF;
+                       card_stats >>= 4;
+
+                       /* multiple collisions */
+                       lp->stats.collisions += card_stats & 0xF;
+               } else if (status & IM_RX_OVRN_INT) {
+                       DBG(1, "%s: RX overrun\n", dev->name);
+                       SMC_ACK_INT(IM_RX_OVRN_INT);
+                       lp->stats.rx_errors++;
+                       lp->stats.rx_fifo_errors++;
+               } else if (status & IM_EPH_INT) {
+                       smc_eph_interrupt(dev);
+               } else if (status & IM_MDINT) {
+                       SMC_ACK_INT(IM_MDINT);
+                       smc_phy_interrupt(dev);
+               } else if (status & IM_ERCV_INT) {
+                       SMC_ACK_INT(IM_ERCV_INT);
+                       PRINTK("%s: UNSUPPORTED: ERCV INTERRUPT \n", dev->name);
+               }
+
+               spin_unlock(&lp->lock);
+       } while (--timeout);
+
+       /* restore register states */
+       SMC_SET_INT_MASK(mask);
+       SMC_SET_PTR(saved_pointer);
+       SMC_SELECT_BANK(saved_bank);
+
+       DBG(3, "%s: Interrupt done (%d loops)\n", dev->name, 8-timeout);
+
+       /*
+        * We return IRQ_HANDLED unconditionally here even if there was
+        * nothing to do.  There is a possibility that a packet might
+        * get enqueued into the chip right after TX_EMPTY_INT is raised
+        * but just before the CPU acknowledges the IRQ.
+        * Better take an unneeded IRQ in some occasions than complexifying
+        * the code for all cases.
+        */
+       return IRQ_HANDLED;
+}
+
+/* Our watchdog timed out. Called by the networking layer */
+static void smc_timeout(struct net_device *dev)
+{
+       struct smc_local *lp = netdev_priv(dev);
+
+       DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+
+       smc_reset(dev);
+       smc_enable(dev);
+
+#if 0
+       /*
+        * Reconfiguring the PHY doesn't seem like a bad idea here, but
+        * it introduced a problem.  Now that this is a timeout routine,
+        * we are getting called from within an interrupt context.
+        * smc_phy_configure() calls msleep() which calls
+        * schedule_timeout() which calls schedule().  When schedule()
+        * is called from an interrupt context, it prints out
+        * "Scheduling in interrupt" and then calls BUG().  This is
+        * obviously not desirable.  This was worked around by removing
+        * the call to smc_phy_configure() here because it didn't seem
+        * absolutely necessary.  Ultimately, if msleep() is
+        * supposed to be usable from an interrupt context (which it
+        * looks like it thinks it should handle), it should be fixed.
+        */
+       if (lp->phy_type != 0)
+               smc_phy_configure(dev);
+#endif
+
+       /* clear anything saved */
+       if (lp->saved_skb != NULL) {
+               dev_kfree_skb (lp->saved_skb);
+               lp->saved_skb = NULL;
+               lp->stats.tx_errors++;
+               lp->stats.tx_aborted_errors++;
+       }
+       /* We can accept TX packets again */
+       dev->trans_start = jiffies;
+       netif_wake_queue(dev);
+}
+
+/*
+ *    This sets the internal hardware table to filter out unwanted multicast
+ *    packets before they take up memory.
+ *
+ *    The SMC chip uses a hash table where the high 6 bits of the CRC of
+ *    address are the offset into the table.  If that bit is 1, then the
+ *    multicast packet is accepted.  Otherwise, it's dropped silently.
+ *
+ *    To use the 6 bits as an offset into the table, the high 3 bits are the
+ *    number of the 8 bit register, while the low 3 bits are the bit within
+ *    that register.
+ *
+ *    This routine is based very heavily on the one provided by Peter Cammaert.
+ */
+static void
+smc_setmulticast(unsigned long ioaddr, int count, struct dev_mc_list *addrs)
+{
+       int i;
+       unsigned char multicast_table[8];
+       struct dev_mc_list *cur_addr;
+
+       /* table for flipping the order of 3 bits */
+       static unsigned char invert3[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+
+       /* start with a table of all zeros: reject all */
+       memset(multicast_table, 0, sizeof(multicast_table));
+
+       cur_addr = addrs;
+       for (i = 0; i < count; i++, cur_addr = cur_addr->next) {
+               int position;
+
+               /* do we have a pointer here? */
+               if (!cur_addr)
+                       break;
+               /* make sure this is a multicast address - shouldn't this
+                  be a given if we have it here ? */
+               if (!(*cur_addr->dmi_addr & 1))
+                       continue;
+
+               /* only use the low order bits */
+               position = crc32_le(~0, cur_addr->dmi_addr, 6) & 0x3f;
+
+               /* do some messy swapping to put the bit in the right spot */
+               multicast_table[invert3[position&7]] |=
+                                       (1<<invert3[(position>>3)&7]);
+
+       }
+       /* now, the table can be loaded into the chipset */
+       SMC_SELECT_BANK(3);
+       SMC_SET_MCAST(multicast_table);
+}
+
+/*
+ * This routine will, depending on the values passed to it,
+ * either make it accept multicast packets, go into
+ * promiscuous mode (for TCPDUMP and cousins) or accept
+ * a select set of multicast packets
+ */
+static void smc_set_multicast_list(struct net_device *dev)
+{
+       struct smc_local *lp = netdev_priv(dev);
+       unsigned long ioaddr = dev->base_addr;
+
+       DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+
+       SMC_SELECT_BANK(0);
+       if (dev->flags & IFF_PROMISC) {
+               DBG(2, "%s: RCR_PRMS\n", dev->name);
+               lp->rcr_cur_mode |= RCR_PRMS;
+               SMC_SET_RCR(lp->rcr_cur_mode);
+       }
+
+/* BUG?  I never disable promiscuous mode if multicasting was turned on.
+   Now, I turn off promiscuous mode, but I don't do anything to multicasting
+   when promiscuous mode is turned on.
+*/
+
+       /*
+        * Here, I am setting this to accept all multicast packets.
+        * I don't need to zero the multicast table, because the flag is
+        * checked before the table is
+        */
+       else if (dev->flags & IFF_ALLMULTI || dev->mc_count > 16) {
+               lp->rcr_cur_mode |= RCR_ALMUL;
+               SMC_SET_RCR(lp->rcr_cur_mode);
+               DBG(2, "%s: RCR_ALMUL\n", dev->name);
+       }
+
+       /*
+        * We just get all multicast packets even if we only want them
+        * from one source.  This will be changed at some future point.
+        */
+       else if (dev->mc_count)  {
+               /* support hardware multicasting */
+
+               /* be sure I get rid of flags I might have set */
+               lp->rcr_cur_mode &= ~(RCR_PRMS | RCR_ALMUL);
+               SMC_SET_RCR(lp->rcr_cur_mode);
+               /*
+                * NOTE: this has to set the bank, so make sure it is the
+                * last thing called.  The bank is set to zero at the top
+                */
+               smc_setmulticast(ioaddr, dev->mc_count, dev->mc_list);
+       } else  {
+               DBG(2, "%s: ~(RCR_PRMS|RCR_ALMUL)\n", dev->name);
+               lp->rcr_cur_mode &= ~(RCR_PRMS | RCR_ALMUL);
+               SMC_SET_RCR(lp->rcr_cur_mode);
+
+               /*
+                * since I'm disabling all multicast entirely, I need to
+                * clear the multicast list
+                */
+               SMC_SELECT_BANK(3);
+               SMC_CLEAR_MCAST();
+       }
+}
+
+
+/*
+ * Open and Initialize the board
+ *
+ * Set up everything, reset the card, etc..
+ */
+static int
+smc_open(struct net_device *dev)
+{
+       struct smc_local *lp = netdev_priv(dev);
+       unsigned long ioaddr = dev->base_addr;
+
+       DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+
+       /*
+        * Check that the address is valid.  If its not, refuse
+        * to bring the device up.  The user must specify an
+        * address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx
+        */
+       if (!is_valid_ether_addr(dev->dev_addr)) {
+               DBG(2, (KERN_DEBUG "smc_open: no valid ethernet hw addr\n"));
+               return -EINVAL;
+       }
+
+       /* clear out all the junk that was put here before... */
+       lp->saved_skb = NULL;
+
+       /* Setup the default Register Modes */
+       lp->tcr_cur_mode = TCR_DEFAULT;
+       lp->rcr_cur_mode = RCR_DEFAULT;
+       lp->rpc_cur_mode = RPC_DEFAULT;
+
+       /*
+        * If we are not using a MII interface, we need to
+        * monitor our own carrier signal to detect faults.
+        */
+       if (lp->phy_type == 0)
+               lp->tcr_cur_mode |= TCR_MON_CSN;
+
+       /* reset the hardware */
+       smc_reset(dev);
+       smc_enable(dev);
+
+       SMC_SELECT_BANK(1);
+       SMC_SET_MAC_ADDR(dev->dev_addr);
+
+       /* Configure the PHY */
+       if (lp->phy_type != 0)
+               smc_phy_configure(dev);
+       else {
+               spin_lock_irq(&lp->lock);
+               smc_10bt_check_media(dev, 1);
+               spin_unlock_irq(&lp->lock);
+       }
+
+       /*
+        * make sure to initialize the link state with netif_carrier_off()
+        * somewhere, too --jgarzik
+        *
+        * smc_phy_configure() and smc_10bt_check_media() does that. --rmk
+        */
+       netif_start_queue(dev);
+       return 0;
+}
+
+/*
+ * smc_close
+ *
+ * this makes the board clean up everything that it can
+ * and not talk to the outside world.   Caused by
+ * an 'ifconfig ethX down'
+ */
+static int smc_close(struct net_device *dev)
+{
+       struct smc_local *lp = netdev_priv(dev);
+
+       DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+
+       netif_stop_queue(dev);
+       netif_carrier_off(dev);
+
+       /* clear everything */
+       smc_shutdown(dev->base_addr);
+
+       if (lp->phy_type != 0)
+               smc_phy_powerdown(dev, lp->mii.phy_id);
+
+       return 0;
+}
+
+/*
+ * Get the current statistics.
+ * This may be called with the card open or closed.
+ */
+static struct net_device_stats *smc_query_statistics(struct net_device *dev)
+{
+       struct smc_local *lp = netdev_priv(dev);
+
+       DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+
+       return &lp->stats;
+}
+
+/*
+ * Ethtool support
+ */
+static int
+smc_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct smc_local *lp = netdev_priv(dev);
+       int ret;
+
+       cmd->maxtxpkt = 1;
+       cmd->maxrxpkt = 1;
+
+       if (lp->phy_type != 0) {
+               spin_lock_irq(&lp->lock);
+               ret = mii_ethtool_gset(&lp->mii, cmd);
+               spin_unlock_irq(&lp->lock);
+       } else {
+               cmd->supported = SUPPORTED_10baseT_Half |
+                                SUPPORTED_10baseT_Full |
+                                SUPPORTED_TP | SUPPORTED_AUI;
+
+               if (lp->ctl_rspeed == 10)
+                       cmd->speed = SPEED_10;
+               else if (lp->ctl_rspeed == 100)
+                       cmd->speed = SPEED_100;
+
+               cmd->autoneg = AUTONEG_DISABLE;
+               cmd->transceiver = XCVR_INTERNAL;
+               cmd->port = 0;
+               cmd->duplex = lp->tcr_cur_mode & TCR_SWFDUP ? DUPLEX_FULL : DUPLEX_HALF;
+
+               ret = 0;
+       }
+
+       return ret;
+}
+
+static int
+smc_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct smc_local *lp = netdev_priv(dev);
+       int ret;
+
+       if (lp->phy_type != 0) {
+               spin_lock_irq(&lp->lock);
+               ret = mii_ethtool_sset(&lp->mii, cmd);
+               spin_unlock_irq(&lp->lock);
+       } else {
+               if (cmd->autoneg != AUTONEG_DISABLE ||
+                   cmd->speed != SPEED_10 ||
+                   (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL) ||
+                   (cmd->port != PORT_TP && cmd->port != PORT_AUI))
+                       return -EINVAL;
+
+//             lp->port = cmd->port;
+               lp->ctl_rfduplx = cmd->duplex == DUPLEX_FULL;
+
+//             if (netif_running(dev))
+//                     smc_set_port(dev);
+
+               ret = 0;
+       }
+
+       return ret;
+}
+
+static void
+smc_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+       strncpy(info->driver, CARDNAME, sizeof(info->driver));
+       strncpy(info->version, version, sizeof(info->version));
+       strncpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info));
+}
+
+static int smc_ethtool_nwayreset(struct net_device *dev)
+{
+       struct smc_local *lp = netdev_priv(dev);
+       int ret = -EINVAL;
+
+       if (lp->phy_type != 0) {
+               spin_lock_irq(&lp->lock);
+               ret = mii_nway_restart(&lp->mii);
+               spin_unlock_irq(&lp->lock);
+       }
+
+       return ret;
+}
+
+static u32 smc_ethtool_getmsglevel(struct net_device *dev)
+{
+       struct smc_local *lp = netdev_priv(dev);
+       return lp->msg_enable;
+}
+
+static void smc_ethtool_setmsglevel(struct net_device *dev, u32 level)
+{
+       struct smc_local *lp = netdev_priv(dev);
+       lp->msg_enable = level;
+}
+
+static struct ethtool_ops smc_ethtool_ops = {
+       .get_settings   = smc_ethtool_getsettings,
+       .set_settings   = smc_ethtool_setsettings,
+       .get_drvinfo    = smc_ethtool_getdrvinfo,
+
+       .get_msglevel   = smc_ethtool_getmsglevel,
+       .set_msglevel   = smc_ethtool_setmsglevel,
+       .nway_reset     = smc_ethtool_nwayreset,
+       .get_link       = ethtool_op_get_link,
+//     .get_eeprom     = smc_ethtool_geteeprom,
+//     .set_eeprom     = smc_ethtool_seteeprom,
+};
+
+/*
+ * smc_findirq
+ *
+ * This routine has a simple purpose -- make the SMC chip generate an
+ * interrupt, so an auto-detect routine can detect it, and find the IRQ,
+ */
+/*
+ * does this still work?
+ *
+ * I just deleted auto_irq.c, since it was never built...
+ *   --jgarzik
+ */
+static int __init smc_findirq(unsigned long ioaddr)
+{
+       int timeout = 20;
+       unsigned long cookie;
+
+       DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
+
+       cookie = probe_irq_on();
+
+       /*
+        * What I try to do here is trigger an ALLOC_INT. This is done
+        * by allocating a small chunk of memory, which will give an interrupt
+        * when done.
+        */
+       /* enable ALLOCation interrupts ONLY */
+       SMC_SELECT_BANK(2);
+       SMC_SET_INT_MASK(IM_ALLOC_INT);
+
+       /*
+        * Allocate 512 bytes of memory.  Note that the chip was just
+        * reset so all the memory is available
+        */
+       SMC_SET_MMU_CMD(MC_ALLOC | 1);
+
+       /*
+        * Wait until positive that the interrupt has been generated
+        */
+       do {
+               int int_status;
+               udelay(10);
+               int_status = SMC_GET_INT();
+               if (int_status & IM_ALLOC_INT)
+                       break;          /* got the interrupt */
+       } while (--timeout);
+
+       /*
+        * there is really nothing that I can do here if timeout fails,
+        * as autoirq_report will return a 0 anyway, which is what I
+        * want in this case.   Plus, the clean up is needed in both
+        * cases.
+        */
+
+       /* and disable all interrupts again */
+       SMC_SET_INT_MASK(0);
+
+       /* and return what I found */
+       return probe_irq_off(cookie);
+}
+
+/*
+ * Function: smc_probe(unsigned long ioaddr)
+ *
+ * Purpose:
+ *     Tests to see if a given ioaddr points to an SMC91x chip.
+ *     Returns a 0 on success
+ *
+ * Algorithm:
+ *     (1) see if the high byte of BANK_SELECT is 0x33
+ *     (2) compare the ioaddr with the base register's address
+ *     (3) see if I recognize the chip ID in the appropriate register
+ *
+ * Here I do typical initialization tasks.
+ *
+ * o  Initialize the structure if needed
+ * o  print out my vanity message if not done so already
+ * o  print out what type of hardware is detected
+ * o  print out the ethernet address
+ * o  find the IRQ
+ * o  set up my private data
+ * o  configure the dev structure with my subroutines
+ * o  actually GRAB the irq.
+ * o  GRAB the region
+ */
+static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
+{
+       struct smc_local *lp = netdev_priv(dev);
+       static int version_printed = 0;
+       int i, retval;
+       unsigned int val, revision_register;
+       const char *version_string;
+
+       DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
+
+       /* First, see if the high byte is 0x33 */
+       val = SMC_CURRENT_BANK();
+       DBG(2, "%s: bank signature probe returned 0x%04x\n", CARDNAME, val);
+       if ((val & 0xFF00) != 0x3300) {
+               if ((val & 0xFF) == 0x33) {
+                       printk(KERN_WARNING
+                               "%s: Detected possible byte-swapped interface"
+                               " at IOADDR 0x%lx\n", CARDNAME, ioaddr);
+               }
+               retval = -ENODEV;
+               goto err_out;
+       }
+
+       /*
+        * The above MIGHT indicate a device, but I need to write to
+        * further test this.
+        */
+       SMC_SELECT_BANK(0);
+       val = SMC_CURRENT_BANK();
+       if ((val & 0xFF00) != 0x3300) {
+               retval = -ENODEV;
+               goto err_out;
+       }
+
+       /*
+        * well, we've already written once, so hopefully another
+        * time won't hurt.  This time, I need to switch the bank
+        * register to bank 1, so I can access the base address
+        * register
+        */
+       SMC_SELECT_BANK(1);
+       val = SMC_GET_BASE();
+       val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT;
+       if ((ioaddr & ((PAGE_SIZE-1)<<SMC_IO_SHIFT)) != val) {
+               printk("%s: IOADDR %lx doesn't match configuration (%x).\n",
+                       CARDNAME, ioaddr, val);
+       }
+
+       /*
+        * check if the revision register is something that I
+        * recognize.  These might need to be added to later,
+        * as future revisions could be added.
+        */
+       SMC_SELECT_BANK(3);
+       revision_register = SMC_GET_REV();
+       DBG(2, "%s: revision = 0x%04x\n", CARDNAME, revision_register);
+       version_string = chip_ids[ (revision_register >> 4) & 0xF];
+       if (!version_string || (revision_register & 0xff00) != 0x3300) {
+               /* I don't recognize this chip, so... */
+               printk("%s: IO 0x%lx: Unrecognized revision register 0x%04x"
+                       ", Contact author.\n", CARDNAME,
+                       ioaddr, revision_register);
+
+               retval = -ENODEV;
+               goto err_out;
+       }
+
+       /* At this point I'll assume that the chip is an SMC91x. */
+       if (version_printed++ == 0)
+               printk("%s", version);
+
+       /* fill in some of the fields */
+       dev->base_addr = ioaddr;
+       lp->version = revision_register & 0xff;
+
+       /* Get the MAC address */
+       SMC_SELECT_BANK(1);
+       SMC_GET_MAC_ADDR(dev->dev_addr);
+
+       /* now, reset the chip, and put it into a known state */
+       smc_reset(dev);
+
+       /*
+        * If dev->irq is 0, then the device has to be banged on to see
+        * what the IRQ is.
+        *
+        * This banging doesn't always detect the IRQ, for unknown reasons.
+        * a workaround is to reset the chip and try again.
+        *
+        * Interestingly, the DOS packet driver *SETS* the IRQ on the card to
+        * be what is requested on the command line.   I don't do that, mostly
+        * because the card that I have uses a non-standard method of accessing
+        * the IRQs, and because this _should_ work in most configurations.
+        *
+        * Specifying an IRQ is done with the assumption that the user knows
+        * what (s)he is doing.  No checking is done!!!!
+        */
+       if (dev->irq < 1) {
+               int trials;
+
+               trials = 3;
+               while (trials--) {
+                       dev->irq = smc_findirq(ioaddr);
+                       if (dev->irq)
+                               break;
+                       /* kick the card and try again */
+                       smc_reset(dev);
+               }
+       }
+       if (dev->irq == 0) {
+               printk("%s: Couldn't autodetect your IRQ. Use irq=xx.\n",
+                       dev->name);
+               retval = -ENODEV;
+               goto err_out;
+       }
+       dev->irq = irq_canonicalize(dev->irq);
+
+       /* Fill in the fields of the device structure with ethernet values. */
+       ether_setup(dev);
+
+       dev->open = smc_open;
+       dev->stop = smc_close;
+       dev->hard_start_xmit = smc_hard_start_xmit;
+       dev->tx_timeout = smc_timeout;
+       dev->watchdog_timeo = msecs_to_jiffies(watchdog);
+       dev->get_stats = smc_query_statistics;
+       dev->set_multicast_list = smc_set_multicast_list;
+       dev->ethtool_ops = &smc_ethtool_ops;
+
+       spin_lock_init(&lp->lock);
+       lp->mii.phy_id_mask = 0x1f;
+       lp->mii.reg_num_mask = 0x1f;
+       lp->mii.force_media = 0;
+       lp->mii.full_duplex = 0;
+       lp->mii.dev = dev;
+       lp->mii.mdio_read = smc_phy_read;
+       lp->mii.mdio_write = smc_phy_write;
+
+       /*
+        * Locate the phy, if any.
+        */
+       if (lp->version >= (CHIP_91100 << 4))
+               smc_detect_phy(dev);
+
+       /* Set default parameters */
+       lp->msg_enable = NETIF_MSG_LINK;
+       lp->ctl_rfduplx = 0;
+       lp->ctl_rspeed = 10;
+
+       if (lp->version >= (CHIP_91100 << 4)) {
+               lp->ctl_rfduplx = 1;
+               lp->ctl_rspeed = 100;
+       }
+
+       /* Grab the IRQ */
+       retval = request_irq(dev->irq, &smc_interrupt, 0, dev->name, dev);
+       if (retval)
+               goto err_out;
+
+       set_irq_type(dev->irq, IRQT_RISING);
+#ifdef SMC_USE_PXA_DMA
+       {
+               int dma = pxa_request_dma(dev->name, DMA_PRIO_LOW,
+                                         smc_pxa_dma_irq, NULL);
+               if (dma >= 0)
+                       dev->dma = dma;
+       }
+#endif
+
+       retval = register_netdev(dev);
+       if (retval == 0) {
+               /* now, print out the card info, in a short format.. */
+               printk("%s: %s (rev %d) at %#lx IRQ %d",
+                       dev->name, version_string, revision_register & 0x0f,
+                       dev->base_addr, dev->irq);
+
+               if (dev->dma != (unsigned char)-1)
+                       printk(" DMA %d", dev->dma);
+
+               printk("%s%s\n", nowait ? " [nowait]" : "",
+                       THROTTLE_TX_PKTS ? " [throttle_tx]" : "");
+
+               if (!is_valid_ether_addr(dev->dev_addr)) {
+                       printk("%s: Invalid ethernet MAC address.  Please "
+                              "set using ifconfig\n", dev->name);
+               } else {
+                       /* Print the Ethernet address */
+                       printk("%s: Ethernet addr: ", dev->name);
+                       for (i = 0; i < 5; i++)
+                               printk("%2.2x:", dev->dev_addr[i]);
+                       printk("%2.2x\n", dev->dev_addr[5]);
+               }
+
+               if (lp->phy_type == 0) {
+                       PRINTK("%s: No PHY found\n", dev->name);
+               } else if ((lp->phy_type & 0xfffffff0) == 0x0016f840) {
+                       PRINTK("%s: PHY LAN83C183 (LAN91C111 Internal)\n", dev->name);
+               } else if ((lp->phy_type & 0xfffffff0) == 0x02821c50) {
+                       PRINTK("%s: PHY LAN83C180\n", dev->name);
+               }
+       }
+
+err_out:
+#ifdef SMC_USE_PXA_DMA
+       if (retval && dev->dma != (unsigned char)-1)
+               pxa_free_dma(dev->dma);
+#endif
+       return retval;
+}
+
+static int smc_enable_device(unsigned long attrib_phys)
+{
+       unsigned long flags;
+       unsigned char ecor, ecsr;
+       void *addr;
+
+       /*
+        * Map the attribute space.  This is overkill, but clean.
+        */
+       addr = ioremap(attrib_phys, ATTRIB_SIZE);
+       if (!addr)
+               return -ENOMEM;
+
+       /*
+        * Reset the device.  We must disable IRQs around this
+        * since a reset causes the IRQ line become active.
+        */
+       local_irq_save(flags);
+       ecor = readb(addr + (ECOR << SMC_IO_SHIFT)) & ~ECOR_RESET;
+       writeb(ecor | ECOR_RESET, addr + (ECOR << SMC_IO_SHIFT));
+       readb(addr + (ECOR << SMC_IO_SHIFT));
+
+       /*
+        * Wait 100us for the chip to reset.
+        */
+       udelay(100);
+
+       /*
+        * The device will ignore all writes to the enable bit while
+        * reset is asserted, even if the reset bit is cleared in the
+        * same write.  Must clear reset first, then enable the device.
+        */
+       writeb(ecor, addr + (ECOR << SMC_IO_SHIFT));
+       writeb(ecor | ECOR_ENABLE, addr + (ECOR << SMC_IO_SHIFT));
+
+       /*
+        * Set the appropriate byte/word mode.
+        */
+       ecsr = readb(addr + (ECSR << SMC_IO_SHIFT)) & ~ECSR_IOIS8;
+#ifndef SMC_CAN_USE_16BIT
+       ecsr |= ECSR_IOIS8;
+#endif
+       writeb(ecsr, addr + (ECSR << SMC_IO_SHIFT));
+       local_irq_restore(flags);
+
+       iounmap(addr);
+
+       /*
+        * Wait for the chip to wake up.  We could poll the control
+        * register in the main register space, but that isn't mapped
+        * yet.  We know this is going to take 750us.
+        */
+       msleep(1);
+
+       return 0;
+}
+
+/*
+ * smc_init(void)
+ *   Input parameters:
+ *     dev->base_addr == 0, try to find all possible locations
+ *     dev->base_addr > 0x1ff, this is the address to check
+ *     dev->base_addr == <anything else>, return failure code
+ *
+ *   Output:
+ *     0 --> there is a device
+ *     anything else, error
+ */
+static int smc_drv_probe(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct net_device *ndev;
+       struct resource *res, *ext = NULL;
+       unsigned int *addr;
+       int ret;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               ret = -ENODEV;
+               goto out;
+       }
+
+       /*
+        * Request the regions.
+        */
+       if (!request_mem_region(res->start, SMC_IO_EXTENT, "smc91x")) {
+               ret = -EBUSY;
+               goto out;
+       }
+
+       ndev = alloc_etherdev(sizeof(struct smc_local));
+       if (!ndev) {
+               printk("%s: could not allocate device.\n", CARDNAME);
+               ret = -ENOMEM;
+               goto release_1;
+       }
+       SET_MODULE_OWNER(ndev);
+       SET_NETDEV_DEV(ndev, dev);
+
+       ndev->dma = (unsigned char)-1;
+       ndev->irq = platform_get_irq(pdev, 0);
+
+       ext = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       if (ext) {
+               if (!request_mem_region(ext->start, ATTRIB_SIZE, ndev->name)) {
+                       ret = -EBUSY;
+                       goto release_1;
+               }
+
+#if defined(CONFIG_SA1100_ASSABET)
+               NCR_0 |= NCR_ENET_OSC_EN;
+#endif
+
+               ret = smc_enable_device(ext->start);
+               if (ret)
+                       goto release_both;
+       }
+
+       addr = ioremap(res->start, SMC_IO_EXTENT);
+       if (!addr) {
+               ret = -ENOMEM;
+               goto release_both;
+       }
+
+       dev_set_drvdata(dev, ndev);
+       ret = smc_probe(ndev, (unsigned long)addr);
+       if (ret != 0) {
+               dev_set_drvdata(dev, NULL);
+               iounmap(addr);
+ release_both:
+               if (ext)
+                       release_mem_region(ext->start, ATTRIB_SIZE);
+               free_netdev(ndev);
+ release_1:
+               release_mem_region(res->start, SMC_IO_EXTENT);
+ out:
+               printk("%s: not found (%d).\n", CARDNAME, ret);
+       }
+#ifdef SMC_USE_PXA_DMA
+       else {
+               struct smc_local *lp = netdev_priv(ndev);
+               lp->physaddr = res->start;
+       }
+#endif
+
+       return ret;
+}
+
+static int smc_drv_remove(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct net_device *ndev = dev_get_drvdata(dev);
+       struct resource *res;
+
+       dev_set_drvdata(dev, NULL);
+
+       unregister_netdev(ndev);
+
+       free_irq(ndev->irq, ndev);
+
+#ifdef SMC_USE_PXA_DMA
+       if (ndev->dma != (unsigned char)-1)
+               pxa_free_dma(ndev->dma);
+#endif
+       iounmap((void *)ndev->base_addr);
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       if (res)
+               release_mem_region(res->start, ATTRIB_SIZE);
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       release_mem_region(res->start, SMC_IO_EXTENT);
+
+       free_netdev(ndev);
+
+       return 0;
+}
+
+static int smc_drv_suspend(struct device *dev, u32 state, u32 level)
+{
+       struct net_device *ndev = dev_get_drvdata(dev);
+
+       if (ndev && level == SUSPEND_DISABLE) {
+               if (netif_running(ndev)) {
+                       netif_device_detach(ndev);
+                       smc_shutdown(ndev->base_addr);
+               }
+       }
+       return 0;
+}
+
+static int smc_drv_resume(struct device *dev, u32 level)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct net_device *ndev = dev_get_drvdata(dev);
+
+       if (ndev && level == RESUME_ENABLE) {
+               struct smc_local *lp = netdev_priv(ndev);
+               unsigned long ioaddr = ndev->base_addr;
+
+               if (pdev->num_resources == 3)
+                       smc_enable_device(pdev->resource[2].start);
+               if (netif_running(ndev)) {
+                       smc_reset(ndev);
+                       smc_enable(ndev);
+                       SMC_SELECT_BANK(1);
+                       SMC_SET_MAC_ADDR(ndev->dev_addr);
+                       if (lp->phy_type != 0)
+                               smc_phy_configure(ndev);
+                       netif_device_attach(ndev);
+               }
+       }
+       return 0;
+}
+
+static struct device_driver smc_driver = {
+       .name           = CARDNAME,
+       .bus            = &platform_bus_type,
+       .probe          = smc_drv_probe,
+       .remove         = smc_drv_remove,
+       .suspend        = smc_drv_suspend,
+       .resume         = smc_drv_resume,
+};
+
+static int __init smc_init(void)
+{
+#ifdef MODULE
+       if (io == -1)
+               printk(KERN_WARNING 
+                       "%s: You shouldn't use auto-probing with insmod!\n",
+                       CARDNAME);
+#endif
+
+       return driver_register(&smc_driver);
+}
+
+static void __exit smc_cleanup(void)
+{
+       driver_unregister(&smc_driver);
+}
+
+module_init(smc_init);
+module_exit(smc_cleanup);
diff --git a/drivers/net/arm/smc91x.h b/drivers/net/arm/smc91x.h
new file mode 100644 (file)
index 0000000..5212e37
--- /dev/null
@@ -0,0 +1,829 @@
+/*------------------------------------------------------------------------
+ . smc91x.h - macros for SMSC's 91C9x/91C1xx single-chip Ethernet device.
+ .
+ . Copyright (C) 1996 by Erik Stahlman
+ . Copyright (C) 2001 Standard Microsystems Corporation
+ .     Developed by Simple Network Magic Corporation
+ . Copyright (C) 2003 Monta Vista Software, Inc.
+ .     Unified SMC91x driver by Nicolas Pitre
+ .
+ . 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
+ .
+ . Information contained in this file was obtained from the LAN91C111
+ . manual from SMC.  To get a copy, if you really want one, you can find
+ . information under www.smsc.com.
+ .
+ . Authors
+ .     Erik Stahlman           <erik@vt.edu>
+ .     Daris A Nevil           <dnevil@snmc.com>
+ .     Nicolas Pitre           <nico@cam.org>
+ .
+ ---------------------------------------------------------------------------*/
+#ifndef _SMC91X_H_
+#define _SMC91X_H_
+
+
+/*
+ * Define your architecture specific bus configuration parameters here.
+ */
+
+#if    defined(CONFIG_SA1100_GRAPHICSCLIENT) || \
+       defined(CONFIG_SA1100_PFS168) || \
+       defined(CONFIG_SA1100_FLEXANET) || \
+       defined(CONFIG_SA1100_GRAPHICSMASTER) || \
+       defined(CONFIG_ARCH_LUBBOCK)
+
+/* We can only do 16-bit reads and writes in the static memory space. */
+#define SMC_CAN_USE_8BIT       0
+#define SMC_CAN_USE_16BIT      1
+#define SMC_CAN_USE_32BIT      0
+#define SMC_NOWAIT             1
+
+/* The first two address lines aren't connected... */
+#define SMC_IO_SHIFT           2
+
+#define SMC_inw(a, r)          readw((a) + (r))
+#define SMC_outw(v, a, r)      writew(v, (a) + (r))
+#define SMC_insw(a, r, p, l)   readsw((a) + (r), p, l)
+#define SMC_outsw(a, r, p, l)  writesw((a) + (r), p, l)
+
+#elif defined(CONFIG_SA1100_ASSABET)
+
+#include <asm/arch/neponset.h>
+
+/* We can only do 8-bit reads and writes in the static memory space. */
+#define SMC_CAN_USE_8BIT       1
+#define SMC_CAN_USE_16BIT      0
+#define SMC_CAN_USE_32BIT      0
+#define SMC_NOWAIT             1
+
+/* The first two address lines aren't connected... */
+#define SMC_IO_SHIFT           2
+
+#define SMC_inb(a, r)          readb((a) + (r))
+#define SMC_outb(v, a, r)      writeb(v, (a) + (r))
+#define SMC_insb(a, r, p, l)   readsb((a) + (r), p, (l))
+#define SMC_outsb(a, r, p, l)  writesb((a) + (r), p, (l))
+
+#elif  defined(CONFIG_ARCH_INNOKOM) || \
+       defined(CONFIG_MACH_MAINSTONE) || \
+       defined(CONFIG_ARCH_PXA_IDP) || \
+       defined(CONFIG_ARCH_RAMSES)
+
+#define SMC_CAN_USE_8BIT       1
+#define SMC_CAN_USE_16BIT      1
+#define SMC_CAN_USE_32BIT      1
+#define SMC_IO_SHIFT           0
+#define SMC_NOWAIT             1
+#define SMC_USE_PXA_DMA                1
+
+#define SMC_inb(a, r)          readb((a) + (r))
+#define SMC_inw(a, r)          readw((a) + (r))
+#define SMC_inl(a, r)          readl((a) + (r))
+#define SMC_outb(v, a, r)      writeb(v, (a) + (r))
+#define SMC_outl(v, a, r)      writel(v, (a) + (r))
+#define SMC_insl(a, r, p, l)   readsl((a) + (r), p, l)
+#define SMC_outsl(a, r, p, l)  writesl((a) + (r), p, l)
+
+/* We actually can't write halfwords properly if not word aligned */
+static inline void
+SMC_outw(u16 val, unsigned long ioaddr, int reg)
+{
+       if (reg & 2) {
+               unsigned int v = val << 16;
+               v |= readl(ioaddr + (reg & ~2)) & 0xffff;
+               writel(v, ioaddr + (reg & ~2));
+       } else {
+               writew(val, ioaddr + reg);
+       }
+}
+
+#elif  defined(CONFIG_ISA)
+
+#define SMC_CAN_USE_8BIT       1
+#define SMC_CAN_USE_16BIT      1
+#define SMC_CAN_USE_32BIT      0
+
+#define SMC_inb(a, r)          inb((a) + (r))
+#define SMC_inw(a, r)          inw((a) + (r))
+#define SMC_outb(v, a, r)      outb(v, (a) + (r))
+#define SMC_outw(v, a, r)      outw(v, (a) + (r))
+#define SMC_insw(a, r, p, l)   insw((a) + (r), p, l)
+#define SMC_outsw(a, r, p, l)  outsw((a) + (r), p, l)
+
+#else
+
+#define SMC_CAN_USE_8BIT       1
+#define SMC_CAN_USE_16BIT      1
+#define SMC_CAN_USE_32BIT      1
+#define SMC_NOWAIT             1
+
+#define SMC_inb(a, r)          readb((a) + (r))
+#define SMC_inw(a, r)          readw((a) + (r))
+#define SMC_inl(a, r)          readl((a) + (r))
+#define SMC_outb(v, a, r)      writeb(v, (a) + (r))
+#define SMC_outw(v, a, r)      writew(v, (a) + (r))
+#define SMC_outl(v, a, r)      writel(v, (a) + (r))
+#define SMC_insl(a, r, p, l)   readsl((a) + (r), p, l)
+#define SMC_outsl(a, r, p, l)  writesl((a) + (r), p, l)
+
+#define RPC_LSA_DEFAULT                RPC_LED_100_10
+#define RPC_LSB_DEFAULT                RPC_LED_TX_RX
+
+#endif
+
+
+#ifdef SMC_USE_PXA_DMA
+/*
+ * Let's use the DMA engine on the XScale PXA2xx for RX packets. This is
+ * always happening in irq context so no need to worry about races.  TX is
+ * different and probably not worth it for that reason, and not as critical
+ * as RX which can overrun memory and lose packets.
+ */
+#include <linux/pci.h>
+#include <asm/dma.h>
+
+#ifdef SMC_insl
+#undef SMC_insl
+#define SMC_insl(a, r, p, l) \
+       smc_pxa_dma_insl(a, lp->physaddr, r, dev->dma, p, l)
+static inline void
+smc_pxa_dma_insl(u_long ioaddr, u_long physaddr, int reg, int dma,
+                u_char *buf, int len)
+{
+       dma_addr_t dmabuf;
+
+       /* fallback if no DMA available */
+       if (dma == (unsigned char)-1) {
+               readsl(ioaddr + reg, buf, len);
+               return;
+       }
+
+       /* 64 bit alignment is required for memory to memory DMA */
+       if ((long)buf & 4) {
+               *((u32 *)buf)++ = SMC_inl(ioaddr, reg);
+               len--;
+       }
+
+       len *= 4;
+       dmabuf = dma_map_single(NULL, buf, len, PCI_DMA_FROMDEVICE);
+       DCSR(dma) = DCSR_NODESC;
+       DTADR(dma) = dmabuf;
+       DSADR(dma) = physaddr + reg;
+       DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 |
+                    DCMD_WIDTH4 | (DCMD_LENGTH & len));
+       DCSR(dma) = DCSR_NODESC | DCSR_RUN;
+       while (!(DCSR(dma) & DCSR_STOPSTATE));
+       DCSR(dma) = 0;
+       dma_unmap_single(NULL, dmabuf, len, PCI_DMA_FROMDEVICE);
+}
+#endif
+
+#ifdef SMC_insw
+#undef SMC_insw
+#define SMC_insw(a, r, p, l) \
+       smc_pxa_dma_insw(a, lp->physaddr, r, dev->dma, p, l)
+static inline void
+smc_pxa_dma_insw(u_long ioaddr, u_long physaddr, int reg, int dma,
+                u_char *buf, int len)
+{
+       dma_addr_t dmabuf;
+
+       /* fallback if no DMA available */
+       if (dma == (unsigned char)-1) {
+               readsw(ioaddr + reg, buf, len);
+               return;
+       }
+
+       /* 64 bit alignment is required for memory to memory DMA */
+       while ((long)buf & 6) {
+               *((u16 *)buf)++ = SMC_inw(ioaddr, reg);
+               len--;
+       }
+
+       len *= 2;
+       dmabuf = dma_map_single(NULL, buf, len, PCI_DMA_FROMDEVICE);
+       DCSR(dma) = DCSR_NODESC;
+       DTADR(dma) = dmabuf;
+       DSADR(dma) = physaddr + reg;
+       DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 |
+                    DCMD_WIDTH2 | (DCMD_LENGTH & len));
+       DCSR(dma) = DCSR_NODESC | DCSR_RUN;
+       while (!(DCSR(dma) & DCSR_STOPSTATE));
+       DCSR(dma) = 0;
+       dma_unmap_single(NULL, dmabuf, len, PCI_DMA_FROMDEVICE);
+}
+#endif
+
+static void
+smc_pxa_dma_irq(int dma, void *dummy, struct pt_regs *regs)
+{
+       DCSR(dma) = 0;
+}
+#endif  /* SMC_USE_PXA_DMA */
+
+
+/* Because of bank switching, the LAN91x uses only 16 I/O ports */
+#ifndef SMC_IO_SHIFT
+#define SMC_IO_SHIFT   0
+#endif
+#define SMC_IO_EXTENT  (16 << SMC_IO_SHIFT)
+
+
+/*
+ . Bank Select Register:
+ .
+ .             yyyy yyyy 0000 00xx
+ .             xx              = bank number
+ .             yyyy yyyy       = 0x33, for identification purposes.
+*/
+#define BANK_SELECT            (14 << SMC_IO_SHIFT)
+
+
+// Transmit Control Register
+/* BANK 0  */
+#define TCR_REG        SMC_REG(0x0000, 0)
+#define TCR_ENABLE     0x0001  // When 1 we can transmit
+#define TCR_LOOP       0x0002  // Controls output pin LBK
+#define TCR_FORCOL     0x0004  // When 1 will force a collision
+#define TCR_PAD_EN     0x0080  // When 1 will pad tx frames < 64 bytes w/0
+#define TCR_NOCRC      0x0100  // When 1 will not append CRC to tx frames
+#define TCR_MON_CSN    0x0400  // When 1 tx monitors carrier
+#define TCR_FDUPLX     0x0800  // When 1 enables full duplex operation
+#define TCR_STP_SQET   0x1000  // When 1 stops tx if Signal Quality Error
+#define TCR_EPH_LOOP   0x2000  // When 1 enables EPH block loopback
+#define TCR_SWFDUP     0x8000  // When 1 enables Switched Full Duplex mode
+
+#define TCR_CLEAR      0       /* do NOTHING */
+/* the default settings for the TCR register : */
+#define TCR_DEFAULT    (TCR_ENABLE | TCR_PAD_EN)
+
+
+// EPH Status Register
+/* BANK 0  */
+#define EPH_STATUS_REG SMC_REG(0x0002, 0)
+#define ES_TX_SUC      0x0001  // Last TX was successful
+#define ES_SNGL_COL    0x0002  // Single collision detected for last tx
+#define ES_MUL_COL     0x0004  // Multiple collisions detected for last tx
+#define ES_LTX_MULT    0x0008  // Last tx was a multicast
+#define ES_16COL       0x0010  // 16 Collisions Reached
+#define ES_SQET                0x0020  // Signal Quality Error Test
+#define ES_LTXBRD      0x0040  // Last tx was a broadcast
+#define ES_TXDEFR      0x0080  // Transmit Deferred
+#define ES_LATCOL      0x0200  // Late collision detected on last tx
+#define ES_LOSTCARR    0x0400  // Lost Carrier Sense
+#define ES_EXC_DEF     0x0800  // Excessive Deferral
+#define ES_CTR_ROL     0x1000  // Counter Roll Over indication
+#define ES_LINK_OK     0x4000  // Driven by inverted value of nLNK pin
+#define ES_TXUNRN      0x8000  // Tx Underrun
+
+
+// Receive Control Register
+/* BANK 0  */
+#define RCR_REG                SMC_REG(0x0004, 0)
+#define RCR_RX_ABORT   0x0001  // Set if a rx frame was aborted
+#define RCR_PRMS       0x0002  // Enable promiscuous mode
+#define RCR_ALMUL      0x0004  // When set accepts all multicast frames
+#define RCR_RXEN       0x0100  // IFF this is set, we can receive packets
+#define RCR_STRIP_CRC  0x0200  // When set strips CRC from rx packets
+#define RCR_ABORT_ENB  0x0200  // When set will abort rx on collision
+#define RCR_FILT_CAR   0x0400  // When set filters leading 12 bit s of carrier
+#define RCR_SOFTRST    0x8000  // resets the chip
+
+/* the normal settings for the RCR register : */
+#define RCR_DEFAULT    (RCR_STRIP_CRC | RCR_RXEN)
+#define RCR_CLEAR      0x0     // set it to a base state
+
+
+// Counter Register
+/* BANK 0  */
+#define COUNTER_REG    SMC_REG(0x0006, 0)
+
+
+// Memory Information Register
+/* BANK 0  */
+#define MIR_REG                SMC_REG(0x0008, 0)
+
+
+// Receive/Phy Control Register
+/* BANK 0  */
+#define RPC_REG                SMC_REG(0x000A, 0)
+#define RPC_SPEED      0x2000  // When 1 PHY is in 100Mbps mode.
+#define RPC_DPLX       0x1000  // When 1 PHY is in Full-Duplex Mode
+#define RPC_ANEG       0x0800  // When 1 PHY is in Auto-Negotiate Mode
+#define RPC_LSXA_SHFT  5       // Bits to shift LS2A,LS1A,LS0A to lsb
+#define RPC_LSXB_SHFT  2       // Bits to get LS2B,LS1B,LS0B to lsb
+#define RPC_LED_100_10 (0x00)  // LED = 100Mbps OR's with 10Mbps link detect
+#define RPC_LED_RES    (0x01)  // LED = Reserved
+#define RPC_LED_10     (0x02)  // LED = 10Mbps link detect
+#define RPC_LED_FD     (0x03)  // LED = Full Duplex Mode
+#define RPC_LED_TX_RX  (0x04)  // LED = TX or RX packet occurred
+#define RPC_LED_100    (0x05)  // LED = 100Mbps link dectect
+#define RPC_LED_TX     (0x06)  // LED = TX packet occurred
+#define RPC_LED_RX     (0x07)  // LED = RX packet occurred
+
+#ifndef RPC_LSA_DEFAULT
+#define RPC_LSA_DEFAULT        RPC_LED_100
+#endif
+#ifndef RPC_LSB_DEFAULT
+#define RPC_LSB_DEFAULT RPC_LED_FD
+#endif
+
+#define RPC_DEFAULT (RPC_ANEG | (RPC_LSA_DEFAULT << RPC_LSXA_SHFT) | (RPC_LSB_DEFAULT << RPC_LSXB_SHFT) | RPC_SPEED | RPC_DPLX)
+
+
+/* Bank 0 0x0C is reserved */
+
+// Bank Select Register
+/* All Banks */
+#define BSR_REG                0x000E
+
+
+// Configuration Reg
+/* BANK 1 */
+#define CONFIG_REG     SMC_REG(0x0000, 1)
+#define CONFIG_EXT_PHY 0x0200  // 1=external MII, 0=internal Phy
+#define CONFIG_GPCNTRL 0x0400  // Inverse value drives pin nCNTRL
+#define CONFIG_NO_WAIT 0x1000  // When 1 no extra wait states on ISA bus
+#define CONFIG_EPH_POWER_EN 0x8000 // When 0 EPH is placed into low power mode.
+
+// Default is powered-up, Internal Phy, Wait States, and pin nCNTRL=low
+#define CONFIG_DEFAULT (CONFIG_EPH_POWER_EN)
+
+
+// Base Address Register
+/* BANK 1 */
+#define BASE_REG       SMC_REG(0x0002, 1)
+
+
+// Individual Address Registers
+/* BANK 1 */
+#define ADDR0_REG      SMC_REG(0x0004, 1)
+#define ADDR1_REG      SMC_REG(0x0006, 1)
+#define ADDR2_REG      SMC_REG(0x0008, 1)
+
+
+// General Purpose Register
+/* BANK 1 */
+#define GP_REG         SMC_REG(0x000A, 1)
+
+
+// Control Register
+/* BANK 1 */
+#define CTL_REG                SMC_REG(0x000C, 1)
+#define CTL_RCV_BAD    0x4000 // When 1 bad CRC packets are received
+#define CTL_AUTO_RELEASE 0x0800 // When 1 tx pages are released automatically
+#define CTL_LE_ENABLE  0x0080 // When 1 enables Link Error interrupt
+#define CTL_CR_ENABLE  0x0040 // When 1 enables Counter Rollover interrupt
+#define CTL_TE_ENABLE  0x0020 // When 1 enables Transmit Error interrupt
+#define CTL_EEPROM_SELECT 0x0004 // Controls EEPROM reload & store
+#define CTL_RELOAD     0x0002 // When set reads EEPROM into registers
+#define CTL_STORE      0x0001 // When set stores registers into EEPROM
+
+
+// MMU Command Register
+/* BANK 2 */
+#define MMU_CMD_REG    SMC_REG(0x0000, 2)
+#define MC_BUSY                1       // When 1 the last release has not completed
+#define MC_NOP         (0<<5)  // No Op
+#define MC_ALLOC       (1<<5)  // OR with number of 256 byte packets
+#define MC_RESET       (2<<5)  // Reset MMU to initial state
+#define MC_REMOVE      (3<<5)  // Remove the current rx packet
+#define MC_RELEASE     (4<<5)  // Remove and release the current rx packet
+#define MC_FREEPKT     (5<<5)  // Release packet in PNR register
+#define MC_ENQUEUE     (6<<5)  // Enqueue the packet for transmit
+#define MC_RSTTXFIFO   (7<<5)  // Reset the TX FIFOs
+
+
+// Packet Number Register
+/* BANK 2 */
+#define PN_REG         SMC_REG(0x0002, 2)
+
+
+// Allocation Result Register
+/* BANK 2 */
+#define AR_REG         SMC_REG(0x0003, 2)
+#define AR_FAILED      0x80    // Alocation Failed
+
+
+// TX FIFO Ports Register
+/* BANK 2 */
+#define TXFIFO_REG     SMC_REG(0x0004, 2)
+#define TXFIFO_TEMPTY  0x80    // TX FIFO Empty
+
+// RX FIFO Ports Register
+/* BANK 2 */
+#define RXFIFO_REG     SMC_REG(0x0005, 2)
+#define RXFIFO_REMPTY  0x80    // RX FIFO Empty
+
+#define FIFO_REG       SMC_REG(0x0004, 2)
+
+// Pointer Register
+/* BANK 2 */
+#define PTR_REG                SMC_REG(0x0006, 2)
+#define PTR_RCV                0x8000 // 1=Receive area, 0=Transmit area
+#define PTR_AUTOINC    0x4000 // Auto increment the pointer on each access
+#define PTR_READ       0x2000 // When 1 the operation is a read
+
+
+// Data Register
+/* BANK 2 */
+#define DATA_REG       SMC_REG(0x0008, 2)
+
+
+// Interrupt Status/Acknowledge Register
+/* BANK 2 */
+#define INT_REG                SMC_REG(0x000C, 2)
+
+
+// Interrupt Mask Register
+/* BANK 2 */
+#define IM_REG         SMC_REG(0x000D, 2)
+#define IM_MDINT       0x80 // PHY MI Register 18 Interrupt
+#define IM_ERCV_INT    0x40 // Early Receive Interrupt
+#define IM_EPH_INT     0x20 // Set by Ethernet Protocol Handler section
+#define IM_RX_OVRN_INT 0x10 // Set by Receiver Overruns
+#define IM_ALLOC_INT   0x08 // Set when allocation request is completed
+#define IM_TX_EMPTY_INT        0x04 // Set if the TX FIFO goes empty
+#define IM_TX_INT      0x02 // Transmit Interrupt
+#define IM_RCV_INT     0x01 // Receive Interrupt
+
+
+// Multicast Table Registers
+/* BANK 3 */
+#define MCAST_REG1     SMC_REG(0x0000, 3)
+#define MCAST_REG2     SMC_REG(0x0002, 3)
+#define MCAST_REG3     SMC_REG(0x0004, 3)
+#define MCAST_REG4     SMC_REG(0x0006, 3)
+
+
+// Management Interface Register (MII)
+/* BANK 3 */
+#define MII_REG                SMC_REG(0x0008, 3)
+#define MII_MSK_CRS100 0x4000 // Disables CRS100 detection during tx half dup
+#define MII_MDOE       0x0008 // MII Output Enable
+#define MII_MCLK       0x0004 // MII Clock, pin MDCLK
+#define MII_MDI                0x0002 // MII Input, pin MDI
+#define MII_MDO                0x0001 // MII Output, pin MDO
+
+
+// Revision Register
+/* BANK 3 */
+/* ( hi: chip id   low: rev # ) */
+#define REV_REG                SMC_REG(0x000A, 3)
+
+
+// Early RCV Register
+/* BANK 3 */
+/* this is NOT on SMC9192 */
+#define ERCV_REG       SMC_REG(0x000C, 3)
+#define ERCV_RCV_DISCRD        0x0080 // When 1 discards a packet being received
+#define ERCV_THRESHOLD 0x001F // ERCV Threshold Mask
+
+
+// External Register
+/* BANK 7 */
+#define EXT_REG                SMC_REG(0x0000, 7)
+
+
+#define CHIP_9192      3
+#define CHIP_9194      4
+#define CHIP_9195      5
+#define CHIP_9196      6
+#define CHIP_91100     7
+#define CHIP_91100FD   8
+#define CHIP_91111FD   9
+
+static const char * chip_ids[ 16 ] =  {
+       NULL, NULL, NULL,
+       /* 3 */ "SMC91C90/91C92",
+       /* 4 */ "SMC91C94",
+       /* 5 */ "SMC91C95",
+       /* 6 */ "SMC91C96",
+       /* 7 */ "SMC91C100",
+       /* 8 */ "SMC91C100FD",
+       /* 9 */ "SMC91C11xFD",
+       NULL, NULL, NULL,
+       NULL, NULL, NULL};
+
+
+/*
+ . Transmit status bits
+*/
+#define TS_SUCCESS 0x0001
+#define TS_LOSTCAR 0x0400
+#define TS_LATCOL  0x0200
+#define TS_16COL   0x0010
+
+/*
+ . Receive status bits
+*/
+#define RS_ALGNERR     0x8000
+#define RS_BRODCAST    0x4000
+#define RS_BADCRC      0x2000
+#define RS_ODDFRAME    0x1000
+#define RS_TOOLONG     0x0800
+#define RS_TOOSHORT    0x0400
+#define RS_MULTICAST   0x0001
+#define RS_ERRORS      (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT)
+
+
+/*
+ * PHY IDs
+ *  LAN83C183 == LAN91C111 Internal PHY
+ */
+#define PHY_LAN83C183  0x0016f840
+#define PHY_LAN83C180  0x02821c50
+
+/*
+ * PHY Register Addresses (LAN91C111 Internal PHY)
+ *
+ * Generic PHY registers can be found in <linux/mii.h>
+ *
+ * These phy registers are specific to our on-board phy.
+ */
+
+// PHY Configuration Register 1
+#define PHY_CFG1_REG           0x10
+#define PHY_CFG1_LNKDIS                0x8000  // 1=Rx Link Detect Function disabled
+#define PHY_CFG1_XMTDIS                0x4000  // 1=TP Transmitter Disabled
+#define PHY_CFG1_XMTPDN                0x2000  // 1=TP Transmitter Powered Down
+#define PHY_CFG1_BYPSCR                0x0400  // 1=Bypass scrambler/descrambler
+#define PHY_CFG1_UNSCDS                0x0200  // 1=Unscramble Idle Reception Disable
+#define PHY_CFG1_EQLZR         0x0100  // 1=Rx Equalizer Disabled
+#define PHY_CFG1_CABLE         0x0080  // 1=STP(150ohm), 0=UTP(100ohm)
+#define PHY_CFG1_RLVL0         0x0040  // 1=Rx Squelch level reduced by 4.5db
+#define PHY_CFG1_TLVL_SHIFT    2       // Transmit Output Level Adjust
+#define PHY_CFG1_TLVL_MASK     0x003C
+#define PHY_CFG1_TRF_MASK      0x0003  // Transmitter Rise/Fall time
+
+
+// PHY Configuration Register 2
+#define PHY_CFG2_REG           0x11
+#define PHY_CFG2_APOLDIS       0x0020  // 1=Auto Polarity Correction disabled
+#define PHY_CFG2_JABDIS                0x0010  // 1=Jabber disabled
+#define PHY_CFG2_MREG          0x0008  // 1=Multiple register access (MII mgt)
+#define PHY_CFG2_INTMDIO       0x0004  // 1=Interrupt signaled with MDIO pulseo
+
+// PHY Status Output (and Interrupt status) Register
+#define PHY_INT_REG            0x12    // Status Output (Interrupt Status)
+#define PHY_INT_INT            0x8000  // 1=bits have changed since last read
+#define PHY_INT_LNKFAIL                0x4000  // 1=Link Not detected
+#define PHY_INT_LOSSSYNC       0x2000  // 1=Descrambler has lost sync
+#define PHY_INT_CWRD           0x1000  // 1=Invalid 4B5B code detected on rx
+#define PHY_INT_SSD            0x0800  // 1=No Start Of Stream detected on rx
+#define PHY_INT_ESD            0x0400  // 1=No End Of Stream detected on rx
+#define PHY_INT_RPOL           0x0200  // 1=Reverse Polarity detected
+#define PHY_INT_JAB            0x0100  // 1=Jabber detected
+#define PHY_INT_SPDDET         0x0080  // 1=100Base-TX mode, 0=10Base-T mode
+#define PHY_INT_DPLXDET                0x0040  // 1=Device in Full Duplex
+
+// PHY Interrupt/Status Mask Register
+#define PHY_MASK_REG           0x13    // Interrupt Mask
+// Uses the same bit definitions as PHY_INT_REG
+
+
+/*
+ * SMC91C96 ethernet config and status registers.
+ * These are in the "attribute" space.
+ */
+#define ECOR                   0x8000
+#define ECOR_RESET             0x80
+#define ECOR_LEVEL_IRQ         0x40
+#define ECOR_WR_ATTRIB         0x04
+#define ECOR_ENABLE            0x01
+
+#define ECSR                   0x8002
+#define ECSR_IOIS8             0x20
+#define ECSR_PWRDWN            0x04
+#define ECSR_INT               0x02
+
+#define ATTRIB_SIZE            ((64*1024) << SMC_IO_SHIFT)
+
+
+/*
+ * Macros to abstract register access according to the data bus
+ * capabilities.  Please use those and not the in/out primitives.
+ * Note: the following macros do *not* select the bank -- this must
+ * be done separately as needed in the main code.  The SMC_REG() macro
+ * only uses the bank argument for debugging purposes (when enabled).
+ */
+
+#if SMC_DEBUG > 0
+#define SMC_REG(reg, bank)                                             \
+       ({                                                              \
+               int __b = SMC_CURRENT_BANK();                           \
+               if (unlikely((__b & ~0xf0) != (0x3300 | bank))) {       \
+                       printk( "%s: bank reg screwed (0x%04x)\n",      \
+                               CARDNAME, __b );                        \
+                       BUG();                                          \
+               }                                                       \
+               reg<<SMC_IO_SHIFT;                                      \
+       })
+#else
+#define SMC_REG(reg, bank)     (reg<<SMC_IO_SHIFT)
+#endif
+
+#if SMC_CAN_USE_8BIT
+#define SMC_GET_PN()           SMC_inb( ioaddr, PN_REG )
+#define SMC_SET_PN(x)          SMC_outb( x, ioaddr, PN_REG )
+#define SMC_GET_AR()           SMC_inb( ioaddr, AR_REG )
+#define SMC_GET_TXFIFO()       SMC_inb( ioaddr, TXFIFO_REG )
+#define SMC_GET_RXFIFO()       SMC_inb( ioaddr, RXFIFO_REG )
+#define SMC_GET_INT()          SMC_inb( ioaddr, INT_REG )
+#define SMC_ACK_INT(x)         SMC_outb( x, ioaddr, INT_REG )
+#define SMC_GET_INT_MASK()     SMC_inb( ioaddr, IM_REG )
+#define SMC_SET_INT_MASK(x)    SMC_outb( x, ioaddr, IM_REG )
+#else
+#define SMC_GET_PN()           (SMC_inw( ioaddr, PN_REG ) & 0xFF)
+#define SMC_SET_PN(x)          SMC_outw( x, ioaddr, PN_REG )
+#define SMC_GET_AR()           (SMC_inw( ioaddr, PN_REG ) >> 8)
+#define SMC_GET_TXFIFO()       (SMC_inw( ioaddr, TXFIFO_REG ) & 0xFF)
+#define SMC_GET_RXFIFO()       (SMC_inw( ioaddr, TXFIFO_REG ) >> 8)
+#define SMC_GET_INT()          (SMC_inw( ioaddr, INT_REG ) & 0xFF)
+#define SMC_ACK_INT(x)                                                 \
+       do {                                                            \
+               unsigned long __flags;                                  \
+               int __mask;                                             \
+               local_irq_save(__flags);                                \
+               __mask = SMC_inw( ioaddr, INT_REG ) & ~0xff;            \
+               SMC_outw( __mask | (x), ioaddr, INT_REG );              \
+               local_irq_restore(__flags);                             \
+       } while (0)
+#define SMC_GET_INT_MASK()     (SMC_inw( ioaddr, INT_REG ) >> 8)
+#define SMC_SET_INT_MASK(x)    SMC_outw( (x) << 8, ioaddr, INT_REG )
+#endif
+
+#define SMC_CURRENT_BANK()     SMC_inw( ioaddr, BANK_SELECT )
+#define SMC_SELECT_BANK(x)     SMC_outw( x, ioaddr, BANK_SELECT )
+#define SMC_GET_BASE()         SMC_inw( ioaddr, BASE_REG )
+#define SMC_SET_BASE(x)                SMC_outw( x, ioaddr, BASE_REG )
+#define SMC_GET_CONFIG()       SMC_inw( ioaddr, CONFIG_REG )
+#define SMC_SET_CONFIG(x)      SMC_outw( x, ioaddr, CONFIG_REG )
+#define SMC_GET_COUNTER()      SMC_inw( ioaddr, COUNTER_REG )
+#define SMC_GET_CTL()          SMC_inw( ioaddr, CTL_REG )
+#define SMC_SET_CTL(x)         SMC_outw( x, ioaddr, CTL_REG )
+#define SMC_GET_MII()          SMC_inw( ioaddr, MII_REG )
+#define SMC_SET_MII(x)         SMC_outw( x, ioaddr, MII_REG )
+#define SMC_GET_MIR()          SMC_inw( ioaddr, MIR_REG )
+#define SMC_SET_MIR(x)         SMC_outw( x, ioaddr, MIR_REG )
+#define SMC_GET_MMU_CMD()      SMC_inw( ioaddr, MMU_CMD_REG )
+#define SMC_SET_MMU_CMD(x)     SMC_outw( x, ioaddr, MMU_CMD_REG )
+#define SMC_GET_FIFO()         SMC_inw( ioaddr, FIFO_REG )
+#define SMC_GET_PTR()          SMC_inw( ioaddr, PTR_REG )
+#define SMC_SET_PTR(x)         SMC_outw( x, ioaddr, PTR_REG )
+#define SMC_GET_RCR()          SMC_inw( ioaddr, RCR_REG )
+#define SMC_SET_RCR(x)         SMC_outw( x, ioaddr, RCR_REG )
+#define SMC_GET_REV()          SMC_inw( ioaddr, REV_REG )
+#define SMC_GET_RPC()          SMC_inw( ioaddr, RPC_REG )
+#define SMC_SET_RPC(x)         SMC_outw( x, ioaddr, RPC_REG )
+#define SMC_GET_TCR()          SMC_inw( ioaddr, TCR_REG )
+#define SMC_SET_TCR(x)         SMC_outw( x, ioaddr, TCR_REG )
+
+#ifndef SMC_GET_MAC_ADDR
+#define SMC_GET_MAC_ADDR(addr)                                         \
+       do {                                                            \
+               unsigned int __v;                                       \
+               __v = SMC_inw( ioaddr, ADDR0_REG );                     \
+               addr[0] = __v; addr[1] = __v >> 8;                      \
+               __v = SMC_inw( ioaddr, ADDR1_REG );                     \
+               addr[2] = __v; addr[3] = __v >> 8;                      \
+               __v = SMC_inw( ioaddr, ADDR2_REG );                     \
+               addr[4] = __v; addr[5] = __v >> 8;                      \
+       } while (0)
+#endif
+
+#define SMC_SET_MAC_ADDR(addr)                                         \
+       do {                                                            \
+               SMC_outw( addr[0]|(addr[1] << 8), ioaddr, ADDR0_REG );  \
+               SMC_outw( addr[2]|(addr[3] << 8), ioaddr, ADDR1_REG );  \
+               SMC_outw( addr[4]|(addr[5] << 8), ioaddr, ADDR2_REG );  \
+       } while (0)
+
+#define SMC_CLEAR_MCAST()                                              \
+       do {                                                            \
+               SMC_outw( 0, ioaddr, MCAST_REG1 );                      \
+               SMC_outw( 0, ioaddr, MCAST_REG2 );                      \
+               SMC_outw( 0, ioaddr, MCAST_REG3 );                      \
+               SMC_outw( 0, ioaddr, MCAST_REG4 );                      \
+       } while (0)
+#define SMC_SET_MCAST(x)                                               \
+       do {                                                            \
+               unsigned char *mt = (x);                                \
+               SMC_outw( mt[0] | (mt[1] << 8), ioaddr, MCAST_REG1 );   \
+               SMC_outw( mt[2] | (mt[3] << 8), ioaddr, MCAST_REG2 );   \
+               SMC_outw( mt[4] | (mt[5] << 8), ioaddr, MCAST_REG3 );   \
+               SMC_outw( mt[6] | (mt[7] << 8), ioaddr, MCAST_REG4 );   \
+       } while (0)
+
+#if SMC_CAN_USE_32BIT
+/*
+ * Some setups just can't write 8 or 16 bits reliably when not aligned
+ * to a 32 bit boundary.  I tell you that exists!
+ * We re-do the ones here that can be easily worked around if they can have
+ * their low parts written to 0 without adverse effects.
+ */
+#undef SMC_SELECT_BANK
+#define SMC_SELECT_BANK(x)     SMC_outl( (x)<<16, ioaddr, 12<<SMC_IO_SHIFT )
+#undef SMC_SET_RPC
+#define SMC_SET_RPC(x)         SMC_outl( (x)<<16, ioaddr, SMC_REG(8, 0) )
+#undef SMC_SET_PN
+#define SMC_SET_PN(x)          SMC_outl( (x)<<16, ioaddr, SMC_REG(0, 2) )
+#undef SMC_SET_PTR
+#define SMC_SET_PTR(x)         SMC_outl( (x)<<16, ioaddr, SMC_REG(4, 2) )
+#endif
+
+#if SMC_CAN_USE_32BIT
+#define SMC_PUT_PKT_HDR(status, length)                                        \
+       SMC_outl( (status) | (length) << 16, ioaddr, DATA_REG )
+#define SMC_GET_PKT_HDR(status, length)                                        \
+       do {                                                            \
+               unsigned int __val = SMC_inl( ioaddr, DATA_REG );       \
+               (status) = __val & 0xffff;                              \
+               (length) = __val >> 16;                                 \
+       } while (0)
+#else
+#define SMC_PUT_PKT_HDR(status, length)                                        \
+       do {                                                            \
+               SMC_outw( status, ioaddr, DATA_REG );                   \
+               SMC_outw( length, ioaddr, DATA_REG );                   \
+       } while (0)
+#define SMC_GET_PKT_HDR(status, length)                                        \
+       do {                                                            \
+               (status) = SMC_inw( ioaddr, DATA_REG );                 \
+               (length) = SMC_inw( ioaddr, DATA_REG );                 \
+       } while (0)
+#endif
+
+#if SMC_CAN_USE_32BIT
+#define SMC_PUSH_DATA(p, l)                                            \
+       do {                                                            \
+               char *__ptr = (p);                                      \
+               int __len = (l);                                        \
+               if (__len >= 2 && (long)__ptr & 2) {                    \
+                       __len -= 2;                                     \
+                       SMC_outw( *((u16 *)__ptr)++, ioaddr, DATA_REG );\
+               }                                                       \
+               SMC_outsl( ioaddr, DATA_REG, __ptr, __len >> 2);        \
+               if (__len & 2) {                                        \
+                       __ptr += (__len & ~3);                          \
+                       SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG );  \
+               }                                                       \
+       } while (0)
+#define SMC_PULL_DATA(p, l)                                            \
+       do {                                                            \
+               char *__ptr = (p);                                      \
+               int __len = (l);                                        \
+               if ((long)__ptr & 2) {                                  \
+                       /*                                              \
+                        * We want 32bit alignment here.                \
+                        * Since some buses perform a full 32bit        \
+                        * fetch even for 16bit data we can't use       \
+                        * SMC_inw() here.  Back both source (on chip   \
+                        * and destination) pointers of 2 bytes.        \
+                        */                                             \
+                       (long)__ptr &= ~2;                              \
+                       __len += 2;                                     \
+                       SMC_SET_PTR( 2|PTR_READ|PTR_RCV|PTR_AUTOINC );  \
+               }                                                       \
+               __len += 2;                                             \
+               SMC_insl( ioaddr, DATA_REG, __ptr, __len >> 2);         \
+       } while (0)
+#elif SMC_CAN_USE_16BIT
+#define SMC_PUSH_DATA(p, l)    SMC_outsw( ioaddr, DATA_REG, p, (l) >> 1 )
+#define SMC_PULL_DATA(p, l)    SMC_insw ( ioaddr, DATA_REG, p, (l) >> 1 )
+#elif SMC_CAN_USE_8BIT
+#define SMC_PUSH_DATA(p, l)    SMC_outsb( ioaddr, DATA_REG, p, l )
+#define SMC_PULL_DATA(p, l)    SMC_insb ( ioaddr, DATA_REG, p, l )
+#endif
+
+#if ! SMC_CAN_USE_16BIT
+#define SMC_outw(x, ioaddr, reg)                                       \
+       do {                                                            \
+               unsigned int __val16 = (x);                             \
+               SMC_outb( __val16, ioaddr, reg );                       \
+               SMC_outb( __val16 >> 8, ioaddr, reg + (1 << SMC_IO_SHIFT));\
+       } while (0)
+#define SMC_inw(ioaddr, reg)                                           \
+       ({                                                              \
+               unsigned int __val16;                                   \
+               __val16 =  SMC_inb( ioaddr, reg );                      \
+               __val16 |= SMC_inb( ioaddr, reg + (1 << SMC_IO_SHIFT)) << 8; \
+               __val16;                                                \
+       })
+#endif
+
+
+#endif  /* _SMC91X_H_ */
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
new file mode 100644 (file)
index 0000000..3356fd8
--- /dev/null
@@ -0,0 +1,3277 @@
+/*
+ * This code is derived from the VIA reference driver (copyright message
+ * below) provided to Red Hat by VIA Networking Technologies, Inc. for
+ * addition to the Linux kernel.
+ *
+ * The code has been merged into one source file, cleaned up to follow
+ * Linux coding style,  ported to the Linux 2.6 kernel tree and cleaned
+ * for 64bit hardware platforms.
+ *
+ * TODO
+ *     Big-endian support
+ *     rx_copybreak/alignment
+ *     Scatter gather
+ *     More testing
+ *
+ * The changes are (c) Copyright 2004, Red Hat Inc. <alan@redhat.com>
+ * Additional fixes and clean up: Francois Romieu
+ *
+ * This source has not been verified for use in safety critical systems.
+ *
+ * Please direct queries about the revamped driver to the linux-kernel
+ * list not VIA.
+ *
+ * Original code:
+ *
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * This software may be redistributed and/or modified under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or
+ * 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.
+ *
+ * Author: Chuang Liang-Shing, AJ Jiang
+ *
+ * Date: Jan 24, 2003
+ *
+ * MODULE_LICENSE("GPL");
+ *
+ */
+
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/version.h>
+#include <linux/string.h>
+#include <linux/wait.h>
+#include <asm/io.h>
+#include <linux/if.h>
+#include <linux/config.h>
+#include <asm/uaccess.h>
+#include <linux/proc_fs.h>
+#include <linux/inetdevice.h>
+#include <linux/reboot.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/in.h>
+#include <linux/if_arp.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+
+#include "via-velocity.h"
+
+
+static int velocity_nics = 0;
+static int msglevel = MSG_LEVEL_INFO;
+
+
+static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
+static struct ethtool_ops velocity_ethtool_ops;
+
+/*
+    Define module options
+*/
+
+MODULE_AUTHOR("VIA Networking Technologies, Inc.");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("VIA Networking Velocity Family Gigabit Ethernet Adapter Driver");
+
+#define VELOCITY_PARAM(N,D) \
+        static const int N[MAX_UNITS]=OPTION_DEFAULT;\
+        MODULE_PARM(N, "1-" __MODULE_STRING(MAX_UNITS) "i");\
+        MODULE_PARM_DESC(N, D);
+
+#define RX_DESC_MIN     64
+#define RX_DESC_MAX     255
+#define RX_DESC_DEF     64
+VELOCITY_PARAM(RxDescriptors, "Number of receive descriptors");
+
+#define TX_DESC_MIN     16
+#define TX_DESC_MAX     256
+#define TX_DESC_DEF     64
+VELOCITY_PARAM(TxDescriptors, "Number of transmit descriptors");
+
+#define VLAN_ID_MIN     0
+#define VLAN_ID_MAX     4095
+#define VLAN_ID_DEF     0
+/* VID_setting[] is used for setting the VID of NIC.
+   0: default VID.
+   1-4094: other VIDs.
+*/
+VELOCITY_PARAM(VID_setting, "802.1Q VLAN ID");
+
+#define RX_THRESH_MIN   0
+#define RX_THRESH_MAX   3
+#define RX_THRESH_DEF   0
+/* rx_thresh[] is used for controlling the receive fifo threshold.
+   0: indicate the rxfifo threshold is 128 bytes.
+   1: indicate the rxfifo threshold is 512 bytes.
+   2: indicate the rxfifo threshold is 1024 bytes.
+   3: indicate the rxfifo threshold is store & forward.
+*/
+VELOCITY_PARAM(rx_thresh, "Receive fifo threshold");
+
+#define DMA_LENGTH_MIN  0
+#define DMA_LENGTH_MAX  7
+#define DMA_LENGTH_DEF  0
+
+/* DMA_length[] is used for controlling the DMA length
+   0: 8 DWORDs
+   1: 16 DWORDs
+   2: 32 DWORDs
+   3: 64 DWORDs
+   4: 128 DWORDs
+   5: 256 DWORDs
+   6: SF(flush till emply)
+   7: SF(flush till emply)
+*/
+VELOCITY_PARAM(DMA_length, "DMA length");
+
+#define TAGGING_DEF     0
+/* enable_tagging[] is used for enabling 802.1Q VID tagging.
+   0: disable VID seeting(default).
+   1: enable VID setting.
+*/
+VELOCITY_PARAM(enable_tagging, "Enable 802.1Q tagging");
+
+#define IP_ALIG_DEF     0
+/* IP_byte_align[] is used for IP header DWORD byte aligned
+   0: indicate the IP header won't be DWORD byte aligned.(Default) .
+   1: indicate the IP header will be DWORD byte aligned.
+      In some enviroment, the IP header should be DWORD byte aligned,
+      or the packet will be droped when we receive it. (eg: IPVS)
+*/
+VELOCITY_PARAM(IP_byte_align, "Enable IP header dword aligned");
+
+#define TX_CSUM_DEF     1
+/* txcsum_offload[] is used for setting the checksum offload ability of NIC.
+   (We only support RX checksum offload now)
+   0: disable csum_offload[checksum offload
+   1: enable checksum offload. (Default)
+*/
+VELOCITY_PARAM(txcsum_offload, "Enable transmit packet checksum offload");
+
+#define FLOW_CNTL_DEF   1
+#define FLOW_CNTL_MIN   1
+#define FLOW_CNTL_MAX   5
+
+/* flow_control[] is used for setting the flow control ability of NIC.
+   1: hardware deafult - AUTO (default). Use Hardware default value in ANAR.
+   2: enable TX flow control.
+   3: enable RX flow control.
+   4: enable RX/TX flow control.
+   5: disable
+*/
+VELOCITY_PARAM(flow_control, "Enable flow control ability");
+
+#define MED_LNK_DEF 0
+#define MED_LNK_MIN 0
+#define MED_LNK_MAX 4
+/* speed_duplex[] is used for setting the speed and duplex mode of NIC.
+   0: indicate autonegotiation for both speed and duplex mode
+   1: indicate 100Mbps half duplex mode
+   2: indicate 100Mbps full duplex mode
+   3: indicate 10Mbps half duplex mode
+   4: indicate 10Mbps full duplex mode
+
+   Note:
+        if EEPROM have been set to the force mode, this option is ignored
+            by driver.
+*/
+VELOCITY_PARAM(speed_duplex, "Setting the speed and duplex mode");
+
+#define VAL_PKT_LEN_DEF     0
+/* ValPktLen[] is used for setting the checksum offload ability of NIC.
+   0: Receive frame with invalid layer 2 length (Default)
+   1: Drop frame with invalid layer 2 length
+*/
+VELOCITY_PARAM(ValPktLen, "Receiving or Drop invalid 802.3 frame");
+
+#define WOL_OPT_DEF     0
+#define WOL_OPT_MIN     0
+#define WOL_OPT_MAX     7
+/* wol_opts[] is used for controlling wake on lan behavior.
+   0: Wake up if recevied a magic packet. (Default)
+   1: Wake up if link status is on/off.
+   2: Wake up if recevied an arp packet.
+   4: Wake up if recevied any unicast packet.
+   Those value can be sumed up to support more than one option.
+*/
+VELOCITY_PARAM(wol_opts, "Wake On Lan options");
+
+#define INT_WORKS_DEF   20
+#define INT_WORKS_MIN   10
+#define INT_WORKS_MAX   64
+
+VELOCITY_PARAM(int_works, "Number of packets per interrupt services");
+
+static int velocity_found1(struct pci_dev *pdev, const struct pci_device_id *ent);
+static void velocity_init_info(struct pci_dev *pdev, struct velocity_info *vptr, struct velocity_info_tbl *info);
+static int velocity_get_pci_info(struct velocity_info *, struct pci_dev *pdev);
+static void velocity_print_info(struct velocity_info *vptr);
+static int velocity_open(struct net_device *dev);
+static int velocity_change_mtu(struct net_device *dev, int mtu);
+static int velocity_xmit(struct sk_buff *skb, struct net_device *dev);
+static int velocity_intr(int irq, void *dev_instance, struct pt_regs *regs);
+static void velocity_set_multi(struct net_device *dev);
+static struct net_device_stats *velocity_get_stats(struct net_device *dev);
+static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int velocity_close(struct net_device *dev);
+static int velocity_rx_srv(struct velocity_info *vptr, int status);
+static int velocity_receive_frame(struct velocity_info *, int idx);
+static int velocity_alloc_rx_buf(struct velocity_info *, int idx);
+static void velocity_init_registers(struct velocity_info *vptr, enum velocity_init_type type);
+static void velocity_free_rd_ring(struct velocity_info *vptr);
+static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *);
+static int velocity_soft_reset(struct velocity_info *vptr);
+static void mii_init(struct velocity_info *vptr, u32 mii_status);
+static u32 velocity_get_opt_media_mode(struct velocity_info *vptr);
+static void velocity_print_link_status(struct velocity_info *vptr);
+static void safe_disable_mii_autopoll(struct mac_regs * regs);
+static void velocity_shutdown(struct velocity_info *vptr);
+static void enable_flow_control_ability(struct velocity_info *vptr);
+static void enable_mii_autopoll(struct mac_regs * regs);
+static int velocity_mii_read(struct mac_regs *, u8 byIdx, u16 * pdata);
+static int velocity_mii_write(struct mac_regs *, u8 byMiiAddr, u16 data);
+static int velocity_set_wol(struct velocity_info *vptr);
+static void velocity_save_context(struct velocity_info *vptr, struct velocity_context *context);
+static void velocity_restore_context(struct velocity_info *vptr, struct velocity_context *context);
+static u32 mii_check_media_mode(struct mac_regs * regs);
+static u32 check_connection_type(struct mac_regs * regs);
+static void velocity_init_cam_filter(struct velocity_info *vptr);
+static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status);
+
+#ifdef CONFIG_PM
+static int velocity_suspend(struct pci_dev *pdev, u32 state);
+static int velocity_resume(struct pci_dev *pdev);
+
+static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr);
+
+static struct notifier_block velocity_inetaddr_notifier = {
+      notifier_call:velocity_netdev_event,
+};
+
+#endif                         /* CONFIG_PM */
+
+/*
+ *     Internal board variants. At the moment we have only one
+ */
+
+static struct velocity_info_tbl chip_info_table[] = {
+       {CHIP_TYPE_VT6110, "VIA Networking Velocity Family Gigabit Ethernet Adapter", 256, 1, 0x00FFFFFFUL},
+       {0, NULL}
+};
+
+/*
+ *     Describe the PCI device identifiers that we support in this
+ *     device driver. Used for hotplug autoloading.
+ */
+
+static struct pci_device_id velocity_id_table[] __devinitdata = {
+       {0x1106, 0x3119, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &chip_info_table[0]},
+       {0,}
+};
+
+MODULE_DEVICE_TABLE(pci, velocity_id_table);
+
+/**
+ *     get_chip_name   -       identifier to name
+ *     @id: chip identifier
+ *
+ *     Given a chip identifier return a suitable description. Returns
+ *     a pointer a static string valid while the driver is loaded.
+ */
+
+static char __devinit *get_chip_name(enum chip_type chip_id)
+{
+       int i;
+       for (i = 0; chip_info_table[i].name != NULL; i++)
+               if (chip_info_table[i].chip_id == chip_id)
+                       break;
+       return chip_info_table[i].name;
+}
+
+/**
+ *     velocity_remove1        -       device unplug
+ *     @pdev: PCI device being removed
+ *
+ *     Device unload callback. Called on an unplug or on module
+ *     unload for each active device that is present. Disconnects
+ *     the device from the network layer and frees all the resources
+ */
+
+static void __devexit velocity_remove1(struct pci_dev *pdev)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+       struct velocity_info *vptr = dev->priv;
+
+       unregister_netdev(dev);
+       iounmap(vptr->mac_regs);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+       pci_set_drvdata(pdev, NULL);
+       free_netdev(dev);
+}
+
+/**
+ *     velocity_set_int_opt    -       parser for integer options
+ *     @opt: pointer to option value
+ *     @val: value the user requested (or -1 for default)
+ *     @min: lowest value allowed
+ *     @max: highest value allowed
+ *     @def: default value
+ *     @name: property name
+ *     @dev: device name
+ *
+ *     Set an integer property in the module options. This function does
+ *     all the verification and checking as well as reporting so that
+ *     we don't duplicate code for each option.
+ */
+
+static void __devinit velocity_set_int_opt(int *opt, int val, int min, int max, int def, char *name, char *devname)
+{
+       if (val == -1)
+               *opt = def;
+       else if (val < min || val > max) {
+               VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (%d-%d)\n",
+                                       devname, name, min, max);
+               *opt = def;
+       } else {
+               VELOCITY_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: set value of parameter %s to %d\n",
+                                       devname, name, val);
+               *opt = val;
+       }
+}
+
+/**
+ *     velocity_set_bool_opt   -       parser for boolean options
+ *     @opt: pointer to option value
+ *     @val: value the user requested (or -1 for default)
+ *     @def: default value (yes/no)
+ *     @flag: numeric value to set for true.
+ *     @name: property name
+ *     @dev: device name
+ *
+ *     Set a boolean property in the module options. This function does
+ *     all the verification and checking as well as reporting so that
+ *     we don't duplicate code for each option.
+ */
+
+static void __devinit velocity_set_bool_opt(u32 * opt, int val, int def, u32 flag, char *name, char *devname)
+{
+       (*opt) &= (~flag);
+       if (val == -1)
+               *opt |= (def ? flag : 0);
+       else if (val < 0 || val > 1) {
+               printk(KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (0-1)\n", 
+                       devname, name);
+               *opt |= (def ? flag : 0);
+       } else {
+               printk(KERN_INFO "%s: set parameter %s to %s\n", 
+                       devname, name, val ? "TRUE" : "FALSE");
+               *opt |= (val ? flag : 0);
+       }
+}
+
+/**
+ *     velocity_get_options    -       set options on device
+ *     @opts: option structure for the device
+ *     @index: index of option to use in module options array
+ *     @devname: device name
+ *
+ *     Turn the module and command options into a single structure
+ *     for the current device
+ */
+
+static void __devinit velocity_get_options(struct velocity_opt *opts, int index, char *devname)
+{
+
+       velocity_set_int_opt(&opts->rx_thresh, rx_thresh[index], RX_THRESH_MIN, RX_THRESH_MAX, RX_THRESH_DEF, "rx_thresh", devname);
+       velocity_set_int_opt(&opts->DMA_length, DMA_length[index], DMA_LENGTH_MIN, DMA_LENGTH_MAX, DMA_LENGTH_DEF, "DMA_length", devname);
+       velocity_set_int_opt(&opts->numrx, RxDescriptors[index], RX_DESC_MIN, RX_DESC_MAX, RX_DESC_DEF, "RxDescriptors", devname);
+       velocity_set_int_opt(&opts->numtx, TxDescriptors[index], TX_DESC_MIN, TX_DESC_MAX, TX_DESC_DEF, "TxDescriptors", devname);
+       velocity_set_int_opt(&opts->vid, VID_setting[index], VLAN_ID_MIN, VLAN_ID_MAX, VLAN_ID_DEF, "VID_setting", devname);
+       velocity_set_bool_opt(&opts->flags, enable_tagging[index], TAGGING_DEF, VELOCITY_FLAGS_TAGGING, "enable_tagging", devname);
+       velocity_set_bool_opt(&opts->flags, txcsum_offload[index], TX_CSUM_DEF, VELOCITY_FLAGS_TX_CSUM, "txcsum_offload", devname);
+       velocity_set_int_opt(&opts->flow_cntl, flow_control[index], FLOW_CNTL_MIN, FLOW_CNTL_MAX, FLOW_CNTL_DEF, "flow_control", devname);
+       velocity_set_bool_opt(&opts->flags, IP_byte_align[index], IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN, "IP_byte_align", devname);
+       velocity_set_bool_opt(&opts->flags, ValPktLen[index], VAL_PKT_LEN_DEF, VELOCITY_FLAGS_VAL_PKT_LEN, "ValPktLen", devname);
+       velocity_set_int_opt((int *) &opts->spd_dpx, speed_duplex[index], MED_LNK_MIN, MED_LNK_MAX, MED_LNK_DEF, "Media link mode", devname);
+       velocity_set_int_opt((int *) &opts->wol_opts, wol_opts[index], WOL_OPT_MIN, WOL_OPT_MAX, WOL_OPT_DEF, "Wake On Lan options", devname);
+       velocity_set_int_opt((int *) &opts->int_works, int_works[index], INT_WORKS_MIN, INT_WORKS_MAX, INT_WORKS_DEF, "Interrupt service works", devname);
+       opts->numrx = (opts->numrx & ~3);
+}
+
+/**
+ *     velocity_init_cam_filter        -       initialise CAM
+ *     @vptr: velocity to program
+ *
+ *     Initialize the content addressable memory used for filters. Load
+ *     appropriately according to the presence of VLAN
+ */
+
+static void velocity_init_cam_filter(struct velocity_info *vptr)
+{
+       struct mac_regs * regs = vptr->mac_regs;
+
+       /* T urn on MCFG_PQEN, turn off MCFG_RTGOPT */
+       WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, &regs->MCFG);
+       WORD_REG_BITS_ON(MCFG_VIDFR, &regs->MCFG);
+
+       /* Disable all CAMs */
+       memset(vptr->vCAMmask, 0, sizeof(u8) * 8);
+       memset(vptr->mCAMmask, 0, sizeof(u8) * 8);
+       mac_set_cam_mask(regs, vptr->vCAMmask, VELOCITY_VLAN_ID_CAM);
+       mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM);
+
+       /* Enable first VCAM */
+       if (vptr->flags & VELOCITY_FLAGS_TAGGING) {
+               /* If Tagging option is enabled and VLAN ID is not zero, then
+                  turn on MCFG_RTGOPT also */
+               if (vptr->options.vid != 0)
+                       WORD_REG_BITS_ON(MCFG_RTGOPT, &regs->MCFG);
+
+               mac_set_cam(regs, 0, (u8 *) & (vptr->options.vid), VELOCITY_VLAN_ID_CAM);
+               vptr->vCAMmask[0] |= 1;
+               mac_set_cam_mask(regs, vptr->vCAMmask, VELOCITY_VLAN_ID_CAM);
+       } else {
+               u16 temp = 0;
+               mac_set_cam(regs, 0, (u8 *) &temp, VELOCITY_VLAN_ID_CAM);
+               temp = 1;
+               mac_set_cam_mask(regs, (u8 *) &temp, VELOCITY_VLAN_ID_CAM);
+       }
+}
+
+/**
+ *     velocity_rx_reset       -       handle a receive reset
+ *     @vptr: velocity we are resetting
+ *
+ *     Reset the ownership and status for the receive ring side.
+ *     Hand all the receive queue to the NIC.
+ */
+
+static void velocity_rx_reset(struct velocity_info *vptr)
+{
+
+       struct mac_regs * regs = vptr->mac_regs;
+       int i;
+
+       vptr->rd_used = vptr->rd_curr = 0;
+
+       /*
+        *      Init state, all RD entries belong to the NIC
+        */
+       for (i = 0; i < vptr->options.numrx; ++i)
+               vptr->rd_ring[i].rdesc0.owner = cpu_to_le32(OWNED_BY_NIC);
+
+       writew(vptr->options.numrx, &regs->RBRDU);
+       writel(vptr->rd_pool_dma, &regs->RDBaseLo);
+       writew(0, &regs->RDIdx);
+       writew(vptr->options.numrx - 1, &regs->RDCSize);
+}
+
+/**
+ *     velocity_init_registers -       initialise MAC registers
+ *     @vptr: velocity to init
+ *     @type: type of initialisation (hot or cold)
+ *
+ *     Initialise the MAC on a reset or on first set up on the
+ *     hardware.
+ */
+
+static void velocity_init_registers(struct velocity_info *vptr, 
+                                   enum velocity_init_type type)
+{
+       struct mac_regs * regs = vptr->mac_regs;
+       int i, mii_status;
+
+       mac_wol_reset(regs);
+
+       switch (type) {
+       case VELOCITY_INIT_RESET:
+       case VELOCITY_INIT_WOL:
+
+               netif_stop_queue(vptr->dev);
+
+               /*
+                *      Reset RX to prevent RX pointer not on the 4X location
+                */
+               velocity_rx_reset(vptr);
+               mac_rx_queue_run(regs);
+               mac_rx_queue_wake(regs);
+
+               mii_status = velocity_get_opt_media_mode(vptr);
+               if (velocity_set_media_mode(vptr, mii_status) != VELOCITY_LINK_CHANGE) {
+                       velocity_print_link_status(vptr);
+                       if (!(vptr->mii_status & VELOCITY_LINK_FAIL))
+                               netif_wake_queue(vptr->dev);
+               }
+
+               enable_flow_control_ability(vptr);
+
+               mac_clear_isr(regs);
+               writel(CR0_STOP, &regs->CR0Clr);
+               writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT), 
+                                                       &regs->CR0Set);
+
+               break;
+
+       case VELOCITY_INIT_COLD:
+       default:
+               /*
+                *      Do reset
+                */
+               velocity_soft_reset(vptr);
+               mdelay(5);
+
+               mac_eeprom_reload(regs);
+               for (i = 0; i < 6; i++) {
+                       writeb(vptr->dev->dev_addr[i], &(regs->PAR[i]));
+               }
+               /*
+                *      clear Pre_ACPI bit.
+                */
+               BYTE_REG_BITS_OFF(CFGA_PACPI, &(regs->CFGA));
+               mac_set_rx_thresh(regs, vptr->options.rx_thresh);
+               mac_set_dma_length(regs, vptr->options.DMA_length);
+
+               writeb(WOLCFG_SAM | WOLCFG_SAB, &regs->WOLCFGSet);
+               /*
+                *      Bback off algorithm use original IEEE standard
+                */
+               BYTE_REG_BITS_SET(CFGB_OFSET, (CFGB_CRANDOM | CFGB_CAP | CFGB_MBA | CFGB_BAKOPT), &regs->CFGB);
+
+               /*
+                *      Set packet filter: Receive directed and broadcast address
+                */
+               velocity_set_multi(vptr->dev);
+
+               /*
+                *      Enable MII auto-polling
+                */
+               enable_mii_autopoll(regs);
+
+               vptr->int_mask = INT_MASK_DEF;
+
+               writel(cpu_to_le32(vptr->rd_pool_dma), &regs->RDBaseLo);
+               writew(vptr->options.numrx - 1, &regs->RDCSize);
+               mac_rx_queue_run(regs);
+               mac_rx_queue_wake(regs);
+
+               writew(vptr->options.numtx - 1, &regs->TDCSize);
+
+               for (i = 0; i < vptr->num_txq; i++) {
+                       writel(cpu_to_le32(vptr->td_pool_dma[i]), &(regs->TDBaseLo[i]));
+                       mac_tx_queue_run(regs, i);
+               }
+
+               velocity_init_cam_filter(vptr);
+
+               init_flow_control_register(vptr);
+
+               writel(CR0_STOP, &regs->CR0Clr);
+               writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT), &regs->CR0Set);
+
+               mii_status = velocity_get_opt_media_mode(vptr);
+               netif_stop_queue(vptr->dev);
+               mac_clear_isr(regs);
+
+               mii_init(vptr, mii_status);
+
+               if (velocity_set_media_mode(vptr, mii_status) != VELOCITY_LINK_CHANGE) {
+                       velocity_print_link_status(vptr);
+                       if (!(vptr->mii_status & VELOCITY_LINK_FAIL))
+                               netif_wake_queue(vptr->dev);
+               }
+
+               enable_flow_control_ability(vptr);
+               mac_hw_mibs_init(regs);
+               mac_write_int_mask(vptr->int_mask, regs);
+               mac_clear_isr(regs);
+
+       }
+}
+
+/**
+ *     velocity_soft_reset     -       soft reset
+ *     @vptr: velocity to reset
+ *
+ *     Kick off a soft reset of the velocity adapter and then poll
+ *     until the reset sequence has completed before returning.
+ */
+
+static int velocity_soft_reset(struct velocity_info *vptr)
+{
+       struct mac_regs * regs = vptr->mac_regs;
+       int i = 0;
+
+       writel(CR0_SFRST, &regs->CR0Set);
+
+       for (i = 0; i < W_MAX_TIMEOUT; i++) {
+               udelay(5);
+               if (!DWORD_REG_BITS_IS_ON(CR0_SFRST, &regs->CR0Set))
+                       break;
+       }
+
+       if (i == W_MAX_TIMEOUT) {
+               writel(CR0_FORSRST, &regs->CR0Set);
+               /* FIXME: PCI POSTING */
+               /* delay 2ms */
+               mdelay(2);
+       }
+       return 0;
+}
+
+/**
+ *     velocity_found1         -       set up discovered velocity card
+ *     @pdev: PCI device
+ *     @ent: PCI device table entry that matched
+ *
+ *     Configure a discovered adapter from scratch. Return a negative
+ *     errno error code on failure paths.
+ */
+
+static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+       static int first = 1;
+       struct net_device *dev;
+       int i;
+       struct velocity_info_tbl *info = (struct velocity_info_tbl *) ent->driver_data;
+       struct velocity_info *vptr;
+       struct mac_regs * regs;
+       int ret = -ENOMEM;
+
+       if (velocity_nics++ >= MAX_UNITS) {
+               printk(KERN_NOTICE VELOCITY_NAME ": already found %d NICs.\n", 
+                               velocity_nics);
+               return -ENODEV;
+       }
+
+       dev = alloc_etherdev(sizeof(struct velocity_info));
+
+       if (dev == NULL) {
+               printk(KERN_ERR VELOCITY_NAME ": allocate net device failed.\n");
+               goto out;
+       }
+       
+       /* Chain it all together */
+       
+       SET_MODULE_OWNER(dev);
+       SET_NETDEV_DEV(dev, &pdev->dev);
+       vptr = dev->priv;
+
+
+       if (first) {
+               printk(KERN_INFO "%s Ver. %s\n", 
+                       VELOCITY_FULL_DRV_NAM, VELOCITY_VERSION);
+               printk(KERN_INFO "Copyright (c) 2002, 2003 VIA Networking Technologies, Inc.\n");
+               printk(KERN_INFO "Copyright (c) 2004 Red Hat Inc.\n");
+               first = 0;
+       }
+
+       velocity_init_info(pdev, vptr, info);
+
+       vptr->dev = dev;
+
+       dev->priv = vptr;
+       dev->irq = pdev->irq;
+
+       ret = pci_enable_device(pdev);
+       if (ret < 0) 
+               goto err_free_dev;
+
+       ret = velocity_get_pci_info(vptr, pdev);
+       if (ret < 0) {
+               printk(KERN_ERR VELOCITY_NAME ": Failed to find PCI device.\n");
+               goto err_disable;
+       }
+
+       ret = pci_request_regions(pdev, VELOCITY_NAME);
+       if (ret < 0) {
+               printk(KERN_ERR VELOCITY_NAME ": Failed to find PCI device.\n");
+               goto err_disable;
+       }
+
+       regs = ioremap(vptr->memaddr, vptr->io_size);
+       if (regs == NULL) {
+               ret = -EIO;
+               goto err_release_res;
+       }
+
+       vptr->mac_regs = regs;
+
+       mac_wol_reset(regs);
+
+       dev->base_addr = vptr->ioaddr;
+
+       for (i = 0; i < 6; i++)
+               dev->dev_addr[i] = readb(&regs->PAR[i]);
+
+
+       velocity_get_options(&vptr->options, velocity_nics - 1, dev->name);
+
+       /* 
+        *      Mask out the options cannot be set to the chip
+        */
+        
+       vptr->options.flags &= info->flags;
+
+       /*
+        *      Enable the chip specified capbilities
+        */
+        
+       vptr->flags = vptr->options.flags | (info->flags & 0xFF000000UL);
+
+       vptr->wol_opts = vptr->options.wol_opts;
+       vptr->flags |= VELOCITY_FLAGS_WOL_ENABLED;
+
+       vptr->phy_id = MII_GET_PHY_ID(vptr->mac_regs);
+
+       dev->irq = pdev->irq;
+       dev->open = velocity_open;
+       dev->hard_start_xmit = velocity_xmit;
+       dev->stop = velocity_close;
+       dev->get_stats = velocity_get_stats;
+       dev->set_multicast_list = velocity_set_multi;
+       dev->do_ioctl = velocity_ioctl;
+       dev->ethtool_ops = &velocity_ethtool_ops;
+       dev->change_mtu = velocity_change_mtu;
+#ifdef  VELOCITY_ZERO_COPY_SUPPORT
+       dev->features |= NETIF_F_SG;
+#endif
+
+       if (vptr->flags & VELOCITY_FLAGS_TX_CSUM) {
+               dev->features |= NETIF_F_HW_CSUM;
+       }
+
+       ret = register_netdev(dev);
+       if (ret < 0)
+               goto err_iounmap;
+
+       velocity_print_info(vptr);
+       pci_set_drvdata(pdev, dev);
+       
+       /* and leave the chip powered down */
+       
+       pci_set_power_state(pdev, 3);
+out:
+       return ret;
+
+err_iounmap:
+       iounmap(regs);
+err_release_res:
+       pci_release_regions(pdev);
+err_disable:
+       pci_disable_device(pdev);
+err_free_dev:
+       free_netdev(dev);
+       goto out;
+}
+
+/**
+ *     velocity_print_info     -       per driver data
+ *     @vptr: velocity
+ *
+ *     Print per driver data as the kernel driver finds Velocity
+ *     hardware
+ */
+
+static void __devinit velocity_print_info(struct velocity_info *vptr)
+{
+       struct net_device *dev = vptr->dev;
+
+       printk(KERN_INFO "%s: %s\n", dev->name, get_chip_name(vptr->chip_id));
+       printk(KERN_INFO "%s: Ethernet Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\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]);
+}
+
+/**
+ *     velocity_init_info      -       init private data
+ *     @pdev: PCI device
+ *     @vptr: Velocity info
+ *     @info: Board type
+ *
+ *     Set up the initial velocity_info struct for the device that has been
+ *     discovered.
+ */
+
+static void __devinit velocity_init_info(struct pci_dev *pdev, struct velocity_info *vptr, struct velocity_info_tbl *info)
+{
+       memset(vptr, 0, sizeof(struct velocity_info));
+
+       vptr->pdev = pdev;
+       vptr->chip_id = info->chip_id;
+       vptr->io_size = info->io_size;
+       vptr->num_txq = info->txqueue;
+       vptr->multicast_limit = MCAM_SIZE;
+
+       spin_lock_init(&vptr->lock);
+       spin_lock_init(&vptr->xmit_lock);
+}
+
+/**
+ *     velocity_get_pci_info   -       retrieve PCI info for device
+ *     @vptr: velocity device
+ *     @pdev: PCI device it matches
+ *
+ *     Retrieve the PCI configuration space data that interests us from
+ *     the kernel PCI layer
+ */
+
+static int __devinit velocity_get_pci_info(struct velocity_info *vptr, struct pci_dev *pdev)
+{
+
+       if(pci_read_config_byte(pdev, PCI_REVISION_ID, &vptr->rev_id) < 0)
+               return -EIO;
+               
+       pci_set_master(pdev);
+
+       vptr->ioaddr = pci_resource_start(pdev, 0);
+       vptr->memaddr = pci_resource_start(pdev, 1);
+       
+       if(!(pci_resource_flags(pdev, 0) & IORESOURCE_IO))
+       {
+               printk(KERN_ERR "%s: region #0 is not an I/O resource, aborting.\n",
+                               pci_name(pdev));
+               return -EINVAL;
+       }
+
+       if((pci_resource_flags(pdev, 1) & IORESOURCE_IO))
+       {
+               printk(KERN_ERR "%s: region #1 is an I/O resource, aborting.\n",
+                               pci_name(pdev));
+               return -EINVAL;
+       }
+
+       if(pci_resource_len(pdev, 1) < 256)
+       {
+               printk(KERN_ERR "%s: region #1 is too small.\n", 
+                               pci_name(pdev));
+               return -EINVAL;
+       }
+       vptr->pdev = pdev;
+
+       return 0;
+}
+
+/**
+ *     velocity_init_rings     -       set up DMA rings
+ *     @vptr: Velocity to set up
+ *
+ *     Allocate PCI mapped DMA rings for the receive and transmit layer
+ *     to use.
+ */
+
+static int velocity_init_rings(struct velocity_info *vptr)
+{
+       int i;
+       unsigned int psize;
+       unsigned int tsize;
+       dma_addr_t pool_dma;
+       u8 *pool;
+
+       /*
+        *      Allocate all RD/TD rings a single pool 
+        */
+        
+       psize = vptr->options.numrx * sizeof(struct rx_desc) + 
+               vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq;
+
+       /*
+        * pci_alloc_consistent() fulfills the requirement for 64 bytes
+        * alignment
+        */
+       pool = pci_alloc_consistent(vptr->pdev, psize, &pool_dma);
+
+       if (pool == NULL) {
+               printk(KERN_ERR "%s : DMA memory allocation failed.\n", 
+                                       vptr->dev->name);
+               return -ENOMEM;
+       }
+
+       memset(pool, 0, psize);
+
+       vptr->rd_ring = (struct rx_desc *) pool;
+
+       vptr->rd_pool_dma = pool_dma;
+
+       tsize = vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq;
+       vptr->tx_bufs = pci_alloc_consistent(vptr->pdev, tsize, 
+                                               &vptr->tx_bufs_dma);
+
+       if (vptr->tx_bufs == NULL) {
+               printk(KERN_ERR "%s: DMA memory allocation failed.\n", 
+                                       vptr->dev->name);
+               pci_free_consistent(vptr->pdev, psize, pool, pool_dma);
+               return -ENOMEM;
+       }
+
+       memset(vptr->tx_bufs, 0, vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq);
+
+       i = vptr->options.numrx * sizeof(struct rx_desc);
+       pool += i;
+       pool_dma += i;
+       for (i = 0; i < vptr->num_txq; i++) {
+               int offset = vptr->options.numtx * sizeof(struct tx_desc);
+
+               vptr->td_pool_dma[i] = pool_dma;
+               vptr->td_rings[i] = (struct tx_desc *) pool;
+               pool += offset;
+               pool_dma += offset;
+       }
+       return 0;
+}
+
+/**
+ *     velocity_free_rings     -       free PCI ring pointers
+ *     @vptr: Velocity to free from
+ *
+ *     Clean up the PCI ring buffers allocated to this velocity.
+ */
+
+static void velocity_free_rings(struct velocity_info *vptr)
+{
+       int size;
+
+       size = vptr->options.numrx * sizeof(struct rx_desc) + 
+              vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq;
+
+       pci_free_consistent(vptr->pdev, size, vptr->rd_ring, vptr->rd_pool_dma);
+
+       size = vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq;
+
+       pci_free_consistent(vptr->pdev, size, vptr->tx_bufs, vptr->tx_bufs_dma);
+}
+
+/**
+ *     velocity_init_rd_ring   -       set up receive ring
+ *     @vptr: velocity to configure
+ *
+ *     Allocate and set up the receive buffers for each ring slot and
+ *     assign them to the network adapter.
+ */
+
+static int velocity_init_rd_ring(struct velocity_info *vptr)
+{
+       int i, ret = -ENOMEM;
+       struct rx_desc *rd;
+       struct velocity_rd_info *rd_info;
+       unsigned int rsize = sizeof(struct velocity_rd_info) * 
+                                       vptr->options.numrx;
+
+       vptr->rd_info = kmalloc(rsize, GFP_KERNEL);
+       if(vptr->rd_info == NULL)
+               goto out;
+       memset(vptr->rd_info, 0, rsize);
+
+       /* Init the RD ring entries */
+       for (i = 0; i < vptr->options.numrx; i++) {
+               rd = &(vptr->rd_ring[i]);
+               rd_info = &(vptr->rd_info[i]);
+
+               ret = velocity_alloc_rx_buf(vptr, i);
+               if (ret < 0) {
+                       VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR
+                               "%s: failed to allocate RX buffer.\n", 
+                               vptr->dev->name);
+                       velocity_free_rd_ring(vptr);
+                       goto out;
+               }
+               rd->rdesc0.owner = OWNED_BY_NIC;
+       }
+       vptr->rd_used = vptr->rd_curr = 0;
+out:
+       return ret;
+}
+
+/**
+ *     velocity_free_rd_ring   -       set up receive ring
+ *     @vptr: velocity to clean up
+ *
+ *     Free the receive buffers for each ring slot and any
+ *     attached socket buffers that need to go away.
+ */
+
+static void velocity_free_rd_ring(struct velocity_info *vptr)
+{
+       int i;
+
+       if (vptr->rd_info == NULL)
+               return;
+
+       for (i = 0; i < vptr->options.numrx; i++) {
+               struct velocity_rd_info *rd_info = &(vptr->rd_info[i]);
+
+               if (!rd_info->skb_dma)
+                       continue;
+               pci_unmap_single(vptr->pdev, rd_info->skb_dma, vptr->rx_buf_sz,
+                                PCI_DMA_FROMDEVICE);
+               rd_info->skb_dma = (dma_addr_t) NULL;
+
+               dev_kfree_skb(rd_info->skb);
+               rd_info->skb = NULL;
+       }
+
+       kfree(vptr->rd_info);
+       vptr->rd_info = NULL;
+}
+
+/**
+ *     velocity_init_td_ring   -       set up transmit ring
+ *     @vptr:  velocity
+ *
+ *     Set up the transmit ring and chain the ring pointers together.
+ *     Returns zero on success or a negative posix errno code for
+ *     failure.
+ */
+static int velocity_init_td_ring(struct velocity_info *vptr)
+{
+       int i, j;
+       dma_addr_t curr;
+       struct tx_desc *td;
+       struct velocity_td_info *td_info;
+       unsigned int tsize = sizeof(struct velocity_td_info) * 
+                                       vptr->options.numtx;
+
+       /* Init the TD ring entries */
+       for (j = 0; j < vptr->num_txq; j++) {
+               curr = vptr->td_pool_dma[j];
+
+               vptr->td_infos[j] = kmalloc(tsize, GFP_KERNEL);
+               if(vptr->td_infos[j] == NULL)
+               {
+                       while(--j >= 0)
+                               kfree(vptr->td_infos[j]);
+                       return -ENOMEM;
+               }
+               memset(vptr->td_infos[j], 0, tsize);
+
+               for (i = 0; i < vptr->options.numtx; i++, curr += sizeof(struct tx_desc)) {
+                       td = &(vptr->td_rings[j][i]);
+                       td_info = &(vptr->td_infos[j][i]);
+                       td_info->buf = vptr->tx_bufs + (i + j) * PKT_BUF_SZ;
+                       td_info->buf_dma = vptr->tx_bufs_dma + (i + j) * PKT_BUF_SZ;
+               }
+               vptr->td_tail[j] = vptr->td_curr[j] = vptr->td_used[j] = 0;
+       }
+       return 0;
+}
+
+/*
+ *     FIXME: could we merge this with velocity_free_tx_buf ?
+ */
+
+static void velocity_free_td_ring_entry(struct velocity_info *vptr,
+                                                        int q, int n)
+{
+       struct velocity_td_info * td_info = &(vptr->td_infos[q][n]);
+       int i;
+       
+       if (td_info == NULL)
+               return;
+               
+       if (td_info->skb) {
+               for (i = 0; i < td_info->nskb_dma; i++)
+               {
+                       if (td_info->skb_dma[i]) {
+                               pci_unmap_single(vptr->pdev, td_info->skb_dma[i], 
+                                       td_info->skb->len, PCI_DMA_TODEVICE);
+                               td_info->skb_dma[i] = (dma_addr_t) NULL;
+                       }
+               }
+               dev_kfree_skb(td_info->skb);
+               td_info->skb = NULL;
+       }
+}
+
+/**
+ *     velocity_free_td_ring   -       free td ring
+ *     @vptr: velocity
+ *
+ *     Free up the transmit ring for this particular velocity adapter.
+ *     We free the ring contents but not the ring itself.
+ */
+static void velocity_free_td_ring(struct velocity_info *vptr)
+{
+       int i, j;
+
+       for (j = 0; j < vptr->num_txq; j++) {
+               if (vptr->td_infos[j] == NULL)
+                       continue;
+               for (i = 0; i < vptr->options.numtx; i++) {
+                       velocity_free_td_ring_entry(vptr, j, i);
+
+               }
+               if (vptr->td_infos[j]) {
+                       kfree(vptr->td_infos[j]);
+                       vptr->td_infos[j] = NULL;
+               }
+       }
+}
+
+/**
+ *     velocity_rx_srv         -       service RX interrupt
+ *     @vptr: velocity
+ *     @status: adapter status (unused)
+ *
+ *     Walk the receive ring of the velocity adapter and remove
+ *     any received packets from the receive queue. Hand the ring
+ *     slots back to the adapter for reuse.
+ */
+static int velocity_rx_srv(struct velocity_info *vptr, int status)
+{
+       struct rx_desc *rd;
+       struct net_device_stats *stats = &vptr->stats;
+       struct mac_regs * regs = vptr->mac_regs;
+       int rd_curr = vptr->rd_curr;
+       int works = 0;
+
+       while (1) {
+
+               rd = &(vptr->rd_ring[rd_curr]);
+
+               if ((vptr->rd_info[rd_curr]).skb == NULL) {
+                       if (velocity_alloc_rx_buf(vptr, rd_curr) < 0)
+                               break;
+               }
+
+               if (works++ > 15)
+                       break;
+
+               if (rd->rdesc0.owner == OWNED_BY_NIC)
+                       break;
+
+               /*
+                *      Don't drop CE or RL error frame although RXOK is off
+                *      FIXME: need to handle copybreak
+                */
+               if ((rd->rdesc0.RSR & RSR_RXOK) || (!(rd->rdesc0.RSR & RSR_RXOK) && (rd->rdesc0.RSR & (RSR_CE | RSR_RL)))) {
+                       if (velocity_receive_frame(vptr, rd_curr) == 0) {
+                               if (velocity_alloc_rx_buf(vptr, rd_curr) < 0) {
+                                       VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not allocate rx buf\n", vptr->dev->name);
+                                       break;
+                               }
+                       } else {
+                               stats->rx_dropped++;
+                       }
+               } else {
+                       if (rd->rdesc0.RSR & RSR_CRC)
+                               stats->rx_crc_errors++;
+                       if (rd->rdesc0.RSR & RSR_FAE)
+                               stats->rx_frame_errors++;
+
+                       stats->rx_dropped++;
+               }
+
+               rd->inten = 1;
+
+               if (++vptr->rd_used >= 4) {
+                       int i, rd_prev = rd_curr;
+                       for (i = 0; i < 4; i++) {
+                               if (--rd_prev < 0)
+                                       rd_prev = vptr->options.numrx - 1;
+
+                               rd = &(vptr->rd_ring[rd_prev]);
+                               rd->rdesc0.owner = OWNED_BY_NIC;
+                       }
+                       writew(4, &(regs->RBRDU));
+                       vptr->rd_used -= 4;
+               }
+
+               vptr->dev->last_rx = jiffies;
+
+               rd_curr++;
+               if (rd_curr >= vptr->options.numrx)
+                       rd_curr = 0;
+       }
+       vptr->rd_curr = rd_curr;
+       VAR_USED(stats);
+       return works;
+}
+
+/**
+ *     velocity_rx_csum        -       checksum process
+ *     @rd: receive packet descriptor
+ *     @skb: network layer packet buffer
+ *
+ *     Process the status bits for the received packet and determine
+ *     if the checksum was computed and verified by the hardware
+ */
+static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb)
+{
+       skb->ip_summed = CHECKSUM_NONE;
+
+       if (rd->rdesc1.CSM & CSM_IPKT) {
+               if (rd->rdesc1.CSM & CSM_IPOK) {
+                       if ((rd->rdesc1.CSM & CSM_TCPKT) || 
+                                       (rd->rdesc1.CSM & CSM_UDPKT)) {
+                               if (!(rd->rdesc1.CSM & CSM_TUPOK)) {
+                                       return;
+                               }
+                       }
+                       skb->ip_summed = CHECKSUM_UNNECESSARY;
+               }
+       }
+}
+
+/**
+ *     velocity_receive_frame  -       received packet processor
+ *     @vptr: velocity we are handling
+ *     @idx: ring index
+ *     
+ *     A packet has arrived. We process the packet and if appropriate
+ *     pass the frame up the network stack
+ */
+static int velocity_receive_frame(struct velocity_info *vptr, int idx)
+{
+       struct net_device_stats *stats = &vptr->stats;
+       struct velocity_rd_info *rd_info = &(vptr->rd_info[idx]);
+       struct rx_desc *rd = &(vptr->rd_ring[idx]);
+       struct sk_buff *skb;
+
+       if (rd->rdesc0.RSR & (RSR_STP | RSR_EDP)) {
+               VELOCITY_PRT(MSG_LEVEL_VERBOSE, KERN_ERR " %s : the received frame span multple RDs.\n", vptr->dev->name);
+               stats->rx_length_errors++;
+               return -EINVAL;
+       }
+
+       if (rd->rdesc0.RSR & RSR_MAR)
+               vptr->stats.multicast++;
+
+       skb = rd_info->skb;
+       skb->dev = vptr->dev;
+
+       pci_unmap_single(vptr->pdev, rd_info->skb_dma, vptr->rx_buf_sz, 
+                                                       PCI_DMA_FROMDEVICE);
+       rd_info->skb_dma = (dma_addr_t) NULL;
+       rd_info->skb = NULL;
+
+       /* FIXME - memmove ? */
+       if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN) {
+               int i;
+               for (i = rd->rdesc0.len + 4; i >= 0; i--)
+                       *(skb->data + i + 2) = *(skb->data + i);
+               skb->data += 2;
+               skb->tail += 2;
+       }
+
+       skb_put(skb, (rd->rdesc0.len - 4));
+       skb->protocol = eth_type_trans(skb, skb->dev);
+
+       /*
+        *      Drop frame not meeting IEEE 802.3
+        */
+        
+       if (vptr->flags & VELOCITY_FLAGS_VAL_PKT_LEN) {
+               if (rd->rdesc0.RSR & RSR_RL) {
+                       stats->rx_length_errors++;
+                       return -EINVAL;
+               }
+       }
+
+       velocity_rx_csum(rd, skb);
+       
+       /*
+        *      FIXME: need rx_copybreak handling
+        */
+
+       stats->rx_bytes += skb->len;
+       netif_rx(skb);
+
+       return 0;
+}
+
+/**
+ *     velocity_alloc_rx_buf   -       allocate aligned receive buffer
+ *     @vptr: velocity
+ *     @idx: ring index
+ *
+ *     Allocate a new full sized buffer for the reception of a frame and
+ *     map it into PCI space for the hardware to use. The hardware
+ *     requires *64* byte alignment of the buffer which makes life
+ *     less fun than would be ideal.
+ */
+static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
+{
+       struct rx_desc *rd = &(vptr->rd_ring[idx]);
+       struct velocity_rd_info *rd_info = &(vptr->rd_info[idx]);
+
+       rd_info->skb = dev_alloc_skb(vptr->rx_buf_sz + 64);
+       if (rd_info->skb == NULL)
+               return -ENOMEM;
+
+       /*
+        *      Do the gymnastics to get the buffer head for data at
+        *      64byte alignment.
+        */
+       skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->tail & 63);
+       rd_info->skb->dev = vptr->dev;
+       rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->tail, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE);
+       
+       /*
+        *      Fill in the descriptor to match
+        */     
+        
+       *((u32 *) & (rd->rdesc0)) = 0;
+       rd->len = cpu_to_le32(vptr->rx_buf_sz);
+       rd->inten = 1;
+       rd->pa_low = cpu_to_le32(rd_info->skb_dma);
+       rd->pa_high = 0;
+       return 0;
+}
+
+/**
+ *     tx_srv          -       transmit interrupt service
+ *     @vptr; Velocity
+ *     @status:
+ *
+ *     Scan the queues looking for transmitted packets that
+ *     we can complete and clean up. Update any statistics as
+ *     neccessary/
+ */
+static int velocity_tx_srv(struct velocity_info *vptr, u32 status)
+{
+       struct tx_desc *td;
+       int qnum;
+       int full = 0;
+       int idx;
+       int works = 0;
+       struct velocity_td_info *tdinfo;
+       struct net_device_stats *stats = &vptr->stats;
+
+       for (qnum = 0; qnum < vptr->num_txq; qnum++) {
+               for (idx = vptr->td_tail[qnum]; vptr->td_used[qnum] > 0; 
+                       idx = (idx + 1) % vptr->options.numtx) {
+
+                       /*
+                        *      Get Tx Descriptor
+                        */
+                       td = &(vptr->td_rings[qnum][idx]);
+                       tdinfo = &(vptr->td_infos[qnum][idx]);
+
+                       if (td->tdesc0.owner == OWNED_BY_NIC)
+                               break;
+
+                       if ((works++ > 15))
+                               break;
+
+                       if (td->tdesc0.TSR & TSR0_TERR) {
+                               stats->tx_errors++;
+                               stats->tx_dropped++;
+                               if (td->tdesc0.TSR & TSR0_CDH)
+                                       stats->tx_heartbeat_errors++;
+                               if (td->tdesc0.TSR & TSR0_CRS)
+                                       stats->tx_carrier_errors++;
+                               if (td->tdesc0.TSR & TSR0_ABT)
+                                       stats->tx_aborted_errors++;
+                               if (td->tdesc0.TSR & TSR0_OWC)
+                                       stats->tx_window_errors++;
+                       } else {
+                               stats->tx_packets++;
+                               stats->tx_bytes += tdinfo->skb->len;
+                       }
+                       velocity_free_tx_buf(vptr, tdinfo);
+                       vptr->td_used[qnum]--;
+               }
+               vptr->td_tail[qnum] = idx;
+
+               if (AVAIL_TD(vptr, qnum) < 1) {
+                       full = 1;
+               }
+       }
+       /*
+        *      Look to see if we should kick the transmit network
+        *      layer for more work.
+        */
+       if (netif_queue_stopped(vptr->dev) && (full == 0)
+           && (!(vptr->mii_status & VELOCITY_LINK_FAIL))) {
+               netif_wake_queue(vptr->dev);
+       }
+       return works;
+}
+
+/**
+ *     velocity_print_link_status      -       link status reporting
+ *     @vptr: velocity to report on
+ *
+ *     Turn the link status of the velocity card into a kernel log
+ *     description of the new link state, detailing speed and duplex
+ *     status
+ */
+
+static void velocity_print_link_status(struct velocity_info *vptr)
+{
+
+       if (vptr->mii_status & VELOCITY_LINK_FAIL) {
+               VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: failed to detect cable link\n", vptr->dev->name);
+       } else if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
+               VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link autonegation", vptr->dev->name);
+
+               if (vptr->mii_status & VELOCITY_SPEED_1000)
+                       VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps");
+               else if (vptr->mii_status & VELOCITY_SPEED_100)
+                       VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps");
+               else
+                       VELOCITY_PRT(MSG_LEVEL_INFO, " speed 10M bps");
+
+               if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
+                       VELOCITY_PRT(MSG_LEVEL_INFO, " full duplex\n");
+               else
+                       VELOCITY_PRT(MSG_LEVEL_INFO, " half duplex\n");
+       } else {
+               VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link forced", vptr->dev->name);
+               switch (vptr->options.spd_dpx) {
+               case SPD_DPX_100_HALF:
+                       VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps half duplex\n");
+                       break;
+               case SPD_DPX_100_FULL:
+                       VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps full duplex\n");
+                       break;
+               case SPD_DPX_10_HALF:
+                       VELOCITY_PRT(MSG_LEVEL_INFO, " speed 10M bps half duplex\n");
+                       break;
+               case SPD_DPX_10_FULL:
+                       VELOCITY_PRT(MSG_LEVEL_INFO, " speed 10M bps full duplex\n");
+                       break;
+               default:
+                       break;
+               }
+       }
+}
+
+/**
+ *     velocity_error  -       handle error from controller
+ *     @vptr: velocity
+ *     @status: card status
+ *
+ *     Process an error report from the hardware and attempt to recover
+ *     the card itself. At the moment we cannot recover from some 
+ *     theoretically impossible errors but this could be fixed using
+ *     the pci_device_failed logic to bounce the hardware
+ *
+ */
+static void velocity_error(struct velocity_info *vptr, int status)
+{
+
+       if (status & ISR_TXSTLI) {
+               struct mac_regs * regs = vptr->mac_regs;
+
+               printk(KERN_ERR "TD structure errror TDindex=%hx\n", readw(&regs->TDIdx[0]));
+               BYTE_REG_BITS_ON(TXESR_TDSTR, &regs->TXESR);
+               writew(TRDCSR_RUN, &regs->TDCSRClr);
+               netif_stop_queue(vptr->dev);
+               
+               /* FIXME: port over the pci_device_failed code and use it
+                  here */
+       }
+
+       if (status & ISR_SRCI) {
+               struct mac_regs * regs = vptr->mac_regs;
+               int linked;
+
+               if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
+                       vptr->mii_status = check_connection_type(regs);
+
+                       /*
+                        *      If it is a 3119, disable frame bursting in 
+                        *      halfduplex mode and enable it in fullduplex
+                        *       mode
+                        */
+                       if (vptr->rev_id < REV_ID_VT3216_A0) {
+                               if (vptr->mii_status | VELOCITY_DUPLEX_FULL)
+                                       BYTE_REG_BITS_ON(TCR_TB2BDIS, &regs->TCR);
+                               else
+                                       BYTE_REG_BITS_OFF(TCR_TB2BDIS, &regs->TCR);
+                       }
+                       /*
+                        *      Only enable CD heart beat counter in 10HD mode
+                        */
+                       if (!(vptr->mii_status & VELOCITY_DUPLEX_FULL) && (vptr->mii_status & VELOCITY_SPEED_10)) {
+                               BYTE_REG_BITS_OFF(TESTCFG_HBDIS, &regs->TESTCFG);
+                       } else {
+                               BYTE_REG_BITS_ON(TESTCFG_HBDIS, &regs->TESTCFG);
+                       }
+               }
+               /*
+                *      Get link status from PHYSR0
+                */
+               linked = readb(&regs->PHYSR0) & PHYSR0_LINKGD;
+
+               if (linked) {
+                       vptr->mii_status &= ~VELOCITY_LINK_FAIL;
+               } else {
+                       vptr->mii_status |= VELOCITY_LINK_FAIL;
+               }
+
+               velocity_print_link_status(vptr);
+               enable_flow_control_ability(vptr);
+
+               /*
+                *      Re-enable auto-polling because SRCI will disable 
+                *      auto-polling
+                */
+                
+               enable_mii_autopoll(regs);
+
+               if (vptr->mii_status & VELOCITY_LINK_FAIL)
+                       netif_stop_queue(vptr->dev);
+               else
+                       netif_wake_queue(vptr->dev);
+
+       };
+       if (status & ISR_MIBFI)
+               velocity_update_hw_mibs(vptr);
+       if (status & ISR_LSTEI)
+               mac_rx_queue_wake(vptr->mac_regs);
+}
+
+/**
+ *     velocity_free_tx_buf    -       free transmit buffer
+ *     @vptr: velocity
+ *     @tdinfo: buffer
+ *
+ *     Release an transmit buffer. If the buffer was preallocated then
+ *     recycle it, if not then unmap the buffer.
+ */
+static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *tdinfo)
+{
+       struct sk_buff *skb = tdinfo->skb;
+       int i;
+
+       /*
+        *      Don't unmap the pre-allocated tx_bufs
+        */
+       if (tdinfo->skb_dma && (tdinfo->skb_dma[0] != tdinfo->buf_dma)) {
+
+               for (i = 0; i < tdinfo->nskb_dma; i++) {
+#ifdef VELOCITY_ZERO_COPY_SUPPORT
+                       pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], td->tdesc1.len, PCI_DMA_TODEVICE);
+#else
+                       pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], skb->len, PCI_DMA_TODEVICE);
+#endif
+                       tdinfo->skb_dma[i] = 0;
+               }
+       }
+       dev_kfree_skb_irq(skb);
+       tdinfo->skb = NULL;
+}
+
+/**
+ *     velocity_open           -       interface activation callback
+ *     @dev: network layer device to open
+ *
+ *     Called when the network layer brings the interface up. Returns
+ *     a negative posix error code on failure, or zero on success.
+ *
+ *     All the ring allocation and set up is done on open for this
+ *     adapter to minimise memory usage when inactive
+ */
+static int velocity_open(struct net_device *dev)
+{
+       struct velocity_info *vptr = dev->priv;
+       int ret;
+
+       vptr->rx_buf_sz = (dev->mtu <= 1504 ? PKT_BUF_SZ : dev->mtu + 32);
+
+       ret = velocity_init_rings(vptr);
+       if (ret < 0)
+               goto out;
+
+       ret = velocity_init_rd_ring(vptr);
+       if (ret < 0)
+               goto err_free_desc_rings;
+
+       ret = velocity_init_td_ring(vptr);
+       if (ret < 0)
+               goto err_free_rd_ring;
+       
+       /* Ensure chip is running */    
+       pci_set_power_state(vptr->pdev, 0);
+       
+       velocity_init_registers(vptr, VELOCITY_INIT_COLD);
+
+       ret = request_irq(vptr->pdev->irq, &velocity_intr, SA_SHIRQ,
+                         dev->name, dev);
+       if (ret < 0) {
+               /* Power down the chip */
+               pci_set_power_state(vptr->pdev, 3);
+               goto err_free_td_ring;
+       }
+
+       mac_enable_int(vptr->mac_regs);
+       netif_start_queue(dev);
+       vptr->flags |= VELOCITY_FLAGS_OPENED;
+out:
+       return ret;
+
+err_free_td_ring:
+       velocity_free_td_ring(vptr);
+err_free_rd_ring:
+       velocity_free_rd_ring(vptr);
+err_free_desc_rings:
+       velocity_free_rings(vptr);
+       goto out;
+}
+
+/** 
+ *     velocity_change_mtu     -       MTU change callback
+ *     @dev: network device
+ *     @new_mtu: desired MTU
+ *
+ *     Handle requests from the networking layer for MTU change on
+ *     this interface. It gets called on a change by the network layer.
+ *     Return zero for success or negative posix error code.
+ */
+static int velocity_change_mtu(struct net_device *dev, int new_mtu)
+{
+       struct velocity_info *vptr = dev->priv;
+       unsigned long flags;
+       int oldmtu = dev->mtu;
+       int ret = 0;
+
+       if ((new_mtu < VELOCITY_MIN_MTU) || new_mtu > (VELOCITY_MAX_MTU)) {
+               VELOCITY_PRT(MSG_LEVEL_ERR, KERN_NOTICE "%s: Invalid MTU.\n", 
+                               vptr->dev->name);
+               return -EINVAL;
+       }
+
+       if (new_mtu != oldmtu) {
+               spin_lock_irqsave(&vptr->lock, flags);
+
+               netif_stop_queue(dev);
+               velocity_shutdown(vptr);
+
+               velocity_free_td_ring(vptr);
+               velocity_free_rd_ring(vptr);
+
+               dev->mtu = new_mtu;
+               if (new_mtu > 8192)
+                       vptr->rx_buf_sz = 9 * 1024;
+               else if (new_mtu > 4096)
+                       vptr->rx_buf_sz = 8192;
+               else
+                       vptr->rx_buf_sz = 4 * 1024;
+
+               ret = velocity_init_rd_ring(vptr);
+               if (ret < 0)
+                       goto out_unlock;
+
+               ret = velocity_init_td_ring(vptr);
+               if (ret < 0)
+                       goto out_unlock;
+
+               velocity_init_registers(vptr, VELOCITY_INIT_COLD);
+
+               mac_enable_int(vptr->mac_regs);
+               netif_start_queue(dev);
+out_unlock:
+               spin_unlock_irqrestore(&vptr->lock, flags);
+       }
+
+       return ret;
+}
+
+/**
+ *     velocity_shutdown       -       shut down the chip
+ *     @vptr: velocity to deactivate
+ *
+ *     Shuts down the internal operations of the velocity and
+ *     disables interrupts, autopolling, transmit and receive
+ */
+static void velocity_shutdown(struct velocity_info *vptr)
+{
+       struct mac_regs * regs = vptr->mac_regs;
+       mac_disable_int(regs);
+       writel(CR0_STOP, &regs->CR0Set);
+       writew(0xFFFF, &regs->TDCSRClr);
+       writeb(0xFF, &regs->RDCSRClr);
+       safe_disable_mii_autopoll(regs);
+       mac_clear_isr(regs);
+}
+
+/**
+ *     velocity_close          -       close adapter callback
+ *     @dev: network device
+ *
+ *     Callback from the network layer when the velocity is being
+ *     deactivated by the network layer
+ */
+
+static int velocity_close(struct net_device *dev)
+{
+       struct velocity_info *vptr = dev->priv;
+
+       netif_stop_queue(dev);
+       velocity_shutdown(vptr);
+
+       if (vptr->flags & VELOCITY_FLAGS_WOL_ENABLED)
+               velocity_get_ip(vptr);
+       if (dev->irq != 0)
+               free_irq(dev->irq, dev);
+               
+       /* Power down the chip */
+       pci_set_power_state(vptr->pdev, 3);
+       
+       /* Free the resources */
+       velocity_free_td_ring(vptr);
+       velocity_free_rd_ring(vptr);
+       velocity_free_rings(vptr);
+
+       vptr->flags &= (~VELOCITY_FLAGS_OPENED);
+       return 0;
+}
+
+/**
+ *     velocity_xmit           -       transmit packet callback
+ *     @skb: buffer to transmit
+ *     @dev: network device
+ *
+ *     Called by the networ layer to request a packet is queued to
+ *     the velocity. Returns zero on success.
+ */
+static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct velocity_info *vptr = dev->priv;
+       int qnum = 0;
+       struct tx_desc *td_ptr;
+       struct velocity_td_info *tdinfo;
+       unsigned long flags;
+       int index;
+
+       int pktlen = skb->len;
+
+       spin_lock_irqsave(&vptr->lock, flags);
+
+       index = vptr->td_curr[qnum];
+       td_ptr = &(vptr->td_rings[qnum][index]);
+       tdinfo = &(vptr->td_infos[qnum][index]);
+
+       td_ptr->tdesc1.TCPLS = TCPLS_NORMAL;
+       td_ptr->tdesc1.TCR = TCR0_TIC;
+       td_ptr->td_buf[0].queue = 0;
+
+       /*
+        *      Pad short frames. 
+        */
+       if (pktlen < ETH_ZLEN) {
+               /* Cannot occur until ZC support */
+               if(skb_linearize(skb, GFP_ATOMIC))
+                       return 0; 
+               pktlen = ETH_ZLEN;
+               memcpy(tdinfo->buf, skb->data, skb->len);
+               memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
+               tdinfo->skb = skb;
+               tdinfo->skb_dma[0] = tdinfo->buf_dma;
+               td_ptr->tdesc0.pktsize = pktlen;
+               td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
+               td_ptr->td_buf[0].pa_high = 0;
+               td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize;
+               tdinfo->nskb_dma = 1;
+               td_ptr->tdesc1.CMDZ = 2;
+       } else
+#ifdef VELOCITY_ZERO_COPY_SUPPORT
+       if (skb_shinfo(skb)->nr_frags > 0) {
+               int nfrags = skb_shinfo(skb)->nr_frags;
+               tdinfo->skb = skb;
+               if (nfrags > 6) {
+                       skb_linearize(skb, GFP_ATOMIC);
+                       memcpy(tdinfo->buf, skb->data, skb->len);
+                       tdinfo->skb_dma[0] = tdinfo->buf_dma;
+                       td_ptr->tdesc0.pktsize = 
+                       td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
+                       td_ptr->td_buf[0].pa_high = 0;
+                       td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize;
+                       tdinfo->nskb_dma = 1;
+                       td_ptr->tdesc1.CMDZ = 2;
+               } else {
+                       int i = 0;
+                       tdinfo->nskb_dma = 0;
+                       tdinfo->skb_dma[i] = pci_map_single(vptr->pdev, skb->data, skb->len - skb->data_len, PCI_DMA_TODEVICE);
+
+                       td_ptr->tdesc0.pktsize = pktlen;
+
+                       /* FIXME: support 48bit DMA later */
+                       td_ptr->td_buf[i].pa_low = cpu_to_le32(tdinfo->skb_dma);
+                       td_ptr->td_buf[i].pa_high = 0;
+                       td_ptr->td_buf[i].bufsize = skb->len->skb->data_len;
+
+                       for (i = 0; i < nfrags; i++) {
+                               skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+                               void *addr = ((void *) page_address(frag->page + frag->page_offset));
+
+                               tdinfo->skb_dma[i + 1] = pci_map_single(vptr->pdev, addr, frag->size, PCI_DMA_TODEVICE);
+
+                               td_ptr->td_buf[i + 1].pa_low = cpu_to_le32(tdinfo->skb_dma[i + 1]);
+                               td_ptr->td_buf[i + 1].pa_high = 0;
+                               td_ptr->td_buf[i + 1].bufsize = frag->size;
+                       }
+                       tdinfo->nskb_dma = i - 1;
+                       td_ptr->tdesc1.CMDZ = i;
+               }
+
+       } else
+#endif
+       {
+               /*
+                *      Map the linear network buffer into PCI space and
+                *      add it to the transmit ring.
+                */
+               tdinfo->skb = skb;
+               tdinfo->skb_dma[0] = pci_map_single(vptr->pdev, skb->data, pktlen, PCI_DMA_TODEVICE);
+               td_ptr->tdesc0.pktsize = pktlen;
+               td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
+               td_ptr->td_buf[0].pa_high = 0;
+               td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize;
+               tdinfo->nskb_dma = 1;
+               td_ptr->tdesc1.CMDZ = 2;
+       }
+
+       if (vptr->flags & VELOCITY_FLAGS_TAGGING) {
+               td_ptr->tdesc1.pqinf.VID = (vptr->options.vid & 0xfff);
+               td_ptr->tdesc1.pqinf.priority = 0;
+               td_ptr->tdesc1.pqinf.CFI = 0;
+               td_ptr->tdesc1.TCR |= TCR0_VETAG;
+       }
+
+       /*
+        *      Handle hardware checksum
+        */
+       if ((vptr->flags & VELOCITY_FLAGS_TX_CSUM)
+                                && (skb->ip_summed == CHECKSUM_HW)) {
+               struct iphdr *ip = skb->nh.iph;
+               if (ip->protocol == IPPROTO_TCP)
+                       td_ptr->tdesc1.TCR |= TCR0_TCPCK;
+               else if (ip->protocol == IPPROTO_UDP)
+                       td_ptr->tdesc1.TCR |= (TCR0_UDPCK);
+               td_ptr->tdesc1.TCR |= TCR0_IPCK;
+       }
+       {
+
+               int prev = index - 1;
+
+               if (prev < 0)
+                       prev = vptr->options.numtx - 1;
+               td_ptr->tdesc0.owner = OWNED_BY_NIC;
+               vptr->td_used[qnum]++;
+               vptr->td_curr[qnum] = (index + 1) % vptr->options.numtx;
+
+               if (AVAIL_TD(vptr, qnum) < 1)
+                       netif_stop_queue(dev);
+
+               td_ptr = &(vptr->td_rings[qnum][prev]);
+               td_ptr->td_buf[0].queue = 1;
+               mac_tx_queue_wake(vptr->mac_regs, qnum);
+       }
+       dev->trans_start = jiffies;
+       spin_unlock_irqrestore(&vptr->lock, flags);
+       return 0;
+}
+
+/**
+ *     velocity_intr           -       interrupt callback
+ *     @irq: interrupt number
+ *     @dev_instance: interrupting device
+ *     @pt_regs: CPU register state at interrupt
+ *
+ *     Called whenever an interrupt is generated by the velocity
+ *     adapter IRQ line. We may not be the source of the interrupt
+ *     and need to identify initially if we are, and if not exit as
+ *     efficiently as possible.
+ */
+static int velocity_intr(int irq, void *dev_instance, struct pt_regs *regs)
+{
+       struct net_device *dev = dev_instance;
+       struct velocity_info *vptr = dev->priv;
+       u32 isr_status;
+       int max_count = 0;
+
+
+       spin_lock(&vptr->lock);
+       isr_status = mac_read_isr(vptr->mac_regs);
+
+       /* Not us ? */
+       if (isr_status == 0) {
+               spin_unlock(&vptr->lock);
+               return IRQ_NONE;
+       }
+
+       mac_disable_int(vptr->mac_regs);
+
+       /*
+        *      Keep processing the ISR until we have completed
+        *      processing and the isr_status becomes zero
+        */
+        
+       while (isr_status != 0) {
+               mac_write_isr(vptr->mac_regs, isr_status);
+               if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI)))
+                       velocity_error(vptr, isr_status);
+               if (isr_status & (ISR_PRXI | ISR_PPRXI))
+                       max_count += velocity_rx_srv(vptr, isr_status);
+               if (isr_status & (ISR_PTXI | ISR_PPTXI))
+                       max_count += velocity_tx_srv(vptr, isr_status);
+               isr_status = mac_read_isr(vptr->mac_regs);
+               if (max_count > vptr->options.int_works)
+               {
+                       printk(KERN_WARNING "%s: excessive work at interrupt.\n", 
+                               dev->name);
+                       max_count = 0;
+               }
+       }
+       spin_unlock(&vptr->lock);
+       mac_enable_int(vptr->mac_regs);
+       return IRQ_HANDLED;
+
+}
+
+
+/**
+ *     ether_crc       -       ethernet CRC function
+ *
+ *     Compute an ethernet CRC hash of the data block provided. This
+ *     is not performance optimised but is not needed in performance
+ *     critical code paths.
+ *
+ *     FIXME: could we use shared code here ?
+ */
+static inline u32 ether_crc(int length, unsigned char *data)
+{
+       static unsigned const ethernet_polynomial = 0x04c11db7U;
+       
+       int crc = -1;
+
+       while (--length >= 0) {
+               unsigned char current_octet = *data++;
+               int bit;
+               for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
+                       crc = (crc << 1) ^ ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
+               }
+       }
+       return crc;
+}
+
+/**
+ *     velocity_set_multi      -       filter list change callback
+ *     @dev: network device
+ *
+ *     Called by the network layer when the filter lists need to change
+ *     for a velocity adapter. Reload the CAMs with the new address
+ *     filter ruleset.
+ */
+static void velocity_set_multi(struct net_device *dev)
+{
+       struct velocity_info *vptr = dev->priv;
+       struct mac_regs * regs = vptr->mac_regs;
+       u8 rx_mode;
+       int i;
+       struct dev_mc_list *mclist;
+
+       if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
+               /* Unconditionally log net taps. */
+               printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
+               writel(0xffffffff, &regs->MARCAM[0]);
+               writel(0xffffffff, &regs->MARCAM[4]);
+               rx_mode = (RCR_AM | RCR_AB | RCR_PROM);
+       } else if ((dev->mc_count > vptr->multicast_limit)
+                  || (dev->flags & IFF_ALLMULTI)) {
+               writel(0xffffffff, &regs->MARCAM[0]);
+               writel(0xffffffff, &regs->MARCAM[4]);
+               rx_mode = (RCR_AM | RCR_AB);
+       } else {
+               int offset = MCAM_SIZE - vptr->multicast_limit;
+               mac_get_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM);
+
+               for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) {
+                       mac_set_cam(regs, i + offset, mclist->dmi_addr, VELOCITY_MULTICAST_CAM);
+                       vptr->mCAMmask[(offset + i) / 8] |= 1 << ((offset + i) & 7);
+               }
+
+               mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM);
+               rx_mode = (RCR_AM | RCR_AB);
+       }
+       if (dev->mtu > 1500)
+               rx_mode |= RCR_AL;
+
+       BYTE_REG_BITS_ON(rx_mode, &regs->RCR);
+
+}
+
+/**
+ *     velocity_get_status     -       statistics callback
+ *     @dev: network device
+ *
+ *     Callback from the network layer to allow driver statistics
+ *     to be resynchronized with hardware collected state. In the
+ *     case of the velocity we need to pull the MIB counters from
+ *     the hardware into the counters before letting the network
+ *     layer display them.
+ */
+static struct net_device_stats *velocity_get_stats(struct net_device *dev)
+{
+       struct velocity_info *vptr = dev->priv;
+       
+       /* If the hardware is down, don't touch MII */
+       if(!netif_running(dev))
+               return &vptr->stats;
+
+       spin_lock_irq(&vptr->lock);
+       velocity_update_hw_mibs(vptr);
+       spin_unlock_irq(&vptr->lock);
+
+       vptr->stats.rx_packets = vptr->mib_counter[HW_MIB_ifRxAllPkts];
+       vptr->stats.rx_errors = vptr->mib_counter[HW_MIB_ifRxErrorPkts];
+       vptr->stats.rx_length_errors = vptr->mib_counter[HW_MIB_ifInRangeLengthErrors];
+
+//  unsigned long   rx_dropped;     /* no space in linux buffers    */
+       vptr->stats.collisions = vptr->mib_counter[HW_MIB_ifTxEtherCollisions];
+       /* detailed rx_errors: */
+//  unsigned long   rx_length_errors;
+//  unsigned long   rx_over_errors;     /* receiver ring buff overflow  */
+       vptr->stats.rx_crc_errors = vptr->mib_counter[HW_MIB_ifRxPktCRCE];
+//  unsigned long   rx_frame_errors;    /* recv'd frame alignment error */
+//  unsigned long   rx_fifo_errors;     /* recv'r fifo overrun      */
+//  unsigned long   rx_missed_errors;   /* receiver missed packet   */
+
+       /* detailed tx_errors */
+//  unsigned long   tx_fifo_errors;
+
+       return &vptr->stats;
+}
+
+
+/**
+ *     velocity_ioctl          -       ioctl entry point
+ *     @dev: network device
+ *     @rq: interface request ioctl
+ *     @cmd: command code
+ *
+ *     Called when the user issues an ioctl request to the network
+ *     device in question. The velocity interface supports MII.
+ */
+static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+       struct velocity_info *vptr = dev->priv;
+       int ret;
+
+       /* If we are asked for information and the device is power
+          saving then we need to bring the device back up to talk to it */
+               
+       if(!netif_running(dev))
+               pci_set_power_state(vptr->pdev, 0);
+               
+       switch (cmd) {
+       case SIOCGMIIPHY:       /* Get address of MII PHY in use. */
+       case SIOCGMIIREG:       /* Read MII PHY register. */
+       case SIOCSMIIREG:       /* Write to MII PHY register. */
+               ret = velocity_mii_ioctl(dev, rq, cmd);
+               break;
+
+       default:
+               ret = -EOPNOTSUPP;
+       }
+       if(!netif_running(dev))
+               pci_set_power_state(vptr->pdev, 3);
+               
+               
+       return ret;
+}
+
+/*
+ *     Definition for our device driver. The PCI layer interface
+ *     uses this to handle all our card discover and plugging
+ */
+static struct pci_driver velocity_driver = {
+      name:VELOCITY_NAME,
+      id_table:velocity_id_table,
+      probe:velocity_found1,
+      remove:velocity_remove1,
+#ifdef CONFIG_PM
+      suspend:velocity_suspend,
+      resume:velocity_resume,
+#endif
+};
+
+/**
+ *     velocity_init_module    -       load time function
+ *
+ *     Called when the velocity module is loaded. The PCI driver
+ *     is registered with the PCI layer, and in turn will call
+ *     the probe functions for each velocity adapter installed
+ *     in the system.
+ */
+static int __init velocity_init_module(void)
+{
+       int ret;
+       ret = pci_module_init(&velocity_driver);
+
+#ifdef CONFIG_PM
+       register_inetaddr_notifier(&velocity_inetaddr_notifier);
+#endif
+       return ret;
+}
+
+/**
+ *     velocity_cleanup        -       module unload
+ *
+ *     When the velocity hardware is unloaded this function is called.
+ *     It will clean up the notifiers and the unregister the PCI 
+ *     driver interface for this hardware. This in turn cleans up
+ *     all discovered interfaces before returning from the function
+ */
+static void __exit velocity_cleanup_module(void)
+{
+#ifdef CONFIG_PM
+       unregister_inetaddr_notifier(&velocity_inetaddr_notifier);
+#endif
+       pci_unregister_driver(&velocity_driver);
+}
+
+module_init(velocity_init_module);
+module_exit(velocity_cleanup_module);
+
+
+/*
+ * MII access , media link mode setting functions
+ */
+/**
+ *     mii_init        -       set up MII
+ *     @vptr: velocity adapter
+ *     @mii_status:  links tatus
+ *
+ *     Set up the PHY for the current link state.
+ */
+static void mii_init(struct velocity_info *vptr, u32 mii_status)
+{
+       u16 BMCR;
+
+       switch (PHYID_GET_PHY_ID(vptr->phy_id)) {
+       case PHYID_CICADA_CS8201:
+               /*
+                *      Reset to hardware default
+                */
+               MII_REG_BITS_OFF((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
+               /*
+                *      Turn on ECHODIS bit in NWay-forced full mode and turn it
+                *      off it in NWay-forced half mode for NWay-forced v.s. 
+                *      legacy-forced issue.
+                */
+               if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
+                       MII_REG_BITS_ON(TCSR_ECHODIS, MII_REG_TCSR, vptr->mac_regs);
+               else
+                       MII_REG_BITS_OFF(TCSR_ECHODIS, MII_REG_TCSR, vptr->mac_regs);
+               /*
+                *      Turn on Link/Activity LED enable bit for CIS8201
+                */
+               MII_REG_BITS_ON(PLED_LALBE, MII_REG_PLED, vptr->mac_regs);
+               break;
+       case PHYID_VT3216_32BIT:
+       case PHYID_VT3216_64BIT:
+               /*
+                *      Reset to hardware default
+                */
+               MII_REG_BITS_ON((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
+               /*
+                *      Turn on ECHODIS bit in NWay-forced full mode and turn it
+                *      off it in NWay-forced half mode for NWay-forced v.s. 
+                *      legacy-forced issue
+                */
+               if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
+                       MII_REG_BITS_ON(TCSR_ECHODIS, MII_REG_TCSR, vptr->mac_regs);
+               else
+                       MII_REG_BITS_OFF(TCSR_ECHODIS, MII_REG_TCSR, vptr->mac_regs);
+               break;
+
+       case PHYID_MARVELL_1000:
+       case PHYID_MARVELL_1000S:
+               /*
+                *      Assert CRS on Transmit 
+                */
+               MII_REG_BITS_ON(PSCR_ACRSTX, MII_REG_PSCR, vptr->mac_regs);
+               /*
+                *      Reset to hardware default 
+                */
+               MII_REG_BITS_ON((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
+               break;
+       default:
+               ;
+       }
+       velocity_mii_read(vptr->mac_regs, MII_REG_BMCR, &BMCR);
+       if (BMCR & BMCR_ISO) {
+               BMCR &= ~BMCR_ISO;
+               velocity_mii_write(vptr->mac_regs, MII_REG_BMCR, BMCR);
+       }
+}
+
+/**
+ *     safe_disable_mii_autopoll       -       autopoll off
+ *     @regs: velocity registers
+ *
+ *     Turn off the autopoll and wait for it to disable on the chip
+ */
+static void safe_disable_mii_autopoll(struct mac_regs * regs)
+{
+       u16 ww;
+
+       /*  turn off MAUTO */
+       writeb(0, &regs->MIICR);
+       for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+               udelay(1);
+               if (BYTE_REG_BITS_IS_ON(MIISR_MIDLE, &regs->MIISR))
+                       break;
+       }
+}
+
+/**
+ *     enable_mii_autopoll     -       turn on autopolling
+ *     @regs: velocity registers
+ *
+ *     Enable the MII link status autopoll feature on the Velocity
+ *     hardware. Wait for it to enable.
+ */
+
+static void enable_mii_autopoll(struct mac_regs * regs)
+{
+       int ii;
+
+       writeb(0, &(regs->MIICR));
+       writeb(MIIADR_SWMPL, &regs->MIIADR);
+
+       for (ii = 0; ii < W_MAX_TIMEOUT; ii++) {
+               udelay(1);
+               if (BYTE_REG_BITS_IS_ON(MIISR_MIDLE, &regs->MIISR))
+                       break;
+       }
+
+       writeb(MIICR_MAUTO, &regs->MIICR);
+
+       for (ii = 0; ii < W_MAX_TIMEOUT; ii++) {
+               udelay(1);
+               if (!BYTE_REG_BITS_IS_ON(MIISR_MIDLE, &regs->MIISR))
+                       break;
+       }
+
+}
+
+/**
+ *     velocity_mii_read       -       read MII data
+ *     @regs: velocity registers
+ *     @index: MII register index
+ *     @data: buffer for received data
+ *
+ *     Perform a single read of an MII 16bit register. Returns zero
+ *     on success or -ETIMEDOUT if the PHY did not respond.
+ */
+static int velocity_mii_read(struct mac_regs * regs, u8 index, u16 *data)
+{
+       u16 ww;
+
+       /*
+        *      Disable MIICR_MAUTO, so that mii addr can be set normally
+        */
+       safe_disable_mii_autopoll(regs);
+
+       writeb(index, &regs->MIIADR);
+
+       BYTE_REG_BITS_ON(MIICR_RCMD, &regs->MIICR);
+
+       for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+               if (!(readb(&regs->MIICR) & MIICR_RCMD))
+                       break;
+       }
+
+       *data = readw(&regs->MIIDATA);
+
+       enable_mii_autopoll(regs);
+       if (ww == W_MAX_TIMEOUT)
+               return -ETIMEDOUT;
+       return 0;
+}
+
+/**
+ *     velocity_mii_write      -       write MII data
+ *     @regs: velocity registers
+ *     @index: MII register index
+ *     @data: 16bit data for the MII register
+ *
+ *     Perform a single write to an MII 16bit register. Returns zero
+ *     on success or -ETIMEDOUT if the PHY did not respond.
+ */
+static int velocity_mii_write(struct mac_regs * regs, u8 mii_addr, u16 data)
+{
+       u16 ww;
+
+       /*
+        *      Disable MIICR_MAUTO, so that mii addr can be set normally
+        */
+       safe_disable_mii_autopoll(regs);
+
+       /* MII reg offset */
+       writeb(mii_addr, &regs->MIIADR);
+       /* set MII data */
+       writew(data, &regs->MIIDATA);
+
+       /* turn on MIICR_WCMD */
+       BYTE_REG_BITS_ON(MIICR_WCMD, &regs->MIICR);
+
+       /* W_MAX_TIMEOUT is the timeout period */
+       for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+               udelay(5);
+               if (!(readb(&regs->MIICR) & MIICR_WCMD))
+                       break;
+       }
+       enable_mii_autopoll(regs);
+
+       if (ww == W_MAX_TIMEOUT)
+               return -ETIMEDOUT;
+       return 0;
+}
+
+/**
+ *     velocity_get_opt_media_mode     -       get media selection
+ *     @vptr: velocity adapter
+ *
+ *     Get the media mode stored in EEPROM or module options and load
+ *     mii_status accordingly. The requested link state information
+ *     is also returned.
+ */
+static u32 velocity_get_opt_media_mode(struct velocity_info *vptr)
+{
+       u32 status = 0;
+
+       switch (vptr->options.spd_dpx) {
+       case SPD_DPX_AUTO:
+               status = VELOCITY_AUTONEG_ENABLE;
+               break;
+       case SPD_DPX_100_FULL:
+               status = VELOCITY_SPEED_100 | VELOCITY_DUPLEX_FULL;
+               break;
+       case SPD_DPX_10_FULL:
+               status = VELOCITY_SPEED_10 | VELOCITY_DUPLEX_FULL;
+               break;
+       case SPD_DPX_100_HALF:
+               status = VELOCITY_SPEED_100;
+               break;
+       case SPD_DPX_10_HALF:
+               status = VELOCITY_SPEED_10;
+               break;
+       }
+       vptr->mii_status = status;
+       return status;
+}
+
+/**
+ *     mii_set_auto_on         -       autonegotiate on
+ *     @vptr: velocity
+ *
+ *     Enable autonegotation on this interface
+ */
+static void mii_set_auto_on(struct velocity_info *vptr)
+{
+       if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs))
+               MII_REG_BITS_ON(BMCR_REAUTO, MII_REG_BMCR, vptr->mac_regs);
+       else
+               MII_REG_BITS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs);
+}
+
+
+/*
+static void mii_set_auto_off(struct velocity_info * vptr)
+{
+    MII_REG_BITS_OFF(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs);
+}
+*/
+
+/**
+ *     set_mii_flow_control    -       flow control setup
+ *     @vptr: velocity interface
+ *
+ *     Set up the flow control on this interface according to
+ *     the supplied user/eeprom options.
+ */
+static void set_mii_flow_control(struct velocity_info *vptr)
+{
+       /*Enable or Disable PAUSE in ANAR */
+       switch (vptr->options.flow_cntl) {
+       case FLOW_CNTL_TX:
+               MII_REG_BITS_OFF(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
+               MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
+               break;
+
+       case FLOW_CNTL_RX:
+               MII_REG_BITS_ON(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
+               MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
+               break;
+
+       case FLOW_CNTL_TX_RX:
+               MII_REG_BITS_ON(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
+               MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
+               break;
+
+       case FLOW_CNTL_DISABLE:
+               MII_REG_BITS_OFF(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
+               MII_REG_BITS_OFF(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
+               break;
+       default:
+               break;
+       }
+}
+
+/**
+ *     velocity_set_media_mode         -       set media mode
+ *     @mii_status: old MII link state
+ *
+ *     Check the media link state and configure the flow control
+ *     PHY and also velocity hardware setup accordingly. In particular
+ *     we need to set up CD polling and frame bursting.
+ */
+static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status)
+{
+       u32 curr_status;
+       struct mac_regs * regs = vptr->mac_regs;
+
+       vptr->mii_status = mii_check_media_mode(vptr->mac_regs);
+       curr_status = vptr->mii_status & (~VELOCITY_LINK_FAIL);
+
+       /* Set mii link status */
+       set_mii_flow_control(vptr);
+
+       /*
+          Check if new status is consisent with current status
+          if (((mii_status & curr_status) & VELOCITY_AUTONEG_ENABLE)
+          || (mii_status==curr_status)) {
+          vptr->mii_status=mii_check_media_mode(vptr->mac_regs);
+          vptr->mii_status=check_connection_type(vptr->mac_regs);
+          VELOCITY_PRT(MSG_LEVEL_INFO, "Velocity link no change\n");
+          return 0;
+          }
+        */
+
+       if (PHYID_GET_PHY_ID(vptr->phy_id) == PHYID_CICADA_CS8201) {
+               MII_REG_BITS_ON(AUXCR_MDPPS, MII_REG_AUXCR, vptr->mac_regs);
+       }
+
+       /*
+        *      If connection type is AUTO
+        */
+       if (mii_status & VELOCITY_AUTONEG_ENABLE) {
+               VELOCITY_PRT(MSG_LEVEL_INFO, "Velocity is AUTO mode\n");
+               /* clear force MAC mode bit */
+               BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, &regs->CHIPGCR);
+               /* set duplex mode of MAC according to duplex mode of MII */
+               MII_REG_BITS_ON(ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10, MII_REG_ANAR, vptr->mac_regs);
+               MII_REG_BITS_ON(G1000CR_1000FD | G1000CR_1000, MII_REG_G1000CR, vptr->mac_regs);
+               MII_REG_BITS_ON(BMCR_SPEED1G, MII_REG_BMCR, vptr->mac_regs);
+
+               /* enable AUTO-NEGO mode */
+               mii_set_auto_on(vptr);
+       } else {
+               u16 ANAR;
+               u8 CHIPGCR;
+
+               /*
+                * 1. if it's 3119, disable frame bursting in halfduplex mode
+                *    and enable it in fullduplex mode
+                * 2. set correct MII/GMII and half/full duplex mode in CHIPGCR
+                * 3. only enable CD heart beat counter in 10HD mode
+                */
+
+               /* set force MAC mode bit */
+               BYTE_REG_BITS_ON(CHIPGCR_FCMODE, &regs->CHIPGCR);
+
+               CHIPGCR = readb(&regs->CHIPGCR);
+               CHIPGCR &= ~CHIPGCR_FCGMII;
+
+               if (mii_status & VELOCITY_DUPLEX_FULL) {
+                       CHIPGCR |= CHIPGCR_FCFDX;
+                       writeb(CHIPGCR, &regs->CHIPGCR);
+                       VELOCITY_PRT(MSG_LEVEL_INFO, "set Velocity to forced full mode\n");
+                       if (vptr->rev_id < REV_ID_VT3216_A0)
+                               BYTE_REG_BITS_OFF(TCR_TB2BDIS, &regs->TCR);
+               } else {
+                       CHIPGCR &= ~CHIPGCR_FCFDX;
+                       VELOCITY_PRT(MSG_LEVEL_INFO, "set Velocity to forced half mode\n");
+                       writeb(CHIPGCR, &regs->CHIPGCR);
+                       if (vptr->rev_id < REV_ID_VT3216_A0)
+                               BYTE_REG_BITS_ON(TCR_TB2BDIS, &regs->TCR);
+               }
+
+               MII_REG_BITS_OFF(G1000CR_1000FD | G1000CR_1000, MII_REG_G1000CR, vptr->mac_regs);
+
+               if (!(mii_status & VELOCITY_DUPLEX_FULL) && (mii_status & VELOCITY_SPEED_10)) {
+                       BYTE_REG_BITS_OFF(TESTCFG_HBDIS, &regs->TESTCFG);
+               } else {
+                       BYTE_REG_BITS_ON(TESTCFG_HBDIS, &regs->TESTCFG);
+               }
+               /* MII_REG_BITS_OFF(BMCR_SPEED1G, MII_REG_BMCR, vptr->mac_regs); */
+               velocity_mii_read(vptr->mac_regs, MII_REG_ANAR, &ANAR);
+               ANAR &= (~(ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10));
+               if (mii_status & VELOCITY_SPEED_100) {
+                       if (mii_status & VELOCITY_DUPLEX_FULL)
+                               ANAR |= ANAR_TXFD;
+                       else
+                               ANAR |= ANAR_TX;
+               } else {
+                       if (mii_status & VELOCITY_DUPLEX_FULL)
+                               ANAR |= ANAR_10FD;
+                       else
+                               ANAR |= ANAR_10;
+               }
+               velocity_mii_write(vptr->mac_regs, MII_REG_ANAR, ANAR);
+               /* enable AUTO-NEGO mode */
+               mii_set_auto_on(vptr);
+               /* MII_REG_BITS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs); */
+       }
+       /* vptr->mii_status=mii_check_media_mode(vptr->mac_regs); */
+       /* vptr->mii_status=check_connection_type(vptr->mac_regs); */
+       return VELOCITY_LINK_CHANGE;
+}
+
+/**
+ *     mii_check_media_mode    -       check media state
+ *     @regs: velocity registers
+ *
+ *     Check the current MII status and determine the link status
+ *     accordingly
+ */
+static u32 mii_check_media_mode(struct mac_regs * regs)
+{
+       u32 status = 0;
+       u16 ANAR;
+
+       if (!MII_REG_BITS_IS_ON(BMSR_LNK, MII_REG_BMSR, regs))
+               status |= VELOCITY_LINK_FAIL;
+
+       if (MII_REG_BITS_IS_ON(G1000CR_1000FD, MII_REG_G1000CR, regs))
+               status |= VELOCITY_SPEED_1000 | VELOCITY_DUPLEX_FULL;
+       else if (MII_REG_BITS_IS_ON(G1000CR_1000, MII_REG_G1000CR, regs))
+               status |= (VELOCITY_SPEED_1000);
+       else {
+               velocity_mii_read(regs, MII_REG_ANAR, &ANAR);
+               if (ANAR & ANAR_TXFD)
+                       status |= (VELOCITY_SPEED_100 | VELOCITY_DUPLEX_FULL);
+               else if (ANAR & ANAR_TX)
+                       status |= VELOCITY_SPEED_100;
+               else if (ANAR & ANAR_10FD)
+                       status |= (VELOCITY_SPEED_10 | VELOCITY_DUPLEX_FULL);
+               else
+                       status |= (VELOCITY_SPEED_10);
+       }
+
+       if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, regs)) {
+               velocity_mii_read(regs, MII_REG_ANAR, &ANAR);
+               if ((ANAR & (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10))
+                   == (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10)) {
+                       if (MII_REG_BITS_IS_ON(G1000CR_1000 | G1000CR_1000FD, MII_REG_G1000CR, regs))
+                               status |= VELOCITY_AUTONEG_ENABLE;
+               }
+       }
+
+       return status;
+}
+
+static u32 check_connection_type(struct mac_regs * regs)
+{
+       u32 status = 0;
+       u8 PHYSR0;
+       u16 ANAR;
+       PHYSR0 = readb(&regs->PHYSR0);
+
+       /*
+          if (!(PHYSR0 & PHYSR0_LINKGD))
+          status|=VELOCITY_LINK_FAIL;
+        */
+
+       if (PHYSR0 & PHYSR0_FDPX)
+               status |= VELOCITY_DUPLEX_FULL;
+
+       if (PHYSR0 & PHYSR0_SPDG)
+               status |= VELOCITY_SPEED_1000;
+       if (PHYSR0 & PHYSR0_SPD10)
+               status |= VELOCITY_SPEED_10;
+       else
+               status |= VELOCITY_SPEED_100;
+
+       if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, regs)) {
+               velocity_mii_read(regs, MII_REG_ANAR, &ANAR);
+               if ((ANAR & (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10))
+                   == (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10)) {
+                       if (MII_REG_BITS_IS_ON(G1000CR_1000 | G1000CR_1000FD, MII_REG_G1000CR, regs))
+                               status |= VELOCITY_AUTONEG_ENABLE;
+               }
+       }
+
+       return status;
+}
+
+/**
+ *     enable_flow_control_ability     -       flow control
+ *     @vptr: veloity to configure
+ *
+ *     Set up flow control according to the flow control options
+ *     determined by the eeprom/configuration.
+ */
+
+static void enable_flow_control_ability(struct velocity_info *vptr)
+{
+
+       struct mac_regs * regs = vptr->mac_regs;
+
+       switch (vptr->options.flow_cntl) {
+
+       case FLOW_CNTL_DEFAULT:
+               if (BYTE_REG_BITS_IS_ON(PHYSR0_RXFLC, &regs->PHYSR0))
+                       writel(CR0_FDXRFCEN, &regs->CR0Set);
+               else
+                       writel(CR0_FDXRFCEN, &regs->CR0Clr);
+
+               if (BYTE_REG_BITS_IS_ON(PHYSR0_TXFLC, &regs->PHYSR0))
+                       writel(CR0_FDXTFCEN, &regs->CR0Set);
+               else
+                       writel(CR0_FDXTFCEN, &regs->CR0Clr);
+               break;
+
+       case FLOW_CNTL_TX:
+               writel(CR0_FDXTFCEN, &regs->CR0Set);
+               writel(CR0_FDXRFCEN, &regs->CR0Clr);
+               break;
+
+       case FLOW_CNTL_RX:
+               writel(CR0_FDXRFCEN, &regs->CR0Set);
+               writel(CR0_FDXTFCEN, &regs->CR0Clr);
+               break;
+
+       case FLOW_CNTL_TX_RX:
+               writel(CR0_FDXTFCEN, &regs->CR0Set);
+               writel(CR0_FDXRFCEN, &regs->CR0Set);
+               break;
+
+       case FLOW_CNTL_DISABLE:
+               writel(CR0_FDXRFCEN, &regs->CR0Clr);
+               writel(CR0_FDXTFCEN, &regs->CR0Clr);
+               break;
+
+       default:
+               break;
+       }
+
+}
+
+
+/**
+ *     velocity_ethtool_up     -       pre hook for ethtool
+ *     @dev: network device
+ *
+ *     Called before an ethtool operation. We need to make sure the
+ *     chip is out of D3 state before we poke at it.
+ */
+static int velocity_ethtool_up(struct net_device *dev)
+{
+       struct velocity_info *vptr = dev->priv;
+       if(!netif_running(dev))
+               pci_set_power_state(vptr->pdev, 0);
+       return 0;
+}      
+
+/**
+ *     velocity_ethtool_down   -       post hook for ethtool
+ *     @dev: network device
+ *
+ *     Called after an ethtool operation. Restore the chip back to D3
+ *     state if it isn't running.
+ */
+static void velocity_ethtool_down(struct net_device *dev)
+{
+       struct velocity_info *vptr = dev->priv;
+       if(!netif_running(dev))
+               pci_set_power_state(vptr->pdev, 3);
+}
+
+static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct velocity_info *vptr = dev->priv;
+       struct mac_regs * regs = vptr->mac_regs;
+       u32 status;
+       status = check_connection_type(vptr->mac_regs);
+
+       cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full;
+       if (status & VELOCITY_SPEED_100)
+               cmd->speed = SPEED_100;
+       else
+               cmd->speed = SPEED_10;
+       cmd->autoneg = (status & VELOCITY_AUTONEG_ENABLE) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+       cmd->port = PORT_TP;
+       cmd->transceiver = XCVR_INTERNAL;
+       cmd->phy_address = readb(&regs->MIIADR) & 0x1F;
+
+       if (status & VELOCITY_DUPLEX_FULL)
+               cmd->duplex = DUPLEX_FULL;
+       else
+               cmd->duplex = DUPLEX_HALF;
+               
+       return 0;
+}
+
+static int velocity_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct velocity_info *vptr = dev->priv;
+       u32 curr_status;
+       u32 new_status = 0;
+       int ret = 0;
+       
+       curr_status = check_connection_type(vptr->mac_regs);
+       curr_status &= (~VELOCITY_LINK_FAIL);
+
+       new_status |= ((cmd->autoneg) ? VELOCITY_AUTONEG_ENABLE : 0);
+       new_status |= ((cmd->speed == SPEED_100) ? VELOCITY_SPEED_100 : 0);
+       new_status |= ((cmd->speed == SPEED_10) ? VELOCITY_SPEED_10 : 0);
+       new_status |= ((cmd->duplex == DUPLEX_FULL) ? VELOCITY_DUPLEX_FULL : 0);
+
+       if ((new_status & VELOCITY_AUTONEG_ENABLE) && (new_status != (curr_status | VELOCITY_AUTONEG_ENABLE)))
+               ret = -EINVAL;
+       else
+               velocity_set_media_mode(vptr, new_status);
+
+       return ret;
+}
+
+static u32 velocity_get_link(struct net_device *dev)
+{
+       struct velocity_info *vptr = dev->priv;
+       struct mac_regs * regs = vptr->mac_regs;
+       return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, &regs->PHYSR0)  ? 0 : 1;
+}
+
+static void velocity_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+       struct velocity_info *vptr = dev->priv;
+       strcpy(info->driver, VELOCITY_NAME);
+       strcpy(info->version, VELOCITY_VERSION);
+       strcpy(info->bus_info, vptr->pdev->slot_name);
+}
+
+static void velocity_ethtool_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+       struct velocity_info *vptr = dev->priv;
+       wol->supported = WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_ARP;
+       wol->wolopts |= WAKE_MAGIC;
+       /*
+          if (vptr->wol_opts & VELOCITY_WOL_PHY)
+                  wol.wolopts|=WAKE_PHY;
+                        */
+       if (vptr->wol_opts & VELOCITY_WOL_UCAST)
+               wol->wolopts |= WAKE_UCAST;
+       if (vptr->wol_opts & VELOCITY_WOL_ARP)
+               wol->wolopts |= WAKE_ARP;
+       memcpy(&wol->sopass, vptr->wol_passwd, 6);
+}
+
+static int velocity_ethtool_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+       struct velocity_info *vptr = dev->priv;
+
+       if (!(wol->wolopts & (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_ARP)))
+               return -EFAULT;
+       vptr->wol_opts = VELOCITY_WOL_MAGIC;
+
+       /*
+          if (wol.wolopts & WAKE_PHY) {
+          vptr->wol_opts|=VELOCITY_WOL_PHY;
+          vptr->flags |=VELOCITY_FLAGS_WOL_ENABLED;
+          }
+        */
+
+       if (wol->wolopts & WAKE_MAGIC) {
+               vptr->wol_opts |= VELOCITY_WOL_MAGIC;
+               vptr->flags |= VELOCITY_FLAGS_WOL_ENABLED;
+       }
+       if (wol->wolopts & WAKE_UCAST) {
+               vptr->wol_opts |= VELOCITY_WOL_UCAST;
+               vptr->flags |= VELOCITY_FLAGS_WOL_ENABLED;
+       }
+       if (wol->wolopts & WAKE_ARP) {
+               vptr->wol_opts |= VELOCITY_WOL_ARP;
+               vptr->flags |= VELOCITY_FLAGS_WOL_ENABLED;
+       }
+       memcpy(vptr->wol_passwd, wol->sopass, 6);
+       return 0;
+}
+
+static u32 velocity_get_msglevel(struct net_device *dev)
+{
+       return msglevel;
+}
+
+static void velocity_set_msglevel(struct net_device *dev, u32 value)
+{
+        msglevel = value;
+}
+
+static struct ethtool_ops velocity_ethtool_ops = {
+       .get_settings   =       velocity_get_settings,
+       .set_settings   =       velocity_set_settings,
+       .get_drvinfo    =       velocity_get_drvinfo,
+       .get_wol        =       velocity_ethtool_get_wol,
+       .set_wol        =       velocity_ethtool_set_wol,
+       .get_msglevel   =       velocity_get_msglevel,
+       .set_msglevel   =       velocity_set_msglevel,
+       .get_link       =       velocity_get_link,
+       .begin          =       velocity_ethtool_up,
+       .complete       =       velocity_ethtool_down
+};
+
+/**
+ *     velocity_mii_ioctl              -       MII ioctl handler
+ *     @dev: network device
+ *     @ifr: the ifreq block for the ioctl
+ *     @cmd: the command
+ *
+ *     Process MII requests made via ioctl from the network layer. These
+ *     are used by tools like kudzu to interrogate the link state of the
+ *     hardware
+ */
+static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+       struct velocity_info *vptr = dev->priv;
+       struct mac_regs * regs = vptr->mac_regs;
+       unsigned long flags;
+       struct mii_ioctl_data *miidata = (struct mii_ioctl_data *) &(ifr->ifr_data);
+       int err;
+       
+       switch (cmd) {
+       case SIOCGMIIPHY:
+               miidata->phy_id = readb(&regs->MIIADR) & 0x1f;
+               break;
+       case SIOCGMIIREG:
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
+               if(velocity_mii_read(vptr->mac_regs, miidata->reg_num & 0x1f, &(miidata->val_out)) < 0)
+                       return -ETIMEDOUT;
+               break;
+       case SIOCSMIIREG:
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
+               spin_lock_irqsave(&vptr->lock, flags);
+               err = velocity_mii_write(vptr->mac_regs, miidata->reg_num & 0x1f, miidata->val_in);
+               spin_unlock_irqrestore(&vptr->lock, flags);
+               check_connection_type(vptr->mac_regs);
+               if(err)
+                       return err;
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+       return 0;
+}
+
+#ifdef CONFIG_PM
+
+/**
+ *     velocity_save_context   -       save registers
+ *     @vptr: velocity 
+ *     @context: buffer for stored context
+ *
+ *     Retrieve the current configuration from the velocity hardware
+ *     and stash it in the context structure, for use by the context
+ *     restore functions. This allows us to save things we need across
+ *     power down states
+ */
+static void velocity_save_context(struct velocity_info *vptr, struct velocity_context * context)
+{
+       struct mac_regs * regs = vptr->mac_regs;
+       u16 i;
+       u8 *ptr = (u8 *)regs;
+
+       for (i = MAC_REG_PAR; i < MAC_REG_CR0_CLR; i += 4)
+               *((u32 *) (context->mac_reg + i)) = readl(ptr + i);
+
+       for (i = MAC_REG_MAR; i < MAC_REG_TDCSR_CLR; i += 4)
+               *((u32 *) (context->mac_reg + i)) = readl(ptr + i);
+
+       for (i = MAC_REG_RDBASE_LO; i < MAC_REG_FIFO_TEST0; i += 4)
+               *((u32 *) (context->mac_reg + i)) = readl(ptr + i);
+
+}
+
+/**
+ *     velocity_restore_context        -       restore registers
+ *     @vptr: velocity 
+ *     @context: buffer for stored context
+ *
+ *     Reload the register configuration from the velocity context 
+ *     created by velocity_save_context.
+ */
+static void velocity_restore_context(struct velocity_info *vptr, struct velocity_context *context)
+{
+       struct mac_regs * regs = vptr->mac_regs;
+       int i;
+       u8 *ptr = (u8 *)regs;
+
+       for (i = MAC_REG_PAR; i < MAC_REG_CR0_SET; i += 4) {
+               writel(*((u32 *) (context->mac_reg + i)), ptr + i);
+       }
+
+       /* Just skip cr0 */
+       for (i = MAC_REG_CR1_SET; i < MAC_REG_CR0_CLR; i++) {
+               /* Clear */
+               writeb(~(*((u8 *) (context->mac_reg + i))), ptr + i + 4);
+               /* Set */
+               writeb(*((u8 *) (context->mac_reg + i)), ptr + i);
+       }
+
+       for (i = MAC_REG_MAR; i < MAC_REG_IMR; i += 4) {
+               writel(*((u32 *) (context->mac_reg + i)), ptr + i);
+       }
+
+       for (i = MAC_REG_RDBASE_LO; i < MAC_REG_FIFO_TEST0; i += 4) {
+               writel(*((u32 *) (context->mac_reg + i)), ptr + i);
+       }
+
+       for (i = MAC_REG_TDCSR_SET; i <= MAC_REG_RDCSR_SET; i++) {
+               writeb(*((u8 *) (context->mac_reg + i)), ptr + i);
+       }
+
+}
+
+static int velocity_suspend(struct pci_dev *pdev, u32 state)
+{
+       struct velocity_info *vptr = pci_get_drvdata(pdev);
+       unsigned long flags;
+       
+       if(!netif_running(vptr->dev))
+               return 0;
+               
+       netif_device_detach(vptr->dev);
+       
+       spin_lock_irqsave(&vptr->lock, flags);
+       pci_save_state(pdev, vptr->pci_state);
+#ifdef ETHTOOL_GWOL
+       if (vptr->flags & VELOCITY_FLAGS_WOL_ENABLED) {
+               velocity_get_ip(vptr);
+               velocity_save_context(vptr, &vptr->context);
+               velocity_shutdown(vptr);
+               velocity_set_wol(vptr);
+               pci_enable_wake(pdev, 3, 1);
+               pci_set_power_state(pdev, 3);
+       } else {
+               velocity_save_context(vptr, &vptr->context);
+               velocity_shutdown(vptr);
+               pci_disable_device(pdev);
+               pci_set_power_state(pdev, state);
+       }
+#else
+       pci_set_power_state(pdev, state);
+#endif
+       spin_unlock_irqrestore(&vptr->lock, flags);
+       return 0;
+}
+
+static int velocity_resume(struct pci_dev *pdev)
+{
+       struct velocity_info *vptr = pci_get_drvdata(pdev);
+       unsigned long flags;
+       int i;
+       
+       if(!netif_running(vptr->dev))
+               return 0;
+               
+       pci_set_power_state(pdev, 0);
+       pci_enable_wake(pdev, 0, 0);
+       pci_restore_state(pdev, vptr->pci_state);
+
+       mac_wol_reset(vptr->mac_regs);
+
+       spin_lock_irqsave(&vptr->lock, flags);
+       velocity_restore_context(vptr, &vptr->context);
+       velocity_init_registers(vptr, VELOCITY_INIT_WOL);
+       mac_disable_int(vptr->mac_regs);
+
+       velocity_tx_srv(vptr, 0);
+
+       for (i = 0; i < vptr->num_txq; i++) {
+               if (vptr->td_used[i]) {
+                       mac_tx_queue_wake(vptr->mac_regs, i);
+               }
+       }
+
+       mac_enable_int(vptr->mac_regs);
+       spin_unlock_irqrestore(&vptr->lock, flags);
+       netif_device_attach(vptr->dev);
+
+       return 0;
+}
+
+static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr)
+{
+       struct in_ifaddr *ifa = (struct in_ifaddr *) ptr;
+       struct net_device *dev;
+       struct velocity_info *vptr;
+
+       if (ifa) {
+               dev = ifa->ifa_dev->dev;
+               vptr = dev->priv;
+               velocity_get_ip(vptr);
+       }
+       return NOTIFY_DONE;
+}
+#endif
+
+/*
+ * Purpose: Functions to set WOL.
+ */
+
+const static unsigned short crc16_tab[256] = {
+       0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
+       0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
+       0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
+       0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
+       0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
+       0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
+       0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+       0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
+       0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
+       0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
+       0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
+       0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
+       0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
+       0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+       0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
+       0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
+       0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
+       0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
+       0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
+       0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
+       0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+       0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
+       0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
+       0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
+       0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
+       0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
+       0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
+       0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+       0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
+       0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
+       0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
+       0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
+};
+
+
+static u32 mask_pattern[2][4] = {
+       {0x00203000, 0x000003C0, 0x00000000, 0x0000000},        /* ARP          */
+       {0xfffff000, 0xffffffff, 0xffffffff, 0x000ffff}         /* Magic Packet */ 
+};
+
+/**
+ *     ether_crc16     -       compute ethernet CRC
+ *     @len: buffer length
+ *     @cp: buffer
+ *     @crc16: initial CRC
+ *
+ *     Compute a CRC value for a block of data. 
+ *     FIXME: can we use generic functions ?
+ */
+static u16 ether_crc16(int len, u8 * cp, u16 crc16)
+{
+       while (len--)
+               crc16 = (crc16 >> 8) ^ crc16_tab[(crc16 ^ *cp++) & 0xff];
+       return (crc16);
+}
+
+/**
+ *     bit_reverse             -       16bit reverse
+ *     @data: 16bit data t reverse
+ *
+ *     Reverse the order of a 16bit value and return the reversed bits
+ */
+static u16 bit_reverse(u16 data)
+{
+       u32 new = 0x00000000;
+       int ii;
+
+
+       for (ii = 0; ii < 16; ii++) {
+               new |= ((u32) (data & 1) << (31 - ii));
+               data >>= 1;
+       }
+
+       return (u16) (new >> 16);
+}
+
+/**
+ *     wol_calc_crc            -       WOL CRC
+ *     @pattern: data pattern
+ *     @mask_pattern: mask
+ *
+ *     Compute the wake on lan crc hashes for the packet header
+ *     we are interested in.
+ */
+u16 wol_calc_crc(int size, u8 * pattern, u8 *mask_pattern)
+{
+       u16 crc = 0xFFFF;
+       u8 mask;
+       int i, j;
+
+       for (i = 0; i < size; i++) {
+               mask = mask_pattern[i];
+
+               /* Skip this loop if the mask equals to zero */
+               if (mask == 0x00)
+                       continue;
+
+               for (j = 0; j < 8; j++) {
+                       if ((mask & 0x01) == 0) {
+                               mask >>= 1;
+                               continue;
+                       }
+                       mask >>= 1;
+                       crc = ether_crc16(1, &(pattern[i * 8 + j]), crc);
+               }
+       }
+       /*      Finally, invert the result once to get the correct data */
+       crc = ~crc;
+       return bit_reverse(crc);
+}
+
+/**
+ *     velocity_set_wol        -       set up for wake on lan
+ *     @vptr: velocity to set WOL status on
+ *
+ *     Set a card up for wake on lan either by unicast or by
+ *     ARP packet.
+ *
+ *     FIXME: check static buffer is safe here
+ */
+static int velocity_set_wol(struct velocity_info *vptr)
+{
+       struct mac_regs * regs = vptr->mac_regs;
+       static u8 buf[256];
+       int i;
+
+       writew(0xFFFF, &regs->WOLCRClr);
+       writeb(WOLCFG_SAB | WOLCFG_SAM, &regs->WOLCFGSet);
+       writew(WOLCR_MAGIC_EN, &regs->WOLCRSet);
+
+       /*
+          if (vptr->wol_opts & VELOCITY_WOL_PHY)
+          writew((WOLCR_LINKON_EN|WOLCR_LINKOFF_EN), &regs->WOLCRSet);
+        */
+
+       if (vptr->wol_opts & VELOCITY_WOL_UCAST) {
+               writew(WOLCR_UNICAST_EN, &regs->WOLCRSet);
+       }
+
+       if (vptr->wol_opts & VELOCITY_WOL_ARP) {
+               struct arp_packet *arp = (struct arp_packet *) buf;
+               u16 crc;
+               memset(buf, 0, sizeof(struct arp_packet) + 7);
+
+               for (i = 0; i < 4; i++)
+                       writel(mask_pattern[0][i], &regs->ByteMask[0][i]);
+
+               arp->type = htons(ETH_P_ARP);
+               arp->ar_op = htons(1);
+
+               memcpy(arp->ar_tip, vptr->ip_addr, 4);
+
+               crc = wol_calc_crc((sizeof(struct arp_packet) + 7) / 8, buf, (u8 *) & mask_pattern[0][0]);
+
+               writew(crc, &regs->PatternCRC[0]);
+               writew(WOLCR_ARP_EN, &regs->WOLCRSet);
+       }
+
+       BYTE_REG_BITS_ON(PWCFG_WOLTYPE, &regs->PWCFGSet);
+       BYTE_REG_BITS_ON(PWCFG_LEGACY_WOLEN, &regs->PWCFGSet);
+
+       writew(0x0FFF, &regs->WOLSRClr);
+
+       if (vptr->mii_status & VELOCITY_AUTONEG_ENABLE) {
+               if (PHYID_GET_PHY_ID(vptr->phy_id) == PHYID_CICADA_CS8201)
+                       MII_REG_BITS_ON(AUXCR_MDPPS, MII_REG_AUXCR, vptr->mac_regs);
+
+               MII_REG_BITS_OFF(G1000CR_1000FD | G1000CR_1000, MII_REG_G1000CR, vptr->mac_regs);
+       }
+
+       if (vptr->mii_status & VELOCITY_SPEED_1000)
+               MII_REG_BITS_ON(BMCR_REAUTO, MII_REG_BMCR, vptr->mac_regs);
+
+       BYTE_REG_BITS_ON(CHIPGCR_FCMODE, &regs->CHIPGCR);
+
+       {
+               u8 GCR;
+               GCR = readb(&regs->CHIPGCR);
+               GCR = (GCR & ~CHIPGCR_FCGMII) | CHIPGCR_FCFDX;
+               writeb(GCR, &regs->CHIPGCR);
+       }
+
+       BYTE_REG_BITS_OFF(ISR_PWEI, &regs->ISR);
+       /* Turn on SWPTAG just before entering power mode */
+       BYTE_REG_BITS_ON(STICKHW_SWPTAG, &regs->STICKHW);
+       /* Go to bed ..... */
+       BYTE_REG_BITS_ON((STICKHW_DS1 | STICKHW_DS0), &regs->STICKHW);
+
+       return 0;
+}
+
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
new file mode 100644 (file)
index 0000000..9f75c87
--- /dev/null
@@ -0,0 +1,2153 @@
+/*
+   3w-9xxx.c -- 3ware 9000 Storage Controller device driver for Linux.
+
+   Written By: Adam Radford <linuxraid@amcc.com>
+
+   Copyright (C) 2004 Applied Micro Circuits Corporation.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   NO WARRANTY
+   THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+   CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+   LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+   solely responsible for determining the appropriateness of using and
+   distributing the Program and assumes all risks associated with its
+   exercise of rights under this Agreement, including but not limited to
+   the risks and costs of program errors, damage to or loss of data,
+   programs or equipment, and unavailability or interruption of operations.
+
+   DISCLAIMER OF LIABILITY
+   NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+   DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
+   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+   TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+   USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+   HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+   Bugs/Comments/Suggestions should be mailed to:
+   linuxraid@amcc.com
+
+   For more information, goto:
+   http://www.amcc.com
+
+   Note: This version of the driver does not contain a bundled firmware
+         image.
+
+   History
+   -------
+   2.26.02.000 - Driver cleanup for kernel submission.
+   2.26.02.001 - Replace schedule_timeout() calls with msleep().
+*/
+
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/moduleparam.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/time.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_cmnd.h>
+#include "3w-9xxx.h"
+
+/* Globals */
+static const char *twa_driver_version="2.26.02.001";
+static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
+static unsigned int twa_device_extension_count;
+static int twa_major = -1;
+extern struct timezone sys_tz;
+
+/* Module parameters */
+MODULE_AUTHOR ("AMCC");
+MODULE_DESCRIPTION ("3ware 9000 Storage Controller Linux Driver");
+MODULE_LICENSE("GPL");
+
+/* Function prototypes */
+static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header);
+static int twa_aen_read_queue(TW_Device_Extension *tw_dev, int request_id);
+static char *twa_aen_severity_lookup(unsigned char severity_code);
+static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id);
+static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+static int twa_chrdev_open(struct inode *inode, struct file *file);
+static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_sense, int print_host);
+static void twa_free_request_id(TW_Device_Extension *tw_dev,int request_id);
+static void twa_get_request_id(TW_Device_Extension *tw_dev, int *request_id);
+static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits,
+                             u32 set_features, unsigned short current_fw_srl, 
+                             unsigned short current_fw_arch_id, 
+                             unsigned short current_fw_branch, 
+                             unsigned short current_fw_build, 
+                             unsigned short *fw_on_ctlr_srl, 
+                             unsigned short *fw_on_ctlr_arch_id, 
+                             unsigned short *fw_on_ctlr_branch, 
+                             unsigned short *fw_on_ctlr_build, 
+                             u32 *init_connect_result);
+static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length);
+static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds);
+static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds);
+static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal);
+static int twa_reset_device_extension(TW_Device_Extension *tw_dev);
+static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset);
+static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Apache *sglistarg);
+static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id);
+static char *twa_string_lookup(twa_message_type *table, unsigned int aen_code);
+static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id);
+
+/* Functions */
+
+/* Show some statistics about the card */
+static ssize_t twa_show_stats(struct class_device *class_dev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(class_dev);
+       TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
+       unsigned long flags = 0;
+       ssize_t len;
+
+       spin_lock_irqsave(tw_dev->host->host_lock, flags);
+       len = snprintf(buf, PAGE_SIZE, "Driver version: %s\n"
+                      "Current commands posted:   %4d\n"
+                      "Max commands posted:       %4d\n"
+                      "Current pending commands:  %4d\n"
+                      "Max pending commands:      %4d\n"
+                      "Last sgl length:           %4d\n"
+                      "Max sgl length:            %4d\n"
+                      "Last sector count:         %4d\n"
+                      "Max sector count:          %4d\n"
+                      "SCSI Host Resets:          %4d\n"
+                      "SCSI Aborts/Timeouts:      %4d\n"
+                      "AEN's:                     %4d\n", 
+                      twa_driver_version,
+                      tw_dev->posted_request_count,
+                      tw_dev->max_posted_request_count,
+                      tw_dev->pending_request_count,
+                      tw_dev->max_pending_request_count,
+                      tw_dev->sgl_entries,
+                      tw_dev->max_sgl_entries,
+                      tw_dev->sector_count,
+                      tw_dev->max_sector_count,
+                      tw_dev->num_resets,
+                      tw_dev->num_aborts,
+                      tw_dev->aen_count);
+       spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
+       return len;
+} /* End twa_show_stats() */
+
+/* This function will set a devices queue depth */
+static ssize_t twa_store_queue_depth(struct device *dev, const char *buf, size_t count)
+{
+       int queue_depth;
+       struct scsi_device *sdev = to_scsi_device(dev);
+
+       queue_depth = simple_strtoul(buf, NULL, 0);
+       if (queue_depth > TW_Q_LENGTH-2)
+               return -EINVAL;
+       scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
+
+       return count;
+} /* End twa_store_queue_depth() */
+
+/* Create sysfs 'queue_depth' entry */
+static struct device_attribute twa_queue_depth_attr = {
+       .attr = {
+               .name =         "queue_depth",
+               .mode =         S_IRUSR | S_IWUSR,
+       },
+       .store = twa_store_queue_depth
+};
+
+/* Device attributes initializer */
+static struct device_attribute *twa_dev_attrs[] = {
+       &twa_queue_depth_attr,
+       NULL,
+};
+
+/* Create sysfs 'stats' entry */
+static struct class_device_attribute twa_host_stats_attr = {
+       .attr = {
+               .name =         "stats",
+               .mode =         S_IRUGO,
+       },
+       .show = twa_show_stats
+};
+
+/* Host attributes initializer */
+static struct class_device_attribute *twa_host_attrs[] = {
+       &twa_host_stats_attr,
+       NULL,
+};
+
+/* File operations struct for character device */
+static struct file_operations twa_fops = {
+       .owner          = THIS_MODULE,
+       .ioctl          = twa_chrdev_ioctl,
+       .open           = twa_chrdev_open,
+       .release        = NULL
+};
+
+/* This function will complete an aen request from the isr */
+static int twa_aen_complete(TW_Device_Extension *tw_dev, int request_id)
+{
+       TW_Command_Full *full_command_packet;
+       TW_Command *command_packet;
+       TW_Command_Apache_Header *header;
+       unsigned short aen;
+       int retval = 1;
+
+       header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
+       tw_dev->posted_request_count--;
+       aen = header->status_block.error;
+       full_command_packet = tw_dev->command_packet_virt[request_id];
+       command_packet = &full_command_packet->command.oldcommand;
+
+       /* First check for internal completion of set param for time sync */
+       if (TW_OP_OUT(command_packet->opcode__sgloffset) == TW_OP_SET_PARAM) {
+               /* Keep reading the queue in case there are more aen's */
+               if (twa_aen_read_queue(tw_dev, request_id))
+                       goto out2;
+               else {
+                       retval = 0;
+                       goto out;
+               }
+       }
+
+       switch (aen) {
+       case TW_AEN_QUEUE_EMPTY:
+               /* Quit reading the queue if this is the last one */
+               break;
+       case TW_AEN_SYNC_TIME_WITH_HOST:
+               twa_aen_sync_time(tw_dev, request_id);
+               retval = 0;
+               goto out;
+       default:
+               twa_aen_queue_event(tw_dev, header);
+
+               /* If there are more aen's, keep reading the queue */
+               if (twa_aen_read_queue(tw_dev, request_id))
+                       goto out2;
+               else {
+                       retval = 0;
+                       goto out;
+               }
+       }
+       retval = 0;
+out2:
+       tw_dev->state[request_id] = TW_S_COMPLETED;
+       twa_free_request_id(tw_dev, request_id);
+       clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
+out:
+       return retval;
+} /* End twa_aen_complete() */
+
+/* This function will drain aen queue */
+static int twa_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
+{
+       int request_id = 0;
+       char cdb[TW_MAX_CDB_LEN];
+       TW_SG_Apache sglist[1];
+       int finished = 0, count = 0;
+       TW_Command_Full *full_command_packet;
+       TW_Command_Apache_Header *header;
+       unsigned short aen;
+       int first_reset = 0, queue = 0, retval = 1;
+
+       if (no_check_reset)
+               first_reset = 0;
+       else
+               first_reset = 1;
+
+       full_command_packet = tw_dev->command_packet_virt[request_id];
+       memset(full_command_packet, 0, sizeof(TW_Command_Full));
+
+       /* Initialize cdb */
+       memset(&cdb, 0, TW_MAX_CDB_LEN);
+       cdb[0] = REQUEST_SENSE; /* opcode */
+       cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
+
+       /* Initialize sglist */
+       memset(&sglist, 0, sizeof(TW_SG_Apache));
+       sglist[0].length = TW_SECTOR_SIZE;
+       sglist[0].address = tw_dev->generic_buffer_phys[request_id];
+
+       if (sglist[0].address & TW_ALIGNMENT_9000_SGL) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1, "Found unaligned address during AEN drain");
+               goto out;
+       }
+
+       /* Mark internal command */
+       tw_dev->srb[request_id] = NULL;
+
+       do {
+               /* Send command to the board */
+               if (twa_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
+                       TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2, "Error posting request sense");
+                       goto out;
+               }
+
+               /* Now poll for completion */
+               if (twa_poll_response(tw_dev, request_id, 30)) {
+                       TW_PRINTK(tw_dev->host, TW_DRIVER, 0x3, "No valid response while draining AEN queue");
+                       tw_dev->posted_request_count--;
+                       goto out;
+               }
+
+               tw_dev->posted_request_count--;
+               header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
+               aen = header->status_block.error;
+               queue = 0;
+               count++;
+
+               switch (aen) {
+               case TW_AEN_QUEUE_EMPTY:
+                       if (first_reset != 1)
+                               goto out;
+                       else
+                               finished = 1;
+                       break;
+               case TW_AEN_SOFT_RESET:
+                       if (first_reset == 0)
+                               first_reset = 1;
+                       else
+                               queue = 1;
+                       break;
+               case TW_AEN_SYNC_TIME_WITH_HOST:
+                       break;
+               default:
+                       queue = 1;
+               }
+
+               /* Now queue an event info */
+               if (queue)
+                       twa_aen_queue_event(tw_dev, header);
+       } while ((finished == 0) && (count < TW_MAX_AEN_DRAIN));
+
+       if (count == TW_MAX_AEN_DRAIN)
+               goto out;
+
+       retval = 0;
+out:
+       tw_dev->state[request_id] = TW_S_INITIAL;
+       return retval;
+} /* End twa_aen_drain_queue() */
+
+/* This function will queue an event */
+static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
+{
+       u32 local_time;
+       struct timeval time;
+       TW_Event *event;
+       unsigned short aen;
+       char host[16];
+
+       tw_dev->aen_count++;
+
+       /* Fill out event info */
+       event = tw_dev->event_queue[tw_dev->error_index];
+
+       /* Check for clobber */
+       host[0] = '\0';
+       if (tw_dev->host) {
+               sprintf(host, " scsi%d:", tw_dev->host->host_no);
+               if (event->retrieved == TW_AEN_NOT_RETRIEVED)
+                       tw_dev->aen_clobber = 1;
+       }
+
+       aen = header->status_block.error;
+       memset(event, 0, sizeof(TW_Event));
+
+       event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
+       do_gettimeofday(&time);
+       local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
+       event->time_stamp_sec = local_time;
+       event->aen_code = aen;
+       event->retrieved = TW_AEN_NOT_RETRIEVED;
+       event->sequence_id = tw_dev->error_sequence_id;
+       tw_dev->error_sequence_id++;
+
+       header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0';
+       event->parameter_len = strlen(header->err_specific_desc);
+       memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len);
+       if (event->severity != TW_AEN_SEVERITY_DEBUG)
+               printk(KERN_WARNING "3w-9xxx:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n",
+                      host,
+                      twa_aen_severity_lookup(TW_SEV_OUT(header->status_block.severity__reserved)),
+                      TW_MESSAGE_SOURCE_CONTROLLER_EVENT, aen,
+                      twa_string_lookup(twa_aen_table, aen),
+                      header->err_specific_desc);
+       else
+               tw_dev->aen_count--;
+
+       if ((tw_dev->error_index + 1) == TW_Q_LENGTH)
+               tw_dev->event_queue_wrapped = 1;
+       tw_dev->error_index = (tw_dev->error_index + 1 ) % TW_Q_LENGTH;
+} /* End twa_aen_queue_event() */
+
+/* This function will read the aen queue from the isr */
+static int twa_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
+{
+       char cdb[TW_MAX_CDB_LEN];
+       TW_SG_Apache sglist[1];
+       TW_Command_Full *full_command_packet;
+       int retval = 1;
+
+       full_command_packet = tw_dev->command_packet_virt[request_id];
+       memset(full_command_packet, 0, sizeof(TW_Command_Full));
+
+       /* Initialize cdb */
+       memset(&cdb, 0, TW_MAX_CDB_LEN);
+       cdb[0] = REQUEST_SENSE; /* opcode */
+       cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
+
+       /* Initialize sglist */
+       memset(&sglist, 0, sizeof(TW_SG_Apache));
+       sglist[0].length = TW_SECTOR_SIZE;
+       sglist[0].address = tw_dev->generic_buffer_phys[request_id];
+
+       /* Mark internal command */
+       tw_dev->srb[request_id] = NULL;
+
+       /* Now post the command packet */
+       if (twa_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x4, "Post failed while reading AEN queue");
+               goto out;
+       }
+       retval = 0;
+out:
+       return retval;
+} /* End twa_aen_read_queue() */
+
+/* This function will look up an AEN severity string */
+static char *twa_aen_severity_lookup(unsigned char severity_code)
+{
+       char *retval = NULL;
+
+       if ((severity_code < (unsigned char) TW_AEN_SEVERITY_ERROR) ||
+           (severity_code > (unsigned char) TW_AEN_SEVERITY_DEBUG))
+               goto out;
+
+       retval = twa_aen_severity_table[severity_code];
+out:
+       return retval;
+} /* End twa_aen_severity_lookup() */
+
+/* This function will sync firmware time with the host time */
+static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
+{
+       u32 schedulertime;
+       struct timeval utc;
+       TW_Command_Full *full_command_packet;
+       TW_Command *command_packet;
+       TW_Param_Apache *param;
+       u32 local_time;
+
+       /* Fill out the command packet */
+       full_command_packet = tw_dev->command_packet_virt[request_id];
+       memset(full_command_packet, 0, sizeof(TW_Command_Full));
+       command_packet = &full_command_packet->command.oldcommand;
+       command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
+       command_packet->request_id = request_id;
+       command_packet->byte8_offset.param.sgl[0].address = tw_dev->generic_buffer_phys[request_id];
+       command_packet->byte8_offset.param.sgl[0].length = TW_SECTOR_SIZE;
+       command_packet->size = TW_COMMAND_SIZE;
+       command_packet->byte6_offset.parameter_count = 1;
+
+       /* Setup the param */
+       param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
+       memset(param, 0, TW_SECTOR_SIZE);
+       param->table_id = TW_TIMEKEEP_TABLE | 0x8000; /* Controller time keep table */
+       param->parameter_id = 0x3; /* SchedulerTime */
+       param->parameter_size_bytes = 4;
+
+       /* Convert system time in UTC to local time seconds since last 
+           Sunday 12:00AM */
+       do_gettimeofday(&utc);
+       local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
+       schedulertime = local_time - (3 * 86400);
+       schedulertime = schedulertime % 604800;
+
+       memcpy(param->data, &schedulertime, sizeof(u32));
+
+       /* Mark internal command */
+       tw_dev->srb[request_id] = NULL;
+
+       /* Now post the command */
+       twa_post_command_packet(tw_dev, request_id, 1);
+} /* End twa_aen_sync_time() */
+
+/* This function will allocate memory and check if it is correctly aligned */
+static int twa_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
+{
+       int i;
+       dma_addr_t dma_handle;
+       unsigned long *cpu_addr;
+       int retval = 1;
+
+       cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, &dma_handle);
+       if (!cpu_addr) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x5, "Memory allocation failed");
+               goto out;
+       }
+
+       if ((unsigned long)cpu_addr % (TW_ALIGNMENT_9000)) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x6, "Failed to allocate correctly aligned memory");
+               pci_free_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, cpu_addr, dma_handle);
+               goto out;
+       }
+
+       memset(cpu_addr, 0, size*TW_Q_LENGTH);
+
+       for (i = 0; i < TW_Q_LENGTH; i++) {
+               switch(which) {
+               case 0:
+                       tw_dev->command_packet_phys[i] = dma_handle+(i*size);
+                       tw_dev->command_packet_virt[i] = (TW_Command_Full *)((unsigned char *)cpu_addr + (i*size));
+                       break;
+               case 1:
+                       tw_dev->generic_buffer_phys[i] = dma_handle+(i*size);
+                       tw_dev->generic_buffer_virt[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
+                       break;
+               }
+       }
+       retval = 0;
+out:
+       return retval;
+} /* End twa_allocate_memory() */
+
+/* This function will check the status register for unexpected bits */
+static int twa_check_bits(u32 status_reg_value)
+{
+       int retval = 1;
+
+       if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS)
+               goto out;
+       if ((status_reg_value & TW_STATUS_UNEXPECTED_BITS) != 0)
+               goto out;
+
+       retval = 0;
+out:
+       return retval;
+} /* End twa_check_bits() */
+
+/* This function will check the srl and decide if we are compatible  */
+static int twa_check_srl(TW_Device_Extension *tw_dev, int *flashed)
+{
+       int retval = 1;
+       unsigned short fw_on_ctlr_srl = 0, fw_on_ctlr_arch_id = 0;
+       unsigned short fw_on_ctlr_branch = 0, fw_on_ctlr_build = 0;
+       u32 init_connect_result = 0;
+
+       if (twa_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS,
+                              TW_EXTENDED_INIT_CONNECT, TW_CURRENT_FW_SRL,
+                              TW_9000_ARCH_ID, TW_CURRENT_FW_BRANCH,
+                              TW_CURRENT_FW_BUILD, &fw_on_ctlr_srl,
+                              &fw_on_ctlr_arch_id, &fw_on_ctlr_branch,
+                              &fw_on_ctlr_build, &init_connect_result)) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x7, "Initconnection failed while checking SRL");
+               goto out;
+       }
+
+       tw_dev->working_srl = TW_CURRENT_FW_SRL;
+       tw_dev->working_branch = TW_CURRENT_FW_BRANCH;
+       tw_dev->working_build = TW_CURRENT_FW_BUILD;
+
+       /* Try base mode compatibility */
+       if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) {
+               if (twa_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS,
+                                      TW_EXTENDED_INIT_CONNECT,
+                                      TW_BASE_FW_SRL, TW_9000_ARCH_ID,
+                                      TW_BASE_FW_BRANCH, TW_BASE_FW_BUILD,
+                                      &fw_on_ctlr_srl, &fw_on_ctlr_arch_id,
+                                      &fw_on_ctlr_branch, &fw_on_ctlr_build,
+                                      &init_connect_result)) {
+                       TW_PRINTK(tw_dev->host, TW_DRIVER, 0xa, "Initconnection (base mode) failed while checking SRL");
+                       goto out;
+               }
+               if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) {
+                       if (TW_CURRENT_FW_SRL > fw_on_ctlr_srl) {
+                               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x32, "Firmware and driver incompatibility: please upgrade firmware");
+                       } else {
+                               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x33, "Firmware and driver incompatibility: please upgrade driver");
+                       }
+                       goto out;
+               }
+               tw_dev->working_srl = TW_BASE_FW_SRL;
+               tw_dev->working_branch = TW_BASE_FW_BRANCH;
+               tw_dev->working_build = TW_BASE_FW_BUILD;
+       }
+       retval = 0;
+out:
+       return retval;
+} /* End twa_check_srl() */
+
+/* This function handles ioctl for the character device */
+static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+       long timeout;
+       unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0;
+       dma_addr_t dma_handle;
+       int request_id = 0;
+       unsigned int sequence_id = 0;
+       unsigned char event_index, start_index;
+       TW_Ioctl_Driver_Command driver_command;
+       TW_Ioctl_Buf_Apache *tw_ioctl;
+       TW_Lock *tw_lock;
+       TW_Command_Full *full_command_packet;
+       TW_Compatibility_Info *tw_compat_info;
+       TW_Event *event;
+       struct timeval current_time;
+       u32 current_time_ms;
+       TW_Device_Extension *tw_dev = twa_device_extension_list[iminor(inode)];
+       int retval = TW_IOCTL_ERROR_OS_EFAULT;
+
+       /* Only let one of these through at a time */
+       if (down_interruptible(&tw_dev->ioctl_sem)) {
+               retval = TW_IOCTL_ERROR_OS_EINTR;
+               goto out;
+       }
+
+       /* First copy down the driver command */
+       if (copy_from_user(&driver_command, (void *)arg, sizeof(TW_Ioctl_Driver_Command)))
+               goto out2;
+
+       /* Check data buffer size */
+       if (driver_command.buffer_length > TW_MAX_SECTORS * 512) {
+               retval = TW_IOCTL_ERROR_OS_EINVAL;
+               goto out2;
+       }
+
+       /* Hardware can only do multiple of 512 byte transfers */
+       data_buffer_length_adjusted = (driver_command.buffer_length + 511) & ~511;
+
+       /* Now allocate ioctl buf memory */
+       cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, &dma_handle);
+       if (!cpu_addr) {
+               retval = TW_IOCTL_ERROR_OS_ENOMEM;
+               goto out2;
+       }
+
+       tw_ioctl = (TW_Ioctl_Buf_Apache *)cpu_addr;
+
+       /* Now copy down the entire ioctl */
+       if (copy_from_user(tw_ioctl, (void *)arg, driver_command.buffer_length + sizeof(TW_Ioctl_Buf_Apache) - 1))
+               goto out3;
+
+       /* See which ioctl we are doing */
+       switch (cmd) {
+       case TW_IOCTL_FIRMWARE_PASS_THROUGH:
+               spin_lock_irqsave(tw_dev->host->host_lock, flags);
+               twa_get_request_id(tw_dev, &request_id);
+
+               /* Flag internal command */
+               tw_dev->srb[request_id] = 0;
+
+               /* Flag chrdev ioctl */
+               tw_dev->chrdev_request_id = request_id;
+
+               full_command_packet = &tw_ioctl->firmware_command;
+
+               /* Load request id and sglist for both command types */
+               twa_load_sgl(full_command_packet, request_id, dma_handle, data_buffer_length_adjusted);
+
+               memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full));
+
+               /* Now post the command packet to the controller */
+               twa_post_command_packet(tw_dev, request_id, 1);
+               spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
+
+               timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
+
+               /* Now wait for command to complete */
+               timeout = wait_event_interruptible_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
+
+               /* Check if we timed out, got a signal, or didn't get
+                   an interrupt */
+               if ((timeout <= 0) && (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE)) {
+                       /* Now we need to reset the board */
+                       if (timeout == TW_IOCTL_ERROR_OS_ERESTARTSYS) {
+                               retval = timeout;
+                       } else {
+                               printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n",
+                                      tw_dev->host->host_no, TW_DRIVER, 0xc,
+                                      cmd);
+                               retval = TW_IOCTL_ERROR_OS_EIO;
+                       }
+                       spin_lock_irqsave(tw_dev->host->host_lock, flags);
+                       tw_dev->state[request_id] = TW_S_COMPLETED;
+                       twa_free_request_id(tw_dev, request_id);
+                       tw_dev->posted_request_count--;
+                       twa_reset_device_extension(tw_dev);
+                       spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
+                       goto out3;
+               }
+
+               /* Now copy in the command packet response */
+               memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_Full));
+               
+               /* Now complete the io */
+               spin_lock_irqsave(tw_dev->host->host_lock, flags);
+               tw_dev->posted_request_count--;
+               tw_dev->state[request_id] = TW_S_COMPLETED;
+               twa_free_request_id(tw_dev, request_id);
+               spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
+               break;
+       case TW_IOCTL_GET_COMPATIBILITY_INFO:
+               tw_ioctl->driver_command.status = 0;
+               /* Copy compatiblity struct into ioctl data buffer */
+               tw_compat_info = (TW_Compatibility_Info *)tw_ioctl->data_buffer;
+               strncpy(tw_compat_info->driver_version, twa_driver_version, strlen(twa_driver_version));
+               tw_compat_info->working_srl = tw_dev->working_srl;
+               tw_compat_info->working_branch = tw_dev->working_branch;
+               tw_compat_info->working_build = tw_dev->working_build;
+               break;
+       case TW_IOCTL_GET_LAST_EVENT:
+               if (tw_dev->event_queue_wrapped) {
+                       if (tw_dev->aen_clobber) {
+                               tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
+                               tw_dev->aen_clobber = 0;
+                       } else
+                               tw_ioctl->driver_command.status = 0;
+               } else {
+                       if (!tw_dev->error_index) {
+                               tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
+                               break;
+                       }
+                       tw_ioctl->driver_command.status = 0;
+               }
+               event_index = (tw_dev->error_index - 1 + TW_Q_LENGTH) % TW_Q_LENGTH;
+               memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event));
+               tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED;
+               break;
+       case TW_IOCTL_GET_FIRST_EVENT:
+               if (tw_dev->event_queue_wrapped) {
+                       if (tw_dev->aen_clobber) {
+                               tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
+                               tw_dev->aen_clobber = 0;
+                       } else 
+                               tw_ioctl->driver_command.status = 0;
+                       event_index = tw_dev->error_index;
+               } else {
+                       if (!tw_dev->error_index) {
+                               tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
+                               break;
+                       }
+                       tw_ioctl->driver_command.status = 0;
+                       event_index = 0;
+               }
+               memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event));
+               tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED;
+               break;
+       case TW_IOCTL_GET_NEXT_EVENT:
+               event = (TW_Event *)tw_ioctl->data_buffer;
+               sequence_id = event->sequence_id;
+               tw_ioctl->driver_command.status = 0;
+
+               if (tw_dev->event_queue_wrapped) {
+                       if (tw_dev->aen_clobber) {
+                               tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
+                               tw_dev->aen_clobber = 0;
+                       }
+                       start_index = tw_dev->error_index;
+               } else {
+                       if (!tw_dev->error_index) {
+                               tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
+                               break;
+                       }
+                       start_index = 0;
+               }
+               event_index = (start_index + sequence_id - tw_dev->event_queue[start_index]->sequence_id + 1) % TW_Q_LENGTH;
+
+               if (!(tw_dev->event_queue[event_index]->sequence_id > sequence_id)) {
+                       if (tw_ioctl->driver_command.status == TW_IOCTL_ERROR_STATUS_AEN_CLOBBER)
+                               tw_dev->aen_clobber = 1;
+                       tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
+                       break;
+               }
+               memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event));
+               tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED;
+               break;
+       case TW_IOCTL_GET_PREVIOUS_EVENT:
+               event = (TW_Event *)tw_ioctl->data_buffer;
+               sequence_id = event->sequence_id;
+               tw_ioctl->driver_command.status = 0;
+
+               if (tw_dev->event_queue_wrapped) {
+                       if (tw_dev->aen_clobber) {
+                               tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
+                               tw_dev->aen_clobber = 0;
+                       }
+                       start_index = tw_dev->error_index;
+               } else {
+                       if (!tw_dev->error_index) {
+                               tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
+                               break;
+                       }
+                       start_index = 0;
+               }
+               event_index = (start_index + sequence_id - tw_dev->event_queue[start_index]->sequence_id - 1) % TW_Q_LENGTH;
+
+               if (!(tw_dev->event_queue[event_index]->sequence_id < sequence_id)) {
+                       if (tw_ioctl->driver_command.status == TW_IOCTL_ERROR_STATUS_AEN_CLOBBER)
+                               tw_dev->aen_clobber = 1;
+                       tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
+                       break;
+               }
+               memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event));
+               tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED;
+               break;
+       case TW_IOCTL_GET_LOCK:
+               tw_lock = (TW_Lock *)tw_ioctl->data_buffer;
+               do_gettimeofday(&current_time);
+               current_time_ms = (current_time.tv_sec * 1000) + (current_time.tv_usec / 1000);
+
+               if ((tw_lock->force_flag == 1) || (tw_dev->ioctl_sem_lock == 0) || (current_time_ms >= tw_dev->ioctl_msec)) {
+                       tw_dev->ioctl_sem_lock = 1;
+                       tw_dev->ioctl_msec = current_time_ms + tw_lock->timeout_msec;
+                       tw_ioctl->driver_command.status = 0;
+                       tw_lock->time_remaining_msec = tw_lock->timeout_msec;
+               } else {
+                       tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_LOCKED;
+                       tw_lock->time_remaining_msec = tw_dev->ioctl_msec - current_time_ms;
+               }
+               break;
+       case TW_IOCTL_RELEASE_LOCK:
+               if (tw_dev->ioctl_sem_lock == 1) {
+                       tw_dev->ioctl_sem_lock = 0;
+                       tw_ioctl->driver_command.status = 0;
+               } else {
+                       tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NOT_LOCKED;
+               }
+               break;
+       default:
+               retval = TW_IOCTL_ERROR_OS_ENOTTY;
+               goto out3;
+       }
+
+       /* Now copy the entire response to userspace */
+       if (copy_to_user((void *)arg, tw_ioctl, sizeof(TW_Ioctl_Buf_Apache) + driver_command.buffer_length - 1) == 0)
+               retval = 0;
+out3:
+       /* Now free ioctl buf memory */
+       pci_free_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, cpu_addr, dma_handle);
+out2:
+       up(&tw_dev->ioctl_sem);
+out:
+       return retval;
+} /* End twa_chrdev_ioctl() */
+
+/* This function handles open for the character device */
+static int twa_chrdev_open(struct inode *inode, struct file *file)
+{
+       unsigned int minor_number;
+       int retval = TW_IOCTL_ERROR_OS_ENODEV;
+
+       minor_number = iminor(inode);
+       if (minor_number >= twa_device_extension_count)
+               goto out;
+       retval = 0;
+out:
+       return retval;
+} /* End twa_chrdev_open() */
+
+/* This function will print readable messages from status register errors */
+static int twa_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value)
+{
+       int retval = 1;
+
+       /* Check for various error conditions and handle them appropriately */
+       if (status_reg_value & TW_STATUS_PCI_PARITY_ERROR) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0xc, "PCI Parity Error: clearing");
+               writel(TW_CONTROL_CLEAR_PARITY_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
+       }
+
+       if (status_reg_value & TW_STATUS_PCI_ABORT) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0xd, "PCI Abort: clearing");
+               writel(TW_CONTROL_CLEAR_PCI_ABORT, TW_CONTROL_REG_ADDR(tw_dev));
+               pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PCI_ABORT);
+       }
+
+       if (status_reg_value & TW_STATUS_QUEUE_ERROR) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing");
+               writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
+       }
+
+       if (status_reg_value & TW_STATUS_SBUF_WRITE_ERROR) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0xf, "SBUF Write Error: clearing");
+               writel(TW_CONTROL_CLEAR_SBUF_WRITE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
+       }
+
+       if (status_reg_value & TW_STATUS_MICROCONTROLLER_ERROR) {
+               if (tw_dev->reset_print == 0) {
+                       TW_PRINTK(tw_dev->host, TW_DRIVER, 0x10, "Microcontroller Error: clearing");
+                       tw_dev->reset_print = 1;
+               }
+               goto out;
+       }
+       retval = 0;
+out:
+       return retval;
+} /* End twa_decode_bits() */
+
+/* This function will empty the response queue */
+static int twa_empty_response_queue(TW_Device_Extension *tw_dev)
+{
+       u32 status_reg_value, response_que_value;
+       int count = 0, retval = 1;
+
+       status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
+
+       while (((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) && (count < TW_MAX_RESPONSE_DRAIN)) {
+               response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
+               status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
+               count++;
+       }
+       if (count == TW_MAX_RESPONSE_DRAIN)
+               goto out;
+
+       retval = 0;
+out:
+       return retval;
+} /* End twa_empty_response_queue() */
+
+/* This function passes sense keys from firmware to scsi layer */
+static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_sense, int print_host)
+{
+       TW_Command_Full *full_command_packet;
+       unsigned short error;
+       int retval = 1;
+
+       full_command_packet = tw_dev->command_packet_virt[request_id];
+       /* Don't print error for Logical unit not supported during rollcall */
+       error = full_command_packet->header.status_block.error;
+       if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE)) {
+               if (print_host)
+                       printk(KERN_WARNING "3w-9xxx: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n",
+                              tw_dev->host->host_no,
+                              TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
+                              full_command_packet->header.status_block.error,
+                              twa_string_lookup(twa_error_table,
+                                                full_command_packet->header.status_block.error),
+                              full_command_packet->header.err_specific_desc);
+               else
+                       printk(KERN_WARNING "3w-9xxx: ERROR: (0x%02X:0x%04X): %s:%s.\n",
+                              TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
+                              full_command_packet->header.status_block.error,
+                              twa_string_lookup(twa_error_table,
+                                                full_command_packet->header.status_block.error),
+                              full_command_packet->header.err_specific_desc);
+       }
+
+       if (copy_sense) {
+               memcpy(tw_dev->srb[request_id]->sense_buffer, full_command_packet->header.sense_data, TW_SENSE_DATA_LENGTH);
+               tw_dev->srb[request_id]->result = (full_command_packet->command.newcommand.status << 1);
+               retval = TW_ISR_DONT_RESULT;
+               goto out;
+       }
+       retval = 0;
+out:
+       return retval;
+} /* End twa_fill_sense() */
+
+/* This function will free up device extension resources */
+static void twa_free_device_extension(TW_Device_Extension *tw_dev)
+{
+       if (tw_dev->command_packet_virt[0])
+               pci_free_consistent(tw_dev->tw_pci_dev,
+                                   sizeof(TW_Command_Full)*TW_Q_LENGTH,
+                                   tw_dev->command_packet_virt[0],
+                                   tw_dev->command_packet_phys[0]);
+
+       if (tw_dev->generic_buffer_virt[0])
+               pci_free_consistent(tw_dev->tw_pci_dev,
+                                   TW_SECTOR_SIZE*TW_Q_LENGTH,
+                                   tw_dev->generic_buffer_virt[0],
+                                   tw_dev->generic_buffer_phys[0]);
+
+       if (tw_dev->event_queue[0])
+               kfree(tw_dev->event_queue[0]);
+} /* End twa_free_device_extension() */
+
+/* This function will free a request id */
+static void twa_free_request_id(TW_Device_Extension *tw_dev, int request_id)
+{
+       tw_dev->free_queue[tw_dev->free_tail] = request_id;
+       tw_dev->state[request_id] = TW_S_FINISHED;
+       tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
+} /* End twa_free_request_id() */
+
+/* This function will get parameter table entires from the firmware */
+static void *twa_get_param(TW_Device_Extension *tw_dev, int request_id, int table_id, int parameter_id, int parameter_size_bytes)
+{
+       TW_Command_Full *full_command_packet;
+       TW_Command *command_packet;
+       TW_Param_Apache *param;
+       unsigned long param_value;
+       void *retval = NULL;
+
+       /* Setup the command packet */
+       full_command_packet = tw_dev->command_packet_virt[request_id];
+       memset(full_command_packet, 0, sizeof(TW_Command_Full));
+       command_packet = &full_command_packet->command.oldcommand;
+
+       command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
+       command_packet->size              = TW_COMMAND_SIZE;
+       command_packet->request_id        = request_id;
+       command_packet->byte6_offset.block_count = 1;
+
+       /* Now setup the param */
+       param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
+       memset(param, 0, TW_SECTOR_SIZE);
+       param->table_id = table_id | 0x8000;
+       param->parameter_id = parameter_id;
+       param->parameter_size_bytes = parameter_size_bytes;
+       param_value = tw_dev->generic_buffer_phys[request_id];
+
+       command_packet->byte8_offset.param.sgl[0].address = param_value;
+       command_packet->byte8_offset.param.sgl[0].length = TW_SECTOR_SIZE;
+
+       /* Post the command packet to the board */
+       twa_post_command_packet(tw_dev, request_id, 1);
+
+       /* Poll for completion */
+       if (twa_poll_response(tw_dev, request_id, 30))
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x13, "No valid response during get param")
+       else
+               retval = (void *)&(param->data[0]);
+
+       tw_dev->posted_request_count--;
+       tw_dev->state[request_id] = TW_S_INITIAL;
+
+       return retval;
+} /* End twa_get_param() */
+
+/* This function will assign an available request id */
+static void twa_get_request_id(TW_Device_Extension *tw_dev, int *request_id)
+{
+       *request_id = tw_dev->free_queue[tw_dev->free_head];
+       tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
+       tw_dev->state[*request_id] = TW_S_STARTED;
+} /* End twa_get_request_id() */
+
+/* This function will send an initconnection command to controller */
+static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits,
+                             u32 set_features, unsigned short current_fw_srl, 
+                             unsigned short current_fw_arch_id, 
+                             unsigned short current_fw_branch, 
+                             unsigned short current_fw_build, 
+                             unsigned short *fw_on_ctlr_srl, 
+                             unsigned short *fw_on_ctlr_arch_id, 
+                             unsigned short *fw_on_ctlr_branch, 
+                             unsigned short *fw_on_ctlr_build, 
+                             u32 *init_connect_result)
+{
+       TW_Command_Full *full_command_packet;
+       TW_Initconnect *tw_initconnect;
+       int request_id = 0, retval = 1;
+
+       /* Initialize InitConnection command packet */
+       full_command_packet = tw_dev->command_packet_virt[request_id];
+       memset(full_command_packet, 0, sizeof(TW_Command_Full));
+       full_command_packet->header.header_desc.size_header = 128;
+       
+       tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand;
+       tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION);
+       tw_initconnect->request_id = request_id;
+       tw_initconnect->message_credits = message_credits;
+       tw_initconnect->features = set_features;
+#if BITS_PER_LONG > 32
+       /* Turn on 64-bit sgl support */
+       tw_initconnect->features |= 1;
+#endif
+
+       if (set_features & TW_EXTENDED_INIT_CONNECT) {
+               tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED;
+               tw_initconnect->fw_srl = current_fw_srl;
+               tw_initconnect->fw_arch_id = current_fw_arch_id;
+               tw_initconnect->fw_branch = current_fw_branch;
+               tw_initconnect->fw_build = current_fw_build;
+       } else 
+               tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE;
+
+       /* Send command packet to the board */
+       twa_post_command_packet(tw_dev, request_id, 1);
+
+       /* Poll for completion */
+       if (twa_poll_response(tw_dev, request_id, 30)) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "No valid response during init connection");
+       } else {
+               if (set_features & TW_EXTENDED_INIT_CONNECT) {
+                       *fw_on_ctlr_srl = tw_initconnect->fw_srl;
+                       *fw_on_ctlr_arch_id = tw_initconnect->fw_arch_id;
+                       *fw_on_ctlr_branch = tw_initconnect->fw_branch;
+                       *fw_on_ctlr_build = tw_initconnect->fw_build;
+                       *init_connect_result = tw_initconnect->result;
+               }
+               retval = 0;
+       }
+
+       tw_dev->posted_request_count--;
+       tw_dev->state[request_id] = TW_S_INITIAL;
+
+       return retval;
+} /* End twa_initconnection() */
+
+/* This function will initialize the fields of a device extension */
+static int twa_initialize_device_extension(TW_Device_Extension *tw_dev)
+{
+       int i, retval = 1;
+
+       /* Initialize command packet buffers */
+       if (twa_allocate_memory(tw_dev, sizeof(TW_Command_Full), 0)) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x16, "Command packet memory allocation failed");
+               goto out;
+       }
+
+       /* Initialize generic buffer */
+       if (twa_allocate_memory(tw_dev, TW_SECTOR_SIZE, 1)) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x17, "Generic memory allocation failed");
+               goto out;
+       }
+
+       /* Allocate event info space */
+       tw_dev->event_queue[0] = kmalloc(sizeof(TW_Event) * TW_Q_LENGTH, GFP_KERNEL);
+       if (!tw_dev->event_queue[0]) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x18, "Event info memory allocation failed");
+               goto out;
+       }
+
+       memset(tw_dev->event_queue[0], 0, sizeof(TW_Event) * TW_Q_LENGTH);
+
+       for (i = 0; i < TW_Q_LENGTH; i++) {
+               tw_dev->event_queue[i] = (TW_Event *)((unsigned char *)tw_dev->event_queue[0] + (i * sizeof(TW_Event)));
+               tw_dev->free_queue[i] = i;
+               tw_dev->state[i] = TW_S_INITIAL;
+       }
+
+       tw_dev->pending_head = TW_Q_START;
+       tw_dev->pending_tail = TW_Q_START;
+       tw_dev->free_head = TW_Q_START;
+       tw_dev->free_tail = TW_Q_START;
+       tw_dev->error_sequence_id = 1;
+       tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
+
+       init_MUTEX(&tw_dev->ioctl_sem);
+       init_waitqueue_head(&tw_dev->ioctl_wqueue);
+
+       retval = 0;
+out:
+       return retval;
+} /* End twa_initialize_device_extension() */
+
+/* This function is the interrupt service routine */
+static irqreturn_t twa_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+{
+       int request_id, error = 0;
+       u32 status_reg_value;
+       TW_Response_Queue response_que;
+       TW_Command_Full *full_command_packet;
+       TW_Command *command_packet;
+       TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
+       int handled = 0;
+
+       /* Get the per adapter lock */
+       spin_lock(tw_dev->host->host_lock);
+
+       /* See if the interrupt matches this instance */
+       if (tw_dev->tw_pci_dev->irq == (unsigned int)irq) {
+
+               handled = 1;
+
+               /* Read the registers */
+               status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
+
+               /* Check if this is our interrupt, otherwise bail */
+               if (!(status_reg_value & TW_STATUS_VALID_INTERRUPT))
+                       goto twa_interrupt_bail;
+
+               /* Check controller for errors */
+               if (twa_check_bits(status_reg_value)) {
+                       if (twa_decode_bits(tw_dev, status_reg_value)) {
+                               TW_CLEAR_ALL_INTERRUPTS(tw_dev);
+                               goto twa_interrupt_bail;
+                       }
+               }
+
+               /* Handle host interrupt */
+               if (status_reg_value & TW_STATUS_HOST_INTERRUPT)
+                       TW_CLEAR_HOST_INTERRUPT(tw_dev);
+
+               /* Handle attention interrupt */
+               if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT) {
+                       TW_CLEAR_ATTENTION_INTERRUPT(tw_dev);
+                       if (!(test_and_set_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags))) {
+                               twa_get_request_id(tw_dev, &request_id);
+
+                               error = twa_aen_read_queue(tw_dev, request_id);
+                               if (error) {
+                                       tw_dev->state[request_id] = TW_S_COMPLETED;
+                                       twa_free_request_id(tw_dev, request_id);
+                                       clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
+                               }
+                       }
+               }
+
+               /* Handle command interrupt */
+               if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT) {
+                       TW_MASK_COMMAND_INTERRUPT(tw_dev);
+                       /* Drain as many pending commands as we can */
+                       while (tw_dev->pending_request_count > 0) {
+                               request_id = tw_dev->pending_queue[tw_dev->pending_head];
+                               if (tw_dev->state[request_id] != TW_S_PENDING) {
+                                       TW_PRINTK(tw_dev->host, TW_DRIVER, 0x19, "Found request id that wasn't pending");
+                                       TW_CLEAR_ALL_INTERRUPTS(tw_dev);
+                                       goto twa_interrupt_bail;
+                               }
+                               if (twa_post_command_packet(tw_dev, request_id, 1)==0) {
+                                       tw_dev->pending_head = (tw_dev->pending_head + 1) % TW_Q_LENGTH;
+                                       tw_dev->pending_request_count--;
+                               } else {
+                                       /* If we get here, we will continue re-posting on the next command interrupt */
+                                       break;
+                               }
+                       }
+               }
+
+               /* Handle response interrupt */
+               if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT) {
+
+                       /* Drain the response queue from the board */
+                       while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
+                               /* Complete the response */
+                               response_que.value = readl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
+                               request_id = TW_RESID_OUT(response_que.response_id);
+                               full_command_packet = tw_dev->command_packet_virt[request_id];
+                               error = 0;
+                               command_packet = &full_command_packet->command.oldcommand;
+                               /* Check for command packet errors */
+                               if (full_command_packet->command.newcommand.status != 0) {
+                                       if (tw_dev->srb[request_id] != 0) {
+                                               error = twa_fill_sense(tw_dev, request_id, 1, 1);
+                                       } else {
+                                               /* Skip ioctl error prints */
+                                               if (request_id != tw_dev->chrdev_request_id) {
+                                                       error = twa_fill_sense(tw_dev, request_id, 0, 1);
+                                               }
+                                       }
+                               }
+
+                               /* Check for correct state */
+                               if (tw_dev->state[request_id] != TW_S_POSTED) {
+                                       if (tw_dev->srb[request_id] != 0) {
+                                               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Received a request id that wasn't posted");
+                                               TW_CLEAR_ALL_INTERRUPTS(tw_dev);
+                                               goto twa_interrupt_bail;
+                                       }
+                               }
+
+                               /* Check for internal command completion */
+                               if (tw_dev->srb[request_id] == 0) {
+                                       if (request_id != tw_dev->chrdev_request_id) {
+                                               if (twa_aen_complete(tw_dev, request_id))
+                                                       TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Error completing AEN during attention interrupt");
+                                       } else {
+                                               tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
+                                               wake_up(&tw_dev->ioctl_wqueue);
+                                       }
+                               } else {
+                                       twa_scsiop_execute_scsi_complete(tw_dev, request_id);
+                                       /* If no error command was a success */
+                                       if (error == 0) {
+                                               tw_dev->srb[request_id]->result = (DID_OK << 16);
+                                       }
+
+                                       /* If error, command failed */
+                                       if (error == 1) {
+                                               /* Ask for a host reset */
+                                               tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
+                                       }
+
+                                       /* Now complete the io */
+                                       tw_dev->state[request_id] = TW_S_COMPLETED;
+                                       twa_free_request_id(tw_dev, request_id);
+                                       tw_dev->posted_request_count--;
+                                       tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+                                       twa_unmap_scsi_data(tw_dev, request_id);
+                               }
+
+                               /* Check for valid status after each drain */
+                               status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
+                               if (twa_check_bits(status_reg_value)) {
+                                       if (twa_decode_bits(tw_dev, status_reg_value)) {
+                                               TW_CLEAR_ALL_INTERRUPTS(tw_dev);
+                                               goto twa_interrupt_bail;
+                                       }
+                               }
+                       }
+               }
+       }
+twa_interrupt_bail:
+       spin_unlock(tw_dev->host->host_lock);
+       return IRQ_RETVAL(handled);
+} /* End twa_interrupt() */
+
+/* This function will load the request id and various sgls for ioctls */
+static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length)
+{
+       TW_Command *oldcommand;
+       TW_Command_Apache *newcommand;
+       TW_SG_Entry *sgl;
+
+       if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
+               newcommand = &full_command_packet->command.newcommand;
+               newcommand->request_id = request_id;
+               newcommand->sg_list[0].address = dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1;
+               newcommand->sg_list[0].length = length;
+       } else {
+               oldcommand = &full_command_packet->command.oldcommand;
+               oldcommand->request_id = request_id;
+
+               if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) {
+                       /* Load the sg list */
+                       sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset));
+                       sgl->address = dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1;
+                       sgl->length = length;
+               }
+       }
+} /* End twa_load_sgl() */
+
+/* This function will perform a pci-dma mapping for a scatter gather list */
+static int twa_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id)
+{
+       int use_sg;
+       struct scsi_cmnd *cmd = tw_dev->srb[request_id];
+       struct pci_dev *pdev = tw_dev->tw_pci_dev;
+       int retval = 0;
+
+       if (cmd->use_sg == 0)
+               goto out;
+
+       use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
+
+       if (use_sg == 0) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to map scatter gather list");
+               goto out;
+       }
+
+       cmd->SCp.phase = TW_PHASE_SGLIST;
+       cmd->SCp.have_data_in = use_sg;
+       retval = use_sg;
+out:
+       return retval;
+} /* End twa_map_scsi_sg_data() */
+
+/* This function will perform a pci-dma map for a single buffer */
+static dma_addr_t twa_map_scsi_single_data(TW_Device_Extension *tw_dev, int request_id)
+{
+       dma_addr_t mapping;
+       struct scsi_cmnd *cmd = tw_dev->srb[request_id];
+       struct pci_dev *pdev = tw_dev->tw_pci_dev;
+       int retval = 0;
+
+       if (cmd->request_bufflen == 0) {
+               retval = 0;
+               goto out;
+       }
+
+       mapping = pci_map_single(pdev, cmd->request_buffer, cmd->request_bufflen, DMA_BIDIRECTIONAL);
+
+       if (mapping == 0) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1d, "Failed to map page");
+               goto out;
+       }
+
+       cmd->SCp.phase = TW_PHASE_SINGLE;
+       cmd->SCp.have_data_in = mapping;
+       retval = mapping;
+out:
+       return retval;
+} /* End twa_map_scsi_single_data() */
+
+/* This function will poll for a response interrupt of a request */
+static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds)
+{
+       int retval = 1, found = 0, response_request_id;
+       TW_Response_Queue response_queue;
+       TW_Command_Full *full_command_packet = tw_dev->command_packet_virt[request_id];
+
+       if (twa_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, seconds) == 0) {
+               response_queue.value = readl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
+               response_request_id = TW_RESID_OUT(response_queue.response_id);
+               if (request_id != response_request_id) {
+                       TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1e, "Found unexpected request id while polling for response");
+                       goto out;
+               }
+               if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
+                       if (full_command_packet->command.newcommand.status != 0) {
+                               /* bad response */
+                               twa_fill_sense(tw_dev, request_id, 0, 0);
+                               goto out;
+                       }
+                       found = 1;
+               } else {
+                       if (full_command_packet->command.oldcommand.status != 0) {
+                               /* bad response */
+                               twa_fill_sense(tw_dev, request_id, 0, 0);
+                               goto out;
+                       }
+                       found = 1;
+               }
+       }
+
+       if (found)
+               retval = 0;
+out:
+       return retval;
+} /* End twa_poll_response() */
+
+/* This function will poll the status register for a flag */
+static int twa_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds)
+{
+       u32 status_reg_value; 
+       unsigned long before;
+       int retval = 1;
+
+       status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
+       before = jiffies;
+
+       if (twa_check_bits(status_reg_value))
+               twa_decode_bits(tw_dev, status_reg_value);
+
+       while ((status_reg_value & flag) != flag) {
+               status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
+
+               if (twa_check_bits(status_reg_value))
+                       twa_decode_bits(tw_dev, status_reg_value);
+
+               if (time_after(jiffies, before + HZ * seconds))
+                       goto out;
+
+               msleep(50);
+       }
+       retval = 0;
+out:
+       return retval;
+} /* End twa_poll_status() */
+
+/* This function will poll the status register for disappearance of a flag */
+static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds)
+{
+       u32 status_reg_value;
+       unsigned long before;
+       int retval = 1;
+
+       status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
+       before = jiffies;
+
+       if (twa_check_bits(status_reg_value))
+               twa_decode_bits(tw_dev, status_reg_value);
+
+       while ((status_reg_value & flag) != 0) {
+               status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
+               if (twa_check_bits(status_reg_value))
+                       twa_decode_bits(tw_dev, status_reg_value);
+
+               if (time_after(jiffies, before + HZ * seconds))
+                       goto out;
+
+               msleep(50);
+       }
+       retval = 0;
+out:
+       return retval;
+} /* End twa_poll_status_gone() */
+
+/* This function will attempt to post a command packet to the board */
+static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal)
+{
+       u32 status_reg_value;
+       unsigned long command_que_value;
+       int retval = 1;
+
+       command_que_value = tw_dev->command_packet_phys[request_id];
+       status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
+
+       if (twa_check_bits(status_reg_value))
+               twa_decode_bits(tw_dev, status_reg_value);
+
+       if (((tw_dev->pending_request_count > 0) && (tw_dev->state[request_id] != TW_S_PENDING)) || (status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL)) {
+
+               /* Only pend internal driver commands */
+               if (!internal) {
+                       retval = SCSI_MLQUEUE_HOST_BUSY;
+                       goto out;
+               }
+
+               /* Couldn't post the command packet, so we do it later */
+               if (tw_dev->state[request_id] != TW_S_PENDING) {
+                       tw_dev->state[request_id] = TW_S_PENDING;
+                       tw_dev->pending_request_count++;
+                       if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) {
+                               tw_dev->max_pending_request_count = tw_dev->pending_request_count;
+                       }
+                       tw_dev->pending_queue[tw_dev->pending_tail] = request_id;
+                       tw_dev->pending_tail = (tw_dev->pending_tail + 1) % TW_Q_LENGTH;
+               }
+               TW_UNMASK_COMMAND_INTERRUPT(tw_dev);
+               goto out;
+       } else {
+               /* We successfully posted the command packet */
+#if BITS_PER_LONG > 32
+               writeq(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
+#else
+               writel(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
+#endif
+               tw_dev->state[request_id] = TW_S_POSTED;
+               tw_dev->posted_request_count++;
+               if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) {
+                       tw_dev->max_posted_request_count = tw_dev->posted_request_count;
+               }
+       }
+       retval = 0;
+out:
+       return retval;
+} /* End twa_post_command_packet() */
+
+/* This function will reset a device extension */
+static int twa_reset_device_extension(TW_Device_Extension *tw_dev)
+{
+       int i = 0;
+       int retval = 1;
+
+       /* Abort all requests that are in progress */
+       for (i = 0; i < TW_Q_LENGTH; i++) {
+               if ((tw_dev->state[i] != TW_S_FINISHED) &&
+                   (tw_dev->state[i] != TW_S_INITIAL) &&
+                   (tw_dev->state[i] != TW_S_COMPLETED)) {
+                       if (tw_dev->srb[i]) {
+                               tw_dev->srb[i]->result = (DID_RESET << 16);
+                               tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
+                               twa_unmap_scsi_data(tw_dev, i);
+                       }
+               }
+       }
+
+       /* Reset queues and counts */
+       for (i = 0; i < TW_Q_LENGTH; i++) {
+               tw_dev->free_queue[i] = i;
+               tw_dev->state[i] = TW_S_INITIAL;
+       }
+       tw_dev->free_head = TW_Q_START;
+       tw_dev->free_tail = TW_Q_START;
+       tw_dev->posted_request_count = 0;
+       tw_dev->pending_request_count = 0;
+       tw_dev->pending_head = TW_Q_START;
+       tw_dev->pending_tail = TW_Q_START;
+       tw_dev->reset_print = 0;
+       tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
+       tw_dev->flags = 0;
+
+       TW_DISABLE_INTERRUPTS(tw_dev);
+
+       if (twa_reset_sequence(tw_dev, 1))
+               goto out;
+
+        TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
+
+       retval = 0;
+out:
+       return retval;
+} /* End twa_reset_device_extension() */
+
+/* This function will reset a controller */
+static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset)
+{
+       int tries = 0, retval = 1, flashed = 0, do_soft_reset = soft_reset;
+
+       while (tries < TW_MAX_RESET_TRIES) {
+               if (do_soft_reset)
+                       TW_SOFT_RESET(tw_dev);
+
+               /* Make sure controller is in a good state */
+               if (twa_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY | (do_soft_reset == 1 ? TW_STATUS_ATTENTION_INTERRUPT : 0), 30)) {
+                       TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1f, "Microcontroller not ready during reset sequence");
+                       do_soft_reset = 1;
+                       tries++;
+                       continue;
+               }
+
+               /* Empty response queue */
+               if (twa_empty_response_queue(tw_dev)) {
+                       TW_PRINTK(tw_dev->host, TW_DRIVER, 0x20, "Response queue empty failed during reset sequence");
+                       do_soft_reset = 1;
+                       tries++;
+                       continue;
+               }
+
+               flashed = 0;
+
+               /* Check for compatibility/flash */
+               if (twa_check_srl(tw_dev, &flashed)) {
+                       TW_PRINTK(tw_dev->host, TW_DRIVER, 0x21, "Compatibility check failed during reset sequence");
+                       do_soft_reset = 1;
+                       tries++;
+                       continue;
+               } else {
+                       if (flashed) {
+                               tries++;
+                               continue;
+                       }
+               }
+
+               /* Drain the AEN queue */
+               if (twa_aen_drain_queue(tw_dev, soft_reset)) {
+                       TW_PRINTK(tw_dev->host, TW_DRIVER, 0x22, "AEN drain failed during reset sequence");
+                       do_soft_reset = 1;
+                       tries++;
+                       continue;
+               }
+
+               /* If we got here, controller is in a good state */
+               retval = 0;
+               goto out;
+       }
+out:
+       return retval;
+} /* End twa_reset_sequence() */
+
+/* This funciton returns unit geometry in cylinders/heads/sectors */
+static int twa_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[])
+{
+       int heads, sectors, cylinders;
+       TW_Device_Extension *tw_dev;
+
+       tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
+
+       if (capacity >= 0x200000) {
+               heads = 255;
+               sectors = 63;
+               cylinders = sector_div(capacity, heads * sectors);
+       } else {
+               heads = 64;
+               sectors = 32;
+               cylinders = sector_div(capacity, heads * sectors);
+       }
+
+       geom[0] = heads;
+       geom[1] = sectors;
+       geom[2] = cylinders;
+
+       return 0;
+} /* End twa_scsi_biosparam() */
+
+/* This is the new scsi eh abort function */
+static int twa_scsi_eh_abort(struct scsi_cmnd *SCpnt)
+{
+       int i;
+       TW_Device_Extension *tw_dev = NULL;
+       int retval = FAILED;
+
+       tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
+
+       spin_unlock_irq(tw_dev->host->host_lock);
+
+       tw_dev->num_aborts++;
+
+       /* If we find any IO's in process, we have to reset the card */
+       for (i = 0; i < TW_Q_LENGTH; i++) {
+               if ((tw_dev->state[i] != TW_S_FINISHED) && (tw_dev->state[i] != TW_S_INITIAL)) {
+                       printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Unit #%d: Command (0x%x) timed out, resetting card.\n",
+                              tw_dev->host->host_no, TW_DRIVER, 0x2c,
+                              SCpnt->device->id, SCpnt->cmnd[0]);
+                       if (twa_reset_device_extension(tw_dev)) {
+                               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2a, "Controller reset failed during scsi abort");
+                               goto out;
+                       }
+                       break;
+               }
+       }
+       retval = SUCCESS;
+out:
+       spin_lock_irq(tw_dev->host->host_lock);
+       return retval;
+} /* End twa_scsi_eh_abort() */
+
+/* This is the new scsi eh reset function */
+static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt)
+{
+       TW_Device_Extension *tw_dev = NULL;
+       int retval = FAILED;
+
+       tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
+
+       spin_unlock_irq(tw_dev->host->host_lock);
+
+       tw_dev->num_resets++;
+
+       printk(KERN_WARNING "3w-9xxx: scsi%d: SCSI host reset started.\n", tw_dev->host->host_no);
+
+       /* Now reset the card and some of the device extension data */
+       if (twa_reset_device_extension(tw_dev)) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset");
+               goto out;
+       }
+       printk(KERN_WARNING "3w-9xxx: scsi%d: SCSI host reset succeeded.\n", tw_dev->host->host_no);
+       retval = SUCCESS;
+out:
+       spin_lock_irq(tw_dev->host->host_lock);
+       return retval;
+} /* End twa_scsi_eh_reset() */
+
+/* This is the main scsi queue function to handle scsi opcodes */
+static int twa_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+{
+       int request_id, retval;
+       TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
+
+       /* Save done function into scsi_cmnd struct */
+       SCpnt->scsi_done = done;
+               
+       /* Get a free request id */
+       twa_get_request_id(tw_dev, &request_id);
+
+       /* Save the scsi command for use by the ISR */
+       tw_dev->srb[request_id] = SCpnt;
+
+       /* Initialize phase to zero */
+       SCpnt->SCp.phase = TW_PHASE_INITIAL;
+
+       retval = twa_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
+       switch (retval) {
+       case SCSI_MLQUEUE_HOST_BUSY:
+               twa_free_request_id(tw_dev, request_id);
+               break;
+       case 1:
+               tw_dev->state[request_id] = TW_S_COMPLETED;
+               twa_free_request_id(tw_dev, request_id);
+               SCpnt->result = (DID_ERROR << 16);
+               done(SCpnt);
+       }
+
+       return retval;
+} /* End twa_scsi_queue() */
+
+/* This function hands scsi cdb's to the firmware */
+static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Apache *sglistarg)
+{
+       TW_Command_Full *full_command_packet;
+       TW_Command_Apache *command_packet;
+       u32 num_sectors = 0x0;
+       int i, sg_count;
+       struct scsi_cmnd *srb = NULL;
+       struct scatterlist *sglist = NULL;
+       u32 buffaddr = 0x0;
+       int retval = 1;
+
+       if (tw_dev->srb[request_id]) {
+               if (tw_dev->srb[request_id]->request_buffer) {
+                       sglist = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
+               }
+               srb = tw_dev->srb[request_id];
+       }
+
+       /* Initialize command packet */
+       full_command_packet = tw_dev->command_packet_virt[request_id];
+       full_command_packet->header.header_desc.size_header = 128;
+       full_command_packet->header.status_block.error = 0;
+       full_command_packet->header.status_block.severity__reserved = 0;
+
+       command_packet = &full_command_packet->command.newcommand;
+       command_packet->status = 0;
+       command_packet->opcode__reserved = TW_OPRES_IN(0, TW_OP_EXECUTE_SCSI);
+
+       /* We forced 16 byte cdb use earlier */
+       if (!cdb)
+               memcpy(command_packet->cdb, srb->cmnd, TW_MAX_CDB_LEN);
+       else
+               memcpy(command_packet->cdb, cdb, TW_MAX_CDB_LEN);
+
+       if (srb)
+               command_packet->unit = srb->device->id;
+       else
+               command_packet->unit = 0;
+
+       command_packet->request_id = request_id;
+       command_packet->sgl_offset = 16;
+
+       if (!sglistarg) {
+               /* Map sglist from scsi layer to cmd packet */
+               if (tw_dev->srb[request_id]->use_sg == 0) {
+                       if (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH) {
+                               command_packet->sg_list[0].address = tw_dev->generic_buffer_phys[request_id];
+                               command_packet->sg_list[0].length = TW_MIN_SGL_LENGTH;
+                       } else {
+                               buffaddr = twa_map_scsi_single_data(tw_dev, request_id);
+                               if (buffaddr == 0)
+                                       goto out;
+
+                               command_packet->sg_list[0].address = buffaddr;
+                               command_packet->sg_list[0].length = tw_dev->srb[request_id]->request_bufflen;
+                       }
+                       command_packet->sgl_entries = 1;
+
+                       if (command_packet->sg_list[0].address & TW_ALIGNMENT_9000_SGL) {
+                               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2d, "Found unaligned address during execute scsi");
+                               goto out;
+                       }
+               }
+
+               if (tw_dev->srb[request_id]->use_sg > 0) {
+                       sg_count = twa_map_scsi_sg_data(tw_dev, request_id);
+                       if (sg_count == 0)
+                               goto out;
+
+                       for (i = 0; i < sg_count; i++) {
+                               command_packet->sg_list[i].address = sg_dma_address(&sglist[i]);
+                               command_packet->sg_list[i].length = sg_dma_len(&sglist[i]);
+                               if (command_packet->sg_list[i].address & TW_ALIGNMENT_9000_SGL) {
+                                       TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2e, "Found unaligned sgl address during execute scsi");
+                                       goto out;
+                               }
+                       }
+                       command_packet->sgl_entries = tw_dev->srb[request_id]->use_sg;
+               }
+       } else {
+               /* Internal cdb post */
+               for (i = 0; i < use_sg; i++) {
+                       command_packet->sg_list[i].address = sglistarg[i].address;
+                       command_packet->sg_list[i].length = sglistarg[i].length;
+                       if (command_packet->sg_list[i].address & TW_ALIGNMENT_9000_SGL) {
+                               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2f, "Found unaligned sgl address during internal post");
+                               goto out;
+                       }
+               }
+               command_packet->sgl_entries = use_sg;
+       }
+
+       if (srb) {
+               if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6)
+                       num_sectors = (u32)srb->cmnd[4];
+
+               if (srb->cmnd[0] == READ_10 || srb->cmnd[0] == WRITE_10)
+                       num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
+       }
+
+       /* Update sector statistic */
+       tw_dev->sector_count = num_sectors;
+       if (tw_dev->sector_count > tw_dev->max_sector_count)
+               tw_dev->max_sector_count = tw_dev->sector_count;
+
+       /* Update SG statistics */
+       if (srb) {
+               tw_dev->sgl_entries = tw_dev->srb[request_id]->use_sg;
+               if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
+                       tw_dev->max_sgl_entries = tw_dev->sgl_entries;
+       }
+
+       /* Now post the command to the board */
+       if (srb) {
+               retval = twa_post_command_packet(tw_dev, request_id, 0);
+       } else {
+               twa_post_command_packet(tw_dev, request_id, 1);
+               retval = 0;
+       }
+out:
+       return retval;
+} /* End twa_scsiop_execute_scsi() */
+
+/* This function completes an execute scsi operation */
+static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id)
+{
+       /* Copy the response if too small */
+       if ((tw_dev->srb[request_id]->request_buffer) && (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH)) {
+               memcpy(tw_dev->srb[request_id]->request_buffer,
+                      tw_dev->generic_buffer_virt[request_id],
+                      tw_dev->srb[request_id]->request_bufflen);
+       }
+} /* End twa_scsiop_execute_scsi_complete() */
+
+/* This function tells the controller to shut down */
+static void __twa_shutdown(TW_Device_Extension *tw_dev)
+{
+       /* Disable interrupts */
+       TW_DISABLE_INTERRUPTS(tw_dev);
+
+       printk(KERN_WARNING "3w-9xxx: Shutting down host %d.\n", tw_dev->host->host_no);
+
+       /* Tell the card we are shutting down */
+       if (twa_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x31, "Connection shutdown failed");
+       } else {
+               printk(KERN_WARNING "3w-9xxx: Shutdown complete.\n");
+       }
+
+       /* Clear all interrupts just before exit */
+       TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
+} /* End __twa_shutdown() */
+
+/* Wrapper for __twa_shutdown */
+static void twa_shutdown(struct device *dev)
+{
+       struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev));
+       TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
+
+       __twa_shutdown(tw_dev);
+} /* End twa_shutdown() */
+
+/* This function will look up a string */
+static char *twa_string_lookup(twa_message_type *table, unsigned int code)
+{
+       int index;
+
+       for (index = 0; ((code != table[index].code) &&
+                     (table[index].text != (char *)0)); index++);
+       return(table[index].text);
+} /* End twa_string_lookup() */
+
+/* This function will perform a pci-dma unmap */
+static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id)
+{
+       struct scsi_cmnd *cmd = tw_dev->srb[request_id];
+       struct pci_dev *pdev = tw_dev->tw_pci_dev;
+
+       switch(cmd->SCp.phase) {
+       case TW_PHASE_SINGLE:
+               pci_unmap_single(pdev, cmd->SCp.have_data_in, cmd->request_bufflen, DMA_BIDIRECTIONAL);
+               break;
+       case TW_PHASE_SGLIST:
+               pci_unmap_sg(pdev, cmd->request_buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
+               break;
+       }
+} /* End twa_unmap_scsi_data() */
+
+/* scsi_host_template initializer */
+static struct scsi_host_template driver_template = {
+       .module                 = THIS_MODULE,
+       .name                   = "3ware 9000 Storage Controller",
+       .queuecommand           = twa_scsi_queue,
+       .eh_abort_handler       = twa_scsi_eh_abort,
+       .eh_host_reset_handler  = twa_scsi_eh_reset,
+       .bios_param             = twa_scsi_biosparam,
+       .can_queue              = TW_Q_LENGTH-2,
+       .this_id                = -1,
+       .sg_tablesize           = TW_APACHE_MAX_SGL_LENGTH,
+       .max_sectors            = TW_MAX_SECTORS,
+       .cmd_per_lun            = TW_MAX_CMDS_PER_LUN,
+       .use_clustering         = ENABLE_CLUSTERING,
+       .shost_attrs            = twa_host_attrs,
+       .sdev_attrs             = twa_dev_attrs,
+       .emulated               = 1
+};
+
+/* This function will probe and initialize a card */
+static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
+{
+       struct Scsi_Host *host = NULL;
+       TW_Device_Extension *tw_dev;
+       u32 mem_addr;
+       int retval = -ENODEV;
+
+       retval = pci_enable_device(pdev);
+       if (retval) {
+               TW_PRINTK(host, TW_DRIVER, 0x34, "Failed to enable pci device");
+               goto out_disable_device;
+       }
+
+       pci_set_master(pdev);
+
+       retval = pci_set_dma_mask(pdev, TW_DMA_MASK);
+       if (retval) {
+               TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask");
+               goto out_disable_device;
+       }
+
+       host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
+       if (!host) {
+               TW_PRINTK(host, TW_DRIVER, 0x24, "Failed to allocate memory for device extension");
+               retval = -ENOMEM;
+               goto out_disable_device;
+       }
+       tw_dev = (TW_Device_Extension *)host->hostdata;
+
+       memset(tw_dev, 0, sizeof(TW_Device_Extension));
+
+       /* Save values to device extension */
+       tw_dev->host = host;
+       tw_dev->tw_pci_dev = pdev;
+
+       if (twa_initialize_device_extension(tw_dev)) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x25, "Failed to initialize device extension");
+               goto out_free_device_extension;
+       }
+
+       /* Request IO regions */
+       retval = pci_request_regions(pdev, "3w-9xxx");
+       if (retval) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x26, "Failed to get mem region");
+               goto out_free_device_extension;
+       }
+
+       mem_addr = pci_resource_start(pdev, 1);
+
+       /* Save base address */
+       tw_dev->base_addr = ioremap(mem_addr, PAGE_SIZE);
+       if (!tw_dev->base_addr) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x35, "Failed to ioremap");
+               goto out_release_mem_region;
+       }
+
+       /* Disable interrupts on the card */
+       TW_DISABLE_INTERRUPTS(tw_dev);
+
+       /* Initialize the card */
+       if (twa_reset_sequence(tw_dev, 0))
+               goto out_release_mem_region;
+
+       /* Set host specific parameters */
+       host->max_id = TW_MAX_UNITS;
+       host->max_cmd_len = TW_MAX_CDB_LEN;
+
+       /* Luns and channels aren't supported by adapter */
+       host->max_lun = 0;
+       host->max_channel = 0;
+
+       /* Register the card with the kernel SCSI layer */
+       retval = scsi_add_host(host, &pdev->dev);
+       if (retval) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x27, "scsi add host failed");
+               goto out_release_mem_region;
+       }
+
+       pci_set_drvdata(pdev, host);
+
+       printk(KERN_WARNING "3w-9xxx: scsi%d: Found a 3ware 9000 Storage Controller at 0x%x, IRQ: %d.\n",
+              host->host_no, mem_addr, pdev->irq);
+       printk(KERN_WARNING "3w-9xxx: scsi%d: Firmware %s, BIOS %s, Ports: %d.\n",
+              host->host_no,
+              (char *)twa_get_param(tw_dev, 0, TW_VERSION_TABLE,
+                                    TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH),
+              (char *)twa_get_param(tw_dev, 1, TW_VERSION_TABLE,
+                                    TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH),
+              *(int *)twa_get_param(tw_dev, 2, TW_INFORMATION_TABLE,
+                                    TW_PARAM_PORTCOUNT, TW_PARAM_PORTCOUNT_LENGTH));
+
+       /* Now setup the interrupt handler */
+       retval = request_irq(pdev->irq, twa_interrupt, SA_SHIRQ, "3w-9xxx", tw_dev);
+       if (retval) {
+               TW_PRINTK(tw_dev->host, TW_DRIVER, 0x30, "Error requesting IRQ");
+               goto out_remove_host;
+       }
+
+       twa_device_extension_list[twa_device_extension_count] = tw_dev;
+       twa_device_extension_count++;
+
+       /* Re-enable interrupts on the card */
+       TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
+
+       /* Finally, scan the host */
+       scsi_scan_host(host);
+
+       if (twa_major == -1) {
+               if ((twa_major = register_chrdev (0, "twa", &twa_fops)) < 0)
+                       TW_PRINTK(host, TW_DRIVER, 0x29, "Failed to register character device");
+       }
+       return 0;
+
+out_remove_host:
+       scsi_remove_host(host);
+out_release_mem_region:
+       pci_release_regions(pdev);
+out_free_device_extension:
+       twa_free_device_extension(tw_dev);
+       scsi_host_put(host);
+out_disable_device:
+       pci_disable_device(pdev);
+
+       return retval;
+} /* End twa_probe() */
+
+/* This function is called to remove a device */
+static void twa_remove(struct pci_dev *pdev)
+{
+       struct Scsi_Host *host = pci_get_drvdata(pdev);
+       TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
+
+       scsi_remove_host(tw_dev->host);
+
+       __twa_shutdown(tw_dev);
+
+       /* Free up the IRQ */
+       free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
+
+       /* Free up the mem region */
+       pci_release_regions(pdev);
+
+       /* Free up device extension resources */
+       twa_free_device_extension(tw_dev);
+
+       /* Unregister character device */
+       if (twa_major >= 0) {
+               unregister_chrdev(twa_major, "twa");
+               twa_major = -1;
+       }
+
+       scsi_host_put(tw_dev->host);
+       pci_disable_device(pdev);
+       twa_device_extension_count--;
+} /* End twa_remove() */
+
+/* PCI Devices supported by this driver */
+static struct pci_device_id twa_pci_tbl[] __devinitdata = {
+       { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9000,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { }
+};
+MODULE_DEVICE_TABLE(pci, twa_pci_tbl);
+
+/* pci_driver initializer */
+static struct pci_driver twa_driver = {
+       .name           = "3w-9xxx",
+       .id_table       = twa_pci_tbl,
+       .probe          = twa_probe,
+       .remove         = twa_remove,
+       .driver         = {
+               .shutdown = twa_shutdown
+       }
+};
+
+/* This function is called on driver initialization */
+static int __init twa_init(void)
+{
+       printk(KERN_WARNING "3ware 9000 Storage Controller device driver for Linux v%s.\n", twa_driver_version);
+
+       return pci_module_init(&twa_driver);
+} /* End twa_init() */
+
+/* This function is called on driver exit */
+static void __exit twa_exit(void)
+{
+       pci_unregister_driver(&twa_driver);
+} /* End twa_exit() */
+
+module_init(twa_init);
+module_exit(twa_exit);
+
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
new file mode 100644 (file)
index 0000000..2e4f49a
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ *
+ * Includes for cdc-acm.c
+ *
+ * Mainly take from usbnet's cdc-ether part
+ *
+ */
+
+/*
+ * CMSPAR, some architectures can't have space and mark parity.
+ */
+
+#ifndef CMSPAR
+#define CMSPAR                 0
+#endif
+
+/*
+ * Major and minor numbers.
+ */
+
+#define ACM_TTY_MAJOR          166
+#define ACM_TTY_MINORS         32
+
+/*
+ * Requests.
+ */
+
+#define USB_RT_ACM             (USB_TYPE_CLASS | USB_RECIP_INTERFACE)
+
+#define ACM_REQ_COMMAND                0x00
+#define ACM_REQ_RESPONSE       0x01
+#define ACM_REQ_SET_FEATURE    0x02
+#define ACM_REQ_GET_FEATURE    0x03
+#define ACM_REQ_CLEAR_FEATURE  0x04
+
+#define ACM_REQ_SET_LINE       0x20
+#define ACM_REQ_GET_LINE       0x21
+#define ACM_REQ_SET_CONTROL    0x22
+#define ACM_REQ_SEND_BREAK     0x23
+
+/*
+ * IRQs.
+ */
+
+#define ACM_IRQ_NETWORK                0x00
+#define ACM_IRQ_LINE_STATE     0x20
+
+/*
+ * Output control lines.
+ */
+
+#define ACM_CTRL_DTR           0x01
+#define ACM_CTRL_RTS           0x02
+
+/*
+ * Input control lines and line errors.
+ */
+
+#define ACM_CTRL_DCD           0x01
+#define ACM_CTRL_DSR           0x02
+#define ACM_CTRL_BRK           0x04
+#define ACM_CTRL_RI            0x08
+
+#define ACM_CTRL_FRAMING       0x10
+#define ACM_CTRL_PARITY                0x20
+#define ACM_CTRL_OVERRUN       0x40
+
+/*
+ * Line speed and caracter encoding.
+ */
+
+struct acm_line {
+       __u32 speed;
+       __u8 stopbits;
+       __u8 parity;
+       __u8 databits;
+} __attribute__ ((packed));
+
+/*
+ * Internal driver structures.
+ */
+
+struct acm {
+       struct usb_device *dev;                         /* the corresponding usb device */
+       struct usb_interface *control;                  /* control interface */
+       struct usb_interface *data;                     /* data interface */
+       struct tty_struct *tty;                         /* the corresponding tty */
+       struct urb *ctrlurb, *readurb, *writeurb;       /* urbs */
+       struct acm_line line;                           /* line coding (bits, stop, parity) */
+       struct work_struct work;                        /* work queue entry for line discipline waking up */
+       struct tasklet_struct bh;                       /* rx processing */
+       unsigned int ctrlin;                            /* input control lines (DCD, DSR, RI, break, overruns) */
+       unsigned int ctrlout;                           /* output control lines (DTR, RTS) */
+       unsigned int writesize;                         /* max packet size for the output bulk endpoint */
+       unsigned int used;                              /* someone has this acm's device open */
+       unsigned int minor;                             /* acm minor number */
+       unsigned char throttle;                         /* throttled by tty layer */
+       unsigned char clocal;                           /* termios CLOCAL */
+       unsigned char ready_for_write;                  /* write urb can be used */
+};
+
+/* "Union Functional Descriptor" from CDC spec 5.2.3.X */
+struct union_desc {
+       u8      bLength;
+       u8      bDescriptorType;
+       u8      bDescriptorSubType;
+
+       u8      bMasterInterface0;
+       u8      bSlaveInterface0;
+       /* ... and there could be other slave interfaces */
+} __attribute__ ((packed));
+
+#define CDC_UNION_TYPE         0x06
+#define CDC_DATA_INTERFACE_TYPE        0x0a
+
diff --git a/fs/isofs/export.c b/fs/isofs/export.c
new file mode 100644 (file)
index 0000000..e4252c9
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * fs/isofs/export.c
+ *
+ *  (C) 2004  Paul Serice - The new inode scheme requires switching
+ *                          from iget() to iget5_locked() which means
+ *                          the NFS export operations have to be hand
+ *                          coded because the default routines rely on
+ *                          iget().
+ *
+ * The following files are helpful:
+ *
+ *     Documentation/filesystems/Exporting
+ *     fs/exportfs/expfs.c.
+ */
+
+#include <linux/buffer_head.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/iso_fs.h>
+#include <linux/kernel.h>
+
+static struct dentry *
+isofs_export_iget(struct super_block *sb,
+                 unsigned long block,
+                 unsigned long offset,
+                 __u32 generation)
+{
+       struct inode *inode;
+       struct dentry *result;
+       if (block == 0)
+               return ERR_PTR(-ESTALE);
+       inode = isofs_iget(sb, block, offset);
+       if (inode == NULL)
+               return ERR_PTR(-ENOMEM);
+       if (is_bad_inode(inode)
+           || (generation && inode->i_generation != generation))
+       {
+               iput(inode);
+               return ERR_PTR(-ESTALE);
+       }
+       result = d_alloc_anon(inode);
+       if (!result) {
+               iput(inode);
+               return ERR_PTR(-ENOMEM);
+       }
+       return result;
+}
+
+static struct dentry *
+isofs_export_get_dentry(struct super_block *sb, void *vobjp)
+{
+       __u32 *objp = vobjp;
+       unsigned long block = objp[0];
+       unsigned long offset = objp[1];
+       __u32 generation = objp[2];
+       return isofs_export_iget(sb, block, offset, generation);
+}
+
+/* This function is surprisingly simple.  The trick is understanding
+ * that "child" is always a directory. So, to find its parent, you
+ * simply need to find its ".." entry, normalize its block and offset,
+ * and return the underlying inode.  See the comments for
+ * isofs_normalize_block_and_offset(). */
+static struct dentry *isofs_export_get_parent(struct dentry *child)
+{
+       unsigned long parent_block = 0;
+       unsigned long parent_offset = 0;
+       struct inode *child_inode = child->d_inode;
+       struct iso_inode_info *e_child_inode = ISOFS_I(child_inode);
+       struct inode *parent_inode = NULL;
+       struct iso_directory_record *de = NULL;
+       struct buffer_head * bh = NULL;
+       struct dentry *rv = NULL;
+
+       /* "child" must always be a directory. */
+       if (!S_ISDIR(child_inode->i_mode)) {
+               printk(KERN_ERR "isofs: isofs_export_get_parent(): "
+                      "child is not a directory!\n");
+               rv = ERR_PTR(-EACCES);
+               goto out;
+       }
+
+       /* It is an invariant that the directory offset is zero.  If
+        * it is not zero, it means the directory failed to be
+        * normalized for some reason. */
+       if (e_child_inode->i_iget5_offset != 0) {
+               printk(KERN_ERR "isofs: isofs_export_get_parent(): "
+                      "child directory not normalized!\n");
+               rv = ERR_PTR(-EACCES);
+               goto out;
+       }
+
+       /* The child inode has been normalized such that its
+        * i_iget5_block value points to the "." entry.  Fortunately,
+        * the ".." entry is located in the same block. */
+       parent_block = e_child_inode->i_iget5_block;
+
+       /* Get the block in question. */
+       bh = sb_bread(child_inode->i_sb, parent_block);
+       if (bh == NULL) {
+               rv = ERR_PTR(-EACCES);
+               goto out;
+       }
+
+       /* This is the "." entry. */
+       de = (struct iso_directory_record*)bh->b_data;
+
+       /* The ".." entry is always the second entry. */
+       parent_offset = (unsigned long)isonum_711(de->length);
+       de = (struct iso_directory_record*)(bh->b_data + parent_offset);
+
+       /* Verify it is in fact the ".." entry. */
+       if ((isonum_711(de->name_len) != 1) || (de->name[0] != 1)) {
+               printk(KERN_ERR "isofs: Unable to find the \"..\" "
+                      "directory for NFS.\n");
+               rv = ERR_PTR(-EACCES);
+               goto out;
+       }
+
+       /* Normalize */
+       isofs_normalize_block_and_offset(de, &parent_block, &parent_offset);
+
+       /* Get the inode. */
+       parent_inode = isofs_iget(child_inode->i_sb,
+                                 parent_block,
+                                 parent_offset);
+       if (parent_inode == NULL) {
+               rv = ERR_PTR(-EACCES);
+               goto out;
+       }
+
+       /* Allocate the dentry. */
+       rv = d_alloc_anon(parent_inode);
+       if (rv == NULL) {
+               rv = ERR_PTR(-ENOMEM);
+               goto out;
+       }
+
+ out:
+       if (bh) {
+               brelse(bh);
+       }
+       return rv;
+}
+
+static int
+isofs_export_encode_fh(struct dentry *dentry,
+                      __u32 *fh32,
+                      int *max_len,
+                      int connectable)
+{
+       struct inode * inode = dentry->d_inode;
+       struct iso_inode_info * ei = ISOFS_I(inode);
+       int len = *max_len;
+       int type = 1;
+       __u16 *fh16 = (__u16*)fh32;
+
+       /*
+        * WARNING: max_len is 5 for NFSv2.  Because of this
+        * limitation, we use the lower 16 bits of fh32[1] to hold the
+        * offset of the inode and the upper 16 bits of fh32[1] to
+        * hold the offset of the parent.
+        */
+
+       if (len < 3 || (connectable && len < 5))
+               return 255;
+
+       len = 3;
+       fh32[0] = ei->i_iget5_block;
+       fh16[2] = (__u16)ei->i_iget5_offset;  /* fh16 [sic] */
+       fh32[2] = inode->i_generation;
+       if (connectable && !S_ISDIR(inode->i_mode)) {
+               struct inode *parent;
+               struct iso_inode_info *eparent;
+               spin_lock(&dentry->d_lock);
+               parent = dentry->d_parent->d_inode;
+               eparent = ISOFS_I(parent);
+               fh32[3] = eparent->i_iget5_block;
+               fh16[3] = (__u16)eparent->i_iget5_offset;  /* fh16 [sic] */
+               fh32[4] = parent->i_generation;
+               spin_unlock(&dentry->d_lock);
+               len = 5;
+               type = 2;
+       }
+       *max_len = len;
+       return type;
+}
+
+
+static struct dentry *
+isofs_export_decode_fh(struct super_block *sb,
+                      __u32 *fh32,
+                      int fh_len,
+                      int fileid_type,
+                      int (*acceptable)(void *context, struct dentry *de),
+                      void *context)
+{
+       __u16 *fh16 = (__u16*)fh32;
+       __u32 child[3];   /* The child is what triggered all this. */
+       __u32 parent[3];  /* The parent is just along for the ride. */
+
+       if (fh_len < 3 || fileid_type > 2)
+               return NULL;
+
+       child[0] = fh32[0];
+       child[1] = fh16[2];  /* fh16 [sic] */
+       child[2] = fh32[2];
+
+       parent[0] = 0;
+       parent[1] = 0;
+       parent[2] = 0;
+       if (fileid_type == 2) {
+               if (fh_len > 2) parent[0] = fh32[3];
+               parent[1] = fh16[3];  /* fh16 [sic] */
+               if (fh_len > 4) parent[2] = fh32[4];
+       }
+
+       return sb->s_export_op->find_exported_dentry(sb, child, parent,
+                                                    acceptable, context);
+}
+
+
+struct export_operations isofs_export_ops = {
+       .decode_fh      = isofs_export_decode_fh,
+       .encode_fh      = isofs_export_encode_fh,
+       .get_dentry     = isofs_export_get_dentry,
+       .get_parent     = isofs_export_get_parent,
+};
diff --git a/include/asm-arm/hardware/clock.h b/include/asm-arm/hardware/clock.h
new file mode 100644 (file)
index 0000000..2fbf607
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ *  linux/include/asm-arm/hardware/clock.h
+ *
+ *  Copyright (C) 2004 ARM Limited.
+ *  Written by Deep Blue Solutions Limited.
+ *
+ * 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.
+ */
+#ifndef ASMARM_CLOCK_H
+#define ASMARM_CLOCK_H
+
+struct device;
+
+/*
+ * The base API.
+ */
+
+
+/*
+ * struct clk - an machine class defined object / cookie.
+ */
+struct clk;
+
+/**
+ * clk_get - lookup and obtain a reference to a clock producer.
+ * @dev: device for clock "consumer"
+ * @id: device ID
+ *
+ * Returns a struct clk corresponding to the clock producer, or
+ * valid IS_ERR() condition containing errno.
+ */
+struct clk *clk_get(struct device *dev, const char *id);
+
+/**
+ * clk_enable - inform the system when the clock source should be running.
+ * @clk: clock source
+ *
+ * If the clock can not be enabled/disabled, this should return success.
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_enable(struct clk *clk);
+
+/**
+ * clk_disable - inform the system when the clock source is no longer required.
+ * @clk: clock source
+ */
+void clk_disable(struct clk *clk);
+
+/**
+ * clk_use - increment the use count
+ * @clk: clock source
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_use(struct clk *clk);
+
+/**
+ * clk_unuse - decrement the use count
+ * @clk: clock source
+ */
+void clk_unuse(struct clk *clk);
+
+/**
+ * clk_get_rate - obtain the current clock rate for a clock source.
+ *               This is only valid once the clock source has been enabled.
+ * @clk: clock source
+ */
+unsigned long clk_get_rate(struct clk *clk);
+
+/**
+ * clk_put     - "free" the clock source
+ * @clk: clock source
+ */
+void clk_put(struct clk *clk);
+
+
+/*
+ * The remaining APIs are optional for machine class support.
+ */
+
+
+/**
+ * clk_round_rate - adjust a rate to the exact rate a clock can provide
+ * @clk: clock source
+ * @rate: desired clock rate in kHz
+ *
+ * Returns rounded clock rate, or negative errno.
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate);
+/**
+ * clk_set_rate - set the clock rate for a clock source
+ * @clk: clock source
+ * @rate: desired clock rate in kHz
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate);
+/**
+ * clk_set_parent - set the parent clock source for this clock
+ * @clk: clock source
+ * @parent: parent clock source
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_set_parent(struct clk *clk, struct clk *parent);
+                                                                                
+/**
+ * clk_get_parent - get the parent clock source for this clock
+ * @clk: clock source
+ *
+ * Returns struct clk corresponding to parent clock source, or
+ * valid IS_ERR() condition containing errno.
+ */
+struct clk *clk_get_parent(struct clk *clk);
+
+#endif
diff --git a/include/asm-arm/vfp.h b/include/asm-arm/vfp.h
new file mode 100644 (file)
index 0000000..14c5e09
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * linux/include/asm-arm/vfp.h
+ *
+ * VFP register definitions.
+ * First, the standard VFP set.
+ */
+
+#define FPSID                  cr0
+#define FPSCR                  cr1
+#define FPEXC                  cr8
+
+/* FPSID bits */
+#define FPSID_IMPLEMENTER_BIT  (24)
+#define FPSID_IMPLEMENTER_MASK (0xff << FPSID_IMPLEMENTER_BIT)
+#define FPSID_SOFTWARE         (1<<23)
+#define FPSID_FORMAT_BIT       (21)
+#define FPSID_FORMAT_MASK      (0x3  << FPSID_FORMAT_BIT)
+#define FPSID_NODOUBLE         (1<<20)
+#define FPSID_ARCH_BIT         (16)
+#define FPSID_ARCH_MASK                (0xF  << FPSID_ARCH_BIT)
+#define FPSID_PART_BIT         (8)
+#define FPSID_PART_MASK                (0xFF << FPSID_PART_BIT)
+#define FPSID_VARIANT_BIT      (4)
+#define FPSID_VARIANT_MASK     (0xF  << FPSID_VARIANT_BIT)
+#define FPSID_REV_BIT          (0)
+#define FPSID_REV_MASK         (0xF  << FPSID_REV_BIT)
+
+/* FPEXC bits */
+#define FPEXC_EXCEPTION                (1<<31)
+#define FPEXC_ENABLE           (1<<30)
+
+/* FPSCR bits */
+#define FPSCR_DEFAULT_NAN      (1<<25)
+#define FPSCR_FLUSHTOZERO      (1<<24)
+#define FPSCR_ROUND_NEAREST    (0<<22)
+#define FPSCR_ROUND_PLUSINF    (1<<22)
+#define FPSCR_ROUND_MINUSINF   (2<<22)
+#define FPSCR_ROUND_TOZERO     (3<<22)
+#define FPSCR_RMODE_BIT                (22)
+#define FPSCR_RMODE_MASK       (3 << FPSCR_RMODE_BIT)
+#define FPSCR_STRIDE_BIT       (20)
+#define FPSCR_STRIDE_MASK      (3 << FPSCR_STRIDE_BIT)
+#define FPSCR_LENGTH_BIT       (16)
+#define FPSCR_LENGTH_MASK      (7 << FPSCR_LENGTH_BIT)
+#define FPSCR_IOE              (1<<8)
+#define FPSCR_DZE              (1<<9)
+#define FPSCR_OFE              (1<<10)
+#define FPSCR_UFE              (1<<11)
+#define FPSCR_IXE              (1<<12)
+#define FPSCR_IDE              (1<<15)
+#define FPSCR_IOC              (1<<0)
+#define FPSCR_DZC              (1<<1)
+#define FPSCR_OFC              (1<<2)
+#define FPSCR_UFC              (1<<3)
+#define FPSCR_IXC              (1<<4)
+#define FPSCR_IDC              (1<<7)
+
+/*
+ * VFP9-S specific.
+ */
+#define FPINST                 cr9
+#define FPINST2                        cr10
+
+/* FPEXC bits */
+#define FPEXC_FPV2             (1<<28)
+#define FPEXC_LENGTH_BIT       (8)
+#define FPEXC_LENGTH_MASK      (7 << FPEXC_LENGTH_BIT)
+#define FPEXC_INV              (1 << 7)
+#define FPEXC_UFC              (1 << 3)
+#define FPEXC_OFC              (1 << 2)
+#define FPEXC_IOC              (1 << 0)
+
+/* Bit patterns for decoding the packaged operation descriptors */
+#define VFPOPDESC_LENGTH_BIT   (9)
+#define VFPOPDESC_LENGTH_MASK  (0x07 << VFPOPDESC_LENGTH_BIT)
+#define VFPOPDESC_UNUSED_BIT   (24)
+#define VFPOPDESC_UNUSED_MASK  (0xFF << VFPOPDESC_UNUSED_BIT)
+#define VFPOPDESC_OPDESC_MASK  (~(VFPOPDESC_LENGTH_MASK | VFPOPDESC_UNUSED_MASK))
diff --git a/include/asm-ppc/immap_85xx.h b/include/asm-ppc/immap_85xx.h
new file mode 100644 (file)
index 0000000..50fb5e4
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * include/asm-ppc/immap_85xx.h
+ *
+ * MPC85xx Internal Memory Map
+ *
+ * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ *
+ * Copyright 2004 Freescale Semiconductor, 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.
+ *
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_IMMAP_85XX_H__
+#define __ASM_IMMAP_85XX_H__
+
+/* Eventually this should define all the IO block registers in 85xx */
+
+/* PCI Registers */
+typedef struct ccsr_pci {
+       uint    cfg_addr;       /* 0x.000 - PCI Configuration Address Register */
+       uint    cfg_data;       /* 0x.004 - PCI Configuration Data Register */
+       uint    int_ack;        /* 0x.008 - PCI Interrupt Acknowledge Register */
+       char    res1[3060];
+       uint    potar0;         /* 0x.c00 - PCI Outbound Transaction Address Register 0 */
+       uint    potear0;        /* 0x.c04 - PCI Outbound Translation Extended Address Register 0 */
+       uint    powbar0;        /* 0x.c08 - PCI Outbound Window Base Address Register 0 */
+       char    res2[4];
+       uint    powar0;         /* 0x.c10 - PCI Outbound Window Attributes Register 0 */
+       char    res3[12];
+       uint    potar1;         /* 0x.c20 - PCI Outbound Transaction Address Register 1 */
+       uint    potear1;        /* 0x.c24 - PCI Outbound Translation Extended Address Register 1 */
+       uint    powbar1;        /* 0x.c28 - PCI Outbound Window Base Address Register 1 */
+       char    res4[4];
+       uint    powar1;         /* 0x.c30 - PCI Outbound Window Attributes Register 1 */
+       char    res5[12];
+       uint    potar2;         /* 0x.c40 - PCI Outbound Transaction Address Register 2 */
+       uint    potear2;        /* 0x.c44 - PCI Outbound Translation Extended Address Register 2 */
+       uint    powbar2;        /* 0x.c48 - PCI Outbound Window Base Address Register 2 */
+       char    res6[4];
+       uint    powar2;         /* 0x.c50 - PCI Outbound Window Attributes Register 2 */
+       char    res7[12];
+       uint    potar3;         /* 0x.c60 - PCI Outbound Transaction Address Register 3 */
+       uint    potear3;        /* 0x.c64 - PCI Outbound Translation Extended Address Register 3 */
+       uint    powbar3;        /* 0x.c68 - PCI Outbound Window Base Address Register 3 */
+       char    res8[4];
+       uint    powar3;         /* 0x.c70 - PCI Outbound Window Attributes Register 3 */
+       char    res9[12];
+       uint    potar4;         /* 0x.c80 - PCI Outbound Transaction Address Register 4 */
+       uint    potear4;        /* 0x.c84 - PCI Outbound Translation Extended Address Register 4 */
+       uint    powbar4;        /* 0x.c88 - PCI Outbound Window Base Address Register 4 */
+       char    res10[4];
+       uint    powar4;         /* 0x.c90 - PCI Outbound Window Attributes Register 4 */
+       char    res11[268];
+       uint    pitar3;         /* 0x.da0 - PCI Inbound Translation Address Register 3  */
+       char    res12[4];
+       uint    piwbar3;        /* 0x.da8 - PCI Inbound Window Base Address Register 3 */
+       uint    piwbear3;       /* 0x.dac - PCI Inbound Window Base Extended Address Register 3 */
+       uint    piwar3;         /* 0x.db0 - PCI Inbound Window Attributes Register 3 */
+       char    res13[12];
+       uint    pitar2;         /* 0x.dc0 - PCI Inbound Translation Address Register 2  */
+       char    res14[4];
+       uint    piwbar2;        /* 0x.dc8 - PCI Inbound Window Base Address Register 2 */
+       uint    piwbear2;       /* 0x.dcc - PCI Inbound Window Base Extended Address Register 2 */
+       uint    piwar2;         /* 0x.dd0 - PCI Inbound Window Attributes Register 2 */
+       char    res15[12];
+       uint    pitar1;         /* 0x.de0 - PCI Inbound Translation Address Register 1  */
+       char    res16[4];
+       uint    piwbar1;        /* 0x.de8 - PCI Inbound Window Base Address Register 1 */
+       char    res17[4];
+       uint    piwar1;         /* 0x.df0 - PCI Inbound Window Attributes Register 1 */
+       char    res18[12];
+       uint    err_dr;         /* 0x.e00 - PCI Error Detect Register */
+       uint    err_cap_dr;     /* 0x.e04 - PCI Error Capture Disable Register */
+       uint    err_en;         /* 0x.e08 - PCI Error Enable Register */
+       uint    err_attrib;     /* 0x.e0c - PCI Error Attributes Capture Register */
+       uint    err_addr;       /* 0x.e10 - PCI Error Address Capture Register */
+       uint    err_ext_addr;   /* 0x.e14 - PCI Error Extended Address Capture Register */
+       uint    err_dl;         /* 0x.e18 - PCI Error Data Low Capture Register */
+       uint    err_dh;         /* 0x.e1c - PCI Error Data High Capture Register */
+       uint    gas_timr;       /* 0x.e20 - PCI Gasket Timer Register */
+       uint    pci_timr;       /* 0x.e24 - PCI Timer Register */
+       char    res19[472];
+} ccsr_pci_t;
+
+/* Global Utility Registers */
+typedef struct ccsr_guts {
+       uint    porpllsr;       /* 0x.0000 - POR PLL Ratio Status Register */
+       uint    porbmsr;        /* 0x.0004 - POR Boot Mode Status Register */
+       uint    porimpscr;      /* 0x.0008 - POR I/O Impedance Status and Control Register */
+       uint    pordevsr;       /* 0x.000c - POR I/O Device Status Register */
+       uint    pordbgmsr;      /* 0x.0010 - POR Debug Mode Status Register */
+       char    res1[12];
+       uint    gpporcr;        /* 0x.0020 - General-Purpose POR Configuration Register */
+       char    res2[12];
+       uint    gpiocr;         /* 0x.0030 - GPIO Control Register */
+       char    res3[12];
+       uint    gpoutdr;        /* 0x.0040 - General-Purpose Output Data Register */
+       char    res4[12];
+       uint    gpindr;         /* 0x.0050 - General-Purpose Input Data Register */
+       char    res5[12];
+       uint    pmuxcr;         /* 0x.0060 - Alternate Function Signal Multiplex Control */
+       char    res6[12];
+       uint    devdisr;        /* 0x.0070 - Device Disable Control */
+       char    res7[12];
+       uint    powmgtcsr;      /* 0x.0080 - Power Management Status and Control Register */
+       char    res8[12];
+       uint    mcpsumr;        /* 0x.0090 - Machine Check Summary Register */
+       char    res9[12];
+       uint    pvr;            /* 0x.00a0 - Processor Version Register */
+       uint    svr;            /* 0x.00a4 - System Version Register */
+       char    res10[3416];
+       uint    clkocr;         /* 0x.0e00 - Clock Out Select Register */
+       char    res11[12];
+       uint    ddrdllcr;       /* 0x.0e10 - DDR DLL Control Register */
+       char    res12[12];
+       uint    lbcdllcr;       /* 0x.0e20 - LBC DLL Control Register */
+       char    res13[61916];
+} ccsr_guts_t;
+
+#endif /* __ASM_IMMAP_85XX_H__ */
+#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h
new file mode 100644 (file)
index 0000000..276a817
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * include/asm-ppc/mpc85xx.h
+ *
+ * MPC85xx definitions
+ *
+ * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ *
+ * Copyright 2004 Freescale Semiconductor, 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.
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_MPC85xx_H__
+#define __ASM_MPC85xx_H__
+
+#include <linux/config.h>
+#include <asm/mmu.h>
+
+#ifdef CONFIG_85xx
+
+#ifdef CONFIG_MPC8540_ADS
+#include <platforms/85xx/mpc8540_ads.h>
+#endif
+
+#define _IO_BASE        isa_io_base
+#define _ISA_MEM_BASE   isa_mem_base
+#define PCI_DRAM_OFFSET pci_dram_offset
+
+/*
+ * The "residual" board information structure the boot loader passes
+ * into the kernel.
+ */
+extern unsigned char __res[];
+
+/* Internal IRQs on MPC85xx OpenPIC */
+/* Not all of these exist on all MPC85xx implementations */
+
+#ifndef MPC85xx_OPENPIC_IRQ_OFFSET
+#define MPC85xx_OPENPIC_IRQ_OFFSET     64
+#endif
+
+/* The 32 internal sources */
+#define MPC85xx_IRQ_L2CACHE    ( 0 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_ECM                ( 1 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_DDR                ( 2 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_LBIU       ( 3 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_DMA0       ( 4 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_DMA1       ( 5 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_DMA2       ( 6 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_DMA3       ( 7 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_PCI1       ( 8 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_PCI2       ( 9 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_RIO_ERROR  ( 9 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_RIO_BELL   (10 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_RIO_TX     (11 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_RIO_RX     (12 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_TSEC1_TX   (13 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_TSEC1_RX   (14 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_TSEC1_ERROR        (18 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_TSEC2_TX   (19 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_TSEC2_RX   (20 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_TSEC2_ERROR        (24 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_FEC                (25 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_DUART      (26 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_IIC1       (27 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_PERFMON    (28 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_CPM                (30 + MPC85xx_OPENPIC_IRQ_OFFSET)
+
+/* The 12 external interrupt lines */
+#define MPC85xx_IRQ_EXT0        (32 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT1        (33 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT2        (34 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT3        (35 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT4        (36 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT5        (37 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT6        (38 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT7        (39 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT8        (40 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT9        (41 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT10       (42 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT11       (43 + MPC85xx_OPENPIC_IRQ_OFFSET)
+
+/* Offset from CCSRBAR */
+#define MPC85xx_CPM_OFFSET     (0x80000)
+#define MPC85xx_CPM_SIZE       (0x40000)
+#define MPC85xx_DMA_OFFSET     (0x21000)
+#define MPC85xx_DMA_SIZE       (0x01000)
+#define MPC85xx_ENET1_OFFSET   (0x24000)
+#define MPC85xx_ENET1_SIZE     (0x01000)
+#define MPC85xx_ENET2_OFFSET   (0x25000)
+#define MPC85xx_ENET2_SIZE     (0x01000)
+#define MPC85xx_ENET3_OFFSET   (0x26000)
+#define MPC85xx_ENET3_SIZE     (0x01000)
+#define MPC85xx_GUTS_OFFSET    (0xe0000)
+#define MPC85xx_GUTS_SIZE      (0x01000)
+#define MPC85xx_IIC1_OFFSET    (0x03000)
+#define MPC85xx_IIC1_SIZE      (0x01000)
+#define MPC85xx_OPENPIC_OFFSET (0x40000)
+#define MPC85xx_OPENPIC_SIZE   (0x40000)
+#define MPC85xx_PCI1_OFFSET    (0x08000)
+#define MPC85xx_PCI1_SIZE      (0x01000)
+#define MPC85xx_PCI2_OFFSET    (0x09000)
+#define MPC85xx_PCI2_SIZE      (0x01000)
+#define MPC85xx_PERFMON_OFFSET (0xe1000)
+#define MPC85xx_PERFMON_SIZE   (0x01000)
+#define MPC85xx_UART0_OFFSET   (0x04500)
+#define MPC85xx_UART0_SIZE     (0x00100)
+#define MPC85xx_UART1_OFFSET   (0x04600)
+#define MPC85xx_UART1_SIZE     (0x00100)
+
+#define MPC85xx_CCSRBAR_SIZE   (1024*1024)
+
+/* Let modules/drivers get at CCSRBAR */
+extern phys_addr_t get_ccsrbar(void);
+
+#ifdef MODULE
+#define CCSRBAR get_ccsrbar()
+#else
+#define CCSRBAR BOARD_CCSRBAR
+#endif
+
+#endif /* CONFIG_85xx */
+#endif /* __ASM_MPC85xx_H__ */
+#endif /* __KERNEL__ */
diff --git a/include/linux/hpet.h b/include/linux/hpet.h
new file mode 100644 (file)
index 0000000..9ab04e9
--- /dev/null
@@ -0,0 +1,133 @@
+#ifndef        __HPET__
+#define        __HPET__ 1
+
+/*
+ * Offsets into HPET Registers
+ */
+
+struct hpet {
+       u64 hpet_cap;           /* capabilities */
+       u64 res0;               /* reserved */
+       u64 hpet_config;        /* configuration */
+       u64 res1;               /* reserved */
+       u64 hpet_isr;           /* interrupt status reg */
+       u64 res2[25];           /* reserved */
+       union {                 /* main counter */
+               u64 _hpet_mc64;
+               u32 _hpet_mc32;
+               unsigned long _hpet_mc;
+       } _u0;
+       u64 res3;               /* reserved */
+       struct hpet_timer {
+               u64 hpet_config;        /* configuration/cap */
+               union {         /* timer compare register */
+                       u64 _hpet_hc64;
+                       u32 _hpet_hc32;
+                       unsigned long _hpet_compare;
+               } _u1;
+               u64 hpet_fsb[2];        /* FSB route */
+       } hpet_timers[1];
+};
+
+#define        hpet_mc         _u0._hpet_mc
+#define        hpet_compare    _u1._hpet_compare
+
+#define        HPET_MAX_TIMERS (32)
+
+/*
+ * HPET general capabilities register
+ */
+
+#define        HPET_COUNTER_CLK_PERIOD_MASK    (0xffffffff00000000ULL)
+#define        HPET_COUNTER_CLK_PERIOD_SHIFT   (32UL)
+#define        HPET_VENDOR_ID_MASK             (0x00000000ffff0000ULL)
+#define        HPET_VENDOR_ID_SHIFT            (16ULL)
+#define        HPET_LEG_RT_CAP_MASK            (0x8000)
+#define        HPET_COUNTER_SIZE_MASK          (0x2000)
+#define        HPET_NUM_TIM_CAP_MASK           (0x1f00)
+#define        HPET_NUM_TIM_CAP_SHIFT          (8ULL)
+
+/*
+ * HPET general configuration register
+ */
+
+#define        HPET_LEG_RT_CNF_MASK            (2UL)
+#define        HPET_ENABLE_CNF_MASK            (1UL)
+
+/*
+ * HPET interrupt status register
+ */
+
+#define        HPET_ISR_CLEAR(HPET, TIMER)                             \
+               (HPET)->hpet_isr |= (1UL << TIMER)
+
+/*
+ * Timer configuration register
+ */
+
+#define        Tn_INT_ROUTE_CAP_MASK           (0xffffffff00000000ULL)
+#define        Tn_INI_ROUTE_CAP_SHIFT          (32UL)
+#define        Tn_FSB_INT_DELCAP_MASK          (0x8000UL)
+#define        Tn_FSB_INT_DELCAP_SHIFT         (15)
+#define        Tn_FSB_EN_CNF_MASK              (0x4000UL)
+#define        Tn_FSB_EN_CNF_SHIFT             (14)
+#define        Tn_INT_ROUTE_CNF_MASK           (0x3e00UL)
+#define        Tn_INT_ROUTE_CNF_SHIFT          (9)
+#define        Tn_32MODE_CNF_MASK              (0x0100UL)
+#define        Tn_VAL_SET_CNF_MASK             (0x0040UL)
+#define        Tn_SIZE_CAP_MASK                (0x0020UL)
+#define        Tn_PER_INT_CAP_MASK             (0x0010UL)
+#define        Tn_TYPE_CNF_MASK                (0x0008UL)
+#define        Tn_INT_ENB_CNF_MASK             (0x0004UL)
+#define        Tn_INT_TYPE_CNF_MASK            (0x0002UL)
+
+/*
+ * Timer FSB Interrupt Route Register
+ */
+
+#define        Tn_FSB_INT_ADDR_MASK            (0xffffffff00000000ULL)
+#define        Tn_FSB_INT_ADDR_SHIFT           (32UL)
+#define        Tn_FSB_INT_VAL_MASK             (0x00000000ffffffffULL)
+
+struct hpet_info {
+       unsigned long hi_ireqfreq;      /* Hz */
+       unsigned long hi_flags; /* information */
+       unsigned short hi_hpet;
+       unsigned short hi_timer;
+};
+
+#define        HPET_INFO_PERIODIC      0x0001  /* timer is periodic */
+
+#define        HPET_IE_ON      _IO('h', 0x01)  /* interrupt on */
+#define        HPET_IE_OFF     _IO('h', 0x02)  /* interrupt off */
+#define        HPET_INFO       _IOR('h', 0x03, struct hpet_info)
+#define        HPET_EPI        _IO('h', 0x04)  /* enable periodic */
+#define        HPET_DPI        _IO('h', 0x05)  /* disable periodic */
+#define        HPET_IRQFREQ    _IOW('h', 0x6, unsigned long)   /* IRQFREQ usec */
+
+/*
+ * exported interfaces
+ */
+
+struct hpet_task {
+       void (*ht_func) (void *);
+       void *ht_data;
+       void *ht_opaque;
+};
+
+struct hpet_data {
+       unsigned long hd_address;
+       unsigned short hd_nirqs;
+       unsigned short hd_flags;
+       unsigned int hd_state;  /* timer allocated */
+       unsigned int hd_irq[HPET_MAX_TIMERS];
+};
+
+#define        HPET_DATA_PLATFORM      0x0001  /* platform call to hpet_alloc */
+
+int hpet_alloc(struct hpet_data *);
+int hpet_register(struct hpet_task *, int);
+int hpet_unregister(struct hpet_task *);
+int hpet_control(struct hpet_task *, unsigned int, unsigned long);
+
+#endif                         /* !__HPET__ */
diff --git a/net/core/stream.c b/net/core/stream.c
new file mode 100644 (file)
index 0000000..24a6f72
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *     SUCS NET3:
+ *
+ *     Generic stream handling routines. These are generic for most
+ *     protocols. Even IP. Tonight 8-).
+ *     This is used because TCP, LLC (others too) layer all have mostly
+ *     identical sendmsg() and recvmsg() code.
+ *     So we (will) share it here.
+ *
+ *     Authors:        Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *                     (from old tcp.c code)
+ *                     Alan Cox <alan@redhat.com> (Borrowed comments 8-))
+ */
+
+#include <linux/module.h>
+#include <linux/net.h>
+#include <linux/signal.h>
+#include <linux/wait.h>
+#include <net/sock.h>
+
+/**
+ * sk_stream_write_space - stream socket write_space callback.
+ * sk - socket
+ *
+ * FIXME: write proper description
+ */
+void sk_stream_write_space(struct sock *sk)
+{
+       struct socket *sock = sk->sk_socket;
+
+       if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk) && sock) {
+               clear_bit(SOCK_NOSPACE, &sock->flags);
+
+               if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+                       wake_up_interruptible(sk->sk_sleep);
+               if (sock->fasync_list && !(sk->sk_shutdown & SEND_SHUTDOWN))
+                       sock_wake_async(sock, 2, POLL_OUT);
+       }
+}
+
+EXPORT_SYMBOL(sk_stream_write_space);